-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathInputBox.cpp
179 lines (155 loc) · 4.58 KB
/
InputBox.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#define STRICT
//#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <tchar.h>
#include "arg.inl"
#ifdef UNICODE
#define tWinMain wWinMain
#else
#define tWinMain WinMain
#endif
#define IDD_INPUTBOX 1001
#define IDC_PROMPT 101
#define IDC_EDIT1 102
BOOL SetClientWindowRect(_In_ HWND hWnd, _In_ const RECT* prc)
{
return SetWindowPos(hWnd, NULL, prc->left, prc->top, prc->right - prc->left, prc->bottom - prc->top, SWP_NOZORDER);
}
void CenterWindow(_In_ HWND hWnd)
{
const HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
MONITORINFO mi = { sizeof(MONITORINFO) };
GetMonitorInfo(hMonitor, &mi);
const POINT pt = { (mi.rcWork.left + mi.rcWork.right)/2, (mi.rcWork.top + mi.rcWork.bottom)/2 };
RECT rc;
GetWindowRect(hWnd, &rc);
const POINT d = { pt.x - (rc.left + rc.right)/2, pt.y - (rc.top + rc.bottom)/2 };
rc.left += d.x;
rc.right += d.x;
rc.top += d.y;
rc.bottom += d.y;
SetClientWindowRect(hWnd, &rc);
}
BOOL GetClientWindowRect(_In_ HWND hWnd, _In_ RECT* prc)
{
HWND hParent = GetParent(hWnd);
BOOL b = GetWindowRect(hWnd, prc);
::ScreenToClient(hParent, (POINT*) &prc->left);
::ScreenToClient(hParent, (POINT*) &prc->right);
return b;
}
struct InputBoxParam
{
LPCTSTR title;
LPCTSTR prompt;
LPCTSTR default;
TCHAR result[2048];
};
struct MoveChildData
{
int dy;
};
BOOL CALLBACK MoveChild(
_In_ HWND hWnd,
_In_ LPARAM lParam
)
{
const MoveChildData* mcd = (MoveChildData*) lParam;
const int id = GetWindowLong(hWnd, GWL_ID);
switch (id)
{
case IDC_EDIT1:
case IDOK:
case IDCANCEL:
{
RECT rc;
GetClientWindowRect(hWnd, &rc);
rc.top += mcd->dy;
rc.bottom += mcd->dy;
SetClientWindowRect(hWnd, &rc);
}
break;
}
return TRUE;
}
void CalcRect(HWND hWnd, RECT* prc)
{
TCHAR text[1024];
HDC hDC = GetWindowDC(hWnd);
HFONT hFont = GetWindowFont(hWnd);
HFONT hOldFont = SelectFont(hDC, hFont);
GetWindowText(hWnd, text, ARRAYSIZE(text));
DrawText(hDC, text, -1, prc, DT_CALCRECT | DT_WORDBREAK);
SelectFont(hDC, hOldFont);
ReleaseDC(hWnd, hDC);
}
void FixSize(HWND hDlg)
{
HWND hPrompt = GetDlgItem(hDlg, IDC_PROMPT);
RECT rc;
GetClientWindowRect(hPrompt, &rc);
RECT nrc = rc;
CalcRect(hPrompt, &nrc);
SetClientWindowRect(hPrompt, &nrc);
MoveChildData mcd = {};
mcd.dy = (nrc.bottom - nrc.top) - (rc.bottom - rc.top);
EnumChildWindows(hDlg, MoveChild, LPARAM(&mcd));
GetClientWindowRect(hDlg, &rc);
rc.bottom += mcd.dy;
SetClientWindowRect(hDlg, &rc);
}
INT_PTR InputBoxDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
InputBoxParam* p = reinterpret_cast<InputBoxParam*>(GetWindowLongPtr(hDlg, GWLP_USERDATA));;
switch (uMsg)
{
case WM_INITDIALOG:
p = (InputBoxParam*) lParam;
SetWindowLongPtr(hDlg, GWLP_USERDATA, LONG_PTR(p));
if (p->title) SetWindowText(hDlg, p->title);
if (p->prompt) SetDlgItemText(hDlg, IDC_PROMPT, p->prompt);
if (p->default) SetDlgItemText(hDlg, IDC_EDIT1, p->default);
FixSize(hDlg);
CenterWindow(hDlg);
return TRUE;
case WM_COMMAND:
switch (wParam)
{
case IDOK:
GetDlgItemText(hDlg, IDC_EDIT1, p->result, ARRAYSIZE(p->result));
EndDialog(hDlg, EXIT_SUCCESS);
break;
case IDCANCEL:
EndDialog(hDlg, EXIT_FAILURE);
break;
}
return TRUE;
case WM_CLOSE:
EndDialog(hDlg, EXIT_FAILURE + 1);
return TRUE;
default:
return FALSE;
}
}
int WINAPI tWinMain(/*[in]*/ HINSTANCE hInstance, /*[in, optional]*/ HINSTANCE hPrevInstance, /*[in]*/ LPTSTR lpCmdLine, /*[in]*/ int nCmdShow)
{
UNREFERENCED_PARAMETER(hInstance);
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(nCmdShow);
InputBoxParam p = {};
arginit(__argc, __wargv);
p.title = argvaluedesc(_T("/Title"), nullptr, _T("title"), _T("Dialog title"));
p.prompt = argnumdesc(1, nullptr, _T("prompt"), _T("Dialog prompt"));
p.default = argvaluedesc(_T("/Default"), nullptr, _T("initial_value"), _T("Input initial value"));
if (!argcleanup())
return EXIT_FAILURE;
if (argusage())
return EXIT_SUCCESS;
INT_PTR ret = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_INPUTBOX), NULL, InputBoxDlgProc, LPARAM(&p));
if (ret == 0)
_tprintf(_T("%s\n"), p.result);
return int(ret);
}