OSDN Git Service

Merge branch 'master' of https://github.com/hengband/hengband
[hengbandforosx/hengbandosx.git] / src / main-win / main-win-utils.cpp
1 /*!
2  * @file main-win-utils.cpp
3  * @brief Windows版固有実装(ユーティリティー)
4  */
5
6 #include "main-win/main-win-utils.h"
7 #include "cmd-io/cmd-process-screen.h"
8 #include "locale/language-switcher.h"
9 #include "main-win/main-win-define.h"
10 #include "system/angband-version.h"
11 #include <string>
12
13 /*!
14  * @brief (Windows固有)変愚蛮怒が起動済かどうかのチェック
15  * @details
16  * 特定の名前のミューテックスオブジェクトの所有権取得を試みる。
17  * 取得できない場合は他に変愚蛮怒のプロセスが起動しているとみなす。
18  * 取得したミューテックスのハンドルは明示的な解放は行わず、プロセス終了時にOSが解放する。
19  * バリアント名の先頭から63文字が一致していたらそれらを同時起動できない (が、そのようなことは起きない想定)。
20  * @return 起動済の変愚蛮怒プロセス有無
21  */
22 bool is_already_running(void)
23 {
24     constexpr auto max_mutex_length = 64;
25     wchar_t wtext[max_mutex_length]{};
26     mbstowcs(wtext, VARIANT_NAME.data(), max_mutex_length - 1);
27     [[maybe_unused]] HANDLE hMutex = CreateMutexW(NULL, TRUE, wtext);
28     return GetLastError() == ERROR_ALREADY_EXISTS;
29 }
30
31 /*!
32  * @brief (Windows固有)画面をHTMLファイルに保存する
33  * @details
34  * ファイル保存ダイアログを表示し、指定のファイルに画面内容を保存する。
35  * @param hWnd ダイアログの親にするウインドウのハンドル
36  */
37 void save_screen_as_html(HWND hWnd)
38 {
39     std::vector<WCHAR> buf(MAIN_WIN_MAX_PATH + 1);
40     OPENFILENAMEW ofnw;
41
42     memset(&ofnw, 0, sizeof(ofnw));
43     ofnw.lStructSize = sizeof(ofnw);
44     ofnw.hwndOwner = hWnd;
45     ofnw.lpstrFilter = L"HTML Files (*.html)\0*.html\0";
46     ofnw.nFilterIndex = 1;
47     ofnw.lpstrFile = &buf[0];
48     ofnw.nMaxFile = MAIN_WIN_MAX_PATH;
49     ofnw.lpstrDefExt = L"html";
50     ofnw.lpstrInitialDir = NULL;
51     ofnw.lpstrTitle = _(L"HTMLでスクリーンダンプを保存", L"Save screen dump as HTML.");
52     ofnw.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
53
54     if (GetSaveFileNameW(&ofnw)) {
55         do_cmd_save_screen_html_aux(to_multibyte(&buf[0]).c_str(), 0);
56     }
57 }
58
59 /*!
60  * @brief 対象ファイルを選択した状態でエクスプローラーを開く
61  * @param filename 対象ファイル
62  */
63 void open_dir_in_explorer(std::string_view filename)
64 {
65     std::stringstream ss;
66     ss << "/select," << filename;
67     ShellExecuteW(NULL, NULL, L"explorer.exe", to_wchar(ss.str().data()).wc_str(), NULL, SW_SHOWNORMAL);
68 }
69
70 /*!
71  * @brief GetOpenFileNameW APIのラッパー
72  * @details
73  * ワイド文字列版のAPIを使用するが、選択ファイルのパスをマルチバイト文字列で受け取る。
74  * @param ofn GetOpenFileNameWに指定するOPENFILENAMEW構造体へのポインタ。
75  * lpstrFile、nMaxFileメンバの設定は無視される(関数内で上書きするため)。
76  * @param path_dir GetOpenFileNameWに指定する初期フォルダパス。
77  * empty以外を指定した場合、ワイド文字列に変換しlpstrInitialDirに設定される。
78  * @param path_file 選択ファイルパス
79  * @param max_name_size filenameのバッファサイズ
80  * @retval true filenameに選択されたファイルのパスが設定されている。
81  * @retval false ファイル選択がキャンセルされた。
82  */
83 std::optional<std::string> get_open_filename(OPENFILENAMEW *ofn, const std::filesystem::path &path_dir, const std::filesystem::path &path_file, DWORD max_name_size)
84 {
85     std::vector<WCHAR> buf(max_name_size);
86     const auto &path_file_str = path_file.string();
87     wcscpy(&buf[0], to_wchar(path_file_str.data()).wc_str());
88     const char *dir = nullptr;
89     if (!path_dir.empty()) {
90         const auto &dirname_str = path_dir.string();
91         dir = dirname_str.data();
92     }
93
94     to_wchar wc_dir(dir);
95
96     // Overwrite struct data
97     ofn->lpstrFile = &buf[0];
98     ofn->nMaxFile = max_name_size - 1;
99     ofn->lpstrInitialDir = wc_dir.wc_str();
100
101     // call API
102     if (GetOpenFileNameW(ofn)) {
103         // to multibyte
104         char multibyte_filename[1024];
105         strncpy_s(multibyte_filename, max_name_size, to_multibyte(&buf[0]).c_str(), _TRUNCATE);
106         return multibyte_filename;
107     }
108
109     return std::nullopt;
110 }