Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

バグ修正や小さな改善. #46

Merged
merged 3 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions Common/WinUtility.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,16 @@ inline BOOL setWindowRect(HWND hwnd, LPCRECT rc, UINT flags = 0)
//
inline BOOL isAncestor(HWND hwnd1, HWND hwnd2)
{
while (hwnd1)
{
if (hwnd1 == hwnd2)
return TRUE;
//while (hwnd1)
//{
// if (hwnd1 == hwnd2)
// return TRUE;

hwnd1 = ::GetParent(hwnd1);
}
// hwnd1 = ::GetParent(hwnd1);
//}

return FALSE;
//return FALSE;
return hwnd1 == hwnd2 || ::IsChild(hwnd2, hwnd1);
}

//--------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions Common/Window.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ namespace Tools
UINT_PTR id, DWORD_PTR refData)
{
// MY_TRACE_FUNC("0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X", hwnd, message, wParam, lParam, id, refData);
TCHAR className[MAX_PATH] = {};
::GetClassName(hwnd, className, std::size(className));
//TCHAR className[MAX_PATH] = {};
//::GetClassName(hwnd, className, std::size(className));
// MY_TRACE_TSTR(className);

auto window = (Window*)refData;
Expand Down
39 changes: 21 additions & 18 deletions DirtyCheck/auls_confirmclose.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,36 +89,30 @@ namespace fgo::dirty_check
}

//
// ダーティーフラグをチェックします。
// ダーティーな場合はtrueを返します。
// ダーティーフラグを更新します.
//
bool check()
void update()
{
if (*g_undo_id_ptr == g_undo_id_prev) return false;
g_undo_id_prev = *g_undo_id_ptr;
g_dirty_flag = true;
return true;
if (!g_dirty_flag && *g_undo_id_ptr != g_undo_id_prev)
g_dirty_flag = true;
}

//
// ダーティーフラグを初期値に戻します。
//
void clear()
{
g_undo_id_prev = 0;
g_undo_id_prev = *g_undo_id_ptr;
g_dirty_flag = false;
}
} dirty_flag;

