News:

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

Using Global Structure in winmain

Started by raleeper, May 01, 2007, 10:25:53 AM

Previous topic - Next topic

raleeper

I am trying to do something that crashes my program.  There is no output or other apparent response (no "this program has performed an illegal operation...") and the exe file then cannot be opened or deleted.

Following Iczelion's tutorial 4, I declare in winmain

LOCAL   wc:WNDCLASSEX

and initialize it ala Iczelion, starting with

mov   wc.cbSize,SIZEOF WNDCLASSEX

That works fine.

But now when I declare a global structure outside winmain and initialize it with the same values, I get the odd sort of crash described above.

My question: is the whole idea of using a global structure wrong, or should I keep trying to find some mistake I'm making?

This is my structure (in .DATA)

LFwc    LABEL   DWORD   ;LFile Window Class structure
   DD   SIZEOF WNDCLASSEX             ; 0 wc.cbSize
   DD   CS_HREDRAW or CS_VREDRAW   ; 4 wc.style
   DD   OF WndProc                             ; 8 wc.lpfnWndProc
   DD   0                                    ;0C wc.cbClsExtra
   DD   0            ;10 wc.cbWndExtra
hinst   DD   ?            ;14 wc.hinst
hbkbr   DD   ?            ;18 CreateSolidBrush,0FF0000h
   DD   0            ;1C wc.lpszMenuName
   DD   OF ClassName         ;20 wc.lpszClassName
hicon   DD   ?            ;24 LoadIcon,0,IDI_APPLICATION
hiconsm   DD   ?            ;28    wc.hIconSm
hcurs   DD   ?            ;2C LoadCursor,NULL,IDC_ARROW
                  ;30   end LFwc

I initialize the "?"s at the start of .CODE and none of the invokes used here generates an assembler error or returns 0.


raleeper

I forgot to mention that "OF" = "OFFSET' via an equate.

Tedd

There's nothing particularly wrong with having a 'global' structure - it's only done local for the convenience and that it's only used on initialisation.
If that really is the only change then it indicates some other problem with your code, which happens to not show when done as local.
Whatever it is, you'll have to give us the full code so we can test what you actually have (not what we guess you should have :wink)
No snowflake in an avalanche feels responsible.

raleeper

#3
Here is the whole program.  I apologize for its length and for the ideosyncratic stye.  And for not being able, for now, to get the tabs to line up right in the post. 

The critical change is marked by "***"


;Base
.NOCREF
.386
.model flat,stdcall
option casemap:none

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

.NOLIST
include h:\masm32\include\windows.inc
include h:\masm32\include\user32.inc
include h:\masm32\include\kernel32.inc
include h:\masm32\include\gdi32.inc
includelib h:\masm32\lib\user32.lib
includelib h:\masm32\lib\kernel32.lib
includelib h:\masm32\lib\gdi32.lib
.RADIX 16
include g:\orig\prog\lf\leqm.asm
.RADIX 10

.LISTALL
crlf EQU 0A0Dh
tab EQU 9
.DATA

ClassName DB "RICHEDIT_CLASS"
AppName DB "lfw 0.3 7428",0
test$ DB "LFile v. 0.3 7423 (c)RA Leeper - working on drawtext."
DB "  Next is test crlf"
DW 0A0Dh
DW 0A0Dh
db "Did it work?",0
DW 0A0Dh
db tab,"Yes!"
DW 0A0Dh
db "Now test long line"
DW 0A0Dh
DB "Now - 7428 - converting to RAL style - The 1st step is doing away w/ the local wc structure.  It will be global and in .DATA.",10,13
DW 0A0Dh
DB "0123456789abcdef 123456789abcdef 123456789abcdef 123456789abcdef "
DW 0A0Dh
DB "Next, we'll try to get an 'edit control' working, so we can have rich text.",10,13
DW 0A0Dh
DB "Rich edit test{\rtf1\ansi{\fonttbl\f0\fswiss Helvetica;}\f0\pard"
DW 0A0Dh
DB "This is some {\b bold} text.\par}"

