回 帖 发 新 帖 刷新版面

主题:[讨论]一个很郁闷的问题

[code=c]
请填写代码
//请帮我看看下面一段程序
#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK WindowxProc(
                            HWND hwnd,      // handle to window
                            UINT uMsg,      // message identifier
                            WPARAM wParam,  // first message parameter
                            LPARAM lParam   // second message parameter
                            );


int WINAPI WinMain(
                   HINSTANCE hInstance,      // handle to current instance
                   HINSTANCE hPrevInstance,  // handle to previous instance
                   LPSTR lpCmdLine,          // command line
                   int nCmdShow              // show state
                   )
{
    WNDCLASS wncls;
    wncls.cbClsExtra=0;
    wncls.cbWndExtra=0;
    wncls.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
    wncls.hCursor=LoadCursor(NULL,IDC_ARROW);
    wncls.hIcon=LoadIcon(NULL,IDI_ERROR);
    wncls.hInstance=hInstance;
    wncls.lpfnWndProc=WindowxProc;
    wncls.lpszClassName="xiaohei";
    wncls.lpszMenuName=NULL;
    wncls.style=CS_HREDRAW|CS_VREDRAW;

    RegisterClass(&wncls);

    HWND hwnd;
    hwnd=CreateWindow("xiaohei","威信",WS_OVERLAPPEDWINDOW,
        20,50,600,300,NULL,NULL,hInstance,NULL);
    ShowWindow(hwnd,SW_NORMAL);
    UpdateWindow(hwnd);

    MSG msg;   
    while (GetMessage(&msg,hwnd,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}
LRESULT CALLBACK WindowxProc(
                            HWND hwnd,      // handle to window
                            UINT uMsg,      // message identifier
                            WPARAM wParam,  // first message parameter
                            LPARAM lParam   // second message parameter
                            )
{
    switch (uMsg)
    {
    case WM_CHAR:
        
        char szchar[20];
        sprintf(szchar,"the chars is %d",wParam);
        MessageBox(hwnd,szchar,"键盘消息!",NULL);
        break;
    case WM_LBUTTONDOWN:
        HDC hdc;
        MessageBox(hwnd,"鼠标按下","xiaohei123",NULL);
        hdc=GetDC(hwnd);
           TextOut(hdc,60,150,"小河向东流!",strlen("小河向东流!"));
        ReleaseDC(hwnd,hdc);
        break;
        
    case WM_RBUTTONDOWN:
                 MessageBox(hwnd,"右键按下!","xiaohei123",0);
         hdc=GetDC(hwnd);
        TextOut(hdc,100,250,"你好呀!",strlen("你好呀!"));
        ReleaseDC(hwnd,hdc);
        break;
    case WM_PAINT:
        
        PAINTSTRUCT ps;
        hdc=BeginPaint(hwnd,&ps);
        TextOut(hdc,100,200,"小黑来了!",strlen("小黑来了!"));
        EndPaint(hwnd,&ps); 
        break;
    case WM_CLOSE:
        if (IDYES==MessageBox(hwnd,"是否要关闭窗口?","xiaohei123",MB_YESNO))
        {
           DestroyWindow(hwnd);
          
        }
        break;
    case WM_DESTROY:
         PostQuitMessage(0);
          break;
    
   default:
        return DefWindowProc(hwnd,uMsg,wParam,lParam);
    }
    return 0;
}
//在编译和链接以及运行的时候没啥问题,就是是关闭了窗口,
这个程序的进程仍然没有关闭,请问是怎么回事呀?



[/code][code=c]
请填写代码
[/code][code=c]
请填写代码
[/code]

回复列表 (共8个回复)

沙发

DestroyWindow(hwnd);
这个你看下MSDN

可以用
              exit(1);
不过要加头文件
            stdlib.h

板凳

你调用   DestroyWindow(hwnd);后就不会进一步发送WM_DESTROY消息了,因为窗口已经销毁了。正确的做法是直接在WM_CLOSE消息中调用::PostQuitMessage(0)

3 楼

上面两位的说法都有待商榷,调用DestroyWindow(hwnd)后窗口确实是销毁了,但肯定要发送WM_DESTROY消息的,你可以跟踪调试一下,你这里可以修改消息循环如下
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
理由:调用DestroyWindow(hwnd)后发出的WM_DESTROY因为窗口销毁了,无法通过hwnd被GetMessage获得。改成NULL后GetMessage则可以取到属于这个线程的所有消息,因而能顺得取到WM_DESTROY以结束消息循环。以下是MSDN关于GetMessage的部分内容,请注意hwnd为NULL的有关解释。
GetMessage Function

--------------------------------------------------------------------------------

The GetMessage function retrieves a message from the calling thread's message queue. The function dispatches incoming sent messages until a posted message is available for retrieval. 

Unlike GetMessage, the PeekMessage function does not wait for a message to be posted before returning.


Syntax

BOOL GetMessage(          LPMSG lpMsg,
    HWND hWnd,
    UINT wMsgFilterMin,
    UINT wMsgFilterMax
);
Parameters

lpMsg
[out] Pointer to an MSG structure that receives message information from the thread's message queue.
hWnd
[in] Handle to the window whose messages are to be retrieved. The window must belong to the current thread. 
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.

If hWnd is -1, GetMessage retrieves only messages on the current thread's message queue whose hwnd value is NULL, that is, thread messages as posted by PostMessage (when the hWnd parameter is NULL) or PostThreadMessage.

4 楼

傻子都知道窗口销毁的时候要不要发送WM_DESTROY消息

5 楼

在DestroyWindow(hwnd);和PostQuitMessage(0);两处各设一个断点,如果调用DestroyWindow结束后不立即运行到PostQuitMessage(0);,本人就承认调用DestroyWindow后不发送WM_DESTROY消息及坦承愚笨,否则请聪明人给出一个解释。另外聪明人不上机调试程序的吗?
还是MSDN的内容。
DestroyWindow Function
--------------------------------------------------------------------------------
The DestroyWindow function destroys the specified window. The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it. The function also destroys the window's menu, flushes the thread message queue, destroys timers, removes clipboard ownership, and breaks the clipboard viewer chain (if the window is at the top of the viewer chain).
If the specified window is a parent or owner window, DestroyWindow automatically destroys the associated child or owned windows when it destroys the parent or owner window. The function first destroys child or owned windows, and then it destroys the parent or owner window.

6 楼

聪明人呢?

7 楼


我们在论坛上,最好不要说一些伤人的话,
毕竟我们来这里的目的是探讨问题的,而不是
吵斗的。要以和为贵呀!这样才能把问题解决呀!

8 楼

如果我的一句"有待商榷"伤人的话,我一百个道歉,当然是如果成立.另外呢,既然被认定为傻子,那总得证明给本人看啊,这对聪明人来说应该是很轻松的吧?
也希望xiaohei2或别的朋友是不是可以按咱这傻子说的调试运行一下?也当咱在这请教了.当然咱要是不对,恳请批评指正.

我来回复

您尚未登录,请登录后再回复。点此登录或注册