-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Utils.hpp
321 lines (274 loc) · 10.3 KB
/
Utils.hpp
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
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
//////////////////////////////////////////////////////////////////////////////
// Utils.hpp --- XWord Giver (Japanese Crossword Generator)
// Copyright (C) 2012-2020 Katayama Hirofumi MZ. All Rights Reserved.
// (Japanese, UTF-8)
#pragma once
#include "XWordGiver.hpp"
//////////////////////////////////////////////////////////////////////////////
// デバッグ出力。
#ifdef NDEBUG
#define DebugPrintfW(file, lineno, pszFormat, ...)
#define DOUTW(fmt, ...)
#else
void __cdecl DebugPrintfW(const char *file, int lineno, LPCWSTR pszFormat, ...);
#define DOUTW(fmt, ...) DebugPrintfW(__FILE__, __LINE__, (fmt), ##__VA_ARGS__)
#endif
// リソース文字列を読み込む。
LPWSTR __fastcall XgLoadStringDx1(int id) noexcept;
// リソース文字列を読み込む。
LPWSTR __fastcall XgLoadStringDx2(int id) noexcept;
// フィルター文字列を作る。
LPWSTR __fastcall XgMakeFilterString(LPWSTR psz) noexcept;
// ショートカットのターゲットのパスを取得する。
bool __fastcall XgGetPathOfShortcutW(LPCWSTR pszLnkFile, LPWSTR pszPath);
// 空白文字群。
#define XG_WHITE_SPACES L" \t\r\n\x3000"
// 文字列の前後の空白を取り除く。
static inline void __fastcall xg_str_trim(XGStringW& str)
{
const size_t i = str.find_first_not_of(XG_WHITE_SPACES);
const size_t j = str.find_last_not_of(XG_WHITE_SPACES);
if (i != XGStringW::npos)
str = str.substr(i, j - i + 1);
else
str.clear();
}
// 文字列の右側の空白を取り除く。
static inline void __fastcall xg_str_trim_right(XGStringW& str)
{
const size_t j = str.find_last_not_of(XG_WHITE_SPACES);
if (j != XGStringW::npos)
str = str.substr(0, j + 1);
else
str.clear();
}
// 文字列をエスケープする。
XGStringW xg_str_escape(const XGStringW& str);
// 文字列をアンエスケープする。
XGStringW xg_str_unescape(const XGStringW& str);
// 文字列を引用する。
static inline XGStringW xg_str_quote(const XGStringW& str)
{
XGStringW ret = L"\"";
ret += xg_str_escape(str);
ret += L"\"";
return ret;
}
// 文字列を逆引用する。
static inline XGStringW xg_str_unquote(const XGStringW& str)
{
XGStringW ret;
ret = str;
xg_str_trim(ret);
if (ret.empty())
return L"";
if (ret[0] == L'"')
ret = ret.substr(1);
if (ret.size() && ret[ret.size() - 1] == L'"')
ret = ret.substr(0, ret.size() - 1);
return xg_str_unescape(ret);
}
// 文字列を置換する。
bool __fastcall xg_str_replace_all(XGStringW &s, const XGStringW& from, const XGStringW& to);
// 文字列からマルチセットへ変換する。
void __fastcall xg_str_to_multiset(std::unordered_multiset<WCHAR>& mset, const XGStringW& str);
// ベクターからマルチセットへ変換する。
void __fastcall xg_vec_to_multiset(std::unordered_multiset<WCHAR>& mset, const std::vector<WCHAR>& str);
// 部分マルチセットかどうか?
bool __fastcall xg_submultiseteq(const std::unordered_multiset<WCHAR>& ms1,
const std::unordered_multiset<WCHAR>& ms2);
// UTF-8 -> Unicode.
XGStringW __fastcall XgUtf8ToUnicode(const std::string& ansi);
// ダイアログを中央によせる関数。
void __fastcall XgCenterDialog(HWND hwnd) noexcept;
// 中央寄せメッセージボックスを表示する。
int __fastcall
XgCenterMessageBoxW(HWND hwnd, LPCWSTR pszText, LPCWSTR pszCaption, UINT uType) noexcept;
// 中央寄せメッセージボックスを表示する。
int __fastcall
XgCenterMessageBoxIndirectW(LPMSGBOXPARAMS lpMsgBoxParams) noexcept;
// ファイルが書き込み可能か?
bool __fastcall XgCanWriteFile(const WCHAR *pszFile);
// Unicode -> UTF8
std::string XgUnicodeToUtf8(const XGStringW& wide);
// ANSI -> Unicode
XGStringW XgAnsiToUnicode(const std::string& ansi);
// ANSI -> Unicode
XGStringW XgAnsiToUnicode(const std::string& ansi, INT charset);
// Unicode -> ANSI
std::string XgUnicodeToAnsi(const XGStringW& wide);
// JSON文字列を作る。
XGStringW XgJsonEncodeString(const XGStringW& str);
// 16進で表す。
char XgToHex(char code) noexcept;
// 24BPPビットマップを作成。
HBITMAP XgCreate24BppBitmap(HDC hDC, LONG width, LONG height) noexcept;
// パック形式のDIBを作成する。
BOOL PackedDIB_CreateFromHandle(std::vector<BYTE>& vecData, HBITMAP hbm);
//////////////////////////////////////////////////////////////////////////////
// パスを作る。
BOOL XgMakePathW(LPCWSTR pszPath);
// ローカルファイルを見つける。
BOOL XgFindLocalFile(LPWSTR pszPath, UINT cchPath, LPCWSTR pszFileName);
// ローカルファイルを開く。
inline void XgOpenLocalFile(HWND hwnd, LPCWSTR pszFileName)
{
WCHAR szPath[MAX_PATH];
if (XgFindLocalFile(szPath, _countof(szPath), pszFileName))
ShellExecuteW(hwnd, nullptr, szPath, nullptr, nullptr, SW_SHOWNORMAL);
}
//////////////////////////////////////////////////////////////////////////////
// HTML形式のクリップボードデータを作成する。
std::string XgMakeClipHtmlData(const std::string& html_utf8, const std::string& style_utf8/* = ""*/);
// HTML形式のクリップボードデータを作成する。
std::string XgMakeClipHtmlData(const XGStringW& html_wide, const XGStringW& style_wide/* = L""*/);
//////////////////////////////////////////////////////////////////////////////
template <typename T_STR_CONTAINER>
inline void
mstr_split(T_STR_CONTAINER& container,
const typename T_STR_CONTAINER::value_type& str,
const typename T_STR_CONTAINER::value_type& chars)
{
container.clear();
size_t i = 0, k = str.find_first_of(chars);
while (k != T_STR_CONTAINER::value_type::npos)
{
container.push_back(str.substr(i, k - i));
i = k + 1;
k = str.find_first_of(chars, i);
}
container.push_back(str.substr(i));
}
template <typename T_STR_CONTAINER>
inline void
mstr_split_insert(T_STR_CONTAINER& container,
const typename T_STR_CONTAINER::value_type& str,
const typename T_STR_CONTAINER::value_type& chars)
{
container.clear();
size_t i = 0, k = str.find_first_of(chars);
while (k != T_STR_CONTAINER::value_type::npos)
{
container.insert(str.substr(i, k - i));
i = k + 1;
k = str.find_first_of(chars, i);
}
container.insert(str.substr(i));
}
template <typename T_STRING>
inline void mstr_trim(T_STRING& str, const typename T_STRING::value_type *spaces)
{
const auto i = str.find_first_not_of(spaces);
const auto j = str.find_last_not_of(spaces);
if ((i == str.npos) || (j == str.npos))
{
str.clear();
}
else
{
str = str.substr(i, j - i + 1);
}
}
template <typename T_STR_CONTAINER>
inline typename T_STR_CONTAINER::value_type
mstr_join(const T_STR_CONTAINER& container,
const typename T_STR_CONTAINER::value_type& sep)
{
typename T_STR_CONTAINER::value_type result;
typename T_STR_CONTAINER::const_iterator it, end;
it = container.begin();
end = container.end();
if (it != end)
{
result = *it;
for (++it; it != end; ++it)
{
result += sep;
result += *it;
}
}
return result;
}
// 整数を文字列にする。
LPCWSTR XgIntToStr(int nValue);
// バイナリを16進にする。
XGStringW XgBinToHex(const void *ptr, size_t size);
// 16進をバイナリにする。
void XgHexToBin(std::vector<BYTE>& data, const XGStringW& str);
// 画像を読み込む。
BOOL XgLoadImage(const XGStringW& filename, HBITMAP& hbm, HENHMETAFILE& hEMF);
// 画像ファイルか?
BOOL XgIsImageFile(LPCWSTR pszFileName) noexcept;
// テキストファイルか?
BOOL XgIsTextFile(LPCWSTR pszFileName) noexcept;
// ファイルを読み込む。
BOOL XgReadFileAll(LPCWSTR file, std::string& strBinary);
BOOL XgReadTextFileAll(LPCWSTR file, XGStringW& strText, bool ecw = false);
// ファイルを読み込む。
BOOL XgWriteFileAll(LPCWSTR file, const std::string& strBinary) noexcept;
// エンディアン変換。
void XgSwab(LPBYTE pbFile, size_t cbFile) noexcept;
// コンボボックスからテキストを取得。
BOOL ComboBox_RealGetText(HWND hwndCombo, LPWSTR pszText, int cchText) noexcept;
// コンボボックスにテキストを設定。
BOOL ComboBox_RealSetText(HWND hwndCombo, LPCWSTR pszText) noexcept;
struct XG_FileManager
{
XGStringW m_filename;
XGStringW m_looks;
XGStringW m_block_dir;
std::unordered_map<XGStringW, std::string> m_path2contents;
std::unordered_map<XGStringW, HBITMAP> m_path2hbm;
std::unordered_map<XGStringW, HENHMETAFILE> m_path2hemf;
XG_FileManager() noexcept
{
}
~XG_FileManager() noexcept
{
}
void set_file(LPCWSTR filename);
XGStringW get_looks_file();
void set_looks(LPCWSTR looks);
void delete_handles() noexcept;
bool load_image(LPCWSTR filename);
bool save_image(const XGStringW& path);
bool save_image2(XGStringW& path);
bool save_images();
bool save_images(const std::unordered_set<XGStringW>& files);
void convert();
void clear();
XGStringW get_file_title(const XGStringW& str) const;
XGStringW get_full_path(const XGStringW& str) const;
XGStringW get_block_dir();
XGStringW get_block_dir_worker() const;
bool get_files_dir(XGStringW& dir) const;
XGStringW get_canonical(const XGStringW& path);
XGStringW get_real_path(const XGStringW& path);
bool get_list(std::vector<XGStringW>& paths);
bool load_block_image(const XGStringW& path);
bool load_block_image(const XGStringW& path, HBITMAP& hbm, HENHMETAFILE& hEMF);
void convert(XGStringW& path)
{
if (path.empty())
return;
XGStringW canonical = L"$FILES\\";
canonical += get_file_title(path);
path = std::move(canonical);
}
template <typename T_TYPE>
void convert(std::unordered_map<XGStringW, T_TYPE>& map)
{
std::unordered_map<XGStringW, T_TYPE> new_map;
for (auto& pair : map)
{
if (pair.first.empty())
continue;
XGStringW path = L"$FILES\\";
path += get_file_title(pair.first);
new_map[path] = pair.second;
}
map = std::move(new_map);
}
};
std::shared_ptr<XG_FileManager>& XgGetFileManager(void);
//////////////////////////////////////////////////////////////////////////////