DW 0A0Dh
DW 0A0Dh
DB "Well, the last version does nothing.  7428 - Trying to find what's wrong."
DW 0A0Dh
DW 0A0Dh
DB "There are no assr errors, so try erbeep"
DW 0A0Dh
DW 0A0Dh
DB "last line 5.43"
DB 13,10,10
DB "OK I've done a bunch of cosmetic stuff w/ no problems.  Next a few things that should not matter - shorten some variable names - ALIGN 8 - NO GOOD - but just ALIGN is OK"
DW crlf,crlf
DB "Now - replace local wc w/ global LFwc.  This is gonna crash it",13,10,10
DB "7428b",tab,"last line 7.15",13,10,10
DB "7429",tab,"last line 6.16a",13,10,10
DB "7430",tab,"last line 5.58a",13,10,10

tslen EQU $-test$
FontName db "TimesNewRoman",0
;FontName db "Courier New",0
;FontName db "Arial",0
;FontName db "Verdana",0
ALIGN
txtclr EQU 0FFFFFFh

LFwc LABEL DWORD ;LFile Window Class structure
DD SIZEOF WNDCLASSEX ; 0 wc.cbSize
DD CS_HREDRAW or CS_VREDRAW ; 4 wc.style
DD OF WndProc ; 8 wc.lpfnWndProc
DD 0 ;0C wc.cbClsExtra
DD 0 ;10 wc.cbWndExtra
hinst DD ? ;14 wc.hinst
hbkbr DD ? ;18 CreateSolidBrush,0FF0000h
DD 0 ;1C wc.lpszMenuName
DD OF ClassName ;20 wc.lpszClassName
hicon DD ? ;24 LoadIcon,0,IDI_APPLICATION
hiconsm DD ? ;28 wc.hIconSm
hcurs DD ? ;2C LoadCursor,NULL,IDC_ARROW
;30 end LFwc
;wc WNDCLASSEX

.DATA?
hin@ HINSTANCE ?
cmdl LPSTR ?

.CODE

;   start: Initialize lfwc

start:
invoke CreateSolidBrush,0FF0000h
mov [hbkbr], eax
invoke LoadIcon,0,IDI_APPLICATION
mov [hicon], eax
mov [hiconsm], eax
invoke LoadCursor,0,IDC_ARROW
mov [hcurs], eax
; [hin@]  !GetModuleHandle [cmdl]  !GetCommandLine

invoke GetModuleHandle, 0
mov [hin@], eax
invoke GetCommandLine
or eax, eax
CALLZ erbeep
mov [cmdl], eax
; !WinMain {...} !ExitProcess,eax
invoke WinMain, hin@, 0, cmdl, SW_SHOWDEFAULT
invoke ExitProcess,eax

;   winmain !RegisterClassEx !CreateWindowEx
WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD

LOCAL msg:MSG
LOCAL hwnd:HWND
LOCAL wc:WNDCLASSEX
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
mov eax, [hInst]
mov [wc.hInstance], eax
invoke CreateSolidBrush,0FF0000h
mov wc.hbrBackground,eax
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax

;invoke RegisterClassEx, addr wc                    ***
invoke RegisterClassEx, OF LFwc;                  ***
mov edx, CW_USEDEFAULT
invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,edx,edx,edx,edx,0,0,hInst,0
; [hwnd]  eax !ShowWindow !UpdateWindow
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWMAXIMIZED
invoke UpdateWindow, hwnd

;   msglp: !GetMessage; eax=0 => _ex eax=-1 => _err ; !TranslateMessage !DispatchMessage ;   ex:/err: eax  msg.wParam ret

.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

WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT
LOCAL rect:RECT
LOCAL hbrsh:DWORD
LOCAL hfont:HFONT

.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_PAINT
call dspl
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor    eax,eax
ret
;; DSPL main DiSPLay

dspl:
tfmt EQU DT_EXPANDTABS or DT_LEFT or DT_NOCLIP or DT_TOP or DT_WORDBREAK

invoke BeginPaint,hWnd, ADDR ps; fills (ps) w/ defaults
mov    hdc,eax
; font, color of text, bkgr

invoke CreateFont,24,16,0,0,400,0,0,0,OEM_CHARSET,\
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
DEFAULT_QUALITY,DEFAULT_PITCH or FF_ROMAN,\
ADDR FontName
invoke SelectObject, hdc, eax
mov hfont,eax
invoke SetTextColor,hdc,0FFFFFFh
invoke SetBkColor,hdc,0FF0000h
invoke GetClientRect,hWnd, ADDR rect

invoke DrawText, hdc,ADDR test$,tslen, ADDR rect, tfmt

