Noob
Noob

Reputation: 23

How to get Hotkey for background MFC app to show

I create a MFC App that can hide (SHIFT+W) or show (SHIFT+A) if I press hot key. By default it's hidden when startup. I search the solution and find it:

// OnPaint to paint the app and hide
void CAppDlg::OnPaint()
{
    ShowWindow(SW_HIDE);
}

// Register the Hotkey when app startup
BOOL CAppDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    RegisterHotKey(CAppDlg::m_hWnd, 1001, MOD_SHIFT, 'A');
    RegisterHotKey(CAppDlg::m_hWnd, 1002, MOD_SHIFT, 'a');
}

// Get SHIFT+W to hide app again
BOOL CAppDlg::PreTranslateMessage(MSG* pMsg){
    if (pMsg->message == WM_KEYDOWN){
        if (pMsg->wParam == 0x57){
            if (GetKeyState(VK_SHIFT) & 0x8000) {
                ShowWindow(SW_HIDE);
            }   
        }
    }

    return CDialog::PreTranslateMessage(pMsg);
}

// Get hotkey id (SHIFT+A) to show app
LRESULT CAppDlg::OnHotKey(WPARAM wParam, LPARAM lParam){
    if (wParam == 1001 || wParam == 1002){
        ShowWindow(SW_SHOWNORMAL);
    }
    return 0;
}

This app will hide when startup, function ShowWindow(SW_HIDE) must be declared in OnPaint() function, if it's declared in OnInitDialog() it's not hidden. But if I press SHIFT+A to show windows, it shows and hide right away (because of OnPaint() function is recalled). How can I do now? Thank all

Upvotes: 1

Views: 150

Answers (1)

Vlad Feinstein
Vlad Feinstein

Reputation: 11311

Here is how you can hide a main window of the dialog-based MFC app.

Add bool member variable to your dialog class:

bool m_bFirst = true;

Add handler for WM_WINDOWPOSCHANGING message to your BEGIN_MESSAGE_MAP:

ON_WM_WINDOWPOSCHANGING()

and declare it in the header file

afx_msg void OnWindowPosChanging(WINDOWPOS* lpwndpos);

You can use a Class Wizard to add it to your class.

In the handler, enforce a flag to hide the window until you get a first hot key message:

void CMFCApplicationDlg::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
    if (m_bFirst) {
        lpwndpos->flags &= ~SWP_SHOWWINDOW;
        lpwndpos->flags |= SWP_HIDEWINDOW;
    }
    CDialogEx::OnWindowPosChanging(lpwndpos);
}

And finally reset that flag in your WM_HOTKEY handler:

void CMFCApplicationDlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
    if (nHotKeyId == 1001) {
        m_bFirst = false;
        ShowWindow(SW_SHOW);
    }
    else if (nHotKeyId == 1002)
        ShowWindow(SW_HIDE);
}

NOTE:

I would strongly advise against using simple MOD_SHIFT modifier for the hot key: you will no longer be able to type upper-case A into any other apps.

Upvotes: 2

Related Questions