i have a strange problem with SetMenu
it seems that it alters an unrelated dword in initialized data
has anyone else had this kind of trouble?
.DATA
WinStates dd 1Fh
;
;
WndProc PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
mov ecx,uMsg
;
;
;
cmp ecx,WM_CREATE
jz WndPrY
;
;
;
WndPrY: INVOKE wmCreate,hWnd
jmp WndPr0
;
;
;
wmCreate PROC USES EDI hWnd:HWND
xor edi,edi
INVOKE LoadMenu,hInstance,IDM_MAINMENU
mov hMenu,eax
push WinStates
INVOKE SetMenu,hWnd,eax
pop WinStates
;
;
the push/pop WinStates instructions fix the problem :dazzled:
Very odd, Dave.
WinStates is the first item in .data ? Have you watched in Olly what's happening? Can you post the full code?
i think i figured it out ;)
when you call SetMenu, it must send a WM_SIZE message
at any rate, i am close - lol
How could a WM_SIZE message cause your problem?
Quote from: dedndave on February 06, 2011, 10:52:41 AM
when you call SetMenu, it must send a WM_SIZE message
Maybe, but even then, on return the value of WinStates is still the same. Use a global var to check if your check is balanced, often that is the problem.
my wmSize routine alters WinStates
the routine is in the test phase, and at this point zeros WinStates
however, it is invalid - and i do not want it called until all the control windows are created
the control windows are created right after SetMenu :P
i'll figure it out today
if i have to, i'll disable wmSize until all control windows are created
the solution was simple
in wmCreate, i create all the control windows before i load/set the menu :bg
(http://l.yimg.com/us.yimg.com/i/mesg/emoticons7/24.gif)
what's wrong with this picture.....
ALIGN 16
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
wmSize PROC dwWidth:DWORD,dwHeight:DWORD
that'll teach me to use copy/paste
Let me guess:
...
ret 8
? :bg
oddly enough - that didn't cause the problems
but - EBP was pointing to the wrong place, that's for sure - lol
all kinds of stuff was happening
i fought that fucker for a week
i appreciate the help that i have gotten from Edgar, Jochen, and Alex
EDIT - updated code below
by the way...
what tipped me off was when the horizontal scroll bar Y position moved when sizing the window horiontally - lol
i knew i had passed the parms correctly - checked and double-checked :P
Hi Dave,
Glad you got it done, it did present some interesting problems and it appears that you've solved them all.
i wonder what you thought of the way i handled DeferWindowPos :P
i mean - pushing everything onto the stack then looping
Good idea, I usually use invoke because GoAsm will assemble it properly for 32/64 bit platforms while push/call will fail but if the app is only ever going to be for 32 bit its a good way to get the job done. Tends to obfuscate the code a bit though, makes it a bit harder to read through the source but that's not an issue if you're the only one whose going to be editing it.
lol
it seems all my best code is like that
it makes perfect sense to me :bg
i could eliminate the SHOW loop - and combine it into the HIDE loop - save a few bytes
but, it might be slower, having to draw certain windows twice
EDIT - come to think of it, i could do the shows and hides in a single loop after positioning
a little more complicated, but i think i'll give it a try
it works great with the hide/show loop combined :bg
if a window is to be hidden, it's position isn't updated, anyways
;*************************************************************************************************************
ALIGN 16
OPTION PROLOGUE:None
OPTION EPILOGUE:None
wmSize PROC dwWidth:DWORD,dwHeight:DWORD
;Each control window has a bit in WinStates that indicates the current show/hide state for that window.
;The "old" WinStates flags reside in the WinStates dword.
;The "new" WinStates flags reside at [EBP-4], and replaces the "old" WinStates flags when done.
;
;For each control window, the new state/position is calculated.
;If a control window needs to be repositioned, ESI is incremented and 7 parameters are pushed onto the stack.
;These represent the last 7 of the 8 parameters for DeferWindowPos, or the 7 parameters for SetWindowPos.
;For DeferWindowPos, the remaining parameter is pushed inside the defer loop.
;Also, the new position and size values for that control window are updated for later comparison.
;
;Once the stack is set up and the newWinStates dword is created:
; 1) defer window positions as required (ESI indicates count) or set window position for a single window
; 2) hide any control windows that are showing and need to be hidden
; show any control windows that are hidden and need to be showing
; 3) update WinStates dword
;----------------------
;stack frame TEXTEQUates
sHeight TEXTEQU <[EBP+24]> ;client area height
sWidth TEXTEQU <[EBP+20]> ;client area width
; <[EBP+16]> ;RETurn address
; <[EBP+12]> ;saved EBX contents
; <[EBP+8]> ;saved ESI contents
; <[EBP+4]> ;saved EDI contents
; <[EBP]> ;saved EBP contents
newWinStates TEXTEQU <[EBP-4]> ;new WinStates dword
;----------------------
;SP_FLAGSET EQU SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOOWNERZORDER
;
;IDC_STATUSBAR EQU 1001h ;4097
;IDC_HSCROLLBAR EQU 1002h ;4098
;IDC_VSCROLLBAR EQU 1004h ;4100
;IDC_SIZEBOXN EQU 1008h ;4104
;IDC_SIZEGRIP EQU 1010h ;4112
;
;ControlHandles LABEL dword
;hStatus dd ?
;hHScroll dd ?
;hVScroll dd ?
;hSizeBoxNG dd ?
;hSizeBoxG dd ?
;----------------------
push ebx
push esi
push edi
push ebp
xor ebx,ebx ;EBX = newWinStates
mov ebp,esp
mov esi,ebx ;ESI = control update count
mov edi,ebx ;EDI = 0
push ebx ;[EBP-4] = newWinStates
;----------------------
;status bar
cmp edi,StbState
mov edx,sHeight
mov ecx,sWidth
jz sScrl0
sub edx,StbHeight
inc ebx ;set IDC_STATUSBAR bit
cmp ecx,StbWidth
jnz sStBar
cmp edx,StbPosY
jz sScrl0
sStBar: push SP_FLAGSET ;uFlags
inc esi
push StbHeight ;cy (height)
push ecx ;cx (width)
mov StbWidth,ecx
push edx ;y (y pos)
push edi ;x (x pos)
mov StbPosY,edx
push edi ;hWndInsertAfter
push hStatus ;hWnd
;----------------------
;scroll bar test-retest
sScrl0: cmp ecx,hsi.nMax
ja sScrl1
sub edx,HSbHeight
or ebx,IDC_HSCROLLBAR and 1Fh
sScrl1: cmp edx,vsi.nMax
ja sHScr0
sub ecx,VSbWidth
test ebx,IDC_HSCROLLBAR
jnz sScrl2
cmp ecx,hsi.nMax
ja sScrl2
or ebx,IDC_HSCROLLBAR and 1Fh
sub edx,HSbHeight
sScrl2: or ebx,IDC_VSCROLLBAR and 1Fh
;----------------------
;horizontal scroll bar
sHScr0: test ebx,IDC_HSCROLLBAR
jz sVScr0
cmp ecx,hsi.nPage
jz sHScr1
mov hsi.nPage,ecx
push ecx
push edx
INVOKE SetScrollInfo,hHScroll,SB_CTL,offset hsi,FALSE
pop edx
pop ecx
jmp short sHScr2
sHScr1: cmp edx,HSbPosY
jz sVScr0
sHScr2: push SP_FLAGSET ;uFlags
inc esi
push HSbHeight ;cy (height)
push ecx ;cx (width)
push edx ;y (y pos)
push edi ;x (x pos)
mov HSbPosY,edx
push edi ;hWndInsertAfter
push hHScroll ;hWnd
;----------------------
;vertical scroll bar
sVScr0: test ebx,IDC_VSCROLLBAR
jz sSzBx0
cmp edx,vsi.nPage
jz sVScr1
mov vsi.nPage,edx
push ecx
push edx
INVOKE SetScrollInfo,hVScroll,SB_CTL,offset vsi,FALSE
pop edx
pop ecx
jmp short sVScr2
sVScr1: cmp ecx,VSbPosX
jz sSzBx0
sVScr2: push SP_FLAGSET ;uFlags
inc esi
push edx ;cy (height)
push VSbWidth ;cx (width)
push edi ;y (y pos)
push ecx ;x (x pos)
mov VSbPosX,ecx
push edi ;hWndInsertAfter
push hVScroll ;hWnd
;----------------------
;size boxes
sSzBx0: push ebx
mov eax,(IDC_HSCROLLBAR or IDC_VSCROLLBAR) and 1Fh
and ebx,eax
cmp eax,ebx
pop ebx
jnz SetPos
test bl,1
jz sSzBx1
or ebx,IDC_SIZEBOXN and 1Fh
cmp ecx,BngPosX
mov eax,hSizeBoxNG
jnz sSzBx2
cmp edx,BngPosY
jz SetPos
mov BngPosX,ecx
mov BngPosY,edx
jmp short sSzBx2
sSzBx1: or ebx,IDC_SIZEGRIP and 1Fh
cmp ecx,BsgPosX
mov eax,hSizeBoxG
jnz sSzBx2
cmp edx,BsgPosY
jz SetPos
mov BsgPosX,ecx
mov BsgPosY,edx
sSzBx2: push SP_FLAGSET ;uFlags
push HSbHeight ;cy (height)
inc esi
push VSbWidth ;cx (width)
push edx ;y (y pos)
push ecx ;x (x pos)
push edi ;hWndInsertAfter
push eax ;hWnd
;----------------------
;set window position(s)
;ESI = window update count
;stack: 7 parms per ESI count
SetPos: dec esi
mov newWinStates,ebx
jz sSetWP
inc esi
jz State0
INVOKE BeginDeferWindowPos,esi
sDefer: push eax
CALL DeferWindowPos
dec esi
jnz sDefer
INVOKE EndDeferWindowPos,eax
jmp short State0
sSetWP: CALL SetWindowPos
;----------------------
;not hide = newWinStates OR NOT(old_WinStates)
; show = newWinStates AND NOT(old_WinStates)
State0: mov eax,WinStates
mov edi,offset ControlHandles
mov ebp,newWinStates
not eax
mov ebx,ebp
mov esi,5
and ebp,eax ;EBP = show
or ebx,eax ;EBX = not hide
State1: xor eax,eax
shr ebp,1
rcl eax,1
shl eax,1
shr ebx,1
rcl eax,1
cmp al,1
jz State2
INVOKE ShowWindow,[edi],eax
State2: dec esi
lea edi,[edi+4]
jnz State1
;----------------------
pop WinStates
pop ebp
pop edi
pop esi
pop ebx
ret 8
wmSize ENDP
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
;*************************************************************************************************************
i haven't added the scroll code, yet, but here is an example so you can see the scroll bars hide/show
also, you can see the size box is selected according to whether or not the status bar is enabled (with or without grippies)
posted an updated version below
Quote from: dedndave on February 08, 2011, 01:41:05 AM
i haven't added the scroll code, yet, but here is an example so you can see the scroll bars hide/show
also, you can see the size box is selected according to whether or not the status bar is enabled (with or without grippies)
I don't understand what you want to tell. Where do we "see" scroll bars or a "size box"? Do you suggest that your code is "readable"? Perhaps an example for noobies to learn from?
No. It looks like what it is: the early adventures of someone learning the Windows GUI API.
Quote from: japheth on February 08, 2011, 06:34:19 AMNo. It looks like what it is: the early adventures of someone learning the Windows GUI API.
I thought with old age people would get wiser and more patient ::)
Quote from: jj2007 on February 08, 2011, 06:53:10 AM
I thought with old age people would get wiser and more patient ::)
Perhaps a misconception. Or, it's true, but you just don't know how bad the status was in my younger years.
Back to my remark about Dave's code: it's seen from my perspective ( of course ), and I absolutely don't mind if your opinion differs. IMO it's a style of coding which is very much responsible for assembly language's bad reputation: difficult to read for others, hard to maintain and a card house.
if you can offer some constructive critisism, i'd be happy to hear it
or - perhaps you have some code to post that is somehow better
otherwise, keep your mouth shut and your eyes open
you're wasting your time passing out insults instead of instruction, as i tend to ignore them
who knows - "andreas the great" may actually learn something
Calm down boys.
I think both Japheth's and Dave's points are valid. When I write any code as an example or something that others might learn from I tend to lean more towards easily readable, however my "inhouse" code tends to be more like Dave's. In the end it is a personal choice, you do whatever you're most comfortable with and damn everyone else. As for assembly language's reputation, it's really not an issue, I write mainly in C and assembler because that is what I write in, whether anyone else chooses to do so is up to them.
Quote from: dedndave on February 08, 2011, 08:16:15 AM
if you can offer some constructive critisism, i'd be happy to hear it
or - perhaps you have some code to post that is somehow better
otherwise, keep your mouth shut and your eyes open
you're wasting your time passing out insults instead of instruction, as i tend to ignore them
who knows - "andreas the great" may actually learn something
Dave, I see you take my remark personally. That's a pity.
However, I disagree that my remark was an insult. It was perfectly valid critisism - while your response - and also JJ's - are troll posts and off-topic.
instructions, for those that do not understand...
it's a WM_SIZE handler
it manages the scroll bar control presence, position, and size when the window is resized
it also manages the size box and status bar
so, to observe the behaviour, open the program and size the window
you can see that the scroll bars disappear when the client area is larger than the text
you can turn the status bar off and on to see how it affects size box selection
as for the coding style...
one of the reasons i write in assembler is to get away from the constructs of C
if i wanted my code to look and act like a C program, i'd probably write it in C
i don't write something a certain way just because some instructor says it's the "right way"
i try to write code that works well and is small, hopefully fast
i test it so that i know it's reliable
here is a little bit of an update
i got rid of the scroll bar "flashing" when a dark background color is selected
also - Alex found a bug in my resource file :U
now, i can work on the scrolling text code
all downhill from here, i think
Quote from: dedndave on February 08, 2011, 10:34:45 PM
all downhill from here, i think
Favourite joke of all assembler programmers, I guess :green2