NO

Author Topic: Using SetWindowLongPtrA  (Read 3175 times)

Grincheux

  • Guest
Using SetWindowLongPtrA
« on: June 19, 2021, 01:16:54 PM »
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
Quote
MOV      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:

Quote
MOV      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
Quote
void 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 ;
}
« Last Edit: June 19, 2021, 01:25:45 PM by Grincheux »

Offline John Z

  • Member
  • *
  • Posts: 860
Re: Using SetWindowLongPtrA
« Reply #1 on: June 20, 2021, 02:26:21 PM »
 :)

Tutoring....good


John Z

Offline Vortex

  • Member
  • *
  • Posts: 867
    • http://www.vortex.masmcode.com
Re: Using SetWindowLongPtrA
« Reply #2 on: June 20, 2021, 07:20:50 PM »
Hi Grincheux,

Maybe I am wrong but why not to specify a pointer to a structure?
Code it... That's all...

Grincheux

  • Guest
Re: Using SetWindowLongPtrA
« Reply #3 on: June 20, 2021, 07:42:17 PM »
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.