Is there a standard way to handle this situation? I ask because in Notepad++ the hotkey F3> still works even when the Find popup window has focus.
In my application the main dialog is using the accelerator table to map F3> to a resource ID which is subsequently mapped to the function performing the find action.
But, pressing F3> when the modeless Find window is focussed with not trigger the find as it eats the hotkey itself. From my perspective I think I have two approaches:
PreTranslateMessage
to detect the hotkey and post a message that way.Is there any other approach that one can use with MFC architecture? I don't think using RegisterHotkey
is the way to go, but I could be wrong!
Actually, using RegisterHotKey
etc. was the way to go!
I added the following functions to my MSAFind
namespace:
// Registers hotkeys (CTRL+F and F3) for find and repeat commands.
static void RegisterHotKeys(HWND hWnd) {
if (!RegisterHotKey(hWnd, ID_EDIT_FIND, MOD_CONTROL, 'F')) {
TRACE(L"Failed to register CTRL + F as a hotkey!\n");
}
if (!RegisterHotKey(hWnd, ID_EDIT_REPEAT, 0, VK_F3)) {
TRACE(L"Failed to register F3 as a hotkey!\n");
}
}
// Unregisters the hotkeys to release associated resources.
static void UnregisterHotKeys(HWND hWnd) noexcept {
UnregisterHotKey(hWnd, ID_EDIT_FIND);
UnregisterHotKey(hWnd, ID_EDIT_REPEAT);
}
// Processes hotkey events and triggers the corresponding actions.
static void OnHotKey(CWnd* pWnd, UINT nHotKeyId, UINT nKey1, UINT nKey2) {
if (pWnd) {
switch (nHotKeyId)
{
case ID_EDIT_FIND:
pWnd->PostMessage(WM_COMMAND, ID_EDIT_FIND);
break;
case ID_EDIT_REPEAT:
pWnd->PostMessage(theApp.UWM_FIND_NEXT_MSG);
break;
default:
// Log an error, display a message, or take no action for unrecognized hotkey IDs.
TRACE(L"Unhandled hotkey ID: %u\n", nHotKeyId);
break;
}
}
}
And, I call them respectively in my respective dialog classes that invoke Find functionality. This approach works fine and the hotkeys work, irrespective of the popup having focus.
I take onboard the comments made about the side-effect of using RegisterHotkey
being system wide. In which case the simplest solution is to use PreTranslateMessage
:
BOOL CMyFindDialog::PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_F3)
{
// Handle the F3 key press here
CWnd* pWnd = GetParent();
if (pWnd) {
pWnd->PostMessage(theApp.UWM_FIND_NEXT_MSG);
}
return true; // Message handled
}
return __super::PreTranslateMessage(pMsg);
}