PDA

View Full Version : Declare function no longer works



msnyder701
02-15-2022, 05:16 PM
I'm using Excel for Office 365 and up until a couple of weeks ago (or thereabouts) this statement gave no trouble:


Private Declare Function apiShowWindow Lib "user32" Alias "ShowWindow" _
(ByVal hWnd As Long, ByVal nCmdShow As Long) As Long

Now, trying to save a program with this line in it gives me a sharing violation and an access violation. Can someone please help? Thanks!!

arnelgp
02-15-2022, 06:20 PM
if you are using x64, you need to change the declaration, with conditional compiler directives:


#If VBA7 Then
Private Declare PtrSafe Function apiShowWindow Lib "user32" Alias "ShowWindow" _
(ByVal hWnd As LongPtr, ByVal nCmdShow As Long) As Long
#Else
Private Declare Function apiShowWindow Lib "user32" Alias "ShowWindow" _
(ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
#End If

msnyder701
02-15-2022, 07:08 PM
That's what I had thought, but it still doesn't work. I get the following error message: "The document was saved successfully, but Excel cannot re-open it because of a sharing violation. Please close the document and try to open it again."

msnyder701
02-15-2022, 09:43 PM
if you are using x64, you need to change the declaration, with conditional compiler directives:


#If VBA7 Then
Private Declare PtrSafe Function apiShowWindow Lib "user32" Alias "ShowWindow" _
(ByVal hWnd As LongPtr, ByVal nCmdShow As Long) As Long
#Else
Private Declare Function apiShowWindow Lib "user32" Alias "ShowWindow" _
(ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
#End If

arnelgp
02-16-2022, 06:20 AM
there is similar problem here:
Excel 2016 Sharing violation - Microsoft Community (https://answers.microsoft.com/en-us/msoffice/forum/all/excel-2016-sharing-violation/cbd8b1c6-0b6c-4881-ab89-4728ea2243ef?auth=1)

Paul_Hossler
02-16-2022, 07:17 PM
According to the MS 32/64 document




Declare PtrSafe Function ShowWindow Lib "user32" Alias "ShowWindow" (ByVal hwnd As LongPtr, ByVal nCmdShow As Long) As Long

arnelgp
02-17-2022, 12:44 AM
According to the MS 32/64 document




Declare PtrSafe Function ShowWindow Lib "user32" Alias "ShowWindow" (ByVal hwnd As LongPtr, ByVal nCmdShow As Long) As Long

that is if you are using Office 2010 and newer.

Aussiebear
02-17-2022, 02:38 AM
I believe the OP stated they were using Excel for Office 365

Bob Phillips
02-17-2022, 02:43 AM
All handles should be LongPtr in a 64bit environment.

arnelgp
02-17-2022, 02:49 AM
In post 1, only OP is using 365.

Paul_Hossler
02-17-2022, 03:09 AM
All handles should be LongPtr in a 64bit environment.


Agreed, but I think it also works with 32 bit office

https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/longptr-data-type?f1url=%3FappId%3DDev11IDEF1%26l%3Den-US%26k%3Dk(vblr6.chm1009053);k(TargetFrameworkMoniker-Office.Version%3Dv16)%26rd%3Dtrue




LongPtr (Long (https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/long-data-type) integer on 32-bit systems, LongLong (https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/longlong-data-type) integer on 64-bit systems) variables are stored as:



Signed 32-bit (4-byte) numbers ranging in value from -2,147,483,648 to 2,147,483,647 on 32-bit systems
Signed 64-bit (8-byte) numbers ranging in value from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 on 64-bit systems



LongPtr (https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/longptr-data-type) is not a true data type because it transforms to a Long (https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/long-data-type) in 32-bit environments, or a LongLong (https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/longlong-data-type) in 64-bit environments. Using LongPtr enables writing portable code that can run in both 32-bit and 64-bit environments. Use LongPtr for pointers and handles.

Bob Phillips
02-17-2022, 04:56 AM
<p>

Agreed, but I think it also works with 32 bit office https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/longptr-data-type?f1url=%3FappId%3DDev11IDEF1%26l%3Den-US%26k%3Dk(vblr6.chm1009053);k(TargetFrameworkMoniker-Office.Version%3Dv16)%26rd%3Dtrue That would suggest that we should just declare every long as LongPtr, 32bit or 64bit, and the conditional code is only necessary for PtrSafe? Might explain why it works when I have declared a non-handle variable as LongPtr.</p>

PhilS
02-17-2022, 07:27 AM
That would suggest that we should just declare every long as LongPtr, 23bit or 64bit, and the conditional code is only necessary for PtrSafe? Might explain why it works when I have declared a non-handle variable as LongPtr.
The conditional compilation for VBA7 is necessary for LongPtr and PtrSafe because these keywords only exist in VBA7.

As for "just declare every long as LongPtr", you will get away with declaring most Long variables as LongPtr but not all of them.
If you are interested in the details, I recommend my text Windows API declarations in VBA for 64-bit (https://codekabinett.com/rdumps.php?Lang=2&targetDoc=windows-api-declaration-vba-64-bit). (It mentions Microsoft Access in some locations, but the same is also true Excel, Word, and any other VBA enabled application.)

Paul_Hossler
02-17-2022, 11:15 AM
The conditional compilation for VBA7 is necessary for LongPtr and PtrSafe because these keywords only exist in VBA7. As for "just declare every long as LongPtr", you will get away with declaring most Long variables as LongPtr but not all of them. If you are interested in the details, ...


Don't know


I don't have enough versions (2010, 2013, 2016, 365) and 32/64 bit to test