//程序入口
intAPIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg; //消息结构体
//向系统注册窗口类别,输入的参数“hInstance”是目前程序运个体的对象代码
MyRegisterClass(hInstance);
//运行初始化函数
if( ! InitInstance(hInstance,nCmdShow) //InitInstance函数进行初始实例化操作
{
return FALSE;
}
while( GetMessage( &msg,NULL, 0, 0 ) ) //GetMessage函数从消息队列中抓取消息
{
TranslateMessage(&msg); //对键盘消息进行转换成系统消息
DispatchMessage(&msg); //分派消息到WndProc函数给对应的消息处理函数处理
}
return msg.wParam; //退出时返回给操作系统的消息
}
//MyRegisterClass函数
ATMO MyRegisterClass( HINSTANCE hInstance )
{
WNDCLASSEX wcex;
wcex.cbsize = sizeof(WNDCLASSEX); //WNDCLASS所占用的内存字节
wcex.style = CS_HREARAW | CS_VREDRAW; //窗体的样式
wcex.lpfnWndProc = (WNDPROC) WndProc; //消息处理函数名,自己命名
wcex.cbClsExtra = 0; //指定分配给窗口类结构(此处指lpszClassName)之后的额外字节数
wcex.cbWndExtra = 0; //指定分配给窗口实例(此处指hInstance)之后的额外字节数
wcex.hInstance = hInstance; //指定窗口过程所对应的实例句柄
wcex.hIcon =NULL; //任务栏上的图标,NULL表示采用默认图标
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //指定光标的样式
wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW+1); //指定窗口的背景画刷
wcex.lpszMenuName = NULL; //通过菜单资源名称加载菜单
wcex.lpszClassName = "seekCName"; //窗口类的类名(一个结构体而已,并不是C++的类)
wcex.hIconSm = NULL; //窗口标题栏左侧的小图标,NULL表示采用默认图标
return RegisterClassEx(&wcex);
}
//WNDCLASSEX只是比WNDCLASS多了cbsize和hIconSm这两个成员,其它的都是一样。
//以上参数具体参看:http://baike.baidu.com/view/1750396.html
Nwcex.lpszName = "lpszClassName"详解:
当程序员将wcex结构按自己要求填写完成后就可以调用RegisterClass(或RegisterClassEx)函数将该类注册,这样以后凡是要创建该窗口,只需要以该类名(lpszClassName中指定)为参数调用CreateWindow,你看多方便呀,真是一举多得啊!如下Instance函数中的CreateWindow中的第一个参数“seekName”。
//InitInstance函数
BOOL Instance( HINSTANCE hInstance, int nCmdShow )
{
HWND hWnd;
hInst = hInstance;
//建立一个窗口对象
hWnd = CreateWindow( "seekCName", //窗口类名
"绘图窗口", //窗口标题栏的标题
WS_OVERLAPPEDWINDOW, //窗口的风格,定义为普通型
CW_USEDEFAULT, //窗口左上角X轴坐标
0, //窗口左上角Y轴坐标
CW_USEDEFAULT, //窗体的宽度
10, //窗体的高度
NULL, //父窗体句柄
NULL, //菜单句柄
hInstance, //此应用程序的实例句柄
NULL); //一般不用,设为空
if( !hWnd )
{
return FALSE;
}
MoveWindow( hWnd, 10, 10, 600, 450, true ); //设定窗口显示位置及窗口大小
ShowWindow( hWnd, nCmdShow ); //显示窗体
UpdateWindow( hWnd ); //更新窗体
return TRUE;
}
详解ShowWindow和UpdateWindow的作用:
UpdateWindow只是更新客户区的多个无效区域(待更新区域),如果客户区的某个区域需要重画了,那么windows只是将这个区域设为无效区,此时它不是立即重画,而是等待用户或者系统自动调用UpdateWindow,这样如果有多个区域需要重画的话,就可以串联成一个无效区链表,这样只需调用一次UpdateWindow就将这些无效区重画了,而不用多次调用,提高了效率。
UpdateWindow()只向窗体发送WM_PAINT消息,在发送之前判断GetUpdateRect(hWnd,NULL,TRUE)看有无可绘制的客户区域,如果没有,则不发送WM_PAINT。
UpdateWindow是在HDC上画图的(无论窗口隐藏与否),不是用来显示窗口的;
ShowWindow 是用来显示/隐藏窗口,而不是用来在HDC上作图的。
//WndProc函数
LRESULT CALLBACK WndProc( HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hdc;
switch( message )
{
case WM_PAINT: //窗口重绘消息
hdc = BeginPaint( hWnd, &ps );
//用hdc进行具体的绘图动作
EndPaint( hWnd, &ps );
break;
case WM_DESTROY: //窗口结束消息
PostQuitMessage(0);
break;
default:
return DefWindowProc( hWnd, message, wParam, lParam ); //默认处理函数
}
retrun 0;
}