1

Topic: API: How in hook-procedure for GetOpenFileName to receive OPENFILENAME?

Hello.
It is impossible in hook-procedure for GetOpenFileName to consider structure OPENFILENAME.
I try to do all on . That is, according to the official documentation.
But Word  on CopyMemory (marked in the code):

Option Explicit: Option Base 0: Option Compare Binary
Private Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
Private Declare PtrSafe Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)
Private Declare PtrSafe Function GetOpenFileName Lib "comdlg32" Alias "GetOpenFileNameA" (pOpenFileName As OPENFILENAME) As Boolean
Private Type OPENFILENAME
lStructSize As Long
hwndOwner As LongPtr
hInstance As LongPtr
lpstrFilter As String
lpstrCustomFilter As String
nMaxCustFilter As Long
nFilterIndex As Long
lpstrFile As String
nMaxFile As Long
lpstrFileTitle As String
nMaxFileTitle As Long
lpstrInitialDir As String
lpstrTitle As String
flags As Long
nFileOffset As Integer
nFileExtension As Integer
lpstrDefExt As String
lCustData As LongPtr
lpfnHook As LongPtr
lpTemplateName As String
pvReserved As LongPtr
dwReserved As Long
FlagsEx As Long
End Type
Private Type NMHDR
hwndFrom As LongPtr
idfrom As LongPtr
code As Long
End Type
Private Type OFNOTIFY
hdr As NMHDR
lpOFN As OPENFILENAME
pszFile As String
End Type
Const WM_NOTIFY = &H4E
Const CDN_FIRST = -601&
Const CDN_TYPECHANGE = (CDN_FIRST - 6&)
Const OFN_ENABLEHOOK = &H20
Const OFN_ENABLESIZING = &H800000
Const OFN_EXPLORER = &H80000
Const OFN_HIDEREADONLY = &H4
Const OFN_LONGNAMES = &H200000
Const OFN_NOVALIDATE = &H100
Const OFN_OVERWRITEPROMPT = &H2
Const OFN_PATHMUSTEXIST = &H800
Private Function GetAddressOfFunction (ByVal Adr As LongPtr) As LongPtr
GetAddressOfFunction = Adr
End Function
Private Function MyHookProc (ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As Long
Dim oHead As NMHDR
Dim oNotify As OFNOTIFY
If uMsg = WM_NOTIFY Then
' event title
CopyMemory oHead, ByVal lParam, LenB (oHead)
' changed type of files
If oHead.code = CDN_TYPECHANGE Then
' event parameters
CopyMemory oNotify, ByVal lParam, LenB (oNotify) ' here Word  at once!!!
End If
End If
End Function
Function API_SelectFolderDlg () As Long
Dim OFN As OPENFILENAME
OFN.hwndOwner = GetActiveWindow ()
OFN.hInstance = 0
OFN.flags = OFN_EXPLORER _
Or OFN_ENABLESIZING _
Or OFN_LONGNAMES _
Or OFN_HIDEREADONLY _
Or OFN_PATHMUSTEXIST _
Or OFN_NOVALIDATE _
Or OFN_ENABLEHOOK
OFN.lpfnHook = GetAddressOfFunction (AddressOf MyHookProc)
OFN.lpstrFilter = "All files" and vbNullChar and "*. *" both vbNullChar and _
"Documents Word" and vbNullChar and "*.DOCX;*.DOCM;*.DOC;*.RTF" both vbNullChar and _
vbNullChar
OFN.nFilterIndex = 1
OFN.lpstrInitialDir = vbNullChar
OFN.lpstrFile = String $ (4096, vbNullChar)
OFN.nMaxFile = Len (OFN.lpstrFile) - 1
OFN.lStructSize = LenB (OFN)
GetOpenFileName OFN
End Function

Tried also such variant:

Private Type OFNOTIFY
hdr As NMHDR
lpOFN As LongPtr ' OPENFILENAME
pszFile As String
End Type
Private Function MyHookProc (ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As Long
Dim oNotify As OFNOTIFY
Dim OFN As OPENFILENAME
If uMsg = WM_NOTIFY Then
CopyMemory oNotify, ByVal lParam, LenB (oNotify)
If oNotify.hdr.code = CDN_TYPECHANGE Then
CopyMemory OFN, ByVal oNotify.lpOFN, LenB (OFN) ' here Word , but not at once!!!
End If
End If
End Function

Prompt, where the fool?

2

Re: API: How in hook-procedure for GetOpenFileName to receive OPENFILENAME?

the leader wrote:

Private Type OFNOTIFY
hdr As NMHDR
>>> lpOFN As OPENFILENAME <<<
pszFile As String
End Type

Prompt, where the fool?

3

Re: API: How in hook-procedure for GetOpenFileName to receive OPENFILENAME?

234522 wrote:

it is passed...

But this variant too does not work (the example above) see:

Private Type OFNOTIFY
hdr As NMHDR
>>> lpOFN As LongPtr ' OPENFILENAME <<<
pszFile As String
End Type

While, threw out CopyMemory and I read the data directly from the form, through SendMessage.
But it would be desirable to understand, where an error with OPENFILENAME?

4

Re: API: How in hook-procedure for GetOpenFileName to receive OPENFILENAME?

The son of the leader;
Is not present VBA7, therefore without LongPtr. And without String, to a heap (can, a paranoia):

Option Explicit: Option Base 0: Option Compare Binary
Private Declare Function GetActiveWindow Lib "user32" () As Long
Private Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)
Private Declare Function GetOpenFileName Lib "comdlg32" Alias "GetOpenFileNameW" (pOpenFileName As OPENFILENAME) As Long
Private Type OPENFILENAME
lStructSize As Long
hwndOwner As Long
hInstance As Long
lpstrFilter As Long ' String
lpstrCustomFilter As Long ' String
nMaxCustFilter As Long
nFilterIndex As Long
lpstrFile As Long ' String
nMaxFile As Long
lpstrFileTitle As Long ' String
nMaxFileTitle As Long
lpstrInitialDir As Long ' String
lpstrTitle As Long ' String
flags As Long
nFileOffset As Integer
nFileExtension As Integer
lpstrDefExt As Long ' String
lCustData As Long
lpfnHook As Long
lpTemplateName As Long ' String
pvReserved As Long
dwReserved As Long
FlagsEx As Long
End Type
Private Type NMHDR
hwndFrom As Long
idfrom As Long
code As Long
End Type
Private Type OFNOTIFY
hdr As NMHDR
lpOFN As Long ' OPENFILENAME
pszFile As Long ' String
End Type
Const WM_NOTIFY = &H4E
Const CDN_FIRST = -601&
Const CDN_TYPECHANGE = (CDN_FIRST - 6&)
Const OFN_ENABLEHOOK = &H20
Const OFN_ENABLESIZING = &H800000
Const OFN_EXPLORER = &H80000
Const OFN_HIDEREADONLY = &H4
Const OFN_LONGNAMES = &H200000
Const OFN_NOVALIDATE = &H100
Const OFN_OVERWRITEPROMPT = &H2
Const OFN_PATHMUSTEXIST = &H800
Private Function GetAddressOfFunction (ByVal Adr As Long) As Long
GetAddressOfFunction = Adr
End Function
Private Function MyHookProc (ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim oHead As NMHDR
Dim oNotify As OFNOTIFY
If uMsg = WM_NOTIFY Then
' event title
CopyMemory oHead, ByVal lParam, LenB (oHead)
' changed type of files
If oHead.code = CDN_TYPECHANGE Then
' event parameters
CopyMemory oNotify, ByVal lParam, LenB (oNotify) ' here Word  at once!!!
Dim oOFN As OPENFILENAME
CopyMemory oOFN.lStructSize, ByVal oNotify.lpOFN, LenB (oOFN.lStructSize)
CopyMemory oOFN, ByVal oNotify.lpOFN, oOFN.lStructSize
End If
End If
End Function
Function API_SelectFolderDlg () As Long
Dim OFN As OPENFILENAME
OFN.hwndOwner = GetActiveWindow ()
OFN.hInstance = 0
OFN.flags = OFN_EXPLORER _
Or OFN_ENABLESIZING _
Or OFN_LONGNAMES _
Or OFN_HIDEREADONLY _
Or OFN_PATHMUSTEXIST _
Or OFN_NOVALIDATE _
Or OFN_ENABLEHOOK
OFN.lpfnHook = GetAddressOfFunction (AddressOf MyHookProc)
OFN.lpstrFilter = StrPtr ("All files" and vbNullChar and "*. *" both vbNullChar and _
"Documents Word" and vbNullChar and "*.DOCX;*.DOCM;*.DOC;*.RTF" both vbNullChar and _
vbNullChar)
OFN.nFilterIndex = 1
OFN.lpstrInitialDir = 0 ' vbNullChar
Dim strFile As String
strFile = String $ (4096, vbNullChar)
OFN.lpstrFile = StrPtr (strFile)
OFN.nMaxFile = 4096
OFN.lStructSize = LenB (OFN)
GetOpenFileName OFN
End Function

does not fall, in Locals values probable.
Perhaps not to suffer, and to take ready?

5

Re: API: How in hook-procedure for GetOpenFileName to receive OPENFILENAME?

234522 wrote:

is not present VBA7, therefore without LongPtr. And without String, to a heap (can, a paranoia)

Without String it is inconvenient, when it is necessary to receive, and not just to send. Just my case.
Passage on GetOpenFileNameW (instead of GetOpenFileNameA) I support, though it and attracts application StrConv.

234522 wrote:

does not fall, in Locals values probable.

Yes, understood! I thank! Understood an error with a size.

234522 wrote:

Perhaps not to suffer, and to take ready?

So anywhere there is no example, including under the link where something from OPENFILENAME is read.
Unfortunately, at debugging of functions API, Word it is frequent  on break points, though the code the worker.
All the same I tend GetDlgItem and SendMessage, instead of CopyMemory

6

Re: API: How in hook-procedure for GetOpenFileName to receive OPENFILENAME?

the leader wrote:

Without String it is inconvenient, when it is necessary to receive, and not just to send. Just my case.

With String "offstage" there are string conversions, in certain cases absolutely superfluous. As on me, in such cases it is possible to write a class-cover for structure, and to use explicit conversion:

Private Declare Function CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (_
Dest As Any, Src As Any, ByVal cb As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" (_
ByVal psString As Any) As Long
Public Function LPWSTR2String (ByVal lpWStr As Long) As String
Dim nStrLen As Long
If lpWStr Then
nStrLen = lstrlenW (lpWStr)
LPWSTR2String = String $ (nStrLen, vbNullChar)
CopyMemory ByVal StrPtr (LPWSTR2String), ByVal lpWStr, nStrLen * 2
Else
LPWSTR2String = vbNullString
End If
End Function

the leader wrote:

Passage on GetOpenFileNameW (instead of GetOpenFileNameA) I support,

Windows 95 already came to an end, yes. Though and there was Unicode layer.

the leader wrote:

though it also attracts application StrConv.

Where, what for (with the registration of the above-stated procedure)?

the leader wrote:

it is passed...
Yes, understood! I thank! Understood an error with a size.

the Code

Dim oOFN As OPENFILENAME
CopyMemory oOFN.lStructSize, ByVal oNotify.lpOFN, LenB (oOFN.lStructSize)
CopyMemory oOFN, ByVal oNotify.lpOFN, oOFN.lStructSize

as time fast-dirty and at all the sample for imitation as theoretically potentially leads buffer overrun. After reading of the size of structure it is necessary to select or the buffer of the necessary size and to copy there, or if we decided to manage Dim oOFN As OPENFILENAME, to write in oOFN the Minimum (LenB (oOFN), oOFN.lStructSize) byte.

the leader wrote:

it is passed...
So anywhere there is no example, including under the link where something from OPENFILENAME is read.

Under the link is, including an example (Example_GetFileName).

7

Re: API: How in hook-procedure for GetOpenFileName to receive OPENFILENAME?

234522 wrote:

With String "offstage" there are string conversions, in certain cases absolutely superfluous. As on me, in such cases it is possible to write a class-cover for structure, and to use explicit conversion

If also offstage the converter costs, is finite. Now, for string, everywhere it is necessary to do StrConv, both on an output, and on an input.

234522 wrote:

Dim oOFN As OPENFILENAME
CopyMemory oOFN.lStructSize, ByVal oNotify.lpOFN, LenB (oOFN.lStructSize)
CopyMemory oOFN, ByVal oNotify.lpOFN, oOFN.lStructSize

As time fast-dirty and at all the sample for imitation as theoretically potentially leads buffer overrun. After reading of the size of structure it is necessary to select or the buffer of the necessary size and to copy there, or if we decided to manage Dim oOFN As OPENFILENAME, to write in oOFN the Minimum (LenB (oOFN), oOFN.lStructSize) byte.

. Means, between two CopyMemory there is no the line adjusting the size oOFN.

8

Re: API: How in hook-procedure for GetOpenFileName to receive OPENFILENAME?

the leader wrote:

it is passed...
. Means, between two CopyMemory there is no the line adjusting the size oOFN.

Something is above written not that. After all the size of structure does not change, whence overflow? Will interrupt more correctly handling if LenB (oOFN) differs from the size oOFN.lStructSize,  here CopyMemory oOFN.lStructSize, ByVal oNotify.lpOFN, LenB (oOFN.lStructSize). That is, when function returned not clearly that. In the light of it, by the way, even at coincidence of the sizes not the fact that structures of objects coincide. It quits generally a trouble sad
The branch subject can be reduced in a question: "As under the pointer on object to receive object". There is any general-purpose circuit? Somehow it is possible to define, what the object structure under the pointer, coincides with declared by us? If in the documentation on API one, and functions API return another, how to work? Or I did not read up it? smile