Need correct syntax to declare and call HTMLHelp API in 64-bit Office and VBA7 - vba7

This VBA code displays context-sensitive help in a CHM in 32-bit Microsoft Office and VBA6:
Private Declare Function HtmlHelp Lib "HHCtrl.ocx" Alias "HtmlHelpA" _
(ByVal hWndCaller As Long, _
ByVal pszFile As String, _
ByVal uCommand As Long, _
dwData As Any) As Long
Const HH_DISPLAY_TOPIC As Long = 0
HtmlHelp hwnd, sPathToCHM, HH_DISPLAY_TOPIC, ByVal "topic_name.htm"
This code displays nothing and no error messages in 64-bit Microsoft Office with VBA7:
Declare PtrSafe Function HtmlHelp Lib "hhctrl.ocx" Alias "HtmlHelpA" _
(ByVal hwndCaller As LongPtr, _
ByVal pszFile As String, _
ByVal uCommand As Long, _
ByVal dwData As String) As Long
HtmlHelp(hwndCalling, strHelpTopicFile, HH_DISPLAY_TOPIC, strHelpTopic)

Related

Can some one explain what this is actually doing?

I have been searching for a way to close windows explorer using vba, and i have found something that works. However i actually have no idea what it is actually doing, or what any of it means. Could someone please explain what is happening below?
Private Const CLOSE_WIN = &H10
Dim Hwnd As Long
Private Declare Function apiFindWindow _
Lib "user32" Alias "FindWindowA" _
(ByVal lpClassname As String, _
ByVal lpWindowName As String) _
As Long
Private Declare Function apiPostMessage _
Lib "user32" Alias "PostMessageA" _
(ByVal Hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) _
As Long
Hwnd = apiFindWindow("CabinetWClass", vbNullString)
Dim retval As Long
If (Hwnd) Then
retval = apiPostMessage(Hwnd, CLOSE_WIN, 0, ByVal 0&)
End If
Thank You

vb.net applications to reload the INI file

i write this code to change default printer in windows and work fine but in reload the INI file have a error
this is a code :
Private Sub SetDefaultPrinter(ByVal PrinterName As String, ByVal DriverName As String, ByVal PrinterPort As String)
Dim DeviceLine As String
'rebuild a valid device line string
DeviceLine = PrinterName & "," & DriverName & "," & PrinterPort
'Store the new printer information in the
'[WINDOWS] section of the WIN.INI file for
'the DEVICE= item
Call WriteProfileString("windows", "Device", DeviceLine)
'Cause all applications to reload the INI file
Call SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, "windows")
End Sub
Private Declare Function WriteProfileString Lib "kernel32" Alias "WriteProfileStringA" (ByVal lpszSection As String, ByVal lpszKeyName As String, ByVal lpszString As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lparam As String) As Long
Private Const HWND_BROADCAST As Long = &HFFFF&
Private Const WM_WININICHANGE As Long = &H1A
and this is a error :
A call to PInvoke function 'Test!Test.Form2::SendMessage' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
Does anyone have an idea to solve this problem?
Thankful
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
ByVal lparam As String) As Long
Your data types are wrong. The hwnd parameter is pointer sized, wMsg is a 32 bit value, and wParam, lParam and the return value are pointer sized. Note that Long is a 64 bit type.
Instead it should be
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As IntPtr, _
ByVal lparam As String) As IntPtr
Note that I recommend that, in the modern day, you use pinvoke declarations rather than Declare. This offer much more flexibility.

Converting Excel VBA 32bit code to 64bit

A friend of mine made this Excel VBA code for me a while ago. It's 32bit, but now I need it converted for 64bit.
Can anyone please help me to do so?
Private Declare Function FindWindow Lib "user32" _
Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function GetWindowLong Lib "user32.dll" _
Alias "GetWindowLongA" ( _
ByVal hWnd As Long, _
ByVal nIndex As Long) As Long
Private Declare Function SetWindowsHookEx Lib "user32" _
Alias "SetWindowsHookExA" ( _
ByVal idHook As Long, _
ByVal lpfn As Long, _
ByVal hmod As Long, _
ByVal dwThreadId As Long) As Long
Private Declare Function CallNextHookEx Lib "user32" ( _
ByVal hHook As Long, _
ByVal nCode As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" ( _
ByVal hHook As Long) As Long
Private Declare Function PostMessage Lib "user32.dll" _
Alias "PostMessageA" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Private Declare Function WindowFromPoint Lib "user32" ( _
ByVal xPoint As Long, _
ByVal yPoint As Long) As Long
Private Declare Function GetCursorPos Lib "user32.dll" ( _
ByRef lpPoint As POINTAPI) As Long
You need to use "PtrSafe" when declaring function :
Private Declare PtrSafe Function
Also in 64bit Excel, use LongLong instead of Long
and LongPtr for callback functions
but for ptrSafe compiler itself will warn you if this is missing

