SetWindowLong API

tiredofit

Well-known Member
Joined
Apr 11, 2013
Messages
1,926
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:

Excel Facts

Why does 9 mean SUM in SUBTOTAL?
It is because Sum is the 9th alphabetically in Average, Count, CountA, Max, Min, Product, StDev.S, StDev.P, Sum, VAR.S, VAR.P.
What version of Excel are you using? If an older version, I would think that PtrSafe would go red as well.

Anyways, I believe that Jan Karel's declarations are correct, and these are the same as in Win32API_PtrSafe.TXT.

Hope that helps,

Mark
 
Upvote 0
It doesn't matter that they are in red (I assume you are using a 64 bit Office version).
 
Upvote 0
It doesn't matter that they are in red (I assume you are using a 64 bit Office version).

Hey Rory,

:huh:...Because if the OP is in 64-bit, the lack of PtrSafe is causing the red? :banghead:

Mark
 
Upvote 0
Yup. Even though the code won't run, it gets syntax checked and highlighted.
 
Upvote 0
That makes perfect sense :oops: of course.

Hopefully by Summer's end, I'll have enough tucked away to buy a clue. (LOL)

Thanks Rory,

Mark
 
Upvote 0
tiredofit:

If of interest, I believe you should be able to download a sizable list of 32|64 bit declarations HERE
 
Upvote 0
Firstly thanks for the prompt response.

My O/S is 64 bit as it Excel (2013).

Everytime I type:

Code:
Private Declare Function

without the Ptr, the compiler makes an error noise.

So if I understand you correctly, I shall still proceed and it'll run?
 
Last edited:
Upvote 0
While it is of course true that the OS must be 64-bit for any 64-bit software to run, for clarity's sake, it is that you have Excel installed in 64-bit that matters for the declarations.

Assuming you mean 'without the PtrSafe', then yes, as Rory pointed out, even though that declaration of the code will not be compiled (due to #If...#Else...#End If conditional compilation), the code will still turn red due to the syntax being checked, and Excel 64-bit expecting to see the PtrSafe.

In close, it will run fine and due to the conditional compilation, still be able to run in 32-bit Excel in either VBA7 or VBA6.

Mark
 
Upvote 0
Mark, Rory,

This is the situation:

The code below works on a 32 bit Excel.

Rich (BB code):
' In Module1
Option Explicit
Sub abc()
    Dim MyTidyForm As Class1
    Set MyTidyForm = New Class1
    
    With MyTidyForm
    
        Set .MyForm = UserForm1
    
        Call .TidyForm
    
    End With
    
    UserForm1.Show
    Set MyTidyForm = Nothing
    
End Sub


' In Class1


Option Explicit
    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, _
                                                                                ByVal dwNewLong As Long) As Long
     
    Const WS_SYSMENU = &H80000
    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()
    Dim hwnd As Long, lStyle As Long
     
    hwnd = FindWindow(lpClassName:="ThunderDFrame", _
                      lpWindowName:=MyForm.Caption)
     
    lStyle = GetWindowLong(hwnd:=hwnd, _
                           nIndex:=GWL_STYLE)
     
    Call SetWindowLong(hwnd:=hwnd, _
                       nIndex:=GWL_STYLE, _
                       dwNewLong:=lStyle And Not WS_SYSMENU)
     
End Sub

I tried converting the API to 64 bit and this is the code (call it 64):

Rich (BB code):
' In Module ClsTidyForm


Option Explicit

Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, _
                                                                          ByVal lpWindowName As String) As LongPtr
                                                                          
    
    #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
        
        Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongPtr, _
                                                                                ByVal nIndex As Long, _
                                                                                ByVal dwNewLong As LongPtr) As LongPtr
    #Else 
   
       
        Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As LongPtr, _
                                                                                ByVal nIndex As Long) As LongPtr
        
        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) As Long
    #End  If
    
    Const WS_SYSMENU = &H80000
    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()
    Dim hwnd As Long, lStyle As Long
     
    hwnd = FindWindow(lpClassName:="ThunderDFrame", _
                      lpWindowName:=MyForm.Caption)
     
    lStyle = GetWindowLong(hwnd:=hwnd, _
                           nIndex:=GWL_STYLE)
     
    Call SetWindowLong(hwnd:=hwnd, _
                       nIndex:=GWL_STYLE, _
                       dwNewLong:=lStyle And Not WS_SYSMENU)
     
End Sub

Running 64 in 64 bit O/S and Excel, I get an error here:

Rich (BB code):
Sub TidyFrom()

Dim hwnd As Long, lStyle As Long
     
    hwnd = FindWindow(lpClassName:="ThunderDFrame", _
                      lpWindowName:=MyForm.Caption)

with FindWindow highlighted.

Running 64 in 64 bit O/S but 32 bit Excel, I get an error here:

Rich (BB code):
Sub TidyForm()
    Dim hwnd As Long, lStyle As Long
     
    hwnd = FindWindow(lpClassName:="ThunderDFrame", _
                      lpWindowName:=MyForm.Caption)
     
    lStyle = GetWindowLong(hwnd:=hwnd, _

with GetWindowLong highlighted.

First question: according to Jan's article, should both these be included:

Rich (BB code):
Private Declare Function FindWindow Lib "USER32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

 Private Declare PtrSafe Function FindWindow Lib "USER32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr

or just one?

Why am I getting the GetWindow and FindWindow errors?

What is the "rule" for converting? Is it simply to replace Long with LongPtr? Because that DOESN'T seem to be the case.

Thanks
 
Last edited:
Upvote 0

Forum statistics

Threads
1,224,823
Messages
6,181,182
Members
453,021
Latest member
Mohamed Magdi Tawfiq Emam

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