SetWindowLong API

tiredofit

Well-known Member
Joined
Apr 11, 2013
Messages
1,924
Office Version
  1. 365
  2. 2019
Platform
  1. Windows
Can someone please check if the following API conversion, taken from here:


is correct?

Rich (BB code):
#If VBA7 Then
     #If Win64 Then
         Private Declare PtrSafe  Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
     #Else
         Private Declare Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
     #End If
 #Else
     Private Declare Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong  As Long) As Long 
 #End If

These lines are in red:

Rich (BB code):
Private Declare Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
     #End If
 #Else
     Private Declare Function SetWindowLongPtr Lib "USER32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong  As Long) As Long


Thanks
 
Last edited:
Thanks Mark.

So for those who want to refer to this in the future, I take it this is the definitive version?

Rich (BB code):
#If  VBA7 Then   ' (OFFICE 2010 AND LATER - Either 32bit or 64bit Editions)
    Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr

    #If  Win64 Then  '(64bit OS) AND (64bit Office)
        Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
        Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
    #Else    ' (32 or 64 bit OS) AND (32bit Office)
        Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As Long
        Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
     #End  If

#Else    ' (OFFICE 2007 AND BEFORE)  .. Both (32bit OS) AND (32bit Office)
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
#End  If
Private Const WS_SYSMENU = &H80000
Private Const GWL_STYLE = (-16)
Private pMyForm As UserForm
    
Public Property Get MyForm() As UserForm
    Set MyForm = pMyForm
End Property
Public Property Set MyForm(ByVal MForm As UserForm)
    Set pMyForm = MForm
End Property
Sub TidyForm()
    
    '============= Variable Declarations==============================
    
    #If  VBA7 Then  '(OFFICE 2010 AND LATER - Either 32bit or 64bit Editions)
        
        #If  Win64 Then  '(64bit OS) AND (64bit Office)
            Dim hWnd As LongPtr, lStyle As LongPtr, lNewStyle As LongPtr
        #Else   '(32bit OS) AND (32bit Office)
            Dim hWnd As LongPtr, lStyle As Long, lNewStyle As Long
        #End  If
   
    #Else   '(OFFICE 2007 AND BEFORE)  .. Both (32bit OS) AND (32bit Office)
        Dim hWnd As Long, lStyle As Long, lNewStyle As Long
    #End  If
    
    '===================================================================
         
    hWnd = FindWindow(lpClassName:="ThunderDFrame", _
                      lpWindowName:=MyForm.Caption)
     
    lStyle = GetWindowLong(hWnd:=hWnd, _
                           nIndex:=GWL_STYLE)
                           
    lNewStyle = lStyle And Not WS_SYSMENU
     
    Call SetWindowLong(hWnd:=hWnd, _
                       nIndex:=GWL_STYLE, _
                       dwNewLong:=llNewStyle)
     
End Sub
 
Last edited:
Upvote 0

Excel Facts

Ambidextrous Undo
Undo last command with Ctrl+Z or Alt+Backspace. If you use the Undo icon in the QAT, open the drop-down arrow to undo up to 100 steps.
Salute and utter agreement!

Not having 64-bit Excel to test against makes me a bit iffy anyways, but that Constant's name just makes me batty! Whenever I do attempt to provide declarations for both 64|32 bit Excel, I make myself read it as "#If Excel64 Then..."

Which brings me to a question for you and Rory that I've been pondering since post #15 ... Would there be something wrong (some failure to correctly compile conditionally) if we were to ask '#If Win64' first? And (sorry, one more question) could we (for one's personal clarity or preference) use a substitute for Win64?

For instance, using Jaafar's declarations (with the exception that I dis-included PtrSafe in the #Else If VBA7 section) would either of you see any shortcoming(s) with:

Rich (BB code):
Option Explicit


#Const Excel64 = Win64
  
#If  Excel64 Then    '(64bit OS) AND (64bit Office)
  Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
  Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#ElseIf  VBA7 Then '(32 or 64 bit OS, OFFICE 2010 AND LATER - Either 32bit or 64bit Editions)
  Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As Long
  Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
#Else              '(32 or 64 bit OS, OFFICE 2007 AND BEFORE - 32bit Office)
  Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
  Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
#End If

#ElseIf VBA7 Then '(32 or 64 bit OS, OFFICE 2010 AND LATER - Either 32bit or 64bit Editions)

I think the 64bit Edition I colored in red in the above clause should not be there as it should already be included in the first #If Excel64 plus you can't run 64bit office in a 32Bit OS.


Apart from that ,I don't see any shortcomings with that... Actually, I think it is less confusing than the standard declaration unless I am not seeing a flaw in the logic.

Thank you Mark.
 
Upvote 0
<a href="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=ElseIf" target="_blank"><a href="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=ElseIf" target="_blank">#Else If VBA7 Then '(32 or 64 bit OS, OFFICE 2010 AND LATER - Either 32bit or 64bit Editions)

I think the 64bit Edition I colored in red in the above clause should not be there as it should already be included in the first #If Excel64 plus you can't run 64bit office in a 32Bit OS.


Apart from that ,I don't see any shortcomings with that... Actually, I think it is less confusing than the standard declaration unless I am not seeing a flaw in the logic.

Thank you Mark.

Jaafar,

So how many times does FindWindow need to be added and where?

Is this correct?

Rich (BB code):
#Const  Excel64 = Win64
  
#If  Excel64 Then     '(64bit OS) AND (64bit Office)
    
  Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
                                                                              ByVal lpWindowName As String) As LongPtr
                                                                              
  Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
  Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
<a href="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=ElseIf" target="_blank">#Else If  VBA7 Then  '(32 or 64 bit OS, OFFICE 2010 AND LATER - Either 32bit or 64bit Editions)
  Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
                                                                                ByVal lpWindowName As String) As Long
  Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As Long
  Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
