I am using Extended monitor screen. How to set the custom popup position of the predefined windows of Microsoft (for Example: OpenFileDialog) in windows forms using C#. This dialog should open to the center of the parent.
-
You can use [SetWindowPos](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowpos) to move a dialog Window to a specific position. You may also use UI Automation to determine when the dialog (the class name is "#32770") is opened. The `AutomationElement` returned by the `WindowOpened` event will also reference the Dialog bounds (as a `Windows.Rect`), so you can use this measure to center it on another Window you own. Note, however, that the position of these dialogs is meant to be a User preference. You shouldn't manipulate it without care. – Jimi Aug 16 '19 at 08:16
-
https://stackoverflow.com/a/2576220/17034 – Hans Passant Aug 16 '19 at 11:45
2 Answers
There is an other question answered by Dima, who wrote the following:
Open file dialog is a system dialog. It means that your application has no control over it. It is controlled by user. If user wants to change its size in one application, it will gain new size in all applications, since this size is user's preference.
Purpose of common dialogs is providing standard UI parts to user. Imagine how uncomfortable for users it would be to search for file to open if every application would use its own OpenFileDialog.
However you can build your own dialog.
But if you want to open your custom form you can use this:
SomeForm form = new SomeForm();
form.StartPosition = FormStartPosition.CenterParent;
form.ShowDialog(this);
Sadly it will not work this way if you use this method with simple Show()
maybe because than it will use another thread and cant access to the parent, or I don't really know.
I hope it helped.
EDIT: If your problem is that the dialog isn't opening on the same screen your application runs maybe there is a solution here:
private void button1_Click(object sender, EventArgs e)
{
Point myNewLocation = Location;
myNewLocation.Offset(20, 20);
OpenFileDialog dlg = new OpenFileDialog();
dlg.Title = "Open";
MoveDialogWhenOpened(dlg.Title, myNewLocation);
dlg.ShowDialog(this);
}
private void MoveDialogWhenOpened(String windowCaption, Point location)
{
Object[] argument = new Object[] { windowCaption, location };
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += new DoWorkEventHandler(MoveDialogThread);
backgroundWorker.RunWorkerAsync(argument);
}
private void MoveDialogThread(Object sender, DoWorkEventArgs e)
{
const String DialogWindowClass = "#32770";
String windowCaption = (String)(((Object[])e.Argument)[0]);
Point location = (Point)(((Object[])e.Argument)[1]);
// try for a maximum of 4 seconds (sleepTime * maxAttempts)
Int32 sleepTime = 10; // milliseconds
Int32 maxAttempts = 400;
for (Int32 i = 0; i < maxAttempts; ++i)
{
// find the handle to the dialog
IntPtr handle = Win32Api.FindWindow(DialogWindowClass, windowCaption);
// if the handle was found and the dialog is visible
if ((Int32)handle > 0 && Win32Api.IsWindowVisible(handle) > 0)
{
// move it
Win32Api.SetWindowPos(handle, (IntPtr)0, location.X, location.Y,
0, 0, Win32Api.SWP_NOSIZE | Win32Api.SWP_NOZORDER);
break;
}
// if not found wait a brief sec and try again
Thread.Sleep(sleepTime);
}
}
public class Win32Api
{
public const Int32 SWP_NOSIZE = 0x1;
public const Int32 SWP_NOZORDER = 0x4;
[DllImport("user32")]
public static extern IntPtr FindWindow(String lpClassName,
String lpWindowName);
[DllImport("user32")]
public static extern Int32 IsWindowVisible(IntPtr hwnd);
[DllImport("user32")]
public static extern Int32 SetWindowPos(IntPtr hwnd,
IntPtr hwndInsertAfter,
Int32 x,
Int32 y,
Int32 cx,
Int32 cy,
Int32 wFlags);
}

