Skip to content

Commit

Permalink
Fix #68
Browse files Browse the repository at this point in the history
  • Loading branch information
katahiromz committed Apr 4, 2024
1 parent f55035c commit 4a44e00
Show file tree
Hide file tree
Showing 12 changed files with 220 additions and 11 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ add_executable(XWordGiver${BITS} WIN32
Utils.cpp
XWordGiver.cpp
XWordGiver_res.rc)
target_link_libraries(XWordGiver${BITS} comctl32 imm32 shell32 ole32 uuid shlwapi SaveBitmapToFile)
target_link_libraries(XWordGiver${BITS} winmm comctl32 imm32 shell32 ole32 uuid shlwapi SaveBitmapToFile)
if(MSVC)
target_link_options(XWordGiver${BITS} PRIVATE /MANIFEST:NO)
endif()
Expand Down
45 changes: 43 additions & 2 deletions GUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#define NOMINMAX
#include "XWordGiver.hpp"
#include <mmsystem.h>
#include "GUI.hpp"
#include <algorithm>
#include "WonSetThreadUILanguage/WonSetThreadUILanguage.h"
Expand Down Expand Up @@ -276,6 +277,16 @@ XGStringW xg_strDoubleFrameLetters;
BOOL xg_bNoReadLooks = FALSE;
BOOL xg_bNoWriteLooks = FALSE;

enum {
I_SOUND_SUCCESS = 0,
I_SOUND_FAILED,
I_SOUND_CANCELED,
I_SOUND_MAX
};

// 音声ファイル。
WCHAR xg_aszSoundFiles[I_SOUND_MAX][MAX_PATH];

//////////////////////////////////////////////////////////////////////////////
// static variables

Expand Down Expand Up @@ -940,6 +951,10 @@ void XgResetSettings(void)

xg_bNoReadLooks = FALSE;
xg_bNoWriteLooks = FALSE;

for (auto& item : xg_aszSoundFiles) {
item[0] = 0;
}
}

// 設定を読み込む。
Expand Down Expand Up @@ -1213,6 +1228,16 @@ bool __fastcall XgLoadSettings(void)
xg_strDoubleFrameLetters = sz;
}

if (!app_key.QuerySz(L"SoundFile0", sz, _countof(sz))) {
StringCchCopy(xg_aszSoundFiles[0], _countof(xg_aszSoundFiles[0]), sz);
}
if (!app_key.QuerySz(L"SoundFile1", sz, _countof(sz))) {
StringCchCopy(xg_aszSoundFiles[1], _countof(xg_aszSoundFiles[1]), sz);
}
if (!app_key.QuerySz(L"SoundFile2", sz, _countof(sz))) {
StringCchCopy(xg_aszSoundFiles[2], _countof(xg_aszSoundFiles[2]), sz);
}

