+ -
当前位置:首页 → 问答吧 → 父窗口 和 子窗口 间的消息??

父窗口 和 子窗口 间的消息??

时间:2011-12-19

来源:互联网

RT
我想实现 这样一个程序:
一个程序里面有 两个窗口 ,每个窗口都有一个线程来处理窗口消息。

过程是这样的:
在主线程里创建 窗口A ,
然后创建一个子线程,在子线程里面 窗口B 并处理 窗口B 的消息。

然后我做了这样一个对比测试操作:
情况1)、开始运行程序 ,在 窗口B 里面进行死循环,这个时候 ,窗口A 仍然很自如的处理着自己的消息。
情况2)、重新开始运行程序 ,然后先“::SetParent(窗口B的HWND, 窗口A的HWND);”再在 窗口B 里面执行死循环。--> 此时 ,窗口A 居然出现反白现象(程序卡住了,停止处理消息了)...

问题:
我在想,窗口A、B不都有自己的线程来处理消息的吗 ? 为什么 情况2 里面的 窗口A 会反白??
他们之间有什么交流的吗??(才出现 情况2 的现象)?

请指教~~

ps :我的测试代码放在 1楼 ,比较短,大家帮看看啊~~

作者: okmnjizc   发布时间: 2011-12-19

C/C++ code

#include <windows.h>

HINSTANCE    g_hInstance = 0;
HWND        g_hWnd1 = 0;
HWND        g_hWnd2 = 0;

////////////   ////////////   ////////////   ////////////   ////////////   ////////////

// 子窗口 消息处理
LRESULT CALLBACK WndProc2(
    HWND _hWnd,
    UINT _uMsg,
    WPARAM _wParam,
    LPARAM _lParam)
{
    switch (_uMsg)
    {
    case WM_CHAR:
        {
            if (_wParam == 98)
            {
                ::MessageBox(0, "B 键", "", 0);
            }
            return 0;
        }
    case WM_RBUTTONUP: // 开始 死循环
        {
            ::MessageBox(0, "WM_RBUTTONUP", "", 0);
            while (true)
            {}
            return 0;
        }
    case WM_DESTROY:
        {
            DestroyWindow(_hWnd);
            PostQuitMessage(0);
            return 0;    
        }
    }
    return DefWindowProc(_hWnd, _uMsg, _wParam, _lParam);
}

// 创建 窗口
HWND CreateWnd(WNDPROC _pProc, char* _pcClassName,
               int _x,int _y, int _iWidth, int _iHeight)
{
    WNDCLASS wndcls = {0};
    wndcls.style        = CS_HREDRAW | CS_VREDRAW;
    wndcls.lpfnWndProc    = _pProc;
    wndcls.cbClsExtra    = 0;
    wndcls.cbWndExtra    = 0;
    wndcls.hInstance    = g_hInstance;
    wndcls.hIcon        = LoadIcon(NULL, IDI_ERROR);
    wndcls.hCursor        = LoadCursor(NULL, IDC_CROSS);
    wndcls.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndcls.lpszMenuName = NULL;
    wndcls.lpszClassName= _pcClassName;
// 注册窗口类
    RegisterClass(&wndcls);

    HWND hWnd = CreateWindowEx(
        WS_EX_NOPARENTNOTIFY, //WS_EX_CLIENTEDGE,
        wndcls.lpszClassName,
        _pcClassName,
        WS_OVERLAPPEDWINDOW,
        _x, _y,
        _iWidth, _iHeight,
        NULL,
        NULL,
        g_hInstance,
        NULL);

    ShowWindow(hWnd, SW_SHOWNORMAL);
    UpdateWindow(hWnd);

    return hWnd;
}

// 子线程 用于创建子窗口
DWORD WINAPI ThreadCreateWnd(LPVOID pArg)  
{
    // 创建 子窗口
    g_hWnd2 = CreateWnd(WndProc2, "Son Window", 0, 50, 200, 100);
  
    MSG msg;  
    while(GetMessage(&msg,NULL,0,0))  
    {  
        TranslateMessage(&msg);  
        DispatchMessage(&msg);  
    }  

    ::MessageBox(0, "Son Window over", "", 0);
    return 0;  
}

// 父窗口 消息处理
LRESULT CALLBACK WndProc1(
    HWND _hWnd,
    UINT _uMsg,
    WPARAM _wParam,
    LPARAM _lParam)
{
    switch (_uMsg)
    {
    case WM_RBUTTONUP:
        {
            ::SetParent(g_hWnd2, g_hWnd1);
            return DefWindowProc(_hWnd, _uMsg, _wParam, _lParam);
        }
    case WM_CHAR:
        {
            if (_wParam == 13) // 回车键 创建子线程
            {
                ::MessageBox(0, "Enter", "", 0);
                CreateThread(NULL, NULL, ThreadCreateWnd, false, false, NULL); 
            }
            else if (_wParam == 97)
            {
                ::MessageBox(0, "A 键", "", 0);
            }
            return DefWindowProc(_hWnd, _uMsg, _wParam, _lParam);
        }
    case WM_DESTROY:
        {
            DestroyWindow(_hWnd);
            PostQuitMessage(0);
            return 0;    
        }
    }
    return DefWindowProc(_hWnd, _uMsg, _wParam, _lParam);
}

// <<<<< <<<<<

int WINAPI WinMain(
    HINSTANCE _hInstance,
    HINSTANCE _hPrevInstance,
    LPSTR _lpCmdLine,
    int _nCmdShow
)
{
    g_hInstance = _hInstance;

    //创建 主窗口
    g_hWnd1 = CreateWnd(WndProc1, "Parent Window", 200, 0, 500, 300); 

    MSG msg;
    while(GetMessage(&msg, 0, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

作者: okmnjizc   发布时间: 2011-12-19

A会卡死??应该不会吧,试了一下,A仍然可以有事件响应的

作者: VisualEleven   发布时间: 2011-12-19

一个进程好像只有一个消息队列

作者: onlycs   发布时间: 2011-12-19

我也试了下,A还是有事件响应的啊,LZ是不是搞错了啊???

作者: calm_keep   发布时间: 2011-12-19

引用 2 楼 visualeleven 的回复:
A会卡死??应该不会吧,试了一下,A仍然可以有事件响应的

引用 4 楼 calm_keep 的回复:
我也试了下,A还是有事件响应的啊,LZ是不是搞错了啊???

楼上两位,不是吧,情况2 设置了 SetParent 后,再子窗口死循环, 父窗口 仍然 按键盘a键 有“A 键”显示出来?? 我怎么没有??

作者: okmnjizc   发布时间: 2011-12-19

我的操作顺序是:
运行程序-->主窗口按下 回车键 ,创建子线程子窗口-->右键主窗口 执行SetParent操作-->右键子窗口,执行死循环-->此时,再按 主窗口键盘a键,没有MessageBox弹出

作者: okmnjizc   发布时间: 2011-12-19