In the WNDCLASS or WNDCLASSEX it is possible to define space which are reserved to the window.
To access it there are to functions:
- SetWindowLongPtrA
- GetWindowLongPtrA
Windows define GWL_USERDATA to access the datas stored.
The problem SetWindowLongPtrA/GetWindowLongPtrA access only a pointer stored at GWL_USRDATA (-21)
If you have to store two pointers you will never access the second like this.
Proceed like this:
First in the class
QuoteMOV DWORD PTR [RDX].WNDCLASSEX.cbWndExtra,2 * SIZEOF QWORD ; Size for two pointers
MOV DWORD PTR [RDX].WNDCLASSEX.cbClsExtra,EAX
Reserve space for two pointers
In the WM_CREATE:
QuoteMOV RCX,RAX
MOV RDX,GWLP_USERDATA ; First pointer, will be accessible in the classic way
MOV R8D,[_RecordNumber]
CALL SetWindowLongPtrA
MOV RCX,RDI
MOV RDX,SIZEOF QWORD ; Don't use GWL_USERDATA
MOV R8D,_dwItemMenu ; Store the second pointer
CALL SetWindowLongPtrA
In WM_PAINT or anywhere else
Quote; _______________________________________________________________________________________
; W M _ P A I N T |
; _______________________________________________________________________________________
ALIGN 16
@WmPaint :
MOV [_hWnd],RCX ; Save the window handle
MOV RDX,SIZEOF QWORD ; Only access the second pointer
CALL GetWindowLongPtrA ; Get the second pointer
MOV RCX,[_hWnd] ; Retrieve the window handle
MOV EDX,EAX ; EDX has now the good value
MOV RAX,OFFSET @Eoj
PUSH RAX
JMP PaintGrey
You could use this to store a string or a password...
I use the second part of the datas not to store a pointer but the item menu the user selected
because the Paint function accepts only a item menu identifier
Quotevoid PaintGrey(HWND __hWnd,DWORD __dwItemMenu)
{
PAINTSTRUCT _Ps ;
RECT _Rc ;
IMAGEINFOS _ImageInfos, *_lpImageInfos ;
HDC _hDC, _hDCMem_1, _hDCMem_2 ;
HBITMAP _hBmp_1, _hBmp_2, _hBmpOld_1, _hBmpOld_2 ;
double _dNewWidth, _dNewHeight ;
DWORD _dwRecordNumber ;
char _szTmp[WINDOWS_MAX_PATH] ;
_hDC = BeginPaint(__hWnd,&_Ps) ;
if(_hDC)
{
_dwRecordNumber = GetWindowLongPtrA(__hWnd,GWLP_USERDATA) ;
switch(__dwItemMenu)
{
case IDM_GREY_01 : GreyChannel_01(_lpImageInfos->BitmapInfo.bmiHeader.biSizeImage,_lpImageInfos->lpImageBits) ; break ;
case IDM_GREY_02 : GreyChannel_02(_lpImageInfos->BitmapInfo.bmiHeader.biSizeImage,_lpImageInfos->lpImageBits) ; break ;
}
}
}
EndPaint(__hWnd,&_Ps) ;
return ;
}
:)
Tutoring....good
John Z
Hi Grincheux,
Maybe I am wrong but why not to specify a pointer to a structure?
Yes but generally you have to allocate memory for it or use a global variable.
In this way the window is not linked to the datas.
I store a database key like this I am free.
In the example I store first a record number and in the second the menu item identifier.
I can use a general function which is the same for many functions.
I did not want to use a pointer on whatever because I must alloc memory : VirtualAlloc or Malloc that's always 4k misused.
Thak You for your comments Vortex.