如何使用 SetTimer() 在 C++ 中创建一定数量的消息框?
How do I use SetTimer() to create certain number of message boxes after another in c++?
我正在努力做到这一点,当一个消息框打开时,另一个消息框会在几秒钟后打开,而无需任何用户输入(按 OK 按钮)。我希望旧的保持打开状态,但出现新的。我还希望能够使用 SetWindowsHookEx
并限制创建的消息框数量。我知道这使用函数 SetTimer() 并且需要某种 if 语句,其中当前的对话框数量等于限制并在达到该数量时停止。那么我该如何进行这项工作呢?我试图研究,但似乎没有任何效果。
我的尝试:
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
thread_local int MsgBox_X;
thread_local int MsgBox_Y;
thread_local int Limit = 10;
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;
if (<# of dialogs> == Limit) {
std::terminate()
}
}
void _MessageBox()
{
HWND HWND1;
MessageBox(HWND1, TEXT("Message"), TEXT("MsgBox"), MB_ICONWARNING | MB_OK);
SetTimer(HWND1,
TIMER1,
2000,
(TIMERPROC)NULL);
case WM_TIMER:
switch (wParam)
{
case TIMER1:
MessageBoxPos(NULL, TEXT("Message 2"), TEXT("MsgBox 2"), MB_ICONWARNING | MB_OK, 50, 50);
return 0;
}
}
}
int main()
{
ShowWindow(::GetConsoleWindow(), SW_HIDE);
_MessageBox();
}
您正在将 未初始化的 HWND
传递给 MessageBox()
。
此外,MessageBox()
是一个阻塞函数,直到对话框关闭它才会退出,所以你需要在调用之前创建定时器MessageBox()
。除非您使用 SetWindowsHookEx()
或 SetWinEventHook()
挂钩对话框的创建,否则您可以在创建对话框的 HWND
时创建计时器,然后将 HWND
传递给 SetTimer()
.
此外,您处理 WM_TIMER
消息的语法完全错误。
也就是说,MessageBox()
显示模式对话框并运行自己的消息循环,因此您根本不需要手动处理 WM_TIMER
。您可以为计时器分配一个回调,让模态循环为您调度回调事件。
试试像这样的东西:
#include <Windows.h>
thread_local int MsgBox_X;
thread_local int MsgBox_Y;
thread_local int NumMsgBoxes = 0;
static LRESULT CALLBACK CBTSetPosProc(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, &CBTSetPosProc, NULL, GetCurrentThreadId());
MsgBox_X = X;
MsgBox_Y = Y;
int result = MessageBox(hWnd, lpText, lpCaption, uType);
if (hHook) UnhookWindowsHookEx(hHook);
return result;
}
static void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD)
{
if (NumMsgBoxes > 0)
{
--NumMsgBoxes;
MessageBoxPos(NULL, TEXT("Message 2"), TEXT("MsgBox 2"), MB_ICONWARNING | MB_OK, 50, 50);
}
}
void _MessageBox(int NumberOfMsgBoxes)
{
NumMsgBoxes = NumberOfMsgBoxes;
if (NumMsgBoxes > 0)
{
--NumMsgBoxes;
UINT timer = SetTimer(NULL, 0, 2000, &TimerProc);
if (timer) {
MessageBox(NULL, TEXT("Message"), TEXT("MsgBox"), MB_ICONWARNING | MB_OK);
KillTimer(NULL, timer);
}
}
}
int main()
{
ShowWindow(GetConsoleWindow(), SW_HIDE);
_MessageBox(5);
}
或者:
#include <Windows.h>
thread_local int MsgBox_X;
thread_local int MsgBox_Y;
thread_local int NumMsgBoxes = 0;
static LRESULT CALLBACK CBTSetPosProc(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, &CBTSetPosProc, NULL, GetCurrentThreadId());
MsgBox_X = X;
MsgBox_Y = Y;
int result = MessageBox(hWnd, lpText, lpCaption, uType);
if (hHook) UnhookWindowsHookEx(hHook);
return result;
}
static void CALLBACK TimerProc(HWND hwnd, UINT message, UINT_PTR idTimer, DWORD dwTime)
{
KillTimer(hwnd, idTimer);
if (NumMsgBoxes > 0)
MessageBoxPos(NULL, TEXT("Message 2"), TEXT("MsgBox 2"), MB_ICONWARNING | MB_OK, 50, 50);
}
static LRESULT CALLBACK CBTSetTimerProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_CREATEWND)
{
CBT_CREATEWND* s = (CBT_CREATEWND*)lParam;
if (s->lpcs->hwndParent == NULL)
{
if (--NumMsgBoxes > 0)
SetTimer((HWND)wParam, 1, 2000, &TimerProc);
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
void _MessageBox(int NumberOfMsgBoxes)
{
HHOOK hHook = SetWindowsHookEx(WH_CBT, &CBTSetTimerProc, NULL, GetCurrentThreadId());
NumMsgBoxes = NumberOfMsgBoxes;
if (NumMsgBoxes > 0)
MessageBox(NULL, TEXT("Message"), TEXT("MsgBox"), MB_ICONWARNING | MB_OK);
if (hHook) UnhookWindowsHookEx(hHook);
}
int main()
{
ShowWindow(GetConsoleWindow(), SW_HIDE);
_MessageBox(5);
}
我正在努力做到这一点,当一个消息框打开时,另一个消息框会在几秒钟后打开,而无需任何用户输入(按 OK 按钮)。我希望旧的保持打开状态,但出现新的。我还希望能够使用 SetWindowsHookEx
并限制创建的消息框数量。我知道这使用函数 SetTimer() 并且需要某种 if 语句,其中当前的对话框数量等于限制并在达到该数量时停止。那么我该如何进行这项工作呢?我试图研究,但似乎没有任何效果。
我的尝试:
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
thread_local int MsgBox_X;
thread_local int MsgBox_Y;
thread_local int Limit = 10;
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;
if (<# of dialogs> == Limit) {
std::terminate()
}
}
void _MessageBox()
{
HWND HWND1;
MessageBox(HWND1, TEXT("Message"), TEXT("MsgBox"), MB_ICONWARNING | MB_OK);
SetTimer(HWND1,
TIMER1,
2000,
(TIMERPROC)NULL);
case WM_TIMER:
switch (wParam)
{
case TIMER1:
MessageBoxPos(NULL, TEXT("Message 2"), TEXT("MsgBox 2"), MB_ICONWARNING | MB_OK, 50, 50);
return 0;
}
}
}
int main()
{
ShowWindow(::GetConsoleWindow(), SW_HIDE);
_MessageBox();
}
您正在将 未初始化的 HWND
传递给 MessageBox()
。
此外,MessageBox()
是一个阻塞函数,直到对话框关闭它才会退出,所以你需要在调用之前创建定时器MessageBox()
。除非您使用 SetWindowsHookEx()
或 SetWinEventHook()
挂钩对话框的创建,否则您可以在创建对话框的 HWND
时创建计时器,然后将 HWND
传递给 SetTimer()
.
此外,您处理 WM_TIMER
消息的语法完全错误。
也就是说,MessageBox()
显示模式对话框并运行自己的消息循环,因此您根本不需要手动处理 WM_TIMER
。您可以为计时器分配一个回调,让模态循环为您调度回调事件。
试试像这样的东西:
#include <Windows.h>
thread_local int MsgBox_X;
thread_local int MsgBox_Y;
thread_local int NumMsgBoxes = 0;
static LRESULT CALLBACK CBTSetPosProc(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, &CBTSetPosProc, NULL, GetCurrentThreadId());
MsgBox_X = X;
MsgBox_Y = Y;
int result = MessageBox(hWnd, lpText, lpCaption, uType);
if (hHook) UnhookWindowsHookEx(hHook);
return result;
}
static void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD)
{
if (NumMsgBoxes > 0)
{
--NumMsgBoxes;
MessageBoxPos(NULL, TEXT("Message 2"), TEXT("MsgBox 2"), MB_ICONWARNING | MB_OK, 50, 50);
}
}
void _MessageBox(int NumberOfMsgBoxes)
{
NumMsgBoxes = NumberOfMsgBoxes;
if (NumMsgBoxes > 0)
{
--NumMsgBoxes;
UINT timer = SetTimer(NULL, 0, 2000, &TimerProc);
if (timer) {
MessageBox(NULL, TEXT("Message"), TEXT("MsgBox"), MB_ICONWARNING | MB_OK);
KillTimer(NULL, timer);
}
}
}
int main()
{
ShowWindow(GetConsoleWindow(), SW_HIDE);
_MessageBox(5);
}
或者:
#include <Windows.h>
thread_local int MsgBox_X;
thread_local int MsgBox_Y;
thread_local int NumMsgBoxes = 0;
static LRESULT CALLBACK CBTSetPosProc(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, &CBTSetPosProc, NULL, GetCurrentThreadId());
MsgBox_X = X;
MsgBox_Y = Y;
int result = MessageBox(hWnd, lpText, lpCaption, uType);
if (hHook) UnhookWindowsHookEx(hHook);
return result;
}
static void CALLBACK TimerProc(HWND hwnd, UINT message, UINT_PTR idTimer, DWORD dwTime)
{
KillTimer(hwnd, idTimer);
if (NumMsgBoxes > 0)
MessageBoxPos(NULL, TEXT("Message 2"), TEXT("MsgBox 2"), MB_ICONWARNING | MB_OK, 50, 50);
}
static LRESULT CALLBACK CBTSetTimerProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_CREATEWND)
{
CBT_CREATEWND* s = (CBT_CREATEWND*)lParam;
if (s->lpcs->hwndParent == NULL)
{
if (--NumMsgBoxes > 0)
SetTimer((HWND)wParam, 1, 2000, &TimerProc);
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
void _MessageBox(int NumberOfMsgBoxes)
{
HHOOK hHook = SetWindowsHookEx(WH_CBT, &CBTSetTimerProc, NULL, GetCurrentThreadId());
NumMsgBoxes = NumberOfMsgBoxes;
if (NumMsgBoxes > 0)
MessageBox(NULL, TEXT("Message"), TEXT("MsgBox"), MB_ICONWARNING | MB_OK);
if (hHook) UnhookWindowsHookEx(hHook);
}
int main()
{
ShowWindow(GetConsoleWindow(), SW_HIDE);
_MessageBox(5);
}