runtime error executing macro in excel 2010

I am receiving:
Run-time error '1004': Cannot run macro Makros.xlm!MakroIni. The
macro may not be available in this workbook or all macros may be
disabled.
...when running a Macro in certain instances of Excel 2010. In some Excel 2010 installations and Excel 2003 it works fine.
There are 2 Workbooks involved: Macro.xlm and Username.xls. Both files are stored on a remote server.
The Macro crashes when executing:
Workbooks.Open Makro_Path & Makro_Nam, ReadOnly:=True
Application.Run Makro_Nam & "!MakroIni", WbTyp
The first line is proper executed and all macros are visible.
Makro_Nam is defined as:
Public Const Makro_Nam As String = "Makros.xlm"
What can i do?
Actually the cause was Excel 64 bit.
The Makro.xlm worksheet contained this function definitions:
Private Declare Function FindFirstFile Lib "kernel32.dll" Alias "FindFirstFileA" ( _
ByVal lpFileName As String, _
ByRef lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile Lib "kernel32.dll" Alias "FindNextFileA" ( _
ByVal hFindFile As Long, _
ByRef lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32.dll" ( _
ByVal hFindFile As Long) As Long
Private Declare Function FileTimeToLocalFileTime Lib "kernel32.dll" ( _
ByRef lpFileTime As FILETIME, _
ByRef lpLocalFileTime As FILETIME) As Long
Private Declare Function FileTimeToSystemTime Lib "kernel32.dll" ( _
ByRef lpFileTime As FILETIME, _
ByRef lpSystemTime As SYSTEMTIME) As Long
I changed them to ptrsafe:
Private Declare PtrSafe Function FindFirstFile Lib "kernel32.dll" Alias "FindFirstFileA" ( _
ByVal lpFileName As String, _
ByRef lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare PtrSafe Function FindNextFile Lib "kernel32.dll" Alias "FindNextFileA" ( _
ByVal hFindFile As Long, _
ByRef lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare PtrSafe Function FindClose Lib "kernel32.dll" ( _
ByVal hFindFile As Long) As Long
Private Declare PtrSafe Function FileTimeToLocalFileTime Lib "kernel32.dll" ( _
ByRef lpFileTime As FILETIME, _
ByRef lpLocalFileTime As FILETIME) As Long
Private Declare PtrSafe Function FileTimeToSystemTime Lib "kernel32.dll" ( _
ByRef lpFileTime As FILETIME, _
ByRef lpSystemTime As SYSTEMTIME) As Long
Now it seems to work.
Depending on what your macro does, the obvious answer seems to be that you need to set
ReadOnly:=True
to be
ReadOnly:=False
So that your macro can make changes to the data.

ShellExecute brings Office programs to crash

I used to printout PDF-files from MS Access 2010 32-bit on Windows 7 32 bit with this code.
Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String) As Long
Function PrintAttachement()
ShellExecute 0, "print", "\\s1016d\attachments\40297827.pdf", "", ""
End Function
Now, we changed to Windows 7 64 bit, but still Office 32 bit and ALL Office applications crashes when running this function.
Strange, because if I use "open" iso. "print" it works as expected!
Please help, as I am lost how to correct my function to run again.
All I want is to printout a PDF-File from Access without opening the file.
As there are many files in a row, I cannot open any PDF-app to printout the file.
Thanks
Michael
Edit: After Long searches I found the solution!
You have to declare the function like in 64bit application, but to make shure to run it also on machines with 32bit declare both.
#If VBA7 Then
Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) _
As Long
#Else
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) _
As Long
#End If
So in order to show this as answered, and also vouch that this does solve the same situation for me. If you are referencing a windows DLL in-line, you need to ensure that the correct DLL is being used based on the environment the access DB is being used in (32bit vs 64bit) you can do this dynamically as described above (and repeated here)
#If VBA7 Then
Private Declare PtrSafe Function apiShellExecute Lib "shell32.dll" _
Alias "ShellExecuteA" _
(ByVal hwnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long _
) As Long
#Else
Private Declare Function apiShellExecute Lib "shell32.dll" _
Alias "ShellExecuteA" _
(ByVal hwnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long _
) As Long
#End If