while((iRet = GetMessage(&msg, hWnd, 0, 0)) != 0 && iRet != -1)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND:
if(wParam == ID_40001)
quit(hWnd);
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}void quit(HWND hWnd)
{
if(IDOK == MessageBox(hWnd, _T("确定要退出吗?"), _T("提示"), MB_OKCANCEL|MB_ICONQUESTION))
{
//SendMessage(hWnd, WM_QUIT, 0, 0);
PostQuitMessage(0);
MessageBox(hWnd, _T("消息发出了"), _T("提示"), MB_OK);
}
}问题是quit()函数。
我要是只发送消息,或者MessageBox在发送消息前,程序就不会退出。 只有把MessageBox放到发送消息后才行。而且只能使用PostQuitMessage, sendmessage不行。纠结这个顺序,另外我总不能再后便写个对话框吧。也不会显示出来。

解决方案 »

  1.   

    而且只能使用PostQuitMessage, sendmessage不行。
    ========
    WM_QUIT本来就不能用SendMessage而是用PostQuitMessage或者MessageBox在发送消息前,程序就不会退出。 只有把MessageBox放到发送消息后才行
    =================
    MessageBox在关闭之后应该就可以了吧
      

  2.   

    我在解释一下quit函数
    其中的if判断是用户现则是否退出,如果点“是”一定会进入if体,因为if中的messagebox会显示出来。
    但是这个messagebox如果放到postquitmessage前程序不能退出,如果放到postquitmessage之后就会退出。
      

  3.   

    if中的MessageBox退出之后关闭之后程序也不能退出,如果是这个MessageBox放到PostQuitMessage之前。
      

  4.   

    while((iRet = GetMessage(&msg, hWnd, 0, 0)) != 0 && iRet != -1)
    -->
    while(GetMessage(&msg, NULL, 0, 0))
      

  5.   

    WM_QUIT消息永远不会进入你的窗口过程函数中,所以不能使用SendMessage来发送WM_QUIT消息
      

  6.   


    void quit(HWND hWnd)
    {
    if(IDOK == MessageBox(hWnd, _T("确定要退出吗?"), _T("提示"), MB_OKCANCEL|MB_ICONQUESTION))
    {
    MessageBox(hWnd, _T("消息发出前"), _T("提示"), MB_OK); // MsgBox A
    PostQuitMessage(0);
    MessageBox(hWnd, _T("消息发出后"), _T("提示"), MB_OK); // MsgBox B
    }
    }如此, 看下注释。  MsgBoxA那行有没有对不会影响程序退出,MsgBoxB存在程序才能退出。 
    试过将MsgBoxB这样换成别的操作(试过给变量赋值),不行。 必须是个MessageBox,更多的没试。
    纠结的是不管有没有msgbox ,PostQuitMessage肯定是执行了,为什么会出现这种问题。
      

  7.   


    MSDN中不推荐你这种方法。
    [Qoute=引用MSDN]
    //Warning  
    Because the return value can be nonzero, zero, or -1, avoid code like this:while (GetMessage( lpMsg, hWnd, 0, 0)) ...
    The possibility of a -1 return value means that such code can lead to fatal application errors. Instead, use code like this://Hide ExampleBOOL bRet;while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)

        if (bRet == -1)
        {
            // handle the error and possibly exit
        }
        else
        {
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        }
    }
    [/Qoute]
      

  8.   


    我就想if体中只postquitmessage,但是不顶用,如果postquitmessage后没有messagebox,就不能退出程序。
      

  9.   


    Warning  
    Because the return value can be nonzero, zero, or -1, avoid code like this:

    while (GetMessage( lpMsg, hWnd, 0, 0)) ...
    The possibility of a -1 return value means that such code can lead to fatal application errors. Instead, use code like this:Hide ExampleBOOL bRet;while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)

        if (bRet == -1)
        {
            // handle the error and possibly exit
        }
        else
        {
            TranslateMessage(&msg); 
            DispatchMessage(&msg); 
        }
    }

      

  10.   

    不要管那个while了,各种我已经都用过了,应该不是这里的问题。
      

  11.   

    while(GetMessage(&msg, NULL, 0, 0))
    请注意,GetMessage的第二个参数是NULL
      

  12.   

    以下是全部代码,修改的地方就是消息循环 hWnd->NULL#include "main.h"
    #include "windows.h"
    #include "tchar.h"
    #include "resource.h"int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
    {
    int iRet;
    HWND hWnd;
    MSG msg;
    //注册窗口类
    WNDCLASS wc;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC)MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
    wc.hCursor = LoadCursor(hInstance, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;  ///(HBRUSH)GetStockObject();
    wc.lpszClassName = TEXT("SDK_WINDOW");
    wc.lpszMenuName = NULL;
    iRet = RegisterClass(&wc);
    if(0 == iRet)
    {
    MessageBox(0, TEXT("注册窗口类失败"), TEXT("SDK程序"), MB_ICONERROR);
    exit(-1);
    }
    hWnd = CreateWindowW(
    wc.lpszClassName,
    TEXT("SDK 程序"),
    WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
    CW_USEDEFAULT, CW_USEDEFAULT,
    CW_USEDEFAULT, CW_USEDEFAULT,
    NULL, LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1)), hInstance, NULL
    );
    ShowWindow(hWnd, nShowCmd);
    UpdateWindow(hWnd);

    //while((iRet = GetMessage(&msg, hWnd, 0, 0)) != 0 && iRet != -1) //有问题的情况
    while(GetMessage(&msg, NULL, 0, 0) != 0) //使用NULL后没问题。
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    return (int)msg.wParam;
    }LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
    switch(uMsg)
    {
    case WM_CLOSE:
    DestroyWindow(hWnd);
    break;
    case WM_DESTROY:
    PostQuitMessage(0);
    break;
    case WM_COMMAND:
    if(wParam == ID_40001)
    quit(hWnd);
    break;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }void quit(HWND hWnd)
    {
    if(IDOK == MessageBox(hWnd, _T("确定要退出吗?"), _T("提示"), MB_OKCANCEL|MB_ICONQUESTION))
    {
    PostQuitMessage(0);
    }
    }
      

  13.   

    NULL和hWnd的区别是什么? GetMessage的这个参数如何确定? MSDN没看明白。
      

  14.   

    If hWnd is NULL, GetMessage retrieves messages for any window that belongs to the current thread, and any messages on the current thread's message queue whose hwnd value is NULL (see the MSG structure). Therefore if hWnd is NULL, both window messages and thread messages are processed.
      

  15.   

    那WM_QUIT输入Window Message还是Thread message?
      

  16.   

    当你用GetMessage(&msg,hwnd,NULL,NULL)时,在窗口关闭之后,hwnd参数已经失效了,此时GetMessage由于hwnd参数失效而失败,返回FALSE,所以while不能返回,你的进程就退不出去。
      

  17.   

    PostQuitMessage是一个Thread message,它没有窗口句柄做参数。
    看来PostQuitMessage后再弹出一个MessageBOx,QuitMessage是被MessageBox的消息循环处理了。