C++:如何将 MessageBox 居中?
Posted
技术标签:
【中文标题】C++:如何将 MessageBox 居中?【英文标题】:C++: How to center MessageBox? 【发布时间】:2011-06-09 21:56:02 【问题描述】:将 Visual Studio C++ 与 MFC 结合使用。如何将 MessageBox 居中到它的父窗口?目前它以桌面为中心。
【问题讨论】:
在 MessageBox 调用之前使用 PostMessage()。在您的消息处理程序中,使用 EnumWindows 找到消息框,然后将 MoveWindow 移到您想要的位置。 消息框的类 #32770 应该可以帮助您找到它 有一种方法可以改变位置,但是对于这么小的任务来说它太复杂了。只需创建您自己的 CDialog。 【参考方案1】:::AfxMessageBox() 对我来说出现在 MainFrame 的中心。这基本上是对 ::MessageBox() 的调用,其中 MainFrame 的句柄作为第一个参数。这不适合你吗?
【讨论】:
对我不起作用。它可能以应用程序的“MainFrame”为中心,但我需要它以我的 CDialog 派生对话框为中心(我从中调用 MessageBox/AfxMessageBox)。【参考方案2】:您需要安装一个钩子并在创建时更改对话框位置。
int MessageBoxCentered(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
// Center message box at its parent window
static HHOOK hHookCBT;
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;
【讨论】:
【参考方案3】:你不能。这就是为什么很多人编写自己的 MessageBox 类的原因。
【讨论】:
【参考方案4】:谁说“不能”?
试试这个:
这是用于 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 提出的问题的小修正。确保父句柄始终一致,这应该可以正常工作。它对我有用,即使是同一个程序的两个实例......
【讨论】:
请注意,这会找到 a 消息框,不一定是 your 消息框。 没问题... 将if(X)
替换为if(GetParent(X)==H_frame)
并且程序中的文件对话框和消息框也由 H_frame 或任何句柄名称作为父级,其值将是唯一的,因此甚至是多个同一程序的实例将安全共存。以上是关于C++:如何将 MessageBox 居中?的主要内容,如果未能解决你的问题,请参考以下文章
C++ MessageBox (Windows.h) - 它有啥作用以及如何使它不可见(或等效)?
新线程中弹出的Messagebox,不点击确定按钮,主线程暂停