为什么只能用SendMessage发送消息WM_CopyData的分析.

SendMessage API使用的COPYData 本文着重讲述了如果用WM_COPYDATA消息来实现两个进程之间传递数据. 进程之间通讯的几种方法: 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯。常用的方法有   使用内存映射文件  通过共享内存DLL共享内存  使用SendMessage向另一进程发送WM_COPYDATA消息 比起前两种的复杂实现来,WM_COPYDATA消息无疑是一种经济实惠的一中方法. W... 阅读详情

为什么只能用SendMessage发送消息WM_CopyData的分析.

Writter: SkyJacker
Date:2006-12-28
Http://blog.youkuaiyun.com/skyjacker

注:能力实在有限,最终并未得出为什么只能用SendMessage发送消息WM_CopyData。
更没有弄清SendMessage的工作原理。
文中引用的资料或观点也许并不准确,只是希望有兴趣者可以继续分析或者给予指导以解惑。谢谢!

一、先从网上搜罗以下基本知识:

资料1:WM_COPYDATA是用内存映射机制实现的。  
   简单思路如下:  
   发送进程为A,目标进程为B。  
   当A进程用SendMessage(WM_COPYDATA,wParam,lParam)进行发送的时候,它先调用  
   HANDLE   hMap   =   CreateFileMapping(0xFFFFFFFF,NULL,PAGE_READWRITE,NULL,dwSize,"MSName")  
   其中dwSize为lParam信息得到的长度(也就是COPYDATASTRUCT结构得到的信息)  
   MSName可以是MS自己定义的名字,这样就把内容复制到共享内存中。然后等待B进程处理;  
   当B进程处理WM_COPYDATA消息时,它先用OpenFileMapping()和MapViewOfFile()得到共享内存地址,
   然后再把地址值保存到lParam里面使B进程处理消息过程能处理这些数据,处理好后进行A与B再  
   用CloseHandle()等API进行清除操作就OK了。

   SkyJacker注:按照这种说法,那么进程B,如何知道映射文件名是"MSName"呢?
 还是lParam本身就表示映射文件名了?
资料2:
   SendMessage是同步函数,会等到窗口处理完才返回
   PostMessage是异步函数,只是将消息挂到消息队列中就立即返回,由于无法同步可能导致无法响应,
       一般情况下窗口消息是不会被丢弃的。
   这是因为系统必须管理用以传递数据的缓冲区的生命期,如果你使用PostMessage,数据缓冲区会在接受端有机会处理该数据之前被系统摧毁掉!
   看看候杰翻译的"多线程程序设计" 里面有详细解释,总而言之 只能用SendMessage。

   SkyJacker注:话虽然是这么说,但是异步也可以接收数据吧。socket函数connect,recv,send等也运行正常啊。
       因此,只能是SendMessage函数的设计使然,而不是因为同步或异步的原因。

资料3:请问如何在2个进程间(一个是多线程数据采集程序,一个是画面显示程序)传递大量数据?
   采集程序中存在数量不定的线程,其中每一个线程都可以采集数据,并将数据发送到显示程序进行显示。
   显示程序就是一个简单的UI程序,将接收到的采集数据显示出来。
   在一定时间段中采集的数据量比较大:每秒几条数据。每条数据大概2-3K(来自不同线程)

   原来我使用SendMessage(WM_COPYDATA,…) 在2个进程间传递数据。但最近发现一个BUG:
   有时在显示数据过程中切换UI的窗口,会引起系统deadlock! 后来查阅资料,发现用SendMessage传递数据时,
   在某些情况下的确可以引起deadlock,所以按照书中的建议用SendMessageTimeout(WM_COPYDATA,…) 进行自我保护方式数据传输。
   deadlock问题倒是解决了,但又出现数据丢失问题,原因是SendMessageTimeout经常返回timout错误 !

   我的问题是除了SendMessage(WM_COPYDATA,…) 方法,还有没有别的方法实现本文中所说的采集程序和画面显示程序间大量数据的传递?
   PostMessage不支持 WM_COPYDATA.
   SendMessageCallback, SendNotifyMessage也不支持WM_COPYDATA.

   我查过国外的很多网站,大概的结论是:

   1)WM_COPYDATA是在两个进程间传递大量数据最方便,最好使的方法.
   2)但只有SendMessage,SendMessageTimeout支持WM_COPYDATA
   3)SendMessage(WM_COPYDATA,…)内部实现是通过File mapping实现的, 系统自动完成同步工作.
   4)SendMessage是阻塞的(block), 在某些情况下会引起deadlock. 所以更安全的方法是使用SendMessageTimeout

   SkyJacker注:还是没有点明本质。

