应用程序间消息的互发

zzz同样是 Windows环境下32位汇编语言程序设计 书中的例子,程序A向程序B发送消息,程序B响应这个消息,代码如下
ContractedBlock.gif ExpandedBlockStart.gif Code
发送程序代码:
#include 
<windows.h>
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
    
char className[]="myclass";
    
char mess[]="fuck you!";
    HWND hWnd
=::FindWindow(className,NULL);
    
if(hWnd)
    {
        ::SendMessage(hWnd,WM_SETTEXT,
0,(LPARAM)mess);
        MessageBox(hWnd,
"send sucess!","sucess",MB_OK);
        
return 0;
    }
    MessageBox(hWnd,
"send fail!","fail",MB_OK);
    
return 0;
}

接收程序代码
ContractedBlock.gif ExpandedBlockStart.gif Code
#include <windows.h>
LRESULT CALLBACK _procWinMain(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
    HWND hWinMain;
    MSG stMsg;
    WNDCLASSEX stWndClass;
    
char className[]="myclass";
    
//hInstance=GetModuleHandle(NULL);
    RtlZeroMemory(&stWndClass,sizeof(stWndClass));//WNDCLASSEX结构置零
    
//注册窗口类
    stWndClass.hCursor=::LoadCursor(0,IDC_ARROW);
    stWndClass.hInstance
=hInstance;
    stWndClass.cbSize
=sizeof(WNDCLASSEX);
    stWndClass.style
=CS_HREDRAW||CS_VREDRAW;
    stWndClass.lpfnWndProc
=_procWinMain;
    stWndClass.hbrBackground
=(HBRUSH)GetStockObject(BLACK_BRUSH);
    stWndClass.lpszClassName
=className;
    ::RegisterClassEx(
&stWndClass);
    
//建立并显示窗口
    hWinMain=::CreateWindowEx(WS_EX_CLIENTEDGE,className,"firstwindow",WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,NULL,hInstance,NULL);
    ::ShowWindow(hWinMain,SW_SHOWNORMAL);
    ::UpdateWindow(hWinMain);
    
while(1)
    {
        
if(::GetMessage(&stMsg,NULL,0,0)==0)//消息为WM_QUIT
            break;
        
else
        {
            ::TranslateMessage(
&stMsg);
            ::DispatchMessage(
&stMsg);
        }
    }
    
return 0;
}
LRESULT CALLBACK _procWinMain(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    
if(uMsg==WM_CLOSE)
    {
        
//MessageBox(NULL,"close!","close",MB_OK);
        ::DestroyWindow(hWnd);
    }
    
else if(uMsg==WM_DESTROY)
    {
        
//MessageBox(NULL,"destroy!","destroy",MB_OK);
        ::PostQuitMessage(NULL);
    }
    
else if(uMsg==WM_SETTEXT)
    {
        
char Buff[256];
        
char Receive[]="Receive WM_SETTEXT.\nparam: %08x\ntext: %s\n";
        wsprintf(Buff,Receive,lParam,lParam);
        MessageBox(hWnd,Buff,
"receive",MB_OK);
    }
    
else
    {
        
return ::DefWindowProc(hWnd,uMsg,wParam,lParam);
    }
    
return 0;
}

例子很简单,但是心里有个疑问,程序A本身产生的消息和程序B产生的消息之间是否有什么差别?能否在程序中识别当前的消息是否本身产生的?否则响应程序的流程不就是乱了吗?
我感觉这个消息互发的功能应该没这么简单,继续研究去~
发现一件有趣的事情,不仅是WM_SETTEXT消息可以通过另外的程序发送,连WM_CLOSE,WM_DESTROY消息也可以,也就是说我可以用一个程序远程关掉另外一个程序,尝试了一下,程序代码如下
ContractedBlock.gif ExpandedBlockStart.gif Code
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
    
char className[]="myclass";
    
char mess[]="fuck you!";
    HWND hWnd
=::FindWindow(className,NULL);
    
if(hWnd)
    {
        
//::SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)mess);
        MessageBox(NULL,"send?","send",MB_OK);
        ::SendMessage(hWnd,WM_CLOSE,
0,0);
        
//::SendMessage(hWnd,WM_DESTROY,0,0);
        MessageBox(hWnd,"send sucess!","sucess",MB_OK);
        
return 0;
    }
    MessageBox(hWnd,
"send fail!","fail",MB_OK);
    
return 0;
}
确实是可以的,开了send程序以后receive程序真的就被关掉了,哈哈。但是,到此又有了一个疑问,还有一个消息WM_QUIT也是完成关闭窗口的功能的,这个消息能成功吗?
试验了一下,竟然不行!问题处在哪里?google了一下,原来SendMessage 直接将消息发送到窗口,并调用窗口处理程序,完成消息响应,即SendMessage  根本就没有将消息发到消息对列中,因此GetMessage 无法从消息对列中收到WM_QUIT 的消息,所以receive程序无法关闭。
那是不是没办法发送WM_QUIT消息了呢?当然不是,WINDOWS给我们提供了PostMessage函数,用法和SendMessage函数一样,使用PostMessage函数是将消息插入消息队列中的,因此recieve程序就能够响应WM_QUIT消息了,用PostMessage函数试验一下,成功!
那么PostMessage函数和SendMessage函数是否一样呢?我们用PostMessage函数来发送一下WM_SETTEXT命令试一下,receive函数没反应!看来,PostMessage和SendMessage名字差不多,功能可是有很大不同的,具体有什么不同,研究下,放到下篇博客再说了:)

转载于:https://www.cnblogs.com/feiyucq/archive/2009/07/27/1532067.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值