Results 1 to 1 of 1

Thread: Native QFileDialog position under Win32

  1. #1

    Default Native QFileDialog position under Win32

    Qt documentation says:

    "Note that on Windows the dialog will spin a blocking modal event loop that will not dispatch any QTimers, and if parent is not 0 then it will position the dialog just under the parent's title bar."

    Not in the center of the parent window, as one expecting.

    But WinAPI provides a very simple way to define native file dialog's positions. In few words - you have to assign a hook function pointer in OPENFILENAME structure and position dialog properly in that function.

    This function creates correct OPENFILENAME (don't forget to make similar changes in qt_win_make_OFNA function)
    Qt Code:
    1. static OPENFILENAME* qt_win_make_OFN(QWidget *parent,
    2. const QString& initialSelection,
    3. const QString& initialDirectory,
    4. const QString& title,
    5. const QString& filters,
    6. QFileDialog::FileMode mode,
    7. QFileDialog::Options options)
    8. {
    9.  
    10. // ....
    11. OPENFILENAME* ofn = new OPENFILENAME;
    12. memset(ofn, 0, sizeof(OPENFILENAME));
    13.  
    14. // ....
    15. ofn->lpfnHook = qt_win_ofn_hook; // custom hook
    16. ofn->lCustData = (LPARAM)parent; // parent of dialog window
    17. ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLEHOOK); // OFN_ENABLEHOOK enables ofn hook fields
    18. // ....
    19. }
    To copy to clipboard, switch view to plain text mode 

    And this is a hook function:
    Qt Code:
    1. UINT_PTR CALLBACK qt_win_ofn_hook(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
    2. {
    3. // process initialization message
    4. if(uiMsg == WM_INITDIALOG)
    5. {
    6. OPENFILENAME* ofn;
    7. QWidget* parent;
    8.  
    9. HWND frame_dlg;
    10. RECT frame_rect;
    11.  
    12. QRect parent_rect;
    13.  
    14. int dlg_left;
    15. int dlg_top;
    16.  
    17. // this should work even if lParam points to OPENFILENAMEA
    18. ofn = (OPENFILENAME*)lParam; // ofn goes to lparam (as MSDN says)
    19. parent = (QWidget*)ofn->lCustData; // custom data filled in ofn
    20.  
    21. if(parent == 0)
    22. {
    23. // using desktop if no parent window
    24. parent_rect = QApplication::desktop()->geometry();
    25. }
    26. else
    27. {
    28. // getting parent rect
    29. QPoint parent_topleft;
    30.  
    31. parent_topleft = parent->mapToGlobal(QPoint(0, 0));
    32. parent_rect = QRect(parent_topleft, parent->size());
    33. }
    34.  
    35. frame_dlg = GetParent(hdlg); // file dialog handle
    36. GetWindowRect(frame_dlg, &frame_rect); // file dialog frame rect
    37.  
    38. // compute left and top of final rect
    39. dlg_left = (parent_rect.left() + parent_rect.right()) / 2 -
    40. (frame_rect.right - frame_rect.left) / 2;
    41. dlg_top = (parent_rect.top() + parent_rect.bottom()) / 2 -
    42. (frame_rect.bottom - frame_rect.top) / 2;
    43.  
    44. // position file dialog
    45. SetWindowPos(frame_dlg, 0, dlg_left, dlg_top, 0, 0, SWP_NOSIZE);
    46. }
    47.  
    48. return FALSE;
    49. }
    To copy to clipboard, switch view to plain text mode 

    Full qfiledialog_win.cpp file is in the attachments.

    Hope it will help. Or may be, in one beautiful day, it will be commited to the main repository.
    Attached Files Attached Files
    Last edited by no_ghost; 28th May 2009 at 18:59.

Similar Threads

  1. Native QFileDialog block
    By Darktib in forum Qt Programming
    Replies: 9
    Last Post: 30th December 2008, 02:56
  2. Native QFileDialog
    By adonel in forum Qt Programming
    Replies: 1
    Last Post: 17th September 2008, 18:40

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.