I used the following procedure to make an experiment of PostMessage():
SendtoNotePad proc uses eax ebx edi esi,hEditor,lpszMsg
.if hEditor ;It is the handle to NotePad's window which receives a succession of WM_CHARs.
mov esi,lpszMsg
cld
.repeat
lodsb
or al,al
.break .if ZERO?
movzx eax,al
invoke PostMessage,hEditor,WM_CHAR,eax,1
.until FALSE
.endif
ret
SendtoNotePad endp
The below is program's frame of the experiment:
WindowProc proc uses ebx edi esi,hWnd,Msg,wParam,lParam
;To translate Msg into proper text and save into a buffer.
......
......
......
invoke SendtoNotePad,hNotePad,offset szBuffer
mov eax,Msg
;To deal with Msg.
......
......
......
ret
WindowProc endp
WinMain proc
;Get the handle to NotePad's window which receives a succession of WM_CHARs.
;And hNotePad = the handle.
......
......
......
invoke GetModuleHandle,NULL
mov hInstance,eax
;Register a window class
......
......
......
invoke SendtoNotePad,hNotePad,offset szMsg1
;To Create a window, and hWindow = the handle to the new window.
......
......
......
invoke SendtoNotePad,hNotePad,offset szMsg2
invoke SendtoNotePad,hNotePad,offset szMsg3
invoke ShowWindow,hWindow,SW_SHOWNORMAL
invoke SendtoNotePad,hNotePad,offset szMsg4
invoke SendtoNotePad,hNotePad,offset szMsg5
invoke UpdateWindow,hWindow
invoke SendtoNotePad,hNotePad,offset szMsg6
invoke SendtoNotePad,hNotePad,offset szMsg7
.while TRUE
invoke GetMessage,addr stMsg,NULL,0,0
.break .if (!eax)
invoke TranslateMessage,addr stMsg
invoke DispatchMessage,addr stMsg
.endw
invoke SendtoNotePad,hNotePad,offset szMsg8
ret
WinMain endp
The :
After opening a NotePad's window, I ran above program and got a strange outcome from the experiment of PostMessage().
In NotePad's window, Msg1, Msg2 and Msg3 are shown completely, and the others can't be found,
besides the text which was getted by translating Msg was shown incompletely.
Why?
might need a setfocus before the messaging, and remember to restore the focus to what it was before you began
I looked up MSDN and found a piece of specifications about PostMessage():
"The PostMessage function places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message."
I conjectured that NotePad didn't process each WM_CHAR.
To verify my conjecture and enforce NotePad process all WM_CHARs, I used SendMessage() instead of PostMessage().
After running the program again, I believe that my conjecture is correct.
If my conjecture is correct, NotePad should disregard some WM_CHAR messages.
Why?
You have a few unknowns in what you are trying to do, Notepad does not appear to be written from ordinary Windows components so you may not have enough information on what it processes in terms of messages but another factor that is often overlooked is the limitations of communicating between two threads that do not share the same memory which is normal between threads.
The techniques with the message qeue hark back from the 16 bit days when all applications ran in the same memory space where you could do almost anything between apps but as later versions isolate memory space between apps, many of these techniques don't work or at least not properly anymore. The catch is that most of this stuff is not documented and will change from version to version so you may not get a reliable method that works across all Windows versions.
Thanks! I know that 4G memory space is independent for each application, the fact means that one application transfers offset address to the other may fail.
But my program didn't use pointers in message parameters, in SendtoNotePad(), PostMessage() posted a WM_CHAR message in NotePad's message queue and returned without waiting for NotePad to process it,
if NotePad didn't disregard some WM_CHAR messages, my program should work fine, and I can get a normal outcome from the experiment.
Obviously, something arose and free NotePad's message queue, the question is: What is the unknown factor?
After using SendMessage() instead of PostMessage(), each character which transfer to NotePad by WM_CHAR message is almost shown,
except my program is broken by incoming nonqueued messages.
hyperon,
Have you looked at Vortex's example on how to do this? It is in the Genesys package. Or you could email him directly. The example is called Autotype.
Paul
hyperon,
Here a simple example showing how to send messages to the client area of notepad.exe :
.386
.model flat,stdcall
option casemap:none
include \GeneSys\include\windows.inc
include \GeneSys\include\user32.inc
include \GeneSys\include\kernel32.inc
includelib \GeneSys\lib\user32.lib
includelib \GeneSys\lib\kernel32.lib
.data
message db 'Hello my friend!', 13, 10
db 'This is an autotyping example. :)', 0
app db 'notepad.exe', 0
wndclass db 'Notepad', 0
childclass db 'Edit', 0
.data?
handle dd ?
.code
start:
invoke WinExec, ADDR app, SW_SHOW
invoke FindWindow, ADDR wndclass, 0
invoke FindWindowEx, eax, 0, ADDR childclass, 0
mov handle, eax
mov esi, OFFSET message
@@:
movzx eax,BYTE PTR [esi]
test eax,eax
jz @f
invoke SendMessage, handle, WM_CHAR, eax, 0
invoke Sleep, 200
inc esi
jmp @b
@@:
invoke ExitProcess, 0
END start
To Vortex:
Thanks! I know how to do this, but it is not the key about my question.
Maybe you neglected that my program called SendtoNotePad() at the entrance of WindowProc(),
and it means that SendtoNotePad() was called whenever Windows calls WindowProc().
Thus a normal outcome from the experiment is like the following:
************************************************************************************************************************************************************************
Msg1
Msg: 0x0024, Message: WM_GETMINMAXINFO , wParam: 00000000, lParam: 0063fbec
Msg: 0x0081, Message: WM_NCCREATE , wParam: 00000000, lParam: 0063fc40
Msg: 0x0083, Message: WM_NCCALCSIZE , wParam: 00000000, lParam: 0063fc60
Msg: 0x0001, Message: WM_CREATE , wParam: 00000000, lParam: 0063fc40
Msg2
Msg3
Msg: 0x0018, Message: WM_SHOWWINDOW , wParam: 00000001, lParam: 00000000
Msg: 0x0046, Message: WM_WINDOWPOSCHANGING , wParam: 00000000, lParam: 0063fc3a
Msg: 0x0046, Message: WM_WINDOWPOSCHANGING , wParam: 00000000, lParam: 0063fb1e
Msg: 0x001c, Message: WM_ACTIVATEAPP , wParam: 00000001, lParam: fffdb017
Msg: 0x0086, Message: WM_NCACTIVATE , wParam: 00000001, lParam: 00000000
Msg: 0x000d, Message: WM_GETTEXT , wParam: 000000ff, lParam: 0063f920
Msg: 0x0006, Message: WM_ACTIVATE , wParam: 00000001, lParam: 00000000
Msg: 0x0007, Message: WM_SETFOCUS , wParam: 00000000, lParam: 00000000
Msg: 0x0085, Message: WM_NCPAINT , wParam: 00000001, lParam: 00000000
Msg: 0x000d, Message: WM_GETTEXT , wParam: 000000ff, lParam: 0063f96e
Msg: 0x0014, Message: WM_ERASEBKGND , wParam: 0000108e, lParam: 00000000
Msg: 0x0047, Message: WM_WINDOWPOSCHANGED , wParam: 00000000, lParam: 0063fc74
Msg: 0x0005, Message: WM_SIZE , wParam: 00000000, lParam: 0171024c
Msg: 0x0003, Message: WM_MOVE , wParam: 00000000, lParam: 007d006a
Msg4
Msg5
Msg: 0x000f, Message: WM_PAINT , wParam: 00000000, lParam: 00000000
Msg6
Msg7
Start getting a message.
Msg: 0x0084, Message: WM_NCHITTEST , wParam: 00000000, lParam: 0088011a
Msg: 0x0020, Message: WM_SETCURSOR , wParam: 000007b0, lParam: 02000001
Got a message, Msg = 0x0200.
Start dispatching a message.
Msg: 0x0200, Message: WM_MOUSEMOVE , wParam: 00000000, lParam: 000b00b0
Start getting a message.
......
......
......
Start getting a message.
Msg: 0x0084, Message: WM_NCHITTEST , wParam: 00000000, lParam: 007002ac
Msg: 0x0020, Message: WM_SETCURSOR , wParam: 000007b0, lParam: 02010014
Got a message, Msg = 0x00a1.
Start dispatching a message.
Msg: 0x00a1, Message: WM_NCLBUTTONDOWN , wParam: 00000014, lParam: 007002ac
Msg: 0x0215, Message: WM_CAPTURECHANGED , wParam: 00000000, lParam: 00000000
Msg: 0x0112, Message: WM_SYSCOMMAND , wParam: 0000f060, lParam: 007002ac
Msg: 0x0010, Message: WM_CLOSE , wParam: 00000000, lParam: 00000000
Msg: 0x0046, Message: WM_WINDOWPOSCHANGING , wParam: 00000000, lParam: 0063f658
Msg: 0x0047, Message: WM_WINDOWPOSCHANGED , wParam: 00000000, lParam: 0063f692
Msg: 0x0086, Message: WM_NCACTIVATE , wParam: 00000000, lParam: 00000000
Msg: 0x0006, Message: WM_ACTIVATE , wParam: 00000000, lParam: 00000000
Msg: 0x001c, Message: WM_ACTIVATEAPP , wParam: 00000000, lParam: fff83c37
Msg: 0x0008, Message: WM_KILLFOCUS , wParam: 00000000, lParam: 00000000
Msg: 0x0002, Message: WM_DESTROY , wParam: 00000000, lParam: 00000000
Msg: 0x0082, Message: WM_NCDESTROY , wParam: 00000000, lParam: 00000000
Start getting a message.
Msg8
************************************************************************************************************************************************************************
Under Windows 98, if I used PostMessage() without using SendMessage(),
then Msg1, Msg2 and Msg3 are shown completely, and the others can't be found,
besides the text which was getted by translating Msg was shown incompletely.
The strange outcome is like the following:
************************************************************************************************************************************************************************
Msg1
Msg: 0x0024, Message: WM_GETMINMAXINFO , wParam: 00000000, lParam: 0063fbec
Msg: 0x0081, Message: WM_NCCREATE , wParam: 00000000, lParam: 0063fc40
Msg: 0x0083, Message: WM_NCCALCSIZE , wParam: 00000000, lParam: 0063fc60
Msg: 0x0001, Message: WM_CREATE , wParam: 00000000, lParam: 0063fc40
Msg2
Msg3
Msg: 0x0018, Message: WM_SHOWWINDOW , wParam: 00000001, lParam: 00000000
Msg: 0x0046, Message: WM_WINDOWPOSCHANGING , wParam: 00000000, lParam: 0063fc3a
Msg: 0x0046, Message: WM_WINDOWPOSCHANGING , wParam: 00000000, lParam: 0063fb1e
Msg: 0x001c, Message: WM_ACTIVATEAPP , wParam: 00000001, lParam: fffdb017
Msg: 0x0086, Message: WM_NCACTIVATE , wParam: 00000001, lParam: 00000000
Msg: 0x000d, Message: WM_GETTEXT , wParam: 000000ff, lParam: 0063f920
Msg: 0x0006, Message: WM_ACTIVATE , wParam: 00000001, lParam: 00000000
Msg: 0x0007, Message: WM_SETFOCUS _NCPAINT , wParam: 00000001, lParam: 00000000
Msg: 0x000 0x0047, Message: WM_WINDOWPOSCHANGED , wParam: 00000000, lParam: 0063fc74
Msg: 0x0005, Message: WM_SIZE , wParam: 00000000, lParam: 0171024c
Msg: 0x0003, Message: WM_MOVE , wParam: 00000000, lMsg: 0x000f, Message: WM_PAINT , wParam: 00000000, lParam: 00000000
Msg: 0x0084, Message: WM_NCHITTEST , wParam: 00000000, lParam: 008100ee
Msg: 0x0020, Message: WM_SETCURSOR , wParam: 000008c4, lParam: 02000001
Got a message, Msg = 0x0200.
Start dispatching a message.
Msg: 0x0200, Message: WM_MOUSEMOVE , wParam: 00000000, lParam: 00040084
Start getting a message.
......
......
......
Msg: 0x0084, Message: WM_NCHITTEST , wParam: 00000000, lParam: 01580181
Msg: 0x0020, Message: WM_SETCURSOR , wParam: 000008c4, lParam: 0oVE , wPara
Start geMsg: 0x0084, Message: WM_NCHITTEST , wParam: 00000000, lParam: 0070026f
Msg: 0x0020, Message: WM_SETCURSOR , wParam: 000008c4, lParamGot a message, Msg = 0, MessMsg: 0x0084, Message: WM_NCHITTEST , wParam: 00000000, lParam: 0064028e
Msg: 0x0020, Message: WM_SETCURSOR , wParam: 000008c4, lParam: 0200000c
Got a message, Msg = 0x00a0.
Start dispatching a message.
Msg: 0x00a0, Message: WM_NCMOUSEMOVE , wParam: 0000000c, lParam: 0064028e
Start getting a message.
Msg: 0x0084, Message: WM_NCHITTEST , wParam: 00000000, lParam: 00650290
Msg: 0x0020, Message: WM_SETCURSOR , wParam: 000008c4,oMsg: 0x0084, Message: WM_NCHITTEST , wParam: 00000000, lParam: 006d02a0
Msg: 0x0020, Message: WM_SETCURSOR , wParam: 000og: 0x00a0, Message: WM00009, lParamMsg: 0x0084, Message: WM_NCHITTEST , wParam: 00000000, lParam: 007102ad
Msg: 0x0020, Message: WM_SETCURSOR , wParam: 000008c4, lParam: 02000014
ot a meting a Msg: 0x0084, Message: WM_NCHITTEST , wParam: 00000000, lParam: 007602b5
Msg: 0x0020, Message: WM_SETCURSOR , wParam:o.
Msg: VEStart getting aMsg: 0x0084, Message: WM_NCHITTEST , wParam: 00000000, lParam: 007602b5
Msg: 0x0020, Message: WM_SETCURSOR , wParam: 000008c4, ohinMsg: 0x0215, Message: WM_CAPTURECHANGED , wParam: 00000000, lParam: 00000000
Msg: 0x0112, Message: WM_SYSCOMMAND , wPa,sg: 0x0046, Message: WM_WIam: 00000000, lParam: 0063f6
************************************************************************************************************************************************************************
To observe above, I conjecture that there are something to free NotePad's message queue,
but I don't details.
I think you need to send WM_CHAR to the Edit child of Notepad, as Vortex has shown. As Hutch said, you don't know the internals
of Notepad's message pump, so it might disable certain messages if it hasn't got the focus.
If you are going to use SendMessage/PostMessage to another app, you need to have a pretty good idea of what it will do when it
receives the message.