inline struct AviUtlWindow
{
HWND hwnd = 0;
WNDPROC orig = 0;

//
// AviUtlウィンドウのウィンドウプロシージャをフックします。
//
static LRESULT CALLBACK hook(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
static LRESULT CALLBACK hook(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, uintptr_t id, auto)
{
if (dirty_flag.is_trigger_message(msg, wp)) {
int id = MessageBoxA(hwnd, "変更された編集データがあります。保存しますか?",
Expand All @@ -129,7 +123,9 @@ namespace fgo::dirty_check
}
else if (id == IDCANCEL) return 0;
}
return CallWindowProc(aviutl_window.orig, hwnd, msg, wp, lp);
else if (msg == WM_DESTROY)
::RemoveWindowSubclass(hwnd, hook, id);
return ::DefSubclassProc(hwnd, msg, wp, lp);
}

//
Expand All @@ -138,10 +134,10 @@ namespace fgo::dirty_check
BOOL init(AviUtl::FilterPlugin* fp)
{
// AviUtlウィンドウを取得します。
hwnd = GetWindow(fp->hwnd, GW_OWNER);
auto hwnd = fp->hwnd_parent;

// AviUtlウィンドウをサブクラス化します。
orig = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG)hook);
::SetWindowSubclass(hwnd, hook, reinterpret_cast<uintptr_t>(&dirty_flag), {});

return TRUE;
}
Expand All @@ -165,8 +161,8 @@ namespace fgo::dirty_check
switch (msg) {
case AviUtl::FilterPlugin::WindowMessage::Update:
if (!fp->exfunc->is_editing(editp)) break;
// プロジェクトが変更されたかもしれないのでダーティーフラグをチェックします。
dirty_flag.check();
// プロジェクトが変更されたかもしれないのでダーティーフラグを更新します.
dirty_flag.update();
break;
case AviUtl::FilterPlugin::WindowMessage::FileClose:
// プロジェクトが閉じられたのでダーティーフラグをクリアします。
Expand All @@ -180,13 +176,20 @@ namespace fgo::dirty_check
{
// プロジェクトが保存されたのでダーティーフラグをクリアします。
dirty_flag.clear();

// フラグをクリアしてもタイトルは変わらないので手動で変更.
char title[MAX_PATH];
::GetWindowTextA(fp->hwnd_parent, title, std::size(title));
if (title[0] == '*' && title[1] == ' ')
::SetWindowTextA(fp->hwnd_parent, title + 2);
return FALSE;
}

BOOL func_modify_title(AviUtl::FilterPlugin* fp, AviUtl::EditHandle* editp, int frame, LPSTR title, int max_title)
{
// プロジェクトが変更されたかもしれないのでダーティーフラグをチェックします。
if (!dirty_flag.check()) return FALSE;
dirty_flag.update();
if (!dirty_flag.get()) return FALSE;
std::string str(title);
sprintf_s(title, max_title, "* %s", str.c_str());
return TRUE;
Expand Down
16 changes: 8 additions & 8 deletions EditBoxTweaker/Servant.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,12 @@ namespace fgo::editbox_tweaker
if (wcslen(font.name) != 0)
{
// DPIに合わせてフォントのサイズを調整します。
int dpi = ::GetSystemDpiForProcess(::GetCurrentProcess());
int height = ::MulDiv(font.height, dpi, 96);
//int dpi = ::GetSystemDpiForProcess(::GetCurrentProcess());
//int height = ::MulDiv(font.height, dpi, 96);

// HFONTを作成します。
// 複数行エディットボックスのWM_SETFONTでこのハンドルが渡されます。
font.handle = ::CreateFontW(height, 0,
font.handle = ::CreateFontW(font.height, 0,
0, 0, 0, 0, 0, 0, DEFAULT_CHARSET,
0, 0, 0, font.pitch, font.name);
}
Expand Down Expand Up @@ -235,7 +235,7 @@ namespace fgo::editbox_tweaker
case WM_SETFONT:
MY_TRACE(_T("WM_SETFONT, 0x%08X, 0x%08X\n"), wparam, lparam);
wparam = reinterpret_cast<WPARAM>(servant.font.handle); // handle is not null here.
//[[fallthrough]];
[[fallthrough]];
case WM_DESTROY:
::RemoveWindowSubclass(hwnd, subclassproc, id);
break;
Expand Down Expand Up @@ -270,16 +270,16 @@ namespace fgo::editbox_tweaker
// この構造体は::DispatchMesageA()を::DispatchMesageW()に置き換えるために使用されます。
//
struct {
inline static decltype(&::DispatchMessageA) hook = ::DispatchMessageW;
inline static decltype(hook) orig = ::DispatchMessageA;
constexpr static auto& hook = ::DispatchMessageW;
inline static decltype(&hook) orig = ::DispatchMessageA;
} DispatchMessageA;

//
// この構造体は::PeekMesageA()を::PeekMesageW()に置き換えるために使用されます。
//
struct {
inline static decltype(&::PeekMessageA) hook = ::PeekMessageW;
inline static decltype(hook) orig = ::PeekMessageA;
constexpr static auto& hook = ::PeekMessageW;
inline static decltype(&hook) orig = ::PeekMessageA;
} PeekMessageA;
} servant;
}
22 changes: 22 additions & 0 deletions Nest/Container/Container.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,13 +357,35 @@ namespace fgo::nest

break;
}
case WM_KEYDOWN:
case WM_KEYUP:
case WM_CHAR:
case WM_DEADCHAR:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_SYSCHAR:
case WM_SYSDEADCHAR:
{
// モーダルダイアログを閉じた直後などで
// ショートカットキーが利かなくなっていた問題に対処.
// メッセージをAviUtlのメインウィンドウに転送します.
return ::SendMessage(hive.aviutlWindow, message, wParam, lParam);
}
case WM_ACTIVATE:
case WM_COMMAND:
case WM_CLOSE:
{
// メッセージをそのままターゲットウィンドウに転送します。
return ::SendMessage(content->getHWND(), message, wParam, lParam);
}
case WM_SYSCOMMAND:
{
// Windows 標準のコマンドでないならターゲットウィンドウに転送して処理させます.
// これでサブウィンドウタイトルの右クリックメニューから名前の変更ができます.
if (wParam < 0xF000)
::PostMessage(content->getHWND(), message, wParam, lParam);
break;
}
}

switch (message)
Expand Down
23 changes: 20 additions & 3 deletions Nest/DockSite.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,14 +400,26 @@ namespace fgo::nest

