[Scummvm-git-logs] scummvm branch-3-0 -> 7a94d82be14991f56249f95c5e670983efe20df8
dreammaster
noreply at scummvm.org
Fri Dec 26 20:34:26 UTC 2025
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
7a94d82be1 BAGEL: MFC: Fix Enter/Escape triggering default dialog actions
Commit: 7a94d82be14991f56249f95c5e670983efe20df8
https://github.com/scummvm/scummvm/commit/7a94d82be14991f56249f95c5e670983efe20df8
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2025-12-27T07:34:16+11:00
Commit Message:
BAGEL: MFC: Fix Enter/Escape triggering default dialog actions
Changed paths:
engines/bagel/mfc/afxwin.h
engines/bagel/mfc/dialog.cpp
engines/bagel/mfc/edit.cpp
engines/bagel/mfc/libs/event_loop.cpp
engines/bagel/mfc/libs/event_loop.h
engines/bagel/mfc/win_app.cpp
engines/bagel/mfc/winnt.h
diff --git a/engines/bagel/mfc/afxwin.h b/engines/bagel/mfc/afxwin.h
index ab08bd289fb..242c2fee9d7 100644
--- a/engines/bagel/mfc/afxwin.h
+++ b/engines/bagel/mfc/afxwin.h
@@ -50,6 +50,7 @@ namespace MFC {
constexpr uint32 DEFAULT_MODAL_RESULT = MKTAG('S', 'C', 'V', 'M');
class CBitmap;
+class CButton;
class CCmdTarget;
class CCmdUI;
class CDC;
@@ -1430,6 +1431,10 @@ public:
}
void DestroyWindow();
void Invalidate(bool bErase = true);
+
+ // Message processing for modeless dialog-like windows
+ virtual bool IsDialogMessage(LPMSG lpMsg) { return false; }
+
int GetWindowText(CString &rString) const;
int GetWindowText(char *lpszStringBuf, int nMaxCount) const;
bool SetWindowText(const char *lpszString);
@@ -1610,7 +1615,11 @@ private:
HINSTANCE hInst);
bool CreateDlgIndirect(LPCDLGTEMPLATE lpDialogTemplate,
CWnd *pParentWnd, HINSTANCE hInst);
- CWnd *GetDefaultPushButton() const;
+ CButton *GetDefaultPushButton() const;
+
+ bool handleEnterKey(LPMSG lpMsg);
+ bool handleEscapeKey(LPMSG lpMsg);
+ void sendButtonClicked(CButton *btn);
protected:
DECLARE_MESSAGE_MAP()
@@ -1640,7 +1649,7 @@ public:
virtual bool OnInitDialog() {
return true;
}
- bool PreTranslateMessage(MSG *pMsg) override;
+ bool IsDialogMessage(LPMSG lpMsg) override;
uint32 GetDefID() const;
void SetDefID(unsigned int nID);
@@ -1750,6 +1759,7 @@ public:
afx_msg void OnSetFocus(CWnd *pOldWnd);
afx_msg void OnKillFocus(CWnd *pNewWnd);
afx_msg void OnTimer(uintptr nTimerId);
+ afx_msg unsigned int OnGetDlgCode();
};
class CScrollBar : public CWnd {
diff --git a/engines/bagel/mfc/dialog.cpp b/engines/bagel/mfc/dialog.cpp
index 131c9f2c938..8969309c5d9 100644
--- a/engines/bagel/mfc/dialog.cpp
+++ b/engines/bagel/mfc/dialog.cpp
@@ -28,13 +28,13 @@ namespace MFC {
IMPLEMENT_DYNAMIC(CDialog, CWnd)
BEGIN_MESSAGE_MAP(CDialog, CWnd)
-ON_COMMAND(IDOK, CDialog::OnOK)
-ON_COMMAND(IDCANCEL, CDialog::OnCancel)
-ON_MESSAGE(WM_INITDIALOG, CDialog::HandleInitDialog)
-ON_MESSAGE(WM_SETFONT, CDialog::HandleSetFont)
-ON_WM_SYSCHAR()
-ON_WM_CLOSE()
-ON_WM_ACTIVATE()
+ ON_COMMAND(IDOK, CDialog::OnOK)
+ ON_COMMAND(IDCANCEL, CDialog::OnCancel)
+ ON_MESSAGE(WM_INITDIALOG, CDialog::HandleInitDialog)
+ ON_MESSAGE(WM_SETFONT, CDialog::HandleSetFont)
+ ON_WM_SYSCHAR()
+ ON_WM_CLOSE()
+ ON_WM_ACTIVATE()
END_MESSAGE_MAP()
CDialog::CDialog(const char *lpszTemplateName, CWnd *pParentWnd) {
@@ -52,7 +52,7 @@ CDialog::CDialog(unsigned int nIDTemplate, CWnd *pParentWnd) {
}
bool CDialog::Create(const char *lpszTemplateName,
- CWnd *pParentWnd) {
+ CWnd *pParentWnd) {
m_lpszTemplateName = lpszTemplateName; // used for help
SetParent(pParentWnd);
@@ -109,7 +109,7 @@ int CDialog::DoModal() {
m_pParentWnd = AfxGetApp()->m_pMainWnd;
if (CreateDlgIndirect(lpDialogTemplate,
- this /*m_pParentWnd*/, hInst)) {
+ this /*m_pParentWnd*/, hInst)) {
AfxGetApp()->doModal(this);
}
@@ -221,42 +221,16 @@ LRESULT CDialog::HandleSetFont(WPARAM wParam, LPARAM) {
return 0;
}
-bool CDialog::PreTranslateMessage(MSG *pMsg) {
- if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) {
- CWnd *pFocus = GetFocus();
-
- // Special case: prevent multi-line edit controls from handling Enter
- if (pFocus && pFocus->IsKindOf(RUNTIME_CLASS(CEdit))) {
- uint32 style = pFocus->GetStyle();
- if ((style & ES_MULTILINE) == 0) {
- // Not a multi-line edit box - simulate default pushbutton
- CWnd *pDefault = GetDefaultPushButton();
- if (pDefault) {
- pDefault->SendMessage(WM_COMMAND, MAKEWPARAM(IDOK, BN_CLICKED), (LPARAM)pDefault->m_hWnd);
-
- } else {
- // No button - just call OnOK directly
- OnOK();
- }
+CButton *CDialog::GetDefaultPushButton() const {
+ for (auto &child : _children) {
+ CButton *pChild = dynamic_cast<CButton *>(child._value);
- return true;
+ if (pChild) {
+ uint32 style = pChild->GetStyle();
+ if ((style & BS_DEFPUSHBUTTON) && pChild->GetDlgCtrlID() == IDOK) {
+ return pChild;
}
}
- } else if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) {
- OnCancel();
- return true;
- }
-
- return CWnd::PreTranslateMessage(pMsg);
-}
-
-CWnd *CDialog::GetDefaultPushButton() const {
- for (auto &child : _children) {
- CWnd *pChild = child._value;
- uint32 style = pChild->GetStyle();
- if ((style & BS_DEFPUSHBUTTON) && pChild->GetDlgCtrlID() == IDOK) {
- return pChild;
- }
}
return nullptr;
@@ -267,7 +241,7 @@ void CDialog::DDX_Control(CDataExchange *pDX, int nIDC, CWnd &rControl) {
}
void CDialog::DDX_Radio(CDataExchange *pDX,
- int nIDCButton1, int &value) {
+ int nIDCButton1, int &value) {
error("TODO: CDialog::DDX_Radio");
}
@@ -297,12 +271,12 @@ void CDialog::DDX_Text(CDataExchange *pDX, int nIDC, double &value) {
}
void CDialog::DDX_Check(CDataExchange *pDX,
- int nIDC, bool value) {
+ int nIDC, bool value) {
error("CDialog::DDX_Check");
}
void CDialog::DDV_MinMaxInt(CDataExchange *pDX,
- int value, int nMin, int nMax) {
+ int value, int nMin, int nMax) {
error("TODO: CDialog::DDV_MinMaxInt");
}
@@ -331,12 +305,12 @@ void CDialog::OnCancel() {
}
bool CDialog::CreateIndirect(LPCDLGTEMPLATE lpDialogTemplate,
- CWnd *pParentWnd, void *lpDialogInit, HINSTANCE hInst) {
+ CWnd *pParentWnd, void *lpDialogInit, HINSTANCE hInst) {
error("TODO: CDialog::CreateIndirect");
}
bool CDialog::CreateIndirect(HGLOBAL hDialogTemplate,
- CWnd *pParentWnd, HINSTANCE hInst) {
+ CWnd *pParentWnd, HINSTANCE hInst) {
error("TODO: CDialog::CreateIndirect");
}
@@ -374,5 +348,68 @@ void CDialog::OnActivate(unsigned int nState, CWnd *pWndOther, bool bMinimized)
CWnd::OnActivate(nState, pWndOther, bMinimized);
}
+bool CDialog::IsDialogMessage(LPMSG lpMsg) {
+ if (lpMsg->message != WM_KEYDOWN)
+ return false;
+
+ switch (lpMsg->wParam) {
+ case VK_RETURN:
+ return handleEnterKey(lpMsg);
+
+ case VK_ESCAPE:
+ return handleEscapeKey(lpMsg);
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool CDialog::handleEnterKey(LPMSG lpMsg) {
+ HWND hFocus = GetFocus();
+ if (!hFocus)
+ return false;
+
+ // Ask control what it wants
+ LRESULT dlgCode = MFC::SendMessage(hFocus, WM_GETDLGCODE,
+ lpMsg->wParam, (LPARAM)lpMsg);
+
+ // If control wants Enter, do nothing
+ if (dlgCode & DLGC_WANTMESSAGE)
+ return false;
+
+ // Multiline edits implicitly want Enter
+ if (dlgCode & DLGC_HASSETSEL)
+ return false;
+
+ // Find default push button
+ CButton *pDefault = GetDefaultPushButton();
+ if (!pDefault)
+ return false;
+
+ if (!pDefault->IsWindowEnabled())
+ // consume Enter, do nothing
+ return true;
+
+ // Simulate button click
+ sendButtonClicked(pDefault);
+ return true;
+}
+
+bool CDialog::handleEscapeKey(LPMSG lpMsg) {
+ CButton *pCancel = dynamic_cast<CButton *>(GetDlgItem(IDCANCEL));
+ if (!pCancel || !pCancel->IsWindowEnabled())
+ return true;
+
+ sendButtonClicked(pCancel);
+ return true;
+}
+
+void CDialog::sendButtonClicked(CButton *btn) {
+ int id = btn->GetDlgCtrlID();
+ SendMessage(WM_COMMAND, MAKEWPARAM(id, BN_CLICKED), (LPARAM)btn->m_hWnd);
+}
+
} // namespace MFC
} // namespace Bagel
diff --git a/engines/bagel/mfc/edit.cpp b/engines/bagel/mfc/edit.cpp
index e65db37faf8..1c124849785 100644
--- a/engines/bagel/mfc/edit.cpp
+++ b/engines/bagel/mfc/edit.cpp
@@ -35,6 +35,7 @@ ON_WM_CHAR()
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
ON_WM_TIMER()
+ON_WM_GETDLGCODE()
END_MESSAGE_MAP()
bool CEdit::Create(uint32 dwStyle, const RECT &rect, CWnd *pParentWnd, unsigned int nID) {
@@ -141,5 +142,14 @@ void CEdit::OnTimer(uintptr nTimerId) {
Invalidate();
}
+unsigned int CEdit::OnGetDlgCode() {
+ uint style = GetStyle();
+
+ if (style & ES_MULTILINE)
+ return DLGC_WANTMESSAGE | DLGC_HASSETSEL;
+
+ return 0;
+}
+
} // namespace MFC
} // namespace Bagel
diff --git a/engines/bagel/mfc/libs/event_loop.cpp b/engines/bagel/mfc/libs/event_loop.cpp
index a8965fa6e63..088950f4e04 100644
--- a/engines/bagel/mfc/libs/event_loop.cpp
+++ b/engines/bagel/mfc/libs/event_loop.cpp
@@ -31,7 +31,7 @@ namespace Libs {
#define FRAME_RATE 50
-void EventLoop::runEventLoop() {
+void EventLoop::runEventLoop(bool isModalDialog) {
MSG msg;
while (!shouldQuit() && !_activeWindows.empty()) {
@@ -43,7 +43,8 @@ void EventLoop::runEventLoop() {
break;
CWnd *mainWnd = GetActiveWindow();
- if (msg.message != WM_NULL && mainWnd && !mainWnd->PreTranslateMessage(&msg)) {
+ if (msg.message != WM_NULL && mainWnd && !mainWnd->PreTranslateMessage(&msg) &&
+ (!isModalDialog || !mainWnd->IsDialogMessage(&msg))) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
@@ -90,7 +91,7 @@ void EventLoop::PopActiveWindow() {
void EventLoop::doModal(CWnd *wnd) {
SetActiveWindow(wnd);
- runEventLoop();
+ runEventLoop(true);
if (GetActiveWindow() == wnd)
wnd->DestroyWindow();
}
diff --git a/engines/bagel/mfc/libs/event_loop.h b/engines/bagel/mfc/libs/event_loop.h
index a58f1fb700b..68a154c1965 100644
--- a/engines/bagel/mfc/libs/event_loop.h
+++ b/engines/bagel/mfc/libs/event_loop.h
@@ -167,7 +167,7 @@ public:
EventLoop() {}
virtual ~EventLoop() {}
- void runEventLoop();
+ void runEventLoop(bool isModalDialog);
void SetActiveWindow(CWnd *wnd);
void PopActiveWindow();
CWnd *GetActiveWindow() const {
diff --git a/engines/bagel/mfc/win_app.cpp b/engines/bagel/mfc/win_app.cpp
index 6d7e82c6c37..6a2a51c2525 100644
--- a/engines/bagel/mfc/win_app.cpp
+++ b/engines/bagel/mfc/win_app.cpp
@@ -168,7 +168,7 @@ int CWinApp::Run() {
SetActiveWindow(m_pMainWnd);
}
- runEventLoop();
+ runEventLoop(false);
SaveAllModified();
ExitInstance();
diff --git a/engines/bagel/mfc/winnt.h b/engines/bagel/mfc/winnt.h
index 5d18320be6f..2fd045aa471 100644
--- a/engines/bagel/mfc/winnt.h
+++ b/engines/bagel/mfc/winnt.h
@@ -652,6 +652,23 @@ typedef struct _GUID {
#define AFX_IDW_PANE_SAVE 0xEA21 // to shift AFX_IDW_PANE_FIRST
#define AFX_WS_DEFAULT_VIEW (WS_CHILD | WS_VISIBLE)
+
+/*
+ * Dialog Codes
+ */
+#define DLGC_WANTARROWS 0x0001 /* Control wants arrow keys */
+#define DLGC_WANTTAB 0x0002 /* Control wants tab keys */
+#define DLGC_WANTALLKEYS 0x0004 /* Control wants all keys */
+#define DLGC_WANTMESSAGE 0x0004 /* Pass message to control */
+#define DLGC_HASSETSEL 0x0008 /* Understands EM_SETSEL message */
+#define DLGC_DEFPUSHBUTTON 0x0010 /* Default pushbutton */
+#define DLGC_UNDEFPUSHBUTTON 0x0020 /* Non-default pushbutton */
+#define DLGC_RADIOBUTTON 0x0040 /* Radio button */
+#define DLGC_WANTCHARS 0x0080 /* Want WM_CHAR messages */
+#define DLGC_STATIC 0x0100 /* Static item: don't include */
+#define DLGC_BUTTON 0x2000 /* Button item: can be checked */
+
+
typedef struct tagTEXTMETRICA {
long tmHeight = 0;
long tmAscent = 0;
More information about the Scummvm-git-logs
mailing list