D语言中国主页  D语言编辑器SciTE4D   DWin库 D语言官方网站
D语言编译器1.x最新版 OpenSource   Tango   webnews  Wiki

查看完整版本: 白手起家Win32SDK应用程序8 关闭窗口的同时退出程序

yidabu 2007-5-6 07:34

白手起家Win32SDK应用程序8 关闭窗口的同时退出程序

白手起家Win32SDK应用程序8 关闭窗口的同时退出程序知识若不分享 实在没有意义 http://www.d-programming-language-china.org 20070506点击下面网址查看原文:http://www.d-programming-language-china.org        by:        白云小飞        D语言论坛 http://www.d-programming-language-china.org 增加D语言实例教程        还记得上篇中最后说到一个问题吗?当我们关闭程序窗口时,窗口确实是关闭了,可是程序并没有退出啊。为什么呢???理解程序的退出条件        首先,我们要先明白程序退出的条件,看上篇中的这段代码:        QUOTE:                                while(GetMessage(&msg, NULL, 0, 0)) //获取一个消息,成功后会放在msg中。                {                    TranslateMessage(&msg); //消息进行必要的预处理转换。                    DispatchMessage(&msg); //调用WinProc回调函数,将msg传递给WinProc函数                }                如果程序一直在这个消息循环中,程序就没能退出。只有当GetMessage收到一个WM_QUIT的消息,则返回值才会为零,退出循环,程序得以结束。(这个道理应该好理解吧?)点关闭按钮时,发生了什么        当我们点窗口右上角的关闭按钮时,到底发生了什么事呢?(请边看源代码,边体会下面的分析噢!)        第一. 它并没有(或最终没有导致)发出WM_QUIT的消息。因此GetMessage函数不会收到WM_QUIT消息,就没法跳出循环了。(那么又产生了什么消息呢?)        第二. 点关闭按钮时,产生WM_CLOSE的消息。GetMessage会收到WM_CLOSE消息的MSG结构信息。        第三. 按前篇所述的消息处理流程可知:DespatchMessage会调用WinProc回调函数,并把WM_CLOSE消息的相关信息传递给WinProc函数参数中。        第四. 现在我们的WinProc里只有一句:        QUOTE:                                LRESULT CALLBACK WinProc(HWND hwnd,                                     UINT msg,                                     WPARAM wparam,                                     LPARAM lparam)                {                    //这里可以添加你的消息处理代码                    return DefWindowProc(hwnd, msg, wparam, lparam);                }                它将WM_CLOSE继续传递给缺省窗口过程函数DefWindowProc。        第五. 在DefWindowProc函数里,判断是WM_CLOSE消息后,就会对参数hwnd所代表的窗口进行销毁。(看吧,销毁窗口的事也是由DefWindowProc来完成了。)        第六. 成功销毁窗口后,DefWindowProc里接着还会发一个WM_DESTROY的消息到消息队列中(表示说窗口已经被销毁了)。然后DefWindowProc函数才结束。        第七. 回到我们的消息循环的GetMessage函数。这个函数又会获得WM_DESTROY消息的信息,开始了下一个消息处理过程。        第八. 这个WM_DESTROY可在WinProc函数中由我们处理。但在WinProc函数体的代码中我们没有自己去处理它。仍然是让DefWindowProc去处理。        第九. 然而,DefWindowProc只是简单地把它给“扔掉”了。        第十. 整个点窗口右上角的关闭按钮作所的所有动作就这样完成了。        你看,上述中,上述程序始终没有产生WM_QUIT的消息,所以窗口确实是销毁了,但程序并没有退出这个消息处理循环。        哦,怪不得我们的程序没法结束了。(那该怎么办呢?)如何使程序结束        退出程序的三点说明:        1. 我们希望是通过单击这个窗口右上角的关闭按钮时来退出程序。        2. 应该在窗口成功销毁后,才让程序退出。        3. 只要让程序产生一个WM_QUIT消息,就可以退出循环而结束程序。        终上所述,程序应在收到WM_DESTROY消息后才能退出程序。因为WM_DESTROY消息表示窗口已经销毁。        那么我们又如何才能产生一个WM_QUIT的消息呢?用下面这个--API函数:( 本文出处: http://www.d-programming-language-china.org )        QUOTE:                                PostQuitMessage(0);                参数代入0值就可。它将产生一个WM_QUIT消息。WM_QUIT消息最终会被GetMessage函数“摘取”到并返回0值。从而退出循环,结束程序。看我实现代码:        QUOTE:                                LRESULT CALLBACK WinProc(HWND hwnd,                                     UINT msg,                                     WPARAM wparam,                                     LPARAM lparam)                {                    switch (msg)    //msg中保存的就是正要处理的消息                    {                        case WM_DESTROY:    //这是我们自行处理的第一个消息                        {                            PostQuitMessage(0);    //发出一个WM_QUIT消息                            return 0;    //然后直接返回。                        }break;                    default:break;                    }                    return DefWindowProc(hwnd, msg, wparam, lparam);                }                                int WINAPI WinMain(HINSTANCE hinstance,                             HINSTANCE hprevinstance,                             LPSTR lpcmdline,                             int ncmdshow)                {                    HWND hWnd;                    MSG msg;                    WNDCLASSEX wndclass;                    //……    这里省略了前面所述的注册窗口类的过程                    //                    hWnd=CreateWindowEx(NULL,WND_CLS_NAME,                                "这是我的第一个窗口",                                WS_OVERLAPPEDWINDOW|WS_VISIBLE ,                                CW_USEDEFAULT, 0,                                400,400,                                NULL,                                NULL,                                hinstance,                                NULL );                    if (!hWnd)                        return 0;                                    ShowWindow(hWnd, ncmdshow);                                    while(GetMessage(&msg, NULL, 0, 0))                    {                        TranslateMessage(&msg);                        DispatchMessage(&msg);                    }                    return 0;                }                D语言论坛 http://www.d-programming-language-china.org 按:        写成D语言代码是这样的:        [Copy to clipboard] [ - ]CODE:                                extern (Windows):                LRESULT WinProc(HWND hwnd,                                     UINT msg,                                     WPARAM wparam,                                     LPARAM lparam)                {                    switch (msg)    //msg中保存的就是正要处理的消息                    {                        case WM_DESTROY:    //这是我们自行处理的第一个消息                        {                            PostQuitMessage(0);    //发出一个WM_QUIT消息                            return 0;    //然后直接返回。                        }                        default:                            return (DefWindowProc(hwnd, msg, wparam, lparam));                    }                                }                                extern (Windows):                int WinMain(HINSTANCE hinstance,                             HINSTANCE hprevinstance,                             LPSTR lpcmdline,                             int ncmdshow)                {                    HWND hWnd;                    MSG msg;                    WNDCLASSEX wndclass;                    //……    这里省略了前面所述的注册窗口类的过程                    //                    hWnd=CreateWindowEx(NULL,WND_CLS_NAME,                                "一大步成功社区 http://bbs.d-programming-language-china.org ",                                WS_OVERLAPPEDWINDOW|WS_VISIBLE ,                                CW_USEDEFAULT, 0,                                400,400,                                null,                                null,                                hinstance,                                null );                    if (!hWnd)                        return 0;                                    ShowWindow(hWnd, ncmdshow);                                    while(GetMessage(&msg, null, 0, 0))                    {                        TranslateMessage(&msg);                        DispatchMessage(&msg);                    }                    return 0;                }                WinProc函数参数中的UINT msg就是程序传递进来的消息标识。我们只要判断msg是否为WM_DESTROY消息,如果是就发一个WM_QUIT消息。        补充说明一点:        WinProc函数参数中有一个msg变量,而WinMain函数中也定义了一个msg。不要把它们给混了啊!它们可是不同的变量啊!WinMain中定义的msg类型是MSG,在Winuser.h中已定义如下:        QUOTE:                                typedef struct tagMSG {                HWND    hwnd;                UINT    message;                WPARAM    wParam;                LPARAM    lParam;                DWORD    time;                POINT    pt;                } MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;                你看,它是一个结构体。而WinProc参数中的msg是一个UINT类型,它其实只是WinProc函数里的msg结构成员message的值。        你看看DispatchMessage(&msg);是如何传递这个msg给WinProc的:        它在调用WinProc时,会——        将msg.hwnd值传递给WinProc参数中的HWND hwnd;        将msg.message值传递给WinProc参数中的UINT msg;        将msg.wParam传递给WinProc参数中的WPARAM wParam;        将msg.lParam值传递给WinProc参数中的LPARAM lParam。        整个程序实现退出的流程还是让你自行去分析啦!应该不会太难吧!?        至此,终于完成了这个SDK程序的基本框架了!(哈,真值得我们去举杯庆祝啦!不过,我的任务还没完啊!还有许多要解决的问题等着我噢!)。( lastupdate:20070506 最新文章请访问http://www.d-programming-language-china.org )关于一大步成功社区:yidabu提倡在交流中学习,在分享中提高收集感兴趣的知识,写下心得,通过网络与别人一起分享理解一点就实践一步,收获什么就分享什么,成功就是这样一点点一步步累积起来的网络只是一个工具,只有自己身心提高才是实实在在的。d-programming-language-china.org为大家提供一个学习交流各种知识的平台
页: [1]
查看完整版本: 白手起家Win32SDK应用程序8 关闭窗口的同时退出程序