Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS Tech Support » Auto-hide tab buttons disappearing in my main frame. Collapse All
Subject Author Date
Daisy Peterson May 16, 2008 - 1:05 PM

I have no idea what is causing this, and I cannot reproduce it in your sample application.


Our main frame has been updated to use Prof-UIS, even though the frame class itself is from another library.  This class ultimately is derived from CMDIFrameWnd.  That said, I have implemented the following:


 class CMyFrame : public CExtNCW< SECWorkbook>,

public CExtDynamicBarSite,

public CExtCustomizeSite


and in the OnCreate of the frame:


CExtControlBar::FrameEnableDocking( this );

CExtControlBar::FrameInjectAutoHideAreas( this );

CExtDynamicBarSite::Install( this );


I create my CExtDynamicControlBar s on the fly utilizing CExtDynamicBarSite::BarAlloc.  The dynamic control bars show up just fine.  I can dock them, float them, MDI them.  But if I unpin them, they go into the auto hide mode, I see the tab button.  I click on something else, the bar hides.  I mouse over to the tab button, the button disappears and the hidden bar, of course, never reshows itself.  It is possible that if I dock another window to the same edge the tab might come back, but it almost certainly will disappear yet again as soon as I do the aforementioned steps. 


I’ve been trying to figure out what might possibly be causing this behavior to no avail.  Using a message spy program on both your sample and my application shows that in my application the CExtTabWnd is not getting any timer messages or paint messages, though it continues to receive mouse messages.  If I debug into the mouse handler of CExtTabWnd, it says although there are apaprently visible buttons, the mouse isn’t over them.


Any suggestions would be greatly appreciated...


Kevin Murray

Kevin Murray May 16, 2008 - 3:35 PM

Well, you are correct that WM_SIZEPARENT is not getting through.  I don’t know where it’s going, but it isn’t getting through.  Whenever I dock another window to the same side as the missing tab(s), they come back, but again, as soon as they are used they go away.  I’ll do some investigating and try to determine why the message dies...


Kevin Murray

Technical Support May 17, 2008 - 12:29 PM

Your investigation needs the presence of all the UI related source code. Otherwise you can only exclude the usage of components available as binaries only to come to conclusion about who eats messages and modifies the default behavior of the frame window. Some additional information. When the frame window’s size becomes changed, it invokes the CFrameWnd::RecalcLayout() virtual method which simply invokes the CWnd::RepositionBars() method. Dialog based sample applications in Prof-UIS with control bar windows invoke the CWnd::RepositionBars() method from the dialog’s OnSize() handler method. The CWnd::RepositionBars() method sends a WM_SIZEPARENT message to all the child windows and allows them to take up the required space near window borders. But the CWnd::RepositionBars() method and WM_SIZEPARENT message can also be used for calculating the rest free space which is free of any bars in the center of the window and this center space is used for a view window in SDI applications and for an MDI client area window in MDI applications. So, the CWnd::RepositionBars() API and WM_SIZEPARENT message represent an important and very frequently used feature of MFC rather than of Win32 API (though the WM_SIZEPARENT preprocessor symbol starts from WM).

Kevin Murray May 18, 2008 - 7:09 PM

Well, now I’m to the point where the tabs don’t repaint themselves.  You can mouse over the tab, the window shows itself.  Move away, it hides.  Move to another tab, the tabs disappear and no windows show themselves.  It will stay this way till I can force a repaint, say by switching to another application then switching back.  Any ideas on this one?  I hope it is a simple repaint issue, and not that the tab windows think they don’t have any tabs any more.  But if I debug, as soon as I switch into the debugger, it says all is good and the tabs will redraw.  I’ve tried forcing a RedrawWindow() for the auto-hide areas on WM_NCACTIVATE, but that isnt’ working.  Tried Invalidate() as well; tried them both together. 


Kevin Murray


 

Technical Support May 19, 2008 - 9:31 AM

Please check the following:

1) Your main frame should have the WS_CLIPSIBLINGS|WS_CLIPCHILDREN styles set on (use the SPY++ utility for that). Although Prof-UIS tries to forcibly set these styles to the main frame window, please check whether they are really added.

