# aardio 范例: OnPaint 自绘示例

```aardio
import win.ui;
/*DSG{{*/
var winform = win.form(text="OnPaint 自绘示例";right=400;bottom=300)
winform.add()
/*}}*/

/*
GDI 自绘。

onPaint 处理 _WM_PAINT 消息并且自动调用 ::BeginPaint 与 ::EndPaint 。
定义 onPaint 时如果 winform.onEraseBkgnd 为 null 则默认设为 `lambda () 0` 。

除 plus 控件以外所有窗体与控件对象都支持 onPaint 事件，
定义 onPaint 会阻止默认其他绘图操作。 
*/
winform.onPaint = function(hdc, rcPaint, fErase, width, height){
	
	//双缓冲优化（说人话就是先在内存画好，再输出到设备）
	gdi.doubleBuffer( hdc,width,height,
	    function( hdc,hMemDc,hMemBitmap ){

    		// 绘制蓝色矩形（GDI 颜色格式为 0xBBGGRR，所以蓝色是 0xFF0000） 
    		var rect = ::RECT(20, 20, 200, 100);
    		gdi.fillRect(hMemDc,0xFF0000,rect);
		
    		// 绘制文本
    		var font = ::LOGFONT(name="Tahoma";point=12;color=0x00FF00 )
    		gdi.textOut(hMemDc,font,"Hello, OnPaint!",30,50)
    	        
	        ::BitBlt(hdc, 0, 0, width, height, hMemDc, 0, 0, 0xCC0020/*_SRCCOPY*/);
	    }
	)

	//忽略返回值
};

// GDI+ 自绘，plus 控件提供了更多的 GDI+ 自绘事件，但 plus 控件不支持 onPaint 事件
import gdip;
winform.onPaint = function(hdc, rcPaint, fErase, width, height){
	var dpiScaleX = winform.dpiScale(1);
	
	// 直接使用传入的 hdc 创建 GDI+ 绘图对象
    var graphics = gdip.graphics(hdc); 
    
    // 使用双缓冲
    var bmp = gdip.bitmap(width, height);
    var mGraphics = bmp.getGraphics();
    
    // 绘制蓝色矩形，参数使用 0xAARRGGBB 格式颜色值
    var brush = gdip.solidBrush(0xFF0000FF)
    mGraphics.fillRoundRect(brush,::RECT(0,0,width, height),8);
    brush.delete();
    
    // 字体
    var font = gdip.font("Tahoma", 28 * dpiScaleX);
    var brushText = gdip.solidBrush(0xFFFFFFFF);
    
    // 对齐格式
    var format = gdip.stringformat();
    format.align = 1;
    format.lineAlign = 1;
        
    // 输出文本
    mGraphics.drawString("Hello, OnPaint!",font,::RECTF(0,0,width, height), format, brushText)

	// 释放对象
 	brushText.delete();
	format.delete();
	font.delete();
	mGraphics.delete();
        
    // 输出到设备
    graphics.drawImage(bmp)
	graphics.delete()
};

winform.show();
win.loopMessage();
```