Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 507
  • Last Modified:

Property page activation

I have a modeless property sheet that I use to display properties for selected items in a tree view. Whenever the tree view selection changes, the pages in the sheet are updated. (New pages may be added and irrelevant pages may be removed)
Because of the dynamic nature of the sheet pages, sometimes an active page may be removed when the user changes the selection.
This causes the sheet to make another page active. When this happens, the sheet window is made active.
This is not what I want because the user still expects to have the focus in the tree view.
I tried to prevent the sheet window activation by handling the WM_WINDOWPOSCHANGING message but it didn't work (I added the SWP_NOACTIVATE flag).
Using Spy++ I see that the sheet gets the WM_WINDOWPOSCHANGING and WM_ACTIVATE messages.

Do you know of a way I can prevent window activation? Or is there another way to work arround tis property sheet behaviour?
0
Shami
Asked:
Shami
  • 5
  • 3
  • 3
  • +2
1 Solution
 
guruprasad031298Commented:
Let's say the tree control member of your tree view is m_pTreeCtrl, then after finishing the processing of updating the property sheet, just call m_pTreeCtrl->SetActiveWindow(). This should reclaim the activity back to the tree view.

Hope this helps !!!
0
 
ShamiAuthor Commented:
I already thought of this and actually this is my workarround currently but this causes window flashes as the sheet window gets focus and then I return the focus to the view (The window title flashes).
I'm looking for a way to prevent activation of the sheet window.
0
 
gelbertCommented:
Try to handle OnActivate() in your property page derived class.
void YourProertyPage::OnActivate( UINT nState, CWnd* pWnd, ... )
{
    if (WA_ACTIVE == nState )
    {
      // set focus back
      SetFocus( pWnd );
    }
    .......
}
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
ShamiAuthor Commented:
Setting the focus back to the old active window will flash the window titles. This workarround is not acceptable.
0
 
piano_boxerCommented:
You may solve the problem by preventing the property sheet window from receiving the deactivate message WM_NCACTIVATE.

Override the WM_NCACTIVATE message in you property sheet class.
Add a bool (m_bAllowNcActivate) that determines if the base-class handler for WM_NCACTIVATE should be called.

BOOL CMySheet::OnNcActivate(BOOL bActive)
{
    if(m_bAllowNcActivate)
        return CPropertySheet::OnNcActivate(bActive);
    return 0;
}

Set this bool to TRUE as default (in the constructor).

Now, when you modify the page-layout (where you have the problem) set the m_bAllowNcActivate to FALSE. before adding or removing pages and back to true after.

0
 
piano_boxerCommented:
I tried to handle the WM_NCACTIVATE the way you offered.
Sometimes the title bar does not repaint and sometimes it does.
Anyway, this workarround still leaves me with a focus problem so I had to call SetActiveWindow for the old window, which caused the title to be repainted. I tried to handle WM_NCACTIVATE for the window that loses the focus as well, but sometimes the focus still goes to the sheet (This maybe happens after I finish changing the pages).
0
 
ShamiAuthor Commented:
OK. If you could create a sample app and E-mail it to me it would be at lot easier for me to help you. (You can se my E-mail by clicking on piano_boxer).
0
 
piano_boxerCommented:
Have you considered using a thread-specific Windows event hook?  Installing a CBT hook that processes HCBT_ACTIVATE and HCBT_SETFOCUS events should give you absolute control over input focus and window activation.

See "Win32 Platform SDK \ Windows Base Services \ Interprocess Communication \ Hooks" for more information.

Read the documentation for the following:
SetWindowsHookEx()
WH_CBT
CBTProc

Good luck,

Forest

0
 
fwilkinsonCommented:
Did something go wrong when you sent the answer? Why is it empty?
0
 
ShamiAuthor Commented:
[Upon returning here, the answer I sent appears intact.  I don't know why it showed up empty for you, but here it is again.  -Forest]

Have you considered using a thread-specific Windows event hook?  Installing
a CBT hook that processes HCBT_ACTIVATE and HCBT_SETFOCUS events
should give you absolute control over input focus and window activation.

For more information, see Win32 Platform SDK: Windows Base
Services / Interprocess Communication / Hooks.

Read the documentation for the following:
SetWindowsHookEx()
WH_CBT
CBTProc

Good luck,

Forest
0
 
fwilkinsonCommented:
I don't know why my answer keeps showing up empty, but you can now see it as a "rejected answer", a couple of frames above.
0
 
fwilkinsonCommented:
The CBTProc documentation specify that CBTProc must be in a DLL (in the remarks section).
Do you have an idea if this is true only for global CBT hooks or for any CBTProc? (I really don't want to write a DLL because I need to monitor messages only for one thread).
0
 
ShamiAuthor Commented:
The CBTProc doesn't have to be in a DLL if you're only going to hook your own application's messages.  If your CBTProc is in your EXE, and you want to hook the current thread, you can do something like this:

hook_handle = SetWindowsHookEx( WH_CBT, CBTProc, NULL,
        AfxGetThread()->m_nThreadID);


0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 5
  • 3
  • 3
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now