二、通过反汇编试图熟悉SendMessage过程
1、发送过程:
procudure SendAlmData(const SendText: string);
var
  DS: TCopyDataStruct;
begin
  DS.dwData := 0;
  DS.cbData := Length(SendText);   //SendText表示要发送的数据     
  DS.lpData := @SendText[1];
  SendMessage(FaceHandle, WM_COPYDATA, 0, LongWord(@DS)); //FaceHandle表示接收数据的主界面
  //PostMessage(FaceHandle, WM_COPYDATA, 0, LongWord(@DS));
  //此处必须用SendMessage,用PostMessage主界面接收不到消息
end;
2、SendMessage声明
SendMessage(FaceHandle, WM_COPYDATA, 0, LongWord(@DS)); //WM_COPYDATA = $004A;
LRESULT SendMessage(
    HWND hWnd,         // handle of destination window
    UINT Msg,         // message to send
    WPARAM wParam, // first message parameter  短参数
    LPARAM lParam  // second message parameter 长参数
   );

3、通过WM_CopyData传输数据
通过TCopyDataStruct结构存储要传输的数据.
只有DS: TCopyDataStruct一个局部变量的情况。
TCopyDataStruct结构:
  tagCOPYDATASTRUCT = packed record
    dwData: DWORD;  
    cbData: DWORD;
    lpData: Pointer;
  end;

4、Delphi编译器调试过程

Begin
004AD36C 53               push ebx //使用ebx存放要传输数据的地址
004AD36D 83C4F4           add esp,-$0c  //分配局部变量空间。TCopyDataStructk结构是12个字节大小 

004AD370 8BDA             mov ebx,edx   //edx指向要传输数据的地址(形参SendText)
004AD372 33C0             xor eax,eax   //ESP=$12F278
004AD374 890424           mov [esp],eax //dwData=0
004AD377 8BC3             mov eax,ebx   
004AD379 E85676F5FF       call @LStrLen
004AD37E 89442404         mov [esp+$04],eax //cbData := Length(Str)
004AD382 8BC3             mov eax,ebx
004AD384 E84378F5FF       call @LStrToPChar //PChar(Str)
004AD389 89442408         mov [esp+$08],eax //lpData := @Str[1] $E44EBC
004AD38D 8BC4             mov eax,esp       //eax存放TCopyDataStruct的起始地址
004AD38F 50               push eax          //stdcall方式从右向左 LPARAM=@CDS
004AD390 6A00             push $00          //WPARAM
004AD392 6A4A             push $4a          //WM_COPYDATA = $004A;
004AD394 A1F0DF4B00       mov eax,[$004bdff0] //[$004bdff0]处,存放全局变量的地址
004AD399 8B00             mov eax,[eax]     //获得全局变量 对方窗口句柄 FaceHandle
004AD39B 50               push eax
004AD39C E857A5F5FF       call SendMessage
004AD3A1 83C40C           add esp,$0c       //恢复堆栈
004AD3A4 5B               pop ebx           //恢复ebx
004AD3A5 C3               ret               //pop EIP
004AD3A6 8BC0             mov eax,eax
004AD3A8 55               push ebp
004AD3A9 8BEC             mov ebp,esp
004AD3AB 33C0             xor eax,eax
004AD3AD 55               push ebp
004AD3AE 68CDD34A00       push $004ad3cd
004AD3B3 64FF30           push dword ptr fs:[eax]
004AD3B6 648920           mov fs:[eax],esp


I=Length(Str)  //eax执行字符串的首地址
004049D4 85C0             test eax,eax   //如果字符串地址为空,则跳$3F
004049D6 7403             jz +$03
004049D8 8B40FC           mov eax,[eax-$04] //取字符串的长度
004049DB C3               ret
004049DC 85D2             test edx,edx
004049DE 743F             jz +$3f


call @LStrToPChar
00404BCC 85C0             test eax,eax  //判断是否为空
00404BCE 7402             jz +$02
00404BD0 C3               ret
00404BD1 00B8D14B4000     add [eax+$00404bd1],bh //冗余垃圾代码
00404BD7 C3               ret


