我在Microsoft文档中找不到任何内容,所以我想知道是否有人知道,是否可以指定IFileDialog的起始位置?具体来说,我希望第一次打开该对话框,以便它在父窗口的中心打开。

除了以某种方式挂接到底层WM_*消息之外,我没有看到一种直接的方法。

是否可以使用 SetWindowPos 之类的东西?

最佳答案

shell 程序的IFileDialog实现支持IOleWindow接口(interface)(请注意,似乎没有记录...)。但是必须先打开对话框,然后才能获取其窗口句柄。

因此,窍门是使用IFileDialogEvents接口(interface)订阅对话框的事件,获取窗口句柄,然后移动它,如下面的示例所示。我选择OnSelectionChange是因为它似乎是个好地方。当然这是要适应的(您不希望每次选择更改时都移动窗口...)。

class Events : public IFileDialogEvents
{
  // poor man's IUnknown implementation :-)
  STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) { *ppvObject = NULL; return E_NOINTERFACE; }
  STDMETHODIMP_(ULONG) AddRef() { return 1; };
  STDMETHODIMP_(ULONG) Release() { return 1; }
  STDMETHODIMP OnFileOk(IFileDialog *pfd) { return S_OK; }
  STDMETHODIMP OnFolderChanging(IFileDialog *pfd, IShellItem *psiFolder) { return S_OK; }
  STDMETHODIMP OnShareViolation(IFileDialog *pfd, IShellItem *psi, FDE_SHAREVIOLATION_RESPONSE *pResponse) { return S_OK; }
  STDMETHODIMP OnTypeChange(IFileDialog *pfd) { return S_OK; }
  STDMETHODIMP OnOverwrite(IFileDialog *pfd, IShellItem *psi, FDE_OVERWRITE_RESPONSE *pResponse) { return S_OK; }
  STDMETHODIMP OnFolderChange(IFileDialog *pfd) { return S_OK; }

  STDMETHODIMP OnSelectionChange(IFileDialog *pfd) {
    IOleWindow *window;
    if (SUCCEEDED(pfd->QueryInterface(&window)))
    {
      HWND hwnd;
      if (SUCCEEDED(window->GetWindow(&hwnd)))
      {
        MoveWindow(hwnd, 0, 0, 600, 600, FALSE);
      }
      window->Release();
    }
    return S_OK;
  }
};

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
  CoInitialize(NULL);
  IFileOpenDialog *dlg;
  if (SUCCEEDED(CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL, IID_PPV_ARGS(&dlg))))
  {
    DWORD cookie;
    Events *evts = new Events();
    dlg->Advise(evts, &cookie);
    dlg->Show(NULL);
    dlg->Unadvise(cookie);
    dlg->Release();
    delete evts;
  }
  CoUninitialize();
}

关于windows - 可以指定IFileDialog的开始位置吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13476169/

10-13 09:19