【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 函数发送(同步方式,系统为了确保数据有效)

 

演示代码

你可能感兴趣的:(demo)