mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
209 lines
6.6 KiB
C++
209 lines
6.6 KiB
C++
#include "stdafx.h"
|
|
#include "MessageBox.h"
|
|
|
|
namespace Forms
|
|
{
|
|
DialogResult MessageBox::Win32ToDialogResult(uint32_t Value)
|
|
{
|
|
switch (Value)
|
|
{
|
|
case IDOK:
|
|
return DialogResult::OK;
|
|
case IDCANCEL:
|
|
return DialogResult::Cancel;
|
|
case IDABORT:
|
|
return DialogResult::Abort;
|
|
case IDRETRY:
|
|
return DialogResult::Retry;
|
|
case IDIGNORE:
|
|
return DialogResult::Ignore;
|
|
case IDYES:
|
|
return DialogResult::Yes;
|
|
case IDNO:
|
|
return DialogResult::No;
|
|
default:
|
|
return DialogResult::No;
|
|
}
|
|
}
|
|
|
|
static Drawing::Color ForegroundColor = Drawing::Color::Black;
|
|
static Drawing::Color BackgroundColor = Drawing::Color::White;
|
|
static Drawing::Color BottomColor = Drawing::Color(240, 240, 240);
|
|
|
|
struct Win32MessageBoxThreadInfo
|
|
{
|
|
HHOOK hHook; // Hook handle
|
|
HWND hWnd; // Message box handle
|
|
WNDPROC lpMsgBoxProc; // Original window proc
|
|
COLORREF crText; // Foreground color
|
|
COLORREF crBack; // Background color
|
|
COLORREF crBottom; // Background bottom color
|
|
HBRUSH hBrush; // Background brush
|
|
HBRUSH hBrushBottom; // Background bottom brush
|
|
} static thread_local Win32PerThreadInfo;
|
|
|
|
LRESULT CALLBACK Win32MessageBoxProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
Win32PerThreadInfo.hBrush = ::CreateSolidBrush(Win32PerThreadInfo.crBack);
|
|
Win32PerThreadInfo.hBrushBottom = ::CreateSolidBrush(Win32PerThreadInfo.crBottom);
|
|
}
|
|
break;
|
|
case WM_CTLCOLORDLG:
|
|
case WM_CTLCOLORSTATIC:
|
|
{
|
|
HDC hDC = (HDC)wParam;
|
|
|
|
::SetBkMode(hDC, TRANSPARENT);
|
|
::SetTextColor(hDC, Win32PerThreadInfo.crText);
|
|
|
|
return (LRESULT)Win32PerThreadInfo.hBrush;
|
|
}
|
|
case WM_CTLCOLORBTN:
|
|
{
|
|
return (LRESULT)Win32PerThreadInfo.hBrushBottom;
|
|
}
|
|
case WM_PAINT:
|
|
{
|
|
auto Result = CallWindowProc(Win32PerThreadInfo.lpMsgBoxProc, hWnd, uMsg, wParam, lParam);
|
|
|
|
RECT Rc{};
|
|
GetClientRect(hWnd, &Rc);
|
|
|
|
auto DC = GetDC(hWnd);
|
|
|
|
FillRect(DC, &Rc, Win32PerThreadInfo.hBrush);
|
|
|
|
Rc.top = Rc.bottom - 42;
|
|
|
|
FillRect(DC, &Rc, Win32PerThreadInfo.hBrushBottom);
|
|
|
|
return Result;
|
|
}
|
|
case WM_COMMAND:
|
|
{
|
|
::DeleteObject(Win32PerThreadInfo.hBrush);
|
|
::DeleteObject(Win32PerThreadInfo.hBrushBottom);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return CallWindowProc(Win32PerThreadInfo.lpMsgBoxProc, hWnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
LRESULT CALLBACK Win32CallbackProc(int nCode, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (nCode < 0)
|
|
return ::CallNextHookEx(Win32PerThreadInfo.hHook, nCode, wParam, lParam);
|
|
|
|
switch (nCode)
|
|
{
|
|
case HCBT_CREATEWND:
|
|
{
|
|
// Ensure that we have the right window to track
|
|
LPCBT_CREATEWND lpCbtCreate = (LPCBT_CREATEWND)lParam;
|
|
if (WC_DIALOG == lpCbtCreate->lpcs->lpszClass)
|
|
{
|
|
Win32PerThreadInfo.hWnd = (HWND)wParam;
|
|
}
|
|
else
|
|
{
|
|
if ((NULL == Win32PerThreadInfo.lpMsgBoxProc) && (NULL != Win32PerThreadInfo.hWnd))
|
|
Win32PerThreadInfo.lpMsgBoxProc = (WNDPROC)::SetWindowLongPtr(Win32PerThreadInfo.hWnd, GWLP_WNDPROC, (LONG_PTR)Win32MessageBoxProc);
|
|
}
|
|
}
|
|
break;
|
|
case HCBT_DESTROYWND:
|
|
{
|
|
// Ensure that our tracked window is being destroyed
|
|
if (Win32PerThreadInfo.hWnd == (HWND)wParam)
|
|
::SetWindowLongPtr(Win32PerThreadInfo.hWnd, GWLP_WNDPROC, (LONG_PTR)Win32PerThreadInfo.lpMsgBoxProc);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
DialogResult MessageBox::ShowCore(const String& Text, const String& Caption, MessageBoxButtons Buttons, MessageBoxIcon Icon, MessageBoxDefaultButton DefaultButton, MessageBoxOptions Options, bool ShowHelp, Control* Owner)
|
|
{
|
|
uint32_t Style = (ShowHelp) ? HELP_BUTTON : 0;
|
|
Style |= (int)Buttons | (int)Icon | (int)DefaultButton | (int)Options;
|
|
|
|
HWND Handle = nullptr;
|
|
|
|
if (ShowHelp || (((int)Options & ((int)MessageBoxOptions::ServiceNotification | (int)MessageBoxOptions::DefaultDesktopOnly)) == 0))
|
|
{
|
|
if (Owner == nullptr)
|
|
Handle = GetActiveWindow();
|
|
else
|
|
Handle = Owner->GetHandle();
|
|
}
|
|
|
|
// Reset hooking data for this thread
|
|
Win32PerThreadInfo.hHook = NULL;
|
|
Win32PerThreadInfo.hWnd = NULL;
|
|
Win32PerThreadInfo.lpMsgBoxProc = NULL;
|
|
|
|
// Load the initial color values
|
|
Win32PerThreadInfo.crText = RGB(ForegroundColor.GetR(), ForegroundColor.GetG(), ForegroundColor.GetB());
|
|
Win32PerThreadInfo.crBack = RGB(BackgroundColor.GetR(), BackgroundColor.GetG(), BackgroundColor.GetB());
|
|
Win32PerThreadInfo.crBottom = RGB(BottomColor.GetR(), BottomColor.GetG(), BottomColor.GetB());
|
|
|
|
// Install the hook
|
|
Win32PerThreadInfo.hHook = ::SetWindowsHookExA(WH_CBT, Win32CallbackProc, GetModuleHandle(NULL), GetCurrentThreadId());
|
|
|
|
auto Result = MessageBoxA(Handle, (const char*)Text, (const char*)Caption, Style);
|
|
|
|
// Remove the hook
|
|
::UnhookWindowsHookEx(Win32PerThreadInfo.hHook);
|
|
|
|
// Convert the result
|
|
return Win32ToDialogResult(Result);
|
|
}
|
|
|
|
DialogResult MessageBox::Show(const String& Text)
|
|
{
|
|
return ShowCore(Text, "", MessageBoxButtons::OK, MessageBoxIcon::None, MessageBoxDefaultButton::Button1, (MessageBoxOptions)0, false, nullptr);
|
|
}
|
|
|
|
DialogResult MessageBox::Show(const String& Text, const String& Caption)
|
|
{
|
|
return ShowCore(Text, Caption, MessageBoxButtons::OK, MessageBoxIcon::None, MessageBoxDefaultButton::Button1, (MessageBoxOptions)0, false, nullptr);
|
|
}
|
|
|
|
DialogResult MessageBox::Show(const String& Text, const String& Caption, MessageBoxButtons Buttons)
|
|
{
|
|
return ShowCore(Text, Caption, Buttons, MessageBoxIcon::None, MessageBoxDefaultButton::Button1, (MessageBoxOptions)0, false, nullptr);
|
|
}
|
|
|
|
DialogResult MessageBox::Show(const String& Text, const String& Caption, MessageBoxButtons Buttons, MessageBoxIcon Icon)
|
|
{
|
|
return ShowCore(Text, Caption, Buttons, Icon, MessageBoxDefaultButton::Button1, (MessageBoxOptions)0, false, nullptr);
|
|
}
|
|
|
|
DialogResult MessageBox::Show(Control* Owner, const String& Text, const String& Caption, MessageBoxButtons Buttons, MessageBoxIcon Icon)
|
|
{
|
|
return ShowCore(Text, Caption, Buttons, Icon, MessageBoxDefaultButton::Button1, (MessageBoxOptions)0, false, Owner);
|
|
}
|
|
|
|
DialogResult MessageBox::Show(Control* Owner, const String& Text, const String& Caption, MessageBoxButtons Buttons, MessageBoxIcon Icon, MessageBoxDefaultButton DefaultButton)
|
|
{
|
|
return ShowCore(Text, Caption, Buttons, Icon, DefaultButton, (MessageBoxOptions)0, false, Owner);
|
|
}
|
|
|
|
DialogResult MessageBox::Show(Control* Owner, const String& Text, const String& Caption, MessageBoxButtons Buttons, MessageBoxIcon Icon, MessageBoxDefaultButton DefaultButton, MessageBoxOptions Options)
|
|
{
|
|
return ShowCore(Text, Caption, Buttons, Icon, DefaultButton, Options, false, Owner);
|
|
}
|
|
|
|
void MessageBox::SetMessageBoxColors(Drawing::Color Foreground, Drawing::Color Background, Drawing::Color Bottom)
|
|
{
|
|
ForegroundColor = Foreground;
|
|
BackgroundColor = Background;
|
|
BottomColor = Bottom;
|
|
}
|
|
}
|