C ++:如何使MessageBox居中?

问题描述 投票:1回答:4

将Visual Studio C ++与MFC一起使用。如何将MessageBox置于其父窗口的中心?目前它以桌面为中心。

c++ windows mfc center messagebox
4个回答
3
投票

:: AfxMessageBox()出现在MainFrame的中心。这基本上是对:: MessageBox()的调用,其中MainFrame的句柄作为第一个参数。这不适合你吗?


0
投票

你不能。这就是很多人编写自己的MessageBox类的原因。


0
投票

谁说“不能”?

试试这个:

这是针对Win32 API,用C语言编写的。根据需要翻译它...

case WM_NOTIFY:{
  HWND X=FindWindow("#32770",NULL);
  if(GetParent(X)==H_frame){int Px,Py,Sx,Sy; RECT R1,R2;
    GetWindowRect(hwnd,&R1); GetWindowRect(X,&R2);
    Sx=R2.right-R2.left,Px=R1.left+(R1.right-R1.left)/2-Sx/2;
    Sy=R2.bottom-R2.top,Py=R1.top+(R1.bottom-R1.top)/2-Sy/2;
    MoveWindow(X,Px,Py,Sx,Sy,1);
  }
} break;

将其添加到WndProc代码中...您可以根据需要设置位置,在这种情况下,它只是在主程序窗口的中心。它将对任何消息框或文件打开/保存对话框以及可能的其他一些本机控件执行此操作。我不确定,但我认为您可能需要包含COMMCTRL或COMMDLG来使用它,至少,如果您想要打开/保存对话框,您将需要。

我试着查看NMHDR的通知代码和hwndFrom,然后决定它同样有效,而且更容易,而不是。如果你真的想要非常具体,请告诉FindWindow寻找你想要它找到的窗口的唯一标题(标题)。

这是在屏幕上绘制消息框之前触发的,因此如果您设置一个全局标记以指示代码何时执行操作,并查找唯一标题,则可以确保您执行的操作只会发生一次(可能会有多个通知程序)。我没有详细探讨过这个问题,但是我设法让CreateWindow在消息框对话框中放置一个编辑框。当老鼠的耳朵嫁接到克隆猪的脊柱上时,它看起来不合适,但它有效。以这种方式做事可能比滚动自己要容易得多。

乌鸦。

编辑:小修正来处理Raymond Chen提出的问题。确保父句柄始终一致,这应该可以正常工作。它对我来说,即使有两个相同程序的实例......


0
投票

您需要安装一个钩子并在创建时更改对话框位置。

HHOOK hHookCBT{};

int MessageBoxCentered(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
    // Center message box at its parent window
    hHookCBT = SetWindowsHookEx(WH_CBT,
        [](int nCode, WPARAM wParam, LPARAM lParam) -> LRESULT
        {
            if (nCode == HCBT_CREATEWND)
            {
                if (((LPCBT_CREATEWND)lParam)->lpcs->lpszClass == (LPWSTR)(ATOM)32770)  // #32770 = dialog box class
                {
                    RECT rcParent{};
                    GetWindowRect(((LPCBT_CREATEWND)lParam)->lpcs->hwndParent, &rcParent);
                    ((LPCBT_CREATEWND)lParam)->lpcs->x = rcParent.left + ((rcParent.right - rcParent.left) - ((LPCBT_CREATEWND)lParam)->lpcs->cx) / 2;
                    ((LPCBT_CREATEWND)lParam)->lpcs->y = rcParent.top + ((rcParent.bottom - rcParent.top) - ((LPCBT_CREATEWND)lParam)->lpcs->cy) / 2;
                }
            }

            return CallNextHookEx(hHookCBT, nCode, wParam, lParam);
        },
        0, GetCurrentThreadId());

    int iRet{ MessageBox(hWnd, lpText, lpCaption, uType) };

    UnhookWindowsHookEx(hHookCBT);

    return iRet;
}
© www.soinside.com 2019 - 2024. All rights reserved.