call SendMessage //跳转到导入表
004078F0 FF254C054C00     jmp dword ptr [$004c054c]  //ScrollWindow
004078F6 8BC0             mov eax,eax
004078F8 FF2548054C00     jmp dword ptr [$004c0548]  //SendMessage
004078FE 8BC0             mov eax,eax
00407900 FF2544054C00     jmp dword ptr [$004c0544]  //SetActiveWindow
00407906 8BC0             mov eax,eax
00407908 FF2540054C00     jmp dword ptr [$004c0540]
......

SendMessage内部:
77D2F39A 8BFF             mov edi,edi
77D2F39C 55               push ebp
77D2F39D 8BEC             mov ebp,esp
77D2F39F 56               push esi
77D2F3A0 8B750C           mov esi,[ebp+$0c]  //首先判断消息WM_CopyData
77D2F3A3 F7C60000FEFF     test esi,$fffe0000
77D2F3A9 0F85911D0100     jnz +$00011d91
77D2F3AF 8B4D08           mov ecx,[ebp+$08]  //判断接收方窗体句柄
77D2F3B2 83F9FF           cmp ecx,-$01       
77D2F3B5 0F847BF10000     jz +$0000f17b       
77D2F3BB 81F9FFFF0000     cmp ecx,$0000ffff  
77D2F3C1 0F846FF10000     jz +$0000f16f     
77D2F3C7 E80491FEFF       call -$00016efc   //进入最终获得一个值eax= $0081DF50,
77D2F3CC 85C0             test eax,eax      //此值的获取于窗口句柄有关系.高低16位寻址操作 90586
77D2F3CE 0F845BF10000     jz +$0000f15b
77D2F3D4 6A01             push $01
77D2F3D6 FF7514           push dword ptr [ebp+$14]  //$0012F278 //DS: TCopyDataStruct的地址;
77D2F3D9 FF7510           push dword ptr [ebp+$10]  //0
77D2F3DC 56               push esi                  //$4A
77D2F3DD 50               push eax                  //$0081DF50=call -$00016efc
77D2F3DE E8F0C3FEFF       call -$00013c10
77D2F3E3 5E               pop esi
77D2F3E4 5D               pop ebp
77D2F3E5 C21000           ret $0010
77D2F3E8 81FF06010000     cmp edi,$00000106

call -$00016efc
77D184D0 64A118000000     mov eax, fs:[$00000018] //EAX=7FFDF000
77D184D6 85C9             test ecx,ecx            //函数首先检测ecx(接收方窗口句柄)
77D184D8 740C             jz +$0c
77D184DA 3B88F4060000     cmp ecx,[eax+$000006f4] //判断EAX偏移6F4位置内容(0)与ECX
77D184E0 0F84F62F0000     jz +$00002ff6
77D184E6 B201             mov dl,$01
77D184E8 EB26             jmp +$26
77D184EA 90               nop
77D184EB 90               nop
77D184EC 90               nop

