创建不可见且无模式的属性表会导致焦点更改?
我正在调查与失去焦点和更改窗口激活有关的问题.我发现如果我创建一个不可见的属性表,活动/前景窗口会发生变化,焦点窗口也会发生变化.下面是一些示例 MFC 代码:
I was investigating an issue related to losing focus and changing activation of windows. What I found was that if I create an invisible property sheet, the active/foreground window changes and so does the focus window. Here is some sample MFC code:
// ignore CAutoDeleter, just a template that calls "delete this " in PostNcDestroy()
CPropertySheet* pSheet = new CAutoDeleter<CPropertySheet>(_T("Test Sheet"));
CTestPage* pPage = new CAutoDeleter<CTestPage>();
pSheet->AddPage(pPage);
DWORD style = WS_SYSMENU | WS_POPUP | WS_CAPTION | DS_MODALFRAME | DS_CONTEXTHELP;
// style |= WS_DISABLED; //does nothing to help
DWORD exStyle = 0;
//exStyle = WS_EX_NOPARENTNOTIFY|WS_EX_NOACTIVATE; // does nothing to help
pSheet->Create(AfxGetMainWnd(), style, exStyle); // adding
调用 pSheet->Create() 后,活动/前景/焦点窗口发生了变化,应用程序窗口位于顶部.如果我使用 Spy++ 并查看创建的窗口,就会发现属性表是一个 DIALOG 窗口类.当然,我假设它有不同的 WNDPROC.有趣的是,如果我使用创建一个不可见的无模式对话框,它不会出现问题.如果我创建不可见的无模式对话框,则活动/前景/焦点窗口保持不变.
After the call to pSheet->Create(), the active/foreground/focus window has changed and the application window is on top. If I use Spy++ and look at the window that is created, it turns out that a property sheet is a DIALOG window class. I am assuming it has a different WNDPROC, of course. What is interesting, is if I create an invisible modeless dialog using, it does not exhibit the problem. If I create the invisible modeless dialog, the active/foreground/focus window remains the same.
我尝试在代码片段中设置各种标志,但可惜它们没有任何明显的效果――我仍然有闪烁和激活的废话.
I tried setting various flags as in the code snippet, but alas they did not have any discernible effect--I still had the flashing and activation non-sense.
我可以通过在 pSheet->Create()
之前和之后设置和清除一个钩子 (WH_CBT) 来获得一些改进――然后吃掉激活消息.当我这样做时,我没有可怕的闪烁,我的应用程序窗口也没有到达顶部.但是,焦点(以及具有插入符号的窗口的插入符号)确实会从 Create() 之前拥有它的任何窗口消失.
I could get some improvement by setting and clearing a hook (WH_CBT) before and after pSheet->Create()
--and then eating the activation messages. When I do that, I don't have the horrible flashing and my application window does not come to the top. However, the focus (and caret for windows that have carets) does go away from whichever window had it before the Create().
有没有人知道在创建不可见的属性表时保持焦点和激活不变的方法?(在某些时候,属性表可能设置为可见,也可能不设置.而且,如果属性表在销毁时不可见,也会导致闪烁和激活变化.)
Does anyone know a way to keep the focus and activation unchanged when creating an invisible property sheet? (At some point, the property sheet may or may not be set visible. And, if the property sheet is invisible when being destroyed, it also causes the blinking and activation changes.)
我尝试使用 GetUIThreadInfo() 中返回的值来尝试在调用 Create() 后恢复内容,但它也会导致一些闪烁.
I tried using the values returned in GetUIThreadInfo() to try and restore things after the call to Create(), but it causes some flashing as well.
我只想知道如何创建一个不可见的属性表,它不会导致活动、前景和焦点窗口发生变化.
I just want to know how to create an invisible Property Sheet which won't cause the active, foreground, and focus window to change.
推荐答案
可惜底层API函数PropertySheet
调用 SetForegroundWindow
在创建后的主属性表对话框中.解决这个问题没有简单的方法 - 你的 WH_CBT
钩子可能是你最好的选择.
Unfortunately the underlying API function PropertySheet
calls SetForegroundWindow
on the main property sheet dialog after creation. There's no easy way around this - your kludge with the WH_CBT
hook is probably your best option.
正如@stephen 在对 这个重复问题的评论中所建议的那样,您可以使用 LockSetForegroundWindow
.
As suggested by @stephen in the comments on this duplicate question, you may be able to prevent the activation/focus change using LockSetForegroundWindow
.
相关文章