The MASM Forum

General => The Campus => Topic started by: xandaz on November 04, 2020, 07:45:31 PM

Title: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: xandaz on November 04, 2020, 07:45:31 PM
   I'm having ouble with this. Where do i get the pointers for cbWndExtra and cbClsExtra? Can someone help me out?
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: Vortex on November 04, 2020, 08:12:08 PM
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
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: xandaz on November 04, 2020, 10:15:10 PM
   Oh i get it. Thanks
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: xandaz on November 04, 2020, 10:19:19 PM
   Sorry. Isnt cbClsExtra and cbWndExtra a byte count?
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: Vortex on November 04, 2020, 10:39:30 PM
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
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: xandaz on November 04, 2020, 11:35:59 PM
ok. thanks vortex.
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: jj2007 on November 04, 2020, 11:52:33 PM
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:
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: TouEnMasm on November 05, 2020, 12:31:10 AM
 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.
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: hutch-- on November 05, 2020, 01:05:29 AM
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.
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: xandaz on November 05, 2020, 02:47:22 AM
   So after all cbClsExtra and cbWndEstra are buffers. How to get the pointers to them?
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: jj2007 on November 05, 2020, 03:01:17 AM
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
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: fearless on November 05, 2020, 03:03:47 AM
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)


Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: Vortex on November 05, 2020, 03:15:36 AM
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
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: jj2007 on November 05, 2020, 03:18:08 AM
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.
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: fearless on November 05, 2020, 03:29:02 AM
: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
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: nidud on November 05, 2020, 04:48:16 AM
deleted
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: hutch-- on November 05, 2020, 07:41:44 AM
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
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: xandaz on November 05, 2020, 08:52:52 AM
    My work in process. Enjoy. Thanks guys.
Title: Re: how to access WNDCLASSEX.cbClsExtra and cbWndExtra?
Post by: xandaz on November 06, 2020, 01:03:16 AM
    There's dimming in thye mdichildren. Why is that? I used WS_CLIPCHILDREN and WS_CLIPSIBLINGS