【问题标题】:How to change position of an OPENFILENAME dialog in Windows?如何在 Windows 中更改 OPENFILENAME 对话框的位置?
【发布时间】: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 调用之后立即调用它时,它才会报告有意义的值。穿插的流操作符可以改变调用线程记录的最后一个错误码。

标签: c++ winapi dialog


【解决方案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;
}

【讨论】:

    猜你喜欢
    • 2022-06-17
    • 1970-01-01
    • 2013-05-23
    • 2012-09-15
    • 2011-03-24
    • 2021-03-09
    • 2012-11-13
    • 1970-01-01
    相关资源
    最近更新 更多