News:

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

RegisterClassEx failure

Started by Don57, October 31, 2011, 06:58:55 PM

Previous topic - Next topic

Don57

My program ran fine until I added screen centering now I have an error in RegisterClassEx. It appears from Olly debug that part of the data structure WNDCLASSEX is invalid.

I have been unable to find  SIZEOF WNDCLASSEX in the include files. I believe the proper value is 2C, but I would rather use the include files. Here's the code snippet, I hope someone can help. Thanx.

WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD


     LOCAL wc:WNDCLASSEX                                                   ; local variables need in proc
     LOCAL msg:MSG
     LOCAL hWnd:DWORD
     LOCAL pos:RECT
     
     invoke SystemParametersInfo, SPI_GETWORKAREA, 0, addr pos, 0


     mov   ecx,pos.left                                                  ;  center windows
     mov   eax,pos.right                                                 
     sub   eax, ecx                                                     
     sub   eax,OPENING_SCREEN_Width
     clc
     sar   eax,1d                                                           ; divide by 2         
     mov   dwWindow_Start_X,eax


     mov   ecx, pos.top
     mov   eax, pos.bottom
     sub   eax, ecx 
     sub   eax, OPENING_SCREEN_Height
     clc
     sar   eax,1d                                                        ; divide by 2         
     mov   dwWindow_Start_Y,eax


     

       
     mov  wc.cbSize, SIZEOF WNDCLASSEX                                     ; DWORD size of WndClassEx structure
     mov  wc.style, CS_HREDRAW                                             ; DWORD specifies style for class
     mov  wc.lpfnWndProc, OFFSET WndProc                                   ; DWORD pointer to windows proc to run
     mov  wc.cbClsExtra, NULL                                              ; DWORD number of extra bytes following windows class
     mov  wc.cbWndExtra, NULL                                              ; DWORD number of extra bytes following windows instance

     push hInstance                                                        ; put program instance handle on stack
     pop  wc.hInstance                                                     ; pop as wc.hInstance
                                                                                 


     mov  wc.hbrBackground, COLOR_WINDOW+1                                 ; DWORD color for window background brush
     mov  wc.lpszMenuName, NULL                                            ; DWORD pointer that specifies resource name for class menu
     mov  wc.lpszClassName, OFFSET szClassName                             ; DWORD pointer to classs name of window


     invoke LoadIcon, NULL, IDI_APPLICATION                                ; load icon and get handle
                                                                           ; hInstane = null  mod handle for exe with icon
                                                                           ; IpIconName - pointer to string name of icon file
     mov  hIcon,eax                                                        ; stash icon handle  needed in other procs             
     mov  wc.hIcon, eax                                                    ; handle returned in eax
     mov  wc.hIconSm, eax                                                  ; set small handle the same

     invoke LoadCursor, NULL, IDC_ARROW                                    ; load cursor and get handle
                                                                           ; NULL = hInstance
                                                                           ; pointer to standard arrow
     mov  wc.hCursor, eax                                                  ; save cursor handle

     invoke RegisterClassEx, addr wc                                       ; now that structure is full register class


NoCforMe

I hope I'm not telling you something you already know, but you won't find SIZEOF WNDCLASSEX in any include file.

SIZEOF is an assembler operator that gives the size of a data item (a structure in this case) in bytes. You should, however, be able to find WNDCLASSEX in an include file.

Haven't had time to look at the rest of your code yet but will later.

Don57

Actually I didn't know that. However if I run the code as is I get error 00000002  FILE_NOT_FOUND

dedndave

WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
;
;
;
     push hInstance                                                        ; put program instance handle on stack
     pop  wc.hInstance                                                     ; pop as wc.hInstance


WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
;
;
;
     push hInst                                                            ; put program instance handle on stack
     pop  wc.hInstance                                                     ; pop as wc.hInstance


if that's not the problem, we'll need to see more of the code
reason - everything else looks like it ought to fly   :P

NoCforMe

Couple things:

  • It looks like you're not setting some of the WNDCLASSEX members, like hbrBackground. may not explain your problem, but you want to make sure you set everything that needs to be set.

    MSDN is your friend here: be sure to look at the page on the WNDCLASSEX structure.

  • Your window-centering code is needlessly complicated. First of all, why are you doing a SAR instead of SHR, which doesn't require clearing the carry flag?

    Here's my centering subroutine, which I copied out of the MASM32 examples and modified:


    ;====================================================================
    ; CenterDim
    ;
    ; Returns half screen dimension (X or Y) minus half window dimension
    ;
    ; On entry,
    ; EAX = screen dimension
    ; EDX = window dimension
    ;
    ; Returns:
    ; sdim/2 - wdim/2
    ;====================================================================

    CenterDim PROC

    SHR EAX, 1 ;divide screen dimension by 2
    SHR EDX, 1 ;divide window dimension by 2
    SUB EAX, EDX
    RET ;Return w/# in EAX

    CenterDim ENDP


    Just set EAX and EDX, call the routine, and you have your centered value in EAX. Simple.

    Also, you don't need to specify "1d" for a decimal value. All numbers are considered decimal by default. Use 0xxH (or h) for hexadecimal, or 0bbbB (or b) for binary. (Thank god for no octal!)

Don57

Probably right about the centering routine, just in the habit of using SAR  for math function. I checked the structure loading in Olly against the template in windows.inc and it is filling the structure with my data, if my data is correct that is another story.I am going to check it all again. The funny thing is that the program was running until i added the centering, then nothing. When I went back an checked my previous versions of the program, that ran, they where not registering the class either but they still ran. Kind of odd and madding. You'lll have to excuse me if iI ramble I've been at this since last night.

NoCforMe

Quote from: Don57 on October 31, 2011, 07:37:58 PM
Probably right about the centering routine, just in the habit of using SAR  for math function.

Well, it's a bad habit that you ought to break. SH[R/L] and SA[R/L] do quite different things. You don't want to use SAR here, as it replicates the high bit instead of shifting it, which is what you do want here.

Don57

I made the change SAR to SHR. I believe my routine is quicker, with the SHR, because the code is inline, there no extra bytes for the proc call and ret. It also calculate both the X and Y co-ordinates, rather than calling the proc twice.

NoCforMe

Well, yes, your code is quicker--but who cares? It's all over in the blink of any eye anyhow. A subroutine saves a little code space, but it's basically 6 of one vs. half a dozen of the other. Do what you prefer here.

In other words, keep things in perspective. Code optimization is important in operations that consume time and where there can be apparent bad effects to the user (slow execution, flicker, etc.). In places like this, it doesn't really make any difference.

None of which has fixed your original problem, I suspect. We'll have to work on that.

dedndave

what is the value of wc.hInstance when you call RegisterClassEx ?

jj2007

Shorter:
mov eax, 1280  ; screen
mov edx, 1600  ; window
SUB EAX, EDX
SAR eax, 1    ; -160

And at least one picosecond faster, too :bg

> You don't want to use SAR here, as it replicates the high bit instead of shifting it, which is what you do want here
Hmmm.... ::)

Don57

wc.hInstance  is 00400000 the addr of the program PE header

Don57

After the call Olly highlights the hCursor and hbrBackground fields in the data structure in red. An error ?

dedndave

what value is returned in EAX after RegisterClassEx ?
is it 0 ?

your cursor, icon, and background color all look good   :P

if the class were not registering, i would think CreateWindowEx would give an error

could we see more of the program ?
data area
window creation
where are you calling GetLastError ?

Don57