1 一个简单的Windows Hello World程序
- #include <windows.h>
- #include <mmsystem.h>
- LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
- int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
- PSTR szCmdLine, int iCmdShow)
- {
- 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, iCmdShow) ;
- UpdateWindow (hwnd) ;
- while (GetMessage (&msg, NULL, 0, 0))
- {
- TranslateMessage (&msg) ;
- DispatchMessage (&msg) ;
- }
- return msg.wParam ;
- }
- LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- HDC hdc ;
- PAINTSTRUCT ps ;
- RECT rect ;
- switch (message)
- {
- case WM_CREATE:
- PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
- return 0 ;
- case WM_PAINT:
- hdc = BeginPaint (hwnd, &ps) ;
- GetClientRect (hwnd, &rect) ;
- DrawText (hdc, TEXT ("Hello, Windows 98!"), -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) ;
- }
2 Windows程序和控制台程序的区别
入口:
Windows程序的入口为:
- int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
- PSTR szCmdLine, int iCmdShow)
控制台程序的入口为:
- int main()
3 写Windows 程序的基本流程:
写一个程序的每个人都有每个人的风格和方式。如对与本程序:有的人就不喜欢这个写法,他反而更喜欢封装:
他将注册窗口类的过程封装为一个被称为:InitApplication的函数中,将创建窗口,显示窗口,更新窗口的过程封装在一个被称为InitInstance的函数中。他之所以这样写并非故弄玄虚,而是有章可循的。具体原因就牵涉到Windows 3.x时代,窗口类只需注册一次,即可供同一程序的后续每一个实例使用。
下面我们就来看看本程序的流程:
① 声明一个回调函数:
回调函数就是由用户定义,由操作系统来调用的函数。
② 定义主函数:
1 注册窗口类.
窗口类顾名思义就是窗口的类型。即我们首先为我们以后所要创建的窗口定义了一个类型。
2 创建窗口
我们创建的窗口是基于以上窗口类的窗口。
3 显示窗口
窗口被创建后并不能自动显示,需我们调用显示窗口的API来显示窗口。
4 更新窗口
此动作发送WM_PAINT消息
5 消息循环
接收消息,转换消息,分配消息
③ 定义回调函数。
由一个Switch case循环来判断接收到的消息的类型,并做相应的处理。若没有找到则交给默认处理函数去处理。
4 理解消息机制
当我们运行本程序后发现,这个程序与我们平常写的控制台程序或DOS程序不同。该程序若我们不关闭它,它将一直处于运行状态。这里将要引起我们的思考了。是什么能让它一直处于运行状态呢。我们只要回忆一下我们以前写控制台程序的时候,有没有什么结构可以使程序一直运行呢。这里我们自然就想到while循环了。我门找一下程序,它也有一个while循环。
- while (GetMessage (&msg, NULL, 0, 0))
- {
- TranslateMessage (&msg) ;
- DispatchMessage (&msg) ;
- }
确实,也就是这个while循环一直支持着程序的运行。它将一直判断消息队列中是否有消息,若有消息就取出,交给
TranslateMessage (&msg) ;函数进行消息的转换。然后交给 DispatchMessage (&msg) ;函数分发消息,该函数会调用我门的回调函数进行消息类型的判断和做相应的处理。若消息队列中没有消息,则循环一直处于判断状态。
5 理解Windows程序的生与死
① Windows程序调用CreateWindow初始化,为程序创建了一个窗口,产生窗口后,CreateWindow会发出一个WM_CREATE消息直接给窗口函数,后者可以在这里做些初始化的工作。
② 在程序活着的时候,不断的由GetMessage从消息队列中抓取消息,如果这个消息是WM_QUIT,GetMessage就会传回0,while循环条件为假,程序结束。
③ DispatchMessage负责分发消息,把消息分派到窗口函数,并进行相应的处理。
④ 程序将不断的进行②,③的操作。
⑤ 单用户点击系统菜单的Close命令时,系统发出WM_CLOSE消息,该消息有DefWindowsProc处理。DefWindowsProc收到WM_CLOSE消息后,调用DestroyWindow函数来销毁窗口。此后DestroyWindow函数会发出WM_DESTROY消息。
⑥ 窗口函数接到此消息后调用PostQuitMessage函数。这个函数仅仅是发送一个WM_QUIT消息来结束程序,它什么也不做。
注意:在第⑥步时,窗口已经被关闭,此时应用程序还在运行。之后WM_QUIT消息令应用程序结束。