News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

An experiment of PostMessage().

Started by hyperon, March 21, 2007, 06:07:48 AM

Previous topic - Next topic

hyperon

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?

evlncrn8

might need a setfocus before the messaging, and remember to restore the focus to what it was before you began

hyperon

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?

hutch--

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.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

hyperon

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.

PBrennick

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
The GeneSys Project is available from:
The Repository or My crappy website

Vortex

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

hyperon

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.

sinsi

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.
Light travels faster than sound, that's why some people seem bright until you hear them.