// 保存先のリストを取得する。
if (!app_key.QueryDword(L"SaveToCount", dwValue)) {
nDirCount = dwValue;
Expand Down Expand Up @@ -1336,6 +1361,10 @@ bool __fastcall XgSaveSettings(void)

app_key.SetSz(L"DoubleFrameLetters", xg_strDoubleFrameLetters.c_str());

app_key.SetSz(L"SoundFile0", xg_aszSoundFiles[0]);
app_key.SetSz(L"SoundFile1", xg_aszSoundFiles[1]);
app_key.SetSz(L"SoundFile2", xg_aszSoundFiles[2]);

// 保存先のリストを設定する。
nCount = static_cast<int>(xg_dirs_save_to.size());
app_key.SetDword(L"SaveToCount", nCount);
Expand Down Expand Up @@ -2810,8 +2839,12 @@ void __fastcall XgShowResults(HWND hwnd, BOOL bOK)
{
WCHAR sz[MAX_PATH];
if (bOK) {
// 必要なら音声を鳴らす。
if (xg_aszSoundFiles[I_SOUND_SUCCESS][0]) {
::PlaySoundW(xg_aszSoundFiles[I_SOUND_SUCCESS], NULL, SND_ASYNC | SND_FILENAME);
}
// 必要なら成功メッセージを表示する。
if (!xg_bNoGeneratedMsg) {
// 成功メッセージを表示する。
if (xg_bAutoSave && PathFileExistsW(xg_strFileName.c_str())) {
StringCchPrintf(sz, _countof(sz), XgLoadStringDx1(IDS_MADEPROBLEM2),
PathFindFileNameW(xg_strFileName.c_str()),
Expand All @@ -2827,14 +2860,22 @@ void __fastcall XgShowResults(HWND hwnd, BOOL bOK)
// ヒントを表示する。
XgShowHints(hwnd);
} else if (xg_bCancelled) {
// 必要なら音声を鳴らす。
if (xg_aszSoundFiles[I_SOUND_CANCELED][0]) {
::PlaySoundW(xg_aszSoundFiles[I_SOUND_CANCELED], NULL, SND_ASYNC | SND_FILENAME);
}
// 必要ならキャンセルメッセージを表示する。
if (!xg_bNoCanceledMsg) {
// キャンセルされた。
StringCchPrintf(sz, _countof(sz), XgLoadStringDx1(IDS_CANCELLED),
DWORD(xg_dwlTick2 - xg_dwlTick0) / 1000,
DWORD(xg_dwlTick2 - xg_dwlTick0) / 100 % 10);
XgCenterMessageBoxW(hwnd, sz, XgLoadStringDx2(IDS_RESULTS), MB_ICONINFORMATION);
}
} else {
// 必要なら音声を鳴らす。
if (xg_aszSoundFiles[I_SOUND_FAILED][0]) {
::PlaySoundW(xg_aszSoundFiles[I_SOUND_FAILED], NULL, SND_ASYNC | SND_FILENAME);
}
// 失敗メッセージを表示する。
StringCchPrintf(sz, _countof(sz), XgLoadStringDx1(IDS_CANTMAKEPROBLEM),
DWORD(xg_dwlTick2 - xg_dwlTick0) / 1000,
Expand Down
2 changes: 2 additions & 0 deletions HISTORY.txt
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@
- 2024-XX-YY ver.5.2.2
- Fixed dictionary list loading.
- The theme can now be opened from the "Dictionaries" settings.
- Able to play a sound file when generation is successful, fails, or cancelled.

# 開発履歴 (Japanese)

Expand Down Expand Up @@ -936,3 +937,4 @@
- 「辞書」設定からテーマを開けるようにした。
- 「ジャンプ」ダイアログを修正。
- 「辞書」設定の一部テキストを修正。
- 生成の成功時・失敗時・キャンセル時に音を鳴らせるようにした。
Binary file added SOUND/Canceled.wav
Binary file not shown.
Binary file added SOUND/Failed.wav
Binary file not shown.
Binary file added SOUND/Success.wav
Binary file not shown.
2 changes: 1 addition & 1 deletion Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1454,7 +1454,7 @@ BOOL ComboBox_RealSetText(HWND hwndCombo, LPCWSTR pszText) noexcept
// ローカルファイルを見つける。
BOOL XgFindLocalFile(LPWSTR pszPath, UINT cchPath, LPCWSTR pszFileName)
{
GetModuleFileNameW(nullptr, pszPath, MAX_PATH);
GetModuleFileNameW(nullptr, pszPath, cchPath);
PathRemoveFileSpecW(pszPath);
PathAppendW(pszPath, pszFileName);
if (!PathFileExistsW(pszPath))
Expand Down
152 changes: 147 additions & 5 deletions XgGenerative.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,64 @@
// 音声コンボボックスを初期化。
BOOL XgGenerative_InitSound(HWND hwnd, INT nComboID, INT nCheckID, LPCWSTR pszPathName)
{
HWND hCmb = GetDlgItem(hwnd, nComboID);

if (pszPathName[0])
::CheckDlgButton(hwnd, nCheckID, BST_CHECKED);
else
::EnableWindow(hCmb, FALSE);

// 「(なし)」を追加して選択。
ComboBox_AddString(hCmb, XgLoadStringDx1(IDS_NONE));
ComboBox_SetCurSel(hCmb, 0);

// SOUNDファイルがなければ音声は無効。
WCHAR szPath[MAX_PATH];
if (!XgFindLocalFile(szPath, _countof(szPath), L"SOUND"))
return FALSE;

// WAVファイルの列挙を開始する。
WIN32_FIND_DATAW find;
PathAppendW(szPath, L"*.wav");
HANDLE hFind = FindFirstFileW(szPath, &find);
if (hFind == INVALID_HANDLE_VALUE)
return FALSE;

do
{
// コンボボックスに追加。
INT iItem = ComboBox_AddString(hCmb, find.cFileName);

// 一致すれば選択。
if (lstrcmpiW(find.cFileName, PathFindFileNameW(pszPathName)) == 0)
ComboBox_SetCurSel(hCmb, iItem);
} while (FindNextFileW(hFind, &find));

FindClose(hFind);
return TRUE;
}

// 音を鳴らす。
void XgGenerative_PlaySound(HWND hwnd, INT nID)
{
// SOUNDフォルダがなければ鳴らさない。
WCHAR szPath[MAX_PATH];
if (!XgFindLocalFile(szPath, _countof(szPath), L"SOUND"))
return;

// コンボボックスからテキストを取得。
WCHAR szText[MAX_PATH];
ComboBox_GetText(GetDlgItem(hwnd, nID), szText, _countof(szText));

// 「(なし)」は鳴らさない。
if (lstrcmpiW(szText, XgLoadStringDx1(IDS_NONE)) == 0)
return;

// パス名を構築して、音声を鳴らす。
PathAppendW(szPath, szText);
::PlaySoundW(szPath, NULL, SND_ASYNC | SND_FILENAME);
}

// [生成]設定。
INT_PTR CALLBACK
XgGenerativeDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Expand All @@ -6,13 +67,19 @@ XgGenerativeDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
case WM_INITDIALOG:
xg_ahSyncedDialogs[I_SYNCED_GENERATIVE] = hwnd;
// チェックボックスを初期化
// チェックボックスとコンボボックスを初期化
if (xg_bNoGeneratedMsg)
::CheckDlgButton(hwnd, chx1, BST_CHECKED);
if (xg_bNoCanceledMsg)
::CheckDlgButton(hwnd, chx2, BST_CHECKED);
if (xg_bAutoRetry)
::CheckDlgButton(hwnd, chx3, BST_CHECKED);
if (!XgGenerative_InitSound(hwnd, cmb1, chx4, xg_aszSoundFiles[0]))
EnableWindow(GetDlgItem(hwnd, chx4), FALSE);
if (!XgGenerative_InitSound(hwnd, cmb2, chx6, xg_aszSoundFiles[1]))
EnableWindow(GetDlgItem(hwnd, chx5), FALSE);
if (!XgGenerative_InitSound(hwnd, cmb3, chx5, xg_aszSoundFiles[2]))
EnableWindow(GetDlgItem(hwnd, chx6), FALSE);
return TRUE;

case WM_COMMAND:
Expand All @@ -22,9 +89,53 @@ XgGenerativeDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case chx1:
case chx2:
case chx3:
case chx4:
case chx5:
case chx6:
if (HIWORD(wParam) == BN_CLICKED)
PropSheet_Changed(GetParent(hwnd), hwnd);
break;
case cmb1:
case cmb2:
case cmb3:
if (HIWORD(wParam) == CBN_SELCHANGE ||
HIWORD(wParam) == CBN_SELENDOK)
{
PropSheet_Changed(GetParent(hwnd), hwnd);
}
break;
}
// チェックボックスの状態によりコンボボックスの有効化・無効化を切り替える。
// 「再生」ボタンで音を出す。
switch (LOWORD(wParam))
{
case chx4:
if (HIWORD(wParam) == BN_CLICKED)
EnableWindow(GetDlgItem(hwnd, cmb1), IsDlgButtonChecked(hwnd, chx4) == BST_CHECKED);
break;
case chx5:
if (HIWORD(wParam) == BN_CLICKED)
EnableWindow(GetDlgItem(hwnd, cmb2), IsDlgButtonChecked(hwnd, chx5) == BST_CHECKED);
break;
case chx6:
if (HIWORD(wParam) == BN_CLICKED)
EnableWindow(GetDlgItem(hwnd, cmb3), IsDlgButtonChecked(hwnd, chx6) == BST_CHECKED);
break;
case psh1:
if (HIWORD(wParam) == BN_CLICKED) {
XgGenerative_PlaySound(hwnd, cmb1);
}
break;
case psh2:
if (HIWORD(wParam) == BN_CLICKED) {
XgGenerative_PlaySound(hwnd, cmb2);
}
break;
case psh3:
if (HIWORD(wParam) == BN_CLICKED) {
XgGenerative_PlaySound(hwnd, cmb3);
}
break;
}
break;

Expand All @@ -33,10 +144,41 @@ XgGenerativeDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
NMHDR *pnmhdr = (NMHDR *)lParam;
switch (pnmhdr->code) {
case PSN_APPLY: // 適用
// チェックボックスから設定を取得する。
xg_bNoGeneratedMsg = (::IsDlgButtonChecked(hwnd, chx1) == BST_CHECKED);
xg_bNoCanceledMsg = (::IsDlgButtonChecked(hwnd, chx2) == BST_CHECKED);
xg_bAutoRetry = (::IsDlgButtonChecked(hwnd, chx3) == BST_CHECKED);
{
// 設定を取得する。
xg_bNoGeneratedMsg = (::IsDlgButtonChecked(hwnd, chx1) == BST_CHECKED);
xg_bNoCanceledMsg = (::IsDlgButtonChecked(hwnd, chx2) == BST_CHECKED);
xg_bAutoRetry = (::IsDlgButtonChecked(hwnd, chx3) == BST_CHECKED);

// いったん音声ファイルの情報をクリアする。
xg_aszSoundFiles[0][0] = 0;
xg_aszSoundFiles[1][0] = 0;
xg_aszSoundFiles[2][0] = 0;

// SOUNDフォルダがなければ無効のまま。
WCHAR szPath[MAX_PATH];
if (!XgFindLocalFile(szPath, _countof(szPath), L"SOUND"))
break;

WCHAR szText[MAX_PATH];

// コンボボックスとチェックボックスの状態に応じて音声ファイルを設定する。
ComboBox_GetText(GetDlgItem(hwnd, cmb1), szText, _countof(szText));
if (::IsDlgButtonChecked(hwnd, chx4) == BST_CHECKED && szText[0]) {
StringCchCopyW(xg_aszSoundFiles[0], _countof(xg_aszSoundFiles[0]), szPath);
PathAppendW(xg_aszSoundFiles[0], szText);
}
ComboBox_GetText(GetDlgItem(hwnd, cmb2), szText, _countof(szText));
if (::IsDlgButtonChecked(hwnd, chx5) == BST_CHECKED && szText[0]) {
StringCchCopyW(xg_aszSoundFiles[1], _countof(xg_aszSoundFiles[0]), szPath);
PathAppendW(xg_aszSoundFiles[1], szText);
}
ComboBox_GetText(GetDlgItem(hwnd, cmb3), szText, _countof(szText));
if (::IsDlgButtonChecked(hwnd, chx6) == BST_CHECKED && szText[0]) {
StringCchCopyW(xg_aszSoundFiles[2], _countof(xg_aszSoundFiles[0]), szPath);
PathAppendW(xg_aszSoundFiles[2], szText);
}
}
break;
}
}
Expand Down
3 changes: 3 additions & 0 deletions installer32.iss
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ Source: "BLOCK\perfect-black.bmp"; DestDir: "{app}\BLOCK"; Flags: ignoreversion
Source: "BLOCK\sakura.jpg"; DestDir: "{app}\BLOCK"; Flags: ignoreversion
Source: "BLOCK\spade.emf"; DestDir: "{app}\BLOCK"; Flags: ignoreversion
Source: "BLOCK\star.emf"; DestDir: "{app}\BLOCK"; Flags: ignoreversion
Source: "SOUND\Success.wav"; DestDir: "{app}\SOUND"; Flags: ignoreversion
Source: "SOUND\Canceled.wav"; DestDir: "{app}\SOUND"; Flags: ignoreversion
Source: "SOUND\Failed.wav"; DestDir: "{app}\SOUND"; Flags: ignoreversion
Source: "LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion
Source: "PAT.txt"; DestDir: "{app}"; Flags: ignoreversion
Source: "POLICY.txt"; DestDir: "{app}"; Flags: ignoreversion
Expand Down
3 changes: 3 additions & 0 deletions installer64.iss
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ Source: "BLOCK\perfect-black.bmp"; DestDir: "{app}\BLOCK"; Flags: ignoreversion
Source: "BLOCK\sakura.jpg"; DestDir: "{app}\BLOCK"; Flags: ignoreversion
Source: "BLOCK\spade.emf"; DestDir: "{app}\BLOCK"; Flags: ignoreversion
Source: "BLOCK\star.emf"; DestDir: "{app}\BLOCK"; Flags: ignoreversion
Source: "SOUND\Success.wav"; DestDir: "{app}\SOUND"; Flags: ignoreversion
Source: "SOUND\Canceled.wav"; DestDir: "{app}\SOUND"; Flags: ignoreversion
Source: "SOUND\Failed.wav"; DestDir: "{app}\SOUND"; Flags: ignoreversion
Source: "LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion
Source: "PAT.txt"; DestDir: "{app}"; Flags: ignoreversion
Source: "POLICY.txt"; DestDir: "{app}"; Flags: ignoreversion
Expand Down
9 changes: 9 additions & 0 deletions lang/en_US.rc
Original file line number Diff line number Diff line change
Expand Up @@ -1538,6 +1538,15 @@ FONT 9, "Tahoma"
AUTOCHECKBOX "Do not display ""Generated a &problem""", chx1, 10, 5, 200, 15
AUTOCHECKBOX "Do not display ""&Cancelled""", chx2, 10, 25, 200, 15
AUTOCHECKBOX "Auto &retry", chx3, 10, 45, 200, 15
AUTOCHECKBOX "Play the following sound on &successful generation:", chx4, 10, 65, 200, 15
COMBOBOX cmb1, 35, 85, 125, 300, CBS_HASSTRINGS | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Play", psh1, 165, 85, 35, 15
AUTOCHECKBOX "Play the following sound on generation &failure:", chx5, 10, 105, 200, 15
COMBOBOX cmb2, 35, 125, 125, 300, CBS_HASSTRINGS | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Play", psh2, 165, 125, 35, 15
AUTOCHECKBOX "Play the following sound when cance&ling generation:", chx6, 10, 145, 200, 15
COMBOBOX cmb3, 35, 165, 125, 300, CBS_HASSTRINGS | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Play", psh3, 165, 165, 35, 15
}

IDD_DICTLIST DIALOG 0, 0, 269, 203
Expand Down
13 changes: 11 additions & 2 deletions lang/ja_JP.rc
Original file line number Diff line number Diff line change
Expand Up @@ -1534,14 +1534,23 @@ FONT 9, "MS UI Gothic"
COMBOBOX cmb1, 60, 170, 95, 300, CBS_HASSTRINGS | CBS_AUTOHSCROLL | CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
}

IDD_GENERATIVE DIALOG 0, 0, 220, 190
IDD_GENERATIVE DIALOG 0, 0, 220, 209
CAPTION "生成"
STYLE DS_CENTER | DS_MODALFRAME | WS_POPUPWINDOW | WS_CAPTION
FONT 9, "MS UI Gothic"
{
AUTOCHECKBOX "「問題を生成しました」を表示しない(&P)", chx1, 10, 5, 200, 15
AUTOCHECKBOX "「キャンセルしました」を表示しない(&C)", chx2, 10, 25, 200, 15
AUTOCHECKBOX "自動で再試行(&T)", chx3, 10, 45, 200, 15
AUTOCHECKBOX "生成の成功時に次の音を鳴らす(&S):", chx4, 10, 65, 200, 15
COMBOBOX cmb1, 35, 85, 125, 300, CBS_HASSTRINGS | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "再生", psh1, 165, 85, 35, 15
AUTOCHECKBOX "生成の失敗時に次の音を鳴らす(&F):", chx5, 10, 105, 200, 15
COMBOBOX cmb2, 35, 125, 125, 300, CBS_HASSTRINGS | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "再生", psh2, 165, 125, 35, 15
AUTOCHECKBOX "生成のキャンセル時に次の音を鳴らす(&L):", chx6, 10, 145, 200, 15
COMBOBOX cmb3, 35, 165, 125, 300, CBS_HASSTRINGS | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "再生", psh3, 165, 165, 35, 15
}

IDD_DICTLIST DIALOG 0, 0, 269, 203
Expand Down Expand Up @@ -1810,9 +1819,9 @@ STRINGTABLE
IDS_OUTOFRANGE, "範囲外です。"
IDS_GENERALSETTINGS, "設定 (Alt+Enter)"
IDS_MADEPROBLEM2, "問題の生成とファイル「%s」への保存に成功しました。\n\n計算時間: %u.%u[秒]"
IDS_FITWHOLE, "全体に合わせる"
IDS_FILENAME, "ファイル名"
IDS_DISPLAYNAME, "表示名"
IDS_FITWHOLE, "全体に合わせる"
IDS_TT_NEW, "新規作成"
IDS_TT_GENERATE, "問題を自動生成する"
IDS_TT_OPEN, "問題を開く"
Expand Down

0 comments on commit 4a44e00

Please sign in to comment.