invoke EndPaint,hWnd, ADDR ps
ret
WndProc endp

;; ERBEEP ERror BEEP

;   erbeep: push eax eax  200 push eax

erbeep:
push eax

mov eax,200

push eax
; shl eax, 4 push eax call Beep

shl eax, 4

push eax

call Beep
; pop eax ret

pop eax

ret

end start


I just added the code tags for you so it can be read properly. hutch--

hutch--

raleeper,

Below is a normal WNDCLASSEX structure definition, it is from WINDOWS.INC.


WNDCLASSEX STRUCT
  cbSize            DWORD      ?
  style             DWORD      ?
  lpfnWndProc       DWORD      ?
  cbClsExtra        DWORD      ?
  cbWndExtra        DWORD      ?
  hInstance         DWORD      ?
  hIcon             DWORD      ?
  hCursor           DWORD      ?
  hbrBackground     DWORD      ?
  lpszMenuName      DWORD      ?
  lpszClassName     DWORD      ?
  hIconSm           DWORD      ?
WNDCLASSEX ENDS


You can if you wish initialise the structure globally in the .DATA section with something like,


.DATA
  wcex WNDCLASSEX <0,0,0,0,0,0,0,0,0,0,0,0>


You can initialise as many as you like with preset values but remember that this is assembly time initialisation, some WNDCLASSEX values can only be set at runtime so you will still have to copy data into at least some of the structure members.

This will be things like instance, cursor and icon handles which are not known at assembly time. (400000h instance handle excepted).

Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Tedd

Okay, very silly problem caused by defining your wndclassex structure wrongly (I didn't look that closely before.)
You've got 'hIcon' and 'hCursor' in the wrong place, which puts everything after hInstance at the wrong offset.

should be..
LFwc LABEL DWORD ;LFile Window Class structure
    DD SIZEOF WNDCLASSEX            ;cbSize
    DD CS_HREDRAW or CS_VREDRAW     ;style
    DD OF WndProc                   ;lpfnWndProc
    DD 0                            ;cbClsExtra
    DD 0                            ;cbWndExtra
    hinst DD ?                      ;hinst
    hicon DD ?                      ;hIcon = LoadIcon,0,IDI_APPLICATION         ; !!!!!
    hcurs DD ?                      ;hCursor = LoadCursor,NULL,IDC_ARROW        ; !!!!!
    hbkbr DD ?                      ;hbrBackground = CreateSolidBrush,0FF0000h
    DD 0                            ;lpszMenuName
    DD OF ClassName                 ;lpszClassName
    hiconsm DD ?                    ;hIconSm
;30 end LFwc
;wc WNDCLASSEX



(This will at least fix one problem, I'm not saying there aren't more :bdg)
No snowflake in an avalanche feels responsible.

raleeper

Quote from: Tedd on May 01, 2007, 01:45:47 PM
Okay, very silly problem caused by defining your wndclassex structure wrongly (I didn't look that closely before.)
You've got 'hIcon' and 'hCursor' in the wrong place, which puts everything after hInstance at the wrong offset.

should be..[...]


Yes.  Thanks Ted and Hutch.  I just took the structure members in the order Iczelion's tutorial initialized them without checking against the definition javascript:void(0);
redface.  Works fine now.

jckl

just looking shouldnt

ClassName DB "RICHEDIT_CLASS"

be

ClassName DB "RICHEDIT_CLASS",0

hutch--

Nope,

The two direct strings you can use are,


"RichEdit" for richedit 1

or

"RichEdit20a" for richedit 2 and later.


C tends to use the equate that you have in quotes in your posting.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

jckl

i meant the ",0" at the end. I wasnt sure if RICHEDIT_CLASS would work or not so i didnt want to change that. I use  RichEditClass   db "RichEdit20A",0

ramguru

from PSDK

#define RICHEDIT_CLASSA "RichEdit20A"

Tedd

Yes, strings should be null-terminated (C/C++ do it automagically when you enclose it in quotes.)
The code isn't actually using a rich-edit control, it's just the class name that's being taken for the main window - which, due to the lack of terminating null, really turns out to be "RICHEDIT_CLASSlfw 0.3 7428",0
For creating a rich-edit control, you can use the RICHEDIT_CLASS atom value, it's not a string.
No snowflake in an avalanche feels responsible.

jckl

thanks tedd thats exactly what i thought