OSDN Git Service

Fix bugs of automatic detection for Kanji code of filenames.
[ffftp/ffftp.git] / misc.c
1 /*=============================================================================\r
2 *\r
3 *                                                       その他の汎用サブルーチン\r
4 *\r
5 ===============================================================================\r
6 / Copyright (C) 1997-2007 Sota. All rights reserved.\r
7 /\r
8 / Redistribution and use in source and binary forms, with or without \r
9 / modification, are permitted provided that the following conditions \r
10 / are met:\r
11 /\r
12 /  1. Redistributions of source code must retain the above copyright \r
13 /     notice, this list of conditions and the following disclaimer.\r
14 /  2. Redistributions in binary form must reproduce the above copyright \r
15 /     notice, this list of conditions and the following disclaimer in the \r
16 /     documentation and/or other materials provided with the distribution.\r
17 /\r
18 / THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR \r
19 / IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES \r
20 / OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
21 / IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, \r
22 / INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
23 / BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
24 / USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
25 / ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
26 / (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF \r
27 / THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
28 /============================================================================*/\r
29 \r
30 #define STRICT\r
31 #include <stdio.h>\r
32 #include <stdlib.h>\r
33 #include <stdarg.h>\r
34 #include <string.h>\r
35 #include <mbstring.h>\r
36 #include <winsock.h>\r
37 #include <windowsx.h>\r
38 #include <commctrl.h>\r
39 #include <shlobj.h>\r
40 #include <locale.h>\r
41 \r
42 #include "common.h"\r
43 #include "resource.h"\r
44 \r
45 #include <htmlhelp.h>\r
46 #include "helpid.h"\r
47 \r
48 // UTF-8対応\r
49 #undef __MBSWRAPPER_H__\r
50 #include "mbswrapper.h"\r
51 \r
52 \r
53 \r
54 /*===== 入力ダイアログデータのストラクチャ =====*/\r
55 \r
56 typedef struct {\r
57         char Title[80];                 /* ダイアログのタイトル */\r
58         char Str[FMAX_PATH+1];  /* デフォルト文字列/入力された文字列(Output) */\r
59         int MaxLen;                             /* 文字列の最長 */\r
60         int Anonymous;                  /* Anonymousフラグ(Output) */\r
61 } DIALOGDATA;\r
62 \r
63 /*===== プロトタイプ =====*/\r
64 \r
65 static BOOL CALLBACK InputDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
66 \r
67 /*===== 外部参照 =====*/\r
68 \r
69 extern HWND hHelpWin;\r
70 \r
71 /*===== ローカルなワーク =====*/\r
72 \r
73 static DIALOGDATA *DialogData;          /* 入力ダイアログデータ */\r
74 static int HelpPage;\r
75 \r
76 \r
77 \r
78 /*----- 入力ダイアログを表示 --------------------------------------------------\r
79 *\r
80 *       Parameter\r
81 *               int Res : ダイアログボックスのID\r
82 *               HWND hWnd : 親ウインドウのウインドウハンドル\r
83 *               char *Title : ウインドウタイトル (NULL=設定しない)\r
84 *               char *Buf : エディットボックスの初期文字列/入力文字列を返すバッファ\r
85 *               int Max : バッファのサイズ (FMAX_PATH+1以下であること)\r
86 *               int *Flg : フラグの初期値/フラグを返すワーク\r
87 *               int Help : ヘルプのコンテキスト番号\r
88 *\r
89 *       Return Value\r
90 *               int ステータス (YES/NO=取り消し)\r
91 *\r
92 *       Note\r
93 *               ダイアログは1個のEditBoxと1個のButtonを持つものを使う\r
94 *----------------------------------------------------------------------------*/\r
95 \r
96 int InputDialogBox(int Res, HWND hWnd, char *Title, char *Buf, int Max, int *Flg, int Help)\r
97 {\r
98         int Ret;\r
99         DIALOGDATA dData;\r
100 \r
101         dData.MaxLen = Max;\r
102         memset(dData.Str, NUL, FMAX_PATH+1);\r
103         strncpy(dData.Str, Buf, FMAX_PATH);\r
104         strcpy(dData.Title, "");\r
105         if(Title != NULL)\r
106                 strcpy(dData.Title, Title);\r
107         dData.Anonymous = *Flg;\r
108         DialogData = &dData;\r
109         HelpPage = Help;\r
110 \r
111         Ret = DialogBox(GetFtpInst(), MAKEINTRESOURCE(Res), hWnd, InputDialogCallBack);\r
112 \r
113         if(Ret == YES)\r
114         {\r
115                 memset(Buf, NUL, Max);\r
116                 strncpy(Buf, dData.Str, Max-1);\r
117                 *Flg = dData.Anonymous;\r
118         }\r
119         return(Ret);\r
120 }\r
121 \r
122 \r
123 /*----- 入力ダイアログのコールバック ------------------------------------------\r
124 *\r
125 *       Parameter\r
126 *               HWND hDlg : ウインドウハンドル\r
127 *               UINT message : メッセージ番号\r
128 *               WPARAM wParam : メッセージの WPARAM 引数\r
129 *               LPARAM lParam : メッセージの LPARAM 引数\r
130 *\r
131 *       Return Value\r
132 *               BOOL TRUE/FALSE\r
133 *----------------------------------------------------------------------------*/\r
134 \r
135 static BOOL CALLBACK InputDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
136 {\r
137         char Tmp[FMAX_PATH+1];\r
138 \r
139         switch (iMessage)\r
140         {\r
141                 case WM_INITDIALOG :\r
142                         if(strlen(DialogData->Title) != 0)\r
143                                 SendMessage(hDlg, WM_SETTEXT, 0, (LPARAM)DialogData->Title);\r
144                         SendDlgItemMessage(hDlg, INP_INPSTR, EM_LIMITTEXT, DialogData->MaxLen-1, 0);\r
145                         SendDlgItemMessage(hDlg, INP_INPSTR, WM_SETTEXT, 0, (LPARAM)DialogData->Str);\r
146                         SendDlgItemMessage(hDlg, INP_ANONYMOUS, BM_SETCHECK, DialogData->Anonymous, 0);\r
147                         return(TRUE);\r
148 \r
149                 case WM_COMMAND :\r
150                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
151                         {\r
152                                 case IDOK :\r
153                                         SendDlgItemMessage(hDlg, INP_INPSTR, WM_GETTEXT, DialogData->MaxLen, (LPARAM)DialogData->Str);\r
154                                         DialogData->Anonymous = SendDlgItemMessage(hDlg, INP_ANONYMOUS, BM_GETCHECK, 0, 0);\r
155                                         EndDialog(hDlg, YES);\r
156                                         break;\r
157 \r
158                                 case IDCANCEL :\r
159                                         EndDialog(hDlg, NO);\r
160                                         break;\r
161 \r
162                                 case IDHELP :\r
163                                         hHelpWin = HtmlHelp(NULL, AskHelpFilePath(), HH_HELP_CONTEXT, HelpPage);\r
164                                         break;\r
165 \r
166                                 case INP_BROWSE :\r
167                                         if(SelectDir(hDlg, Tmp, FMAX_PATH) == TRUE)\r
168                                                 SendDlgItemMessage(hDlg, INP_INPSTR, WM_SETTEXT, 0, (LPARAM)Tmp);\r
169                                         break;\r
170                         }\r
171             return(TRUE);\r
172         }\r
173         return(FALSE);\r
174 }\r
175 \r
176 \r
177 /*----- [実行]と[取消]だけのダイアログの共通コールバック関数 --------------\r
178 *\r
179 *       Parameter\r
180 *               HWND hDlg : ウインドウハンドル\r
181 *               UINT message : メッセージ番号\r
182 *               WPARAM wParam : メッセージの WPARAM 引数\r
183 *               LPARAM lParam : メッセージの LPARAM 引数\r
184 *\r
185 *       Return Value\r
186 *               BOOL TRUE/FALSE\r
187 *----------------------------------------------------------------------------*/\r
188 \r
189 BOOL CALLBACK ExeEscDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
190 {\r
191         switch (message)\r
192         {\r
193                 case WM_INITDIALOG :\r
194                         return(TRUE);\r
195 \r
196                 case WM_COMMAND :\r
197                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
198                         {\r
199                                 case IDOK :\r
200                                         EndDialog(hDlg, YES);\r
201                                         break;\r
202 \r
203                                 case IDCANCEL :\r
204                                         EndDialog(hDlg, NO);\r
205                                         break;\r
206                         }\r
207                         return(TRUE);\r
208         }\r
209     return(FALSE);\r
210 }\r
211 \r
212 \r
213 /*----- [実行]と[取消]だけのダイアログの共通コールバック関数(テキスト表示つき)\r
214 *\r
215 *       Parameter\r
216 *               HWND hDlg : ウインドウハンドル\r
217 *               UINT message : メッセージ番号\r
218 *               WPARAM wParam : メッセージの WPARAM 引数\r
219 *               LPARAM lParam : メッセージの LPARAM 引数\r
220 *\r
221 *       Return Value\r
222 *               BOOL TRUE/FALSE\r
223 *----------------------------------------------------------------------------*/\r
224 \r
225 BOOL CALLBACK ExeEscTextDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
226 {\r
227         switch (message)\r
228         {\r
229                 case WM_INITDIALOG :\r
230                         SendDlgItemMessage(hDlg, COMMON_TEXT, WM_SETTEXT, 0, lParam);\r
231                         return(TRUE);\r
232 \r
233                 case WM_COMMAND :\r
234                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
235                         {\r
236                                 case IDOK :\r
237                                         EndDialog(hDlg, YES);\r
238                                         break;\r
239 \r
240                                 case IDCANCEL :\r
241                                         EndDialog(hDlg, NO);\r
242                                         break;\r
243                         }\r
244                         return(TRUE);\r
245         }\r
246     return(FALSE);\r
247 }\r
248 \r
249 \r
250 /*----- 文字列の最後に "\" を付ける -------------------------------------------\r
251 *\r
252 *       Parameter\r
253 *               char *Str : 文字列\r
254 *\r
255 *       Return Value\r
256 *               なし\r
257 *\r
258 *       Note\r
259 *               オリジナルの文字列 char *Str が変更されます。\r
260 *----------------------------------------------------------------------------*/\r
261 \r
262 void SetYenTail(char *Str)\r
263 {\r
264         if(_mbscmp(_mbsninc(Str, _mbslen(Str) - 1), "\\") != 0)\r
265                 strcat(Str, "\\");\r
266 \r
267         return;;\r
268 }\r
269 \r
270 \r
271 /*----- 文字列の最後の "\" を取り除く -----------------------------------------\r
272 *\r
273 *       Parameter\r
274 *               char *Str : 文字列\r
275 *\r
276 *       Return Value\r
277 *               なし\r
278 *\r
279 *       Note\r
280 *               オリジナルの文字列 char *Str が変更されます。\r
281 *----------------------------------------------------------------------------*/\r
282 \r
283 void RemoveYenTail(char *Str)\r
284 {\r
285         char *Pos;\r
286 \r
287         if(strlen(Str) > 0)\r
288         {\r
289                 Pos = _mbsninc(Str, _mbslen(Str) - 1);\r
290                 if(_mbscmp(Pos, "\\") == 0)\r
291                         *Pos = NUL;\r
292         }\r
293         return;;\r
294 }\r
295 \r
296 \r
297 /*----- 文字列の最後に "/" を付ける -------------------------------------------\r
298 *\r
299 *       Parameter\r
300 *               char *Str : 文字列\r
301 *\r
302 *       Return Value\r
303 *               なし\r
304 *\r
305 *       Note\r
306 *               オリジナルの文字列 char *Str が変更されます。\r
307 *----------------------------------------------------------------------------*/\r
308 \r
309 void SetSlashTail(char *Str)\r
310 {\r
311         if(_mbscmp(_mbsninc(Str, _mbslen(Str) - 1), "/") != 0)\r
312                 strcat(Str, "/");\r
313 \r
314         return;\r
315 }\r
316 \r
317 \r
318 /*----- 文字列から改行コードを取り除く ----------------------------------------\r
319 *\r
320 *       Parameter\r
321 *               char *Str : 文字列\r
322 *\r
323 *       Return Value\r
324 *               なし\r
325 *\r
326 *       Note\r
327 *               オリジナルの文字列 char *Str が変更されます。\r
328 *----------------------------------------------------------------------------*/\r
329 \r
330 void RemoveReturnCode(char *Str)\r
331 {\r
332         char *Pos;\r
333 \r
334         if((Pos = strchr(Str, 0x0D)) != NULL)\r
335                 *Pos = NUL;\r
336         if((Pos = strchr(Str, 0x0A)) != NULL)\r
337                 *Pos = NUL;\r
338         return;\r
339 }\r
340 \r
341 \r
342 /*----- 文字列内の特定の文字を全て置き換える ----------------------------------\r
343 *\r
344 *       Parameter\r
345 *               char *Str : 文字列\r
346 *               char Src : 検索文字\r
347 *               char Dst : 置換文字\r
348 *\r
349 *       Return Value\r
350 *               なし\r
351 *----------------------------------------------------------------------------*/\r
352 \r
353 void ReplaceAll(char *Str, char Src, char Dst)\r
354 {\r
355         char *Pos;\r
356 \r
357         while((Pos = _mbschr(Str, Src)) != NULL)\r
358                 *Pos = Dst;\r
359         return;\r
360 }\r
361 \r
362 \r
363 /*----- 数字もしくは特定の1文字かチェック ------------------------------------\r
364 *\r
365 *       Parameter\r
366 *               int Ch : チェックする文字\r
367 *               int Sym : 記号\r
368 *\r
369 *       Return Value\r
370 *               int ステータス\r
371 *                       0=数字でも特定の記号でもない\r
372 *----------------------------------------------------------------------------*/\r
373 \r
374 int IsDigitSym(int Ch, int Sym)\r
375 {\r
376         int Ret;\r
377 \r
378         if((Ret = IsDigit(Ch)) == 0)\r
379         {\r
380                 if((Sym != NUL) && (Sym == Ch))\r
381                         Ret = 1;\r
382         }\r
383         return(Ret);\r
384 }\r
385 \r
386 \r
387 /*----- 文字列が全て同じ文字かチェック ----------------------------------------\r
388 *\r
389 *       Parameter\r
390 *               char *Str : 文字列\r
391 *               int Ch : 文字\r
392 *\r
393 *       Return Value\r
394 *               int ステータス\r
395 *                       YES/NO\r
396 *----------------------------------------------------------------------------*/\r
397 \r
398 int StrAllSameChar(char *Str, char Ch)\r
399 {\r
400         int Ret;\r
401 \r
402         Ret = YES;\r
403         while(*Str != NUL)\r
404         {\r
405                 if(*Str != Ch)\r
406                 {\r
407                         Ret = NO;\r
408                         break;\r
409                 }\r
410                 Str++;\r
411         }\r
412         return(Ret);\r
413 }\r
414 \r
415 \r
416 /*----- 文字列の末尾のスペースを削除 ------------------------------------------\r
417 *\r
418 *       Parameter\r
419 *               char *Str : 文字列\r
420 *\r
421 *       Return Value\r
422 *               なし\r
423 *----------------------------------------------------------------------------*/\r
424 \r
425 void RemoveTailingSpaces(char *Str)\r
426 {\r
427         char *Pos;\r
428 \r
429         Pos = Str + strlen(Str);\r
430         while(--Pos > Str)\r
431         {\r
432                 if(*Pos != ' ')\r
433                         break;\r
434                 *Pos = NUL;\r
435         }\r
436         return;\r
437 }\r
438 \r
439 \r
440 /*----- 大文字/小文字を区別しないstrstr --------------------------------------\r
441 *\r
442 *       Parameter\r
443 *               char *s1 : 文字列1\r
444 *               char *s2 : 文字列2\r
445 *\r
446 *       Return Value\r
447 *               char *文字列1中で文字列2が見つかった位置\r
448 *                       NULL=見つからなかった\r
449 *----------------------------------------------------------------------------*/\r
450 \r
451 char *stristr(char *s1, char *s2)\r
452 {\r
453         char *Ret;\r
454 \r
455         Ret = NULL;\r
456         while(*s1 != NUL)\r
457         {\r
458                 if((tolower(*s1) == tolower(*s2)) &&\r
459                    (_strnicmp(s1, s2, strlen(s2)) == 0))\r
460                 {\r
461                         Ret = s1;\r
462                         break;\r
463                 }\r
464                 s1++;\r
465         }\r
466         return(Ret);\r
467 }\r
468 \r
469 \r
470 /*----- 文字列中のスペースで区切られた次のフィールドを返す --------------------\r
471 *\r
472 *       Parameter\r
473 *               char *Str : 文字列\r
474 *\r
475 *       Return Value\r
476 *               char *次のフィールド\r
477 *                       NULL=見つからなかった\r
478 *----------------------------------------------------------------------------*/\r
479 \r
480 char *GetNextField(char *Str)\r
481 {\r
482         if((Str = strchr(Str, ' ')) != NULL)\r
483         {\r
484                 while(*Str == ' ')\r
485                 {\r
486                         if(*Str == NUL)\r
487                         {\r
488                                 Str = NULL;\r
489                                 break;\r
490                         }\r
491                         Str++;\r
492                 }\r
493         }\r
494         return(Str);\r
495 }\r
496 \r
497 \r
498 /*----- 現在のフィールドの文字列をコピーする ----------------------------------\r
499 *\r
500 *       Parameter\r
501 *               char *Str : 文字列\r
502 *               char *Buf : コピー先\r
503 *               int Max : 最大文字数\r
504 *\r
505 *       Return Value\r
506 *               int ステータス\r
507 *                       FFFTP_SUCCESS/FFFTP_FAIL=長さが長すぎる\r
508 *----------------------------------------------------------------------------*/\r
509 \r
510 int GetOneField(char *Str, char *Buf, int Max)\r
511 {\r
512         int Sts;\r
513         char *Pos;\r
514 \r
515         Sts = FFFTP_FAIL;\r
516         if((Pos = strchr(Str, ' ')) == NULL)\r
517         {\r
518                 if((int)strlen(Str) <= Max)\r
519                 {\r
520                         strcpy(Buf, Str);\r
521                         Sts = FFFTP_SUCCESS;\r
522                 }\r
523         }\r
524         else\r
525         {\r
526                 if(Pos - Str <= Max)\r
527                 {\r
528                         strncpy(Buf, Str, Pos - Str);\r
529                         *(Buf + (Pos - Str)) = NUL;\r
530                         Sts = FFFTP_SUCCESS;\r
531                 }\r
532         }\r
533         return(Sts);\r
534 }\r
535 \r
536 \r
537 /*----- カンマを取り除く ------------------------------------------------------\r
538 *\r
539 *       Parameter\r
540 *               char *Str : 文字列\r
541 *\r
542 *       Return Value\r
543 *               なし\r
544 *----------------------------------------------------------------------------*/\r
545 \r
546 void RemoveComma(char *Str)\r
547 {\r
548         char *Put;\r
549 \r
550         Put = Str;\r
551         while(*Str != NUL)\r
552         {\r
553                 if(*Str != ',')\r
554                 {\r
555                         *Put = *Str;\r
556                         Put++;\r
557                 }\r
558                 Str++;\r
559         }\r
560         *Put = NUL;\r
561         return;\r
562 }\r
563 \r
564 \r
565 /*----- パス名の中のファイル名の先頭を返す ------------------------------------\r
566 *\r
567 *       Parameter\r
568 *               char *Path : パス名\r
569 *\r
570 *       Return Value\r
571 *               char *ファイル名の先頭\r
572 *\r
573 *       Note\r
574 *               ディレクトリの区切り記号は "\" と "/" の両方が有効\r
575 *----------------------------------------------------------------------------*/\r
576 \r
577 char *GetFileName(char *Path)\r
578 {\r
579         char *Pos;\r
580 \r
581         if((Pos = _mbschr(Path, ':')) != NULL)\r
582                 Path = Pos + 1;\r
583 \r
584         if((Pos = _mbsrchr(Path, '\\')) != NULL)\r
585                 Path = Pos + 1;\r
586 \r
587         if((Pos = _mbsrchr(Path, '/')) != NULL)\r
588                 Path = Pos + 1;\r
589 \r
590         return(Path);\r
591 }\r
592 \r
593 \r
594 /*----- ツールの表示名を返す --------------------------------------------------\r
595 *\r
596 *       Parameter\r
597 *               char *Path : パス名\r
598 *\r
599 *       Return Value\r
600 *               char * : 表示名\r
601 *----------------------------------------------------------------------------*/\r
602 \r
603 char *GetToolName(char *Path)\r
604 {\r
605         char *Pos;\r
606 \r
607         if((Pos = _mbschr(Path, ':')) != NULL)\r
608                 Path = Pos + 1;\r
609 \r
610         if((Pos = _mbsrchr(Path, '\\')) != NULL)\r
611                 Path = Pos + 1;\r
612 \r
613         return(Path);\r
614 }\r
615 \r
616 \r
617 /*----- パス名の中の拡張子の先頭を返す ----------------------------------------\r
618 *\r
619 *       Parameter\r
620 *               char *Path : パス名\r
621 *\r
622 *       Return Value\r
623 *               char *拡張子の先頭\r
624 *----------------------------------------------------------------------------*/\r
625 \r
626 char *GetFileExt(char *Path)\r
627 {\r
628         char *Ret;\r
629 \r
630         Ret = _mbschr(Path, NUL);\r
631         if((_mbscmp(Path, ".") != 0) &&\r
632            (_mbscmp(Path, "..") != 0))\r
633         {\r
634                 while((Path = _mbschr(Path, '.')) != NULL)\r
635                 {\r
636                         Path++;\r
637                         Ret = Path;\r
638                 }\r
639         }\r
640         return(Ret);\r
641 }\r
642 \r
643 \r
644 /*----- パス名からファイル名を取り除く ----------------------------------------\r
645 *\r
646 *       Parameter\r
647 *               char *Path : パス名\r
648 *               char *Buf : ファイル名を除いたパス名のコピー先\r
649 *\r
650 *       Return Value\r
651 *               なし\r
652 *\r
653 *       Note\r
654 *               ディレクトリの区切り記号は "\" と "/" の両方が有効\r
655 *----------------------------------------------------------------------------*/\r
656 \r
657 void RemoveFileName(char *Path, char *Buf)\r
658 {\r
659         char *Pos;\r
660 \r
661         strcpy(Buf, Path);\r
662 \r
663         if((Pos = _mbsrchr(Buf, '/')) != NULL)\r
664                 *Pos = NUL;\r
665         else if((Pos = _mbsrchr(Buf, '\\')) != NULL)\r
666         {\r
667                 if((Pos == Buf) || \r
668                    ((Pos != Buf) && (*(Pos - 1) != ':')))\r
669                         *Pos = NUL;\r
670         }\r
671         return;\r
672 }\r
673 \r
674 \r
675 /*----- 上位ディレクトリのパス名を取得 ----------------------------------------\r
676 *\r
677 *       Parameter\r
678 *               char *Path : パス名\r
679 *\r
680 *       Return Value\r
681 *               なし\r
682 *\r
683 *       Note\r
684 *               ディレクトリの区切り記号は "\" と "/" の両方が有効\r
685 *               最初の "\"や"/"は残す\r
686 *                       例) "/pub"   --> "/"\r
687 *                       例) "C:\DOS" --> "C:\"\r
688 *----------------------------------------------------------------------------*/\r
689 \r
690 void GetUpperDir(char *Path)\r
691 {\r
692         char *Top;\r
693         char *Pos;\r
694 \r
695         if(((Top = _mbschr(Path, '/')) != NULL) ||\r
696            ((Top = _mbschr(Path, '\\')) != NULL))\r
697         {\r
698                 Top++;\r
699                 if(((Pos = _mbsrchr(Top, '/')) != NULL) ||\r
700                    ((Pos = _mbsrchr(Top, '\\')) != NULL))\r
701                         *Pos = NUL;\r
702                 else\r
703                         *Top = NUL;\r
704         }\r
705         return;\r
706 }\r
707 \r
708 \r
709 /*----- 上位ディレクトリのパス名を取得 ----------------------------------------\r
710 *\r
711 *       Parameter\r
712 *               char *Path : パス名\r
713 *\r
714 *       Return Value\r
715 *               なし\r
716 *\r
717 *       Note\r
718 *               ディレクトリの区切り記号は "\" と "/" の両方が有効\r
719 *               最初の "\"や"/"も消す\r
720 *                       例) "/pub"   --> ""\r
721 *                       例) "C:\DOS" --> "C:"\r
722 *----------------------------------------------------------------------------*/\r
723 \r
724 void GetUpperDirEraseTopSlash(char *Path)\r
725 {\r
726         char *Pos;\r
727 \r
728         if(((Pos = _mbsrchr(Path, '/')) != NULL) ||\r
729            ((Pos = _mbsrchr(Path, '\\')) != NULL))\r
730                 *Pos = NUL;\r
731         else\r
732                 *Path = NUL;\r
733 \r
734         return;\r
735 }\r
736 \r
737 \r
738 /*----- ディレクトリの階層数を返す --------------------------------------------\r
739 *\r
740 *       Parameter\r
741 *               char *Path : パス名\r
742 *\r
743 *       Return Value\r
744 *               なし\r
745 *\r
746 *       Note\r
747 *               単に '\' と '/'の数を返すだけ\r
748 *----------------------------------------------------------------------------*/\r
749 \r
750 int AskDirLevel(char *Path)\r
751 {\r
752         char *Pos;\r
753         int Level;\r
754 \r
755         Level = 0;\r
756         while(((Pos = _mbschr(Path, '/')) != NULL) ||\r
757                   ((Pos = _mbschr(Path, '\\')) != NULL))\r
758         {\r
759                 Path = Pos + 1;\r
760                 Level++;\r
761         }\r
762         return(Level);\r
763 }\r
764 \r
765 \r
766 /*----- ファイルサイズを文字列に変換する --------------------------------------\r
767 *\r
768 *       Parameter\r
769 *               double Size : ファイルサイズ\r
770 *               char *Buf : 文字列を返すバッファ\r
771 *\r
772 *       Return Value\r
773 *               なし\r
774 *----------------------------------------------------------------------------*/\r
775 \r
776 void MakeSizeString(double Size, char *Buf)\r
777 {\r
778         if(Size >= (1024*1024))\r
779         {\r
780                 Size /= (1024*1024);\r
781                 sprintf(Buf, "%.2fM Bytes", Size);\r
782         }\r
783         else if (Size >= 1024)\r
784         {\r
785                 Size /= 1024;\r
786                 sprintf(Buf, "%.2fK Bytes", Size);\r
787         }\r
788         else\r
789                 sprintf(Buf, "%.0f Bytes", Size);\r
790 \r
791         return;\r
792 }\r
793 \r
794 \r
795 /*----- StaticTextの領域に収まるようにパス名を整形して表示 --------------------\r
796 *\r
797 *       Parameter\r
798 *               HWND hWnd : ウインドウハンドル\r
799 *               char *Str : 文字列 (長さはFMAX_PATH以下)\r
800 *\r
801 *       Return Value\r
802 *               なし\r
803 *----------------------------------------------------------------------------*/\r
804 \r
805 void DispStaticText(HWND hWnd, char *Str)\r
806 {\r
807         char Buf[FMAX_PATH+1];\r
808         char *Pos;\r
809         char *Tmp;\r
810         RECT Rect;\r
811         SIZE fSize;\r
812         HDC hDC;\r
813         int Force;\r
814 \r
815         GetClientRect(hWnd, &Rect);\r
816         Rect.right -= Rect.left;\r
817 \r
818         hDC = GetDC(hWnd);\r
819         strcpy(Buf, Str);\r
820         Pos = Buf;\r
821         Force = NO;\r
822         while(Force == NO)\r
823         {\r
824                 GetTextExtentPoint32(hDC, Pos, strlen(Pos), &fSize);\r
825 \r
826                 if(fSize.cx <= Rect.right)\r
827                         break;\r
828 \r
829                 if(_mbslen(Pos) <= 4)\r
830                         Force = YES;\r
831                 else\r
832                 {\r
833                         Pos = _mbsninc(Pos, 4);\r
834                         if((Tmp = _mbschr(Pos, '\\')) == NULL)\r
835                                 Tmp = _mbschr(Pos, '/');\r
836 \r
837                         if(Tmp == NULL)\r
838                                 Tmp = _mbsninc(Pos, 4);\r
839 \r
840                         Pos = Tmp - 3;\r
841                         memset(Pos, '.', 3);\r
842                 }\r
843         }\r
844         ReleaseDC(hWnd, hDC);\r
845 \r
846         SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)Pos);\r
847         return;\r
848 }\r
849 \r
850 \r
851 /*----- 文字列アレイの長さを求める --------------------------------------------\r
852 *\r
853 *       Parameter\r
854 *               char *Str : 文字列アレイ (末尾はNUL2つ)\r
855 *\r
856 *       Return Value\r
857 *               int 長さ\r
858 *\r
859 *       Note\r
860 *               終端の2つのNULのうちの最後の物は数えない\r
861 *                       StrMultiLen("") = 0\r
862 *                       StrMultiLen("abc\0xyz\0") = 8\r
863 *                       StrMultiLen("abc") = 終端が2つのNULでないので求められない\r
864 *----------------------------------------------------------------------------*/\r
865 \r
866 int StrMultiLen(char *Str)\r
867 {\r
868         int Len;\r
869         int Tmp;\r
870 \r
871         Len = 0;\r
872         while(*Str != NUL)\r
873         {\r
874                 Tmp = strlen(Str) + 1;\r
875                 Str += Tmp;\r
876                 Len += Tmp;\r
877         }\r
878         return(Len);\r
879 }\r
880 \r
881 \r
882 /*----- RECTをクライアント座標からスクリーン座標に変換 ------------------------\r
883 *\r
884 *       Parameter\r
885 *               HWND hWnd : ウインドウハンドル\r
886 *               RECT *Rect : RECT\r
887 *\r
888 *       Return Value\r
889 *               なし\r
890 *----------------------------------------------------------------------------*/\r
891 \r
892 void RectClientToScreen(HWND hWnd, RECT *Rect)\r
893 {\r
894         POINT Tmp;\r
895 \r
896         Tmp.x = Rect->left;\r
897         Tmp.y = Rect->top;\r
898         ClientToScreen(hWnd, &Tmp);\r
899         Rect->left = Tmp.x;\r
900         Rect->top = Tmp.y;\r
901 \r
902         Tmp.x = Rect->right;\r
903         Tmp.y = Rect->bottom;\r
904         ClientToScreen(hWnd, &Tmp);\r
905         Rect->right = Tmp.x;\r
906         Rect->bottom = Tmp.y;\r
907 \r
908         return;\r
909 }\r
910 \r
911 \r
912 /*----- 16進文字をバイナリに変換 ----------------------------------------------\r
913 *\r
914 *       Parameter\r
915 *               char Ch : 16進文字\r
916 *\r
917 *       Return Value\r
918 *               int バイナリ値\r
919 *----------------------------------------------------------------------------*/\r
920 \r
921 int hex2bin(char Ch)\r
922 {\r
923         int Ret;\r
924 \r
925         if((Ch >= '0') && (Ch <= '9'))\r
926                 Ret = Ch - '0';\r
927         else if((Ch >= 'A') && (Ch <= 'F'))\r
928                 Ret = Ch - 'A' + 10;\r
929         else if((Ch >= 'a') && (Ch <= 'f'))\r
930                 Ret = Ch - 'a' + 10;\r
931 \r
932         return(Ret);\r
933 }\r
934 \r
935 \r
936 /*----- UNC文字列を分解する ------------------------------------------------\r
937 *\r
938 *       Parameter\r
939 *               char *unc : UNC文字列\r
940 *               char *Host : ホスト名をコピーするバッファ (サイズは HOST_ADRS_LEN+1)\r
941 *               char *Path : パス名をコピーするバッファ (サイズは FMAX_PATH+1)\r
942 *               char *File : ファイル名をコピーするバッファ (サイズは FMAX_PATH+1)\r
943 *               char *User : ユーザ名をコピーするバッファ (サイズは USER_NAME_LEN+1)\r
944 *               char *Pass : パスワードをコピーするバッファ (サイズは PASSWORD_LEN+1)\r
945 *               int *Port : ポート番号をコピーするバッファ\r
946 *\r
947 *       Return Value\r
948 *               int ステータス\r
949 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
950 *\r
951 *       "\"は全て"/"に置き換える\r
952 *----------------------------------------------------------------------------*/\r
953 \r
954 int SplitUNCpath(char *unc, char *Host, char *Path, char *File, char *User, char *Pass, int *Port)\r
955 {\r
956         int Sts;\r
957         char *Pos1;\r
958         char *Pos2;\r
959         char Tmp[FMAX_PATH+1];\r
960 \r
961         memset(Host, NUL, HOST_ADRS_LEN+1);\r
962         memset(Path, NUL, FMAX_PATH+1);\r
963         memset(File, NUL, FMAX_PATH+1);\r
964         memset(User, NUL, USER_NAME_LEN+1);\r
965         memset(Pass, NUL, PASSWORD_LEN+1);\r
966         *Port = PORT_NOR;\r
967 \r
968         ReplaceAll(unc, '\\', '/');\r
969 \r
970         if((Pos1 = _mbsstr(unc, "//")) != NULL)\r
971                 Pos1 += 2;\r
972         else\r
973                 Pos1 = unc;\r
974 \r
975         if((Pos2 = _mbschr(Pos1, '@')) != NULL)\r
976         {\r
977                 memset(Tmp, NUL, FMAX_PATH+1);\r
978                 memcpy(Tmp, Pos1, Pos2-Pos1);\r
979                 Pos1 = Pos2 + 1;\r
980 \r
981                 if((Pos2 = _mbschr(Tmp, ':')) != NULL)\r
982                 {\r
983                         memcpy(User, Tmp, min1(Pos2-Tmp, USER_NAME_LEN));\r
984                         strncpy(Pass, Pos2+1, PASSWORD_LEN);\r
985                 }\r
986                 else\r
987                         strncpy(User, Tmp, USER_NAME_LEN);\r
988         }\r
989 \r
990         if((Pos2 = _mbschr(Pos1, ':')) != NULL)\r
991         {\r
992                 memcpy(Host, Pos1, min1(Pos2-Pos1, HOST_ADRS_LEN));\r
993                 Pos2++;\r
994                 if(IsDigit(*Pos2))\r
995                 {\r
996                         *Port = atoi(Pos2);\r
997                         while(*Pos2 != NUL)\r
998                         {\r
999                                 if(IsDigit(*Pos2) == 0)\r
1000                                         break;\r
1001                                 Pos2++;\r
1002                         }\r
1003                 }\r
1004                 RemoveFileName(Pos2, Path);\r
1005                 strncpy(File, GetFileName(Pos2), FMAX_PATH);\r
1006         }\r
1007         else if((Pos2 = _mbschr(Pos1, '/')) != NULL)\r
1008         {\r
1009                 memcpy(Host, Pos1, min1(Pos2-Pos1, HOST_ADRS_LEN));\r
1010                 RemoveFileName(Pos2, Path);\r
1011                 strncpy(File, GetFileName(Pos2), FMAX_PATH);\r
1012         }\r
1013         else\r
1014         {\r
1015                 strncpy(Host, Pos1, HOST_ADRS_LEN);\r
1016         }\r
1017 \r
1018         Sts = FFFTP_FAIL;\r
1019         if(strlen(Host) > 0)\r
1020                 Sts = FFFTP_SUCCESS;\r
1021 \r
1022         return(Sts);\r
1023 }\r
1024 \r
1025 \r
1026 /*----- 日付文字列(JST)をFILETIME(UTC)に変換 ----------------------------------\r
1027 *\r
1028 *       Parameter\r
1029 *               char *Time : 日付文字列 ("yyyy/mm/dd hh:mm")\r
1030 *               FILETIME *Buf : ファイルタイムを返すワーク\r
1031 *\r
1032 *       Return Value\r
1033 *               int ステータス\r
1034 *                       YES/NO=日付情報がなかった\r
1035 *----------------------------------------------------------------------------*/\r
1036 \r
1037 int TimeString2FileTime(char *Time, FILETIME *Buf)\r
1038 {\r
1039         SYSTEMTIME sTime;\r
1040         FILETIME fTime;\r
1041         int Ret;\r
1042 \r
1043         Ret = NO;\r
1044     Buf->dwLowDateTime = 0;\r
1045     Buf->dwHighDateTime = 0;\r
1046 \r
1047         if(strlen(Time) >= 16)\r
1048         {\r
1049                 if(IsDigit(Time[0]) && IsDigit(Time[5]) && IsDigit(Time[8]) && \r
1050                    IsDigit(Time[12]) && IsDigit(Time[14]))\r
1051                 {\r
1052                         Ret = YES;\r
1053                 }\r
1054 \r
1055                 sTime.wYear = atoi(Time);\r
1056                 sTime.wMonth = atoi(Time + 5);\r
1057                 sTime.wDay = atoi(Time + 8);\r
1058                 if(Time[11] != ' ')\r
1059                         sTime.wHour = atoi(Time + 11);\r
1060                 else\r
1061                         sTime.wHour = atoi(Time + 12);\r
1062                 sTime.wMinute = atoi(Time + 14);\r
1063                 sTime.wSecond = 0;\r
1064                 sTime.wMilliseconds = 0;\r
1065 \r
1066                 SystemTimeToFileTime(&sTime, &fTime);\r
1067                 LocalFileTimeToFileTime(&fTime, Buf);\r
1068         }\r
1069         return(Ret);\r
1070 }\r
1071 \r
1072 \r
1073 /*----- FILETIME(UTC)を日付文字列(JST)に変換 ----------------------------------\r
1074 *\r
1075 *       Parameter\r
1076 *               FILETIME *Time : ファイルタイム\r
1077 *               char *Buf : 日付文字列を返すワーク\r
1078 *               int Mode : モード (DISPFORM_xxx)\r
1079 *               int InfoExist : 情報があるかどうか (FINFO_xxx)\r
1080 *\r
1081 *       Return Value\r
1082 *               なし\r
1083 *----------------------------------------------------------------------------*/\r
1084 \r
1085 void FileTime2TimeString(FILETIME *Time, char *Buf, int Mode, int InfoExist)\r
1086 {\r
1087         SYSTEMTIME sTime;\r
1088         FILETIME fTime;\r
1089 \r
1090         if(Mode == DISPFORM_LEGACY)\r
1091         {\r
1092                 if((Time->dwLowDateTime == 0) && (Time->dwHighDateTime == 0))\r
1093                         InfoExist = 0;\r
1094 \r
1095                 /* "yyyy/mm/dd hh:mm" */\r
1096                 FileTimeToLocalFileTime(Time, &fTime);\r
1097                 FileTimeToSystemTime(&fTime, &sTime);\r
1098 \r
1099                 if(InfoExist & FINFO_DATE)\r
1100                         sprintf(Buf, "%04d/%02d/%02d ", sTime.wYear, sTime.wMonth, sTime.wDay);\r
1101                 else\r
1102                         sprintf(Buf, "           ");\r
1103 \r
1104                 if(InfoExist & FINFO_TIME)\r
1105                         sprintf(Buf+11, "%2d:%02d", sTime.wHour, sTime.wMinute);\r
1106                 else\r
1107                         sprintf(Buf+11, "     ");\r
1108         }\r
1109         else\r
1110         {\r
1111 //              if (!strftime((char *)str, 100, "%c",  (const struct tm *)thetime))\r
1112 //                      SetTaskMsg("strftime が失敗しました!\n");\r
1113         }\r
1114         return;\r
1115 }\r
1116 \r
1117 \r
1118 /*----- ファイルタイムを指定タイムゾーンのローカルタイムからGMTに変換 ---------\r
1119 *\r
1120 *       Parameter\r
1121 *               FILETIME *Time : ファイルタイム\r
1122 *               int TimeZone : タイムゾーン\r
1123 *\r
1124 *       Return Value\r
1125 *               なし\r
1126 *----------------------------------------------------------------------------*/\r
1127 \r
1128 void SpecificLocalFileTime2FileTime(FILETIME *Time, int TimeZone)\r
1129 {\r
1130         unsigned __int64 Tmp64;\r
1131 \r
1132         Tmp64 = (unsigned __int64)Time->dwLowDateTime +\r
1133                         ((unsigned __int64)Time->dwHighDateTime << 32);\r
1134 \r
1135         Tmp64 -= (__int64)TimeZone * (__int64)36000000000;\r
1136 \r
1137         Time->dwHighDateTime = (DWORD)(Tmp64 >> 32);\r
1138         Time->dwLowDateTime = (DWORD)(Tmp64 & 0xFFFFFFFF);\r
1139 \r
1140         return;\r
1141 }\r
1142 \r
1143 \r
1144 /*----- 属性文字列を値に変換 --------------------------------------------------\r
1145 *\r
1146 *       Parameter\r
1147 *               char *Str : 属性文字列 ("rwxrwxrwx")\r
1148 *\r
1149 *       Return Value\r
1150 *               int 値\r
1151 *----------------------------------------------------------------------------*/\r
1152 \r
1153 int AttrString2Value(char *Str)\r
1154 {\r
1155         int Ret;\r
1156         char Tmp[10];\r
1157 \r
1158         Ret = 0;\r
1159         memset(Tmp, 0, 10);\r
1160         strncpy(Tmp, Str, 9);\r
1161 \r
1162         if(Tmp[0] != '-')\r
1163                 Ret |= 0x400;\r
1164         if(Tmp[1] != '-')\r
1165                 Ret |= 0x200;\r
1166         if(Tmp[2] != '-')\r
1167                 Ret |= 0x100;\r
1168 \r
1169         if(Tmp[3] != '-')\r
1170                 Ret |= 0x40;\r
1171         if(Tmp[4] != '-')\r
1172                 Ret |= 0x20;\r
1173         if(Tmp[5] != '-')\r
1174                 Ret |= 0x10;\r
1175 \r
1176         if(Tmp[6] != '-')\r
1177                 Ret |= 0x4;\r
1178         if(Tmp[7] != '-')\r
1179                 Ret |= 0x2;\r
1180         if(Tmp[8] != '-')\r
1181                 Ret |= 0x1;\r
1182 \r
1183         return(Ret);\r
1184 }\r
1185 \r
1186 \r
1187 /*----- 属性の値を文字列に変換 ------------------------------------------------\r
1188 *\r
1189 *       Parameter\r
1190 *               int Attr : 属性の値\r
1191 *               char *Buf : 属性文字列をセットするバッファ ("rwxrwxrwx")\r
1192 *\r
1193 *       Return Value\r
1194 *               int 値\r
1195 *----------------------------------------------------------------------------*/\r
1196 \r
1197 void AttrValue2String(int Attr, char *Buf)\r
1198 {\r
1199         strcpy(Buf, "---------");\r
1200 \r
1201         if(Attr & 0x400)\r
1202                 Buf[0] = 'r';\r
1203         if(Attr & 0x200)\r
1204                 Buf[1] = 'w';\r
1205         if(Attr & 0x100)\r
1206                 Buf[2] = 'x';\r
1207 \r
1208         if(Attr & 0x40)\r
1209                 Buf[3] = 'r';\r
1210         if(Attr & 0x20)\r
1211                 Buf[4] = 'w';\r
1212         if(Attr & 0x10)\r
1213                 Buf[5] = 'x';\r
1214 \r
1215         if(Attr & 0x4)\r
1216                 Buf[6] = 'r';\r
1217         if(Attr & 0x2)\r
1218                 Buf[7] = 'w';\r
1219         if(Attr & 0x1)\r
1220                 Buf[8] = 'x';\r
1221 \r
1222         return;\r
1223 }\r
1224 \r
1225 \r
1226 /*----- INIファイル文字列を整形 -----------------------------------------------\r
1227 *\r
1228 *       Parameter\r
1229 *               char *Str : 文字列\r
1230 *\r
1231 *       Return Value\r
1232 *               なし\r
1233 *----------------------------------------------------------------------------*/\r
1234 \r
1235 void FormatIniString(char *Str)\r
1236 {\r
1237         char *Put;\r
1238 \r
1239         Put = Str;\r
1240         while(*Str != NUL)\r
1241         {\r
1242                 if((*Str != ' ') && (*Str != '\t') && (*Str != '\n'))\r
1243                         *Put++ = *Str;\r
1244                 if(*Str++ == '=')\r
1245                         break;\r
1246         }\r
1247 \r
1248         while(*Str != NUL)\r
1249         {\r
1250                 if((*Str != 0x22) && (*Str != '\n'))\r
1251                         *Put++ = *Str;\r
1252                 Str++;\r
1253         }\r
1254         *Put = NUL;\r
1255 \r
1256         return;\r
1257 }\r
1258 \r
1259 \r
1260 /*----- ファイル選択 ----------------------------------------------------------\r
1261 *\r
1262 *       Parameter\r
1263 *               HWND hWnd : ウインドウハンドル\r
1264 *               char *Fname : ファイル名を返すバッファ\r
1265 *               char *Title : タイトル\r
1266 *               char *Filters : フィルター文字列\r
1267 *               char *Ext : デフォルト拡張子\r
1268 *               int Flags : 追加するフラグ\r
1269 *               int Save : 「開く」か「保存」か (0=開く, 1=保存)\r
1270 *\r
1271 *       Return Value\r
1272 *               int ステータス\r
1273 *                       TRUE/FALSE=取消\r
1274 *----------------------------------------------------------------------------*/\r
1275 \r
1276 int SelectFile(HWND hWnd, char *Fname, char *Title, char *Filters, char *Ext, int Flags, int Save)\r
1277 {\r
1278         OPENFILENAME OpenFile;\r
1279         char Tmp[FMAX_PATH+1];\r
1280         char Cur[FMAX_PATH+1];\r
1281         int Sts;\r
1282 \r
1283         GetCurrentDirectory(FMAX_PATH, Cur);\r
1284 \r
1285         strcpy(Tmp, Fname);\r
1286         OpenFile.lStructSize = sizeof(OPENFILENAME);\r
1287         OpenFile.hwndOwner = hWnd;\r
1288         OpenFile.hInstance = 0;\r
1289         OpenFile.lpstrFilter = Filters;\r
1290         OpenFile.lpstrCustomFilter = NULL;\r
1291         OpenFile.nFilterIndex = 1;\r
1292         OpenFile.lpstrFile = Tmp;\r
1293         OpenFile.nMaxFile = FMAX_PATH;\r
1294         OpenFile.lpstrFileTitle = NULL;\r
1295         OpenFile.nMaxFileTitle = 0;\r
1296         OpenFile.lpstrInitialDir = NULL;\r
1297         OpenFile.lpstrTitle = Title;\r
1298         OpenFile.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | Flags;\r
1299         OpenFile.nFileOffset = 0;\r
1300         OpenFile.nFileExtension = 0;\r
1301         OpenFile.lpstrDefExt = Ext;\r
1302         OpenFile.lCustData = 0;\r
1303         OpenFile.lpfnHook = NULL;\r
1304         OpenFile.lpTemplateName = NULL;\r
1305 \r
1306         if(Save == 0)\r
1307         {\r
1308                 if((Sts = GetOpenFileName(&OpenFile)) == TRUE)\r
1309                         strcpy(Fname,Tmp);\r
1310         }\r
1311         else\r
1312         {\r
1313                 if((Sts = GetSaveFileName(&OpenFile)) == TRUE)\r
1314                         strcpy(Fname,Tmp);\r
1315         }\r
1316         SetCurrentDirectory(Cur);\r
1317         return(Sts);\r
1318 }\r
1319 \r
1320 \r
1321 /*----- ディレクトリを選択 ----------------------------------------------------\r
1322 *\r
1323 *       Parameter\r
1324 *               HWND hWnd : ウインドウハンドル\r
1325 *               char *Buf : ディレクトリ名を返すバッファ(初期ディレクトリ名)\r
1326 *               int MaxLen : バッファのサイズ\r
1327 *\r
1328 *       Return Value\r
1329 *               int ステータス\r
1330 *                       TRUE/FALSE=取消\r
1331 *----------------------------------------------------------------------------*/\r
1332 \r
1333 int SelectDir(HWND hWnd, char *Buf, int MaxLen)\r
1334 {\r
1335         char Tmp[FMAX_PATH+1];\r
1336         char Cur[FMAX_PATH+1];\r
1337         BROWSEINFO  Binfo;\r
1338         LPITEMIDLIST lpIdll;\r
1339         int Sts;\r
1340         LPMALLOC lpMalloc;\r
1341 \r
1342         Sts = FALSE;\r
1343         GetCurrentDirectory(FMAX_PATH, Cur);\r
1344 \r
1345         if(SHGetMalloc(&lpMalloc) == NOERROR)\r
1346         {\r
1347                 Binfo.hwndOwner = hWnd;\r
1348                 Binfo.pidlRoot = NULL;\r
1349                 Binfo.pszDisplayName = Tmp;\r
1350                 Binfo.lpszTitle = MSGJPN185;\r
1351                 Binfo.ulFlags = BIF_RETURNONLYFSDIRS;\r
1352                 Binfo.lpfn = NULL;\r
1353                 Binfo.lParam = 0;\r
1354                 Binfo.iImage = 0;\r
1355                 if((lpIdll = SHBrowseForFolder(&Binfo)) != NULL)\r
1356                 {\r
1357                         SHGetPathFromIDList(lpIdll, Tmp);\r
1358                         memset(Buf, NUL, MaxLen);\r
1359                         strncpy(Buf, Tmp, MaxLen-1);\r
1360                         Sts = TRUE;\r
1361                         lpMalloc->lpVtbl->Free(lpMalloc, lpIdll);\r
1362             }\r
1363             lpMalloc->lpVtbl->Release(lpMalloc);\r
1364                 SetCurrentDirectory(Cur);\r
1365         }\r
1366         return(Sts);\r
1367 }\r
1368 \r
1369 \r
1370 /*----- 値に関連付けられたラジオボタンをチェックする --------------------------\r
1371 *\r
1372 *       Parameter\r
1373 *               HWND hDlg : ダイアログボックスのウインドウハンドル\r
1374 *               int Value : 値\r
1375 *               const RADIOBUTTON *Buttons : ラジオボタンと値の関連付けテーブル\r
1376 *               int Num : ボタンの数\r
1377 *\r
1378 *       Return Value\r
1379 *               なし\r
1380 *\r
1381 *       Note\r
1382 *               値に関連付けられたボタンが無い時は、テーブルの最初に登録されているボタ\r
1383 *               ンをチェックする\r
1384 *----------------------------------------------------------------------------*/\r
1385 \r
1386 void SetRadioButtonByValue(HWND hDlg, int Value, const RADIOBUTTON *Buttons, int Num)\r
1387 {\r
1388         int i;\r
1389         int Def;\r
1390 \r
1391         Def = Buttons->ButID;\r
1392         for(i = 0; i < Num; i++)\r
1393         {\r
1394                 if(Value == Buttons->Value)\r
1395                 {\r
1396                         SendDlgItemMessage(hDlg, Buttons->ButID, BM_SETCHECK, 1, 0);\r
1397                         /* ラジオボタンを変更した時に他の項目のハイドなどを行なう事が      */\r
1398                         /* あるので、そのために WM_COMMAND を送る                                          */\r
1399                         SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(Buttons->ButID, 0), 0);\r
1400                         break;\r
1401                 }\r
1402                 Buttons++;\r
1403         }\r
1404         if(i == Num)\r
1405         {\r
1406                 SendDlgItemMessage(hDlg, Def, BM_SETCHECK, 1, 0);\r
1407                 SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(Def, 0), 0);\r
1408         }\r
1409         return;\r
1410 }\r
1411 \r
1412 \r
1413 /*----- チェックされているボタンに関連付けられた値を返す ----------------------\r
1414 *\r
1415 *       Parameter\r
1416 *               HWND hDlg : ダイアログボックスのウインドウハンドル\r
1417 *               const RADIOBUTTON *Buttons : ラジオボタンと値の関連付けテーブル\r
1418 *               int Num : ボタンの数\r
1419 *\r
1420 *       Return Value\r
1421 *               int 値\r
1422 *\r
1423 *       Note\r
1424 *               どのボタンもチェックされていない時は、テーブルの最初に登録されているボ\r
1425 *               タンの値を返す\r
1426 *----------------------------------------------------------------------------*/\r
1427 \r
1428 int AskRadioButtonValue(HWND hDlg, const RADIOBUTTON *Buttons, int Num)\r
1429 {\r
1430         int i;\r
1431         int Ret;\r
1432 \r
1433         Ret = Buttons->Value;\r
1434         for(i = 0; i < Num; i++)\r
1435         {\r
1436                 if(SendDlgItemMessage(hDlg, Buttons->ButID, BM_GETCHECK, 0, 0) == 1)\r
1437                 {\r
1438                         Ret = Buttons->Value;\r
1439                         break;\r
1440                 }\r
1441                 Buttons++;\r
1442         }\r
1443         return(Ret);\r
1444 }\r
1445 \r
1446 \r
1447 /*----- 16進文字列を数値に変換 ----------------------------------------------\r
1448 *\r
1449 *       Parameter\r
1450 *               char *Str : 文字列\r
1451 *\r
1452 *       Return Value\r
1453 *               int 値\r
1454 *----------------------------------------------------------------------------*/\r
1455 \r
1456 int xtoi(char *Str)\r
1457 {\r
1458         int Ret;\r
1459 \r
1460         Ret = 0;\r
1461         while(*Str != NUL)\r
1462         {\r
1463                 Ret *= 0x10;\r
1464                 if((*Str >= '0') && (*Str <= '9'))\r
1465                         Ret += *Str - '0';\r
1466                 else if((*Str >= 'A') && (*Str <= 'F'))\r
1467                         Ret += *Str - 'A' + 10;\r
1468                 else if((*Str >= 'a') && (*Str <= 'f'))\r
1469                         Ret += *Str - 'a' + 10;\r
1470                 else\r
1471                         break;\r
1472 \r
1473                 Str++;\r
1474         }\r
1475         return(Ret);\r
1476 }\r
1477 \r
1478 \r
1479 /*----- ファイルが読み取り可能かどうかを返す ----------------------------------\r
1480 *\r
1481 *       Parameter\r
1482 *               char *Fname : ファイル名\r
1483 *\r
1484 *       Return Value\r
1485 *               int ステータス\r
1486 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1487 *----------------------------------------------------------------------------*/\r
1488 \r
1489 int CheckFileReadable(char *Fname)\r
1490 {\r
1491         int Sts;\r
1492         HANDLE iFileHandle;\r
1493         SECURITY_ATTRIBUTES Sec;\r
1494 \r
1495         Sts = FFFTP_FAIL;\r
1496 \r
1497         Sec.nLength = sizeof(SECURITY_ATTRIBUTES);\r
1498         Sec.lpSecurityDescriptor = NULL;\r
1499         Sec.bInheritHandle = FALSE;\r
1500 \r
1501         if((iFileHandle = CreateFile(Fname, GENERIC_READ,\r
1502                 FILE_SHARE_READ|FILE_SHARE_WRITE, &Sec, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)\r
1503         {\r
1504                 Sts = FFFTP_SUCCESS;\r
1505                 CloseHandle(iFileHandle);\r
1506         }\r
1507         return(Sts);\r
1508 }\r
1509 \r
1510 \r
1511 \r
1512 \r
1513 \r
1514 int max1(int n, int m)\r
1515 {\r
1516         if(n > m)\r
1517                 return(n);\r
1518         else\r
1519                 return(m);\r
1520 }\r
1521 \r
1522 \r
1523 \r
1524 int min1(int n, int m)\r
1525 {\r
1526         if(n < m)\r
1527                 return(n);\r
1528         else\r
1529                 return(m);\r
1530 }\r
1531 \r
1532 \r
1533 void ExcEndianDWORD(DWORD *x)\r
1534 {\r
1535         BYTE *Pos;\r
1536         BYTE Tmp;\r
1537 \r
1538         Pos = (BYTE *)x;\r
1539         Tmp = *(Pos + 0);\r
1540         *(Pos + 0) = *(Pos + 3);\r
1541         *(Pos + 3) = Tmp;\r
1542         Tmp = *(Pos + 1);\r
1543         *(Pos + 1) = *(Pos + 2);\r
1544         *(Pos + 2) = Tmp;\r
1545         return;\r
1546 }\r
1547 \r
1548 \r
1549 \r
1550 \r
1551 /*----- int値の入れ替え -------------------------------------------------------\r
1552 *\r
1553 *       Parameter\r
1554 *               int *Num1 : 数値1\r
1555 *               int *Num2 : 数値2\r
1556 *\r
1557 *       Return Value\r
1558 *               なし\r
1559 *----------------------------------------------------------------------------*/\r
1560 \r
1561 void SwapInt(int *Num1, int *Num2)\r
1562 {\r
1563         int Tmp;\r
1564 \r
1565         Tmp = *Num1;\r
1566         *Num1 = *Num2;\r
1567         *Num2 = Tmp;\r
1568         return;\r
1569 }\r
1570 \r
1571 \r
1572 /*----- 指定されたフォルダがあるかどうかチェック -------------------------------\r
1573 *\r
1574 *       Parameter\r
1575 *               char *Path : パス\r
1576 *\r
1577 *       Return Value\r
1578 *               int ステータス (YES/NO)\r
1579 *----------------------------------------------------------------------------*/\r
1580 \r
1581 int IsFolderExist(char *Path)\r
1582 {\r
1583         int Sts;\r
1584         char Tmp[FMAX_PATH+1];\r
1585         DWORD Attr;\r
1586 \r
1587         Sts = YES;\r
1588         if(strlen(Path) > 0)\r
1589         {\r
1590                 strcpy(Tmp, Path);\r
1591                 if(_mbscmp(Tmp+1, ":\\") != 0)\r
1592                         RemoveYenTail(Tmp);\r
1593 \r
1594                 Attr = GetFileAttributes(Tmp);\r
1595                 if((Attr == 0xFFFFFFFF) || ((Attr & FILE_ATTRIBUTE_DIRECTORY) == 0))\r
1596                         Sts = NO;\r
1597         }\r
1598         return(Sts);\r
1599 }\r
1600 \r
1601 \r
1602 /*----- テーブルにしたがって数値を登録 -----------------------------------------\r
1603 *\r
1604 *       Parameter\r
1605 *               int x : 数値\r
1606 *               int Dir : 変換方向\r
1607 *               INTCONVTBL *Tbl : テーブル\r
1608 *               int Num : テーブルの数値の数\r
1609 *\r
1610 *       Return Value\r
1611 *               int 数値\r
1612 *----------------------------------------------------------------------------*/\r
1613 \r
1614 int ConvertNum(int x, int Dir, const INTCONVTBL *Tbl, int Num)\r
1615 {\r
1616         int i;\r
1617         int Ret;\r
1618 \r
1619         Ret = x;\r
1620         for(i = 0; i < Num; i++)\r
1621         {\r
1622                 if((Dir == 0) && (Tbl->Num1 == x))\r
1623                 {\r
1624                         Ret = Tbl->Num2;\r
1625                         break;\r
1626                 }\r
1627                 else if((Dir == 1) && (Tbl->Num2 == x))\r
1628                 {\r
1629                         Ret = Tbl->Num1;\r
1630                         break;\r
1631                 }\r
1632                 Tbl++;\r
1633         }\r
1634         return(Ret);\r
1635 }\r
1636 \r
1637 \r
1638 \r
1639 \r
1640 \r
1641 \r
1642 /*----- ファイルをゴミ箱に削除 ------------------------------------------------\r
1643 *\r
1644 *       Parameter\r
1645 *               char *Path : ファイル名\r
1646 *\r
1647 *       Return Value\r
1648 *               int ステータス (0=正常終了)\r
1649 *----------------------------------------------------------------------------*/\r
1650 \r
1651 int MoveFileToTrashCan(char *Path)\r
1652 {\r
1653         SHFILEOPSTRUCT FileOp;\r
1654         char Tmp[FMAX_PATH+2];\r
1655 \r
1656         memset(Tmp, 0, FMAX_PATH+2);\r
1657         strcpy(Tmp, Path);\r
1658         FileOp.hwnd = NULL;\r
1659         FileOp.wFunc = FO_DELETE;\r
1660         FileOp.pFrom = Tmp;\r
1661         FileOp.pTo = "";\r
1662         FileOp.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO;\r
1663         FileOp.lpszProgressTitle = "";\r
1664         return(SHFileOperation(&FileOp));\r
1665 }\r
1666 \r
1667 \r
1668 \r
1669 \r
1670 LONGLONG MakeLongLong(DWORD High, DWORD Low)\r
1671 {\r
1672         LONGLONG z;\r
1673         LONGLONG x1, y1;\r
1674 \r
1675         x1 = (LONGLONG)Low;\r
1676         y1 = (LONGLONG)High;\r
1677         z = x1 | (y1 << 32);\r
1678         return(z);\r
1679 }\r
1680 \r
1681 \r
1682 char *MakeNumString(LONGLONG Num, char *Buf, BOOL Comma)\r
1683 {\r
1684         int i;\r
1685         char *Pos;\r
1686 \r
1687         Pos = Buf;\r
1688         *Pos = '\0';\r
1689 \r
1690         i = 1;\r
1691         do\r
1692         {\r
1693                 *Pos++ = (char)(Num % 10) + '0';\r
1694                 Num /= 10;\r
1695                 if((Comma == TRUE) && ((i % 3) == 0) && (Num != 0))\r
1696                         *Pos++ = ',';\r
1697                 i++;\r
1698         }\r
1699         while(Num != 0);\r
1700         *Pos = NUL;\r
1701         _strrev(Buf);\r
1702 \r
1703         return(Buf);\r
1704 }\r
1705 \r
1706 \r