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
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.
Actually I didn't know that. However if I run the code as is I get error 00000002 FILE_NOT_FOUND
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
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 (http://msdn.microsoft.com/en-us/library/ms633577%28VS.85%29.aspx).
- 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!)
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.
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.
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.
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.
what is the value of wc.hInstance when you call RegisterClassEx ?
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.... ::)
wc.hInstance is 00400000 the addr of the program PE header
After the call Olly highlights the hCursor and hbrBackground fields in the data structure in red. An error ?
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 ?
EAX = 0000C25C after the call
that means the class is registering - that is the class global atom
where are you getting the error ? - we need to see more code :P
you might, temporarily, stick some constants in for window x, y, width, height - to see if that's the problem
I live in the country, that means no internet. I'm only on once or twice a week, and I've go to go.
The error is occuring on the RegisterClassEx calll.
We'll have to pick this up maybe wednesday but more than likely next week.
Thanks everybody for your help. Ill log on next week hopefully I have it if not try this again.
THANKS
RegisterClassEx is one of those functions that almost never fails (DAVE knows this).
Even if the Window class is already registered, you'll get an error code telling you that.
Here is: A Simple Tutorial for a Window Program (in C++) (http://www.winprog.org/tutorial/simple_window.html)
Don't seem very clear.
I suggest to put wc.style to null and made further tests with other styles.
For example CS_BYTEALIGNCLIENT or CS_BYTEALIGNWINDOW
Can be also a problem with the name of the class
You can also put the code who center the window in comment (if it is that who made a change)
If the defaut disappear,verify there is no exception generated by the calcul.
there is some kind of misunderstanding, here
if RegisterClassEx returns a non-zero value in EAX, then it is not failing
Quote from: baltoro on November 02, 2011, 05:26:04 PM
Here is: A Simple Tutorial for a Window Program (in C++) (http://www.winprog.org/tutorial/simple_window.html)
Very well written indeed! The ShowWindow/UpdateWindow sequence is not needed if you specify WS_VISIBLE in CreateWindowEx, though.
Went home and worked on it for a few more hours. I feel like an idiot, I found a backslash in a column, than was not visble in full screen (col 160 +), after the invoke statement. I removed it an it solved the problem. I want to thank everybody for their help, I learned alot. Thanks!
I once read a post by a C++ programmer (on another programming forum),...in which he had an large number of insidious errors when he tried to compile the program he was working on. It nearly drove him crazy,...and, took hours to determine the cause.
...As it turned out,...he had accidentally added a closing bracket (}) at some random point in one of the more commonly used windows headers files,...and, the compiler would respond by listing a whole bunch of irrelevant errors every time he tried to compile anything that referenced that header file.
...He suggested to all serious programmers that they make all Windows headers files 'Read Only',...to eliminate that kind of debacle in the future. :eek
Quote from: Don57 on November 03, 2011, 06:00:14 PM
Went home and worked on it for a few more hours. I feel like an idiot, I found a backslash in a column [...]
Idiot? No, that's just the price of admission to the programmer's club.
Quote from: Don57 on November 03, 2011, 06:00:14 PM
Went home and worked on it for a few more hours. I feel like an idiot, I found a backslash in a column, than was not visble in full screen (col 160 +), after the invoke statement. I removed it an it solved the problem. I want to thank everybody for their help, I learned alot. Thanks!
Column 160? I can get around 190 visible columns but I don't use them all! You can use the line continuation character (backslash) to split invoke calls up...
invoke CreateWindowEx, \
WS_EX_CLIENTEDGE, \
offset szWndTreeView, \
NULL, \
WS_CHILD or WS_VISIBLE or WS_TABSTOP or TVS_DISABLEDRAGDROP, \
5, 5, \
255, 280, \
hWin, TV_MAIN, \
hInst, NULL
Some API you would use many more constants and you could even split those up and use mulitple lines for those also.