Hello all!
I have a bit of code which, although it doesn't need "optimization" especially for speed, it is kinda ugly. I was wondering if people had any interesting ways of simplifying a case-like statement.
Specifically, the code I'm talking about is regarding scrolling the document. It compares each case of WM_VSCROLL, adds a value to the current scroll position, and redraws it by calling a proc I've defined called Scroll (imaginative, huh?)
There is a similar batch of code for handling key strokes that have the same effect.
So... any ideas???
I have a bit of code which, although it doesn't need "optimization" especially for speed, it is kinda ugly. I was wondering if people had any interesting ways of simplifying a case-like statement.
Specifically, the code I'm talking about is regarding scrolling the document. It compares each case of WM_VSCROLL, adds a value to the current scroll position, and redraws it by calling a proc I've defined called Scroll (imaginative, huh?)
There is a similar batch of code for handling key strokes that have the same effect.
So... any ideas???
WM_VSCROLL_HANDLER:
mov eax,wParam
cmp ax,SB_PAGEUP
jne @F
mov eax,ScrollInfo.nPos
sub eax,PageHeight
invoke Scroll,hWin,eax
ret
@@:
cmp ax,SB_PAGEDOWN
jne @F
mov eax,ScrollInfo.nPos
add eax,PageHeight
invoke Scroll,hWin,eax
ret
@@:
cmp ax,SB_LINEUP
jne @F
mov eax,ScrollInfo.nPos
sub eax,20
invoke Scroll,hWin,eax
ret
@@:
cmp ax,SB_LINEDOWN
jne @F
mov eax,ScrollInfo.nPos
add eax,20
invoke Scroll,hWin,eax
ret
@@:
cmp ax,SB_THUMBPOSITION
jne @F
shr eax,16
mov ScrollInfo.nPos,eax
invoke InvalidateRect,hWin,NULL,TRUE
ret
@@:
cmp ax,SB_THUMBTRACK
jne @F
shr eax,16
mov ScrollInfo.nPos,eax
invoke InvalidateRect,hWin,NULL,TRUE
@@:
ret
This topic has been brought up in multiple ways (note recursion :)):
http://www.asmcommunity.net/board/index.php?topic=1026
http://www.asmcommunity.net/board/showthread.php?s=&postid=24171
http://www.asmcommunity.net/board/index.php?topic=1026
http://www.asmcommunity.net/board/showthread.php?s=&postid=24171
BitRake,
I have seen these threads before. Thanks though. The reason I put the post up regardless of this fact is that I am looking at a very specific case vs. very general. For instance, the case handling of a windows message loop, where virtually every branch is completely different is not what I was looking for (although it does give me ideas). I find that this particular loop I'm looking to optimize is very "symmetric" in that most every branch calls the same function with a different value loaded.
Regards
--Chorus
I have seen these threads before. Thanks though. The reason I put the post up regardless of this fact is that I am looking at a very specific case vs. very general. For instance, the case handling of a windows message loop, where virtually every branch is completely different is not what I was looking for (although it does give me ideas). I find that this particular loop I'm looking to optimize is very "symmetric" in that most every branch calls the same function with a different value loaded.
Regards
--Chorus
I like macro's for the job. Im not saying this is the 'fastest' or 'smallest' approach, but it is quite readable as a case like structure, and the extra jump's arnt that big of a deal (most cases).
Macro #1: IF_MSG:
Macro #2: IF_WPARAM:
Example framework of their use:
I like this when pounding out new ideas and quickly handling stuff. Its also flexible, if you wanted one case to bleed into the next simply dont add the "jmp @end". Default cases are at the end of the IF_ Macro's. For both, the default here is 'passing the buck' to the windows' default handler.
Hope it helps
:alright:
NaN
Macro #1: IF_MSG:
IF_MSG MACRO WMsg:REQ, DoJmp:REQ
cmp uMsg, WMsg
jz DoJmp
ENDM
Macro #2: IF_WPARAM:
IF_WPARAM MACRO WPrm:REQ, DoJmp:REQ
cmp wParam, WPrm
jz DoJmp
ENDM
Example framework of their use:
_WndECProc proc USES EBX _hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
IF_MSG WM_CASE1, Do_Case1
IF_MSG WM_CASE1, Do_Case2
IF_MSG WM_COMMAND, Do_Command
; Default Case:
@return:
invoke DefWindowProc,_hWnd,uMsg,wParam,lParam
ret
@end:
xor eax, eax
jmp @return
;-------------------------------
Do_Case1:
;-------------------------------
; Case Code Here
jmp @end
;-------------------------------
Do_Case2:
;-------------------------------
; Case Code Here
jmp @end
;-------------------------------
Do_Command:
;-------------------------------
IF_WPARAM 1010, Do_Exit
IF_WPARAM 1011, Do_Something
jmp @return
;-=-=-=-=-=--=-=-=-=-=--=
Do_Exit:
;-=-=-=-=-=--=-=-=-=-=--=
invoke SendMessage,hWnd,WM_SYSCOMMAND,SC_CLOSE,NULL
jmp @end
;-=-=-=-=-=--=-=-=-=-=--=
Do_Something:
;-=-=-=-=-=--=-=-=-=-=--=
; Something code here
jmp @end
I like this when pounding out new ideas and quickly handling stuff. Its also flexible, if you wanted one case to bleed into the next simply dont add the "jmp @end". Default cases are at the end of the IF_ Macro's. For both, the default here is 'passing the buck' to the windows' default handler.
Hope it helps
:alright:
NaN
I find that this particular loop I'm looking to optimize is very "symmetric" in that most every branch calls the same function with a different value loaded.
Haha! Size-optimizing :) Here's the best I can make of it in 10 minutes.
Please note I'm a TASM coder (but learning MASM), and I don't know much about MASM's addressing syntax yet. More specifically, I'v assumed PageHeight is a variable. This causes the PAGEDOWN and PAGEUP compares to be in a different order than the original. If PageHeight is a constant (with EQU or =), then you can keep the original order by negating it were it is used (as in the LINEUP/LINEDOWN case)
WM_VSCROLL_HANDLER:
mov eax,wParam
mov ebx, PageHeight
cmp ax, SB_PAGEDOWN
je @@Scroll
neg ebx
cmp ax,SB_PAGEUP
je @@Scroll
mov ebx, -20
cmp ax,SB_LINEUP
je @@Scroll
neg ebx
cmp ax,SB_LINEDOWN
je @@Scroll
cmp ax,SB_THUMBPOSITION
je @@Scroll_Page
cmp ax,SB_THUMBTRACK
jne @@No_Scroll
@@Scroll_Page:
shr eax,16
mov ScrollInfo.nPos,eax
invoke InvalidateRect,hWin,NULL,TRUE
ret
@@Scroll:
add ebx,ScrollInfo.nPos
invoke Scroll,hWin,ebx
@@No_Scroll:
ret
Please note I'm a TASM coder (but learning MASM), and I don't know much about MASM's addressing syntax yet. More specifically, I'v assumed PageHeight is a variable. This causes the PAGEDOWN and PAGEUP compares to be in a different order than the original. If PageHeight is a constant (with EQU or =), then you can keep the original order by negating it were it is used (as in the LINEUP/LINEDOWN case)
WM_VSCROLL_HANDLER:
mov eax,wParam
mov ebx, PageHeight
cmp ax, SB_PAGEDOWN
je @@Scroll
neg ebx
cmp ax,SB_PAGEUP
je @@Scroll
mov ebx, -20
cmp ax,SB_LINEUP
je @@Scroll
neg ebx
cmp ax,SB_LINEDOWN
je @@Scroll
cmp ax,SB_THUMBPOSITION
je @@Scroll_Page
cmp ax,SB_THUMBTRACK
jne @@No_Scroll
@@Scroll_Page:
shr eax,16
mov ScrollInfo.nPos,eax
invoke InvalidateRect,hWin,NULL,TRUE
ret
@@Scroll:
add ebx,ScrollInfo.nPos
invoke Scroll,hWin,ebx
@@No_Scroll:
ret
Thanks for the replies :)
NaN, I like the ideas of the macros, it is very readable. However, I am actually implementing the version James posted (thanks James). It suits my needs pretty well, especially considering that I can merge my WM_KEYDOWN message with it :)
Thanks again everybody
--Chorus
NaN, I like the ideas of the macros, it is very readable. However, I am actually implementing the version James posted (thanks James). It suits my needs pretty well, especially considering that I can merge my WM_KEYDOWN message with it :)
Thanks again everybody
--Chorus