一、注册窗口类 Windows的窗口类定义了一个窗口的风格,而类中定义的窗口过程决定了窗口的行为。每个类都有一个自己的名字,在Windows中所有的窗口都属于一个窗口类。如果我们需要创建一个自己的窗口,则必须注册一个窗口类。Win32系统提供了一些全局类。这些类无需注册就可以使用。比如:Windows的一些通用控件。对话框类。等等。下面是一个注册窗口类的代码:
WNDCLASS wc;
memset(&wc,0,sizeof(WNDCLASS)); //未使用到的成员函数默认为0
wc.style = CS_HREDRAW|CS_VREDRAW |CS_DBLCLKS ; //这里定义窗口风格
wc.lpfnWndProc = (WNDPROC)MainWndProc; //窗口过程,是一个函数地址,必须编写。
wc.hInstance = hInst; //模块句柄
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); //背景颜色刷子
wc.lpszClassName = "MyWndClass"; //窗口类名
wc.lpszMenuName = MAKEINTRESOURCE(IDMAINMENU); //窗口菜单
wc.hCursor = LoadCursor(NULL,IDC_ARROW); //窗口光标,
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); //窗口图标
if (!RegisterClass(&wc)) //调用RegisterClass注册窗口类
return FALSE; 上面的代码 WNDCLASS 是一个结构体,我们通过设置它的成员的值来设定窗口类的风格和属性。然后将这个结构体传递给系统,申请注册窗口类。成功返回非0值,失败返回0.如果注册成功。我们就可以利用该类名来创建窗口了。
二、创建窗口
创建窗口就比较简单了。我们只需要调用CreateWindow函数,就可以创建它。用户要注意的是,在这里要了解每个参数的作用。
HWND CreatemdiWndClassWnd(void)
{
HWND hwnd=CreateWindow("MyWndClass","MDI 多文档",//这两个参数,第一个为类名,就是我们前面注册的窗口类名,第二个为窗口标题 。
WS_MINIMIZEBOX|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZEBOX|WS_CAPTION|WS_BORDER|WS_SYSMENU|WS_THICKFRAME,//这里是窗口风格,我们可以在这里指定窗口是否有最大化按钮,是否有标题栏,是否可调整边框等等一些风格
CW_USEDEFAULT,0,CW_USEDEFAULT,0,//这里是指定窗口的坐标和尺寸
NULL,
NULL,
hInst,//实例句柄
NULL);
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
return hwnd;
}
通过上面这个函数,我们已经创建了一个窗口,创建完毕后还不能显示,需要调用ShowWindow()函数窗口就会正常显示出来。
三、窗口过程
窗口过程是我们处理消息的关键。前面我们说过,我们的应用程序的大部分工作都由操作系统完成,我们只要悬在我们感兴趣的事件由我们自己处理即可。在注册窗口类的一节我们看到过了。窗口过程是一个函数,它在注册窗口类的时候被传递。
LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg) {
case WM_CREATE: //这里是窗口创建完毕的消息,每一个窗口创建完毕都会产生次事件
//do something 做我们需要做的工作。完了要break;
break;
case WM_CLOSE: //当用户点击关闭按钮的时候会触发这个事件。
DestroyWindow(hWin);
return TRUE;
case WM_DESTROY:
PostQuitMessage(NULL);
break;
default:
return//我说了。大部分工作由系统处理吧,不感兴趣的消息。统统交给默认窗口过程。
}
return 0;
}
上面的窗口过程很简单吧。窗口过程是一个回调函数,页就是说。它是由操作系统调用的。当我们点击一个鼠标或者按下一个键后,操作系统会将消息发送给前台窗口,应用程序接收到此消息后,会调用对应的窗口过程。这个时候窗口过程被执行。
四、消息循环
消息循环顾名思义,就是循环等待消息的到来。
while (GetMessage (&msg, NULL, 0, 0)) //从消息队列中取消息
{
TranslateMessage (&msg) ; //转换消息
DispatchMessage (&msg) ; //派发消息
}
return msg.wParam;
这里是一个最简单的消息循环了。GetMessage 是从消息队列种取得一条消息,如果消息队列中没有消息,这个函数就等待,直到有消息到达才会返回。当然如果收到WM_QUIT 消息,这个函数会返回假,循环跳出,这个时候就宣告应用程序关闭了。窗口过程中的 PostQuitMessage() 就是发送这个消息。通知退出消息循环。TranslateMessage () 函数的功能是对一些原始消息进行预处理,比如按键消息..DispatchMessage ()函数则是负责分派消息,它会将消息的参数做为调用参数,调用该窗口的窗口过程。