if (id)
{
// 原点を切り替えたときボーダーの位置が変わらないよう調整します.
constexpr auto flip_border = [](auto& pane, int origin) {
if (pane->origin == origin) return;
pane->origin = origin;
if (pane->splitMode == Pane::SplitMode::none) return;

pane->border = -pane->borderWidth - pane->border;
switch (pane->splitMode) {
case Pane::SplitMode::horz: pane->border += pane->position.bottom - pane->position.top; break;
case Pane::SplitMode::vert: pane->border += pane->position.right - pane->position.left; break;
}
};
switch (id)
{
case CommandID::SPLIT_MODE_NONE: pane->setSplitMode(Pane::SplitMode::none); break;
case CommandID::SPLIT_MODE_VERT: pane->setSplitMode(Pane::SplitMode::vert); break;
case CommandID::SPLIT_MODE_HORZ: pane->setSplitMode(Pane::SplitMode::horz); break;

case CommandID::ORIGIN_TOP_LEFT: pane->origin = Pane::Origin::topLeft; break;
case CommandID::ORIGIN_BOTTOM_RIGHT: pane->origin = Pane::Origin::bottomRight; break;
case CommandID::ORIGIN_TOP_LEFT: flip_border(pane, Pane::Origin::topLeft); break;
case CommandID::ORIGIN_BOTTOM_RIGHT: flip_border(pane, Pane::Origin::bottomRight); break;

case CommandID::MOVE_TO_LEFT: pane->moveTab(ht, ht - 1); break;
case CommandID::MOVE_TO_RIGHT: pane->moveTab(ht, ht + 1); break;
Expand Down Expand Up @@ -705,8 +717,13 @@ namespace fgo::nest
{
// クリックされたペインがシャトルを持っているなら
Shuttle* shuttle = pane->getCurrentShuttle();
if (shuttle)
if (shuttle) {
::SetFocus(*shuttle); // そのシャトルにフォーカスを当てます。
if (pane->hitTestCaption(point))
// キャプションをクリックしたときは,
// その親のサブウィンドウにフォーカスが移らないよう処理済み扱いにします.
return 0;
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions Nest/Pane/Pane.h
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,11 @@ namespace fgo::nest
break;
}
}
if (limited)
// タブコントロールのサイズが変わらないと再描画が行われないらしい.
// 最大化モードで再描画を抑制中にレイアウトした後で移動が起こった場合,
// アーティファクトが残っていたので対処.
::InvalidateRect(tab, nullptr, FALSE);
}
// タブが1個以下なら
else
Expand Down
48 changes: 48 additions & 0 deletions Nest/SubWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,23 @@ namespace fgo::nest
parent, 0, hive.instance, 0);
}

//
// Shuttle の init() を呼び出して,システムメニューに項目を追加します.
//
void init(const _bstr_t& name, HWND hwnd) {
__super::init(name, hwnd);

// フローティングコンテナのアイコンを設定します。
HICON icon = (HICON)::GetClassLong(hive.aviutlWindow, GCL_HICON);
::SendMessage(*floatContainer, WM_SETICON, ICON_SMALL, (LPARAM)icon);
::SendMessage(*floatContainer, WM_SETICON, ICON_BIG, (LPARAM)icon);

// フローティングコンテナのシステムメニューにメニュー項目とセパレータを追加します.
HMENU menu = ::GetSystemMenu(*floatContainer, FALSE);
::InsertMenu(menu, 0, MF_BYPOSITION | MF_STRING, CommandID::RENAME_SUB_WINDOW, _T("名前を変更"));
::InsertMenu(menu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
}

//
// ウィンドウプロシージャです。
//
Expand All @@ -67,6 +84,37 @@ namespace fgo::nest
// これにより、現存するすべてのサブウィンドウにアクセスできるようになります。
subWindowManager.add(hwnd);

break;
}
case WM_KEYDOWN:
case WM_KEYUP:
case WM_CHAR:
case WM_DEADCHAR:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_SYSCHAR:
case WM_SYSDEADCHAR:
{
// Nest の MainWindow にフォーカスがある状態から
// フロート状態の SubWindow のタイトルをクリックしてフォーカスを移動すると,
// ショートカットキーが利かなくなっていた問題に対処.
// メッセージをAviUtlのメインウィンドウに転送します.
return ::SendMessage(hive.aviutlWindow, message, wParam, lParam);
}
case WM_SYSCOMMAND:
{
// SubWindow を保持する Container クラスから送られてきます.
switch (wParam) {
case CommandID::RENAME_SUB_WINDOW:
{
auto container = getCurrentContainer();
if (!container) break;

// サブウィンドウの名前変更ダイアログを表示します.
shuttleManager.showRenameDialog(this, *container);
break;
}
}
break;
}
case WM_CLOSE:
Expand Down