We all know that we use the 'DispatchMessage' function in our
message pumper/loop. So what does it actually do? well it just forwards
the messages to the message-handler(WndProc), for further examination.
I might be wrong about this assumption but as far as I can see it does
nothing else.

While reading texts/source code/etc. I have never seen someone trying
to substitute the api call with code before now! ( :grin: ) feel free to correct
me if I am wrong.

Anyway, I have probably bored you already. So lets get to the real part,
as i sayd before: the DispatchMessage function only forwards the message
to the message-handler(WndProc). So why not just forward the messages
ourself instead? there are probably more optimized or smaller methods todo
this sortof thing. But this his how I decided to create it.
[COLOR=SIENNA]

...
externdef _imp__DefWindowProcA:dword
...
xor ebp,ebp
mov esi,offset msg
@@: inv GetMessageA, esi, ebp, ebp, ebp
test eax, eax [color=green];[/@-check for wm_quit[/color]
je @F
push dword ptr[esi+12] [color=green];[/@-lParam[/color]
push dword ptr[esi+08] [color=green];[/@-wParam [/color]
push dword ptr[esi+04] [color=green];[/@-message[/color]
push dword ptr[esi+00] [color=green];[/@-hWnd[/color]
call WndProc
jmp @B
@@: inv ExitProcess,[esi+8]

WndProc proc
hWnd equ dword ptr [esp+04]
uMsg equ dword ptr [esp+08]
wParam equ dword ptr [esp+12]
lParam equ dword ptr [esp+16]
.if uMsg==WM_DESTROY
inv PostQuitMessage, edx [color=green];[/@-EDX=0[/color]
.else
[color=green];[/@-parameters already on the stack[/color]
jmp _imp__DefWindowProcA
.endif
ret 4 * sizeof dword [color=green];[/@-cleanstack[/color]
WndProc endp
[/COLOR]

Hopefully someone has something to add/subtract to this message.
Since I am not 100% shure that this code would work in a complex code
structure or not. I developed it inside a small application with few messages.
Please comment, flame, laugh, cry, etc.:alright:
Posted on 2002-12-07 20:43:17 by natas
i dont use pumps or loops !
Posted on 2002-12-07 20:48:32 by Qages
This is an old topic. Search the board for DispatchMessage.


The performance gain from doing this isn't significant or noticeable. All you end up with is bigger size. It also goes agains MS's recommendations to do it this way, and this is potentially dangerous if you want your program to work on future versions of windows.

Regardless, here are some things you can try and then see if your program still works:

- Create and manage more than one window.
- Try to post a message intended solely for your thread using PostThreadMessage.
- Try to use a WM_TIMER callback.

Try those things and then decide if DispatchMessage is still not a good solution. ;)
Posted on 2002-12-08 01:03:54 by iblis
Iblis, First, As i previously stated I know that this might not be a good
thing in all possible situations. However I didnt know that it had been
discussed before.

Why should this generate more code? since we are importing one less api,
and calling one less api, this cannot increase the size.

Doesnt increase the speed? well I havent tested this for performance.
But I would assume that if I can get away with not calling an api
inside a loop I would defintly say that this should be faster.

But do you know the most important thing about about this? I expanded my
knowledge. I have just started to get involved with creating windows etc.
When I started for about one month ago with assembly, I was just reading
and creating console based snippets.

So in the end I have only gained knowledge my friend. :alright:
Posted on 2002-12-08 08:06:10 by natas
natas, I brought up the very same thing a while back :)

http://www.asmcommunity.net/board/index.php?topic=7158

Conclusion of the thread: Yes it'll work, and it is faster to call the proc directly, but I wouldn't say it's "legitimate" programming.

--Chorus
Posted on 2002-12-08 20:01:03 by chorus
Chorus, I guess that was the thread that iblis was talking
about then. But as you also stated in your posts, this is not a waste
of time. Since we expanded our knowledge. I learned alot from doing
this, alot of things wich isnt obvious to the reader. :alright:
Posted on 2002-12-08 20:17:01 by natas
Natas, my goal was not to discourage you from learning, but to discourage you from getting into the habit of bypassing DispatchMessage and other such practices recommended by MS.

It may or may not be a good learning experience, but in practice it's often not wise to circumvent the APIs.
Posted on 2002-12-09 02:09:01 by iblis
Iblis, I didnt think that you where trying to discourage me from learning.
All I wanted to say was that I learned something from this, even if I cannot
use the knowledge I gained directly, I can use it indirectly. ( ;) )
Posted on 2002-12-09 04:00:08 by natas
iblis,
"..MS's recommendations to do it this way.."
Where? Pls, answer if you know

May be in their old MASM-C like or ANSI C examples..
And what about "MS's recommendations to do it this way"
in their C++,VB ,VJava and C# examples?

"and this is potentially dangerous if you want your
program to work on future versions of windows."
Why? GetMessageA must be the same for compatibility?


chorus,
What is a "legitimate" ASM programming and
who is the "legitimator"?



donkey,
". but that defeats one of the original goals of Windows, the BLACK BOX"

What about the "original goal" of Linux?
Which is better, BLACK or "WHITE" BOXES?



Natas,
I like the curious people and ESI and EBP usage in your main loop,
but you can try to substitute next four push's and one call
with Hutch's "High speed message dispatcher" (see algo section)
and it is just "to expand our knowledge", he..he



Best regards,
Lingo
Posted on 2002-12-09 19:40:13 by lingo12
To answer the question directed at myself:
Legitimate programming is following the rules laid out by the operating system that you have implicitly agreed to. The "legitimator" is the end user.
The user doesn't want to worry if his program will run on Windows 2005 because if the program is written correctly, it will. That's half the reason MS uses "Black Box" APIs.
Consider, for example, that in calling GetWindowLong to get the address of the window procedure for any given window, you are either handed the address of the proc or a handle representing that address. In the case of getting a handle back, you must use CallWindowProc instead of call eax (or similar) or you'll crash the program. DispatchMessage takes care of things like this for you. Personally, I have not come across a case where I have recieved a handle instead of a pointer to the WndProc. But that's doesn't mean later versions of Windows won't move in this direction. And why risk it just to end up re-writing the program down the road?

All in all, I think it's a great idea to poke into the APIs and see if they can be replaced. I for one like to use only a few of the lower APIs so that I can customize certain behavior (ex I don't use DrawText because it's really just a wrapper for ExtTextOut). However, in the case of DispatchMessage, I believe it's use is unavoidable.

As a side note, perhaps it's possible to replace TranslateMessage...

--Chorus
Posted on 2002-12-09 20:10:37 by chorus
Chorus,
I don't want to bother you, but which code belongs to
"legitimate" programming?
(I suppose you can read C code and translate it to ASM)

From MSDN->GetMessage() API
 

"If there is an error, the return value is -1.
For example, the function fails if hWnd is an invalid
window handle or lpMsg is an invalid pointer.
To get extended error information, call GetLastError.
Warning Because the return value can be nonzero,
zero, or -1, [B]avoid[/B] code like this:

while (GetMessage( lpMsg, hWnd, 0, 0)) ...

The possibility of a -1 return value means that such
code can lead to fatal application errors.
[B]Instead[/B], use code like this:

BOOL bRet;
while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}" (see example too)

or from people's examples here:


" .WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret"

and


" MsgLoop proc
LOCAL msg:MSG
StartLoop:
invoke GetMessage,ADDR msg,NULL,0,0
cmp eax, 0
je ExitLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp StartLoop
ExitLoop:
mov eax, msg.wParam
ret"


Regards,
Lingo
Posted on 2002-12-12 13:19:13 by lingo12
Nice approach amigo,is it functionning safely everytime?

Regards,

Vortex
Posted on 2002-12-12 14:01:29 by Vortex
is not latest proc needs "lea" ?


lea eax, msg
invoke TranslateMessage, eax


...and so on ?
Posted on 2002-12-12 19:07:29 by cakmak
msg is already a pointer, so there is no need to load effective address.
Posted on 2002-12-12 20:17:52 by roticv
With a question like the topic, I respond with,

1. can you extend it and run it on all windows versions ?

2. Do you get any advantage from doing it ?

3. Should you assume that the message dispatching from the main message loop is processed the same way in every windows version ?

Unless you can say yes with certainty to all 3 questions, stick with the documented technique as it is designed to work this way. It may be "cute", "novel" or "fun" to play with API functions but if you want reliable code that works properly and works across different windows versions, do it the documented way.

Anyone who has worked in Windows coding for any length of time knows it is a can of worms that does not hang together all that well, the documentation is one of the few things that is vaguely reliable and you only have to track variations from version to version.

Unless you are processing keystrokes, you do not need to use the API "TranslateMessage". Below is a normal message loop, ESI is already XORRED to zero.



jmp @F

StartLoop:
invoke DispatchMessage, ADDR msg
@@:
invoke GetMessage,ADDR msg,esi,esi,esi
cmp eax, 0
jne StartLoop


Regards,

hutch@movsd.com
Posted on 2002-12-12 21:32:07 by hutch--
lingo, to quickly address your post:

I would consider all three examples to be legimate. I believe GetMessage will only fail if one of the parameters is invalid, and supposing you can correctly define a MSG structure and reference it, I can't see GetMessage erroring out. Note that the API says to avoid code where GetMessage explicitly states a window handle. Am I nit-picking? Sure. But isn't that the entire point of your line of questioning?

It's certainly not perfect programming to forego error checking. But when was the last time any of us checked the result of GetModuleHandle? In fact, I believe every single API has an error condition. Watching for them all would end up in monstrous code...

Would my definition of legitimate hold up in the Court of Programming Law? Maybe not... but I think it gets across the point that I want to make (casually) in this forum: do what you want, but if you want other people to value your work, play by the rules

--Chorus
Posted on 2002-12-12 23:51:25 by chorus
IMO including error checking in a final product is only necessary if the potential error might be the fault of something other than the programmer. One should not need to check for their own errors if such errors are normally avoidable.
Posted on 2002-12-13 00:23:18 by iblis
Chorus,

"I would consider all three examples to be legimate"
"..if you want other people to value your work, play by the rules"

Very convenient philosophy. Congratulations!


Regards,
Lingo
Posted on 2002-12-13 01:07:31 by lingo12