void _MessageBox()
{
ResultMB = MessageBox(NULL, TEXT("MB!"), TEXT("Message"), MB_OK);
if (ResultMB == IDOK)
{
for (int q = 1; q < 5; q++)
{
ResultMB = MessageBox(NULL, TEXT("hi"), TEXT("Message"), MB_OK);
}
}
}
I want to make every MessageBox be somewhere else on the screen But I do not know how to change a position using C ++
MessageBox()
does not allow you to specify a position for its dialog window. However, you can manipulate the dialog window manually to accomplish this. It just takes a little extra work to gain access to the dialog window.
Prior to Windows Vista, you can install a thread-local hook via SetWindowsHookEx()
or SetWinEventHook()
before calling MessageBox()
. The hook will give you access to the dialog window when it is created. You can then do whatever you want with the dialog window.
For example:
// Using SetWindowsHookEx() ...
__thread int MsgBox_X;
__thread int MsgBox_Y;
static LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_CREATEWND)
{
CBT_CREATEWND *s = (CBT_CREATEWND*) lParam;
if (s->lpcs->hwndParent == NULL)
{
s->lpcs->x = MsgBox_X;
s->lpcs->y = MsgBox_Y;
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int MessageBoxPos(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType, int X, int Y)
{
HHOOK hHook = SetWindowsHookEx(WH_CBT, &CBTProc, NULL, GetCurrentThreadId());
MsgBox_X = X;
MsgBox_Y = Y;
int result = MessageBox(hWnd, lpText, lpCaption, uType);
if (hHook) UnhookWindowsHookEx(hHook);
return result;
}
// Using SetWinEventHook() ...
__thread int MsgBox_X;
__thread int MsgBox_Y;
static void CALLBACK WinEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
if ((GetWindowLongPtr(hwnd, GWL_STYLE) & WS_CHILD) == 0)
SetWindowPos(hwnd, NULL, MsgBox_X, MsgBox_Y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
int MessageBoxPos(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType, int X, int Y)
{
HWINEVENTHOOK hHook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, NULL, &WinEventProc, GetCurrentProcessId(), GetCurrentThreadId(), WINEVENT_OUTOFCONTEXT);
MsgBox_X = X;
MsgBox_Y = Y;
int result = MessageBox(hWnd, lpText, lpCaption, uType);
if (hHook) UnhookWinEvent(hHook);
return result;
}
On Windows Vista and later, the above techniques will still work, but a better option would be to simply not use MessageBox()
at all, use TaskDialogIndirect()
instead. You can assign a callback function to it, and when the callback receives a TDN_CREATED
or TDN_DIALOG_CONSTRUCTED
message, it gives you access to the dialog window, which you can then manipulate however you want.
For example:
// Using TaskDialogIndirect() ...
struct TaskDialogData
{
int X;
int Y;
};
static HRESULT CALLBACK TaskDialogCallback(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData)
{
if (msg == TDN_DIALOG_CONSTRUCTED) // or TDN_CREATED, either one works
{
TaskDialogData *data = (TaskDialogData*) lpRefData;
SetWindowPos(hwnd, NULL, data->X, data->Y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
return S_OK;
}
int MessageBoxPos(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType, int X, int Y)
{
TaskDialogData data;
data.X = X;
data.Y = Y;
TASKDIALOGCONFIG config = {};
config.cbSize = sizeof(config);
config.hwndParent = hWnd;
config.pszWindowTitle = lpCaption;
config.pszContent = lpText;
// configure other settings as desired, based on uType...
config.pfCallback = &TaskDialogCallback;
config.lpCallbackData = (LONG_PTR) &data;
int button = 0;
TaskDialogIndirect(&config, &button, NULL, NULL);
return button;
}
Either way, you can then call MessageBoxPos()
as needed:
void _MessageBox()
{
ResultMB = MessageBoxPos(NULL, TEXT("MB!"), TEXT("Message"), MB_OK, DesiredX, DesiredY);
if (ResultMB == IDOK)
{
for (int q = 1; q < 5; q++)
{
ResultMB = MessageBoxPos(NULL, TEXT("hi"), TEXT("Message"), MB_OK, DesiredX, DesiredY);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With