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.
Subject |
Author |
Date |
|
Offer Har
|
Jun 9, 2006 - 12:51 PM
|
Hi, I am using AppendMenu for adding items into a sub-menu like this: pSubMenu->AppendMenu(MF_STRING, ID_XXX, str);
In a standard MFC application this works fine, but when the menu is a CExtMenuControlBar menu, the text is not displayed, only the menu item. What am i missing?
|
|
Technical Support
|
Jun 10, 2006 - 11:49 AM
|
The CExtMenuControlBar class is derived from CExtToolControlBar , which implements a toolbar in Prof-UIS. Any Prof-UIS toolbar is a window which contains CExtBarButton objects. That means the top-level menu in the menu bar is not based on HMENU handles. The menu bar creates its buttons in the CExtMenuControlBar::_UpdateMenuBar() virtual method which is invoked when the menu bar is created in an SDI/MDI application, when the CExtMenuControlBar::LoadMenuBar() method is invoked and when an MDI child frame is switched, created or destroyed in an MDI application. Please provide us with more details and some code snippets so we can help you.
|
|
Offer Har
|
Jun 10, 2006 - 5:50 PM
|
Hi,
My task is to have a dynamic sub-menu. I know that the sub-menu is under "Display"\"SomeCommand", so i used to use GetMenuString to find the "Display" command, then again to find the "SomeCommand", and then using AppendMenu, i added menu commands to the sub-menu.
What are the function that i should use to implement the same task in the CExtMenuControlBar based menu?
Thanks.
|
|
Technical Support
|
Jun 13, 2006 - 4:50 AM
|
Prof-UIS menus are not based on HMENU handles. They are based on CExtPopupMenuWnd windows. So you cannot use the WM_INITMENUPOPUP and WM_INITMENU messages here.
There are two registered windows messages in Prof-UIS CExtPopupBaseWnd::g_nMsgPrepareMenu and CExtPopupBaseWnd::g_nMsgPrepareOneMenuLevel (starting from Prof-UIS 2.33). The CExtPopupBaseWnd::g_nMsgPrepareMenu message is sent only once for each menu tree and allows you to analyze the entire menu tree before it appears on the screen. The CExtPopupBaseWnd::g_nMsgPrepareOneMenuLevel message is similar to the previous message but it is sent for each single pop-up menu sublevel before it appears on the screen. This makes it handy to construct menus with many submenus.
Let’s assume that we need to insert some new menu items at a certain position in a popup menu. First, we need to open the menu resource and insert some ID_MY_MENU_MARKER command in the popup menu. The menu item text and tip text properties of this item are not important at all. This command item will be replaced with a set of dynamic menu items on-the-fly immediately before the menu appears on the screen. Now, we need to handle the CExtPopupBaseWnd::g_nMsgPrepareOneMenuLevel registered windows message in the application. The message handler function, which should be added to the main frame or dialog window, should make a search for the ID_MY_MENU_MARKER menu item in each displayed sub menu. If this menu item is found, the handler method removes this menu item and inserts new items instead. Here is the method declaration, message map’s entry and implementation.
Method declaration
afx_msg LRESULT OnExtMenuPrepareOneLevel(WPARAM wParam, LPARAM lParam); Message map entry
ON_REGISTERED_MESSAGE(
CExtPopupBaseWnd::g_nMsgPrepareOneMenuLevel,
OnExtMenuPrepareOneLevel
) Method implementation
LRESULT CMainFrame::OnExtMenuPrepareOneLevel( WPARAM wParam, LPARAM lParam )
{
lParam; // unused parameter
CExtPopupMenuWnd::MsgPrepareMenuData_t * pData =
reinterpret_cast < CExtPopupMenuWnd::MsgPrepareMenuData_t * > ( wParam );
ASSERT( pData != NULL );
CExtPopupMenuWnd * pPopup = pData->m_pPopup;
ASSERT( pPopup != NULL );
INT nReplacePos =
pPopup->ItemFindPosForCmdID( ID_MY_MENU_MARKER );
if( nReplacePos < 0 )
return 0;
VERIFY( pPopup->ItemRemove(nReplacePos) );
// insert one command
pPopup->ItemInsertCommand(
ID_APP_ABOUT,
nReplacePos,
"About (1)"
);
// insert one more command
pPopup->ItemInsertCommand(
ID_APP_ABOUT,
nReplacePos + 1,
"About (2)"
);
// and insert one more command
pPopup->ItemInsertCommand(
ID_APP_ABOUT,
nReplacePos + 2,
"About (3)"
);
return 1L;
} As you can see, to find a menu item by its command identifier, you can use the CExtPopupMenuWnd::ItemFindPosForCmdID() method. This method retrieves the menu item position from the command id. If the item is not found methods returns -1. If the pop-up menu has been modified, the pData->m_bMenuChanged property should be set to true . To cancel pop-menu tracking, set pData->m_bMenuCanceled to true . You may also rebuild the top level of the menu bar. The menu bar ( CExtMenuControlBar ) is based on the toolbar ( CExtToolControlBar ). The CExtMenuControlBar::UpdateMenuBar() method invokes an algorithm that rebuilds menu bar’s buttons. You can implement your own algorithm of filling the menu bar with buttons ( CExtBarButton ). Create your own CExtMenuControlBar -derived class and override the CExtMenuControlBar::_UpdateMenuBar() internal virtual method. Your method can be either based on the original method (you only embed buttons you want) or completely rebuild an array of buttons in your own manner. All the commands inside the menus attached to the menu bar buttons should be registered in the command manager. The top level buttons in the menu bar also have their unique command identifiers and should be allocated exactly like it is done in the CExtMenuControlBar::_UpdateMenuBar() method.
|
|
Offer Har
|
Jun 13, 2006 - 5:30 AM
|
Hi,
All works great, but a small issue - The ON_UPDATE_COMMAND_UI for the items in the new sub-menu are not called. And strangely enough, when the menu item is pressed, this is when the command ON_UPDATE_COMMAND_UI is called.. Any ideas?
Thanks.
|
|
Technical Support
|
Jun 13, 2006 - 10:43 AM
|
If the pop-up menu has been modified, the pData->m_bMenuChanged property should be set to true . It is important, so please check this.
|
|
Offer Har
|
Jun 13, 2006 - 11:07 AM
|
The last line in the fucntion OnExtMenuPrepareOneLevel is pData->m_bMenuChanged = true; just before return 1L; Still, the onupdate are not called.
|
|
Technical Support
|
Jun 14, 2006 - 9:30 AM
|
We cannot yet confirm that it is a bug. Please download an updated version of the ProfUIS_Controls sample. You can select the Popup Menus page and invoke the context menu over it. You will see the following two lines in the output window of the Visual Studio:
>>>>> CPagePopupMenus::OnUpdateMenuRarelyItem1() >>>>> CPagePopupMenus::OnUpdateMenuRarelyItem1()
You will see only one of these lines if you comment the following message map entry for the CPagePopupMenus class: ON_REGISTERED_MESSAGE(
CExtPopupMenuWnd::g_nMsgPrepareMenu,
OnExtMenuPrepare
) You will see two lines in the first case because the CPagePopupMenus::OnUpdateMenuRarelyItem1() method is invoked by the command updating mechanism twice. First time, after initializing the menu. Second time, after handling the CExtPopupMenuWnd::g_nMsgPrepareMenu registered windows message in the CPagePopupMenus::OnExtMenuPrepare() method which has the following code at the beginning: CExtPopupMenuWnd::MsgPrepareMenuData_t * pData =
reinterpret_cast
< CExtPopupMenuWnd::MsgPrepareMenuData_t * >
( wParam );
ASSERT( pData != NULL );
CExtPopupMenuWnd * pPopup = pData->m_pPopup;
ASSERT( pPopup != NULL );
pData->m_bMenuChanged = true;
|
|
Offer Har
|
Jun 14, 2006 - 3:07 PM
|
Hi,
I am using ON_REGISTERED_MESSAGE(CExtPopupBaseWnd::nMsgPrepareOneMenuLevel...) and not CExtPopupMenuWnd::g_nMsgPrepareMenu, maybe this is the source of the problem. Please check with nMsgPrepareOneMenuLevel, i think this is the place of the problem.
Thanks.
|
|
Technical Support
|
Jun 16, 2006 - 12:51 PM
|
We checked CExtPopupMenuWnd::g_nMsgPrepareOneMenuLevel message. It is sent from the beginning of the CExtPopupMenuWnd::_TrackPopupMenu() method and invokes the command updating if needed: MsgPrepareMenuData_t _mpmOneTreeLevel( this );
_mpmOneTreeLevel.SendMessage( m_hWndCmdReceiver, true );
if( _mpmOneTreeLevel.m_bMenuCanceled )
return FALSE;
if( _mpmOneTreeLevel.m_bMenuChanged )
{
_SyncItems();
_UpdateCmdUI();
} Would you check command identifiers in your popup menus and message map entries with method names additionally?
|
|
Mark Walsen
|
Jun 8, 2006 - 12:49 PM
|
CExtControlBar::ProfileBarStateLoad is failed in its call to ProfileBarStateSerialize. I’ve seen this happen a couple of times before, each time when my app design introduces a new CExtControlBar or removes one from the design. (I’m talking here about the app design, not showing/hiding CExtControlBars at run-time.)
I’ve been able to work-around this problem by using RegEdit to delete the entire tree of HKEY_CURRENT_USER\Software\MyApp\ProfUIS254. That highly confirms my suspicion that the problem is that ProfileBarStateSerialize cannot deal with changes in the app’s list of CExtControlBars.
One solution for my end-user is that my setup program could delete the registry HKEY_CURRENT_USER\Software\MyApp\ProfUIS254 entries if a new version of my app changes the list of CExtControlBars it uses. But I don’t believe this is a very reliable solution.
The solution I have in mind is this: My app will call CExtControlBar::ProfileBarStateLoad inside a try/catch. If the call fails (throws an exception), then my app will programmatically remove the registry entries for HKEY_CURRENT_USER\Software\MyApp\ProfUIS254.
Is there a better solution already built into Prof-UIS?
Cheers -- Mark
|
|
Technical Support
|
Jun 9, 2006 - 8:02 AM
|
The code for serializing control bars requires all the control bars described in the saved data to be instantiated (exist) in the frame window. If that’s not the case, the ui state assumes to be loaded unsuccessfully. We are working on a new version/bar independent algorithm which is based on tree-like named nodes compatible with XML serialization.
|
|
Mark Walsen
|
Jun 9, 2006 - 8:56 AM
|
That’s a good that a future version of Prof-UIS will handle changes in the list of control bars. In the mean time, I’ll implement the work-around I proposed above, to do the ProfileBarStateLoad in a try/catch, and if an exception is thrown, then clear the ProfUIS registry entry for the app controls.
Cheers -- Mark
|
|
Massimo Germi
|
Jun 8, 2006 - 8:37 AM
|
I’ve not found a combo box class that I can use to display and select font name. I wish to use this class like a control and not in a cell of your grid.
TX
|
|
Technical Support
|
Jun 8, 2006 - 11:15 AM
|
Unfortunately Prof-UIS does not contain the Font Face Name combo box. But it is really easy to implement such a control based on the owner-drawn combo box. You can implement it yourself or we can regard this as a feature request and implement such a control in the next version.
|
|
delu qiu
|
Jun 8, 2006 - 8:35 AM
|
Hi, I want to paint a CExtResizableDialog derived dialog, but my OnPaint() does not work.
class CSPSSelection:public CExtNCW < CExtResizableDialog> { ....... // Generated message map functions //{{AFX_MSG(CSPSSelection) afx_msg void OnPaint(); ....... afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); //}}AFX_MSG DECLARE_MESSAGE_MAP()
}
BEGIN_MESSAGE_MAP(CSPSSelection, CDialog) //{{AFX_MSG_MAP(CSPSSelection) ....... ON_WM_CREATE() ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////// // CSPSSelection message handlers void CSPSSelection::OnPaint() { CPaintDC dc(this); // device context for painting
//1st fill background COLORREF colorBK=RGB(0,0,0); CBrush bkbrush; CRect rect; GetClientRect(&rect); bkbrush.CreateSolidBrush( colorBK); CDC::FromHandle(dc)->FillRect( &rect,&bkbrush); }
How to make it work, and how to paint a CExtResizableDialog after apply skin?
Thanks
|
|
Technical Support
|
Jun 8, 2006 - 11:14 AM
|
Please replace the CPaintDC class with CClientDC : CPaintDC dc(this);
|
|
Michael Valentine
|
Jun 8, 2006 - 8:31 AM
|
Hi,
I have found a situation where a CExtControlBar will wrongly resize itself. I have two CExtControlBars which are docked on top of each other so that they appear on two tabs within the same window. This window is floating (i.e. not docked within the main app). If you grab the left hand side of the floating window frame and resize it, then the bottom of the window will strangely grow downwards... This does not occur with a single floating bar, only when I have 2+ floating bars tabbed together...
Thanks
|
|
Technical Support
|
Jun 9, 2006 - 7:30 AM
|
We have already fixed this bug and can provide you with the source code update.
|
|
Mark Walsen
|
Jun 7, 2006 - 11:20 AM
|
The CExtTabMdiWnd __ETWS_ORIENT_LEFT option places the MDI window tab vertically along the left side of the client area. Is there an option to flip the text orientation by 180 degress so that when the tab is on the left (with __ETWS_ORIENT_LEFT) the base of the text is on the right side rather than left side of the tab? This would make it easier for the user to read, in my opinion and in the opinion of my beta testers.
Cheers -- Mark
|
|
Technical Support
|
Jun 7, 2006 - 12:08 PM
|
Just apply the __ETWS_INVERT_VERT_FONT style to change the direction of the vertical font in any CExtTabWnd -derived class by 180 degrees.
|
|
Mark Walsen
|
Jun 7, 2006 - 3:14 PM
|
Thanks! __ETWS_INVERT_VERT_FONT was what I needed. I should have found it in the header file, but somehow I missed it.
Cheers -- Mark
|
|
steven frierdich
|
Jun 6, 2006 - 7:52 PM
|
I have a simple SDI application that contains two bars, a menu, and a status bar that are all derived from your all DLL classes. The two toolbars have been each derived from the CExtToolControlBar class. At the end of each toolbar is a drop down item. Does anyone know how I can make the drop down items disappear? Also the background colors of the toolbar buttons are the same color as that set by the paint manager, CExtPaintManagerOffice2007_R2_Obsidian, whether the toolbar button is enabled or disabled. Does anyone know how I can change the color of an individual button on the toolbar so when a button is enabled it will be a different color that that set by the paint manager, and change the color back to that set by the paint manager when the button is disabled? Is there a simple function to call in the CCExtToolControlBar class that will do this? OF COURSE THERE ARE NO SIMPLE FUNCTIONS . ANY ONE GOT AN ANSWER TO HOW TO DO THIN You can email me at sun_Water_snow@hotmail.com with any suggestions. Thanks Steve
|
|
Technical Support
|
Jun 7, 2006 - 12:04 PM
|
We received the very same message by e-mail and replied with a modified version of the test project.
|
|
steven frierdich
|
Jun 6, 2006 - 7:49 PM
|
I DERIVE A MENU OBJECT FROM YOUR CExtMenuControlBar CLASS Next CREATE A MENU USING AND ID FROM THE MAIN MENU MENU AND TOOL BARS APPEAR NO PROBLEM
WELL THEN I DECDIE I WANT TO CHANGE THE MENU ID ON THE MENU TO A NEW ID SO THEN I USE THE NEW ID IN THE CREATE METHOD FOR THE MENU GUESS WHAT THE I RUN THE PROGRAM AGAIN THE MENU AND TOOLBARS NO LONGER APPEAR
WHY IS THIS
|
|
Technical Support
|
Jun 7, 2006 - 12:06 PM
|
Please note that the Prof-UIS toolbar and menu bar are not based on the MFC’s CToolBar class and Prof-UIS menus are not based on the Win32’s menu handles because our components have much more features. It is possible to change the toolbar’s contents and menu’s contents on-the-fly. We can help you if you describe what you want to code step-by-step.
|
|
Stefan Wachsmann
|
Jun 6, 2006 - 3:09 PM
|
Dear Support,
with the new Version of Prof-UIS (2.54) I have the following Problem:
The ToolTips are still working, but they are far away from buttons. The ToolTips in the samples too (I tested DRAWCLI-m.exe from the samplecollection and one created on my own from the workspace)!
The distance from the mouse-hotspot to the upperleft coner of the tooltip is 72 pixel instead of the standard 20 pixel!
Is there any posibility to overwrite this distance-Value? I use the standard of 32x32 pixel for the buttonimages and didn’t change the sample-settings.
With version 2.53 this problem didn’t arise!
I use MDE version 7.0
Thank you for your help stefan
|
|
Technical Support
|
Jun 7, 2006 - 10:52 AM
|
When the mouse pointer is moving over toolbar buttons, at least one starts tracking the timeout to display the tooltip window. The tooltip window is displayed at the location which is computed using the following rule: 1) We get the position where the mouse pointer started hovering over the toolbar button. 2) We extract the icon information from the currently installed cursor handle. 3) We use the position saved at the point 1 but moving the Y location to the bottom by the number of pixels equal to the height of the cursor’s bitmap computed at the point 2. The computed position corresponds to the top-left corner of the tooltip window. We do not see any problem with this in Prof-UIS 2.54. There was only one improvement in Prof-UIS 2.54 related to the location of the tooltip window on the screen: if the toolbar window is docked at the bottom, then tooltips appear at the top side of the toolbar’s buttons. But we do not think this improvement relates to the problem described in your message. We guess, the problem with the tooltip location on your desktop may be caused by using some custom cursor set where the classic arrow cursor replaced with something looking as 20x20 pixels but implemented in 64x64 bitmaps in the .CUR file. We believe we will be able to help you if you provide us with more details. Making the tooltip window location configurable is not a problem and we can provide you with the source code update.
|
|
Suhai Gyorgy
|
Jun 6, 2006 - 8:17 AM
|
Dear Support,
I encountered 3 problems while trying to see differences between the two Control Bar states stated above. I’m especially interested in the case where, even though the Control Bar is in docked state in floating CMiniFrame, it is the only visible bar and all other "sibling" Control Bars are invisible.
1.) When I use CExtWRB template to add a thin border, the border is drawn differently in the 2 above mentioned states. I think they should look the same. ScreenShot: Float-vs-Docked-in-Mini.jpg
2.) At program startup the control bars in floating state are drawn when program passes through CMainFrame::OnCreate (before MainFrame appears), but the control bars in docked state inside floating CMiniFrameWnd are drawn only after main application’s InitInstance call is finished. This is disturbing when I have a login dialog, whose DoModal is called from inside InitInstance but after m_pMainWnd->ShowWindow()... If I have 2 control bars, each of them in those 2 different states, the floating one appears when login dialog appears, but the other appears only after login dialog is closed. How could I make all control bars appear at the same time, preferably after login dialog closed (after InitInstance)
3.) I ran into an assertion in ProfileBarStateSave when closing application right after doing this: I have 2 control bars, each of them in the above mention 2 states. I start dragging the one in "docked state inside MiniFrame" and drag it inside the other control bar and tabbed-docking them together.
Call Stack: MyProg.exe!CExtControlBar::InternalDockStateBar::StateGet(CExtControlBar * pBar=0x016b6fd8, CExtControlBar::InternalDockStateBar * pParentState=0x00000000) Line 3104 + 0x2a MyProg.exe!CExtControlBar::InternalDockStateSite::AppendFloatingLayout(CExtMiniDockFrameWnd * pMiniFrame=0x016b7660) Line 2450 MyProg.exe!CExtControlBar::InternalDockStateSite::StateGet() Line 2217 MyProg.exe!CExtControlBar::InternalFriendlyFrameWnd::GetDockState(CExtControlBar::InternalDockStateSite & state={...}) Line 1793 MyProg.exe!CExtControlBar::ProfileBarStateSerialize(CArchive & ar={...}, CFrameWnd * pFrame=0x01671748, tagWINDOWPLACEMENT * pFrameWp=0x0167181c, bool bSerializeFixedBarsState=true, bool bSerializeResizableBarsState=true, bool bEnableThrowExceptions=false) Line 4189 MyProg.exe!CExtControlBar::ProfileBarStateSave(CFrameWnd * pFrame=0x01671748, const unsigned short * sSectionNameCompany=0x011bf9a0, const unsigned short * sSectionNameProduct=0x011bf7f0, const unsigned short * sSectionNameProfile=0x011bf7f0, tagWINDOWPLACEMENT * pFrameWp=0x0167181c, bool bSerializeFixedBarsState=true, bool bSerializeResizableBarsState=true, HKEY__ * hKeyRoot=0x80000001, bool bEnableThrowExceptions=false) Line 1270 + 0x20 C++
Thank you for your help, Chris
|
|
Technical Support
|
Jun 6, 2006 - 11:20 AM
|
The resizable control bars in any state are managed by a tree-like data structure which contains a set of windows derived from the CExtControlBar and CExtDockBar classes. The CExtControlBar windows are either CExtControlBar objects, instances of the CExtDynamicControlBar class which implements the dynamic resizable control bar controlled by the dynamic bar site, CExtDynControlBar windows created on-the-fly to implement rows and/or columns of bars inside other rows and/or columns of bars and CExtDynTabControlBar windows also created on-the-fly to implement tabbed bar groups. You can get the real picture of the resizable control bars’ layout if you compile Prof-UIS when the following lines are un-commented in the ...\Prof-UIS\Src\ExtDockBar.h file: //#define __DEBUG_PAINTING_AREAS_DOCKBAR__
//#define __DEBUG_PAINTING_AREAS_EXTRESIZABLEBAR__ You will see yellow and magenta borders around container windows. This means the sibling term is not well applicable to any kind of resizable control bar in any state. The resizable bars both in Prof-UIS and in Microsoft applications hardly depend on each other. It is hardly possible to specify the location and size of one bar without knowing how it depends on other bars. You should not have any problems with loading the state of resizable bars. Please ensure you are invoking the CExtControlBar::ProfileBarStateLoad() method in your CMainFrame::OnCreate() method and docking the bars initially only if the bars’ state is failed to be loaded. We need additional information about the third question. The call stack looks like accessing a control bar which is just created inside the main frame window but not correctly initialized (i.e. is not enabled for re-docking or has a non-unique dialog control identifier). We need to take a look at least at the CMainFrame::OnCreate() and CMainFrame::DestroyWindow() methods which create control bars, load and save their states. Please also let us know which Prof-UIS version you are using.
|
|
Suhai Gyorgy
|
Jun 7, 2006 - 6:56 AM
|
I made a little sample with Prof-UIS AppWizard and I could reproduce all problems described in this thread and even the problem described in the thread below. Here are the OnCreate and DestroyWindow methods of that sample, but I’m also sending the whole project to you soon by e-mail.
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
CWinApp * pApp = ::AfxGetApp();
ASSERT( pApp != NULL );
ASSERT( pApp->m_pszRegistryKey != NULL );
ASSERT( pApp->m_pszRegistryKey[0] != _T(’\0’) );
ASSERT( pApp->m_pszProfileName != NULL );
ASSERT( pApp->m_pszProfileName[0] != _T(’\0’) );
pApp;
if (CExtNCW < CFrameWnd >::OnCreate(lpCreateStruct) == -1) return -1;
VERIFY(g_CmdManager->ProfileWndAdd(__PROF_UIS_PROJECT_CMD_PROFILE_NAME, GetSafeHwnd()));
VERIFY(g_CmdManager->UpdateFromMenu(__PROF_UIS_PROJECT_CMD_PROFILE_NAME, IDR_MAINFRAME));
//PROJTYPE_MDI
// create a view to occupy the client area of the frame
if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
{ TRACE0("Failed to create view window\n"); return -1;}
if( !m_wndMenuBar.Create(NULL, this, ID_VIEW_MENUBAR,
WS_CHILD|WS_VISIBLE |CBRS_TOP|CBRS_TOOLTIPS|CBRS_GRIPPER
|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_SIZE_DYNAMIC|CBRS_HIDE_INPLACE )
) { TRACE0("Failed to create menubar\n"); return -1; }
if( !m_wndToolBar.Create(NULL, this, AFX_IDW_TOOLBAR,
WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_GRIPPER|CBRS_FLYBY|CBRS_SIZE_DYNAMIC
|CBRS_TOOLTIPS|CBRS_HIDE_INPLACE
) || !m_wndToolBar.LoadToolBar( IDR_MAINFRAME )
)
{ TRACE0("Failed to create toolbar\n"); return -1; }
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)))
{ TRACE0("Failed to create status bar\n"); return -1; }
//__PROFUISAPPWIZ_KEY_RCB2
m_wndResizableBarTree.SetInitDesiredSizeVertical(CSize(200, 400));
m_wndResizableBarTree.SetInitDesiredSizeHorizontal(CSize(400, 200));
m_wndResizableBarTree.SetInitDesiredSizeFloating(CSize(200, 200));
if( !m_wndResizableBarTree.Create(NULL, this, ID_VIEW_RESIZABLEBAR_TREE,
WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY
|CBRS_SIZE_DYNAMIC|CBRS_HIDE_INPLACE)
)
{ TRACE0("Failed to create m_wndResizableBarTree\n"); return -1; }
if( !m_wndDockedCtrlTree.Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL
|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT,
CRect(0,0,0,0), &m_wndResizableBarTree, m_wndResizableBarTree.GetDlgCtrlID())
)
{ TRACE0("Failed to create m_wndDockedCtrlTree\n"); return -1; }
m_wndDockedCtrlTree.SetFont(CFont::FromHandle((HFONT)::GetStockObject(DEFAULT_GUI_FONT)));
HTREEITEM htiAtLevel0 = m_wndDockedCtrlTree.InsertItem(_T("Item 1-1"));
ASSERT( htiAtLevel0 != NULL );
//__PROFUISAPPWIZ_KEY_RCB3
m_wndResizableBarEdit.SetInitDesiredSizeVertical(CSize(200, 400));
m_wndResizableBarEdit.SetInitDesiredSizeHorizontal(CSize(400, 200));
m_wndResizableBarEdit.SetInitDesiredSizeFloating(CSize(200, 200));
if( !m_wndResizableBarEdit.Create(NULL, this, ID_VIEW_RESIZABLEBAR_EDIT,
WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_GRIPPER|CBRS_TOOLTIPS
|CBRS_FLYBY|CBRS_SIZE_DYNAMIC|CBRS_HIDE_INPLACE)
)
{ TRACE0("Failed to create m_wndResizableBarEdit\n"); return -1; }
if( !m_wndDockedCtrlEdit.Create(WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_LEFT,
CRect(0,0,0,0), &m_wndResizableBarEdit, m_wndResizableBarEdit.GetDlgCtrlID())
)
{ TRACE0("Failed to create m_wndDockedCtrlEdit\n"); return -1; }
m_wndDockedCtrlEdit.SetFont(CFont::FromHandle((HFONT)::GetStockObject(DEFAULT_GUI_FONT)));
m_wndDockedCtrlEdit.SetWindowText(_T("Edit control\r\n"));
m_wndResizableBarDlg.SetInitDesiredSizeVertical(CSize(200, 400));
m_wndResizableBarDlg.SetInitDesiredSizeHorizontal(CSize(400, 200));
m_wndResizableBarDlg.SetInitDesiredSizeFloating(CSize(200, 200));
if( !m_wndResizableBarDlg.Create(NULL, this, ID_VIEW_RESIZABLEBAR_DLG,
WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_GRIPPER|CBRS_TOOLTIPS
|CBRS_FLYBY|CBRS_SIZE_DYNAMIC|CBRS_HIDE_INPLACE)
)
{ TRACE0("Failed to create m_wndResizableBarDlg\n"); return -1; }
if( !m_wndDockedResizableDialog.Create(IDD_DIALOG_FOR_RESIZABLE_BAR, &m_wndResizableBarDlg))
{ TRACE0("Failed to create m_wndResizableBarDlg\n"); return -1; }
m_wndDockedResizableDialog.ShowSizeGrip( FALSE );
m_wndDockedResizableDialog.AddAnchor(IDC_EDIT_IN_RESIZABLE_FORM, __RDA_LT, __RDA_RT);
VERIFY( m_wndEditInDockedDlg.SubclassDlgItem(IDC_EDIT_IN_RESIZABLE_FORM, &m_wndDockedResizableDialog));
// TODO: Delete these lines if you don’t want the dockable entity
m_wndMenuBar.EnableDocking( CBRS_ALIGN_ANY );
m_wndToolBar.EnableDocking( CBRS_ALIGN_ANY );
m_wndResizableBarTree.EnableDocking( CBRS_ALIGN_ANY );
m_wndResizableBarEdit.EnableDocking( CBRS_ALIGN_ANY );
m_wndResizableBarDlg.EnableDocking( CBRS_ALIGN_ANY );
// Enable control bars in the frame window to be redocable
//VERBOSE
if( !CExtControlBar::FrameEnableDocking(this) )
{ ASSERT( FALSE ); return -1; }
if (!CExtControlBar::ProfileBarStateLoad(this, pApp->m_pszRegistryKey,
pApp->m_pszProfileName, pApp->m_pszProfileName, &m_dataFrameWP))
{
DockControlBar( &m_wndMenuBar );
DockControlBar( &m_wndToolBar );
ShowControlBar(&m_wndResizableBarTree, false, false);
ShowControlBar(&m_wndResizableBarEdit, false, false);
ShowControlBar(&m_wndResizableBarDlg, false, false);
m_wndResizableBarTree.FloatControlBar();
m_wndResizableBarTree.DockControlBarIntoTabbedContainer(&m_wndResizableBarEdit, -1, this, false);
m_wndResizableBarEdit.DockControlBarIntoTabbedContainer(&m_wndResizableBarTree, -1, this, false);
m_wndResizableBarTree.DockControlBarIntoTabbedContainer(&m_wndResizableBarDlg, -1, this, false);
}
static UINT statBasicCommands[] =
{
ID_APP_EXIT,
ID_APP_ABOUT,
ID_EDIT_COPY,
ID_EDIT_CUT,
ID_EDIT_PASTE,
ID_EDIT_UNDO,
ID_VIEW_TOOLBAR,
//TOOLBAR
ID_VIEW_RESIZABLEBAR_TREE,
ID_VIEW_RESIZABLEBAR_EDIT,
ID_VIEW_RESIZABLEBAR_DLG,
0 // end of commands list
}; // statBasicCommands array
VERIFY( g_CmdManager->SetBasicCommands( __PROF_UIS_PROJECT_CMD_PROFILE_NAME, statBasicCommands));
g_CmdManager->SerializeState(__PROF_UIS_PROJECT_CMD_PROFILE_NAME,
pApp->m_pszRegistryKey, pApp->m_pszProfileName, false);
return 0;
}
BOOL CMainFrame::DestroyWindow()
{
CWinApp * pApp = ::AfxGetApp();
ASSERT( pApp != NULL );
ASSERT( pApp->m_pszRegistryKey != NULL );
ASSERT( pApp->m_pszRegistryKey[0] != _T(’\0’) );
ASSERT( pApp->m_pszProfileName != NULL );
ASSERT( pApp->m_pszProfileName[0] != _T(’\0’) );
pApp;
VERIFY( CExtControlBar::ProfileBarStateSave( this,
pApp->m_pszRegistryKey, pApp->m_pszProfileName,
pApp->m_pszProfileName, &m_dataFrameWP ));
g_CmdManager->ProfileWndRemove( GetSafeHwnd() );
return CExtNCW < CFrameWnd >::DestroyWindow();
}
I’m using ProfUIS254sud.lib, VS2003 (7.1), WinXP. This lib I made with the installation package of Prof-UIS 2.54, but after making this sample’s project-skeleton with Prof-UIS AppWizard, I had to change a setting in the sample’s project properties (along with changing from Multibyte charset to Unicode: "Treat wchar_t as Built-in Type" had to be set to "No". I hope I gave you all the information needed. Thank you, Chris.
|
|
Suhai Gyorgy
|
Jun 2, 2006 - 7:29 AM
|
Dear Support,
We just upgraded from Prof-UIS v2.52 to v2.54 (VS 2003, WinXP). In our application we have some controlbars initially hidden in tabbed-container + floating mode. This worked fine before. But now after upgrading, when I show any of the controlbars 1. it appears in very-very small size in the upper-left corner of my screen and 2. when I try to drag it, it asserts in DockMarkerBase class.
My code:
MainFrm.h:
CExtControlBar *m_pCB1; CExtControlBar *m_pCB2; CExtControlBar *m_pCB3;
MainFrm.cpp (in OnCreate):
... HICON hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_CB1), IMAGE_ICON, 16, 16, 0); ASSERT( hIcon != NULL ); CExtCmdIcon iconCB1; iconCB1.AssignFromHICON( hIcon, true ); g_CmdManager->CmdSetIcon(g_CmdManager->ProfileNameFromWnd(GetSafeHwnd()), ID_VIEW_CB1, &iconCB1, false); m_pCB1 = new CExtControlBar; m_pCB1->Create(NULL, this, ID_VIEW_CB1); if(!m_pCB1 ) { TRACE0("Failed to create m_pCB1\n"); return -1; // fail to create } m_pCB1->EnableDocking(CBRS_ALIGN_ANY); m_pCB1->SetInitDesiredSizeFloating( CSize( 200, 250 ) ); ... //same for m_pCB2 and m_pCB3 ... if( !CExtControlBar::ProfileBarStateLoad(...)) { ShowControlBar(m_pCB1, false, false); ShowControlBar(m_pCB2, false, false); ShowControlBar(m_pCB3, false, false);
m_pCB1->FloatControlBar(); m_pCB1->DockControlBarIntoTabbedContainer(m_pCB2, -1, this, false); m_pCB2->DockControlBarIntoTabbedContainer(m_pCB1, -1, this, false); m_pCB1->DockControlBarIntoTabbedContainer(m_pCB3, -1, this, false); }
Call Stack:
MyProg.exe!CExtPaintManager::DockMarkerBase::CreateFromBitmapResources(CRect rcScreen={...}, CExtPaintManager::eDockMarkerType_t eDockMarkerType=__EDMT_2005_TOP, unsigned long clrTransparentIn=65280, const unsigned short * strResourceBmpIn=0x000076b8, const unsigned short * strResourceBmpOut=0x000076b8, const unsigned short * strResourceTypeBmpIn=0x00000002, const unsigned short * strResourceTypeBmpOut=0x00000002, HINSTANCE__ * hInstBmpIn=0x00000000, HINSTANCE__ * hInstBmpOut=0x00000000) Line 29430 + 0x1c C++ MyProg.exe!CExtPaintManager::DockMarkerBeta2::Create(bool bCentralMode=false, CExtPaintManager::eDockMarkerType_t eDockMarkerType=__EDMT_2005_TOP, CRect rcScreen={...}) Line 30204 + 0x41 C++ MyProg.exe!CExtPaintManager::DockMarkerBase::Create(bool bCentralMode=false, CExtPaintManager::eDockMarkerType_t eDockMarkerType=__EDMT_2005_GROUP_SPARSED, CRect rcScreen={...}) Line 30028 + 0x2f C++ MyProg.exe!CExtPaintManager::DockMarker_CreateWnds(HWND__ * hWndLastDynamicTarget=0x00000000, CExtPaintManager::eDockMarkerType_t eDockMarkerType=__EDMT_2005_GROUP_SPARSED, CRect rcScreen={...}, CTypedPtrArray<CPtrArray,CExtDynDockMarkerWnd *> & arrDockMarkerWnds={...}) Line 30543 + 0x2a C++ MyProg.exe!CExtDynDockMarkerWnd::CreateOuterMarkers(CFrameWnd * pFrame=0x014e0068, bool bShow=false, CExtPaintManager * pPM=0x0102fd60) Line 20977 + 0x41 C++ > MyProg.exe!CExtControlBar::_DraggingStart(const CPoint & point={...}, const CPoint & pointOffset={...}, CSize sizeWaitMouseMove={...}) Line 10568 + 0x30 C++ MyProg.exe!CExtMiniDockFrameWnd::OnNcLButtonDown(unsigned int nHitTest=2, CPoint point={...}) Line 369 + 0xac C++
I see there is a DockMarkerBeta2 class or structure... could that be only a beta version and maybe this is a bug?
Thank you for your help, Chris.
|
|
Technical Support
|
Jun 2, 2006 - 9:36 AM
|
1. Please make sure that you are using the SetInitDesiredSizeFloating() , SetInitDesiredSizeVertical() and SetInitDesiredSizeHorizontal() methods of the CExtControlBar class to specify the initial size of the control bars in the floating, docked vertically and docked horizontally states.
2. The problem relates to failure of loading resources. Please check that you included the following line in your *.rc2 file: #if ( !(defined _AFXDLL && !defined __STATPROFUIS_WITH_DLLMFC__) )
#include <Resources/Resource.rc>
#endif You can read more about this issue in the FAQ How to link statically with Prof-UIS?.
|
|
Suhai Gyorgy
|
Jun 2, 2006 - 4:40 PM
|
I did both of those... even v2.52 wouldn’t have worked without the 2nd. I emitted the SetInitDesiredSizeHorizontal() and SetInitDesiredSizeVertical() here on forum only because I thought that has nothing to do with the problem, but in my real prog I call those too for all controlbars.
Any other possibility?
Thank you, Chris
|
|
Technical Support
|
Jun 5, 2006 - 1:01 PM
|
We think gave you the correct answer. We can review your code if you send it to us. The entire project would be preferable, but the main frame’ source code is enough.
|
|
Suhai Gyorgy
|
Jun 6, 2006 - 2:16 AM
|
I’m really sorry, it was my fault... I added my last post without having the code in front of me, but I remembered seeing those 3 lines in .rc2 file.... Well, yes, they were there but commented! So I did put them in there at some point but commented them for some reason. Anyways, now dragging is working nicely as before.
But I still have the other problem: Control bar appears in very small size.
I’ll post all code concerning creation of control bars... every control bar is created exactly the same way:
.h:
CExtControlBar *m_pCB1; CListCtrl m_wndDockedCtrl1;
.cpp (OnCreate):
HICON hIcon = (HICON)::LoadImage(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_CB1), IMAGE_ICON, 16, 16, 0); ASSERT( hIcon != NULL ); CExtCmdIcon iconCB1; iconCB1.AssignFromHICON( hIcon, true ); g_CmdManager->CmdSetIcon(g_CmdManager->ProfileNameFromWnd(GetSafeHwnd()), ID_VIEW_CB1, &iconCB1, false); m_pCB1 = new CExtControlBar; m_pCB1->Create(NULL, this, ID_VIEW_CB1); if(!m_pCB1 ) { TRACE0("Failed to create m_pCB1\n"); return -1; // fail to create } m_pCB1->EnableDocking(CBRS_ALIGN_ANY); m_pCB1->SetInitDesiredSizeVertical( CSize( 160, 160 ) ); m_pCB1->SetInitDesiredSizeHorizontal( CSize( 160, 160 ) ); m_pCB1->SetInitDesiredSizeFloating( CSize( 160, 160 ) ); m_pCB1->SetWindowText(_T("My Control Bar1")); if( !m_wndDockedCtrl1.Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|LVS_LIST, CRect(0,0,0,0), m_pCB1, m_pCB1->GetDlgCtrlID()) || !( (new CThinFrameWnd)->CreateDynamicThinFrame(&m_wndDockedCtrl1))) { return -1; // fail to create } m_wndDockedCtrl1.SetFont(CFont::FromHandle((HFONT)::GetStockObject(DEFAULT_GUI_FONT)));
CThinFrameWnd class is derived from CWnd and I got that from one of your samples to create a thin frame around controls.
Both our project and MainFrame are quite big, but if this plus information can’t help, I’ll try to create a small sample representing the problem.
Thank you very much: Chris
|
|
Technical Support
|
Jun 6, 2006 - 10:53 AM
|
Your code is absolutely correct, but it simply creates the control bar and the list. The control bar’s position is initialized outside this code. We need to take a look at the entire CMainFrame::OnCreate() method or at its part which docks all the control bars.
|
|
Suhai Gyorgy
|
Jun 6, 2006 - 12:26 PM
|
The docking part of the code looks as I already stated it in the first post of this thread:
if( !CExtControlBar::ProfileBarStateLoad(...)) { ShowControlBar(m_pCB1, false, false); ShowControlBar(m_pCB2, false, false); ShowControlBar(m_pCB3, false, false);
m_pCB1->FloatControlBar(); m_pCB1->DockControlBarIntoTabbedContainer(m_pCB2, -1, this, false); m_pCB2->DockControlBarIntoTabbedContainer(m_pCB1, -1, this, false); m_pCB1->DockControlBarIntoTabbedContainer(m_pCB3, -1, this, false); }
Surely at first program startup all control bars are invisible. But when I activate any of the control bars, it appears in a very small size. Also if I resize the control bar, hide it, close program, open it up again and activating control bar again, it is again in that very small size. I’m sure I save the state in DestroyWindow, because position of control bar is saved, but size is not.
Thank you: Chris
|
|
Technical Support
|
Jun 7, 2006 - 9:57 AM
|
The problem will be fixed if you hide your bars at the final stage: //ShowControlBar(m_pCB1, false, false);
//ShowControlBar(m_pCB2, false, false);
//ShowControlBar(m_pCB3, false, false);
m_pCB1->FloatControlBar();
m_pCB1->DockControlBarIntoTabbedContainer(m_pCB2, -1, this, false);
m_pCB2->DockControlBarIntoTabbedContainer(m_pCB1, -1, this, false);
m_pCB1->DockControlBarIntoTabbedContainer(m_pCB3, -1, this, false);
ShowControlBar(m_pCB1, false, false);
ShowControlBar(m_pCB2, false, false);
ShowControlBar(m_pCB3, false, false); We confirm that tthis will make the bars visible for a short time, but only when the application starts for the first time. The problem can be solved on client machines if the control bar state in the registry is initialized by the installer. We can also spend some time and provide you with the updated code which allows you to dock invisible floating bars.
|
|
Suhai Gyorgy
|
Jun 8, 2006 - 1:19 AM
|
Problem still persists. If I start application for the first time, I see the bars appearing and then disappearing, application is up and running... I close application, start it again right away, and then activating (showing) any of the control bars from menu.... Control bar appears in small size again.
Thank you: Chris.
|
|
Technical Support
|
Jun 8, 2006 - 4:47 AM
|
We sent you a modified version of your test project. The problem discussed in this thread can be solved using the CSufraceHider class implemented in the project. It should be used during the initial docking of all the bars.
|
|
Andrey Chashkov
|
Jun 1, 2006 - 2:38 AM
|
I have problems with redraw of grid lines during resizing of grid. (not sure posted first time)
I have grid screen_01 (http://dev.key-soft.net/4atsoy/profuis/prof_uis_page_01.JPG) And wnat to resize it to smallest size. I left click on grid line and move it to the left. After reaching of ’minimum extent’ vertical grid line didn’t erase screen_02 (http://dev.key-soft.net/4atsoy/profuis/prof_uis_page_02.JPG)
I think that this is must not happens. I think that grid lina must stop redraw after reaching of ’minimum extent’.
When I release left button grid line sets in ’minimum extent’ position and all clean up.
screen_03 (http://dev.key-soft.net/4atsoy/profuis/prof_uis_page_03.JPG)
I’ve use Prof-UIS component with 2.53 Here init code:
SiwModifyStyle( __ESIS_STH_PIXEL |__ESIS_STV_ITEM |__EGBS_FIXED_SIZE_ROWS |__EGBS_SFB_FULL_ROWS |__EGBS_GRIDLINES |__EGBS_NO_HIDE_SELECTION |__EGBS_RESIZING_CELLS_OUTER, __EGBS_SFB_FULL_COLUMNS, false ); BseModifyStyle(__EGWS_BSE_SORT_COLUMNS, __EGWS_BSE_EDIT_DOUBLE_LCLICK | __EGWS_BSE_EDIT_CELLS_INNER ); OuterRowCountTopSet( 1L, true ); // set fixed rows num
caaaiea extent’a aey eiie?aoiiai noieaoa: // set up columns int iColumn = 0; CExtGridCellHeader * pCell = STATIC_DOWNCAST(CExtGridCellHeader, m_tablesGrid1.GridCellGetOuterAtTop(iColumn, 0L, RUNTIME_CLASS(CExtGridCellHeader)) );
pCell->ExtentSet( rcGrid.Width() * 0.35, 0 ); // 0 - curr pCell->ExtentSet( 40, -1 ); // min (!!!) pCell->ExtentSet( rcGrid.Width() * 0.9, 1 ); // max pCell->TextSet( "Table" );
|
|
Technical Support
|
Jun 1, 2006 - 3:50 AM
|
Yes, we confirm that there was this bug in Prof-UIS 2.53. It was fixed in Prof-UIS 2.54.
|
|
Damien Castelltort
|
May 31, 2006 - 11:04 AM
|
Hi,
I’ve encountered a problem using a CExtPopupMenuWnd in a extension DLL. The dll implements a dialog call inside the main app.
The popup Menu is loaded like that : bOK = Menu.LoadMenu( IDR_LIB_NAVIGATOR_POPUP );
SubMenu = Menu.GetSubMenu(0); FillMoveElementMenu(SubMenu->GetSubMenu(4));
CExtPopupMenuWnd * pPopup = new CExtPopupMenuWnd;
//Construct the CExtPopupMenuWnd based on SubMenu pPopup->UpdateFromMenu( GetSafeHwnd(), &Menu, true, // bPopupMenu true, // bTopLevel true // bNoRefToCmdMngr );
//Track it pPopup->TrackPopupMenu(TPMX_LEFTALIGN, point.x, point.y);
The numeric ID of one of my item in the popup menu is the same as one of the main app Menu. In the main menu, the item has an icon associated automatically by profuis because it’s also in my main toolbar.
And when I pop the menu I have the same icon as in the main menu added by the profuis customization.
Here is a little screenshot to explain that a bit better : http://img241.imageshack.us/img241/8310/sanstitre7sa.jpg
|
|
Damien Castelltort
|
Jun 1, 2006 - 2:18 AM
|
OK, you confirm what we thought
Thanks for the answer.
|
|
Technical Support
|
May 31, 2006 - 12:33 PM
|
We recommend you avoid conflicts between commands identifiers. To fix your problem just change the identifier of one of the conflicting commands.
PS We noticed the bug with the Ctrl+Shift+N text in the popup menu. Please note this bug is already fixed in the last versions.
|
|
Mark Walsen
|
May 31, 2006 - 9:57 AM
|
MFC’s CMenu::DrawItem lets you customize a menu. In my case, I’d like to change the font and background color. Is there any sample code, or are there any tips, on how I should do this so as to not conflict with Prof-UIS’s drawing of menus?
Cheers -- Mark
|
|
Technical Support
|
May 31, 2006 - 12:09 PM
|
|
|
Mark Walsen
|
May 31, 2006 - 9:49 AM
|
I have had little success searching for things in this forum. For example, I’m looking for threads about how to customize menus. If I search for "customize menu" or "menu customize", the forum returns with what appears to be every post in the forum. Are there instructions somewhere as to how to conduct a successful search in the forum?
Your support is excellent(!), but you might consider switching to a better forum software package such as Discus by discusware.com
Cheers -- Mark
|
|
Mark Walsen
|
Jun 8, 2006 - 12:33 PM
|
I can highly recommend Discus by discusware.com
Cheers -- Mark
|
|
Mark Walsen
|
May 31, 2006 - 9:54 AM
|
I did learn one thing: For exact match, put the text in quotes, as in "customize menu".
However, neither of the following finds posts that have _both_ the words customize and menu in them:
customize menu
customize & menu
The above two searches just list every post in the forum.
Cheers -- Mark
|
|
Technical Support
|
May 31, 2006 - 12:20 PM
|
Thank you for your comments. The only way you can search for some info in forums now is to use the exact match like "custom drawing". Please note that double quotes are essential.
Most probably we will have to switch to some another forum software to make searching and indexing better.
|
|
David Skok
|
May 31, 2006 - 9:04 AM
|
Greetings!
In my application I use the OnMDIActivate message to synchronize other displays with the active MDI view.
The following code is abbreviated for simplicity and worked fine in v2.53 but now does not work correctly in v2.54. I also did a quick check by replacing the Splitter frame in the DrawCli sample with an overidden CMDIChild and it was broke there also.
class DrawFrame : public CMDIChild { ...
void DrawFrame::OnMDIActivate( BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd ) { CDocument *pDoc;
CMDIChildWnd::OnMDIActivate( bActivate, pActivateWnd, pDeactivateWnd );
if( !bActivate || !pActivateWnd ) return;
if( pActivateWnd->IsKindOf( RUNTIME_CLASS(CMDIChildWnd) ) ) pDoc = ((CMDIChildWnd*) pActivateWnd)->GetActiveDocument();
// ......use pDoc to tell non-views what doc is focused }
GetActiveDocument() returns the active document for the first MDIChild created and for every subsequent child created if the children are not maximized. If the children are maximized GetActiveDocument() returns the correct pDoc for the first new document but NULL for every subsequent "new". In either case (maximized or not) switching between views always returns the active document. It just so happens that my app always operates on maximized views.
Thanks
|
|
Technical Support
|
Jun 1, 2006 - 3:07 AM
|
Thank you for reporting the bug. Please update the source code of the CExtMenuControlBar::OnHookWndMsg() method in the ExtPopupMenuWnd.cpp file: bool CExtMenuControlBar::OnHookWndMsg(
LRESULT & lResult,
HWND hWndHooked,
UINT nMessage,
WPARAM & wParam,
LPARAM & lParam
)
{
__PROF_UIS_MANAGE_STATE;
if( GetSafeHwnd() == NULL
|| (! ::IsWindow(GetSafeHwnd()) )
|| CWnd::FromHandlePermanent(GetSafeHwnd()) == NULL
|| _DraggingGetBar() != NULL
)
return
CExtHookSink::OnHookWndMsg(
lResult,
hWndHooked,
nMessage,
wParam,
lParam
);
HWND hWndMainFrame = NULL;
CWnd * pWndForPlacement = NULL;
if( ! m_bPresubclassDialogMode )
{
hWndMainFrame = _GetHwndMainFrame();
if( hWndMainFrame != NULL )
pWndForPlacement = stat_GetWndForPlacement( CWnd::FromHandle(hWndMainFrame) );
}
if( ( (!m_bPresubclassDialogMode)
&& ( ( hWndMainFrame != NULL
&& hWndHooked == hWndMainFrame
)
|| ( pWndForPlacement != NULL
&& hWndHooked == pWndForPlacement->m_hWnd
)
)
)
|| ( m_bPresubclassDialogMode
&& hWndHooked == _GetHwndPlacement()
)
)
{
if( nMessage == WM_PARENTNOTIFY
&&
CExtPopupMenuWnd::IsMenuTracking()
)
{
lResult = 0;
return true;
}
if( nMessage == WM_SIZE
|| nMessage == WM_ACTIVATEAPP
|| ( nMessage == WM_COMMAND
&& ( ((HIWORD(wParam))==0)
|| ((HIWORD(wParam))==1)
)
)
|| nMessage == WM_SYSCOMMAND
)
{
HWND hWndCapture = CExtMouseCaptureSink::GetCapture();
if( hWndCapture == GetSafeHwnd() )
CExtMouseCaptureSink::ReleaseCapture();
else if( hWndCapture != NULL )
{
CWnd * pWnd = FromHandlePermanent(hWndCapture);
if( pWnd != NULL
&& pWnd->GetSafeHwnd() != NULL
&& ::IsWindow( pWnd->GetSafeHwnd() )
&& pWnd->IsKindOf(RUNTIME_CLASS(CExtControlBar))
)
CExtMouseCaptureSink::ReleaseCapture();
}
_CancelFlatTracking();
if( CExtMenuControlBar::g_bMenuTracking )
CExtMenuControlBar::_CloseTrackingMenus();
return
CExtHookSink::OnHookWndMsg(
lResult,
hWndHooked,
nMessage,
wParam,
lParam
);
}
if( !m_bPresubclassDialogMode )
{
if( (nMessage == WM_NCLBUTTONUP && wParam == HTSYSMENU)
|| (nMessage == WM_NCRBUTTONUP && (wParam == HTCAPTION || wParam == HTSYSMENU))
)
{
CExtToolControlBar::g_bMenuTrackingExpanded = false;
CPoint * pPoint = NULL, ptCursor;
if( nMessage == WM_NCRBUTTONUP )
{
if( ! ::GetCursorPos(&ptCursor) )
{
lResult = 0;
return true;
}
pPoint = &ptCursor;
}
if( !_IsDockSiteCustomizeMode() )
{
if( ! TrackMainFrameSystemMenu(
pPoint,
FALSE
)
)
return false;
}
lResult = 0;
return true;
}
if( (nMessage == WM_NCLBUTTONDOWN || nMessage == WM_NCRBUTTONDOWN)
&& wParam == HTSYSMENU
)
{
lResult = 0;
if( (! m_bAllowProfMainFrameSysmenu )
&& hWndHooked == _GetHwndMainFrame()
)
return false;
if( (! m_bAllowProfChildFrameSysmenu )
&& _IsMdiApp()
&& hWndHooked == _GetHwndChildFrame()
)
return false;
return true;
}
if( nMessage == WM_NCRBUTTONDOWN && wParam == HTCAPTION )
{
if( !_IsDockSiteCustomizeMode() )
{
CExtToolControlBar::g_bMenuTrackingExpanded = false;
CPoint ptCursor;
if( ::GetCursorPos(&ptCursor) )
if( ! TrackMainFrameSystemMenu(
&ptCursor,
FALSE
)
)
return false;
}
lResult = 0;
return true;
}
if( nMessage == CExtPopupMenuWnd::g_nMsgNotifyMenuClosed )
{
m_bSysMenuTracking = false;
return false;
}
}
bool bPrintPreviewMode = false;
if( (!m_bPresubclassDialogMode)
&& m_pDockSite->GetSafeHwnd() != NULL
&& FindPrintPreviewMode(m_pDockSite)
)
bPrintPreviewMode = true;
if( nMessage == CExtPopupMenuWnd::g_nMsgPopupNext
|| nMessage == CExtPopupMenuWnd::g_nMsgPopupPrev
)
{
BOOL bDummyMax = FALSE;
HWND hWndMdiChild = _GetActiveMdiChildWnd(bDummyMax);
int iTrackingIndex =
GetMenuTrackingButton();
if( (!bPrintPreviewMode) && iTrackingIndex < 0 )
{
if( m_bSysMenuTracking )
{
if( nMessage == CExtPopupMenuWnd::g_nMsgPopupNext
&& _IsMdiApp()
&& hWndMdiChild != NULL
&& IsDisplayMdiDocumentButtons()
)
{
ASSERT( !m_bPresubclassDialogMode );
if( ! TrackChildFrameSystemMenu(
NULL,
TRUE
)
)
{
if( m_bAllowProfChildFrameSysmenu )
return false;
int iNewTrackIndex =
GetVisibleButton(
iTrackingIndex,
(nMessage == CExtPopupMenuWnd::g_nMsgPopupNext) ?
TRUE : FALSE
);
if( iNewTrackIndex == iTrackingIndex )
{
lResult = 0;
return true;
}
TrackButtonMenu(iNewTrackIndex);
}
}
else
{
int iNewTrackIndex =
GetVisibleButton(
iTrackingIndex,
(nMessage == CExtPopupMenuWnd::g_nMsgPopupNext) ?
TRUE : FALSE
);
if( iNewTrackIndex == iTrackingIndex )
{
lResult = 0;
return true;
}
TrackButtonMenu(iNewTrackIndex);
}
}
lResult = 0;
return true;
}
if( nMessage == CExtPopupMenuWnd::g_nMsgPopupNext
&& ( !m_bPresubclassDialogMode )
&& iTrackingIndex == GetVisibleButton(-1,FALSE)
)
{
if( ! _IsDockSiteCustomizeMode() )
{
if( (! TrackMainFrameSystemMenu(
NULL,
TRUE
) )
)
{
if( m_bAllowProfMainFrameSysmenu )
return false;
int iNewTrackIndex =
GetVisibleButton(
iTrackingIndex,
(nMessage == CExtPopupMenuWnd::g_nMsgPopupNext) ?
TRUE : FALSE
);
if( bPrintPreviewMode
|| iNewTrackIndex == iTrackingIndex
)
{
lResult = 0;
return true;
}
TrackButtonMenu(iNewTrackIndex);
lResult = 0;
return true;
}
}
lResult = 0;
return true;
}
if( nMessage == CExtPopupMenuWnd::g_nMsgPopupPrev
&& ( !m_bPresubclassDialogMode )
&& iTrackingIndex == 0
&& IsDisplayMdiDocumentButtons()
)
{
if( ! _IsDockSiteCustomizeMode() )
{
if( (! (_IsMdiApp() && hWndMdiChild != NULL ) )
|| bPrintPreviewMode
|| (! TrackChildFrameSystemMenu(
NULL,
TRUE
)
)
)
{
if( ! TrackMainFrameSystemMenu(
NULL,
TRUE
)
)
{
if( m_bAllowProfMainFrameSysmenu )
return false;
int iNewTrackIndex =
GetVisibleButton(
iTrackingIndex,
(nMessage == CExtPopupMenuWnd::g_nMsgPopupNext) ?
TRUE : FALSE
);
if( bPrintPreviewMode
|| iNewTrackIndex == iTrackingIndex
)
{
lResult = 0;
return true;
}
TrackButtonMenu(iNewTrackIndex);
lResult = 0;
return true;
}
}
}
lResult = 0;
return true;
}
if( nMessage == CExtPopupMenuWnd::g_nMsgPopupNext
&& (!m_bPresubclassDialogMode)
&& _IsMdiApp()
&& m_bSysMenuTracking
&& iTrackingIndex < 0
&& hWndMdiChild != NULL
&& IsDisplayMdiDocumentButtons()
&& (!bPrintPreviewMode)
)
{
if( !_IsDockSiteCustomizeMode() )
if( ! TrackChildFrameSystemMenu(
NULL,
TRUE
)
)
return false;
lResult = 0;
return true;
}
int iNewTrackIndex =
GetVisibleButton(
iTrackingIndex,
(nMessage == CExtPopupMenuWnd::g_nMsgPopupNext) ?
TRUE : FALSE
);
if( (! IsDisplayMdiDocumentButtons() )
&& nMessage == CExtPopupMenuWnd::g_nMsgPopupPrev
&& iTrackingIndex == 0
&& iNewTrackIndex > 0
)
{
if( !_IsDockSiteCustomizeMode() )
if( ! TrackMainFrameSystemMenu(
NULL,
TRUE
)
)
return false;
lResult = 0;
return true;
}
if( bPrintPreviewMode
|| iNewTrackIndex == iTrackingIndex
)
{
lResult = 0;
return true;
}
TrackButtonMenu(iNewTrackIndex);
lResult = 0;
return true;
}
if( nMessage == CExtPopupMenuWnd::g_nMsgNotifyMenuExpanded )
{
CExtToolControlBar::g_bMenuTrackingExpanded = true;
lResult = 0;
return true;
}
if( ! m_bPresubclassDialogMode )
{
if( nMessage == WM_STYLECHANGING
|| nMessage == WM_STYLECHANGED
)
return false;
_KillFrameMenu();
}
}
else if( hWndHooked == _GetHwndChildFrame() )
{
if( nMessage == WM_PARENTNOTIFY
&& CExtPopupMenuWnd::IsMenuTracking()
)
{
lResult = 0;
return true;
}
if( nMessage == WM_SIZE
|| nMessage == WM_WINDOWPOSCHANGED
|| nMessage == WM_ACTIVATEAPP
|| ( nMessage == WM_COMMAND && (((HIWORD(wParam))==0)||((HIWORD(wParam))==1)) )
|| nMessage == WM_SYSCOMMAND
)
{
bool bSizePos = false;
if( nMessage == WM_SIZE )
bSizePos = true;
else if( nMessage == WM_WINDOWPOSCHANGED )
{
LPWINDOWPOS lpWP = (LPWINDOWPOS)lParam;
ASSERT( lpWP != NULL );
if( (lpWP->flags & SWP_FRAMECHANGED) == 0 )
bSizePos = true;
}
HWND hWndCapture = CExtMouseCaptureSink::GetCapture();
if( hWndCapture == GetSafeHwnd() )
CExtMouseCaptureSink::ReleaseCapture();
else if( hWndCapture != NULL )
{
CWnd * pWnd = FromHandlePermanent(hWndCapture);
if( pWnd != NULL
&& pWnd->GetSafeHwnd() != NULL
&& ::IsWindow( pWnd->GetSafeHwnd() )
&& pWnd->IsKindOf(RUNTIME_CLASS(CExtControlBar))
&& (! (((CExtControlBar*)pWnd)->_RowResizingGet() ) )
&& (! (((CExtControlBar*)pWnd)->_RowRecalcingGet() ) )
)
CExtMouseCaptureSink::ReleaseCapture();
}
_CancelFlatTracking();
if( CExtMenuControlBar::g_bMenuTracking )
CExtMenuControlBar::_CloseTrackingMenus();
if( CExtPopupMenuWnd::IsMenuTracking() )
CExtPopupMenuWnd::CancelMenuTracking();
if( !bSizePos )
{
_KillFrameMenu();
if( ( nMessage == WM_SIZE
|| nMessage == WM_WINDOWPOSCHANGED
)
&& (! _IsDockSiteCustomizeMode() )
)
{
WINDOWPLACEMENT _wp;
::memset( &_wp, 0, sizeof(WINDOWPLACEMENT) );
_wp.length = sizeof(WINDOWPLACEMENT);
::GetWindowPlacement( _GetHwndChildFrame(), &_wp );
if( _wp.showCmd != SW_SHOWMAXIMIZED
|| ( _GetButtonsCountImpl() > 0
&& (! _GetButtonPtr(0)->IsKindOf(RUNTIME_CLASS(CExtBarMdiDocButton)) )
&& ( IsDisplayMdiDocumentButtons() )
)
)
_DelayUpdateMenuBar();
}
}
return
CExtHookSink::OnHookWndMsg(
lResult,
hWndHooked,
nMessage,
wParam,
lParam
);
}
bool bPrintPreviewMode = false;
if( (!m_bPresubclassDialogMode)
&& m_pDockSite->GetSafeHwnd() != NULL
&& FindPrintPreviewMode(m_pDockSite)
)
bPrintPreviewMode = true;
if( bPrintPreviewMode )
{
lResult = 0;
return true;
}
bool bMinFrameNcLbDown = false;
bool bMinFrameNcLbUp = false;
if( nMessage == WM_NCLBUTTONDOWN
|| nMessage == WM_NCLBUTTONUP
)
{
WINDOWPLACEMENT _wp;
::memset( &_wp, 0, sizeof(WINDOWPLACEMENT) );
_wp.length = sizeof(WINDOWPLACEMENT);
::GetWindowPlacement( hWndHooked, &_wp );
if( _wp.showCmd == SW_SHOWMINIMIZED )
{
if( nMessage == WM_NCLBUTTONDOWN )
bMinFrameNcLbDown = true;
else if( nMessage == WM_NCLBUTTONUP )
bMinFrameNcLbUp = true;
}
}
if( bMinFrameNcLbUp && wParam == HTCAPTION )
return true;
if( ( bMinFrameNcLbDown && wParam == HTCAPTION )
|| (nMessage == WM_NCLBUTTONUP && wParam == HTSYSMENU)
|| (nMessage == WM_NCRBUTTONUP && (wParam == HTCAPTION || wParam == HTSYSMENU))
)
{
CExtToolControlBar::g_bMenuTrackingExpanded = false;
CPoint * pPoint = NULL, ptCursor;
if( nMessage == WM_NCRBUTTONUP )
{
if( ! ::GetCursorPos(&ptCursor) )
{
lResult = 0;
return true;
}
pPoint = &ptCursor;
}
if( !_IsDockSiteCustomizeMode() )
if( ! TrackChildFrameSystemMenu(
pPoint,
FALSE
)
)
return false;
lResult = 0;
return true;
}
if( (nMessage == WM_NCLBUTTONDOWN || nMessage == WM_NCRBUTTONDOWN)
&& wParam == HTSYSMENU
)
{
if( ! m_bAllowProfChildFrameSysmenu )
return false;
lResult = 0;
return true;
}
if( nMessage == WM_NCRBUTTONDOWN && wParam == HTCAPTION )
{
if( !_IsDockSiteCustomizeMode() )
{
CExtToolControlBar::g_bMenuTrackingExpanded = false;
CPoint ptCursor;
if( ::GetCursorPos(&ptCursor) )
if( ! TrackChildFrameSystemMenu(
&ptCursor,
FALSE
)
)
return false;
}
lResult = 0;
return true;
}
if( nMessage == CExtPopupMenuWnd::g_nMsgNotifyMenuClosed )
{
m_bSysMenuTracking = false;
return true;
}
if( nMessage == CExtPopupMenuWnd::g_nMsgPopupNext
|| nMessage == CExtPopupMenuWnd::g_nMsgPopupPrev
)
{
int iTrackingIndex =
GetMenuTrackingButton();
if( nMessage == CExtPopupMenuWnd::g_nMsgPopupPrev )
{
if( ! _IsDockSiteCustomizeMode() )
{
if( ! TrackMainFrameSystemMenu(
NULL,
TRUE
)
)
{
if( m_bAllowProfMainFrameSysmenu )
return false;
int iNewTrackIndex =
GetVisibleButton(
iTrackingIndex,
(nMessage == CExtPopupMenuWnd::g_nMsgPopupNext) ?
TRUE : FALSE
);
if( iNewTrackIndex == iTrackingIndex )
{
lResult = 0;
return true;
}
TrackButtonMenu(iNewTrackIndex);
}
}
lResult = 0;
return true;
}
if( iTrackingIndex < 0 )
{
if( m_bSysMenuTracking )
{
int iNewTrackIndex =
GetVisibleButton(
iTrackingIndex,
(nMessage == CExtPopupMenuWnd::g_nMsgPopupNext) ?
TRUE : FALSE
);
if( iNewTrackIndex == iTrackingIndex )
{
lResult = 0;
return true;
}
TrackButtonMenu(iNewTrackIndex);
}
lResult = 0;
return true;
}
int iNewTrackIndex =
GetVisibleButton(
iTrackingIndex,
(nMessage == CExtPopupMenuWnd::g_nMsgPopupNext) ?
TRUE : FALSE
);
if( iNewTrackIndex == iTrackingIndex )
{
lResult = 0;
return true;
}
TrackButtonMenu(iNewTrackIndex);
lResult = 0;
return true;
}
}
else if( hWndHooked == _GetHwndMdiArea() )
{
if( nMessage == WM_PARENTNOTIFY
&&
CExtPopupMenuWnd::IsMenuTracking()
)
{
lResult = 0;
return true;
}
if( nMessage == WM_MDISETMENU )
{
CFrameWnd * pFrame = _GetDockingFrameImpl();
ASSERT_VALID( pFrame );
HWND hWndFrame = pFrame->GetSafeHwnd();
ASSERT( hWndFrame != NULL );
ASSERT( ::IsWindow(hWndFrame) );
bool bOle = IsOleIpObjActive();
HMENU hOldMdiMenu = m_menuDoc.Detach();
HMENU hNewMdiMenu = (HMENU)wParam;
m_menuDoc.Attach( hNewMdiMenu );
if( bOle )
::SetMenu( hWndFrame, hNewMdiMenu );
else
{
HMENU hFrameRealMenu = ::GetMenu( hWndFrame );
if( hFrameRealMenu != NULL )
::SetMenu( hWndFrame, NULL );
_DelayUpdateMenuBar();
}
CExtHookSink::OnHookWndMsgNextProcCurrent( 0L, 0L );
lResult = (LRESULT)hOldMdiMenu;
_SyncActiveMdiChild();
m_bDelayedSyncActiveMdiChild = false;
return true;
}
if( nMessage == WM_MDIREFRESHMENU )
{
CExtHookSink::OnHookWndMsgNextProcCurrent( 0L, 0L );
_SyncActiveMdiChild();
m_bDelayedSyncActiveMdiChild = false;
lResult = 0;
return true;
}
if( nMessage == WM_CONTEXTMENU )
{
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
CExtCustomizeSite * pSite =
CExtCustomizeSite::GetCustomizeSite( m_hWnd );
if( pSite != NULL
&& pSite->IsCustomizeMode()
)
{
lResult = 0;
return true;
}
#endif
if( !CExtControlBar::FindHelpMode(this) )
{
CFrameWnd * pFrame = _GetDockingFrameImpl();
ASSERT_VALID( pFrame );
CPoint ptCursor;
if( ! ::GetCursorPos(&ptCursor) )
{
lResult = 0;
return true;
}
HWND hWndTrack = GetOwner()->GetSafeHwnd();
ASSERT( hWndTrack != NULL && ::IsWindow(hWndTrack) );
CExtPopupMenuWnd * pPopup = new CExtPopupMenuWnd;
VERIFY( pPopup->CreatePopupMenu(hWndTrack) );
if( ! CExtDockBar::_ConstructDockSiteControlBarPopupMenu(
pFrame,
pPopup,
CExtControlBar::POPUP_MENU_EVENT_DATA::__PMED_MDICLIAREA_CTX,
this,
WM_CONTEXTMENU,
NULL
)
)
delete pPopup;
else
{
if( pPopup->ItemGetCount() == 0 )
delete pPopup;
else
{
::SetFocus( hWndTrack );
if( ! pPopup->TrackPopupMenu(
TPMX_OWNERDRAW_FIXED,
ptCursor.x,
ptCursor.y,
NULL,
this,
NULL,
NULL,
true
)
)
delete pPopup;
}
}
}
lResult = 0;
return true;
}
if( nMessage == WM_MDIACTIVATE
|| nMessage == WM_MDIDESTROY
|| nMessage == WM_MDINEXT
)
{
if( nMessage == WM_MDINEXT
&& IsOleIpObjActive()
)
{
lResult = 0;
return true;
}
_DelaySyncActiveMdiChild();
}
if( g_PaintManager.m_bIsWinXPorLater )
{
HWND hWndMdiArea = _GetHwndMdiArea();
if( nMessage == WM_MDIACTIVATE )
{
HWND hWndNew = (HWND)wParam;
BOOL bOldWasMaximized = FALSE;
HWND hWndOld = (HWND)
::SendMessage( hWndMdiArea, WM_MDIGETACTIVE, 0, (LPARAM)&bOldWasMaximized );
if( bOldWasMaximized )
{
ASSERT( ::IsZoomed( hWndOld ) );
::SendMessage( hWndMdiArea, WM_SETREDRAW, FALSE, 0 );
}
if( ::IsIconic( hWndNew ) )
::SendMessage( hWndMdiArea, WM_MDIRESTORE, (WPARAM)hWndNew, 0 );
LRESULT _lResult = CExtHookSink::OnHookWndMsgDefault();
_lResult;
if( bOldWasMaximized )
{
::SendMessage( hWndMdiArea, WM_SETREDRAW, TRUE, 0 );
::RedrawWindow( hWndMdiArea, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN );
}
return true;
}
return
CExtHookSink::OnHookWndMsg(
lResult,
hWndHooked,
nMessage,
wParam,
lParam
);
}
}
else
{
ASSERT( FALSE );
}
MSG msg;
::memset( &msg, 0, sizeof(MSG) );
msg.hwnd = hWndHooked;
msg.message = nMessage;
msg.wParam = wParam;
msg.lParam = lParam;
if( TranslateMainFrameMessage(&msg) )
return true;
return
CExtHookSink::OnHookWndMsg(
lResult,
hWndHooked,
nMessage,
wParam,
lParam
);
}
|
|
David Skok
|
Jun 1, 2006 - 6:32 AM
|
Thank you for the quick response, problem solved.
As a note for others reading this, the source to replace is in ExtMenuControlBar.cpp not ExtPopupMenuWnd.cpp
|
|
Patrick MITTON
|
May 30, 2006 - 7:41 AM
|
Does profuis can load old registry personalisation? For example, 2.54 version can import personalisation in registry from 2.53 version or older version? Each version has this on registry branch.
|
|
Technical Support
|
May 30, 2006 - 12:20 PM
|
The persistence is currently based on binary archives and cannot be ported between versions. We are developing new persistence subsystems for several controls which are based on a tree like data structure with named folders/values and ability to be saved to / loaded from an XML. This should solve the problem of the cross version compatibility.
|
|
Patrick MITTON
|
May 29, 2006 - 8:43 AM
|
Hi
I have an MDI application made with visual C++ 6.0. I have to create some toolbars and menu at run time.
I have three little problems: - I can’t personalize runtime created tools bars. Static created bars have “add remove button” menu on the right click (I use the French version I guess the menu called like that in English), not the dynamic created. - On this application I haven’t the check marks on visible tools bar (I have an other with only static tools bars who works perfectly) - The MDI menu don’t change with specific loaded documents.
This application load toolbar and menu resources form external DLL is there some precautions to take? (I change resource handle at runtime)
|
|
Technical Support
|
May 29, 2006 - 12:31 PM
|
We recommend you choose the design of customizable toolbars and menus which are based on the Prof-UIS customization subsystem demonstrated in the DRAWCLI, BitmapEditor, StyleEditor and LanguageSwitcher sample applications. The following article describes the basics.
|
|
Raffaele Cappelli
|
May 26, 2006 - 5:07 PM
|
I noted some strange color problems and, after some investigations, I found that, in some cases, CExtBitmap::stat_RGBtoHSL does not work. This happens only in one of my PCs and in release builds: the problem seems that the == comparisons between floating point numbers ("if( r == cmax )" and ("if( g == cmax )") do not return the expected result. I guess this may be due to some optimizations of the compiler (it happens only in release builds) and/or the behavior of a given coprocessor (I can reproduce it only in one PC). In general it is not a good practice to compare floating numbers with ==, but in this case there should not be any problem, since the numbers that are compared should be identical when the corresponding r,g,b values are identical. However, just to be more sure, the function may be modified using tolerances or (I prefer this second option) comparing the r,g,b integer values. As a matter of fact, modifying the function as follows, I was no longer able to reproduce the problem. Please let me know what you think.
void _RGBtoHSL( COLORREF rgb, double *H, double *S, double *L ) {
int nR = GetRValue(rgb);
int nG = GetGValue(rgb);
int nB = GetBValue(rgb);
int nMin = min(nR,min(nG,nB));
int nMax = max(nR,min(nG,nB));
double delta;
double r = (double)nR/255;
double g = (double)nG/255;
double b = (double)nB/255;
double cmax = (double)nMax/255;
double cmin = (double)nMin/255;
*L = (cmax + cmin) / 2.0;
if(nMax==nMin)
{
*S = 0;
*H = 0; // it’s really undefined
}
else
{
if( *L < 0.5 )
*S = (cmax-cmin)/(cmax+cmin);
else
*S = (cmax-cmin)/(2.0-cmax-cmin);
delta = cmax - cmin;
if( nR == nMax )
*H = (g-b)/delta;
else if( nG == nMax )
*H = 2.0 +(b-r)/delta;
else
*H = 4.0 + (r-g)/delta;
*H /= 6.0;
if( *H < 0.0 )
*H += 1;
}
}
|
|
Raffaele Cappelli
|
May 27, 2006 - 2:33 AM
|
Sorry, there is an error in the previous code: it should be
int nMax = max(nR,max(nG,nB));
|
|
Technical Support
|
May 28, 2006 - 12:25 PM
|
This function is based on this article. We have checked the source code and cannot confirm that there is a problem with this. First of all the CExtBitmap::stat_RGBtoHSL() method’s source code looks different than the method in your message and has no problem with min/max function usage.
|
|
Raffaele Cappelli
|
May 29, 2006 - 1:56 AM
|
This is the function I have. Please let me know if it is different from the one in your latest sources. As you can see, it uses floating point numbers, while the MS sample doesn’t.
void CExtBitmap::stat_RGBtoHSL( COLORREF rgb, double *H, double *S, double *L )
{
double delta;
double r = (double)GetRValue(rgb)/255;
double g = (double)GetGValue(rgb)/255;
double b = (double)GetBValue(rgb)/255;
double cmax = max(r,max(g,b));
double cmin = min(r,min(g,b));
*L = (cmax + cmin) / 2.0;
if(cmax==cmin)
{
*S = 0;
*H = 0; // it’s really undefined
}
else
{
if( *L < 0.5 )
*S = (cmax-cmin)/(cmax+cmin);
else
*S = (cmax-cmin)/(2.0-cmax-cmin);
delta = cmax - cmin;
if( r == cmax )
*H = (g-b)/delta;
else if( g == cmax )
*H = 2.0 +(b-r)/delta;
else
*H = 4.0 + (r-g)/delta;
*H /= 6.0;
if( *H < 0.0 )
*H += 1;
}
}
|
|
Technical Support
|
May 29, 2006 - 12:28 PM
|
The following updated version should work on any computer: void CExtBitmap::stat_RGBtoHSL( COLORREF rgb, double *H, double *S, double *L )
{
INT nr = GetRValue( rgb );
INT ng = GetGValue( rgb );
INT nb = GetBValue( rgb );
double delta;
double r = double( nr ) / 255.0;
double g = double( ng ) / 255.0;
double b = double( nb ) / 255.0;
INT ncmax = max( nr, max( ng, nb ) );
INT ncmin = min( nr, min( ng, nb ) );
double cmax = double( ncmax ) / 255.0;
double cmin = double( ncmin ) / 255.0;
*L = ( cmax + cmin ) / 2.0;
if( ncmax == ncmin )
{
*S = 0;
*H = 0; // undefined
}
else
{
if( *L < 0.5 )
*S = ( cmax - cmin ) / ( cmax + cmin );
else
*S = ( cmax - cmin ) / ( 2.0 - cmax - cmin );
delta = cmax - cmin;
if( r == cmax )
*H = ( g -b ) / delta;
else if( g == cmax )
*H = 2.0 +( b - r ) / delta;
else
*H = 4.0 + ( r - g) / delta;
*H /= 6.0;
if( *H < 0.0 )
*H += 1;
}
}
|
|
Raffaele Cappelli
|
May 29, 2006 - 1:40 PM
|
You are still comparing float numbers with == . Please further modify "if( r == cmax )" in " if( nr == ncmax )" and "else if( g == cmax )" in "else if( ng == ncmax )" , as I suggested at the beginning. I think the problem may occur when the compiler optimizes the code placing one of the variables (e.g. r) in the coprocessor stack (80 bit) and another (e.g. cmax) in memory (64 bit).
|
|
Technical Support
|
May 30, 2006 - 12:10 PM
|
Thank you for this comment. We followed your suggestion and replaced two floating point variable comparisons with identical numeric variable comparisons. Now the method is: void CExtBitmap::stat_RGBtoHSL( COLORREF rgb, double *H, double *S, double *L )
{
INT nr = GetRValue( rgb );
INT ng = GetGValue( rgb );
INT nb = GetBValue( rgb );
double delta;
double r = double( nr ) / 255.0;
double g = double( ng ) / 255.0;
double b = double( nb ) / 255.0;
INT ncmax = max( nr, max( ng, nb ) );
INT ncmin = min( nr, min( ng, nb ) );
double cmax = double( ncmax ) / 255.0;
double cmin = double( ncmin ) / 255.0;
*L = ( cmax + cmin ) / 2.0;
if( ncmax == ncmin )
{
*S = 0;
*H = 0; // undefined
}
else
{
if( *L < 0.5 )
*S = ( cmax - cmin ) / ( cmax + cmin );
else
*S = ( cmax - cmin ) / ( 2.0 - cmax - cmin );
delta = cmax - cmin;
if( nr == ncmax )
*H = ( g -b ) / delta;
else if( ng == ncmax )
*H = 2.0 +( b - r ) / delta;
else
*H = 4.0 + ( r - g) / delta;
*H /= 6.0;
if( *H < 0.0 )
*H += 1;
}
}
|
|
Raffaele Cappelli
|
May 29, 2006 - 1:55 AM
|
|
|
Massimo Germi
|
May 26, 2006 - 4:58 AM
|
Hi, I have created a CExtControlBar and a CExtResizableDialog derived class inside. In CExtResizableDialog I have created a mamber variable derived from CExtCheckBox. CExtControlBar derived class i always in autohide mode. Programmatically, in MainFrame class, I wish to check or uncheck CExtCheckBox variable declared in CExtResizableDialog. When I call SetCheck(...) the variable is really checked or unchecked but it does not display its state, is always unchecked.
Do you have any suggestions?
tx again
|
|
Technical Support
|
May 26, 2006 - 9:10 AM
|
We failed to reproduce this bug. Here is a test project we used for testing. Please compile it and let us know whether the bug persists (click on the toolbar button with a red circle). Please also tell us which version of the library you are using.
|
|
Massimo Germi
|
May 26, 2006 - 3:23 PM
|
OK, it has been a my error. I have stored in a SQL table the state of the cjeckbox, it return -1 if true and 0 if false, simple I set the state of checkbox with SetCheck( variable returned from SQL query (-1 or 0)) and not with flag SetCheck(BST_CHECKED or BST_UNCHECKED).
tx for the interest
|
|