OSDN Git Service

Fix bugs of copying URL to clipboard.
[ffftp/ffftp.git] / mbswrapper.c
1 // mbswrapper.c\r
2 // Copyright (C) 2011 Suguru Kawamoto\r
3 // マルチバイト文字ワイド文字APIラッパー\r
4 // マルチバイト文字はUTF-8、ワイド文字はUTF-16であるものとする\r
5 // 全ての制御用の文字はASCIIの範囲であるため、Shift_JISとUTF-8間の変換は不要\r
6 \r
7 #define UNICODE\r
8 #define _UNICODE\r
9 \r
10 #include <tchar.h>\r
11 #include <direct.h>\r
12 #include <windows.h>\r
13 #include <commctrl.h>\r
14 #include <shlobj.h>\r
15 #include <htmlhelp.h>\r
16 \r
17 #define DO_NOT_REPLACE\r
18 #include "mbswrapper.h"\r
19 \r
20 // マルチバイト文字列からワイド文字列へ変換\r
21 int MtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)\r
22 {\r
23         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
24                 return 0;\r
25         if(pDst)\r
26                 return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, pDst, size);\r
27         return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, NULL, 0);\r
28 }\r
29 \r
30 // ワイド文字列からマルチバイト文字列へ変換\r
31 int WtoM(LPSTR pDst, int size, LPCWSTR pSrc, int count)\r
32 {\r
33         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
34                 return 0;\r
35         if(pDst)\r
36                 return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, pDst, size, NULL, NULL);\r
37         return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, NULL, 0, NULL, NULL);\r
38 }\r
39 \r
40 // Shift_JIS文字列からワイド文字列へ変換\r
41 int AtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)\r
42 {\r
43         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
44                 return 0;\r
45         if(pDst)\r
46                 return MultiByteToWideChar(CP_ACP, 0, pSrc, count, pDst, size);\r
47         return MultiByteToWideChar(CP_ACP, 0, pSrc, count, NULL, 0);\r
48 }\r
49 \r
50 // ワイド文字列からShift_JIS文字列へ変換\r
51 int WtoA(LPSTR pDst, int size, LPCWSTR pSrc, int count)\r
52 {\r
53         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
54                 return 0;\r
55         if(pDst)\r
56                 return WideCharToMultiByte(CP_ACP, 0, pSrc, count, pDst, size, NULL, NULL);\r
57         return WideCharToMultiByte(CP_ACP, 0, pSrc, count, NULL, 0, NULL, NULL);\r
58 }\r
59 \r
60 // マルチバイト文字列バッファ終端を強制的にNULLで置換\r
61 int TerminateStringM(LPSTR lpString, int size)\r
62 {\r
63         int i;\r
64         if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)\r
65                 return 0;\r
66         for(i = 0; i < size; i++)\r
67         {\r
68                 if(lpString[i] == '\0')\r
69                         return i;\r
70         }\r
71         i--;\r
72         lpString[i] = '\0';\r
73         return i;\r
74 }\r
75 \r
76 // ワイド文字列バッファ終端を強制的にNULLで置換\r
77 int TerminateStringW(LPWSTR lpString, int size)\r
78 {\r
79         int i;\r
80         if(lpString < (LPWSTR)0x00010000 || lpString == (LPWSTR)~0)\r
81                 return 0;\r
82         for(i = 0; i < size; i++)\r
83         {\r
84                 if(lpString[i] == L'\0')\r
85                         return i;\r
86         }\r
87         i--;\r
88         lpString[i] = L'\0';\r
89         return i;\r
90 }\r
91 \r
92 // Shift_JIS文字列バッファ終端を強制的にNULLで置換\r
93 int TerminateStringA(LPSTR lpString, int size)\r
94 {\r
95         int i;\r
96         if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)\r
97                 return 0;\r
98         for(i = 0; i < size; i++)\r
99         {\r
100                 if(lpString[i] == '\0')\r
101                         return i;\r
102         }\r
103         i--;\r
104         lpString[i] = '\0';\r
105         return i;\r
106 }\r
107 \r
108 // NULL区切り複数マルチバイト文字列の長さを取得\r
109 size_t GetMultiStringLengthM(LPCSTR lpString)\r
110 {\r
111         size_t i;\r
112         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
113                 return 0;\r
114         i = 0;\r
115         while(lpString[i] != '\0' || lpString[i + 1] != '\0')\r
116         {\r
117                 i++;\r
118         }\r
119         i++;\r
120         return i;\r
121 }\r
122 \r
123 // NULL区切り複数ワイド文字列の長さを取得\r
124 size_t GetMultiStringLengthW(LPCWSTR lpString)\r
125 {\r
126         size_t i;\r
127         if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
128                 return 0;\r
129         i = 0;\r
130         while(lpString[i] != L'\0' || lpString[i + 1] != L'\0')\r
131         {\r
132                 i++;\r
133         }\r
134         i++;\r
135         return i;\r
136 }\r
137 \r
138 // NULL区切り複数Shift_JIS文字列の長さを取得\r
139 size_t GetMultiStringLengthA(LPCSTR lpString)\r
140 {\r
141         size_t i;\r
142         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
143                 return 0;\r
144         i = 0;\r
145         while(lpString[i] != '\0' || lpString[i + 1] != '\0')\r
146         {\r
147                 i++;\r
148         }\r
149         i++;\r
150         return i;\r
151 }\r
152 \r
153 // NULL区切りマルチバイト文字列からワイド文字列へ変換\r
154 int MtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)\r
155 {\r
156         int i;\r
157         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
158                 return 0;\r
159         if(!pDst)\r
160                 return GetMultiStringLengthM(pSrc);\r
161         i = 0;\r
162         while(*pSrc != '\0')\r
163         {\r
164                 i += MultiByteToWideChar(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1);\r
165                 pSrc += strlen(pSrc) + 1;\r
166         }\r
167         pDst[i] = L'\0';\r
168         return i;\r
169 }\r
170 \r
171 // NULL区切りワイド文字列からマルチバイト文字列へ変換\r
172 int WtoMMultiString(LPSTR pDst, int size, LPCWSTR pSrc)\r
173 {\r
174         int i;\r
175         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
176                 return 0;\r
177         if(!pDst)\r
178                 return GetMultiStringLengthW(pSrc);\r
179         i = 0;\r
180         while(*pSrc != L'\0')\r
181         {\r
182                 i += WideCharToMultiByte(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);\r
183                 pSrc += wcslen(pSrc) + 1;\r
184         }\r
185         pDst[i] = '\0';\r
186         return i;\r
187 }\r
188 \r
189 // NULL区切りShift_JIS文字列からワイド文字列へ変換\r
190 int AtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)\r
191 {\r
192         int i;\r
193         if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
194                 return 0;\r
195         if(!pDst)\r
196                 return GetMultiStringLengthA(pSrc);\r
197         i = 0;\r
198         while(*pSrc != '\0')\r
199         {\r
200                 i += MultiByteToWideChar(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1);\r
201                 pSrc += strlen(pSrc) + 1;\r
202         }\r
203         pDst[i] = L'\0';\r
204         return i;\r
205 }\r
206 \r
207 // NULL区切りワイド文字列からShift_JIS文字列へ変換\r
208 int WtoAMultiString(LPSTR pDst, int size, LPCWSTR pSrc)\r
209 {\r
210         int i;\r
211         if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
212                 return 0;\r
213         if(!pDst)\r
214                 return GetMultiStringLengthW(pSrc);\r
215         i = 0;\r
216         while(*pSrc != L'\0')\r
217         {\r
218                 i += WideCharToMultiByte(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);\r
219                 pSrc += wcslen(pSrc) + 1;\r
220         }\r
221         pDst[i] = '\0';\r
222         return i;\r
223 }\r
224 \r
225 // マルチバイト文字列用のメモリを確保\r
226 char* AllocateStringM(int size)\r
227 {\r
228         char* p;\r
229         // 0が指定される場合があるため1文字分追加\r
230         p = (char*)malloc(sizeof(char) * (size + 1));\r
231         // 念のため先頭にNULL文字を代入\r
232         if(p)\r
233                 *p = '\0';\r
234         return p;\r
235 }\r
236 \r
237 // ワイド文字列用のメモリを確保\r
238 wchar_t* AllocateStringW(int size)\r
239 {\r
240         wchar_t* p;\r
241         // 0が指定される場合があるため1文字分追加\r
242         p = (wchar_t*)malloc(sizeof(wchar_t) * (size + 1));\r
243         // 念のため先頭にNULL文字を代入\r
244         if(p)\r
245                 *p = L'\0';\r
246         return p;\r
247 }\r
248 \r
249 // Shift_JIS文字列用のメモリを確保\r
250 char* AllocateStringA(int size)\r
251 {\r
252         char* p;\r
253         // 0が指定される場合があるため1文字分追加\r
254         p = (char*)malloc(sizeof(char) * (size + 1));\r
255         // 念のため先頭にNULL文字を代入\r
256         if(p)\r
257                 *p = '\0';\r
258         return p;\r
259 }\r
260 \r
261 // メモリを確保してマルチバイト文字列からワイド文字列へ変換\r
262 // リソースIDならば元の値を返す\r
263 wchar_t* DuplicateMtoW(LPCSTR lpString, int c)\r
264 {\r
265         wchar_t* p;\r
266         int i;\r
267         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
268                 return (wchar_t*)lpString;\r
269         if(c < 0)\r
270                 c = strlen(lpString);\r
271         p = AllocateStringW(MtoW(NULL, 0, lpString, c) + 1);\r
272         if(p)\r
273         {\r
274                 i = MtoW(p, 65535, lpString, c);\r
275                 p[i] = L'\0';\r
276         }\r
277         return p;\r
278 }\r
279 \r
280 // 指定したサイズのメモリを確保してマルチバイト文字列からワイド文字列へ変換\r
281 // リソースIDならば元の値を返す\r
282 wchar_t* DuplicateMtoWBuffer(LPCSTR lpString, int c, int size)\r
283 {\r
284         wchar_t* p;\r
285         int i;\r
286         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
287                 return (wchar_t*)lpString;\r
288         if(c < 0)\r
289                 c = strlen(lpString);\r
290         p = AllocateStringW(size);\r
291         if(p)\r
292         {\r
293                 i = MtoW(p, size, lpString, c);\r
294                 p[i] = L'\0';\r
295         }\r
296         return p;\r
297 }\r
298 \r
299 // メモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換\r
300 // リソースIDならば元の値を返す\r
301 wchar_t* DuplicateMtoWMultiString(LPCSTR lpString)\r
302 {\r
303         int count;\r
304         wchar_t* p;\r
305         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
306                 return (wchar_t*)lpString;\r
307         count = GetMultiStringLengthM(lpString) + 1;\r
308         p = AllocateStringW(count);\r
309         if(p)\r
310                 MtoW(p, count, lpString, count);\r
311         return p;\r
312 }\r
313 \r
314 // 指定したサイズのメモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換\r
315 // リソースIDならば元の値を返す\r
316 wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size)\r
317 {\r
318         int count;\r
319         wchar_t* p;\r
320         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
321                 return (wchar_t*)lpString;\r
322         count = GetMultiStringLengthM(lpString) + 1;\r
323         p = AllocateStringW(size);\r
324         if(p)\r
325         {\r
326                 MtoW(p, size, lpString, count);\r
327                 p[size - 2] = L'\0';\r
328                 p[size - 1] = L'\0';\r
329         }\r
330         return p;\r
331 }\r
332 \r
333 // メモリを確保してワイド文字列からマルチバイト文字列へ変換\r
334 // リソースIDならば元の値を返す\r
335 char* DuplicateWtoM(LPCWSTR lpString, int c)\r
336 {\r
337         char* p;\r
338         int i;\r
339         if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
340                 return (char*)lpString;\r
341         if(c < 0)\r
342                 c = wcslen(lpString);\r
343         p = AllocateStringM(WtoM(NULL, 0, lpString, c) + 1);\r
344         if(p)\r
345         {\r
346                 i = WtoM(p, 65535, lpString, c);\r
347                 p[i] = L'\0';\r
348         }\r
349         return p;\r
350 }\r
351 \r
352 // メモリを確保してShift_JIS文字列からワイド文字列へ変換\r
353 // リソースIDならば元の値を返す\r
354 wchar_t* DuplicateAtoW(LPCSTR lpString, int c)\r
355 {\r
356         wchar_t* p;\r
357         int i;\r
358         if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
359                 return (wchar_t*)lpString;\r
360         if(c < 0)\r
361                 c = strlen(lpString);\r
362         p = AllocateStringW(AtoW(NULL, 0, lpString, c) + 1);\r
363         if(p)\r
364         {\r
365                 i = AtoW(p, 65535, lpString, c);\r
366                 p[i] = L'\0';\r
367         }\r
368         return p;\r
369 }\r
370 \r
371 // メモリを確保してワイド文字列からShift_JIS文字列へ変換\r
372 // リソースIDならば元の値を返す\r
373 char* DuplicateWtoA(LPCWSTR lpString, int c)\r
374 {\r
375         char* p;\r
376         int i;\r
377         if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
378                 return (char*)lpString;\r
379         if(c < 0)\r
380                 c = wcslen(lpString);\r
381         p = AllocateStringA(WtoA(NULL, 0, lpString, c) + 1);\r
382         if(p)\r
383         {\r
384                 i = WtoA(p, 65535, lpString, c);\r
385                 p[i] = L'\0';\r
386         }\r
387         return p;\r
388 }\r
389 \r
390 // 文字列用に確保したメモリを開放\r
391 // リソースIDならば何もしない\r
392 void FreeDuplicatedString(void* p)\r
393 {\r
394         if(p < (void*)0x00010000 || p == (void*)~0)\r
395                 return;\r
396         free(p);\r
397 }\r
398 \r
399 // 以下ラッパー\r
400 // 戻り値バッファ r\r
401 // ワイド文字バッファ pw%d\r
402 // マルチバイト文字バッファ pm%d\r
403 // 引数バッファ a%d\r
404 \r
405 #pragma warning(disable:4102)\r
406 #define START_ROUTINE                                   do{\r
407 #define END_ROUTINE                                             }while(0);end_of_routine:\r
408 #define QUIT_ROUTINE                                    goto end_of_routine;\r
409 \r
410 int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)\r
411 {\r
412         int r = 0;\r
413         char* pm0 = NULL;\r
414 START_ROUTINE\r
415         pm0 = DuplicateWtoM(lpCmdLine, -1);\r
416         r = WinMainM(hInstance, hPrevInstance, pm0, nCmdShow);\r
417 END_ROUTINE\r
418         FreeDuplicatedString(pm0);\r
419         return r;\r
420 }\r
421 \r
422 HMODULE LoadLibraryM(LPCSTR lpLibFileName)\r
423 {\r
424         HMODULE r = NULL;\r
425         wchar_t* pw0 = NULL;\r
426 START_ROUTINE\r
427         pw0 = DuplicateMtoW(lpLibFileName, -1);\r
428         r = LoadLibraryW(pw0);\r
429 END_ROUTINE\r
430         FreeDuplicatedString(pw0);\r
431         return r;\r
432 }\r
433 \r
434 HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)\r
435 {\r
436         HANDLE r = INVALID_HANDLE_VALUE;\r
437         wchar_t* pw0 = NULL;\r
438 START_ROUTINE\r
439         pw0 = DuplicateMtoW(lpFileName, -1);\r
440         r = CreateFileW(pw0, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);\r
441 END_ROUTINE\r
442         FreeDuplicatedString(pw0);\r
443         return r;\r
444 }\r
445 \r
446 int MessageBoxM(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)\r
447 {\r
448         int r = IDOK;\r
449         wchar_t* pw0 = NULL;\r
450         wchar_t* pw1 = NULL;\r
451 START_ROUTINE\r
452         pw0 = DuplicateMtoW(lpText, -1);\r
453         pw1 = DuplicateMtoW(lpCaption, -1);\r
454         r = MessageBoxW(hWnd, pw0, pw1, uType);\r
455 END_ROUTINE\r
456         FreeDuplicatedString(pw0);\r
457         FreeDuplicatedString(pw1);\r
458         return r;\r
459 }\r
460 \r
461 HANDLE FindFirstFileM(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)\r
462 {\r
463         HANDLE r = INVALID_HANDLE_VALUE;\r
464         wchar_t* pw0 = NULL;\r
465         WIN32_FIND_DATAW a0;\r
466 START_ROUTINE\r
467         pw0 = DuplicateMtoW(lpFileName, -1);\r
468         r = FindFirstFileW(pw0, &a0);\r
469         if(r != INVALID_HANDLE_VALUE)\r
470         {\r
471                 lpFindFileData->dwFileAttributes = a0.dwFileAttributes;\r
472                 lpFindFileData->ftCreationTime = a0.ftCreationTime;\r
473                 lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;\r
474                 lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;\r
475                 lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;\r
476                 lpFindFileData->nFileSizeLow = a0.nFileSizeLow;\r
477                 lpFindFileData->dwReserved0 = a0.dwReserved0;\r
478                 lpFindFileData->dwReserved1 = a0.dwReserved1;\r
479                 WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);\r
480                 WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);\r
481         }\r
482 END_ROUTINE\r
483         FreeDuplicatedString(pw0);\r
484         return r;\r
485 }\r
486 \r
487 BOOL FindNextFileM(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)\r
488 {\r
489         BOOL r = FALSE;\r
490         WIN32_FIND_DATAW a0;\r
491 START_ROUTINE\r
492         r = FindNextFileW(hFindFile, &a0);\r
493         if(r)\r
494         {\r
495                 lpFindFileData->dwFileAttributes = a0.dwFileAttributes;\r
496                 lpFindFileData->ftCreationTime = a0.ftCreationTime;\r
497                 lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;\r
498                 lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;\r
499                 lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;\r
500                 lpFindFileData->nFileSizeLow = a0.nFileSizeLow;\r
501                 lpFindFileData->dwReserved0 = a0.dwReserved0;\r
502                 lpFindFileData->dwReserved1 = a0.dwReserved1;\r
503                 WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);\r
504                 WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);\r
505         }\r
506 END_ROUTINE\r
507         return r;\r
508 }\r
509 \r
510 DWORD GetLogicalDriveStringsM(DWORD nBufferLength, LPSTR lpBuffer)\r
511 {\r
512         DWORD r = 0;\r
513         wchar_t* pw0 = NULL;\r
514 START_ROUTINE\r
515         pw0 = AllocateStringW(nBufferLength * 4);\r
516         GetLogicalDriveStringsW(nBufferLength * 4, pw0);\r
517         WtoMMultiString(lpBuffer, nBufferLength, pw0);\r
518         r = TerminateStringM(lpBuffer, nBufferLength);\r
519 END_ROUTINE\r
520         FreeDuplicatedString(pw0);\r
521         return r;\r
522 }\r
523 \r
524 ATOM RegisterClassExM(CONST WNDCLASSEXA * v0)\r
525 {\r
526         ATOM r = 0;\r
527 START_ROUTINE\r
528         // WNDPROCがShift_JIS用であるため\r
529         r = RegisterClassExA(v0);\r
530 END_ROUTINE\r
531         return r;\r
532 }\r
533 \r
534 HWND CreateWindowExM(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)\r
535 {\r
536         HWND r = NULL;\r
537         wchar_t* pw0 = NULL;\r
538         wchar_t* pw1 = NULL;\r
539 START_ROUTINE\r
540         pw0 = DuplicateMtoW(lpClassName, -1);\r
541         pw1 = DuplicateMtoW(lpWindowName, -1);\r
542         r = CreateWindowExW(dwExStyle, pw0, pw1, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);\r
543 END_ROUTINE\r
544         FreeDuplicatedString(pw0);\r
545         FreeDuplicatedString(pw1);\r
546         return r;\r
547 }\r
548 \r
549 LONG GetWindowLongM(HWND hWnd, int nIndex)\r
550 {\r
551         LRESULT r = 0;\r
552 START_ROUTINE\r
553         // WNDPROCがShift_JIS用であるため\r
554         if(IsWindowUnicode(hWnd))\r
555                 r = GetWindowLongW(hWnd, nIndex);\r
556         else\r
557                 r = GetWindowLongA(hWnd, nIndex);\r
558 END_ROUTINE\r
559         return r;\r
560 }\r
561 \r
562 LONG SetWindowLongM(HWND hWnd, int nIndex, LONG dwNewLong)\r
563 {\r
564         LRESULT r = 0;\r
565 START_ROUTINE\r
566         // WNDPROCがShift_JIS用であるため\r
567         if(IsWindowUnicode(hWnd))\r
568                 r = SetWindowLongW(hWnd, nIndex, dwNewLong);\r
569         else\r
570                 r = SetWindowLongA(hWnd, nIndex, dwNewLong);\r
571 END_ROUTINE\r
572         return r;\r
573 }\r
574 \r
575 LRESULT DefWindowProcM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
576 {\r
577         LRESULT r = 0;\r
578 START_ROUTINE\r
579         // WNDPROCがShift_JIS用であるため\r
580         if(IsWindowUnicode(hWnd))\r
581                 r = DefWindowProcW(hWnd, Msg, wParam, lParam);\r
582         else\r
583                 r = DefWindowProcA(hWnd, Msg, wParam, lParam);\r
584 END_ROUTINE\r
585         return r;\r
586 }\r
587 \r
588 LRESULT CallWindowProcM(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
589 {\r
590         LRESULT r = 0;\r
591 START_ROUTINE\r
592         // WNDPROCがShift_JIS用であるため\r
593         if(IsWindowUnicode(hWnd))\r
594                 r = CallWindowProcW(lpPrevWndFunc, hWnd, Msg, wParam, lParam);\r
595         else\r
596                 r = CallWindowProcA(lpPrevWndFunc, hWnd, Msg, wParam, lParam);\r
597 END_ROUTINE\r
598         return r;\r
599 }\r
600 \r
601 LRESULT SendMessageM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
602 {\r
603         LRESULT r = 0;\r
604         wchar_t* pw0 = NULL;\r
605         wchar_t* pw1 = NULL;\r
606         int Size;\r
607         LVITEMA* pmLVItem;\r
608         LVITEMW wLVItem;\r
609         LVFINDINFOA* pmLVFindInfo;\r
610         LVFINDINFOW wLVFindInfo;\r
611         LVCOLUMNA* pmLVColumn;\r
612         LVCOLUMNW wLVColumn;\r
613         TVITEMEXA* pmTVItem;\r
614         TVITEMEXW wTVItem;\r
615         TVINSERTSTRUCTA* pmTVInsert;\r
616         TVINSERTSTRUCTW wTVInsert;\r
617         wchar_t ClassName[MAX_PATH];\r
618 START_ROUTINE\r
619         switch(Msg)\r
620         {\r
621         case WM_SETTEXT:\r
622                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
623                 r = SendMessageW(hWnd, WM_SETTEXT, wParam, (LPARAM)pw0);\r
624                 break;\r
625         case WM_GETTEXT:\r
626                 pw0 = AllocateStringW(wParam * 4);\r
627                 SendMessageW(hWnd, WM_GETTEXT, wParam * 4, (LPARAM)pw0);\r
628                 WtoM((LPSTR)lParam, wParam, pw0, -1);\r
629                 r = TerminateStringM((LPSTR)lParam, wParam);\r
630                 break;\r
631         case WM_GETTEXTLENGTH:\r
632                 Size = SendMessageW(hWnd, WM_GETTEXTLENGTH, wParam, lParam) + 1;\r
633                 pw0 = AllocateStringW(Size);\r
634                 SendMessageW(hWnd, WM_GETTEXT, (WPARAM)Size, (LPARAM)pw0);\r
635                 r = WtoM(NULL, 0, pw0, -1) - 1;\r
636                 break;\r
637         default:\r
638                 GetClassNameW(hWnd, ClassName, sizeof(ClassName) / sizeof(wchar_t));\r
639                 if(_wcsicmp(ClassName, WC_EDITW) == 0)\r
640                 {\r
641                         switch(Msg)\r
642                         {\r
643                         case EM_REPLACESEL:\r
644                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
645                                 r = SendMessageW(hWnd, EM_REPLACESEL, wParam, (LPARAM)pw0);\r
646                                 break;\r
647                         default:\r
648                                 r = SendMessageW(hWnd, Msg, wParam, lParam);\r
649                                 break;\r
650                         }\r
651                 }\r
652                 else if(_wcsicmp(ClassName, WC_COMBOBOXW) == 0)\r
653                 {\r
654                         switch(Msg)\r
655                         {\r
656                         case CB_ADDSTRING:\r
657                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
658                                 r = SendMessageW(hWnd, CB_ADDSTRING, wParam, (LPARAM)pw0);\r
659                                 break;\r
660                         case CB_GETLBTEXT:\r
661                                 Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1;\r
662                                 pw0 = AllocateStringW(Size);\r
663                                 SendMessageW(hWnd, CB_GETLBTEXT, wParam, (LPARAM)pw0);\r
664                                 // バッファ長不明のためオーバーランの可能性あり\r
665                                 WtoM((LPSTR)lParam, Size * 4, pw0, -1);\r
666                                 r = TerminateStringM((LPSTR)lParam, Size * 4);\r
667                                 break;\r
668                         case CB_GETLBTEXTLEN:\r
669                                 Size = SendMessageW(hWnd, CB_GETLBTEXTLEN, wParam, 0) + 1;\r
670                                 pw0 = AllocateStringW(Size);\r
671                                 SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0);\r
672                                 r = WtoM(NULL, 0, pw0, -1) - 1;\r
673                                 break;\r
674                         case CB_INSERTSTRING:\r
675                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
676                                 r = SendMessageW(hWnd, CB_INSERTSTRING, wParam, (LPARAM)pw0);\r
677                                 break;\r
678                         case CB_FINDSTRINGEXACT:\r
679                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
680                                 r = SendMessageW(hWnd, CB_FINDSTRINGEXACT, wParam, (LPARAM)pw0);\r
681                                 break;\r
682                         default:\r
683                                 r = SendMessageW(hWnd, Msg, wParam, lParam);\r
684                                 break;\r
685                         }\r
686                 }\r
687                 else if(_wcsicmp(ClassName, WC_LISTBOXW) == 0)\r
688                 {\r
689                         switch(Msg)\r
690                         {\r
691                         case LB_ADDSTRING:\r
692                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
693                                 r = SendMessageW(hWnd, LB_ADDSTRING, wParam, (LPARAM)pw0);\r
694                                 break;\r
695                         case LB_INSERTSTRING:\r
696                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
697                                 r = SendMessageW(hWnd, LB_INSERTSTRING, wParam, (LPARAM)pw0);\r
698                                 break;\r
699                         case LB_GETTEXT:\r
700                                 Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1;\r
701                                 pw0 = AllocateStringW(Size);\r
702                                 SendMessageW(hWnd, LB_GETTEXT, wParam, (LPARAM)pw0);\r
703                                 // バッファ長不明のためオーバーランの可能性あり\r
704                                 WtoM((LPSTR)lParam, Size * 4, pw0, -1);\r
705                                 r = TerminateStringM((LPSTR)lParam, Size * 4);\r
706                                 break;\r
707                         case LB_GETTEXTLEN:\r
708                                 Size = SendMessageW(hWnd, LB_GETTEXTLEN, wParam, 0) + 1;\r
709                                 pw0 = AllocateStringW(Size);\r
710                                 SendMessageW(hWnd, WM_GETTEXT, wParam, (LPARAM)pw0);\r
711                                 r = WtoM(NULL, 0, pw0, -1) - 1;\r
712                                 break;\r
713                         default:\r
714                                 r = SendMessageW(hWnd, Msg, wParam, lParam);\r
715                                 break;\r
716                         }\r
717                 }\r
718                 else if(_wcsicmp(ClassName, WC_LISTVIEWW) == 0)\r
719                 {\r
720                         switch(Msg)\r
721                         {\r
722                         case LVM_GETITEMA:\r
723                                 pmLVItem = (LVITEMA*)lParam;\r
724                                 wLVItem.mask = pmLVItem->mask;\r
725                                 wLVItem.iItem = pmLVItem->iItem;\r
726                                 wLVItem.iSubItem = pmLVItem->iSubItem;\r
727                                 wLVItem.state = pmLVItem->state;\r
728                                 wLVItem.stateMask = pmLVItem->stateMask;\r
729                                 if(pmLVItem->mask & LVIF_TEXT)\r
730                                 {\r
731                                         Size = pmLVItem->cchTextMax * 4;\r
732                                         pw0 = AllocateStringW(Size);\r
733                                         wLVItem.pszText = pw0;\r
734                                         wLVItem.cchTextMax = Size;\r
735                                 }\r
736                                 wLVItem.iImage = pmLVItem->iImage;\r
737                                 wLVItem.lParam = pmLVItem->lParam;\r
738                                 wLVItem.iIndent = pmLVItem->iIndent;\r
739                                 r = SendMessageW(hWnd, LVM_GETITEMW, wParam, (LPARAM)&wLVItem);\r
740                                 pmLVItem->mask = wLVItem.mask;\r
741                                 pmLVItem->iItem = wLVItem.iItem;\r
742                                 pmLVItem->iSubItem = wLVItem.iSubItem;\r
743                                 pmLVItem->state = wLVItem.state;\r
744                                 pmLVItem->stateMask = wLVItem.stateMask;\r
745                                 if(pmLVItem->mask & LVIF_TEXT)\r
746                                 {\r
747                                         WtoM(pmLVItem->pszText, pmLVItem->cchTextMax, wLVItem.pszText, -1);\r
748                                         TerminateStringM(pmLVItem->pszText, pmLVItem->cchTextMax);\r
749                                 }\r
750                                 pmLVItem->iImage = wLVItem.iImage;\r
751                                 pmLVItem->lParam = wLVItem.lParam;\r
752                                 pmLVItem->iIndent = wLVItem.iIndent;\r
753                                 break;\r
754                         case LVM_SETITEMA:\r
755                                 pmLVItem = (LVITEMA*)lParam;\r
756                                 wLVItem.mask = pmLVItem->mask;\r
757                                 wLVItem.iItem = pmLVItem->iItem;\r
758                                 wLVItem.iSubItem = pmLVItem->iSubItem;\r
759                                 wLVItem.state = pmLVItem->state;\r
760                                 wLVItem.stateMask = pmLVItem->stateMask;\r
761                                 if(pmLVItem->mask & LVIF_TEXT)\r
762                                 {\r
763                                         pw0 = DuplicateMtoW(pmLVItem->pszText, -1);\r
764                                         wLVItem.pszText = pw0;\r
765                                         // TODO: cchTextMaxの確認\r
766                                         wLVItem.cchTextMax = pmLVItem->cchTextMax;\r
767                                 }\r
768                                 wLVItem.iImage = pmLVItem->iImage;\r
769                                 wLVItem.lParam = pmLVItem->lParam;\r
770                                 wLVItem.iIndent = pmLVItem->iIndent;\r
771                                 r = SendMessageW(hWnd, LVM_SETITEMW, wParam, (LPARAM)&wLVItem);\r
772                                 break;\r
773                         case LVM_INSERTITEMA:\r
774                                 pmLVItem = (LVITEMA*)lParam;\r
775                                 wLVItem.mask = pmLVItem->mask;\r
776                                 wLVItem.iItem = pmLVItem->iItem;\r
777                                 wLVItem.iSubItem = pmLVItem->iSubItem;\r
778                                 wLVItem.state = pmLVItem->state;\r
779                                 wLVItem.stateMask = pmLVItem->stateMask;\r
780                                 if(pmLVItem->mask & LVIF_TEXT)\r
781                                 {\r
782                                         pw0 = DuplicateMtoW(pmLVItem->pszText, -1);\r
783                                         wLVItem.pszText = pw0;\r
784                                         // TODO: cchTextMaxの確認\r
785                                         wLVItem.cchTextMax = pmLVItem->cchTextMax;\r
786                                 }\r
787                                 wLVItem.iImage = pmLVItem->iImage;\r
788                                 wLVItem.lParam = pmLVItem->lParam;\r
789                                 wLVItem.iIndent = pmLVItem->iIndent;\r
790                                 r = SendMessageW(hWnd, LVM_INSERTITEMW, wParam, (LPARAM)&wLVItem);\r
791                                 break;\r
792                         case LVM_FINDITEMA:\r
793                                 pmLVFindInfo = (LVFINDINFOA*)lParam;\r
794                                 wLVFindInfo.flags = pmLVFindInfo->flags;\r
795                                 if(pmLVFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL))\r
796                                 {\r
797                                         pw0 = DuplicateMtoW(pmLVFindInfo->psz, -1);\r
798                                         wLVFindInfo.psz = pw0;\r
799                                 }\r
800                                 wLVFindInfo.lParam = pmLVFindInfo->lParam;\r
801                                 wLVFindInfo.pt = pmLVFindInfo->pt;\r
802                                 wLVFindInfo.vkDirection = pmLVFindInfo->vkDirection;\r
803                                 r = SendMessageW(hWnd, LVM_FINDITEMW, wParam, (LPARAM)&wLVItem);\r
804                                 break;\r
805                         case LVM_GETCOLUMNA:\r
806                                 pmLVColumn = (LVCOLUMNA*)lParam;\r
807                                 wLVColumn.mask = pmLVColumn->mask;\r
808                                 wLVColumn.fmt = pmLVColumn->fmt;\r
809                                 wLVColumn.cx = pmLVColumn->cx;\r
810                                 Size = pmLVColumn->cchTextMax * 4;\r
811                                 if(pmLVColumn->mask & LVCF_TEXT)\r
812                                 {\r
813                                         pw0 = AllocateStringW(Size);\r
814                                         wLVColumn.pszText = pw0;\r
815                                         wLVColumn.cchTextMax = Size;\r
816                                 }\r
817                                 wLVColumn.iSubItem = pmLVColumn->iSubItem;\r
818                                 wLVColumn.iImage = pmLVColumn->iImage;\r
819                                 wLVColumn.iOrder = pmLVColumn->iOrder;\r
820                                 r = SendMessageW(hWnd, LVM_GETCOLUMNW, wParam, (LPARAM)&wLVColumn);\r
821                                 pmLVColumn->mask = wLVColumn.mask;\r
822                                 pmLVColumn->fmt = wLVColumn.fmt;\r
823                                 pmLVColumn->cx = wLVColumn.cx;\r
824                                 if(pmLVColumn->mask & LVCF_TEXT)\r
825                                 {\r
826                                         WtoM(pmLVColumn->pszText, pmLVColumn->cchTextMax, wLVColumn.pszText, -1);\r
827                                         TerminateStringM(pmLVColumn->pszText, pmLVColumn->cchTextMax);\r
828                                 }\r
829                                 pmLVColumn->iSubItem = wLVColumn.iSubItem;\r
830                                 pmLVColumn->iImage = wLVColumn.iImage;\r
831                                 pmLVColumn->iOrder = wLVColumn.iOrder;\r
832                                 break;\r
833                         case LVM_INSERTCOLUMNA:\r
834                                 pmLVColumn = (LVCOLUMNA*)lParam;\r
835                                 wLVColumn.mask = pmLVColumn->mask;\r
836                                 wLVColumn.fmt = pmLVColumn->fmt;\r
837                                 wLVColumn.cx = pmLVColumn->cx;\r
838                                 if(pmLVColumn->mask & LVCF_TEXT)\r
839                                 {\r
840                                         pw0 = DuplicateMtoW(pmLVColumn->pszText, -1);\r
841                                         wLVColumn.pszText = pw0;\r
842                                         // TODO: cchTextMaxの確認\r
843                                         wLVColumn.cchTextMax = pmLVColumn->cchTextMax;\r
844                                 }\r
845                                 wLVColumn.iSubItem = pmLVColumn->iSubItem;\r
846                                 wLVColumn.iImage = pmLVColumn->iImage;\r
847                                 wLVColumn.iOrder = pmLVColumn->iOrder;\r
848                                 r = SendMessageW(hWnd, LVM_INSERTCOLUMNW, wParam, (LPARAM)&wLVColumn);\r
849                                 break;\r
850                         case LVM_GETITEMTEXTA:\r
851                                 pmLVItem = (LVITEMA*)lParam;\r
852                                 wLVItem.mask = pmLVItem->mask;\r
853                                 wLVItem.iItem = pmLVItem->iItem;\r
854                                 wLVItem.iSubItem = pmLVItem->iSubItem;\r
855                                 wLVItem.state = pmLVItem->state;\r
856                                 wLVItem.stateMask = pmLVItem->stateMask;\r
857                                 Size = pmLVItem->cchTextMax * 4;\r
858                                 pw0 = AllocateStringW(Size);\r
859                                 wLVItem.pszText = pw0;\r
860                                 wLVItem.cchTextMax = Size;\r
861                                 wLVItem.iImage = pmLVItem->iImage;\r
862                                 wLVItem.lParam = pmLVItem->lParam;\r
863                                 wLVItem.iIndent = pmLVItem->iIndent;\r
864                                 r = SendMessageW(hWnd, LVM_GETITEMTEXTW, wParam, (LPARAM)&wLVItem);\r
865                                 pmLVItem->mask = wLVItem.mask;\r
866                                 pmLVItem->iItem = wLVItem.iItem;\r
867                                 pmLVItem->iSubItem = wLVItem.iSubItem;\r
868                                 pmLVItem->state = wLVItem.state;\r
869                                 pmLVItem->stateMask = wLVItem.stateMask;\r
870                                 WtoM(pmLVItem->pszText, pmLVItem->cchTextMax, wLVItem.pszText, -1);\r
871                                 TerminateStringM(pmLVItem->pszText, pmLVItem->cchTextMax);\r
872                                 pmLVItem->iImage = wLVItem.iImage;\r
873                                 pmLVItem->lParam = wLVItem.lParam;\r
874                                 pmLVItem->iIndent = wLVItem.iIndent;\r
875                                 break;\r
876                         default:\r
877                                 r = SendMessageW(hWnd, Msg, wParam, lParam);\r
878                                 break;\r
879                         }\r
880                 }\r
881                 else if(_wcsicmp(ClassName, STATUSCLASSNAMEW) == 0)\r
882                 {\r
883                         switch(Msg)\r
884                         {\r
885                         case SB_SETTEXTA:\r
886                                 pw0 = DuplicateMtoW((LPCSTR)lParam, -1);\r
887                                 r = SendMessageW(hWnd, SB_SETTEXTW, wParam, (LPARAM)pw0);\r
888                                 break;\r
889                         default:\r
890                                 r = SendMessageW(hWnd, Msg, wParam, lParam);\r
891                                 break;\r
892                         }\r
893                 }\r
894                 else if(_wcsicmp(ClassName, WC_TREEVIEWW) == 0)\r
895                 {\r
896                         switch(Msg)\r
897                         {\r
898                         case TVM_GETITEMA:\r
899                                 pmTVItem = (TVITEMEXA*)lParam;\r
900                                 wTVItem.mask = pmTVItem->mask;\r
901                                 wTVItem.hItem = pmTVItem->hItem;\r
902                                 wTVItem.state = pmTVItem->state;\r
903                                 wTVItem.stateMask = pmTVItem->stateMask;\r
904                                 if(pmTVItem->mask & TVIF_TEXT)\r
905                                 {\r
906                                         Size = pmTVItem->cchTextMax * 4;\r
907                                         pw0 = AllocateStringW(Size);\r
908                                         wTVItem.pszText = pw0;\r
909                                         wTVItem.cchTextMax = Size;\r
910                                 }\r
911                                 wTVItem.iImage = pmTVItem->iImage;\r
912                                 wTVItem.iSelectedImage = pmTVItem->iSelectedImage;\r
913                                 wTVItem.cChildren = pmTVItem->cChildren;\r
914                                 wTVItem.lParam = pmTVItem->lParam;\r
915                                 wTVItem.iIntegral = pmTVItem->iIntegral;\r
916 //                              wTVItem.uStateEx = pmTVItem->uStateEx;\r
917 //                              wTVItem.hwnd = pmTVItem->hwnd;\r
918 //                              wTVItem.iExpandedImage = pmTVItem->iExpandedImage;\r
919 //                              wTVItem.iReserved = pmTVItem->iReserved;\r
920                                 r = SendMessageW(hWnd, TVM_GETITEMW, wParam, (LPARAM)&wTVItem);\r
921                                 pmTVItem->mask = wTVItem.mask;\r
922                                 pmTVItem->hItem = wTVItem.hItem;\r
923                                 pmTVItem->state = wTVItem.state;\r
924                                 pmTVItem->stateMask = wTVItem.stateMask;\r
925                                 if(pmTVItem->mask & TVIF_TEXT)\r
926                                 {\r
927                                         WtoM(pmTVItem->pszText, pmTVItem->cchTextMax, wTVItem.pszText, -1);\r
928                                         TerminateStringM(pmTVItem->pszText, pmTVItem->cchTextMax);\r
929                                 }\r
930                                 pmTVItem->iImage = wTVItem.iImage;\r
931                                 pmTVItem->iSelectedImage = wTVItem.iSelectedImage;\r
932                                 pmTVItem->cChildren = wTVItem.cChildren;\r
933                                 pmTVItem->lParam = wTVItem.lParam;\r
934                                 pmTVItem->iIntegral = wTVItem.iIntegral;\r
935 //                              pmTVItem->uStateEx = wTVItem.uStateEx;\r
936 //                              pmTVItem->hwnd = wTVItem.hwnd;\r
937 //                              pmTVItem->iExpandedImage = wTVItem.iExpandedImage;\r
938 //                              pmTVItem->iReserved = wTVItem.iReserved;\r
939                                 break;\r
940                         case TVM_INSERTITEMA:\r
941                                 pmTVInsert = (TVINSERTSTRUCTA*)lParam;\r
942                                 wTVInsert.hParent = pmTVInsert->hParent;\r
943                                 wTVInsert.hInsertAfter = pmTVInsert->hInsertAfter;\r
944                                 wTVInsert.itemex.mask = pmTVInsert->itemex.mask;\r
945                                 wTVInsert.itemex.hItem = pmTVInsert->itemex.hItem;\r
946                                 wTVInsert.itemex.state = pmTVInsert->itemex.state;\r
947                                 wTVInsert.itemex.stateMask = pmTVInsert->itemex.stateMask;\r
948                                 if(pmTVInsert->itemex.mask & TVIF_TEXT)\r
949                                 {\r
950                                         pw0 = DuplicateMtoW(pmTVInsert->itemex.pszText, -1);\r
951                                         wTVInsert.itemex.pszText = pw0;\r
952                                         // TODO: cchTextMaxの確認\r
953                                         wTVInsert.itemex.cchTextMax = pmTVInsert->itemex.cchTextMax;\r
954                                 }\r
955                                 wTVInsert.itemex.iImage = pmTVInsert->itemex.iImage;\r
956                                 wTVInsert.itemex.iSelectedImage = pmTVInsert->itemex.iSelectedImage;\r
957                                 wTVInsert.itemex.cChildren = pmTVInsert->itemex.cChildren;\r
958                                 wTVInsert.itemex.lParam = pmTVInsert->itemex.lParam;\r
959                                 wTVInsert.itemex.iIntegral = pmTVInsert->itemex.iIntegral;\r
960 //                              wTVInsert.itemex.uStateEx = pmTVInsert->itemex.uStateEx;\r
961 //                              wTVInsert.itemex.hwnd = pmTVInsert->itemex.hwnd;\r
962 //                              wTVInsert.itemex.iExpandedImage = pmTVInsert->itemex.iExpandedImage;\r
963 //                              wTVInsert.itemex.iReserved = pmTVInsert->itemex.iReserved;\r
964                                 r = SendMessageW(hWnd, TVM_INSERTITEMW, wParam, (LPARAM)&wTVInsert);\r
965                                 break;\r
966                         default:\r
967                                 r = SendMessageW(hWnd, Msg, wParam, lParam);\r
968                                 break;\r
969                         }\r
970                 }\r
971                 else\r
972                         r = SendMessageW(hWnd, Msg, wParam, lParam);\r
973                 break;\r
974         }\r
975 END_ROUTINE\r
976         FreeDuplicatedString(pw0);\r
977         FreeDuplicatedString(pw1);\r
978         return r;\r
979 }\r
980 \r
981 LRESULT DefDlgProcM(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)\r
982 {\r
983         LRESULT r = 0;\r
984 START_ROUTINE\r
985         // WNDPROCがShift_JIS用であるため\r
986         if(IsWindowUnicode(hWnd))\r
987                 r = DefDlgProcW(hWnd, Msg, wParam, lParam);\r
988         else\r
989                 r = DefDlgProcA(hWnd, Msg, wParam, lParam);\r
990 END_ROUTINE\r
991         return r;\r
992 }\r
993 \r
994 LRESULT SendDlgItemMessageM(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam)\r
995 {\r
996         LRESULT r = 0;\r
997 START_ROUTINE\r
998         r = SendMessageM(GetDlgItem(hDlg, nIDDlgItem), Msg, wParam, lParam);\r
999 END_ROUTINE\r
1000         return r;\r
1001 }\r
1002 \r
1003 BOOL SetWindowTextM(HWND hWnd, LPCSTR lpString)\r
1004 {\r
1005         BOOL r = FALSE;\r
1006         wchar_t* pw0 = NULL;\r
1007 START_ROUTINE\r
1008         pw0 = DuplicateMtoW(lpString, -1);\r
1009         r = SetWindowTextW(hWnd, pw0);\r
1010 END_ROUTINE\r
1011         FreeDuplicatedString(pw0);\r
1012         return r;\r
1013 }\r
1014 \r
1015 UINT DragQueryFileM(HDROP hDrop, UINT iFile, LPSTR lpszFile, UINT cch)\r
1016 {\r
1017         UINT r = 0;\r
1018         wchar_t* pw0 = NULL;\r
1019 START_ROUTINE\r
1020         if(iFile == (UINT)-1)\r
1021                 r = DragQueryFileW(hDrop, iFile, (LPWSTR)lpszFile, cch);\r
1022         else\r
1023         {\r
1024                 pw0 = AllocateStringW(cch * 4);\r
1025                 DragQueryFileW(hDrop, iFile, pw0, cch * 4);\r
1026                 WtoM(lpszFile, cch, pw0, -1);\r
1027                 r = TerminateStringM(lpszFile, cch);\r
1028         }\r
1029 END_ROUTINE\r
1030         FreeDuplicatedString(pw0);\r
1031         return r;\r
1032 }\r
1033 \r
1034 LPSTR GetCommandLineM()\r
1035 {\r
1036         LPSTR r = 0;\r
1037         static char* pm0 = NULL;\r
1038 START_ROUTINE\r
1039         if(!pm0)\r
1040                 pm0 = DuplicateWtoM(GetCommandLineW(), -1);\r
1041         r = pm0;\r
1042 END_ROUTINE\r
1043         return r;\r
1044 }\r
1045 \r
1046 DWORD GetCurrentDirectoryM(DWORD nBufferLength, LPSTR lpBuffer)\r
1047 {\r
1048         DWORD r = 0;\r
1049         wchar_t* pw0 = NULL;\r
1050 START_ROUTINE\r
1051         // TODO: バッファが不十分な場合に必要なサイズを返す\r
1052         pw0 = AllocateStringW(nBufferLength * 4);\r
1053         GetCurrentDirectoryW(nBufferLength * 4, pw0);\r
1054         WtoM(lpBuffer, nBufferLength, pw0, -1);\r
1055         r = TerminateStringM(lpBuffer, nBufferLength);\r
1056 END_ROUTINE\r
1057         FreeDuplicatedString(pw0);\r
1058         return r;\r
1059 }\r
1060 \r
1061 BOOL SetCurrentDirectoryM(LPCSTR lpPathName)\r
1062 {\r
1063         BOOL r = FALSE;\r
1064         wchar_t* pw0 = NULL;\r
1065 START_ROUTINE\r
1066         pw0 = DuplicateMtoW(lpPathName, -1);\r
1067         r = SetCurrentDirectoryW(pw0);\r
1068 END_ROUTINE\r
1069         FreeDuplicatedString(pw0);\r
1070         return r;\r
1071 }\r
1072 \r
1073 DWORD GetTempPathM(DWORD nBufferLength, LPSTR lpBuffer)\r
1074 {\r
1075         DWORD r = 0;\r
1076         wchar_t* pw0 = NULL;\r
1077 START_ROUTINE\r
1078         pw0 = AllocateStringW(nBufferLength * 4);\r
1079         GetTempPathW(nBufferLength * 4, pw0);\r
1080         WtoM(lpBuffer, nBufferLength, pw0, -1);\r
1081         r = TerminateStringM(lpBuffer, nBufferLength);\r
1082 END_ROUTINE\r
1083         FreeDuplicatedString(pw0);\r
1084         return r;\r
1085 }\r
1086 \r
1087 DWORD GetFileAttributesM(LPCSTR lpFileName)\r
1088 {\r
1089         DWORD r = FALSE;\r
1090         wchar_t* pw0 = NULL;\r
1091 START_ROUTINE\r
1092         pw0 = DuplicateMtoW(lpFileName, -1);\r
1093         r = GetFileAttributesW(pw0);\r
1094 END_ROUTINE\r
1095         FreeDuplicatedString(pw0);\r
1096         return r;\r
1097 }\r
1098 \r
1099 DWORD GetModuleFileNameM(HMODULE hModule, LPCH lpFilename, DWORD nSize)\r
1100 {\r
1101         DWORD r = 0;\r
1102         wchar_t* pw0 = NULL;\r
1103 START_ROUTINE\r
1104         pw0 = AllocateStringW(nSize * 4);\r
1105         GetModuleFileNameW(hModule, pw0, nSize * 4);\r
1106         WtoM(lpFilename, nSize, pw0, -1);\r
1107         r = TerminateStringM(lpFilename, nSize);\r
1108 END_ROUTINE\r
1109         FreeDuplicatedString(pw0);\r
1110         return r;\r
1111 }\r
1112 \r
1113 LSTATUS RegOpenKeyExM(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)\r
1114 {\r
1115         LSTATUS r = 0;\r
1116         wchar_t* pw0 = NULL;\r
1117 START_ROUTINE\r
1118         pw0 = DuplicateMtoW(lpSubKey, -1);\r
1119         r = RegOpenKeyExW(hKey, pw0, ulOptions, samDesired, phkResult);\r
1120 END_ROUTINE\r
1121         FreeDuplicatedString(pw0);\r
1122         return r;\r
1123 }\r
1124 \r
1125 LSTATUS RegCreateKeyExM(HKEY hKey, LPCSTR lpSubKey, DWORD Reserved, LPSTR lpClass, DWORD dwOptions, REGSAM samDesired, CONST LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition)\r
1126 {\r
1127         LSTATUS r = 0;\r
1128         wchar_t* pw0 = NULL;\r
1129         wchar_t* pw1 = NULL;\r
1130 START_ROUTINE\r
1131         pw0 = DuplicateMtoW(lpSubKey, -1);\r
1132         pw1 = DuplicateMtoW(lpClass, -1);\r
1133         r = RegCreateKeyExW(hKey, pw0, Reserved, pw1, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);\r
1134 END_ROUTINE\r
1135         FreeDuplicatedString(pw0);\r
1136         FreeDuplicatedString(pw1);\r
1137         return r;\r
1138 }\r
1139 \r
1140 LSTATUS RegDeleteValueM(HKEY hKey, LPCSTR lpValueName)\r
1141 {\r
1142         LSTATUS r = 0;\r
1143         wchar_t* pw0 = NULL;\r
1144 START_ROUTINE\r
1145         pw0 = DuplicateMtoW(lpValueName, -1);\r
1146         r = RegDeleteValueW(hKey, pw0);\r
1147 END_ROUTINE\r
1148         FreeDuplicatedString(pw0);\r
1149         return r;\r
1150 }\r
1151 \r
1152 LSTATUS RegQueryValueExM(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)\r
1153 {\r
1154         LSTATUS r = 0;\r
1155         wchar_t* pw0 = NULL;\r
1156         wchar_t* pw1 = NULL;\r
1157         DWORD dwType;\r
1158         DWORD wcbData;\r
1159 START_ROUTINE\r
1160         pw0 = DuplicateMtoW(lpValueName, -1);\r
1161         if(RegQueryValueExW(hKey, pw0, NULL, &dwType, NULL, 0) == ERROR_SUCCESS)\r
1162         {\r
1163                 switch(dwType)\r
1164                 {\r
1165                 case REG_SZ:\r
1166                 case REG_EXPAND_SZ:\r
1167                 case REG_MULTI_SZ:\r
1168                         if(lpcbData)\r
1169                         {\r
1170                                 pw1 = AllocateStringW(*lpcbData / sizeof(char) * 4);\r
1171                                 wcbData = *lpcbData / sizeof(char) * 4;\r
1172                                 r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, (LPBYTE)pw1, &wcbData);\r
1173                                 if(lpData)\r
1174                                         *lpcbData = sizeof(char) * WtoM((char*)lpData, *lpcbData / sizeof(char), pw1, wcbData / sizeof(wchar_t));\r
1175                                 else\r
1176                                         *lpcbData = sizeof(char) * WtoM(NULL, 0, pw1, wcbData / sizeof(wchar_t));\r
1177                         }\r
1178                         break;\r
1179                 default:\r
1180                         r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, lpData, lpcbData);\r
1181                         break;\r
1182                 }\r
1183         }\r
1184         else\r
1185                 r = RegQueryValueExW(hKey, pw0, lpReserved, lpType, lpData, lpcbData);\r
1186 END_ROUTINE\r
1187         FreeDuplicatedString(pw0);\r
1188         FreeDuplicatedString(pw1);\r
1189         return r;\r
1190 }\r
1191 \r
1192 LSTATUS RegSetValueExM(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE* lpData, DWORD cbData)\r
1193 {\r
1194         LSTATUS r = 0;\r
1195         wchar_t* pw0 = NULL;\r
1196         wchar_t* pw1 = NULL;\r
1197         DWORD wcbData;\r
1198 START_ROUTINE\r
1199         pw0 = DuplicateMtoW(lpValueName, -1);\r
1200         switch(dwType)\r
1201         {\r
1202         case REG_SZ:\r
1203         case REG_EXPAND_SZ:\r
1204         case REG_MULTI_SZ:\r
1205                 wcbData = MtoW(NULL, 0, (char*)lpData, cbData / sizeof(char));\r
1206                 pw1 = AllocateStringW(wcbData);\r
1207                 MtoW(pw1, wcbData, (char*)lpData, cbData / sizeof(char));\r
1208                 wcbData = sizeof(wchar_t) * wcbData;\r
1209                 lpData = (BYTE*)pw1;\r
1210                 cbData = wcbData;\r
1211                 break;\r
1212         }\r
1213         r = RegSetValueExW(hKey, pw0, Reserved, dwType, lpData, cbData);\r
1214 END_ROUTINE\r
1215         FreeDuplicatedString(pw0);\r
1216         FreeDuplicatedString(pw1);\r
1217         return r;\r
1218 }\r
1219 \r
1220 BOOL TextOutM(HDC hdc, int x, int y, LPCSTR lpString, int c)\r
1221 {\r
1222         BOOL r = FALSE;\r
1223         wchar_t* pw0 = NULL;\r
1224 START_ROUTINE\r
1225         pw0 = DuplicateMtoW(lpString, c);\r
1226         r = TextOutW(hdc, x, y, pw0, wcslen(pw0));\r
1227 END_ROUTINE\r
1228         FreeDuplicatedString(pw0);\r
1229         return r;\r
1230 }\r
1231 \r
1232 BOOL GetTextExtentPoint32M(HDC hdc, LPCSTR lpString, int c, LPSIZE psizl)\r
1233 {\r
1234         BOOL r = FALSE;\r
1235         wchar_t* pw0 = NULL;\r
1236 START_ROUTINE\r
1237         pw0 = DuplicateMtoW(lpString, c);\r
1238         r = GetTextExtentPoint32W(hdc, pw0, wcslen(pw0), psizl);\r
1239 END_ROUTINE\r
1240         FreeDuplicatedString(pw0);\r
1241         return r;\r
1242 }\r
1243 \r
1244 INT_PTR PropertySheetM(LPCPROPSHEETHEADERA v0)\r
1245 {\r
1246         INT_PTR r = 0;\r
1247         PROPSHEETHEADERW a0;\r
1248         PROPSHEETPAGEW* pwPage;\r
1249         UINT i;\r
1250 START_ROUTINE\r
1251         a0.dwSize = sizeof(PROPSHEETHEADERW);\r
1252         a0.dwFlags = v0->dwFlags;\r
1253         a0.hwndParent = v0->hwndParent;\r
1254         a0.hInstance = v0->hInstance;\r
1255         if(v0->dwFlags & PSH_USEICONID)\r
1256                 a0.pszIcon = DuplicateMtoW(v0->pszIcon, -1);\r
1257         else\r
1258                 a0.hIcon = v0->hIcon;\r
1259         a0.pszCaption = DuplicateMtoW(v0->pszCaption, -1);\r
1260         a0.nPages = v0->nPages;\r
1261         if(v0->dwFlags & PSH_USEPSTARTPAGE)\r
1262                 a0.pStartPage = DuplicateMtoW(v0->pStartPage, -1);\r
1263         else\r
1264                 a0.nStartPage = v0->nStartPage;\r
1265         if(v0->dwFlags & PSH_PROPSHEETPAGE)\r
1266         {\r
1267                 if(v0->ppsp && (pwPage = (PROPSHEETPAGEW*)malloc(sizeof(PROPSHEETPAGEW) * v0->nPages)))\r
1268                 {\r
1269                         for(i = 0; i < v0->nPages; i++)\r
1270                         {\r
1271                                 pwPage[i].dwSize = sizeof(PROPSHEETPAGEW);\r
1272                                 pwPage[i].dwFlags = v0->ppsp[i].dwFlags;\r
1273                                 pwPage[i].hInstance = v0->ppsp[i].hInstance;\r
1274                                 if(v0->ppsp[i].dwFlags & PSP_DLGINDIRECT)\r
1275                                         pwPage[i].pResource = v0->ppsp[i].pResource;\r
1276                                 else\r
1277                                         pwPage[i].pszTemplate = DuplicateMtoW(v0->ppsp[i].pszTemplate, -1);\r
1278                                 if(v0->ppsp[i].dwFlags & PSP_USEICONID)\r
1279                                         pwPage[i].pszIcon = DuplicateMtoW(v0->ppsp[i].pszIcon, -1);\r
1280                                 else\r
1281                                         pwPage[i].hIcon = v0->ppsp[i].hIcon;\r
1282                                 if(v0->ppsp[i].dwFlags & PSP_USETITLE)\r
1283                                         pwPage[i].pszTitle = DuplicateMtoW(v0->ppsp[i].pszTitle, -1);\r
1284                                 pwPage[i].pfnDlgProc = v0->ppsp[i].pfnDlgProc;\r
1285                                 pwPage[i].lParam = v0->ppsp[i].lParam;\r
1286                                 // TODO: pfnCallback\r
1287                                 pwPage[i].pfnCallback = (LPFNPSPCALLBACKW)v0->ppsp[i].pfnCallback;\r
1288                                 pwPage[i].pcRefParent = v0->ppsp[i].pcRefParent;\r
1289                                 if(v0->ppsp[i].dwFlags & PSP_USEHEADERTITLE)\r
1290                                         pwPage[i].pszHeaderTitle = DuplicateMtoW(v0->ppsp[i].pszHeaderTitle, -1);\r
1291                                 if(v0->ppsp[i].dwFlags & PSP_USEHEADERSUBTITLE)\r
1292                                         pwPage[i].pszHeaderSubTitle = DuplicateMtoW(v0->ppsp[i].pszHeaderSubTitle, -1);\r
1293                         }\r
1294                 }\r
1295                 else\r
1296                         pwPage = NULL;\r
1297                 a0.ppsp = pwPage;\r
1298         }\r
1299         else\r
1300                 a0.phpage = v0->phpage;\r
1301         a0.pfnCallback = v0->pfnCallback;\r
1302         if(v0->dwFlags & PSH_USEHBMWATERMARK)\r
1303                 a0.hbmWatermark = v0->hbmWatermark;\r
1304         else\r
1305                 a0.pszbmWatermark = DuplicateMtoW(v0->pszbmWatermark, -1);\r
1306         r = PropertySheetW(&a0);\r
1307         if(a0.dwFlags & PSH_USEICONID)\r
1308                 FreeDuplicatedString((void*)a0.pszIcon);\r
1309         FreeDuplicatedString((void*)a0.pszCaption);\r
1310         if(v0->dwFlags & PSH_USEPSTARTPAGE)\r
1311                 FreeDuplicatedString((void*)a0.pStartPage);\r
1312         if(v0->dwFlags & PSH_PROPSHEETPAGE)\r
1313         {\r
1314                 if(pwPage)\r
1315                 {\r
1316                         for(i = 0; i < v0->nPages; i++)\r
1317                         {\r
1318                                 if(!(v0->ppsp[i].dwFlags & PSP_DLGINDIRECT))\r
1319                                         FreeDuplicatedString((void*)pwPage[i].pszTemplate);\r
1320                                 if(v0->ppsp[i].dwFlags & PSP_USEICONID)\r
1321                                         FreeDuplicatedString((void*)pwPage[i].pszIcon);\r
1322                                 if(v0->ppsp[i].dwFlags & PSP_USETITLE)\r
1323                                         FreeDuplicatedString((void*)pwPage[i].pszTitle);\r
1324                                 if(v0->ppsp[i].dwFlags & PSP_USEHEADERTITLE)\r
1325                                         FreeDuplicatedString((void*)pwPage[i].pszHeaderTitle);\r
1326                                 if(v0->ppsp[i].dwFlags & PSP_USEHEADERSUBTITLE)\r
1327                                         FreeDuplicatedString((void*)pwPage[i].pszHeaderSubTitle);\r
1328                         }\r
1329                         free(pwPage);\r
1330                 }\r
1331         }\r
1332         if(!(v0->dwFlags & PSH_USEHBMWATERMARK))\r
1333                 FreeDuplicatedString((void*)a0.pszbmWatermark);\r
1334 END_ROUTINE\r
1335         return r;\r
1336 }\r
1337 \r
1338 BOOL GetOpenFileNameM(LPOPENFILENAMEA v0)\r
1339 {\r
1340         BOOL r = FALSE;\r
1341         wchar_t* pw0 = NULL;\r
1342         wchar_t* pw1 = NULL;\r
1343         wchar_t* pw2 = NULL;\r
1344         wchar_t* pw3 = NULL;\r
1345         wchar_t* pw4 = NULL;\r
1346         wchar_t* pw5 = NULL;\r
1347         wchar_t* pw6 = NULL;\r
1348         wchar_t* pw7 = NULL;\r
1349         wchar_t* pw8 = NULL;\r
1350         wchar_t* pw9 = NULL;\r
1351         OPENFILENAMEW wofn;\r
1352 START_ROUTINE\r
1353         wofn.lStructSize = sizeof(OPENFILENAMEW);\r
1354         wofn.hwndOwner = v0->hwndOwner;\r
1355         wofn.hInstance = v0->hInstance;\r
1356         pw0 = DuplicateMtoWMultiString(v0->lpstrFilter);\r
1357         wofn.lpstrFilter = pw0;\r
1358         pw1 = DuplicateMtoWBuffer(v0->lpstrCustomFilter, -1, v0->nMaxCustFilter * 4);\r
1359         wofn.lpstrCustomFilter = pw1;\r
1360         wofn.nMaxCustFilter = v0->nMaxCustFilter * 4;\r
1361         wofn.nFilterIndex = v0->nFilterIndex;\r
1362         pw2 = DuplicateMtoWMultiStringBuffer(v0->lpstrFile, v0->nMaxFile * 4);\r
1363         wofn.lpstrFile = pw2;\r
1364         wofn.nMaxFile = v0->nMaxFile * 4;\r
1365         pw3 = DuplicateMtoWBuffer(v0->lpstrFileTitle, -1, v0->nMaxFileTitle * 4);\r
1366         wofn.lpstrFileTitle = pw3;\r
1367         wofn.nMaxFileTitle = v0->nMaxFileTitle * 4;\r
1368         pw4 = DuplicateMtoW(v0->lpstrInitialDir, -1);\r
1369         wofn.lpstrInitialDir = pw4;\r
1370         pw5 = DuplicateMtoW(v0->lpstrTitle, -1);\r
1371         wofn.lpstrTitle = pw5;\r
1372         wofn.Flags = v0->Flags;\r
1373         wofn.nFileOffset = MtoW(NULL, 0, v0->lpstrFile, v0->nFileOffset);\r
1374         wofn.nFileExtension = MtoW(NULL, 0, v0->lpstrFile, v0->nFileExtension);\r
1375         pw6 = DuplicateMtoW(v0->lpstrDefExt, -1);\r
1376         wofn.lpstrDefExt = pw6;\r
1377         wofn.lCustData = v0->lCustData;\r
1378         wofn.lpfnHook = v0->lpfnHook;\r
1379         wofn.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);\r
1380         wofn.pvReserved = v0->pvReserved;\r
1381         wofn.FlagsEx = v0->FlagsEx;\r
1382         r = GetOpenFileNameW(&wofn);\r
1383         WtoM(v0->lpstrFile, v0->nMaxFile, wofn.lpstrFile, -1);\r
1384         TerminateStringM(v0->lpstrFile, v0->nMaxFile);\r
1385         v0->nFileOffset = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileOffset);\r
1386         v0->nFileExtension = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileExtension);\r
1387 END_ROUTINE\r
1388         FreeDuplicatedString(pw0);\r
1389         FreeDuplicatedString(pw1);\r
1390         FreeDuplicatedString(pw2);\r
1391         FreeDuplicatedString(pw3);\r
1392         FreeDuplicatedString(pw4);\r
1393         FreeDuplicatedString(pw5);\r
1394         FreeDuplicatedString(pw6);\r
1395         return r;\r
1396 }\r
1397 \r
1398 BOOL GetSaveFileNameM(LPOPENFILENAMEA v0)\r
1399 {\r
1400         BOOL r = FALSE;\r
1401         wchar_t* pw0 = NULL;\r
1402         wchar_t* pw1 = NULL;\r
1403         wchar_t* pw2 = NULL;\r
1404         wchar_t* pw3 = NULL;\r
1405         wchar_t* pw4 = NULL;\r
1406         wchar_t* pw5 = NULL;\r
1407         wchar_t* pw6 = NULL;\r
1408         wchar_t* pw7 = NULL;\r
1409         wchar_t* pw8 = NULL;\r
1410         wchar_t* pw9 = NULL;\r
1411         OPENFILENAMEW wofn;\r
1412 START_ROUTINE\r
1413         wofn.lStructSize = sizeof(OPENFILENAMEW);\r
1414         wofn.hwndOwner = v0->hwndOwner;\r
1415         wofn.hInstance = v0->hInstance;\r
1416         pw0 = DuplicateMtoWMultiString(v0->lpstrFilter);\r
1417         wofn.lpstrFilter = pw0;\r
1418         pw1 = DuplicateMtoWBuffer(v0->lpstrCustomFilter, -1, v0->nMaxCustFilter * 4);\r
1419         wofn.lpstrCustomFilter = pw1;\r
1420         wofn.nMaxCustFilter = v0->nMaxCustFilter * 4;\r
1421         wofn.nFilterIndex = v0->nFilterIndex;\r
1422         pw2 = DuplicateMtoWMultiStringBuffer(v0->lpstrFile, v0->nMaxFile * 4);\r
1423         wofn.lpstrFile = pw2;\r
1424         wofn.nMaxFile = v0->nMaxFile * 4;\r
1425         pw3 = DuplicateMtoWBuffer(v0->lpstrFileTitle, -1, v0->nMaxFileTitle * 4);\r
1426         wofn.lpstrFileTitle = pw3;\r
1427         wofn.nMaxFileTitle = v0->nMaxFileTitle * 4;\r
1428         pw4 = DuplicateMtoW(v0->lpstrInitialDir, -1);\r
1429         wofn.lpstrInitialDir = pw4;\r
1430         pw5 = DuplicateMtoW(v0->lpstrTitle, -1);\r
1431         wofn.lpstrTitle = pw5;\r
1432         wofn.Flags = v0->Flags;\r
1433         wofn.nFileOffset = MtoW(NULL, 0, v0->lpstrFile, v0->nFileOffset);\r
1434         wofn.nFileExtension = MtoW(NULL, 0, v0->lpstrFile, v0->nFileExtension);\r
1435         pw6 = DuplicateMtoW(v0->lpstrDefExt, -1);\r
1436         wofn.lpstrDefExt = pw6;\r
1437         wofn.lCustData = v0->lCustData;\r
1438         wofn.lpfnHook = v0->lpfnHook;\r
1439         wofn.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);\r
1440         wofn.pvReserved = v0->pvReserved;\r
1441         wofn.FlagsEx = v0->FlagsEx;\r
1442         r = GetSaveFileNameW(&wofn);\r
1443         WtoM(v0->lpstrFile, v0->nMaxFile, wofn.lpstrFile, -1);\r
1444         TerminateStringM(v0->lpstrFile, v0->nMaxFile);\r
1445         v0->nFileOffset = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileOffset);\r
1446         v0->nFileExtension = WtoM(NULL, 0, wofn.lpstrFile, wofn.nFileExtension);\r
1447 END_ROUTINE\r
1448         FreeDuplicatedString(pw0);\r
1449         FreeDuplicatedString(pw1);\r
1450         FreeDuplicatedString(pw2);\r
1451         FreeDuplicatedString(pw3);\r
1452         FreeDuplicatedString(pw4);\r
1453         FreeDuplicatedString(pw5);\r
1454         FreeDuplicatedString(pw6);\r
1455         return r;\r
1456 }\r
1457 \r
1458 HWND HtmlHelpM(HWND hwndCaller, LPCSTR pszFile, UINT uCommand, DWORD_PTR dwData)\r
1459 {\r
1460         HWND r = NULL;\r
1461         wchar_t* pw0 = NULL;\r
1462 START_ROUTINE\r
1463         pw0 = DuplicateMtoW(pszFile, -1);\r
1464         r = HtmlHelpW(hwndCaller, pw0, uCommand, dwData);\r
1465 END_ROUTINE\r
1466         FreeDuplicatedString(pw0);\r
1467         return r;\r
1468 }\r
1469 \r
1470 BOOL CreateProcessM(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)\r
1471 {\r
1472         BOOL r = FALSE;\r
1473         wchar_t* pw0 = NULL;\r
1474         wchar_t* pw1 = NULL;\r
1475         wchar_t* pw2 = NULL;\r
1476         wchar_t* pw3 = NULL;\r
1477         wchar_t* pw4 = NULL;\r
1478         wchar_t* pw5 = NULL;\r
1479         STARTUPINFOW wStartupInfo;\r
1480 START_ROUTINE\r
1481         pw0 = DuplicateMtoW(lpApplicationName, -1);\r
1482         pw1 = DuplicateMtoWBuffer(lpCommandLine, -1, (strlen(lpCommandLine) + 1) * 4);\r
1483         pw2 = DuplicateMtoW(lpCurrentDirectory, -1);\r
1484         wStartupInfo.cb = sizeof(LPSTARTUPINFOW);\r
1485         pw3 = DuplicateMtoW(lpStartupInfo->lpReserved, -1);\r
1486         wStartupInfo.lpReserved = pw3;\r
1487         pw4 = DuplicateMtoW(lpStartupInfo->lpDesktop, -1);\r
1488         wStartupInfo.lpDesktop = pw4;\r
1489         pw5 = DuplicateMtoW(lpStartupInfo->lpTitle, -1);\r
1490         wStartupInfo.lpTitle = pw5;\r
1491         wStartupInfo.dwX = lpStartupInfo->dwX;\r
1492         wStartupInfo.dwY = lpStartupInfo->dwY;\r
1493         wStartupInfo.dwXSize = lpStartupInfo->dwXSize;\r
1494         wStartupInfo.dwYSize = lpStartupInfo->dwYSize;\r
1495         wStartupInfo.dwXCountChars = lpStartupInfo->dwXCountChars;\r
1496         wStartupInfo.dwYCountChars = lpStartupInfo->dwYCountChars;\r
1497         wStartupInfo.dwFillAttribute = lpStartupInfo->dwFillAttribute;\r
1498         wStartupInfo.dwFlags = lpStartupInfo->dwFlags;\r
1499         wStartupInfo.wShowWindow = lpStartupInfo->wShowWindow;\r
1500         wStartupInfo.cbReserved2 = lpStartupInfo->cbReserved2;\r
1501         wStartupInfo.lpReserved2 = lpStartupInfo->lpReserved2;\r
1502         wStartupInfo.hStdInput = lpStartupInfo->hStdInput;\r
1503         wStartupInfo.hStdOutput = lpStartupInfo->hStdOutput;\r
1504         wStartupInfo.hStdError = lpStartupInfo->hStdError;\r
1505         r = CreateProcessW(pw0, pw1, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, pw2, &wStartupInfo, lpProcessInformation);\r
1506         WtoM(lpCommandLine, strlen(lpCommandLine) + 1, pw1, -1);\r
1507 END_ROUTINE\r
1508         FreeDuplicatedString(pw0);\r
1509         FreeDuplicatedString(pw1);\r
1510         FreeDuplicatedString(pw2);\r
1511         FreeDuplicatedString(pw3);\r
1512         FreeDuplicatedString(pw4);\r
1513         FreeDuplicatedString(pw5);\r
1514         return r;\r
1515 }\r
1516 \r
1517 HINSTANCE FindExecutableM(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)\r
1518 {\r
1519         HINSTANCE r = NULL;\r
1520         wchar_t* pw0 = NULL;\r
1521         wchar_t* pw1 = NULL;\r
1522         wchar_t* pw2 = NULL;\r
1523         wchar_t* pw3 = NULL;\r
1524 START_ROUTINE\r
1525         pw0 = DuplicateMtoW(lpFile, -1);\r
1526         pw1 = DuplicateMtoW(lpDirectory, -1);\r
1527         pw2 = AllocateStringW(MAX_PATH * 4);\r
1528         r = FindExecutableW(pw0, pw1, pw2);\r
1529         // バッファ長不明のためオーバーランの可能性あり\r
1530         WtoM(lpResult, MAX_PATH, pw2, -1);\r
1531         TerminateStringM(lpResult, MAX_PATH);\r
1532 END_ROUTINE\r
1533         FreeDuplicatedString(pw0);\r
1534         FreeDuplicatedString(pw1);\r
1535         FreeDuplicatedString(pw2);\r
1536         FreeDuplicatedString(pw3);\r
1537         return r;\r
1538 }\r
1539 \r
1540 HINSTANCE ShellExecuteM(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd)\r
1541 {\r
1542         HINSTANCE r = NULL;\r
1543         wchar_t* pw0 = NULL;\r
1544         wchar_t* pw1 = NULL;\r
1545         wchar_t* pw2 = NULL;\r
1546         wchar_t* pw3 = NULL;\r
1547 START_ROUTINE\r
1548         pw0 = DuplicateMtoW(lpOperation, -1);\r
1549         pw1 = DuplicateMtoW(lpFile, -1);\r
1550         pw2 = DuplicateMtoW(lpParameters, -1);\r
1551         pw3 = DuplicateMtoW(lpDirectory, -1);\r
1552         r = ShellExecuteW(hwnd, pw0, pw1, pw2, pw3, nShowCmd);\r
1553 END_ROUTINE\r
1554         FreeDuplicatedString(pw0);\r
1555         FreeDuplicatedString(pw1);\r
1556         FreeDuplicatedString(pw2);\r
1557         FreeDuplicatedString(pw3);\r
1558         return r;\r
1559 }\r
1560 \r
1561 PIDLIST_ABSOLUTE SHBrowseForFolderM(LPBROWSEINFOA lpbi)\r
1562 {\r
1563         PIDLIST_ABSOLUTE r = NULL;\r
1564         wchar_t* pw0 = NULL;\r
1565         wchar_t* pw1 = NULL;\r
1566         BROWSEINFOW wbi;\r
1567 START_ROUTINE\r
1568         wbi.hwndOwner = lpbi->hwndOwner;\r
1569         wbi.pidlRoot = lpbi->pidlRoot;\r
1570         pw0 = DuplicateMtoWBuffer(lpbi->pszDisplayName, -1, MAX_PATH * 4);\r
1571         wbi.pszDisplayName = pw0;\r
1572         pw1 = DuplicateMtoW(lpbi->lpszTitle, -1);\r
1573         wbi.lpszTitle = pw1;\r
1574         wbi.ulFlags = lpbi->ulFlags;\r
1575         // TODO: lpfn\r
1576         wbi.lpfn = lpbi->lpfn;\r
1577         wbi.lParam = lpbi->lParam;\r
1578         wbi.iImage = lpbi->iImage;\r
1579         r = SHBrowseForFolderW(&wbi);\r
1580         // バッファ長不明のためオーバーランの可能性あり\r
1581         WtoM(lpbi->pszDisplayName, MAX_PATH, wbi.pszDisplayName, -1);\r
1582         lpbi->iImage = wbi.iImage;\r
1583 END_ROUTINE\r
1584         FreeDuplicatedString(pw0);\r
1585         FreeDuplicatedString(pw1);\r
1586         return r;\r
1587 }\r
1588 \r
1589 BOOL SHGetPathFromIDListM(PCIDLIST_ABSOLUTE pidl, LPSTR pszPath)\r
1590 {\r
1591         BOOL r = FALSE;\r
1592         wchar_t* pw0 = NULL;\r
1593 START_ROUTINE\r
1594         pw0 = AllocateStringW(MAX_PATH * 4);\r
1595         r = SHGetPathFromIDListW(pidl, pw0);\r
1596         // バッファ長不明のためオーバーランの可能性あり\r
1597         WtoM(pszPath, MAX_PATH, pw0, -1);\r
1598         TerminateStringM(pszPath, MAX_PATH);\r
1599 END_ROUTINE\r
1600         FreeDuplicatedString(pw0);\r
1601         return r;\r
1602 }\r
1603 \r
1604 int SHFileOperationM(LPSHFILEOPSTRUCTA lpFileOp)\r
1605 {\r
1606         int r = 0;\r
1607         wchar_t* pw0 = NULL;\r
1608         wchar_t* pw1 = NULL;\r
1609         wchar_t* pw2 = NULL;\r
1610         SHFILEOPSTRUCTW wFileOp;\r
1611 START_ROUTINE\r
1612         wFileOp.hwnd = lpFileOp->hwnd;\r
1613         wFileOp.wFunc = lpFileOp->wFunc;\r
1614         pw0 = DuplicateMtoWMultiString(lpFileOp->pFrom);\r
1615         wFileOp.pFrom = pw0;\r
1616         pw1 = DuplicateMtoWMultiString(lpFileOp->pTo);\r
1617         wFileOp.pTo = pw1;\r
1618         wFileOp.fFlags = lpFileOp->fFlags;\r
1619         wFileOp.fAnyOperationsAborted = lpFileOp->fAnyOperationsAborted;\r
1620         wFileOp.hNameMappings = lpFileOp->hNameMappings;\r
1621         if(lpFileOp->fFlags & FOF_SIMPLEPROGRESS)\r
1622                 pw2 = DuplicateMtoW(lpFileOp->lpszProgressTitle, -1);\r
1623         r = SHFileOperationW(&wFileOp);\r
1624         lpFileOp->fAnyOperationsAborted = wFileOp.fAnyOperationsAborted;\r
1625 END_ROUTINE\r
1626         FreeDuplicatedString(pw0);\r
1627         FreeDuplicatedString(pw1);\r
1628         FreeDuplicatedString(pw2);\r
1629         return r;\r
1630 }\r
1631 \r
1632 BOOL AppendMenuM(HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem, LPCSTR lpNewItem)\r
1633 {\r
1634         int r = 0;\r
1635         wchar_t* pw0 = NULL;\r
1636 START_ROUTINE\r
1637         if(uFlags & (MF_BITMAP | MF_OWNERDRAW))\r
1638                 r = AppendMenuW(hMenu, uFlags, uIDNewItem, (LPCWSTR)lpNewItem);\r
1639         else\r
1640         {\r
1641                 pw0 = DuplicateMtoW(lpNewItem, -1);\r
1642                 r = AppendMenuW(hMenu, uFlags, uIDNewItem, pw0);\r
1643         }\r
1644 END_ROUTINE\r
1645         FreeDuplicatedString(pw0);\r
1646         return r;\r
1647 }\r
1648 \r
1649 BOOL GetMenuItemInfoM(HMENU hmenu, UINT item, BOOL fByPosition, LPMENUITEMINFOA lpmii)\r
1650 {\r
1651         BOOL r = FALSE;\r
1652         wchar_t* pw0 = NULL;\r
1653         MENUITEMINFOW wmii;\r
1654 START_ROUTINE\r
1655         wmii.cbSize = sizeof(MENUITEMINFOW);\r
1656         wmii.fMask = lpmii->fMask;\r
1657         wmii.fType = lpmii->fType;\r
1658         wmii.fState = lpmii->fState;\r
1659         wmii.wID = lpmii->wID;\r
1660         wmii.hSubMenu = lpmii->hSubMenu;\r
1661         wmii.hbmpChecked = lpmii->hbmpChecked;\r
1662         wmii.hbmpUnchecked = lpmii->hbmpUnchecked;\r
1663         wmii.dwItemData = lpmii->dwItemData;\r
1664         if(lpmii->fMask & MIIM_TYPE)\r
1665         {\r
1666                 pw0 = DuplicateMtoWBuffer(lpmii->dwTypeData, -1, lpmii->cch * 4);\r
1667                 wmii.dwTypeData = pw0;\r
1668                 wmii.cch = lpmii->cch * 4;\r
1669         }\r
1670         wmii.hbmpItem = lpmii->hbmpItem;\r
1671         r = GetMenuItemInfoW(hmenu, item, fByPosition, &wmii);\r
1672         lpmii->fType = wmii.fType;\r
1673         lpmii->fState = wmii.fState;\r
1674         lpmii->wID = wmii.wID;\r
1675         lpmii->hSubMenu = wmii.hSubMenu;\r
1676         lpmii->hbmpChecked = wmii.hbmpChecked;\r
1677         lpmii->hbmpUnchecked = wmii.hbmpUnchecked;\r
1678         lpmii->dwItemData = wmii.dwItemData;\r
1679         WtoM(lpmii->dwTypeData, lpmii->cch, wmii.dwTypeData, -1);\r
1680         TerminateStringM(lpmii->dwTypeData, lpmii->cch);\r
1681 END_ROUTINE\r
1682         FreeDuplicatedString(pw0);\r
1683         return r;\r
1684 }\r
1685 \r
1686 HFONT CreateFontIndirectM(CONST LOGFONTA *lplf)\r
1687 {\r
1688         HFONT r = NULL;\r
1689         LOGFONTW wlf;\r
1690 START_ROUTINE\r
1691         wlf.lfHeight = lplf->lfHeight;\r
1692         wlf.lfWidth = lplf->lfWidth;\r
1693         wlf.lfEscapement = lplf->lfEscapement;\r
1694         wlf.lfOrientation = lplf->lfOrientation;\r
1695         wlf.lfWeight = lplf->lfWeight;\r
1696         wlf.lfItalic = lplf->lfItalic;\r
1697         wlf.lfUnderline = lplf->lfUnderline;\r
1698         wlf.lfStrikeOut = lplf->lfStrikeOut;\r
1699         wlf.lfCharSet = lplf->lfCharSet;\r
1700         wlf.lfOutPrecision = lplf->lfOutPrecision;\r
1701         wlf.lfClipPrecision = lplf->lfClipPrecision;\r
1702         wlf.lfQuality = lplf->lfQuality;\r
1703         wlf.lfPitchAndFamily = lplf->lfPitchAndFamily;\r
1704         MtoW(wlf.lfFaceName, LF_FACESIZE, lplf->lfFaceName, -1);\r
1705         TerminateStringW(wlf.lfFaceName, LF_FACESIZE);\r
1706         r = CreateFontIndirect(&wlf);\r
1707 END_ROUTINE\r
1708         return r;\r
1709 }\r
1710 \r
1711 BOOL ChooseFontM(LPCHOOSEFONTA v0)\r
1712 {\r
1713         BOOL r = FALSE;\r
1714         wchar_t* pw0 = NULL;\r
1715         CHOOSEFONTW a0;\r
1716         LOGFONTW* pwlf;\r
1717 START_ROUTINE\r
1718         a0.lStructSize = sizeof(CHOOSEFONTW);\r
1719         a0.hwndOwner = v0->hwndOwner;\r
1720         a0.hDC = v0->hDC;\r
1721         if(v0->lpLogFont && (pwlf = (LOGFONTW*)malloc(sizeof(LOGFONTW))))\r
1722         {\r
1723                 pwlf->lfHeight = v0->lpLogFont->lfHeight;\r
1724                 pwlf->lfWidth = v0->lpLogFont->lfWidth;\r
1725                 pwlf->lfEscapement = v0->lpLogFont->lfEscapement;\r
1726                 pwlf->lfOrientation = v0->lpLogFont->lfOrientation;\r
1727                 pwlf->lfWeight = v0->lpLogFont->lfWeight;\r
1728                 pwlf->lfItalic = v0->lpLogFont->lfItalic;\r
1729                 pwlf->lfUnderline = v0->lpLogFont->lfUnderline;\r
1730                 pwlf->lfStrikeOut = v0->lpLogFont->lfStrikeOut;\r
1731                 pwlf->lfCharSet = v0->lpLogFont->lfCharSet;\r
1732                 pwlf->lfOutPrecision = v0->lpLogFont->lfOutPrecision;\r
1733                 pwlf->lfClipPrecision = v0->lpLogFont->lfClipPrecision;\r
1734                 pwlf->lfQuality = v0->lpLogFont->lfQuality;\r
1735                 pwlf->lfPitchAndFamily = v0->lpLogFont->lfPitchAndFamily;\r
1736                 MtoW(pwlf->lfFaceName, LF_FACESIZE, v0->lpLogFont->lfFaceName, -1);\r
1737                 TerminateStringW(pwlf->lfFaceName, LF_FACESIZE);\r
1738         }\r
1739         else\r
1740                 pwlf = NULL;\r
1741         a0.lpLogFont = pwlf;\r
1742         a0.iPointSize = v0->iPointSize;\r
1743         a0.Flags = v0->Flags;\r
1744         a0.rgbColors = v0->rgbColors;\r
1745         a0.lCustData = v0->lCustData;\r
1746         a0.lpfnHook = v0->lpfnHook;\r
1747         a0.lpTemplateName = DuplicateMtoW(v0->lpTemplateName, -1);\r
1748         a0.hInstance = v0->hInstance;\r
1749         a0.lpszStyle = DuplicateMtoWBuffer(v0->lpszStyle, -1, LF_FACESIZE * 4);\r
1750         a0.nFontType = v0->nFontType;\r
1751         a0.nSizeMin = v0->nSizeMin;\r
1752         a0.nSizeMax = v0->nSizeMax;\r
1753         r = ChooseFontW(&a0);\r
1754         if(v0->lpLogFont)\r
1755         {\r
1756                 v0->lpLogFont->lfHeight = pwlf->lfHeight;\r
1757                 v0->lpLogFont->lfWidth = pwlf->lfWidth;\r
1758                 v0->lpLogFont->lfEscapement = pwlf->lfEscapement;\r
1759                 v0->lpLogFont->lfOrientation = pwlf->lfOrientation;\r
1760                 v0->lpLogFont->lfWeight = pwlf->lfWeight;\r
1761                 v0->lpLogFont->lfItalic = pwlf->lfItalic;\r
1762                 v0->lpLogFont->lfUnderline = pwlf->lfUnderline;\r
1763                 v0->lpLogFont->lfStrikeOut = pwlf->lfStrikeOut;\r
1764                 v0->lpLogFont->lfCharSet = pwlf->lfCharSet;\r
1765                 v0->lpLogFont->lfOutPrecision = pwlf->lfOutPrecision;\r
1766                 v0->lpLogFont->lfClipPrecision = pwlf->lfClipPrecision;\r
1767                 v0->lpLogFont->lfQuality = pwlf->lfQuality;\r
1768                 v0->lpLogFont->lfPitchAndFamily = pwlf->lfPitchAndFamily;\r
1769                 WtoM(v0->lpLogFont->lfFaceName, LF_FACESIZE, pwlf->lfFaceName, -1);\r
1770                 TerminateStringM(v0->lpLogFont->lfFaceName, LF_FACESIZE);\r
1771         }\r
1772         v0->rgbColors = a0.rgbColors;\r
1773         WtoM(v0->lpszStyle, LF_FACESIZE, a0.lpszStyle, -1);\r
1774         TerminateStringM(v0->lpszStyle, LF_FACESIZE);\r
1775         v0->nFontType = a0.nFontType;\r
1776         if(pwlf)\r
1777                 free(pwlf);\r
1778         FreeDuplicatedString((void*)a0.lpTemplateName);\r
1779         FreeDuplicatedString(a0.lpszStyle);\r
1780 END_ROUTINE\r
1781         FreeDuplicatedString(pw0);\r
1782         return r;\r
1783 }\r
1784 \r
1785 INT_PTR DialogBoxParamM(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)\r
1786 {\r
1787         INT_PTR r = 0;\r
1788         wchar_t* pw0 = NULL;\r
1789 START_ROUTINE\r
1790         pw0 = DuplicateMtoW(lpTemplateName, -1);\r
1791         r = DialogBoxParamW(hInstance, pw0, hWndParent, lpDialogFunc, dwInitParam);\r
1792 END_ROUTINE\r
1793         FreeDuplicatedString(pw0);\r
1794         return r;\r
1795 }\r
1796 \r
1797 HWND CreateDialogParamM(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)\r
1798 {\r
1799         HWND r = NULL;\r
1800         wchar_t* pw0 = NULL;\r
1801 START_ROUTINE\r
1802         pw0 = DuplicateMtoW(lpTemplateName, -1);\r
1803         r = CreateDialogParamW(hInstance, pw0, hWndParent, lpDialogFunc, dwInitParam);\r
1804 END_ROUTINE\r
1805         FreeDuplicatedString(pw0);\r
1806         return r;\r
1807 }\r
1808 \r
1809 BOOL sndPlaySoundM(LPCSTR pszSound, UINT fuSound)\r
1810 {\r
1811         BOOL r = FALSE;\r
1812         wchar_t* pw0 = NULL;\r
1813 START_ROUTINE\r
1814         pw0 = DuplicateMtoW(pszSound, -1);\r
1815         r = sndPlaySoundW(pw0, fuSound);\r
1816 END_ROUTINE\r
1817         FreeDuplicatedString(pw0);\r
1818         return r;\r
1819 }\r
1820 \r
1821 HANDLE SetClipboardDataM(UINT uFormat, HANDLE hMem)\r
1822 {\r
1823         HANDLE r = NULL;\r
1824         char* p;\r
1825         int Length;\r
1826         int BufferLength;\r
1827         HGLOBAL hBufferMem;\r
1828 START_ROUTINE\r
1829         if(uFormat == CF_TEXT)\r
1830         {\r
1831                 p = (char*)GlobalLock(hMem);\r
1832                 Length = (int)GlobalSize(hMem);\r
1833                 BufferLength = MtoW(NULL, 0, p, Length);\r
1834                 if(hBufferMem = GlobalAlloc(GMEM_MOVEABLE, sizeof(wchar_t) * BufferLength))\r
1835                 {\r
1836                         MtoW((LPWSTR)GlobalLock(hBufferMem), BufferLength, p, Length);\r
1837                         GlobalUnlock(hBufferMem);\r
1838                         r = SetClipboardData(CF_UNICODETEXT, hBufferMem);\r
1839                 }\r
1840                 GlobalUnlock(hMem);\r
1841                 GlobalFree(hMem);\r
1842         }\r
1843         else\r
1844                 r = SetClipboardData(uFormat, hMem);\r
1845 END_ROUTINE\r
1846         return r;\r
1847 }\r
1848 \r
1849 int mkdirM(const char * _Path)\r
1850 {\r
1851         int r = 0;\r
1852         wchar_t* pw0 = NULL;\r
1853 START_ROUTINE\r
1854         pw0 = DuplicateMtoW(_Path, -1);\r
1855         r = _wmkdir(pw0);\r
1856 END_ROUTINE\r
1857         FreeDuplicatedString(pw0);\r
1858         return r;\r
1859 }\r
1860 \r
1861 int _mkdirM(const char * _Path)\r
1862 {\r
1863         int r = 0;\r
1864         wchar_t* pw0 = NULL;\r
1865 START_ROUTINE\r
1866         pw0 = DuplicateMtoW(_Path, -1);\r
1867         r = _wmkdir(pw0);\r
1868 END_ROUTINE\r
1869         FreeDuplicatedString(pw0);\r
1870         return r;\r
1871 }\r
1872 \r
1873 int rmdirM(const char * _Path)\r
1874 {\r
1875         int r = 0;\r
1876         wchar_t* pw0 = NULL;\r
1877 START_ROUTINE\r
1878         pw0 = DuplicateMtoW(_Path, -1);\r
1879         r = _wrmdir(pw0);\r
1880 END_ROUTINE\r
1881         FreeDuplicatedString(pw0);\r
1882         return r;\r
1883 }\r
1884 \r
1885 int _rmdirM(const char * _Path)\r
1886 {\r
1887         int r = 0;\r
1888         wchar_t* pw0 = NULL;\r
1889 START_ROUTINE\r
1890         pw0 = DuplicateMtoW(_Path, -1);\r
1891         r = _wrmdir(pw0);\r
1892 END_ROUTINE\r
1893         FreeDuplicatedString(pw0);\r
1894         return r;\r
1895 }\r
1896 \r
1897 size_t _mbslenM(const unsigned char * _Str)\r
1898 {\r
1899         size_t r = 0;\r
1900         wchar_t* pw0 = NULL;\r
1901 START_ROUTINE\r
1902         pw0 = DuplicateMtoW(_Str, -1);\r
1903         r = wcslen(pw0);\r
1904 END_ROUTINE\r
1905         FreeDuplicatedString(pw0);\r
1906         return r;\r
1907 }\r
1908 \r
1909 unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch)\r
1910 {\r
1911         unsigned char* r = NULL;\r
1912         wchar_t* pw0 = NULL;\r
1913         wchar_t* wr;\r
1914 START_ROUTINE\r
1915         pw0 = DuplicateMtoW(_Str, -1);\r
1916         // TODO: 非ASCII文字の対応\r
1917         wr = wcschr(pw0, _Ch);\r
1918         if(wr)\r
1919         {\r
1920                 *wr = L'\0';\r
1921                 r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1;\r
1922         }\r
1923 END_ROUTINE\r
1924         FreeDuplicatedString(pw0);\r
1925         return r;\r
1926 }\r
1927 \r
1928 unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch)\r
1929 {\r
1930         unsigned char* r = NULL;\r
1931         wchar_t* pw0 = NULL;\r
1932         wchar_t* wr;\r
1933 START_ROUTINE\r
1934         pw0 = DuplicateMtoW(_Str, -1);\r
1935         // TODO: 非ASCII文字の対応\r
1936         wr = wcsrchr(pw0, _Ch);\r
1937         if(wr)\r
1938         {\r
1939                 *wr = L'\0';\r
1940                 r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1;\r
1941         }\r
1942 END_ROUTINE\r
1943         FreeDuplicatedString(pw0);\r
1944         return r;\r
1945 }\r
1946 \r
1947 unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr)\r
1948 {\r
1949         unsigned char* r = NULL;\r
1950         wchar_t* pw0 = NULL;\r
1951         wchar_t* pw1 = NULL;\r
1952         wchar_t* wr;\r
1953 START_ROUTINE\r
1954         pw0 = DuplicateMtoW(_Str, -1);\r
1955         pw1 = DuplicateMtoW(_Substr, -1);\r
1956         wr = wcsstr(pw0, pw1);\r
1957         if(wr)\r
1958         {\r
1959                 *wr = L'\0';\r
1960                 r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1;\r
1961         }\r
1962 END_ROUTINE\r
1963         FreeDuplicatedString(pw0);\r
1964         FreeDuplicatedString(pw1);\r
1965         return r;\r
1966 }\r
1967 \r
1968 int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
1969 {\r
1970         int r = 0;\r
1971         wchar_t* pw0 = NULL;\r
1972         wchar_t* pw1 = NULL;\r
1973 START_ROUTINE\r
1974         pw0 = DuplicateMtoW(_Str1, -1);\r
1975         pw1 = DuplicateMtoW(_Str2, -1);\r
1976         r = wcscmp(pw0, pw1);\r
1977 END_ROUTINE\r
1978         FreeDuplicatedString(pw0);\r
1979         FreeDuplicatedString(pw1);\r
1980         return r;\r
1981 }\r
1982 \r
1983 int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
1984 {\r
1985         int r = 0;\r
1986         wchar_t* pw0 = NULL;\r
1987         wchar_t* pw1 = NULL;\r
1988 START_ROUTINE\r
1989         pw0 = DuplicateMtoW(_Str1, -1);\r
1990         pw1 = DuplicateMtoW(_Str2, -1);\r
1991         r = _wcsicmp(pw0, pw1);\r
1992 END_ROUTINE\r
1993         FreeDuplicatedString(pw0);\r
1994         FreeDuplicatedString(pw1);\r
1995         return r;\r
1996 }\r
1997 \r
1998 int _mbsncmpM(const unsigned char * _Str1, const unsigned char * _Str2, size_t _MaxCount)\r
1999 {\r
2000         int r = 0;\r
2001         wchar_t* pw0 = NULL;\r
2002         wchar_t* pw1 = NULL;\r
2003 START_ROUTINE\r
2004         pw0 = DuplicateMtoW(_Str1, -1);\r
2005         pw1 = DuplicateMtoW(_Str2, -1);\r
2006         r = wcsncmp(pw0, pw1, _MaxCount);\r
2007 END_ROUTINE\r
2008         FreeDuplicatedString(pw0);\r
2009         FreeDuplicatedString(pw1);\r
2010         return r;\r
2011 }\r
2012 \r
2013 unsigned char * _mbslwrM(unsigned char * _String)\r
2014 {\r
2015         unsigned char* r = NULL;\r
2016         wchar_t* pw0 = NULL;\r
2017 START_ROUTINE\r
2018         pw0 = DuplicateMtoW(_String, -1);\r
2019         _wcslwr(pw0);\r
2020         r = _String;\r
2021         WtoM(_String, strlen(_String) + 1, pw0, -1);\r
2022 END_ROUTINE\r
2023         FreeDuplicatedString(pw0);\r
2024         return r;\r
2025 }\r
2026 \r
2027 unsigned char * _mbsuprM(unsigned char * _String)\r
2028 {\r
2029         unsigned char* r = NULL;\r
2030         wchar_t* pw0 = NULL;\r
2031 START_ROUTINE\r
2032         pw0 = DuplicateMtoW(_String, -1);\r
2033         _wcsupr(pw0);\r
2034         r = _String;\r
2035         WtoM(_String, strlen(_String) + 1, pw0, -1);\r
2036 END_ROUTINE\r
2037         FreeDuplicatedString(pw0);\r
2038         return r;\r
2039 }\r
2040 \r
2041 unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count)\r
2042 {\r
2043         unsigned char* r = NULL;\r
2044         wchar_t* pw0 = NULL;\r
2045         wchar_t* wr;\r
2046 START_ROUTINE\r
2047         pw0 = DuplicateMtoW(_Str, -1);\r
2048         wr = _wcsninc(pw0, _Count);\r
2049         if(wr)\r
2050         {\r
2051                 *wr = L'\0';\r
2052                 r = (unsigned char*)_Str + WtoM(NULL, 0, pw0, -1) - 1;\r
2053         }\r
2054 END_ROUTINE\r
2055         FreeDuplicatedString(pw0);\r
2056         return r;\r
2057 }\r
2058 \r
2059 FILE * fopenM(const char * _Filename, const char * _Mode)\r
2060 {\r
2061         FILE* r = NULL;\r
2062         wchar_t* pw0 = NULL;\r
2063         wchar_t* pw1 = NULL;\r
2064 START_ROUTINE\r
2065         pw0 = DuplicateMtoW(_Filename, -1);\r
2066         pw1 = DuplicateMtoW(_Mode, -1);\r
2067         r = _wfopen(pw0, pw1);\r
2068 END_ROUTINE\r
2069         FreeDuplicatedString(pw0);\r
2070         FreeDuplicatedString(pw1);\r
2071         return r;\r
2072 }\r
2073 \r