jmp+$26
77D1850F 90               nop
77D18510 8BFF             mov edi,edi
77D18512 55               push ebp      //保存刚进入SendMessage位置,原先用来索引SendMessage的形参
77D18513 8BEC             mov ebp,esp
77D18515 51               push ecx      //消息接收方窗口句柄
77D18516 53               push ebx      //要发送数据的地址
77D18517 56               push esi      //消息WM_CopyData =$4A
77D18518 57               push edi      //edi=$02
77D18519 8855FC           mov [ebp-$04],dl //DL=$01
77D1851C 8BF9             mov edi,ecx   //edi=ecx =窗口句柄
77D1851E 33F6             xor esi,esi
77D18520 64A118000000     mov eax, fs:[$00000018]
77D18526 8B0D8000D777     mov ecx,[$77d70080]
77D1852C 8D98CC060000     lea ebx,[eax+$000006cc]
77D18532 8BC7             mov eax,edi
77D18534 25FFFF0000       and eax,$0000ffff  //获得窗体句柄的低16位 90586 ->0586
77D18539 3B4108           cmp eax,[ecx+$08]  //0586 - 12AA
77D1853C 734D             jnb +$4d  //不成立
77D1853E 8B0DA400D777     mov ecx,[$77d700a4] //ECX=00540000
77D18544 8D0440           lea eax,[eax+eax*2] //eax=eax+eax*2 (eax=$0586)
77D18547 8D0C81           lea ecx,[ecx+eax*4] //ecx=ecx+eax*4 (eax=$0586*3 , ecx=00540000)
77D1854A 8BC7             mov eax,edi  //eax=90586 窗口句柄
77D1854C C1E810           shr eax,$10  //右移16位,得到高16位 =9
77D1854F 663B410A         cmp ax,[ecx+$0a] //if 9= [ecx+$0a](=0009)  条件相等
77D18553 0F8577600000     jnz +$00006077   
77D18559 F6410901         test byte ptr [ecx+$09],$01 //byte ptr [ecx+$09]=$00
77D1855D 752C             jnz +$2c 
77D1855F 8A4108           mov al,[ecx+$08] //$01
77D18562 3AC2             cmp al,dl        //al=dl=$01
77D18564 0F8515560000     jnz +$00005615
77D1856A 8B4318           mov eax,[ebx+$18] //ebx=7FFDF6CC
77D1856D 85C0             test eax,eax      //EAX=00720650
77D1856F 8B31             mov esi,[ecx]
77D18571 0F8432580100     jz +$00015832
77D18577 3B30             cmp esi,[eax]   //ESI=BC73DF50
77D18579 0F822A580100     jb +$0001582a  
77D1857F 3B7004           cmp esi,[eax+$04]
77D18582 0F8321580100     jnb +$00015821
77D18588 2B731C           sub esi,[ebx+$1c]
77D1858B 85DB             test ebx,ebx
77D1858D 740D             jz +$0d
77D1858F F7431400000020   test [ebx+$14],$20000000
77D18596 0F858E5F0000     jnz +$00005f8e
77D1859C 6A01             push $01
77D1859E 57               push edi   //EDI=$90586
77D1859F E84CFFFFFF       call -$000000b4
77D185A4 85C0             test eax,eax  //判断eax,esi是否为零 eax=$01  esi=$0081DF50
77D185A6 0F84555F0000     jz +$00005f55
77D185AC 85F6             test esi,esi
77D185AE 0F844D5F0000     jz +$00005f4d
77D185B4 5F               pop edi
77D185B5 8BC6             mov eax,esi  //结果存入EAX= $0081DF50
77D185B7 5E               pop esi
77D185B8 5B               pop ebx
77D185B9 8BE5             mov esp,ebp
77D185BB 5D               pop ebp     //恢复SendMessage形参
77D185BC C3               ret
77D185BD 90               nop
77D185BE 90               nop


call -$000000b4
----------------------------------------------------
77D184F0 B848120000       mov eax,$00001248
77D184F5 BA0003FE7F       mov edx,$7ffe0300
77D184FA FF12             call dword ptr [edx]
77D184FC C20800           ret $0008
77D184FF 90               nop

call dword ptr [edx]
7C92EB8B 8BD4             mov edx,esp //EDX=12F234
7C92EB8D 0F34             sysenter
7C92EB8F 90               nop
7C92EB90 90               nop
7C92EB91 90               nop

sysenter
77D184FC C20800           ret $0008
77D184FF 90               nop
77D18500 90               nop
77D18501 90               nop
77D18502 90               nop
------------------------------------------------------

call -$00013c10
-------------------------------------------------------------------
77D1B7D3 8BFF             mov edi,edi
77D1B7D5 55               push ebp
77D1B7D6 8BEC             mov ebp,esp  //无局部变量
77D1B7D8 51               push ecx     //ECX=1
77D1B7D9 51               push ecx
77D1B7DA 53               push ebx     //$00E28684-->SendText='AL....'
77D1B7DB 56               push esi     //4A
77D1B7DC 8B7508           mov esi,[ebp+$08]  //$81DF50
77D1B7DF 8B06             mov eax,[esi]      //[$81DF50]=$090586 接收方窗口句柄
77D1B7E1 57               push edi
77D1B7E2 8B7D0C           mov edi,[ebp+$0c]
77D1B7E5 81FFE0030000     cmp edi,$000003e0
77D1B7EB 8945F8           mov [ebp-$08],eax
77D1B7EE C645FF00         mov byte ptr [ebp-$01],$00
77D1B7F2 C6450B00         mov byte ptr [ebp+$0b],$00
77D1B7F6 720C             jb +$0c
77D1B7F8 81FFE8030000     cmp edi,$000003e8
77D1B7FE 0F86AE1C0000     jbe +$00001cae
77D1B804 E84CCEFFFF       call -$000031b4   //以下没有继续分析
77D1B809 3B4608           cmp eax,[esi+$08]
77D1B80C 0F85A01C0000     jnz +$00001ca0
77D1B812 F6461604         test byte ptr [esi+$16],$04
77D1B816 0F85961C0000     jnz +$00001c96
77D1B81C 64A118000000     mov eax, fs:[$00000018]
77D1B822 8B88E4060000     mov ecx,[eax+$000006e4]
77D1B828 8B490C           mov ecx,[ecx+$0c]
77D1B82B 0B88F0060000     or ecx,[eax+$000006f0]
77D1B831 66F7C12020       test cx,$2020
77D1B836 0F85761C0000     jnz +$00001c76
77D1B83C 33C0             xor eax,eax


