OSDN Git Service

d064173e4958d85f3d0ba23f556554f4fffd76af
[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         // IPv6対応\r
991         if((Pos2 = _mbschr(Pos1, '[')) != NULL && Pos2 < _mbschr(Pos1, ':'))\r
992         {\r
993                 Pos1 = Pos2 + 1;\r
994                 if((Pos2 = _mbschr(Pos2, ']')) != NULL)\r
995                 {\r
996                         memcpy(Host, Pos1, min1(Pos2-Pos1, HOST_ADRS_LEN));\r
997                         Pos1 = Pos2 + 1;\r
998                 }\r
999         }\r
1000 \r
1001         if((Pos2 = _mbschr(Pos1, ':')) != NULL)\r
1002         {\r
1003                 // IPv6対応\r
1004 //              memcpy(Host, Pos1, min1(Pos2-Pos1, HOST_ADRS_LEN));\r
1005                 if(strlen(Host) == 0)\r
1006                         memcpy(Host, Pos1, min1(Pos2-Pos1, HOST_ADRS_LEN));\r
1007                 Pos2++;\r
1008                 if(IsDigit(*Pos2))\r
1009                 {\r
1010                         *Port = atoi(Pos2);\r
1011                         while(*Pos2 != NUL)\r
1012                         {\r
1013                                 if(IsDigit(*Pos2) == 0)\r
1014                                         break;\r
1015                                 Pos2++;\r
1016                         }\r
1017                 }\r
1018                 RemoveFileName(Pos2, Path);\r
1019                 strncpy(File, GetFileName(Pos2), FMAX_PATH);\r
1020         }\r
1021         else if((Pos2 = _mbschr(Pos1, '/')) != NULL)\r
1022         {\r
1023                 // IPv6対応\r
1024 //              memcpy(Host, Pos1, min1(Pos2-Pos1, HOST_ADRS_LEN));\r
1025                 if(strlen(Host) == 0)\r
1026                         memcpy(Host, Pos1, min1(Pos2-Pos1, HOST_ADRS_LEN));\r
1027                 RemoveFileName(Pos2, Path);\r
1028                 strncpy(File, GetFileName(Pos2), FMAX_PATH);\r
1029         }\r
1030         else\r
1031         {\r
1032                 // IPv6対応\r
1033 //              strncpy(Host, Pos1, HOST_ADRS_LEN);\r
1034                 if(strlen(Host) == 0)\r
1035                         strncpy(Host, Pos1, HOST_ADRS_LEN);\r
1036         }\r
1037 \r
1038         Sts = FFFTP_FAIL;\r
1039         if(strlen(Host) > 0)\r
1040                 Sts = FFFTP_SUCCESS;\r
1041 \r
1042         return(Sts);\r
1043 }\r
1044 \r
1045 \r
1046 /*----- 日付文字列(JST)をFILETIME(UTC)に変換 ----------------------------------\r
1047 *\r
1048 *       Parameter\r
1049 *               char *Time : 日付文字列 ("yyyy/mm/dd hh:mm")\r
1050 *               FILETIME *Buf : ファイルタイムを返すワーク\r
1051 *\r
1052 *       Return Value\r
1053 *               int ステータス\r
1054 *                       YES/NO=日付情報がなかった\r
1055 *----------------------------------------------------------------------------*/\r
1056 \r
1057 int TimeString2FileTime(char *Time, FILETIME *Buf)\r
1058 {\r
1059         SYSTEMTIME sTime;\r
1060         FILETIME fTime;\r
1061         int Ret;\r
1062 \r
1063         Ret = NO;\r
1064     Buf->dwLowDateTime = 0;\r
1065     Buf->dwHighDateTime = 0;\r
1066 \r
1067         if(strlen(Time) >= 16)\r
1068         {\r
1069                 if(IsDigit(Time[0]) && IsDigit(Time[5]) && IsDigit(Time[8]) && \r
1070                    IsDigit(Time[12]) && IsDigit(Time[14]))\r
1071                 {\r
1072                         Ret = YES;\r
1073                 }\r
1074 \r
1075                 sTime.wYear = atoi(Time);\r
1076                 sTime.wMonth = atoi(Time + 5);\r
1077                 sTime.wDay = atoi(Time + 8);\r
1078                 if(Time[11] != ' ')\r
1079                         sTime.wHour = atoi(Time + 11);\r
1080                 else\r
1081                         sTime.wHour = atoi(Time + 12);\r
1082                 sTime.wMinute = atoi(Time + 14);\r
1083                 sTime.wSecond = 0;\r
1084                 sTime.wMilliseconds = 0;\r
1085 \r
1086                 SystemTimeToFileTime(&sTime, &fTime);\r
1087                 LocalFileTimeToFileTime(&fTime, Buf);\r
1088         }\r
1089         return(Ret);\r
1090 }\r
1091 \r
1092 \r
1093 /*----- FILETIME(UTC)を日付文字列(JST)に変換 ----------------------------------\r
1094 *\r
1095 *       Parameter\r
1096 *               FILETIME *Time : ファイルタイム\r
1097 *               char *Buf : 日付文字列を返すワーク\r
1098 *               int Mode : モード (DISPFORM_xxx)\r
1099 *               int InfoExist : 情報があるかどうか (FINFO_xxx)\r
1100 *\r
1101 *       Return Value\r
1102 *               なし\r
1103 *----------------------------------------------------------------------------*/\r
1104 \r
1105 void FileTime2TimeString(FILETIME *Time, char *Buf, int Mode, int InfoExist)\r
1106 {\r
1107         SYSTEMTIME sTime;\r
1108         FILETIME fTime;\r
1109 \r
1110         if(Mode == DISPFORM_LEGACY)\r
1111         {\r
1112                 if((Time->dwLowDateTime == 0) && (Time->dwHighDateTime == 0))\r
1113                         InfoExist = 0;\r
1114 \r
1115                 /* "yyyy/mm/dd hh:mm" */\r
1116                 FileTimeToLocalFileTime(Time, &fTime);\r
1117                 FileTimeToSystemTime(&fTime, &sTime);\r
1118 \r
1119                 if(InfoExist & FINFO_DATE)\r
1120                         sprintf(Buf, "%04d/%02d/%02d ", sTime.wYear, sTime.wMonth, sTime.wDay);\r
1121                 else\r
1122                         sprintf(Buf, "           ");\r
1123 \r
1124                 if(InfoExist & FINFO_TIME)\r
1125                         sprintf(Buf+11, "%2d:%02d", sTime.wHour, sTime.wMinute);\r
1126                 else\r
1127                         sprintf(Buf+11, "     ");\r
1128         }\r
1129         else\r
1130         {\r
1131 //              if (!strftime((char *)str, 100, "%c",  (const struct tm *)thetime))\r
1132 //                      SetTaskMsg("strftime が失敗しました!\n");\r
1133         }\r
1134         return;\r
1135 }\r
1136 \r
1137 \r
1138 /*----- ファイルタイムを指定タイムゾーンのローカルタイムからGMTに変換 ---------\r
1139 *\r
1140 *       Parameter\r
1141 *               FILETIME *Time : ファイルタイム\r
1142 *               int TimeZone : タイムゾーン\r
1143 *\r
1144 *       Return Value\r
1145 *               なし\r
1146 *----------------------------------------------------------------------------*/\r
1147 \r
1148 void SpecificLocalFileTime2FileTime(FILETIME *Time, int TimeZone)\r
1149 {\r
1150         unsigned __int64 Tmp64;\r
1151 \r
1152         Tmp64 = (unsigned __int64)Time->dwLowDateTime +\r
1153                         ((unsigned __int64)Time->dwHighDateTime << 32);\r
1154 \r
1155         Tmp64 -= (__int64)TimeZone * (__int64)36000000000;\r
1156 \r
1157         Time->dwHighDateTime = (DWORD)(Tmp64 >> 32);\r
1158         Time->dwLowDateTime = (DWORD)(Tmp64 & 0xFFFFFFFF);\r
1159 \r
1160         return;\r
1161 }\r
1162 \r
1163 \r
1164 /*----- 属性文字列を値に変換 --------------------------------------------------\r
1165 *\r
1166 *       Parameter\r
1167 *               char *Str : 属性文字列 ("rwxrwxrwx")\r
1168 *\r
1169 *       Return Value\r
1170 *               int 値\r
1171 *----------------------------------------------------------------------------*/\r
1172 \r
1173 int AttrString2Value(char *Str)\r
1174 {\r
1175         int Ret;\r
1176         char Tmp[10];\r
1177 \r
1178         Ret = 0;\r
1179         memset(Tmp, 0, 10);\r
1180         strncpy(Tmp, Str, 9);\r
1181 \r
1182         if(Tmp[0] != '-')\r
1183                 Ret |= 0x400;\r
1184         if(Tmp[1] != '-')\r
1185                 Ret |= 0x200;\r
1186         if(Tmp[2] != '-')\r
1187                 Ret |= 0x100;\r
1188 \r
1189         if(Tmp[3] != '-')\r
1190                 Ret |= 0x40;\r
1191         if(Tmp[4] != '-')\r
1192                 Ret |= 0x20;\r
1193         if(Tmp[5] != '-')\r
1194                 Ret |= 0x10;\r
1195 \r
1196         if(Tmp[6] != '-')\r
1197                 Ret |= 0x4;\r
1198         if(Tmp[7] != '-')\r
1199                 Ret |= 0x2;\r
1200         if(Tmp[8] != '-')\r
1201                 Ret |= 0x1;\r
1202 \r
1203         return(Ret);\r
1204 }\r
1205 \r
1206 \r
1207 /*----- 属性の値を文字列に変換 ------------------------------------------------\r
1208 *\r
1209 *       Parameter\r
1210 *               int Attr : 属性の値\r
1211 *               char *Buf : 属性文字列をセットするバッファ ("rwxrwxrwx")\r
1212 *\r
1213 *       Return Value\r
1214 *               int 値\r
1215 *----------------------------------------------------------------------------*/\r
1216 \r
1217 void AttrValue2String(int Attr, char *Buf)\r
1218 {\r
1219         strcpy(Buf, "---------");\r
1220 \r
1221         if(Attr & 0x400)\r
1222                 Buf[0] = 'r';\r
1223         if(Attr & 0x200)\r
1224                 Buf[1] = 'w';\r
1225         if(Attr & 0x100)\r
1226                 Buf[2] = 'x';\r
1227 \r
1228         if(Attr & 0x40)\r
1229                 Buf[3] = 'r';\r
1230         if(Attr & 0x20)\r
1231                 Buf[4] = 'w';\r
1232         if(Attr & 0x10)\r
1233                 Buf[5] = 'x';\r
1234 \r
1235         if(Attr & 0x4)\r
1236                 Buf[6] = 'r';\r
1237         if(Attr & 0x2)\r
1238                 Buf[7] = 'w';\r
1239         if(Attr & 0x1)\r
1240                 Buf[8] = 'x';\r
1241 \r
1242         return;\r
1243 }\r
1244 \r
1245 \r
1246 /*----- INIファイル文字列を整形 -----------------------------------------------\r
1247 *\r
1248 *       Parameter\r
1249 *               char *Str : 文字列\r
1250 *\r
1251 *       Return Value\r
1252 *               なし\r
1253 *----------------------------------------------------------------------------*/\r
1254 \r
1255 void FormatIniString(char *Str)\r
1256 {\r
1257         char *Put;\r
1258 \r
1259         Put = Str;\r
1260         while(*Str != NUL)\r
1261         {\r
1262                 if((*Str != ' ') && (*Str != '\t') && (*Str != '\n'))\r
1263                         *Put++ = *Str;\r
1264                 if(*Str++ == '=')\r
1265                         break;\r
1266         }\r
1267 \r
1268         while(*Str != NUL)\r
1269         {\r
1270                 if((*Str != 0x22) && (*Str != '\n'))\r
1271                         *Put++ = *Str;\r
1272                 Str++;\r
1273         }\r
1274         *Put = NUL;\r
1275 \r
1276         return;\r
1277 }\r
1278 \r
1279 \r
1280 /*----- ファイル選択 ----------------------------------------------------------\r
1281 *\r
1282 *       Parameter\r
1283 *               HWND hWnd : ウインドウハンドル\r
1284 *               char *Fname : ファイル名を返すバッファ\r
1285 *               char *Title : タイトル\r
1286 *               char *Filters : フィルター文字列\r
1287 *               char *Ext : デフォルト拡張子\r
1288 *               int Flags : 追加するフラグ\r
1289 *               int Save : 「開く」か「保存」か (0=開く, 1=保存)\r
1290 *\r
1291 *       Return Value\r
1292 *               int ステータス\r
1293 *                       TRUE/FALSE=取消\r
1294 *----------------------------------------------------------------------------*/\r
1295 \r
1296 int SelectFile(HWND hWnd, char *Fname, char *Title, char *Filters, char *Ext, int Flags, int Save)\r
1297 {\r
1298         OPENFILENAME OpenFile;\r
1299         char Tmp[FMAX_PATH+1];\r
1300         char Cur[FMAX_PATH+1];\r
1301         int Sts;\r
1302 \r
1303         GetCurrentDirectory(FMAX_PATH, Cur);\r
1304 \r
1305         strcpy(Tmp, Fname);\r
1306         OpenFile.lStructSize = sizeof(OPENFILENAME);\r
1307         OpenFile.hwndOwner = hWnd;\r
1308         OpenFile.hInstance = 0;\r
1309         OpenFile.lpstrFilter = Filters;\r
1310         OpenFile.lpstrCustomFilter = NULL;\r
1311         OpenFile.nFilterIndex = 1;\r
1312         OpenFile.lpstrFile = Tmp;\r
1313         OpenFile.nMaxFile = FMAX_PATH;\r
1314         OpenFile.lpstrFileTitle = NULL;\r
1315         OpenFile.nMaxFileTitle = 0;\r
1316         OpenFile.lpstrInitialDir = NULL;\r
1317         OpenFile.lpstrTitle = Title;\r
1318         OpenFile.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | Flags;\r
1319         OpenFile.nFileOffset = 0;\r
1320         OpenFile.nFileExtension = 0;\r
1321         OpenFile.lpstrDefExt = Ext;\r
1322         OpenFile.lCustData = 0;\r
1323         OpenFile.lpfnHook = NULL;\r
1324         OpenFile.lpTemplateName = NULL;\r
1325 \r
1326         if(Save == 0)\r
1327         {\r
1328                 if((Sts = GetOpenFileName(&OpenFile)) == TRUE)\r
1329                         strcpy(Fname,Tmp);\r
1330         }\r
1331         else\r
1332         {\r
1333                 if((Sts = GetSaveFileName(&OpenFile)) == TRUE)\r
1334                         strcpy(Fname,Tmp);\r
1335         }\r
1336         SetCurrentDirectory(Cur);\r
1337         return(Sts);\r
1338 }\r
1339 \r
1340 \r
1341 /*----- ディレクトリを選択 ----------------------------------------------------\r
1342 *\r
1343 *       Parameter\r
1344 *               HWND hWnd : ウインドウハンドル\r
1345 *               char *Buf : ディレクトリ名を返すバッファ(初期ディレクトリ名)\r
1346 *               int MaxLen : バッファのサイズ\r
1347 *\r
1348 *       Return Value\r
1349 *               int ステータス\r
1350 *                       TRUE/FALSE=取消\r
1351 *----------------------------------------------------------------------------*/\r
1352 \r
1353 int SelectDir(HWND hWnd, char *Buf, int MaxLen)\r
1354 {\r
1355         char Tmp[FMAX_PATH+1];\r
1356         char Cur[FMAX_PATH+1];\r
1357         BROWSEINFO  Binfo;\r
1358         LPITEMIDLIST lpIdll;\r
1359         int Sts;\r
1360         LPMALLOC lpMalloc;\r
1361 \r
1362         Sts = FALSE;\r
1363         GetCurrentDirectory(FMAX_PATH, Cur);\r
1364 \r
1365         if(SHGetMalloc(&lpMalloc) == NOERROR)\r
1366         {\r
1367                 Binfo.hwndOwner = hWnd;\r
1368                 Binfo.pidlRoot = NULL;\r
1369                 Binfo.pszDisplayName = Tmp;\r
1370                 Binfo.lpszTitle = MSGJPN185;\r
1371                 Binfo.ulFlags = BIF_RETURNONLYFSDIRS;\r
1372                 Binfo.lpfn = NULL;\r
1373                 Binfo.lParam = 0;\r
1374                 Binfo.iImage = 0;\r
1375                 if((lpIdll = SHBrowseForFolder(&Binfo)) != NULL)\r
1376                 {\r
1377                         SHGetPathFromIDList(lpIdll, Tmp);\r
1378                         memset(Buf, NUL, MaxLen);\r
1379                         strncpy(Buf, Tmp, MaxLen-1);\r
1380                         Sts = TRUE;\r
1381                         lpMalloc->lpVtbl->Free(lpMalloc, lpIdll);\r
1382             }\r
1383             lpMalloc->lpVtbl->Release(lpMalloc);\r
1384                 SetCurrentDirectory(Cur);\r
1385         }\r
1386         return(Sts);\r
1387 }\r
1388 \r
1389 \r
1390 /*----- 値に関連付けられたラジオボタンをチェックする --------------------------\r
1391 *\r
1392 *       Parameter\r
1393 *               HWND hDlg : ダイアログボックスのウインドウハンドル\r
1394 *               int Value : 値\r
1395 *               const RADIOBUTTON *Buttons : ラジオボタンと値の関連付けテーブル\r
1396 *               int Num : ボタンの数\r
1397 *\r
1398 *       Return Value\r
1399 *               なし\r
1400 *\r
1401 *       Note\r
1402 *               値に関連付けられたボタンが無い時は、テーブルの最初に登録されているボタ\r
1403 *               ンをチェックする\r
1404 *----------------------------------------------------------------------------*/\r
1405 \r
1406 void SetRadioButtonByValue(HWND hDlg, int Value, const RADIOBUTTON *Buttons, int Num)\r
1407 {\r
1408         int i;\r
1409         int Def;\r
1410 \r
1411         Def = Buttons->ButID;\r
1412         for(i = 0; i < Num; i++)\r
1413         {\r
1414                 if(Value == Buttons->Value)\r
1415                 {\r
1416                         SendDlgItemMessage(hDlg, Buttons->ButID, BM_SETCHECK, 1, 0);\r
1417                         /* ラジオボタンを変更した時に他の項目のハイドなどを行なう事が      */\r
1418                         /* あるので、そのために WM_COMMAND を送る                                          */\r
1419                         SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(Buttons->ButID, 0), 0);\r
1420                         break;\r
1421                 }\r
1422                 Buttons++;\r
1423         }\r
1424         if(i == Num)\r
1425         {\r
1426                 SendDlgItemMessage(hDlg, Def, BM_SETCHECK, 1, 0);\r
1427                 SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(Def, 0), 0);\r
1428         }\r
1429         return;\r
1430 }\r
1431 \r
1432 \r
1433 /*----- チェックされているボタンに関連付けられた値を返す ----------------------\r
1434 *\r
1435 *       Parameter\r
1436 *               HWND hDlg : ダイアログボックスのウインドウハンドル\r
1437 *               const RADIOBUTTON *Buttons : ラジオボタンと値の関連付けテーブル\r
1438 *               int Num : ボタンの数\r
1439 *\r
1440 *       Return Value\r
1441 *               int 値\r
1442 *\r
1443 *       Note\r
1444 *               どのボタンもチェックされていない時は、テーブルの最初に登録されているボ\r
1445 *               タンの値を返す\r
1446 *----------------------------------------------------------------------------*/\r
1447 \r
1448 int AskRadioButtonValue(HWND hDlg, const RADIOBUTTON *Buttons, int Num)\r
1449 {\r
1450         int i;\r
1451         int Ret;\r
1452 \r
1453         Ret = Buttons->Value;\r
1454         for(i = 0; i < Num; i++)\r
1455         {\r
1456                 if(SendDlgItemMessage(hDlg, Buttons->ButID, BM_GETCHECK, 0, 0) == 1)\r
1457                 {\r
1458                         Ret = Buttons->Value;\r
1459                         break;\r
1460                 }\r
1461                 Buttons++;\r
1462         }\r
1463         return(Ret);\r
1464 }\r
1465 \r
1466 \r
1467 /*----- 16進文字列を数値に変換 ----------------------------------------------\r
1468 *\r
1469 *       Parameter\r
1470 *               char *Str : 文字列\r
1471 *\r
1472 *       Return Value\r
1473 *               int 値\r
1474 *----------------------------------------------------------------------------*/\r
1475 \r
1476 int xtoi(char *Str)\r
1477 {\r
1478         int Ret;\r
1479 \r
1480         Ret = 0;\r
1481         while(*Str != NUL)\r
1482         {\r
1483                 Ret *= 0x10;\r
1484                 if((*Str >= '0') && (*Str <= '9'))\r
1485                         Ret += *Str - '0';\r
1486                 else if((*Str >= 'A') && (*Str <= 'F'))\r
1487                         Ret += *Str - 'A' + 10;\r
1488                 else if((*Str >= 'a') && (*Str <= 'f'))\r
1489                         Ret += *Str - 'a' + 10;\r
1490                 else\r
1491                         break;\r
1492 \r
1493                 Str++;\r
1494         }\r
1495         return(Ret);\r
1496 }\r
1497 \r
1498 \r
1499 /*----- ファイルが読み取り可能かどうかを返す ----------------------------------\r
1500 *\r
1501 *       Parameter\r
1502 *               char *Fname : ファイル名\r
1503 *\r
1504 *       Return Value\r
1505 *               int ステータス\r
1506 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1507 *----------------------------------------------------------------------------*/\r
1508 \r
1509 int CheckFileReadable(char *Fname)\r
1510 {\r
1511         int Sts;\r
1512         HANDLE iFileHandle;\r
1513         SECURITY_ATTRIBUTES Sec;\r
1514 \r
1515         Sts = FFFTP_FAIL;\r
1516 \r
1517         Sec.nLength = sizeof(SECURITY_ATTRIBUTES);\r
1518         Sec.lpSecurityDescriptor = NULL;\r
1519         Sec.bInheritHandle = FALSE;\r
1520 \r
1521         if((iFileHandle = CreateFile(Fname, GENERIC_READ,\r
1522                 FILE_SHARE_READ|FILE_SHARE_WRITE, &Sec, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)\r
1523         {\r
1524                 Sts = FFFTP_SUCCESS;\r
1525                 CloseHandle(iFileHandle);\r
1526         }\r
1527         return(Sts);\r
1528 }\r
1529 \r
1530 \r
1531 \r
1532 \r
1533 \r
1534 int max1(int n, int m)\r
1535 {\r
1536         if(n > m)\r
1537                 return(n);\r
1538         else\r
1539                 return(m);\r
1540 }\r
1541 \r
1542 \r
1543 \r
1544 int min1(int n, int m)\r
1545 {\r
1546         if(n < m)\r
1547                 return(n);\r
1548         else\r
1549                 return(m);\r
1550 }\r
1551 \r
1552 \r
1553 void ExcEndianDWORD(DWORD *x)\r
1554 {\r
1555         BYTE *Pos;\r
1556         BYTE Tmp;\r
1557 \r
1558         Pos = (BYTE *)x;\r
1559         Tmp = *(Pos + 0);\r
1560         *(Pos + 0) = *(Pos + 3);\r
1561         *(Pos + 3) = Tmp;\r
1562         Tmp = *(Pos + 1);\r
1563         *(Pos + 1) = *(Pos + 2);\r
1564         *(Pos + 2) = Tmp;\r
1565         return;\r
1566 }\r
1567 \r
1568 \r
1569 \r
1570 \r
1571 /*----- int値の入れ替え -------------------------------------------------------\r
1572 *\r
1573 *       Parameter\r
1574 *               int *Num1 : 数値1\r
1575 *               int *Num2 : 数値2\r
1576 *\r
1577 *       Return Value\r
1578 *               なし\r
1579 *----------------------------------------------------------------------------*/\r
1580 \r
1581 void SwapInt(int *Num1, int *Num2)\r
1582 {\r
1583         int Tmp;\r
1584 \r
1585         Tmp = *Num1;\r
1586         *Num1 = *Num2;\r
1587         *Num2 = Tmp;\r
1588         return;\r
1589 }\r
1590 \r
1591 \r
1592 /*----- 指定されたフォルダがあるかどうかチェック -------------------------------\r
1593 *\r
1594 *       Parameter\r
1595 *               char *Path : パス\r
1596 *\r
1597 *       Return Value\r
1598 *               int ステータス (YES/NO)\r
1599 *----------------------------------------------------------------------------*/\r
1600 \r
1601 int IsFolderExist(char *Path)\r
1602 {\r
1603         int Sts;\r
1604         char Tmp[FMAX_PATH+1];\r
1605         DWORD Attr;\r
1606 \r
1607         Sts = YES;\r
1608         if(strlen(Path) > 0)\r
1609         {\r
1610                 strcpy(Tmp, Path);\r
1611                 if(_mbscmp(Tmp+1, ":\\") != 0)\r
1612                         RemoveYenTail(Tmp);\r
1613 \r
1614                 Attr = GetFileAttributes(Tmp);\r
1615                 if((Attr == 0xFFFFFFFF) || ((Attr & FILE_ATTRIBUTE_DIRECTORY) == 0))\r
1616                         Sts = NO;\r
1617         }\r
1618         return(Sts);\r
1619 }\r
1620 \r
1621 \r
1622 /*----- テーブルにしたがって数値を登録 -----------------------------------------\r
1623 *\r
1624 *       Parameter\r
1625 *               int x : 数値\r
1626 *               int Dir : 変換方向\r
1627 *               INTCONVTBL *Tbl : テーブル\r
1628 *               int Num : テーブルの数値の数\r
1629 *\r
1630 *       Return Value\r
1631 *               int 数値\r
1632 *----------------------------------------------------------------------------*/\r
1633 \r
1634 int ConvertNum(int x, int Dir, const INTCONVTBL *Tbl, int Num)\r
1635 {\r
1636         int i;\r
1637         int Ret;\r
1638 \r
1639         Ret = x;\r
1640         for(i = 0; i < Num; i++)\r
1641         {\r
1642                 if((Dir == 0) && (Tbl->Num1 == x))\r
1643                 {\r
1644                         Ret = Tbl->Num2;\r
1645                         break;\r
1646                 }\r
1647                 else if((Dir == 1) && (Tbl->Num2 == x))\r
1648                 {\r
1649                         Ret = Tbl->Num1;\r
1650                         break;\r
1651                 }\r
1652                 Tbl++;\r
1653         }\r
1654         return(Ret);\r
1655 }\r
1656 \r
1657 \r
1658 \r
1659 \r
1660 \r
1661 \r
1662 /*----- ファイルをゴミ箱に削除 ------------------------------------------------\r
1663 *\r
1664 *       Parameter\r
1665 *               char *Path : ファイル名\r
1666 *\r
1667 *       Return Value\r
1668 *               int ステータス (0=正常終了)\r
1669 *----------------------------------------------------------------------------*/\r
1670 \r
1671 int MoveFileToTrashCan(char *Path)\r
1672 {\r
1673         SHFILEOPSTRUCT FileOp;\r
1674         char Tmp[FMAX_PATH+2];\r
1675 \r
1676         memset(Tmp, 0, FMAX_PATH+2);\r
1677         strcpy(Tmp, Path);\r
1678         FileOp.hwnd = NULL;\r
1679         FileOp.wFunc = FO_DELETE;\r
1680         FileOp.pFrom = Tmp;\r
1681         FileOp.pTo = "";\r
1682         FileOp.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO;\r
1683         FileOp.lpszProgressTitle = "";\r
1684         return(SHFileOperation(&FileOp));\r
1685 }\r
1686 \r
1687 \r
1688 \r
1689 \r
1690 LONGLONG MakeLongLong(DWORD High, DWORD Low)\r
1691 {\r
1692         LONGLONG z;\r
1693         LONGLONG x1, y1;\r
1694 \r
1695         x1 = (LONGLONG)Low;\r
1696         y1 = (LONGLONG)High;\r
1697         z = x1 | (y1 << 32);\r
1698         return(z);\r
1699 }\r
1700 \r
1701 \r
1702 char *MakeNumString(LONGLONG Num, char *Buf, BOOL Comma)\r
1703 {\r
1704         int i;\r
1705         char *Pos;\r
1706 \r
1707         Pos = Buf;\r
1708         *Pos = '\0';\r
1709 \r
1710         i = 1;\r
1711         do\r
1712         {\r
1713                 *Pos++ = (char)(Num % 10) + '0';\r
1714                 Num /= 10;\r
1715                 if((Comma == TRUE) && ((i % 3) == 0) && (Num != 0))\r
1716                         *Pos++ = ',';\r
1717                 i++;\r
1718         }\r
1719         while(Num != 0);\r
1720         *Pos = NUL;\r
1721         _strrev(Buf);\r
1722 \r
1723         return(Buf);\r
1724 }\r
1725 \r
1726 \r