Register class & Create Window

Tight_Coder_Ex 0 Tallied Votes 285 Views Share

Additional features will be added to this section of code such as fixing window size proportial to monitors resolution and subclassing the single edit control of this program. You'll notice I don't call ShowWindow here as WS_VISIBLE in windows style is defined.

STYLE		EQU	WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_VISIBLE
  EX_STYLE	EQU	WS_EX_STATICEDGE



  Wc		dd	48			; cbSize
		dd	CS_HREDRAW | CS_VREDRAW	
		dd	MainWndProc		; Main window procedure
		dd	0, 0			; cbClsExtra & cbWndExtra
  hInst		dd	0			; Instance Handle
		dd	0			; hIcon
		dd	0			; hCursor
		dd	COLOR_APPWORKSPACE + 1
		dd	0			; Hmenu
		dd	AppName			; Applications name
		dd	0			; Small Icon			

; ----------------------------------------------------------------------------------------------------------------------
  AppTitle	db	'Ordered List Lookup & Maintenance', 0
  AppName	db	'LOOK', 0

;-----------------------------------------------------------------------------------------------------------------------

  Cw		dd	EX_STYLE		; dwExStyle
		dd	AppName			; lpClassName
		dd	AppTitle		; lpWindowName
		dd	STYLE			; dwStyle
		dd	CW_USEDEFAULT		; x
		dd	CW_USEDEFAULT		; y
		dd	CW_USEDEFAULT		; nWidth
		dd	CW_USEDEFAULT		; nHeight
		dd	0			; hWndParent
		dd	0			; hMenu
		dd	0			; hInstance
		dd	0			; lpParam


; ============================================================================================
  				     *** SHOW MAIN WINDOW ***

  ; As the name implies the only responsiblity of this section of code is to register and 
  ; display main window.  

;	LEAVE: 	 CY = 1, If either registering class or creating window failed.  Additional
;			 code could be added to further define which caused the error.
; _____________________________________________________________________________________________

  ShowMainWnd	push	ebx
		mov	ebx, Wc			; Point to WNDCLASSEX structure in .data

		push	IDC_ARROW		; Establish main windows cursor
		push	byte 0
		call	_LoadCursorA@8
		mov	[ebx + 0x1c], eax	; hCursor

		push	byte 0
		call	_GetModuleHandleA@4
		mov	[hInst], eax
		push	eax

  	; Now that everything has been initialized the window class can be registered.

		push	ebx
		call	_RegisterClassExA@4
		and	eax, eax		; Set flags
		jz	.Exit			; EAX = 0 then registration failed.		

	; Create applications main window
		mov	ebx, Cw
		pop	eax		
		mov	[ebx + 40], eax
		call	Create_Wnd
		mov	[MainWnd], eax		; Save hWnd
		jnc	.Exit + 1

  .Exit		stc
		pop	ebx
		ret

Dani AI

Generated

Good notes from — a couple of small but important fixes and clarifications will make the register/create sequence robust and easier to extend (monitor scaling, edit subclassing, etc.).

Make sure the WNDCLASSEX you pass to RegisterClassEx has its members fully initialized. In particular set cbSize = sizeof(WNDCLASSEX) and copy your module handle into the class hInstance field before calling RegisterClassEx; RegisterClassEx requires a valid WNDCLASSEX and returns zero on failure (call GetLastError for details). (learn.microsoft.com)

Two quick assembly fixes: (1) actually store the HINSTANCE into the WNDCLASSEX block before RegisterClassEx, and (2) don’t use jnc to test the return in EAX — jnc tests the carry flag, not whether EAX is zero. Use test eax,eax / jz (or cmp eax,0 / jz) after RegisterClassEx and after CreateWindow so failures are caught reliably. Example (minimal):

; eax = hInstance from GetModuleHandleA
mov [Wc + 0x14], eax    ; set WNDCLASSEX.hInstance

push Wc
call _RegisterClassExA@4
test eax, eax
jz .RegFail

call Create_Wnd
test eax, eax
jz .CreateFail
mov [MainWnd], eax

CreateWindowEx returns NULL on failure — check it and call GetLastError if it fails. Also remember jnc is a CF test (jump if no-carry), not a zero/nonnull check. (learn.microsoft.com)

About visibility and painting: creating the window with WS_VISIBLE will make it show, but calling ShowWindow (with the WinMain nCmdShow or SW_SHOWDEFAULT) is the conventional way to honor the process startup state; call UpdateWindow (or let the message loop pump) to force the initial WM_PAINT if you need immediate painting. (learn.microsoft.com)

For scaling: read screen size with GetSystemMetrics (SM_CXSCREEN/SM_CYSCREEN) or use the multi-monitor APIs (EnumDisplayMonitors/GetMonitorInfo) for per-monitor sizing. On modern Windows consider DPI-awareness APIs if you want crisp, DPI-scaled layouts. For subclassing the single edit control prefer the Subclass helper APIs (SetWindowSubclass / DefSubclassProc) over manual SetWindowLongPtr tricks — they are safer and more portable (and use *Ptr variants for 64-bit correct handling). (learn.microsoft.com)

These changes keep the registration/create path deterministic and make the later work (resizing, subclassing) much easier to implement and debug.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.