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

Posted

技术标签:

【中文标题】如何在 Windows 中更改 OPENFILENAME 对话框的位置?【英文标题】:How to change position of an OPENFILENAME dialog in Windows? 【发布时间】:2015-04-28 23:30:07 【问题描述】:

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

【问题讨论】:

这会谴责你使用可怕的 XP 旧版对话框 GetLastError 的返回值在你调用它的时候是没有意义的。仅当 SetWindowPos 失败时,并且仅当您在失败的 API 调用之后立即调用它时,它才会报告有意义的值。穿插的流操作符可以改变调用线程记录的最后一个错误码。 【参考方案1】:

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

OFNHookProc callback function

hdlg [输入] 打开或另存为对话框的子对话框的句柄。 使用 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;

【讨论】:

以上是关于如何在 Windows 中更改 OPENFILENAME 对话框的位置?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows 中更改 Maven 存储库文件夹?

如何在 Windows 中更改默认播放和录制设备名称?

如何在Windows中更改Git终端的标题?

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

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

如何在 Windows Phone 8 中更改数据透视表头模板