以下是一个创建窗口的一般性代码:
#include "stdafx.h"
#include <windows.h>
#include "mmsystem.h"
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int iCmdShow)
{
// TODO: Place code here.
static TCHAR szAppName[]=TEXT("HelloWin");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style =CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc =WndProc;
wndclass.cbClsExtra =0;
wndclass.cbWndExtra =0;
wndclass.hInstance =hInstance;
wndclass.hIcon =LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor =LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName =NULL;
wndclass.lpszClassName =szAppName;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,TEXT("This program requires Windows NT!"),szAppName,MB_ICONERROR);
return 0;
}
hwnd=CreateWindow(szAppName, //window class name
TEXT("The Hello Program"), //window caption
WS_OVERLAPPEDWINDOW, //window style
CW_USEDEFAULT, //initial x position
CW_USEDEFAULT, //initial y position
CW_USEDEFAULT, //initial x size
CW_USEDEFAULT, //initial y size
NULL, //parent window handle
NULL, //window menu handle
hInstance, //program instance handle
NULL); //creation parameters
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch(message)
{
case WM_LBUTTONDOWN:
MessageBox(NULL,"你单击了鼠标左键!","提示",MB_OK);
case WM_CREATE:
PlaySound(TEXT("ding.wav"),NULL,SND_FILENAME|SND_ASYNC);
return 0;
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rect);
DrawText(hdc,TEXT("你好,沙漠!"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(hwnd,&ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
由于在窗口显示开始就开始播放一个音乐,因此在vc6中 工程->设置->连接->对象/库模块 添加winmm.lib,再在程序中添加#include "mmsystem.h" 。
一、注册窗口类 RegisterClass(&wndclass)
窗口类WNDCLASS wndclass。窗口总是在窗口类的基础上创建的,窗口类用以标识处理窗口消息的窗口过程。在为程序创建窗口之前,必须调用RegisterClass注册一个窗口类。该函数只需要一个参数,即一个指向WNDCLASS的结构指针。此结构包括两个指向字符串的域,此结构在WINUSER.H头文件中国定义了两种不同的方式,第一个是ASCII版的WNDCLASSA和UNICODE版的WNDCLASSW,两个版本唯一的区别在于结构的最后两个域定义为后者指向宽字符串量,前者指向ASCII字符串量。WINUSER.H定义了WNDCLASSA和WNDCLASSW结构(以及指向结构的指针)后,头文件基于对UNICODE标识的解释,定义了WNDCLASS和指向WNDCLASS的指针
#ifdef UNICODE
typedef WNDCLASSW WNDCLASS;
tyepdef PWNDCLASSW PWNDCLASS;
typedef NPWNDCLASSW NPWNDCLASS;
typedef LPWNDCLASSW LPWNDCLASS;
#else
typedef WNDCLASSA WNDCLASS;
tyepdef PWNDCLASSA PWNDCLASS;
typedef NPWNDCLASSA NPWNDCLASS;
typedef LPWNDCLASSA LPWNDCLASS;
#endif
二、创建窗口
窗口类定义了窗口的一般特征,因此可以使用同一窗口类创建许多不同的窗口,调用CreateWindow创建窗口时,可能指定有关窗口的更详细的信息。例如,所有的按钮窗口都可以基于同样的窗口类创建。与这个窗口类相关的窗口过程位于Window内部。由窗口类来负责处理按钮的键盘和鼠标输入,并定义按钮在平米上的外观形象,从这点看,所有的按钮都是以同样的方式工作的。但并非所有按钮都是一样的,他们可以有不同的大小,不同的屏幕位置以及不同的正文串。
三、显示窗口
在CreateWindow调用返回之后,Window内部已经创建了这个窗口。这就是说,Windows已经分配了一块内存给这个窗口用来保存关于在CreateWindow调用中指定窗口的全部信息,再加上Windows在随后所能找到的所有其他信息。然而,窗口并未在视频显示器上出现,这就需要两个调用ShowWindow和UpdateWindow。
四、消息循环
调用UpdateWindow之后,窗口就出现在显示器上。程序现在必须准备读入用户用键盘和鼠标输入的数据。Window为当前运行的每个Windows程序维护一个“消息队列”。在发生输入时间之后,Windows将事件转换为一个“消息”,并将消息放入程序的消息队列中。程序通过执行“消息循环”从消息队列中取出消息:
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
msg变量是MSG结构,在WINUSER.H中有定义。消息循环以GetMessage调用开始,它从消息队列中取出一个消息:GetMessage(&msg,NULL,0,0),这个调用传给Windows一个指向名为msg的MSG结构的指针。第二、三和四个参数设置为NULL和0,表示程序接收它自己创建的所有窗口的所有消息。Windows用从消息队列中取出的下一个消息来填充消息结构的各个域。只要从消息队列中取出消息的message域不为WM_QUIT(其值为0x0012),GetMessage就返回一个非0值,WM_QUIT消息将导致GetMessage返回0.
TranstateMessage(&msg)将msg结构传给Windows,进行一些键盘转换。DispatchMessage(&msg)又将msg结构回传给Windows,然后Windows将该消息发送给适当的窗口过程,让进行处理,即Windows将调用窗口过程(即本代码中的WndPro函数),处理完消息之后,WndPro返回到Windows,此时,Windows还停留在DispatchMessage调用中,在结束DispatchMessage调用的处理之后,Windows回到程序中接着从下一个GetMessage调用开始消息循环。
窗口过程在CreateWindow之后就开始被调用了一次,发送给窗口过程的消息是WM_CREATE。
五、窗口过程
窗口过程确定了再窗口的客户区域中显示些什么以及窗口怎样响应用户输入。程序通常不直接调用窗口过程。窗口过程通常由Window本身调用,通过调用SendMessage函数,程序能够直接调用它自己的窗口过程。
六、处理消息
一般来说,Windows程序员使用switch和case结构来确定窗口过程接收的是什么消息以及如何适当地处理它。窗口过程在处理消息时,必须返回0.窗口过程不予处理的所有消息应该被传给名为DefWindowProc的Window函数。从DefWindowProc返回的值必须由窗口过程返回。