diff --git a/src/Dialogs.c b/src/Dialogs.c index 0d9a6cfb..d979fc67 100644 --- a/src/Dialogs.c +++ b/src/Dialogs.c @@ -102,9 +102,10 @@ int MsgBox(int iType,UINT uIdMsg,...) case MBOKCANCEL: iIcon = MB_ICONEXCLAMATION | MB_OKCANCEL; break; } - if (!(hwnd = GetFocus())) + if (!(hwnd = GetActiveWindow())) hwnd = hwndMain; + PostMessage(hwndMain, APPM_CENTER_MESSAGE_BOX, (WPARAM)hwnd, 0); return MessageBoxEx(hwnd, szText,szTitle, MB_SETFOREGROUND | iIcon, @@ -138,6 +139,9 @@ void DisplayCmdLineHelp(HWND hwnd) mbp.lpfnMsgBoxCallback = NULL; mbp.dwLanguageId = MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL); + if (hwnd != NULL) { + PostMessage(hwndMain, APPM_CENTER_MESSAGE_BOX, (WPARAM)hwnd, 0); + } MessageBoxIndirect(&mbp); } diff --git a/src/Dialogs.h b/src/Dialogs.h index 5451e78e..ce438199 100644 --- a/src/Dialogs.h +++ b/src/Dialogs.h @@ -26,6 +26,12 @@ #define MBYESNOCANCEL 4 #define MBOKCANCEL 8 +/** + * App message used to center MessageBox to the window of the program. + * https://stackoverflow.com/questions/6299797/c-how-to-center-messagebox + */ +#define APPM_CENTER_MESSAGE_BOX (WM_APP + 1) + int MsgBox(int,UINT,...); void DisplayCmdLineHelp(HWND hwnd); BOOL GetDirectory(HWND,int,LPWSTR,LPCWSTR,BOOL); diff --git a/src/Helpers.c b/src/Helpers.c index 8138467b..58ab9df9 100644 --- a/src/Helpers.c +++ b/src/Helpers.c @@ -474,9 +474,12 @@ void SetWindowTransparentMode(HWND hwnd,BOOL bTransparentMode) // void CenterDlgInParent(HWND hDlg) { + CenterDlgInParentEx(hDlg, GetParent(hDlg)); +} +void CenterDlgInParentEx(HWND hDlg, HWND hParent) +{ RECT rcDlg; - HWND hParent; RECT rcParent; MONITORINFO mi; HMONITOR hMonitor; @@ -484,8 +487,6 @@ void CenterDlgInParent(HWND hDlg) int xMin, yMin, xMax, yMax, x, y; GetWindowRect(hDlg,&rcDlg); - - hParent = GetParent(hDlg); GetWindowRect(hParent,&rcParent); hMonitor = MonitorFromRect(&rcParent,MONITOR_DEFAULTTONEAREST); @@ -512,6 +513,30 @@ void CenterDlgInParent(HWND hDlg) } +// Why doesn’t the "Automatically move pointer to the default button in a dialog box" +// work for nonstandard dialog boxes, and how do I add it to my own nonstandard dialog boxes? +// https://blogs.msdn.microsoft.com/oldnewthing/20130826-00/?p=3413/ +void SnapToDefaultButton(HWND hwndBox) { + BOOL fSnapToDefButton = FALSE; + if (SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &fSnapToDefButton, 0) && fSnapToDefButton) { + // get child window at the top of the Z order. + // for all our MessageBoxs it's the OK or YES button or NULL. + HWND btn = GetWindow(hwndBox, GW_CHILD); + if (btn != NULL) { + WCHAR className[8] = L""; + GetClassName(btn, className, COUNTOF(className)); + if (lstrcmpi(className, L"Button") == 0) { + RECT rect; + int x, y; + GetWindowRect(btn, &rect); + x = rect.left + (rect.right - rect.left) / 2; + y = rect.top + (rect.bottom - rect.top) / 2; + SetCursorPos(x, y); + } + } + } +} + //============================================================================= // diff --git a/src/Helpers.h b/src/Helpers.h index 490fac20..7cab2a04 100644 --- a/src/Helpers.h +++ b/src/Helpers.h @@ -89,7 +89,9 @@ BOOL SetWindowTitle(HWND,UINT,BOOL,UINT,LPCWSTR,int,BOOL,UINT,BOOL,LPCWSTR); void SetWindowTransparentMode(HWND,BOOL); +void CenterDlgInParentEx(HWND hDlg, HWND hParent); void CenterDlgInParent(HWND); +void SnapToDefaultButton(HWND hwndBox); void GetDlgPos(HWND,LPINT,LPINT); void SetDlgPos(HWND,int,int); void ResizeDlg_Init(HWND,int,int,int); diff --git a/src/Notepad2.c b/src/Notepad2.c index d6b2523a..8aad7836 100644 --- a/src/Notepad2.c +++ b/src/Notepad2.c @@ -1520,6 +1520,16 @@ LRESULT CALLBACK MainWndProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARAM lParam) } break; + case APPM_CENTER_MESSAGE_BOX: { + HWND box = FindWindow(L"#32770", NULL); + HWND parent = GetParent(box); + // MessageBox belongs to us. + if (parent == (HWND)wParam || parent == hwndMain) { + CenterDlgInParentEx(box, parent); + SnapToDefaultButton(box); + } + } + break; default: