Skip to content

Instantly share code, notes, and snippets.

@namazso
Last active January 9, 2021 19:16
Show Gist options
  • Save namazso/0cfd2eb771ab08185de19dee1109d9a8 to your computer and use it in GitHub Desktop.
Save namazso/0cfd2eb771ab08185de19dee1109d9a8 to your computer and use it in GitHub Desktop.
win32 text prompt box, like MessageBox but for text
INT_PTR PromptText(const wchar_t* title, wchar_t* text, size_t len)
{
__pragma(pack(push, 1)) struct alignas(DWORD)
{
DLGTEMPLATE hdr{
WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTER,
0,
1,
100,
100,
200,
10
};
WORD menu = 0x0000;
WORD clazz = 0x0000;
WORD title = 0x0000;
alignas(DWORD) DLGITEMTEMPLATE edit {
WS_VISIBLE | ES_AUTOHSCROLL,
0,
0,
0,
200,
10,
101
};
WORD edit_class_marker = 0xFFFF;
WORD edit_class_selector = 0x0081;
WORD edit_title = 0x0000;
WORD edit_extra = 0x0000;
} __pragma(pack(pop)) dlg;
const auto old_awareness = SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE);
const auto dpi = GetDpiForSystem();
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(ncm);
SystemParametersInfoW(
SPI_GETNONCLIENTMETRICS,
0,
&ncm,
0
);
const auto fontheight = abs(ncm.lfMessageFont.lfHeight);
dlg.hdr.x = dlg.hdr.x * dpi / 96;
dlg.hdr.y = dlg.hdr.y * dpi / 96;
dlg.hdr.cx = dlg.hdr.cx * dpi / 96;
dlg.hdr.cy = fontheight * 72 / 96;
dlg.edit.x = dlg.edit.x * dpi / 96;
dlg.edit.y = dlg.edit.y * dpi / 96;
dlg.edit.cx = dlg.edit.cx * dpi / 96;
dlg.edit.cy = fontheight * 72 / 96;
struct Params
{
HFONT font;
const wchar_t* title;
wchar_t* text;
size_t len;
} p{ CreateFontIndirectW(&ncm.lfMessageFont), title, text, len };
const static auto dlg_proc = (DLGPROC)[](HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -> INT_PTR
{
Params* p;
if (uMsg == WM_INITDIALOG)
{
p = (Params*)lParam;
SetWindowLongPtrW(hDlg, GWLP_USERDATA, lParam);
const auto edit = GetDlgItem(hDlg, 101);
SetWindowFont(edit, p->font, TRUE);
SetWindowTextW(edit, p->text);
SetWindowTextW(hDlg, p->title);
}
else
{
p = (Params*)GetWindowLongPtrW(hDlg, GWLP_USERDATA);
if(uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED)
{
const auto btn = LOWORD(wParam);
if (btn == IDCANCEL)
{
EndDialog(hDlg, IDCANCEL);
}
else if (btn == IDOK)
{
GetWindowTextW(GetDlgItem(hDlg, 101), p->text, p->len);
p->text[p->len - 1] = 0;
EndDialog(hDlg, IDOK);
}
}
}
return FALSE;
};
const auto ret = DialogBoxIndirectParamW(
GetModuleHandleA(nullptr),
(LPCDLGTEMPLATE)&dlg,
nullptr,
dlg_proc,
(LPARAM)&p
);
SetThreadDpiAwarenessContext(old_awareness);
DeleteObject(p.font);
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment