如何在Windows中更改OPENFILENAME对话框的位置?

时间:2015-04-28 23:30:08

标签: c++ winapi dialog

这是我尝试使用钩子函数来获取对话框窗口句柄。 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;
}

1 个答案:

答案 0 :(得分:3)

使用OFN_EXPLORER时,您必须移动hdlg父窗口,因为传递给回调的HWND不是实际的对话窗口。这在文档中明确说明:

OFNHookProc callback function

  

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;
}