-
-
Notifications
You must be signed in to change notification settings - Fork 77
/
Functions.cpp
270 lines (238 loc) · 6.95 KB
/
Functions.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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
#include "stdafx.h"
#include "Functions.h"
void UnicodeSpacesToAscii(CString& string)
{
// Based on:
// https://stackoverflow.com/a/21797208
// https://www.compart.com/en/unicode/category/Zs
// https://www.compart.com/en/unicode/category/Cf
std::unordered_set<WCHAR> unicodeSpaces = {
L'\u00A0', // No-Break Space (NBSP)
//L'\u1680', // Ogham Space Mark
L'\u2000', // En Quad
L'\u2001', // Em Quad
L'\u2002', // En Space
L'\u2003', // Em Space
L'\u2004', // Three-Per-Em Space
L'\u2005', // Four-Per-Em Space
L'\u2006', // Six-Per-Em Space
L'\u2007', // Figure Space
L'\u2008', // Punctuation Space
L'\u2009', // Thin Space
L'\u200A', // Hair Space
L'\u202F', // Narrow No-Break Space (NNBSP)
L'\u205F', // Medium Mathematical Space (MMSP)
L'\u3000' // Ideographic Space
};
std::unordered_set<WCHAR> unicodeInvisible = {
L'\u00AD', // Soft Hyphen (SHY)
//L'\u0600', // Arabic Number Sign
//L'\u0601', // Arabic Sign Sanah
//L'\u0602', // Arabic Footnote Marker
//L'\u0603', // Arabic Sign Safha
//L'\u0604', // Arabic Sign Samvat
//L'\u0605', // Arabic Number Mark Above
//L'\u061C', // Arabic Letter Mark (ALM)
//L'\u06DD', // Arabic End of Ayah
//L'\u070F', // Syriac Abbreviation Mark
//L'\u08E2', // Arabic Disputed End of Ayah
//L'\u180E', // Mongolian Vowel Separator (MVS)
L'\u200B', // Zero Width Space (ZWSP)
L'\u200C', // Zero Width Non-Joiner (ZWNJ)
L'\u200D', // Zero Width Joiner (ZWJ)
L'\u200E', // Left-to-Right Mark (LRM)
L'\u200F', // Right-to-Left Mark (RLM)
L'\u202A', // Left-to-Right Embedding (LRE)
L'\u202B', // Right-to-Left Embedding (RLE)
L'\u202C', // Pop Directional Formatting (PDF)
L'\u202D', // Left-to-Right Override (LRO)
L'\u202E', // Right-to-Left Override (RLO)
L'\u2060', // Word Joiner (WJ)
L'\u2061', // Function Application
L'\u2062', // Invisible Times
L'\u2063', // Invisible Separator
L'\u2064', // Invisible Plus
L'\u2066', // Left-to-Right Isolate (LRI)
L'\u2067', // Right-to-Left Isolate (RLI)
L'\u2068', // First Strong Isolate (FSI)
L'\u2069', // Pop Directional Isolate (PDI)
L'\u206A', // Inhibit Symmetric Swapping
L'\u206B', // Activate Symmetric Swapping
//L'\u206C', // Inhibit Arabic Form Shaping
//L'\u206D', // Activate Arabic Form Shaping
L'\u206E', // National Digit Shapes
L'\u206F', // Nominal Digit Shapes
L'\uFEFF', // Zero Width No-Break Space (BOM, ZWNBSP)
L'\uFFF9', // Interlinear Annotation Anchor
L'\uFFFA', // Interlinear Annotation Separator
L'\uFFFB' // Interlinear Annotation Terminator
};
int i = 0;
while(i < string.GetLength())
{
if(unicodeInvisible.find(string[i]) != unicodeInvisible.end())
{
string.Delete(i, 1);
continue;
}
if(unicodeSpaces.find(string[i]) != unicodeSpaces.end())
{
string.SetAt(i, L' ');
}
i++;
}
}
UINT GetDpiForWindowWithFallback(HWND hWnd)
{
using GetDpiForWindow_t = UINT(WINAPI*)(HWND hwnd);
static GetDpiForWindow_t pGetDpiForWindow = []()
{
HMODULE hUser32 = GetModuleHandle(L"user32.dll");
if(hUser32)
{
return (GetDpiForWindow_t)GetProcAddress(hUser32, "GetDpiForWindow");
}
return (GetDpiForWindow_t)nullptr;
}();
int iDpi = 96;
if(pGetDpiForWindow)
{
iDpi = pGetDpiForWindow(hWnd);
}
else
{
CDC hdc = ::GetDC(NULL);
if(hdc)
{
iDpi = hdc.GetDeviceCaps(LOGPIXELSX);
}
}
return iDpi;
}
int ScaleForWindow(HWND hWnd, int value)
{
return MulDiv(value, GetDpiForWindowWithFallback(hWnd), 96);
}
int GetSystemMetricsForDpiWithFallback(int nIndex, UINT dpi)
{
using GetSystemMetricsForDpi_t = int(WINAPI*)(int nIndex, UINT dpi);
static GetSystemMetricsForDpi_t pGetSystemMetricsForDpi = []()
{
HMODULE hUser32 = GetModuleHandle(L"user32.dll");
if(hUser32)
{
return (GetSystemMetricsForDpi_t)GetProcAddress(hUser32, "GetSystemMetricsForDpi");
}
return (GetSystemMetricsForDpi_t)nullptr;
}();
if(pGetSystemMetricsForDpi)
{
return pGetSystemMetricsForDpi(nIndex, dpi);
}
else
{
return GetSystemMetrics(nIndex);
}
}
int GetSystemMetricsForWindow(HWND hWnd, int nIndex)
{
return GetSystemMetricsForDpiWithFallback(nIndex, GetDpiForWindowWithFallback(hWnd));
}
HICON LoadIconWithScaleDownWithFallback(HINSTANCE hInst, PCWSTR pszName, int cx, int cy)
{
using LoadIconWithScaleDown_t = HRESULT(WINAPI*)(HINSTANCE hinst, PCWSTR pszName, int cx, int cy, HICON* phico);
static LoadIconWithScaleDown_t pLoadIconWithScaleDown = []()
{
HMODULE hComctl32 = GetModuleHandle(L"comctl32.dll");
if(hComctl32)
{
return (LoadIconWithScaleDown_t)GetProcAddress(hComctl32, "LoadIconWithScaleDown");
}
return (LoadIconWithScaleDown_t)nullptr;
}();
if(pLoadIconWithScaleDown)
{
HICON hIcon;
if(SUCCEEDED(pLoadIconWithScaleDown(hInst, pszName, cx, cy, &hIcon)))
{
return hIcon;
}
return nullptr;
}
else
{
return (HICON)LoadImage(hInst, pszName, IMAGE_ICON, cx, cy, LR_DEFAULTCOLOR);
}
}
BOOL AdjustWindowRectExForWindow(HWND hWnd, LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle)
{
using AdjustWindowRectExForDpi_t = BOOL(WINAPI*)(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi);
static AdjustWindowRectExForDpi_t pAdjustWindowRectExForDpi = []()
{
HMODULE hUser32 = GetModuleHandle(L"user32.dll");
if(hUser32)
{
return (AdjustWindowRectExForDpi_t)GetProcAddress(hUser32, "AdjustWindowRectExForDpi");
}
return (AdjustWindowRectExForDpi_t)nullptr;
}();
if(pAdjustWindowRectExForDpi)
{
return pAdjustWindowRectExForDpi(lpRect, dwStyle, bMenu, dwExStyle, GetDpiForWindowWithFallback(hWnd));
}
else
{
return AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle);
}
}
BOOL UnadjustWindowRectExForWindow(HWND hWnd, LPRECT prc, DWORD dwStyle, BOOL fMenu, DWORD dwExStyle)
{
RECT rc;
SetRectEmpty(&rc);
BOOL fRc = AdjustWindowRectExForWindow(hWnd, &rc, dwStyle, fMenu, dwExStyle);
if(fRc)
{
prc->left -= rc.left;
prc->top -= rc.top;
prc->right -= rc.right;
prc->bottom -= rc.bottom;
}
return fRc;
}
BOOL WndAdjustWindowRect(CWindow window, LPRECT prc)
{
DWORD dwStyle = window.GetStyle();
DWORD dwExStyle = window.GetExStyle();
BOOL bMenu = (!(dwStyle & WS_CHILD) && (window.GetMenu() != NULL));
return AdjustWindowRectExForWindow(window, prc, dwStyle, bMenu, dwExStyle);
}
BOOL WndUnadjustWindowRect(CWindow window, LPRECT prc)
{
DWORD dwStyle = window.GetStyle();
DWORD dwExStyle = window.GetExStyle();
BOOL bMenu = (!(dwStyle & WS_CHILD) && (window.GetMenu() != NULL));
return UnadjustWindowRectExForWindow(window, prc, dwStyle, bMenu, dwExStyle);
}
BOOL SetClipboardText(const WCHAR* text)
{
if(!OpenClipboard(NULL))
return FALSE;
BOOL bSucceeded = FALSE;
size_t size = sizeof(WCHAR) * (wcslen(text) + 1);
HANDLE handle = GlobalAlloc(GHND, size);
if(handle)
{
WCHAR* clipboardText = (WCHAR*)GlobalLock(handle);
if(clipboardText)
{
memcpy(clipboardText, text, size);
GlobalUnlock(handle);
bSucceeded = EmptyClipboard() &&
SetClipboardData(CF_UNICODETEXT, handle);
}
if(!bSucceeded)
GlobalFree(handle);
}
CloseClipboard();
return bSucceeded;
}