zoukankan      html  css  js  c++  java
  • 【Demo 0050】消息窗体

    本例练习消息窗体的实现以及消息窗体收发消息;  对消息窗体的定义MSDN里描述大体是这样的, 父窗体指定为HWND_MESSAGE常量,它可以收发消息,没z-order, 不可遍历且不无能接收到广播消息仅做简单的消息分发; 我们可以在创建窗体时指定其父窗体为HWND_MESSAGE常量也可以将现有窗体通过SetParent将父窗体设为HWND_MESSAGE常量从而达到变成消息窗体的目的;

    查找消息窗体句柄, 可以通过FindWindowEx这个函数将其hParent设为HWND_MESSAGE, 并指定类名或窗体名即可找到;

    一、代码演示(为了方便演示提供了二个工程分别为Demo0050 – 实现消息窗体创建以及接受消息和发送消息;  Demo0050Ex – 实现消息的发送以及广播消息的接收

         1.  创建消息窗体(Demo0050)


    //////////////////////////////////////////////////////////////////////////
    HWND CreateWnd(const TCHAR* szClsName, const TCHAR* szWndCaption, HWND hParent = NULL,
                   DWORD dwStyle = WS_POPUP|WS_VISIBLE|WS_SYSMENU|WS_CAPTION,
                   DWORD dwStyleEx = 0)
    {
        if (NULL != szClsName)
        {
            HWND hWnd = CreateWindowEx(dwStyleEx, szClsName, szWndCaption, dwStyle,
                                       0, 0, 800, 480, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
        
            if (NULL != hWnd && IsWindow(hWnd))
            {
                return hWnd;
            }
        }
        return NULL;
    }

         2.  查找消息窗体并发送消息(Demo0050Ex)

        

    HWND hMsgWnd = FindWindowEx(HWND_MESSAGE, NULL, _T("Win32App"), NULL);
    for (int ii = 0; ii < sizeof(CtrlsInfo) / sizeof(*CtrlsInfo); ii++)
    {
        if (wParam == CtrlsInfo[ii].m_ID)
        {
            CtrlsInfo[ii].m_fnProc(hMsgWnd, hWnd);
            
            break;
        }
    }

         列举了自定义消息(WM_UMSG_DATA),系统默认消息(WM_QUIT),  广播消息(WM_UMSG_BROADCAST、WM_UMSG_MSGWNDCREATED) 以及WM_COPYDATA消息

    const UINT  WM_UMSG_DATA            = (WM_APP + 1001);
    const UINT    WM_UMSG_REGISTER        = RegisterWindowMessage(_T("Register_MSG"));
    const UINT    WM_UMSG_BROADCAST        = RegisterWindowMessage(_T("BroadCast_MSG"));
    const UINT    WM_UMSG_MSGWNDCREATED    = RegisterWindowMessage(_T("MSGWndCreated_MSG"));

    typedef void (*FUNPROC)(HWND hWnd, HWND hSender);
    struct TCtrlInfo {
        TCHAR        m_szClsName[32];
        TCHAR        m_szText[64];
        UINT        m_ID;
        FUNPROC        m_fnProc;
    };

    void  OnSendUserMsg(HWND hWnd, HWND hSender)
    {
        PostMessage(hWnd, WM_UMSG_DATA, 100, 110);
        
        return;
    }

    void  OnSendRegisterMsg(HWND hWnd, HWND hSender)
    {
        PostMessage(hWnd, WM_UMSG_REGISTER, 200, 220);

        return;
    }
    void  OnSendBroadcastMsg(HWND hWnd, HWND hSender)
    {
        PostMessage(HWND_BROADCAST, WM_UMSG_BROADCAST, 300, 330);

        return;
    }

    void  OnSendCopyDataMsg(HWND hWnd, HWND hSender)
    {
        struct TPerson {
            UINT    m_nAge;
            TCHAR    m_szName[64];
        };
        
        TPerson Person = { 25, _T("Greg.Yi") };
        COPYDATASTRUCT cds;
        cds.dwData    = 1;
        cds.cbData    = sizeof(Person);
        cds.lpData    = &Person;

        SendMessage(hWnd, WM_COPYDATA, (WPARAM)hSender, (LPARAM)&cds);

        return;
    }

    void  OnSendExitMsg(HWND hWnd, HWND hSender)
    {
        PostMessage(hWnd, WM_CLOSE, 0, 0);

        return;
    }

       

         3.   接收消息( Demo0050,  Demo0050Ex)

         a. Demo0050 消息处理


    const UINT  WM_UMSG_DATA            = (WM_APP + 1001);
    const UINT    WM_UMSG_REGISTER        = RegisterWindowMessage(_T("Register_MSG"));
    const UINT    WM_UMSG_BROADCAST        = RegisterWindowMessage(_T("BroadCast_MSG"));
    const UINT    WM_UMSG_MSGWNDCREATED    = RegisterWindowMessage(_T("MSGWndCreated_MSG"));

    struct TPerson {
        UINT    m_nAge;
        TCHAR    m_szName[64];
    };

    LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
    {    
        switch (nMsg)
        {
            case WM_CREATE:
            {
                MessageBox(hWnd, _T("Message Reciver(Demo0050) Launched!"), _T("Demo0050"), MB_OK);
                PostMessage(HWND_BROADCAST, WM_UMSG_MSGWNDCREATED, 0, 0);
                break;
            }
            case WM_COPYDATA:        
            {
                COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lParam;
                TPerson* pPerson = (TPerson*)cds->lpData;

                TCHAR szTmp[129];
                _stprintf(szTmp, _T("Demo0050 Received a CopyData Messaged -- age: %d name: %s"), pPerson->m_nAge, (LPTSTR)pPerson->m_szName);
                MessageBox(NULL, szTmp, _T("Demo0050"), MB_OK);

                break;
            }
            case WM_UMSG_DATA:        
            {
                TCHAR szTmp[129];
                _stprintf(szTmp, _T("Demo0050 Received a User Messaged -- wParam: %d lParam: %d"), wParam, (LPTSTR)lParam);
                MessageBox(NULL, szTmp, _T("Demo0050"), MB_OK);
                break;
            }
            case WM_CLOSE:
            {
                SendMessage(HWND_BROADCAST, WM_UMSG_MSGWNDCREATED, 0, 1);
                PostQuitMessage(0);
                break;
            }
        }

        if (WM_UMSG_REGISTER == nMsg)
        {
            TCHAR szTmp[129];
            _stprintf(szTmp, _T("Demo0050 Received a Register Message -- wParam: %d lParam: %d"), wParam, (LPTSTR)lParam);
            MessageBox(NULL, szTmp, _T("Demo0050"), MB_OK);
        } else if (WM_UMSG_BROADCAST == nMsg) {
            TCHAR szTmp[129];
            _stprintf(szTmp, _T("Demo0050 Received a Broadcast Message -- wParam: %d lParam: %d"), wParam, (LPTSTR)lParam);
            MessageBox(NULL, szTmp, _T("Demo0050"), MB_OK);
        }
        
        return ::DefWindowProc(hWnd, nMsg, wParam, lParam);
    }

         b.  Demo0050Ex 消息处理


    if (WM_UMSG_BROADCAST == nMsg)
    {
        TCHAR szTmp[129];
        _stprintf(szTmp, _T("Demo0050Ex Broadcast Message -- wParam: %d lParam: %d"), wParam, (LPTSTR)lParam);
        MessageBox(NULL, szTmp, _T("Demo0050Ex"), MB_OK);
    } else if (WM_UMSG_MSGWNDCREATED == nMsg) {
        HWND hMsgWnd = FindWindowEx(HWND_MESSAGE, NULL, _T("Win32App"), NULL);
        for (int ii = 0; ii < sizeof(CtrlsInfo) / sizeof(*CtrlsInfo); ii++)
        {
            EnableWindow(GetDlgItem(hWnd, CtrlsInfo[ii].m_ID), (0 == lParam) ? TRUE : FALSE);
        }
    }

    二、演示结果总结

         1.  消息窗体窗体是不可见,在SPY++窗体中可以找到, 但同步不到也就是说没有被遍历到.

         2.  在Demo0050Ex发出广播消息(WM_UMSG_BROADCAST)后, Demo0050Ex自己收到, 但Demo0050没有收到

         3.  WM_COPYDATA 消息必须由SendMessage 函数发送(同步方式,系统为了确保数据有效)

    演示代码

  • 相关阅读:
    用户场景描述
    NABCD需求分析
    课堂测试返回最大子数组2
    单元测试课堂练习
    正式版
    第二次冲刺团队进展报告七
    第二次冲刺团队进展报告六
    第二次冲刺团队进展报告五
    第二次冲刺团队进展报告四
    第二次冲刺团队进展报告三
  • 原文地址:https://www.cnblogs.com/ztercel/p/2175047.html
Copyright © 2011-2022 走看看