I'm having ouble with this. Where do i get the pointers for cbWndExtra and cbClsExtra? Can someone help me out?
Hello,
Classical window template :
WinMain PROC hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
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
push hInst
pop wc.hInstance
https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-wndclassexa
lea eax,wc.cbClsExtra
Oh i get it. Thanks
Sorry. Isnt cbClsExtra and cbWndExtra a byte count?
Hello,
Each of those items have a size of 4 bytes :
main PROC
LOCAL wc:WNDCLASSEX
invoke crt_printf,ADDR str1,\
sizeof wc.cbClsExtra,\
sizeof wc.cbWndExtra
4 4
ok. thanks vortex.
The question is here "what for?". Both cbClsExtra and cbWndExtra just say "there is a buffer after my WNDCLASSEX structure". You can fill it, of course, but why so complicated? Any global buffer db 100 dup(?) is easier to handle. IMHO cbClsExtra and cbWndExtra are among the most useless "features" of Windows :cool:
wc.cbClsExtra and wc.cbWndExtra are useful in MDI with a particular instruction (Multiple Windows).
If you don't need MDI you don't need also those data,there used had been replaced by
The use of the fuctions setprop getprop.
They serve a very useful purpose as memory that is specifically associated with a Window. If the Window is used multiple times as with a custom control, you have data that is unique to each window without having any scope problems where using a GLOBAL imposes severe restrictions with multiple copies of a Window. Its there if you need it but a vast amount of software never uses it.
So after all cbClsExtra and cbWndEstra are buffers. How to get the pointers to them?
Quote from: hutch-- on November 05, 2020, 01:05:29 AMyou have data
Excuse my ignorance: how do you access these data? Attached a demo how to access user data, that works fine (and instead of the string, that could be a pointer to megabytes of data uniquely associated with the control), but I still haven't found examples on the web showing how to access the extra members.
include \masm32\MasmBasic\Res\MbGui.asm
GuiControl BigEdit, "richedit", Cat$(Left$(MbExeFolder$)+":\Masm32\examples\exampl01\bmbutton\bmbutton.asm"), w700
GuiControl SmallEdit, "edit", "A small edit control", x700, w300
GuiControl Status, "statusbar"
invoke SetWindowLong, hBigEdit, GWL_USERDATA, wRec$("Введите текст здесь")
invoke SetWindowLong, hSmallEdit, GWL_USERDATA, wRec$("Click into the richedit control")
Event Command
.if nCode==EN_SETFOCUS
invoke GetWindowLong, lParam_, GWL_USERDATA
wSetWin$ hStatus=eax
.endif
GuiEnd
I use the cbWndExtra to declare extra space for the associated control (window) like for example in the ModernUI controls: https://github.com/mrfearless/ModernUI/blob/master/Controls/ModernUI_Button/ModernUI_Button.asm#L372
To access the data you can use GetWindowLong and SetWindowLong. (GetWindowLongPtr and SetWindowLongPtr for x64 asm)
For example if i alloc 8 as the cbWndExtra i can read the first dword with:
Invoke GetWindowLong, hWin, 0
and the 2nd dword with:
Invoke GetWindowLong, hWin, 4
And similar to set the appropriate value using SetWindowLong using the correct offset 0/4 for the dword to set (based on allocating only 8 bytes in cbWndExtra).
Of interest is the potential issue of allocating over 40 bytes for cbWndExtra:
https://app.gitbook.com/@fearless/s/creating-controls-in-assembler/control-properties (https://app.gitbook.com/@fearless/s/creating-controls-in-assembler/control-properties)
Quote from: xandaz on November 05, 2020, 02:47:22 AM
So after all cbClsExtra and cbWndEstra are buffers. How to get the pointers to them?
Hi xandaz,
They are not buffers. The two expressions are the members of the structure WNDCLASSEXA :
WNDCLASSEXA 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 ?
WNDCLASSEXA ENDS
.
.
IFDEF __UNICODE__
WNDCLASSEX equ <WNDCLASSEXW>
ELSE
WNDCLASSEX equ <WNDCLASSEXA>
ENDIF
Thanks, fearless - you enlightened me!!!
GWL_WNDPROC equ -4
GWL_HINSTANCE equ -6
GWL_HWNDPARENT equ -8
GWL_STYLE equ -16
GWL_EXSTYLE equ -20
GWL_USERDATA equ -21
GWL_ID equ -12
So GetWindowLong with a positive value simply returns the address of the data... wow! That's so lousily documented by Micros**t that I understand why almost nobody uses it. Still, GWL_USERDATA is easier to handle IMO.
:D
Yeh the GWL_USERDATA can be handy to use.
I usually allocate enough memory (twice) for the control and then save the pointer to one of the cbWndExtra 'spaces' - I internally use the 0 offset to represent a pointer to memory used for 'internal' properties for the control and 4 offset for the 'external' properties that the end user can change. In the past i just used a large buffer for cbWndExtra - like 196 bytes or so and occasionaly noticed some weird crashes or things not working - it didnt happen often but enough that when i read the info in the RegisterClassEx about the memory potentially not being allocated if over 40 bytes, i then changed my methodology to just use 8 bytes for the cbWndExtra and alloc the mem myself during wm_create/wm_ncreate
deleted
JJ,
rcall SetWindowLong,hButn,0,hBmpU
rcall SetWindowLong,hButn,4,hBmpD
Part of a custom control.
.case WM_LBUTTONDOWN
mov F@l@a@g@, 1
mov hBmpD, rvcall(GetWindowLong,hWin,4)
mov hImage, rvcall(GetWindowLong,hWin,8)
rcall SendMessage,hImage,STM_SETIMAGE,IMAGE_BITMAP,hBmpD
rcall SetCapture,hWin
My work in process. Enjoy. Thanks guys.
There's dimming in thye mdichildren. Why is that? I used WS_CLIPCHILDREN and WS_CLIPSIBLINGS