ida5.0.0.879 逆向User32.dll 5.1.2600.2622 Winxp SP2

.text:77D2F390 ; ---------------------------------------------------------------------------
.text:77D2F395                 align 4
.text:77D2F398                 db 2 dup(90h)
.text:77D2F39A ; Exported entry 572. SendMessageA
.text:77D2F39A
.text:77D2F39A ; *************** S U B R O U T I N E ***************************************
.text:77D2F39A
.text:77D2F39A ; Attributes: bp-based frame
.text:77D2F39A
.text:77D2F39A ; LRESULT __stdcall SendMessageA(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
.text:77D2F39A                 public SendMessageA
.text:77D2F39A SendMessageA    proc near               ; CODE XREF: SendDlgItemMessageA+2Dp
.text:77D2F39A                                         ; PostMessageA+25424p
.text:77D2F39A                                         ; sub_77D1B217+2FBB8p
.text:77D2F39A                                         ; sub_77D1B217+2FBCCp
.text:77D2F39A                                         ; DATA XREF: sub_77D5BD93+54o
.text:77D2F39A                                         ; sub_77D5C506+BFo ...
.text:77D2F39A
.text:77D2F39A hWnd            = dword ptr  8
.text:77D2F39A Msg             = dword ptr  0Ch
.text:77D2F39A WideCharStr     = dword ptr  10h
.text:77D2F39A hMem            = dword ptr  14h
.text:77D2F39A
.text:77D2F39A ; FUNCTION CHUNK AT .text:77D3E52F SIZE 00000011 BYTES
.text:77D2F39A ; FUNCTION CHUNK AT .text:77D41140 SIZE 00000046 BYTES
.text:77D2F39A
.text:77D2F39A                 mov     edi, edi
.text:77D2F39C                 push    ebp
.text:77D2F39D                 mov     ebp, esp
.text:77D2F39F                 push    esi
.text:77D2F3A0                 mov     esi, [ebp+Msg]
.text:77D2F3A3                 test    esi, 0FFFE0000h
.text:77D2F3A9                 jnz     loc_77D41140
.text:77D2F3A9
.text:77D2F3AF                 mov     ecx, [ebp+hWnd]
.text:77D2F3B2                 cmp     ecx, 0FFFFFFFFh
.text:77D2F3B5                 jz      loc_77D3E536
.text:77D2F3B5
.text:77D2F3BB                 cmp     ecx, 0FFFFh
.text:77D2F3C1                 jz      loc_77D3E536
.text:77D2F3C1
.text:77D2F3C7                 call    sub_77D184D0
.text:77D2F3C7
.text:77D2F3CC                 test    eax, eax
.text:77D2F3CE                 jz      loc_77D3E52F
.text:77D2F3CE
.text:77D2F3D4                 push    1               ; int
.text:77D2F3D6                 push    [ebp+hMem]      ; hMem
.text:77D2F3D9                 push    [ebp+WideCharStr] ; WideCharStr
.text:77D2F3DC                 push    esi             ; int
.text:77D2F3DD                 push    eax             ; int
.text:77D2F3DE                 call    sub_77D1B7D3
.text:77D2F3DE
.text:77D2F3E3
.text:77D2F3E3 loc_77D2F3E3:                           ; CODE XREF: SendMessageA+F197j
.text:77D2F3E3                                         ; SendMessageA+11DD0j
.text:77D2F3E3                                         ; SendMessageA+11DE7j
.text:77D2F3E3                 pop     esi
.text:77D2F3E4                 pop     ebp
.text:77D2F3E5                 retn    10h
.text:77D2F3E5
.text:77D2F3E5 SendMessageA    endp
.text:77D2F3E5
.text:77D2F3E8 ; ---------------------------------------------------------------------------
.text:77D2F3E8 ; START OF FUNCTION CHUNK FOR sub_77D1B7D3
.text:77D2F3E8
.text:77D2F3E8 loc_77D2F3E8:                           ; CODE XREF: sub_77D1B7D3+13B70j
.text:77D2F3E8                 cmp     edi, 106h
.text:77D2F3EE                 jnb     loc_77D302C2
.text:77D2F3EE
.text:77D2F3F4                 cmp     edi, 2Fh
.text:77D2F3F7                 jz      loc_77D302C2
.text:77D2F3F7
.text:77D2F3FD                 cmp     edi, 0AFh
.text:77D2F403                 jbe     loc_77D2F373
.text:77D2F403
.text:77D2F409                 cmp     edi, 0B1h
.text:77D2F40F                 jbe     loc_77D302AE
.text:77D2F40F
.text:77D2F415                 cmp     edi, 0CCh
.text:77D2F41B                 jz      loc_77D302C2
.text:77D2F41B
.text:77D2F421                 cmp     edi, 101h
.text:77D2F427                 jbe     loc_77D2F373
.text:77D2F427
.text:77D2F42D                 jmp     loc_77D40E50
.text:77D2F42D
.text:77D2F42D ; END OF FUNCTION CHUNK FOR sub_77D1B7D3
.text:77D2F42D ; ----------------------------------------------- 

Qt与MFC通信 win32 sendmessage WM_COPYDATA QT与MCF通信 QT传消息到MFC 先抓取窗口句柄,然后再用win32的WM_COPYDATA进行消息传递。具体抓取窗口句柄和调用外部mfc 的exe方法见QT内嵌外部exe程序。与之前不同的是,这里抓取句柄要写成全局的,因为当内嵌成功后,再去抓取用于消息传递时,就抓不到了。 Qt端 需要用到以下头文件 #include <windows.h> #include <windowsx.h> main.h class MainWindow : public QMainWindow { 阅读详情

相关推荐

Qt中IPC(进程间通信)的方式一:WM_COPYDATA消息

1. 发送消息:SendMessage(WinAPI) WINUSERAPI LRESULT WINAPI SendMessageA( __in HWND hWnd, __in UINT Msg, __in WPARAM wParam, __in LPARAM lParam); WINUSERAPI LRESULT // 返回值,长整形 WINAPI SendMessageW( __i...

u013122905的博客 3075

只能用SendMessage发送消息WM_CopyData的分析

test

1109

delphi使用消息Sendmessage/Postmessage传递字符串三种方式实现

如果同一进程传递字符串可以使用PostMessage传递,该函数将一个消息放入(寄送)到与指定窗口创建的线程相联系消息队列里,不等待线程处理消息就返回,是异步消息模式。消息队列里的消息通过调用GetMessage和PeekMessage取得。2、如果线程之间传递可以使用PostThreadMessage传递,PostThreadMessage是该函数将一个消息放入(寄送)到指定线程的消息队列里,不等待线程处理消息就返回。1、直接传递,但只能传递给同进程的窗口,无法实现跨进程的消息传递。

yygyyygy1233的博客 1463

进程的通信 - WM_COPYDATA

在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯。其中使用向另一进程发送消息是一种比较经济实惠的方法。通信需要将传递的消息封装在结构体中,在消息传递函数时作为lParam参数传递为自定义数据,按照自己习惯设置就好,不影响对象的传输;表示传递数据的大小(以字节为单位表示传递的数据,是一个void*类型使用时要用而不能使用PostMessage,因为SendMessage是的,会等待消息响应窗体处理消息完毕后再返回;

qq_54169998的博客 4440

C#通过SendMessage消息来发送接收文本消息设定控件text

InteropServices,SendMessage,COPYDATASTRUCT,Marshal,AllocCoTaskMem,StructureToPtr详细介绍,全面详细的介绍消息发送函数发送附加消息和接受附加消息的过程。

河西~石头 4918

MFC框架下WM_COPYDATA进程通信实战案例

WM_COPYDATA 是 Windows 系统定义的一个标准消息类型,其消息值为0x004A。它允许一个进程通过函数将一块数据复制到另一个进程的地址空间中。接收方通过OnCopyData虚函数来接收数据。这种机制不同于一般的 Windows 消息,它能够携带自定义数据结构,因此在需要传递结构化数据时非常有用。在Windows进程间通信中,结构体是消息的核心载体。该结构体允许进程通过窗口消息机制传输任意大小的数据块。深入理解。

weixin_31860973的博客 1077

SendMessage和WM_COPYDATA的用法

SendMessage后面的两个参数,一个是WPARAM(UINT),一个是LPARAM(LONG),这是API函数。在VS和CB中都一样。传递字符串,如果是本进程,伪代码如下:String str = "test字符串";::SendMessage(句柄, 自定义消息, str.Length, LPARAM(str.c_str()));或者TCHAR sz[] = "test字符串";::SendMessage(句柄, 自定义消息, _tcslen(sz), LPARAM(sz));使用WM_COPYDA

飘着ing 1万+

delphi进程间消息收发

delphi进程间消息收发 通过获取窗口句柄发送tcopydata消息 附带一些小参数

DELPHI WM_CopyData 用法

unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, ComCtrls;typeTForm1 = class(TForm) Button1: TButton; Edit1: TEdit; Edit2...

weixin_34409357的博客 256

Delphi控件WMCopyData消息数据发送与接收

自制控件,将控件拖放到窗口中,可以轻松快捷实现窗口、程序直接发送数据。参照控件中的代码编写方法可以实现更多控件的自定义功能。

手把手教你用Logisim搞定华科计组实验:单总线CPU硬布线控制器设计(含Excel自动生成电路技巧)

本文详细解析了如何使用Logisim完成华科计组实验中的单总线CPU硬布线控制器设计,特别分享了利用Excel自动生成电路逻辑的高效技巧。从实验准备、状态机表格填写到模块化构建和系统联调,提供全流程实战指导,帮助读者快速掌握计算机组成原理核心概念,大幅提升实验效率。

weixin_28744423的博客 321

Windows进程通信——WM_COPYDATA消息

1. 概述 WM_COPYDATA是一种非常强大却鲜为人知的消息。当一个应用向另一个应用传送数据时,发送方只需使用调用SendMessage函数,参数是目的窗口的句柄、传递数据的起始地址、WM_COPYDATA消息。接收方只需像处理其它消息那样处理WM_COPY DATA消息,这样收发双方就实现了数据共享。 WM_COPYDATA是一种非常简单的方法,它在底层实际上是通过文件映射来实现的。它的

m_buddy的博客 2218

让数学变得更生动manim库的使用(1)-基本概念

0、概述 数学理论与数学公式的展示总是一件很枯燥的事情,但3b1b的manim动画库在github上开源之后,让这一切变得非常简单。目前这个库已经分成两个版本一个由3b1b自身维护。但作者并没有承诺长期维护该库,所以由专门团队再次基础上研发了相应的社区版,并对该版本进行长期维护。本文的所有案例都基于社区版的官方案例。本文主要介绍该库的基本概念相关的案例,文章主要以代码为主,关键代码都有相关注释。 另外本文的运行环境维jupyter这与其他的ide环境运行代码稍微有些不同 1、类库引入已经相关测试 引

amao1998的博客 9965

C#使用WM_COPYDATA传输消息

using System.Runtime.InteropServices; public partial class Form1 : Form { public Form1() { InitializeComponent(); } [DllImport("user32.dll", EntryPoint = "FindWindow")] private extern static.

liang08114的专栏 2193

FPGA设计中的扇出约束实战:从XDC到代码优化的全流程解析

本文全面解析FPGA设计中扇出约束的重要性与应用,详细介绍了从XDC约束文件设置到HDL代码优化的全流程实战技巧。通过MAX_FANOUT约束控制信号负载,结合寄存器复制和物理优化策略,有效解决高扇出导致的时序违例和布线拥塞问题,提升设计性能和可靠性。

nept的博客 796

保姆级教程:用GROMACS 2022.4的拉伸模拟(SMD)加速蛋白-蛋白组装过程

本文详细介绍了如何使用GROMACS 2022.4的拉伸分子动力学模拟(SMD)技术加速大蛋白组装过程。通过CHARMM36力场和SMD技术,将传统需要数月的蛋白结合过程缩短至数天,大幅提升模拟效率。文章包含参数设计、索引组创建、周期性边界处理等实战技巧,并提供了完整的GPU加速工作流和常见问题解决方案。

weixin_30338481的博客 445

[VC++]MFC使用WM_COPYDATA消息进行进程间的通讯

MFC使用WM_COPYDATA消息进行进程间的通讯本代码实现了WM_COPYDATA数据的传递及参数(WPARAM) 与 (LPARAM)的接收,尤其是如何接收WPARAM消息,本示例给出了接收代码。 一、介绍 Windows上MFC应用程序可使用WM_COPYDATA可以完成两个进程之间的通讯。 当一个应用向另一个应用传送数据时,发送方需调用SendMessage函数,参数是目的窗口的句柄、传递数据的起始地址、WM_COPYDATA消息。接收方只需响应WM_COPY DATA消息,双方就实现了数据.

1424

R语言实战:非正态数据下的Scheirer–Ray–Hare检验全流程解析

本文详细解析了在R语言中执行Scheirer–Ray–Hare检验的全流程。当实验数据不符合正态分布时,该非参数检验是分析两因素设计(包括主效应和交互效应)的有效工具。文章从原理、环境配置、数据导入、核心代码到结果解读与报告撰写,提供了完整的实战指南,并附有常见的避坑建议。

weixin_29061465的博客 397

linux消息队列wm_copydata,SendMessage和PostMessage发送消息(不一样进程传递字符串)...

1、函数功能windowsSendMessage函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而函数PostMessage不一样,将一个消息寄送到一个线程的消息队列后当即返回。app2、函数原型异步SendMessage函数的原型为LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPAR...

weixin_42501298的博客 1113

第42章:AI代码生成的质量标准——何时用AI、何时自己写

> - AI代码生成的质量分级标准:可用、稳定、安全、优雅 > - 一个决策矩阵:什么场景适合用AI,什么场景必须人工编写 > - 如何评估AI生成的代码质量(复杂度、可读性、安全性) > - 实战对比:同一需求下AI生成代码 vs 人工编写代码 > - 团队落地:将质量标准集成到Code Review和CI流程 > - 我如何将团队AI代码接受率从70%提升到90%

sfishfly的博客 161

SpringBoot+Vue+kkFileView实现文档管理(文档上传、下载、在线预览)

上面在使用OpenOffice实现doc、excel、ppt等文档的管理和预览。除此之外可用kkFileView实现包括且更多文档的预览。

BADAO_LIUMANG_QIZHI的博客 1万+

C++进程通信实现-----WM_COPYDATA消息

工作中碰到了32位dll和64位dll通信问题,上网搜索了相关的问题,发现最简单的实现方式就是利用WM_COPYDATA消息传递,很多博客给出了实现代码,但大部分都是发送端C++,接收端C#或MFC。本文给出自己实现的简单例子,发送接收相互通信,都是用C++实现。   目录   WM_COPYDATA 消息 代码实现 WM_COPYDATA 消息 An application ...

Mister5ive的专栏 6032

新手必看:C#调用YOLO模型完成图片/视频目标检测(上位机版)

新手学习C#调用YOLO模型,核心是先把基础流程跑通,再逐步优化。图片检测是基础,视频检测就是在图片的基础上加循环和线程,而上位机的实际项目,就是在这个基础上适配工业硬件和业务需求。本文的代码都是新手能直接复制运行的,如果你运行时遇到问题,先检查前期准备是否到位,再看避坑指南。记住,新手别追求一步到位,先实现功能,再慢慢优化性能和界面。等你能熟练调用YOLO模型后,再去研究模型训练、量化优化等进阶内容,会轻松很多。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 986

[VC]SendMessage和PostMessage发送消息(不同进程传递字符串)

一、函数功能 该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回。 二、函数原型 SendMessage函数的原型为  LRESULT SendMessage(    HWND hWnd,    UINT Msg,    WPARAM wParam, 

slj_win的专栏 6033

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

进程之间通过CWnd::SendMessage(WM_COPYDATA,*,*)发送和获取消息

<br />发送端代码:<br />void CProcessADlg::OnSendMessage() { // TODO: Add your control notification handler code here //找到接收消息的窗口(窗口名为Receiver) CString str="ProcessB"; CWnd *pWnd=CWnd::FindWindow(NULL,str); CString m_Msg1; GetDlgItem(IDC_EDIT1)->Ge

qinken547的专栏 1410

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

进程间传递消息 WM_COPYDATA的用法

 下面是postmessage工程的代码 COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/ CString m_szdata="这是CString字符串"; 这个就是要发送的字符串 cpd.dwData = 1;

天使的薄荷 2018

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

上一篇: mysql的视图、存储过程在还原备份功能上,噩梦暂时醒来。
下一篇: Delphi技巧集FAQs索引
skyjacker
博客等级 码龄23年 11粉丝 32原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值