这是我尝试使用钩子函数来获取对话框窗口句柄。 SetWindowPos()
和GetLastError()
都返回正确的值,但对话框窗口不受影响并显示在0,0
位置。
#include <windows.h>
#include <iostream>
static UINT_PTR CALLBACK OFNHookProc (HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) {
using namespace std;
switch (uiMsg) {
case WM_INITDIALOG: {
// SetWindowPos returns 1
cout << SetWindowPos(hdlg, HWND_TOPMOST, 200, 200, 0, 0, SWP_NOSIZE ) << endl;
// GetLastError returns 0
cout << GetLastError() << endl;
break;
}
}
return 0;
}
int main() {
OPENFILENAMEW ofn;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAMEW);
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_ENABLEHOOK;
ofn.lpfnHook = OFNHookProc;
GetOpenFileNameW(&ofn);
return 0;
}
答案 0 :(得分:3)
使用OFN_EXPLORER
时,您必须移动hdlg
的父窗口,因为传递给回调的HWND不是实际的对话窗口。这在文档中明确说明:
hdlg [in]
打开或另存为对话框的子对话框的句柄。 使用GetParent函数获取“打开”或“另存为”对话框的句柄。
此外,您应该等待回调接收CDN_INITDONE
通知,而不是WM_INITDIALOG
消息。
试试这个:
static UINT_PTR CALLBACK OFNHookProc (HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
if ((uiMsg == WM_NOTIFY) &&
(reinterpret_cast<OFNOTIFY*>(lParam)->hdr.code == CDN_INITDONE))
{
SetWindowPos(GetParent(hdlg), HWND_TOPMOST, 200, 200, 0, 0, SWP_NOSIZE);
}
return 0;
}