- 494
- 5
- 15
-
Thanks for your response. But i am not using custom form. I am facing issue once when i try to use OpenFileDialog and PrintDialog like that. So suggest me solution based on that. – Thirumurugan Loganathan Aug 16 '19 at 07:00
-
@Thirumurugan By the way now I tried to open the OpenFileDialog on a WinForms button click and it always opened and it's center was the button beneath it. It your program doesn't work like it maybe you can try the openFileDialog.ShowDialog(this);. Or you can try the other solution that I added above. – turanszkik Aug 16 '19 at 09:12
GetOpenFilename() allows you specify a hook procedure via the OFN_ENABLEHOOK flag, and through this, you can create a hook procedure that receives a window handle to a child window of the open file dialog. By calling GetParent() from the hook procedure, you can subclass the window procedure of the GetOpenFilename() dialog and control where it locates itself when it is shown.
This method works well for me.
HWND hMainWnd = NULL; // Designated window handle assigned before GetOpenFilename() call.
TCHAR szFilepath[512] = _T(""); // Filename returned from GetOpenFile().
const UINT WM_OPENSAVE_DIALOG = RegisterWindowMessage(_T("OPENSAVE"));
bool bTriggerMove = false; // Move open file dialog only once, on WM_INITDIALOG.
WNDPROC pOldDlgProc = NULL; // Pointer to original window procedur for open file dialog
// Forward declarations.
BOOL CALLBACK NewOpenFileProc( HWND hDlg, UINT uMsg,
WPARAM wParam, LPARAM lParam );
UINT_PTR CALLBACK OpenFileHookProc( HWND hDlg, UINT uMsg,
WPARAM wParam, LPARAM lParam );
// Define a hook procedure for the GetOpenFilename() call
//---------------------------------------------------------------------------
UINT_PTR CALLBACK OpenFileHookProc( HWND hDlg, UINT uMsg,
WPARAM wParam, LPARAM lParam )
{
//==========================================================================
// This is the publicly exposed hook procedure for the open file dialog.
// From here, we subclass the parent window to get the *actual* OpenFile
// dialog box procedure, hook it, and set our trigger
if( uMsg == WM_INITDIALOG )
{
//The hook procedure handle is a child window of the actual dialog.
HWND hDlgParent = GetParent( hDlg );
pOldDlgProc = (WNDPROC)GetWindowLong( hDlgParent, GWL_WNDPROC );
bTriggerMove = true;
SetWindowLong( hDlgParent, GWL_WNDPROC, (LONG) NewOpenFileProc );
}
return 0;
}
// Define a window procedure subclass for the GetOpenFilename() call
//---------------------------------------------------------------------------
BOOL CALLBACK NewOpenFileProc( HWND hDlg, UINT uMsg,
WPARAM wParam, LPARAM lParam )
{
BOOL bResult = FALSE;
//========================================================================
// This is a window procedure subclass that centers a file open dialog
// over a designated window when GetOpenFilename() is called and refers
// to the OPENFILENAME structure defined in the function MyFileOpenDialog(),
// below. The dialog is centered over it's designated window regardless of
// what monitor the designated window is on.
if( pOldDlgProc != NULL )
{
if( uMsg == WM_NCDESTROY )
{
// Destroying open dialog window so remove window subclass.
SetWindowLong( hDlg, GWL_WNDPROC,(LONG)pOldDlgProc );
// Falls through and calls the old dialog procedure.
}
else
if( uMsg == WM_SHOWWINDOW )
{
// Showing or hide the open dialog window
if( wParam == TRUE && bTriggerMove == true )
{
// Showing the window for the first time.
bTriggerMove = false;
SendMessage( hDlg, WM_OPENSAVE_DIALOG, 0, 0 );
}
// Falls through and calls the old dialog procedure.
}
else
if( uMsg == WM_OPENSAVE_DIALOG )
{
// Center the dialog over hMainWnd (the designated window).
RECT rcDlg; int cxDlg, cyDlg;
RECT rcWnd; int cxWnd, cyWnd;
int iLeft, iTop;
// main window metrics
GetWindowRect( hMainWnd, &rcWnd );
cxWnd= rcWnd.right - rcWnd.left;
cyWnd= rcWnd.bottom - rcWnd.top;
// OpenFilename dialog metrics
GetWindowRect( hDlg, &rcDlg );
cxDlg= rcDlg.right - rcWnd.left;
cyDlg= rcDlg.bottom - rcDlg.top;
iLeft = rcWnd.left + ( ( cxWnd - cxDlg ) / 2);
iTop = rcWnd.top + ( ( cyWnd - cyDlg ) / 2);
SetWindowPos( hDlg, NULL, iLeft, iTop , 0, 0, SWP_NOSIZE );
//Don't call old window procedure for this custom message.
return FALSE;
}
bResult = CallWindowProc( pOldDlgProc, hDlg, uMsg, wParam, lParam );
}
return bResult;
}
// Define a function to incorporate necessary business logic, assign
// handle of window to center the dialog on, then call GetOpenFilename().
//---------------------------------------------------------------------------
void MyOpenFileDialog( void )
{
OPENFILENAME ofn;
// Initialize OPENFILENAME
memset( &ofn, 0, sizeof(ofn) );
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hMainWnd;
ofn.lpstrFile = szFilepath;
ofn.nMaxFile = RTL_NUMBER_OF(szFilepath);
ofn.lpstrFilter = _T("Excel Workbook\0*.xls\0");
ofn.nFilterIndex = 0;
ofn.lpstrTitle = _T("Import from Excel...");
ofn.lpfnHook = OFNHookProc;
ofn.Flags = OFN_PATHMUSTEXIST |
OFN_FILEMUSTEXIST |
OFN_ENABLEHOOK |
OFN_EXPLORER |
OFN_ENABLESIZING |
0;
// Display the Open dialog box.
if( GetOpenFileName( &ofn ) != TRUE )
{
return;
}
}