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 » CExtControlBar closing (hiding) Collapse All
Subject Author Date
Alexey Spichak Feb 26, 2009 - 8:13 AM

I need to destroy a window that i put into CExtControlBar when user hides the corresponding CExtControlBar-object (with a cross in the upper-right corner). Alternately I need to create my window when user shows the corresponding CExtControlBar-object.
I want to do these actions because my windows perform some heavy calculations and I don’t want them to work when they are not on the screen.
I’ve tried to override OnControlBarPositionChange function but it doesn’t trigger on cross button.
I’ve also tried to catch WM_SYSCOMMAND message (with wParam == SC_CLOSE) but it doesn’t come.
I’ve tried WM_WINDOWSPOSCHANGED notification with SWP_HIDEWINDOW flag. It triggers correctly but it also triggers when CExtControlBar-object is to dock to some side. And I don’t want to destroy my window in such cases because i need to create it in a moment after destroying.

Is there a good solution for my problem?

Technical Support Mar 10, 2009 - 1:07 PM

You are using MFC and Prof-UIS from the non-MFC EXE application. This means you DLL module which used Prof-UIS should be the MFC regular DLL project type. If you are using Prof-UIS in the MFC regular DLL project, then you should use the RDE version of Prof-UIS which requires invocation of the CExt_ProfUIS_ModuleState::InitExtension() method:

http://www.prof-uis.com/prof-uis/tech-support/faq/miscellaneous.aspx#how-to-use-prof-uis-in-my-dll-project

The second important thing is very specific for the non-EXE MFC UI which does not control the thread message loop and, as result, the MFC idle processing mechanism is not invoked. The MFC frame windows and control bars inside them, including Prof-UIS control bars, often use delayed layout recalculation based on the CFrameWnd::DelayRecalcLayout() method. The control bars often do position changing, window showing and hiding for more than one control bar window at once. It’s not effective and not flicker free to do window position and visibility changing for each control bar immediately. So, control bars just remember how they should change their positions and visibility and delay the frame layout recalculation. When the thread message loop in the MFC based EXE becomes idle, the CFrameWnd::OnIdleUpdateCmdUI() method is invoked. This method analyzes whether some control bars delayed their position and visibility changing and invokes the CFrameWnd::RecalcLayout() method for applying all the delayed actions. But the MFC regular DLL modules typically does not control the thread message loop, they does not known when the thread becomes idle and, as result, the frame windows in such DLLs does not have any chances for invoking any algorithms based on the MFC’s idle time processing. This is related to both delayed layout computations for control bars and delayed CCmdUI-based command updating for visible UI elements. We guess that’s why some of the control bars present in your frame window does not finalize their layout changing after particular user actions. There are two solutions of this problem. If you have some idle thread state detection mechanism in your main Win32 EXE module, then you should notify the frame window in your MFC regular DLL about idle time events and this DLL should invoke the frame’s CFrameWnd::OnIdleUpdateCmdUI() method. If the idle time detection is not available in your main EXE module, then you can run some timer each 100 milliseconds in your frame window and invoke the frame’s CFrameWnd::OnIdleUpdateCmdUI() method from the timer’s handler method. The last approach is used in our Frame Features ActiveX control which is MFC regular DLL with Prof-UIS/ProfAuto/RDE modules applied and running inside Visual Basic 6.0, Visual J++ and .NET based applications.

Alexey Spichak Apr 15, 2009 - 10:43 AM

That helped. Thank you very much!

Alexey Spichak Mar 10, 2009 - 9:53 AM

Hello!

That’s a good solution, thanks. But while experimenting with CExtDynamicControlBar I’ve found virtual methods that will be enough to override to get the functionality I want. (Actually I’ve overridden two methods: BarStateSet in CExtDynamicControlBar and NcButtons_HandleClick in CExtDynamicTabbedControlBar (by the way this method is always called twice and that made me do some cheats to handle it correctly) )

Unfortunately I’ve encountered a couple of other problems. They are rather difficult to explain and i’ve made some screenshots to make it more obvious.

Problem 1.

1. I have 2 windows: one is docked and one is floating

Docked window is single (is an instance of a class CExtDynamicControlBar, but not of a class CExtDynamicTabbedControlBar)

2. I drag floating window to be tabbed to a docked one like this:


3. Then I expect CExtDynamicControlBar to be created and two windows to be tabbed but i have just this:


4. After resizing of main frame everything comes all right:


This stuff happens only when one window is docked and another floating window is dragged to be tabbed.


Problem 2.
1. I have floating CExtDynamicTabbedControlBar container with 2 windows in it


2. Click on cross button once (I have CExtControlBar::g_bCloseOnlyOneBarInTabGroup = true;)


3. Clicking on cross button again i expect the window to be closed, but I see this:

Everything OK but the container is still visible.

4. After an attempt to dock the container disappears.




I should mention the structure of my project.

I’ve got pure WinAPI (not MFC) exe-file. This project uses MFC-dll in witch I store all the user interface code. This MFC-dll deals with Prof-UIS dll.

I suppose the problem is in bad initialization of all that stuff. When used in a simple mfc exe application Prof-UIS doesn’t have this bug.

Technical Support Feb 26, 2009 - 1:22 PM

You should create two windows. One is a child of the CExtControlBar window. We call it the container window. Second one is your heavy control ant it should be created as a child of the first container window. The container window should move its child heavy control to bounds of the container’s client area. When the container window receives the WM_PAINT message, it does not paint anything. It just posts some (WM_USER+100) message to himself. The (WM_USER+100) message handler creates the heavy child window and starts some timer in the container window. The timer handler code analyzes whether the container window has the WS_VISIBLE window style. If it has, then the timer handler just returns execution control and does nothing else. If this style is absent, then the timer handler code kills the window timer and destroys the heavy child control window. Of course, the container window should handle the WM_SIZE message for repositioning its heavy child window.