Last active
May 7, 2021 03:25
-
-
Save haseeb-heaven/a97ea40c4ca3b6ba6d5a1b8348bd0585 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* AutoCloseMessageBox - C++ Implementation of original code of C# from CodeProject https://www.codeproject.com/Articles/7968/MessageBox-with-a-timeout-for-NET | |
By Artic Coder. | |
*/ | |
#undef UNICODE | |
#include <iostream> | |
#include <Windows.h> | |
using std::string; | |
//Pointer to Hook functions. | |
typedef intptr_t(*HookProc)(int nCode, intptr_t wParam, intptr_t lParam); | |
typedef void(*TimerProc)(intptr_t hWnd, uint32_t uMsg, uintptr_t nIDEvent, uint32_t dwTime); | |
//Global vars. | |
const int timerID = 42; | |
HookProc hookProc; | |
TimerProc hookTimer; | |
uint32_t hookTimeout; | |
string hookCaption; | |
HHOOK hHook; | |
int captionLen; | |
class AutoCloseMessageBox { | |
private: | |
static void MessageBoxHook(string caption, uint32_t uTimeout) | |
{ | |
if (hHook != NULL) | |
throw new std::runtime_error("multiple calls are not supported"); | |
hookTimeout = uTimeout; | |
hookCaption = !caption.empty() ? caption : ""; | |
hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, (HOOKPROC)hookProc, 0, GetCurrentThreadId()); | |
} | |
static intptr_t MessageBoxHookProc(int nCode, intptr_t wParam, intptr_t lParam) | |
{ | |
if (nCode < 0) | |
return CallNextHookEx(hHook, nCode, wParam, lParam); | |
auto msg = reinterpret_cast<CWPRETSTRUCT*>(lParam); | |
auto hook = hHook; | |
//Hook Messagebox on Initialization. | |
if (!hookCaption.empty() && msg->message == WM_INITDIALOG) | |
{ | |
int nLength = GetWindowTextLength(msg->hwnd); | |
char* text = new char[captionLen + 1]; | |
GetWindowText(msg->hwnd, text, captionLen + 1); | |
//If Capttion window found Unhook it. | |
if (hookCaption == text) | |
{ | |
hookCaption = string(""); | |
SetTimer(msg->hwnd, (uintptr_t)timerID, hookTimeout, (TIMERPROC)hookTimer); | |
UnhookWindowsHookEx(hHook); | |
hHook = 0; | |
} | |
} | |
return CallNextHookEx(hook, nCode, wParam, lParam); | |
} | |
static void MessageBoxTimerProc(HWND hWnd, uint32_t uMsg, uintptr_t nIDEvent, uint32_t dwTime) | |
{ | |
if (nIDEvent == (uintptr_t)timerID) | |
{ | |
short dw = (short)SendMessage(hWnd, DM_GETDEFID, 0, 0); | |
EndDialog(hWnd, (intptr_t)dw); | |
} | |
} | |
public: | |
AutoCloseMessageBox() { | |
hookProc = HookProc(MessageBoxHookProc); | |
hookTimer = TimerProc(MessageBoxTimerProc); | |
hookTimeout = 0; | |
hookCaption = string(""); | |
hHook = 0; | |
} | |
//Different overloaded methods for Showing message. | |
static int Show(string message) { | |
string caption = " "; | |
captionLen = caption.length(); | |
MessageBoxHook(caption, 1000); | |
return MessageBox((HWND)NULL,message.c_str(), caption.c_str(),0); | |
} | |
static int Show(string message,uint32_t uTimeout) { | |
string caption = " "; | |
captionLen = caption.length(); | |
MessageBoxHook(caption, uTimeout); | |
return MessageBox((HWND)NULL, message.c_str(),caption.c_str(), 0); | |
} | |
static int Show(string message, string caption, uint32_t uTimeout) { | |
captionLen = caption.length(); | |
MessageBoxHook(caption, uTimeout); | |
return MessageBox((HWND)NULL, message.c_str(), caption.c_str(), 0); | |
} | |
static int Show(string message, string caption, uint32_t uTimeout,uint32_t iconType) { | |
captionLen = caption.length(); | |
MessageBoxHook(caption, uTimeout); | |
caption = !caption.empty() ? caption : ""; | |
return MessageBox((HWND)0, message.c_str(),caption.c_str(),iconType); | |
} | |
}; | |
//Main methods with examples. | |
int main() | |
{ | |
AutoCloseMessageBox().Show("Hello AutoCloseMsgBox");//Message with default timeout. | |
AutoCloseMessageBox().Show("Hello AutoCloseMsgBox",2500);//Message with 2.5 Seconds timeout. | |
AutoCloseMessageBox().Show("Hello AutoCloseMsgBox","Error",1000); //Message with 1 Seconds timeout with Caption. | |
AutoCloseMessageBox().Show("Hello AutoCloseMsgBox","Confirmation Dialog",1000,MB_YESNOCANCEL); //Message with 1 Seconds timeout with Caption and MessageButton. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment