Domanda

Generally I have some button that opens child window and the second press on this button should close it. I use a touch screen.

The problem is when I try to press the button for closing the child window, it is not pressed the first time, so I need another click.

In order to fix this I am trying to return the focus to the parent window after the child window is opened.

I register the OnShowWindow message and call SetFocus on the parent window:

void CFlashGuidanceSteps::OnShowWindow(BOOL bShow, UINT nStatus)
{
    CDialog::OnShowWindow(bShow, nStatus);
    GetParent()->SetFocus();
}

While the function is called (I can see it in debugger), the focus is not returned to the parent window.

However, it works with the OnSetFocus event:

void CFlashGuidanceSteps::OnSetFocus(CWnd* pOldWnd)
{
    CDialog::OnSetFocus(pOldWnd);
    GetParent()->SetFocus();
}

Why is the focus is not retained with the OnShowWindow event?

È stato utile?

Soluzione

The explanation

The usual rule in MFC is that OnXxx functions are called in response to similarly named window messages, e.g. WM_Xxx. So OnShowWindow would be called in response to WM_SHOWWINDOW.

And according to the documentation, WM_SHOWWINDOW is

Sent to a window when the window is about to be hidden or shown.

That means it is sent before the window is actually shown. So when you set the focus to the parent window inside of the OnShowWindow function, nothing actually happens because the parent window already has the focus. Then, after OnShowWindow finishes running, the child window is displayed and demands the focus. It is as if you never made any attempt to change the focus.

By contrast, OnSetFocus, which corresponds to WM_SETFOCUS, is not called until after the window has gained the focus. So when you reassign the focus here, it works because the child window doesn't steal the focus back.

The better idea

That explains the behavior you are seeing, and as you know, things work fine when you adjust the focus in OnSetFocus. But this really isn't the best way of solving the problem.

Manually changing the focus when a window gets and/or loses the focus is approaching the problem the wrong way around, and generally error-prone. You'll get all kinds of focus-related bugs that are difficult to debug. You are better off looking for ways to prevent the focus from changing when you don't want it to.

It sounds to me like you want to prevent the child window from getting the focus when it is created. And there is a way to do precisely that.

When you display the child window, presumably by calling the ShowWindow function or its moral equivalent in MFC, you should pass the SW_SHOWNA flag. That causes the window to be shown without activating it (i.e., granting it the focus).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top