2) Do you have some painting code based on CDC::GetDC() API or ::GetDC() API invoked for the main frame window with flags for retrieving the entire window/client DC without any clipping?

Such fantastic problems require similar fantastic approaches for resolving them: in the hardest case you will need to comment out some parts of your project one by one until the problem is gone and then try to understand what causes the problem.

Kevin Murray May 22, 2008 - 12:10 PM

Once again, you guys prove you know your stuff. :)


Turns out, after heavy debugging, the base class we are using has a member they call m_pMDIClientArea, which overrides OnPaint.  So as long as I override OnPaint, let the base class do its thing, then do the repaint of the control bars, all is well.


My question to you now is this:



void CMyFrame::OnPaint()


{


__super::OnPaint();


RepositionBars( 0, 0xFFFF, 0 );


}


 



That’s what I have.  The hide animation, though, is now terribly slow.  The CExtDynAutoHideArea’s do not seem to respond to a RedrawWindow() request.  Is there a more effecient way to repaint these in the OnPaint handler so the animation is smoother?


K.

Technical Support May 22, 2008 - 1:03 PM

The WM_PAINT, WM_ERASEBKGND and WM_NCPAINT message handlers should draw something into the device context and should not do anything with windows including their states, positions and visibility. Otherwise, these message handlers will cause further sending of these messages to the same and/or other windows. Although what was just said above is true, preventing the window procedure of the MDI client area window from receiving the WM_ERASEBKGND message can cause the MDI interface to work incorrectly.

Could you send us source code of your improved frames and source code of class which subclasses the MDI client area window (type of m_pMDIClientArea) ?

Kevin Murray May 22, 2008 - 5:03 PM

Unfortunately I cannot send you the source code as it is a purchased product, much like your library. 


I can tell you they call RepositionBars(...reposQuery) to adjust the client rectangle before they do their drawing.  However, they end with the following:



RedrawWindow(NULL, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN);  


I suspect that might be the problem. 



K.


Technical Support May 23, 2008 - 2:04 PM

It would be extremely interesting to know what the non-Prof-UIS UI classes really do in your project? We have a lot of test applications which modify different behaviors of MDI, SDI and dialog based applications. These test applications have been collected as replies and suggestions to Prof-UIS users during more than five years. It’s possible we can provide you with a ready-to-use solution which allows you to remove the code conflicting with Prof-UIS.

Technical Support May 16, 2008 - 2:34 PM

The CExtNCW template class in Prof-UIS 2.82 has a specialized version for MDI child frames, but the MDI child window support in this class is beta and requires usage of the CExtNCW < CMDIChildWnd > template based type rather than CExtNCW < SECWorkbook >. This template class is completely re-coded in Prof-UIS 2.83 and well supports MDI child frames even without specialized version for the CMDIChildWnd class. We can provide you v.2.83 beta.

The auto hide tabs handle the standard MFC’s WM_SIZEPARENT message which allows them to take up the required space inside an MFC frame window. The auto hide tabs (CExtDynAutoHideArea) work similar to standard MFC control bars which are not enabled for drag-and-drop based re-docking. In other words, auto-hide tabs are the windows like a status bar. But the tabs are not based on MFC’s CControlBar class which is really not critical and do not conflict with MFC. If you are using some framework or library which filters WM_SIZEPARENT messages through some hooks or message pre-translation and do not allow you to receive these messages to some windows that are not based on CControlBar, the auto hide tabs can really disappear. But there is no point to filter out WM_SIZEPARENT messages. If you need to "inject" some window between control bars in an MFC frame window, you should handle WM_SIZEPARENT messages in this window and do not do anything else. This will allow you to code your own MDI tabs like window or your own caption window similar to the popup blocking alert window with text message and "X" button in Mozilla Firefox or Internet Explorer. Of course, you can set a breakpoint in the CExtDynAutoHideArea::OnSizeParent() method and see whether the WM_SIZEPARENT messages are delivered to the auto hide tabs. There are four CExtDynAutoHideArea windows that are created in an MFC frame window by the CExtControlBar::FrameInjectAutoHideAreas() method and each docks itself to one side of its parent frame window.