#Else               '(32 or 64 bit OS, OFFICE 2007 AND BEFORE - 32bit Office)
  Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
                                                                              ByVal lpWindowName As String) As Long
                                                                              
  Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
  Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
#End  If
    
    Private Const WS_SYSMENU = &H80000
    Private Const GWL_STYLE = (-16)

Does the order of the variable declarations part have to change as well, so that #Excel64 comes first?
 
Last edited:
Upvote 0
@tiredofit.

Sorry to have confused you with the SetWindowLong function.

So how many times does FindWindow need to be added and where?

You need to declare it twice.

This is the code declaration you need:

Code:
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=If"]#If[/URL]  VBA7 Then   ' (OFFICE 2010 AND LATER - Either 32bit or 64bit Editions)
     Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
     
    [URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=If"]#If[/URL]  Win64 Then  '(64bit OS) AND (64bit Office)
        Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr
        Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
    [URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=Else"]#Else[/URL]   '(32 or 64 bit OS) AND (32bit Office)
        Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long) As Long
        Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
     [URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=End"]#End[/URL]  If


[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=Else"]#Else[/URL]    ' (OFFICE 2007 AND BEFORE)  .. Both (32bit OS) AND (32bit Office)
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
[URL="https://www.mrexcel.com/forum/usertag.php?do=list&action=hash&hash=End"]#End[/URL]  If
 
Last edited:
Upvote 0
@JAAFAR:

...plus you can't run 64bit office in a 32Bit OS.

:oops: ARGH! Yes, I quite missed the needed correction to the comment. My forehead is probably a bit red with as many times as I've palm-smacked it...


Apart from that ,I don't see any shortcomings with that... Actually, I think it is less confusing than the standard declaration unless I am not seeing a flaw in the logic.

Thank you Mark.

Thank you Jaafar; this has been interesting and informative. Personally, I think I will start using #Const Excel64 = Win64 just for my own clarity.

Have a great day!
@tiredofit:

I believe you have it exactly right at post # 31.

If you were going to restructure the #IF like post # 33, I personally would simply do a separate #IF for FindWindow(), like:

Rich (BB code):
#IF  VBA7 Then
  Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
#Else 
  Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#End If

Hope that helps,

Mark
 
Upvote 0
@JAAFAR:

...plus you can't run 64bit office in a 32Bit OS.


:oops: ARGH! Yes, I quite missed the needed correction to the comment. My forehead is probably a bit red with as many times as I've palm-smacked it...


Apart from that ,I don't see any shortcomings with that... Actually, I think it is less confusing than the standard declaration unless I am not seeing a flaw in the logic.

Thank you Mark.

Thank you Jaafar; this has been interesting and informative. Personally, I think I will start using #Const Excel64 = Win64 just for my own clarity.

Have a great day!
@tiredofit:

I believe you have it exactly right at post # 31.

If you were going to restructure the #IF like post # 33, I personally would simply do a separate #IF for FindWindow(), like:

Rich (BB code):
#IF  VBA7 Then
  Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
#Else 
  Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#End If

Hope that helps,

Mark
 
Upvote 0
Thanks to all but just ONE last point, :)

In Jan's article:


his Getwindow is this:

Rich (BB code):
#If  VBA7 Then
     #If  Win64 Then
         Private Declare PtrSafe  Function GetWindowLongPtr Lib "USER32" Alias "GetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
     #Else 
         Private Declare PtrSafe  Function GetWindowLongPtr Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
     #End  If
 #Else 
     Private Declare Function GetWindowLongPtr Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long 
 #End  If

whereas Jaafar and Mark agree it ought to be:

Rich (BB code):
#If   VBA7 Then   ' (OFFICE 2010 AND LATER - Either 32bit or 64bit Editions)
    
    #If   Win64 Then  '(64bit OS) AND (64bit Office)
        Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr
        
    #Else    '(32 or 64 bit OS) AND (32bit Office)
        Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long) As Long
        
     #End   If

#Else     ' (OFFICE 2007 AND BEFORE)  .. Both (32bit OS) AND (32bit Office)
     Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    
#End   If

There's a difference in the first else, in that Jan states it should be declared as LongPtr but J+M say it's declared as Long.

Have I missed something?
 
Upvote 0
Thanks to all but just ONE last point, :)

In Jan's article:


his Getwindow is this:

Rich (BB code):
#If  VBA7 Then
     #If  Win64 Then
         Private Declare PtrSafe  Function GetWindowLongPtr Lib "USER32" Alias "GetWindowLongPtrA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
     #Else 
         Private Declare PtrSafe  Function GetWindowLongPtr Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
     #End  If
 #Else 
     Private Declare Function GetWindowLongPtr Lib "USER32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long 
 #End  If

whereas Jaafar and Mark agree it ought to be:

Rich (BB code):
#If   VBA7 Then   ' (OFFICE 2010 AND LATER - Either 32bit or 64bit Editions)
    
    #If   Win64 Then  '(64bit OS) AND (64bit Office)
        Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongPtrA" (ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr
        
    #Else    '(32 or 64 bit OS) AND (32bit Office)
        Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As Long) As Long
        
     #End   If

#Else     ' (OFFICE 2007 AND BEFORE)  .. Both (32bit OS) AND (32bit Office)
     Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    
#End   If

There's a difference in the first else, in that Jan states it should be declared as LongPtr but J+M say it's declared as Long.

Have I missed something?
 
Upvote 0
Deleted .... Duplicate post due to slow website
 
Last edited:
Upvote 0

Forum statistics

Threads
1,223,911
Messages
6,175,337
Members
452,637
Latest member
Ezio2866

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top