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 |
|
Chris Thomas
|
Sep 22, 2005 - 1:52 PM
|
--third attempt at posting--- sorry if there end up duplicates ---
I have an app with a modeless dialog that is created/destroyed via a toolbar button, like a toggle. I want to replace that with a docking bar that hosts the dialog, but I want to do it at runtime. You can move the floating bar around and close it, and it persists its location and size, so next time it shows where it was.
It is working but I’m having two problems: 1) can’t seem to reliably get the coordinates of the control bar. I think it has trouble compensating for the floating frame’s size. And it exhibits strange behavior on a second monitor - it insists on putting the floating bar at the same position, regardless of where you try to move it. 2) Something is wrong with the docking bar creation code. If you create it, it crashes if you try to dock it somewhere. I’m doing all the same initialization steps that the similar bars do in mainframe OnCreate().
I really don’t want to create placeholders in mainframe for the 7 or so dialogs I have. The dialogs aren’t created in mainframe, so if mainframe did create CExtControlBar placeholders, they would be hidden and empty - I don’t know if that is problematic or not.
I have two functions in mainframe - one for loading a CWnd into a CExtControlBar, and one for unloading. The loading function takes a CWnd* ptr and creates a new CExtControlBar, reparents the CWnd into it, and floats it. The unloader finds the bar and removes and deletes it.
What am I missing or doing wrong?
----------------
bool CMainFrame::LoadDockingWindow(const CString& csName, CWnd* pWnd /*, CPoint& pt*/) { CExtControlBar* pBar = 0; if (m_mapControlBars.Lookup(csName, (void*&)pBar)) //bail if already exists, shouldn’t happen return false;
//make a new CControlBar pBar = new CExtControlBar(); if (!pBar->Create(csName, this, pWnd->GetDlgCtrlID(), WS_CHILD|WS_VISIBLE |CBRS_LEFT|CBRS_GRIPPER|CBRS_TOOLTIPS |CBRS_FLYBY|CBRS_SIZE_DYNAMIC |CBRS_HIDE_INPLACE)) return false;
CRect rc; pWnd->GetWindowRect(&rc); ScreenToClient(&rc);
TRACE("floating at (%d,%d) (%d x %d)\n", rc.left, rc.top, rc.Width(), rc.Height()); pWnd->SetParent(pBar); pBar->EnableDocking( CBRS_ALIGN_ANY ); pBar->SetInitDesiredPosFloating(rc.TopLeft()); pBar->SetInitDesiredSizeFloating(rc.Size()); FloatControlBar(pBar, CPoint(rc.left, rc.top)); //??? doesn’t work -- pWnd->SetWindowPos(NULL, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER); //activate the window pWnd->Invalidate(); pWnd->UpdateWindow(); m_mapControlBars.SetAt(csName, (void*)pBar); RecalcLayout(); return true; }
bool CMainFrame::UnloadDockingWindow(const CString& csName) { CExtControlBar* pBar = 0; if (!m_mapControlBars.Lookup(csName, (void*&)pBar) || pBar == 0) //bail if doesn’t exists, shouldn’t happen return false; m_mapControlBars.RemoveKey(csName); RemoveControlBar(pBar); pBar->DestroyWindow(); delete pBar; RecalcLayout(); return true; }
|
|
Chris Thomas
|
Sep 22, 2005 - 2:44 PM
|
I have more info -- first I solved the position problem by using the bar’s GetPosFloating() and GetSizeFloating() functions. However it still has funky behavior if you move the floating bar to the second monitor, destroy it, then create it. It won’t create at the position on the second monitor, rather it mysteriously puts it back on the first monitor, down in the right corner. Strange.
The docking on-the-fly is working better than I first reported. It docks and floats fine, except it ASSERTs when you dock the floating bar, then re-float it. It ASSERTs in CDockBar line 1186, in CExtDockBar::_RemovePlaceHolder(): ASSERT( pBar != NULL ); // may be placeholder ID
Ignoring that ASSERT brings you to another ASSERT at the same place. Ignoring that one works, and voila the floating bar appears. So it could probably be a Debug-only problem, but my fellow programmers here would tar and feather me if they had to see those in debug mode...
So I must be doing something incorrect when I create the CExtControlBar...?
The other issue I’m having is a barrage of ASSERTs when the floating bar is up, and I right-click on unused control bar space to see the menu of control bars. I think this is because the command manager doesn’t know about the new floating bar’s id or name. Ignoring all those ASSERTs allows it to work, but you don’t see a menu item for the floating bar. How can I override that menu so it won’t allow the user to see or manipulate certain bars? Is there a magic flag buried somewhere to control each bar’s participation in this?
Thanks!
|
|
Technical Support
|
Sep 23, 2005 - 10:05 AM
|
We appreciate your strong interest in Prof-UIS control bars but we would prefer to receive your project and debug it. The information in your message is not enough to suppose any source of the problem. We know the control bar positions are saved and restored correctly regardless of the monitor location. So, we really need something compilable and linkable. Additionally we must make a very important note about your application design. You wrote that you have some modeless dialog which is converted into resizable control bar and vice versa on the fly. If fact, this UI solution is already available in Prof-UIS. It is called dynamic resizable control bar (the CExtDynamicControlBar class). This is an advanced version of the CExtControlBar resizable control bar class. The dynamic bars have the Window Options button in the non client area which allows you to make the bar always floating only absolutely like your modeless dialog. Please take a look at the MDI_DynamicBars and SDI_DynamicBars sample applications and try to play with their dynamic bars. We also recommend you read the article about dynamic control bars.
|
|
Chris Thomas
|
Sep 26, 2005 - 3:18 PM
|
Ok I have a test app, I’ll email it to you. In the zip there is a readme.txt that details the issue, and I’ll include that readme.txt in the email body, just to make sure.
I’m hoping it is just somthing stupid that I am doing. Perhaps I am incorrectly assuming that a CExtControlBar instance with a child dialog always remain together as a pair, and the two live together regardless of floating, docked, or tabbed.
I understand your point about the application design. The problem I have is the app has a few modeless dialogs that appear at various times and stay for various lengths of time, created and maintained in parts of the app that are far away from CMainFrame::OnCreate(). I did look at the dynamic bars examples and I saw the Windows Options button. But does that do anything other than force floating instead of docking?
After reading the dynamic control bar article, I got the impression that these bars are still created in Mainframe::OnCreate(), and all of them have to exist at that point in time. Hey if you can get that test app to work with dynamic bars, I’d be happy with that.
We simply want to create a dialog, anywhere in the app, and tell mainframe to host it as a dockable entity. The user should be able to move and dock it anywhere, and terminate it by the X button or by some other UI that toggles it. That is all we want mainframe to do here.
Thanks!
|
|
Technical Support
|
Sep 27, 2005 - 5:48 AM
|
|
|
Chris Thomas
|
Sep 27, 2005 - 8:00 AM
|
Sorry, I sent it to support@profuis.com, without the "-". FYI that is what your link on your home page says. I’ll resend it right away.
|
|
Technical Support
|
Sep 27, 2005 - 11:56 AM
|
This message is both posted to the technical support forum and e-mailed to you. A modified version of your project is enclosed in the e-mail. First of all, we added the following line to the constructor of the CMainFrame class: CExtControlBar::g_bCloseOnlyOneBarInTabGroup = true; This tells the resizable control bar to close only the one bar when the "X" button on the tab group is pressed. This is essential for your destroyable bars.
Second, we recoded the CMainFrame::UnloadDockingWindow() window and it brings no problems now. The bForceNoOptimizeMode parameter of this method should be set to true when you invoke this method from CMainFrame::DestroyWindow() , i.e. when the frame enters its destruction sequence. So, the bar can be destroyed before saving states of other bars.
We noticed that two dynamic control bars have the static entries in the message map of the main frame window. It seems these control bars are not fully dynamic or it’s done just for testing.
We have also updated the source code for the CExtBarNcAreaButtonCloseIgnore::OnNcAreaClicked() method and added the message handler for the CExtControlBar::g_nMsgCreateTabbedBar registered windows message to the main frame window. This will make Prof-UIS bars using your CExtBarNcAreaButtonCloseIgnore class as the "X" button implementation in any resizable control bars.
Finally, the implementation of your bars requires Visual Studio .NET-like implementation of handling commands for each resizable control bar instead of classic MFC’s show/hide control bar commands which are not compatible with the auto-hidable resizable control bars. You should simply add the following methods to the CMainFrame class: void CMainFrame::OnUpdateControlBarMenu(CCmdUI* pCmdUI)
{
CExtControlBar::DoFrameBarCheckUpdate(
this,
pCmdUI,
false
);
}
BOOL CMainFrame::OnBarCheck(UINT nID)
{
return
CExtControlBar::DoFrameBarCheckCmd(
this,
nID,
false
);
} These methods will be used in the message map of the CMainFrame class instead of the methods with the same name defined in the CFrameWnd class. As for replacing the bars in your project with the dynamic control bars, it is not very difficult and will have the same visual result. But if your SDI application uses the CExtTabPageContainerWnd window (or derived from it) as the main view window, all the dynamic bars will be able to switch their states to the page windows inside tab page container.
|
|
Chris Thomas
|
Sep 27, 2005 - 12:59 PM
|
Thanks for such a quick response! Those fixes work great.
|
|
Krustys Donuts
|
Sep 22, 2005 - 1:38 PM
|
I downloaded 2.43 and built it without incident. The problem is that if I then try to rebuild again (or debug or whatever) the compiler thinks 2.43 is dirty so it keeps trying to rebuild even though there is nothing to do! What am I doing wrong?
|
|
Technical Support
|
Sep 23, 2005 - 5:54 AM
|
Our guess is that it may be caused by differences in the time zones or if you set a new time on your machine, which is less than the time of file modification.
|
|
Srinivasan Natarajan
|
Sep 22, 2005 - 4:00 AM
|
Hi, How to set alternate color for rows in CExtGridWnd rgs sundar
|
|
Technical Support
|
Sep 22, 2005 - 10:03 AM
|
To set the color of a row, just set the color for each cell in this row. Starting from Prof-UIS 2.42, BackColorSet() /BackColorGet() methods are available in the CExtGridCell class. These methods alow you to specify background colors for any grid cell in the normal, hovered and selected states.
|
|
Andrew Harding
|
Sep 19, 2005 - 11:10 AM
|
I’m trying to install Prof-UIS 2.4 but I can’t get past the Integration Wizard. I’m trying to build all configurations for MSVC 7.1. It will build exactly one library and then it will pop up this error message:
"Class view information will not be available for VC projects because the solution NCB file C:\Program Files (x86)\FOSS Software Inc\Prof-UIS\ProfUISDLL\profuisdll_710.ncb is read-only. If your solution directory is read-only or the solution path contains UNICODE characters, other features will also be affected."
From this time on, the window still reads "Executing..." and the animation continues to run, but nothing else happens. I let it run over the weekend and when I came back this morning, it was still stuck trying to build the second library configuration.
System information:
Windows XP X64 Edition with SP2 Athlon 64 X2 3800+ Dual Core Processor 2GB RAM
|
|
Andrew Harding
|
Sep 19, 2005 - 11:11 AM
|
For what it’s worth, running in single-processor mode (appending /onecpu to the line in the boot.ini file) doesn’t change anything.
|
|
Technical Support
|
Sep 19, 2005 - 12:02 PM
|
Please make sure that the Visual Studio IDE is closed before you starts the Integration Wizard. The NCB file contains information generated by the parser, which is used by Class View. If the file is accidentally or deliberately deleted, it is automatically built again. So, you can manually remove it. If the problem still persists, we recommend you to build the library manually, which is not difficult: 1) Open ProfUIS_710.sln in your VS; 2) Click Build | Batch Build... to start the Batch Buid dialog, unselect all, select the required configuration (e.g MBCS Debug) for the profuisdll project and compile the library 3) Now when you have library binaries, you can compile Prof-UIS samples or your project that uses Prof-UIS. But please note that before you start compiling a project, you need to set the required paths in VS settings. This is described in the article Getting Started with Prof-UIS. Please also note that you need to compile the ProfAuto project before compiling the ActiveScripts sample application. Do not hesitate to contact us if you encounter any problems (either in this forum or by e-mail). You can count on our help and assistance.
|
|
Michael Morrison
|
Sep 16, 2005 - 9:34 AM
|
I would like to turn the "Hide" [X] button in my CExtControlBars/CExtDynamicControlBars into a real "Close" button. There have been several previous discussions on this in this forum, and I want to verify that the following steps are what is required to do this: 1) Derive a class from <!--StartFragment -->CExtBarNcAreaButtonClose to override the OnNcAreaClicked method. 2) Derive a class from CExtControlBar to override the OnNcAreaButtonsReinitialize method. Insert my derived "Close" class instead of CExtBarNcAreaButtonClose. 3) Possibly override the OnDbsCreateTabbedBarInstance in my main frame in order to return one of my derived classes instead of the control bar class it returns: CExtDynamicTabbedControlBar *
CMainFrame::OnDbsCreateTabbedBarInstance() const
{
ASSERT( this != NULL );
CExtDynamicTabbedControlBar * pBar =
new C_YOUR_DynamicTabbedControlBar;
return pBar;
} 4) Add this method to my main frame class: <!--StartFragment --> #include "AfxPriv.h"
#include "../Src/ExtDockBar.h"
#include "../Src/ExtControlBarTabbedFeatures.h"
. . .
void CMainFrame::_RemovePanel(
CExtControlBar * pBar
)
{
CMiniDockFrameWnd * pMiniFrame = NULL;
if( pBar->IsFloating() )
{
pMiniFrame =
DYNAMIC_DOWNCAST(
CMiniDockFrameWnd,
pBar->GetDockingFrame()
);
ASSERT_VALID( pMiniFrame );
}
else
{
ASSERT( ! pBar->m_pDockBar->m_bFloating );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( pBar->AutoHideModeGet() )
{
ASSERT_KINDOF(
CExtDockBar,
pBar->m_pDockBar
);
CExtDynAutoHideArea * pWndAutoHideArea =
((CExtDockBar*)pBar->m_pDockBar)->
_GetAutoHideArea();
ASSERT_VALID( pWndAutoHideArea );
CExtDynAutoHideSlider * pWndSlider =
pWndAutoHideArea->GetAutoHideSlider();
ASSERT_VALID( pWndSlider );
if( (pWndSlider->GetStyle()&WS_VISIBLE) != 0 )
pWndSlider->SendMessage( WM_CANCELMODE );
pWndAutoHideArea->
RemoveControlBar( pBar, true );
}
#endif
if( pBar->m_pDockBar->
IsKindOf(
RUNTIME_CLASS( CExtDockBar )
)
)
{
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
if( pBar->m_pDockBar->
IsKindOf(
RUNTIME_CLASS(
CExtDockDynTabBar
)
)
)
{
CExtDynTabControlBar * pDynTabbedBar =
STATIC_DOWNCAST(
CExtDynTabControlBar,
pBar->m_pDockBar->GetParent()
);
LONG nIdx =
pDynTabbedBar->FindControlBar( pBar );
if( nIdx >= 0 )
{
LONG nSel =
pDynTabbedBar->
GetSwitcherSelection();
if( nIdx != nSel )
pDynTabbedBar->
SetSwitcherSelection( nIdx );
pDynTabbedBar->RemoveSelFromSwitcher();
if( pDynTabbedBar->
GetSwitcherItemCount() > 0
)
pDynTabbedBar->
SetSwitcherSelection(0);
pDynTabbedBar->
OnNcAreaButtonsReinitialize();
}
}
#endif
VERIFY(
((CExtDockBar *)pBar->m_pDockBar)->
RemoveControlBar( pBar, -1, 0, false )
);
}
else
{
VERIFY(
pBar->m_pDockBar->RemoveControlBar(pBar)
);
}
} // else from if( pBar->IsFloating() )
RemoveControlBar( pBar );
pBar->m_pDockSite = NULL;
pBar->m_pDockBar = NULL;
if( pMiniFrame != NULL )
pMiniFrame->DestroyWindow();
else
pBar->DestroyWindow();
CExtDockBar::_OptimizeCircles( this);
RecalcLayout();
} 5) Inside my CExtBarNcAreaButtonClose::OnButtonClose method, if CExtBarNcAreaButtonClose::OnButtonClose() returns true, call CMainFrame::_RemoveBar() on the button’s parent. This seems like a lot of work, is there an easier way? Thanks.
|
|
Michael Morrison
|
Sep 19, 2005 - 12:02 PM
|
Thanks for the clarifications.
Since we use both CExtDynamicControlBars and CExtControlBars, can I call CExtDynamicBarSite::BarFree() on my CExtControlBar (not CExtDynamicControlBar) - derived class? Should I use CExtDynamicBarNcAreaButtonClose in my CExtControlBar-derived classes too?
Also, what exactly should happen inside my XXX::OnButtonClose() method? Can I just call CExtDynamicBarSite::BarFree() on the button’s parent and everything will work out correctly (ie: window is closed and removed from popup menus, MFC stuff like DestroyWindow is called on child window, etc)? Can you post what the "right way" to handle this is?
Would it be possible to add a method to the CExt(Dynamic)ControlBar class to set whether the [X] button is Hide or Close? It seems this would simplify things and not require so much subclassing. Just a thought.
Thanks.
|
|
Technical Support
|
Sep 20, 2005 - 7:58 AM
|
The CExtDynamicBarSite is the management system for dynamic resizable control bars (the CExtDynamicControlBar class). So, if you decide to use dynamic bars, then we recommend you forget about the CExtControlBar class and follow our recommendations described the previous answer. By default, the X button simply hides the bar. But, as we said, you can make it destroy the bar. The dynamic bars must be destroyed by invoking the CExtDynamicBarSite::BarFree() method. Besides, we must note that after destroying a bar, its location information is lost. So, you should carefully think about whether you really need to destroy your dynamic bars or just to hide them.
|
|
Technical Support
|
Sep 19, 2005 - 3:13 AM
|
Here are some comments about the steps you provided:
1) The CExtControlBar class uses CExtBarNcAreaButtonClose as its X button implementation. The CExtDynamicControlBar class uses the CExtDynamicBarNcAreaButtonClose class instead. We recommend you use CExtDynamicBarNcAreaButtonClose as a base class for implementing your X button. 2) CExtControlBar is a simple resizable control bar which exists persistently as long as its frame window does and does not relate to the subsystem that manages dynamic control bars. So, create the CExtDynamicControlBar -derived class, override the OnNcAreaButtonsReinitialize() method in it and instantiate the CExtDynamicBarNcAreaButtonClose -derived object. Please note that the implementation of your dynamic control bar must include DECLARE_SERIAL / IMPLEMENT_SERIAL MFC features absolutely like in the CExtDynamicControlBar class. 3) Suppose your tabbed bar container is correct. Please ensure it is derived from the CExtDynamicTabbedControlBar class (not from CExtDynTabControlBar ) and its OnNcAreaButtonsReinitialize() virtual method creates only CExtDynamicBarNcArea*** -derived classes as caption buttons. 4) Looks correct but the CExtDynamicBarSite::BarFree() method in the Prof-UIS 2.40 performs the same work. 5) As we said above, CExtDynamicBarSite::BarFree() is better and allow you avoid dependencies on Prof-UIS versions.
Finally, we are very impressed and appreciate your interest in dynamic control bars. Please do not hesitate to contact us if you encounter any difficulties. Of course, we could code a simplier API for resizable control bars, but the current API would have lost its flexibility and extensibility.
|
|
Maxim Tebenev
|
Sep 15, 2005 - 11:53 PM
|
Greetings! Is there way to display shell context menu with Office-like menus (CExtPopupMenuWnd)? Although I’ve added shell menu items to popup menu without problems, I was unable to handle messages using IContextMenu2 and IContextMenu3 interfaces. Their HandleMenuMsg(...) methods return E_FAIL. This causes problems with displaying ’Send To’ sub-menus and owner-drawn menus as well. Similar application with simple Win32 menus are working well. Any suggestions? Best regards, Maxim Tebenev. TrieTech(http://www.trietech.com)
|
|
Technical Support
|
Sep 16, 2005 - 8:32 AM
|
Could you let us take a look at your code for creating and tracking shell context menu? We will try to help you.
|
|
Eli Kaczer
|
Sep 15, 2005 - 12:53 PM
|
In the property grid sample application, one can specify on a dialog a custom control with class name: ’ProfUIS-PropertyGridCtrl’. I could not find an equivalent way to do this for CExtGridWnd. I would appreciate any help regarding this issue. Thanks, Eli
|
|
Technical Support
|
Sep 16, 2005 - 4:56 AM
|
Here is part of the Prof-UIS class hierarchy: CExtPropertyGridWnd->CExtTreeGridWnd-> CExtGridWnd->CExtGridBaseWnd-> CExtScrollItemWnd->CExtScrollWnd As you can see CExtGridWnd is kind of the CExtScrollItemWnd class that implements a control which has table-like scrollable items. The CExtScrollItemWnd class can be inserted into dialog forms as a custom control. You should use ProfUIS-ScrollItemWindow as the window class name of the custom control and subclass it with the CExtGridWnd object. If you encounter any difficulties, just contact us by e-mail: we will code and send you a simple dialog-based project with a CExtGridWnd control placed on the main dialog form.
|
|
Ernest Peters
|
Sep 14, 2005 - 10:06 PM
|
Hi, I am trying to place a button in a status bar. the status bar belongs to a CExtResizableDialog dialog with only a grid on it. The button is on the context menu of the grid ctrl (and that part works fine), just the button on the status bar is ALWAYS disabled.
I have tried all manual methods of enabling it (SetPaneStyle, EnableWindow etc). each enabling the control for an instant, then it gets disabled again.
Apart from the fact the control is in the context menu, my code is a direct replication of that in your examples StatusPanes-nd.exe and ProfUIS_Controls-nd.exe
BEGIN_MESSAGE_MAP(CGridLogDlg, CBaseGridDlg) ON_WM_LBUTTONDOWN() ON_WM_CONTEXTMENU() ON_COMMAND_RANGE(IDS_LOGLIST_NAME_0, IDS_LOGLIST_NAME_255, OnShowNewList) ON_COMMAND(ID_ECULOGGING_VIEWLOGLISTS, OnShowLogLists) ON_WM_TIMER() ON_BN_CLICKED(ID_LOGWINDOW_STARTSTOP, OnLogwindowStartStop) ON_UPDATE_COMMAND_UI(ID_LOGWINDOW_STARTSTOP, OnUpdateLogwindowStartStop) END_MESSAGE_MAP()
BOOL CGridLogDlg::OnInitDialog() { __super::OnInitDialog();
static UINT indicators[] = { ID_SEPARATOR, // status line indicator };
// setup the status bar and anchor it to the window if ((false == this->m_StatusBar.Create(this)) || (false == this->m_StatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)))) { // TODO: log something..is this the end of the world for this dialog? } else { this->m_StatusBar.GetStatusBarCtrl().SetMinHeight(20); this->m_StatusBar.SetPaneWidth(0, 150); CWnd::RepositionBars(0,0xFFFF,0); this->AddAnchor(this->m_StatusBar.m_hWnd, __RDA_LT, __RDA_LB); }
if (false == this->m_StartStopLogging_btn.Create(_T("Start"), WS_CHILD|WS_VISIBLE|WS_TABSTOP, CRect(0,0,0,0), &this->m_StatusBar, ID_LOGWINDOW_STARTSTOP)) { // TODO: log something..is this the end of the world for this dialog and its ability to log? } else { this->m_StartStopLogging_btn.SetFlat(); this->m_StartStopLogging_btn.SetDrawBorder(true); bool bRet = this->m_StatusBar.AddPane(IDS_PANE_BUTTON, 1); if(!bRet) { AfxMessageBox(_T("Pane index out of range\nor pane with same ID already exists in the status bar"), MB_ICONERROR); return (false); } int nIndex = this->m_StatusBar.CommandToIndex(IDS_PANE_BUTTON); if (nIndex == -1) { return (false); }
this->m_StatusBar.SetPaneWidth(nIndex, 50); this->m_StatusBar.SetPaneControl(this->m_StartStopLogging_btn, IDS_PANE_BUTTON, true);
this->m_StatusBar.EnableControl(nIndex); } if (!m_LoggingRate_edit.Create(WS_CHILD|WS_VISIBLE|WS_TABSTOP, CRect(0,0,0,0), &m_StatusBar, 0)) { TRACE(_T("Failed to create edit control.\n")); return (false); } else { m_LoggingRate_edit.SetFont(CFont::FromHandle((HFONT)::GetStockObject(DEFAULT_GUI_FONT))); m_LoggingRate_edit.SetWindowText(_T("Type text here...")); bool bRet = m_StatusBar.AddPane(IDS_PANE_EDIT, 2); if(!bRet) { AfxMessageBox(_T("Pane index out of range\nor pane with same ID already exists in the status bar"), MB_ICONERROR); return (false); } int nIndex = m_StatusBar.CommandToIndex(IDS_PANE_EDIT); if (nIndex == -1) { return (false); } m_StatusBar.SetPaneWidth(nIndex, 100); m_StatusBar.SetPaneControl(m_LoggingRate_edit, IDS_PANE_EDIT, true); }
// Fixed Columns and rows this->m_Grid.OuterRowCountTopSet(2L, false); this->m_Grid.OuterColumnCountLeftSet(1L, false); this->m_Grid.OuterColumnWidthSet(true, 0L, 60);
// show the log list this->ShowLogListItems();
return (true); // return TRUE unless you set the focus to a control }
void CGridLogDlg::OnLogwindowStartStop() { AfxMessageBox("About to log"); }
// TODO: If we were to restrict users being able to log..this would be the place void CGridLogDlg::OnUpdateLogwindowStartStop(CCmdUI *pCmdUI) { pCmdUI->Enable();
this->m_StartStopLogging_btn.EnableWindow(); }
|
|
Technical Support
|
Sep 20, 2005 - 8:27 AM
|
Your source code looks OK, but you should not use the anchor mechanism for the status bar window. Just use the CWnd::RepositionBars( 0, 0xFFFF,0 ) API instead. The button in the status pane should be enabled without any conditions. So, we may guess the problem hides somewhere outside the source code snippet porvided in your message. To clear the issue, we coded a very simple dialog-based application. Please take a look at it and compare it with your real project. Of course, you can send us your project so we can fix it. Alternatively, we can connect to your desktop remotely and find out what’s wrong.
|
|
Ernest Peters
|
Sep 22, 2005 - 3:31 AM
|
Hi, your example works (obviously :)). The problem i am having is that the button i am inserting is part of a context menu as well. maybe send me a sample that has a context menu that is creatd both at run time and one with a dialog that creates the context menu from a resource.
with regards to the anchoring, i have to anchor it , as the reposition leaves it in the centre of the screen. and if i dont call reposition the status doesnt even get drawn. thanks again ernest.
|
|
Technical Support
|
Sep 22, 2005 - 10:27 AM
|
It’s not completely clear what you need to implement in the status bar with reagard to the button. Are you talking about the drop-down button, which fires a pop-up menu when clicking its right part?
|
|
Ernest Peters
|
Sep 26, 2005 - 7:27 PM
|
No, you are misunderstanding me. What i have is a button in the main menu called ’Start’ (to start a comms logging session with id ID_LOGWINDOW_START). In the context menu for the grid i have the same button ’Start’ also using id ID_LOGWINDOW_START. I also want the ’Start’ button in the status bar (using id ID_LOGWINDOW_START).
Basically, i need to locate the same functionality for ’Start’ in three different places all updated with ON_UPDATE_COMMAND_UI.
|
|
Technical Support
|
Sep 28, 2005 - 7:29 AM
|
Please take a look at the StatusPanes sample in which you can find how to insert a button to the status bar pane and implement the ON_UPDATE_COMMAND_UI handler.
|
|
Krustys Donuts
|
Sep 14, 2005 - 7:31 PM
|
If I handle changes to the gridcell value by handling OnPgcInputComplete and pop up a MessageBox from the handler, in some cases the application will crash. Specifically, accepting changes by pressing the Enter key does not result in a crash, but clicking on another grid cell does crash.
Any ideas?
|
|
Technical Support
|
Sep 16, 2005 - 5:09 AM
|
We fixed this problem. The property grid is now safe for displaying the modal dialog when the grid cell’s in-place editor is active. Please contact us by e-mail if you need this update immediately.
|
|
Krustys Donuts
|
Sep 12, 2005 - 10:51 PM
|
I used your example to put a custom caption into a tab managed by a CExtTabMdiWnd. What’s the best way to dynamically change that caption later? If I use SetTitle() and/or SetWindowText(), the text doesn’t change until I move the mouse over the tab. And it won’t resize in any case (if the new caption is longer than the old caption). What do you suggest?
Thanks.
|
|
Krustys Donuts
|
Sep 12, 2005 - 11:45 PM
|
Never mind... RecalcLayout(). Duh.
|
|
Technical Support
|
Sep 13, 2005 - 4:01 AM
|
You should invoke the CExtTabWnd::UpdateTabWnd() in this case.
|
|
Mel Sampat
|
Sep 9, 2005 - 3:30 PM
|
Is there a way to automatically save the size/positions of a resizable CExtResizableDialog’s and restore the same size the next time it is shown (modal)?
|
|
Technical Support
|
Sep 10, 2005 - 11:44 AM
|
Yes, resizable dialog feratures saving/restoring its position. The main dialog in the ProfUIS_Controls sample application demonstrates this feature. Your dialog will automatically save/restore it positions, if you enable this feature by invoking the EnableSaveRestore() method in the OnInitDialog() method of your dialog class.
|
|
Krustys Donuts
|
Sep 8, 2005 - 4:36 PM
|
Currently, property stores are nice because they give you the combining functionality that allows a user to set a property of multiple objects simultaneously. However, is there a way to specify that a particular value should NOT be combined, and thus not appear in the property grid control when grouped?
|
|
Technical Support
|
Sep 9, 2005 - 12:14 PM
|
We think there is no compelling reason to make particular values partially combined or uncombined at all. If the copies of these values inside several property stores are always equal to each other, they look like non-combined. This special case can be implemented outside the property grid control.
|
|
Krustys Donuts
|
Sep 8, 2005 - 10:01 AM
|
Hi, in the past, you’ve instructed me to use the __EGCS_NO_INPLACE_CONTROL style to make my CExtGridCellComboBox subclasses act like a droplist control. Overall, it does function like a droplist, *however*, one of the nicest things about a true droplist is that you can make the list appear by clicking on the cell itself, instead of the "down arrow" button. Can you tell me how to modify the behavior of this class to act like this, or is it impossible because the NO_INPLACE_CONTROL style throws out mouse clicks in the cell’s editable area?
|
|
Technical Support
|
Sep 8, 2005 - 11:01 AM
|
Create a CExtGridCell -derived class and override the CExtGridCell::OnClick() virtual method in this way: bool CExtGridCell::OnClick(
CExtGridWnd & wndGrid,
const CExtGridHitTestInfo & htInfo,
UINT nChar,
UINT nRepCnt,
UINT nFlags
)
{
ASSERT_VALID( this );
if( nChar == VK_LBUTTON && ( nRepCnt == 1 || nRepCnt == 2 ) )
{
if( (nFlags&(MK_SHIFT|MK_CONTROL)) == 0 )
{
CExtGridHitTestInfo htInfoTrack( htInfo );
htInfo.m_dwAreaFlags |= __EGBWA_CELL_BUTTON;
htInfoTrack.m_nButtonType = (int)__EBTT_DROPDOWN;
return
wndGrid.OnGridTrackCellButton(
this,
htInfoTrack
);
}
}
return
CExtGridCell::OnClick(
wndGrid,
htInfo,
nChar,
nRepCnt,
nFlags
);
} That should implement the behavior that is expected.
|
|
Krustys Donuts
|
Sep 8, 2005 - 2:32 PM
|
Doesn’t work -- seems that OnClick is not a virtual method in the CExtGridCellComboBox class. It is for CExtGridCell and CExtGridCellHyperlink... but the combobox isn’t derived in any way from either of those two classes.
|
|
Technical Support
|
Sep 9, 2005 - 7:11 AM
|
Here is a ready-to-use CExtGridCellDropDownComboBox class:
CLASS DECLARATION: /////////////////////////////////////////////////////////////////////////////
// CExtGridCellDropDownComboBox
class CExtGridCellDropDownComboBox : public CExtGridCellComboBox
{
public:
DECLARE_SERIAL( CExtGridCellDropDownComboBox );
IMPLEMENT_ExtGridCell_Clone( CExtGridCellDropDownComboBox, CExtGridCellComboBox );
CExtGridCellDropDownComboBox(
CExtGridDataProvider * pDataProvider = NULL
);
virtual bool OnClick(
CExtGridWnd & wndGrid,
const CExtGridHitTestInfo & htInfo,
UINT nChar,
UINT nRepCnt,
UINT nFlags
);
}; // class CExtGridCellDropDownComboBox CLASS IMPLEMENTATION:IMPLEMENT_SERIAL( CExtGridCellDropDownComboBox, CExtGridCellComboBox, VERSIONABLE_SCHEMA|1 );
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CExtGridCellDropDownComboBox
CExtGridCellDropDownComboBox::CExtGridCellDropDownComboBox(
CExtGridDataProvider * pDataProvider // = NULL
)
: CExtGridCellComboBox( pDataProvider )
{
}
bool CExtGridCellDropDownComboBox::OnClick(
CExtGridWnd & wndGrid,
const CExtGridHitTestInfo & htInfo,
UINT nChar,
UINT nRepCnt,
UINT nFlags
)
{
ASSERT_VALID( this );
ASSERT_VALID( (&wndGrid) );
ASSERT( ! htInfo.IsHoverEmpty() );
ASSERT( htInfo.IsValidRect() );
ASSERT( nChar == VK_LBUTTON || nChar == VK_RBUTTON || nChar == VK_MBUTTON );
ASSERT( 0 <= nRepCnt && nRepCnt <= 3 );
if( nChar == VK_LBUTTON && ( nRepCnt == 1 || nRepCnt == 2 ) )
{
if( (nFlags&(MK_SHIFT|MK_CONTROL)) == 0 )
{
CExtGridHitTestInfo htInfoTrack( htInfo );
htInfoTrack.m_dwAreaFlags |= __EGBWA_CELL_BUTTON;
htInfoTrack.m_nButtonType = (int)__EBTT_DROPDOWN;
return
wndGrid.OnGridTrackCellButton(
this,
htInfoTrack
);
}
}
return
CExtGridCellComboBox::OnClick(
wndGrid,
htInfo,
nChar,
nRepCnt,
nFlags
);
}
|
|
Krustys Donuts
|
Sep 6, 2005 - 5:21 PM
|
I have subclassed CExtGridCellString and now have my own class that has the __EBCS_BUTTON_ELLIPSIS style bit set. I’ve also overridden the OnButtonPressed method.
My problem now is that when I click on the button, the object whose OnButtonPressed method gets called is actually different than the one that I had initially created!
My creation code basically looks like this:
pValue = new CExtPropertyValue( property.name.c_str());
pData = STATIC_DOWNCAST( LabwareEllipsisCell, pValue->ValueActiveGetByRTC( RUNTIME_CLASS(LabwareEllipsisCell)));
// just a test
EllipsisCell* pEllipsisCell = dynamic_cast<LabwareEllipsisCell*>(pData);
if( pEllipsisCell)
pEllipsisCell->setDonut( donut);
The program crashes when the OnButtonPressed method executes, because the donut variable is invalid (null). This is because the EllipsisCell object is actually different than the one created in the code above! Can you please explain why this is the case? The only reason why I have the setDonut() method is because there doesn’t seem to be a way to pass extra arguments to the EllipsisCell constructor when using the MFC macros. Am I wrong? Can you propose an alternate solution?
Thank you!
|
|
Technical Support
|
Sep 7, 2005 - 5:16 AM
|
It seems you forgot to insert the line below into the declaration of your LabwareEllipsisCell class: IMPLEMENT_ExtGridCell_Clone( LabwareEllipsisCell, CExtGridCellString );
|
|
Krustys Donuts
|
Sep 7, 2005 - 6:42 AM
|
Hi, actually I do have it in the declaration of my EllipsisCell class, I just didn’t paste the declaration of the class into the code above...
|
|
Krustys Donuts
|
Sep 7, 2005 - 11:27 AM
|
The problem was that I didn’t implement Assign. I’m not an old-school MFC programmer, so it had never occurred to me in the first place that I’d have to write the Assign code for the cell objects that get dynamically created.
|
|
Technical Support
|
Sep 7, 2005 - 12:44 PM
|
The Assign() method should certainly assign data members like numeric or string values. You should put pointers to interfaces like IDonut* in your CExtPropertyValue classes which are outside the property grid window. The CExtPropertyValue::Apply() virtual method is invoked when the property grid’s cell is changed so you can invoke IDonut ’s methods. You can see how the property value classes keep properties for star buttons in the PropertyGrid sample application, which is similar to your design.
|
|
Krustys Donuts
|
Sep 7, 2005 - 3:59 PM
|
I have another somewhat related question. When I combine stores, values like checkboxes, strings, and numbers seem to change correctly.
For example, I have two stores with a checkbox cell named "has sprinkles" (defaults to unchecked). If I then select both stores (which internally calls Combine ) and check the checkbox, once I select each store individually, the checkbox is still checked. This is perfect.
However, I also have a grid cell that, when checked, pops up a dialog box that allows me to modify properties of a particular member of the grid cell. If I select both stores again and then modify the properties of that object, it only does so for one of them, not both. I would expect this because there isn’t a way for Prof-UIS to know to update the parameters of the other object. So I was just wondering if there’s some mechanism in Prof-UIS to allow this to happen. Sorry if this example is confusing...
|
|
Technical Support
|
Sep 8, 2005 - 10:57 AM
|
Thank you for the good comment. The CExtGridCell paints its check box in the CExtGridCell::OnPaintCheck() method. It supports the indeterminate check box state with the __EGCS_CHK_INDETERMINATE cell style. But property store’s mixing algorithm does not use this style at all. It uses a more universal __EGCS_EX_UNDEFINED_ROLE extended cell style which affects not only the check box but also blank cells for text and other cells, "?" character rendering in the icon area of the color cell and etc. Please use this style for detecting object property differences. Besides, we have improved the CExtGridCell::OnPaintCheck() method in the ExtGridWnd.cpp file and now it paints the indeterminate check box if the __EGCS_EX_UNDEFINED_ROLE extended cell style is applied: void CExtGridCell::OnPaintCheck(
const RECT & rcCheck,
const CExtGridWnd & wndGrid,
CDC & dc,
LONG nVisibleColNo,
LONG nVisibleRowNo,
LONG nColNo,
LONG nRowNo,
INT nColType,
INT nRowType,
const RECT & rcCellExtra,
const RECT & rcCell,
const RECT & rcVisibleRange,
DWORD dwAreaFlags,
DWORD dwHelperPaintFlags
) const
{
ASSERT_VALID( this );
ASSERT_VALID( (&wndGrid) );
ASSERT( dc.GetSafeHdc() != NULL );
if( ! dc.RectVisible(&rcCheck) )
return;
rcCellExtra;
rcCell;
rcVisibleRange;
DWORD dwCellStyle = GetStyle();
if( (dwCellStyle&__EGCS_CHK_MASK) == __EGCS_CHK_NONE )
return;
bool bReadOnly =
( (dwCellStyle&__EGCS_READ_ONLY) != 0 )
? true : false;
CSize szCheck =
OnCalcCheckSize(
wndGrid,
dc,
nVisibleColNo,
nVisibleRowNo,
nColNo,
nRowNo,
nColType,
nRowType,
dwAreaFlags,
dwHelperPaintFlags
);
ASSERT( szCheck.cx >= 0 && szCheck.cy >= 0 );
DWORD dwCellStyleEx = GetStyleEx();
DWORD dwStylePart = dwCellStyle & __EGCS_CHK_MASK;
bool bIndeterminate =
( (dwCellStyle&__EGCS_CHK_MASK) ==
__EGCS_CHK_INDETERMINATE )
? true : false;
bool bChecked =
( (dwCellStyle&__EGCS_CHECKED) != 0 )
? true : false;
if( (dwCellStyleEx&__EGCS_EX_UNDEFINED_ROLE) != 0 )
{
dwStylePart = __EGCS_CHK_INDETERMINATE;
bIndeterminate = true;
bChecked = true;
}
bool bDefaultDrawing = true;
if( g_PaintManager.m_UxTheme.IsControlsThemed()
&& g_PaintManager.m_UxTheme.OpenThemeData(
wndGrid.GetSafeHwnd(),
L"BUTTON"
) != NULL
)
{
INT nState = 0;
INT nPartID = 0;
switch( dwStylePart )
{
case __EGCS_CHK_CHECK:
case __EGCS_CHK_INDETERMINATE:
{
nPartID = BP_CHECKBOX;
if( bChecked )
{
nState =
bReadOnly
? ( bIndeterminate
? CBS_MIXEDDISABLED
: CBS_CHECKEDDISABLED
)
: ( bIndeterminate
? CBS_MIXEDNORMAL
: CBS_CHECKEDNORMAL
);
}
else
{
nState =
bReadOnly
? CBS_UNCHECKEDDISABLED
: CBS_UNCHECKEDNORMAL;
}
}
break;
case __EGCS_CHK_RADIO:
{
nPartID = BP_RADIOBUTTON;
if( bChecked )
{
nState =
bReadOnly
? RBS_CHECKEDDISABLED
: RBS_CHECKEDNORMAL;
}
else
{
nState =
bReadOnly
? RBS_UNCHECKEDDISABLED
: RBS_UNCHECKEDNORMAL;
}
}
break;
default:
ASSERT( FALSE );
return;
} // switch( dwStylePart )
CRect rcPaint( rcCheck );
rcPaint.SetRect(
rcPaint.left,
rcPaint.top,
rcPaint.left + szCheck.cx,
rcPaint.top + szCheck.cy
);
if( g_PaintManager.m_UxTheme.
DrawThemeBackground(
dc.GetSafeHdc(),
nPartID,
nState,
&rcPaint,
&rcCell
) == S_OK
)
bDefaultDrawing = false;
g_PaintManager.m_UxTheme.
CloseThemeData( true );
}
if( bDefaultDrawing )
{
UINT nState = DFCS_FLAT;
switch( dwStylePart )
{
case __EGCS_CHK_CHECK:
nState |= DFCS_BUTTONCHECK;
break;
case __EGCS_CHK_RADIO:
nState |= DFCS_BUTTONRADIO;
break;
case __EGCS_CHK_INDETERMINATE:
nState |=
DFCS_BUTTONCHECK
|DFCS_BUTTON3STATE
;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
}; // switch( dwStylePart )
if( bChecked )
nState |= DFCS_CHECKED;
if( bReadOnly )
nState |= DFCS_INACTIVE;
CRect rcPaint( rcCheck );
rcPaint.SetRect(
rcPaint.left,
rcPaint.top,
rcPaint.left + szCheck.cx,
rcPaint.top + szCheck.cy
);
dc.DrawFrameControl(
(RECT *)&rcPaint,
DFC_BUTTON,
nState
);
} // if( bDefaultDrawing )
}
|
|
Krustys Donuts
|
Sep 7, 2005 - 3:46 PM
|
Could you please explain why you recommend that interface pointers be stored in the CExtPropertyValue object? Currently, we just use Assign to copy the pointer to the cell copy, and it seems to work okay at the moment.
|
|
Technical Support
|
Sep 8, 2005 - 9:39 AM
|
In fact, you can keep interface pointers in grid cells and this design will always work OK in property grid windows. But generally, the CExtGridCell class is designed to be a cloneable and serializable object for keeping only data values. The grid cell serialization can be used for copy, paste and drag-and-drop between processes.
|
|
Krustys Donuts
|
Sep 6, 2005 - 6:55 PM
|
I have a little more information from my recent debugging session. It seems that the problem stems from my calling PropertyStoreSynchronize(). I call this method every time someone clicks on a tree control. However, when PropertyStoreSychronize is invoked, it ends up creating another instance of the grid cell. I’m not sure why it would do this, as I have already explicitly created the cell (please see previous post).
The call stack when the user clicks on a tree item looks like this:
krusty.dll!EllipsisCell::EllipsisCell(CExtGridDataProvider * pDataProvider=0x00000000) Line 16 C++
krusty.dll!EllipsisCell::CreateObject() Line 13 + 0x6a C++
mfc71d.dll!CRuntimeClass::CreateObject() Line 137 + 0x6 C++
ProfUIS242md.dll!CExtGridCell::InstanceCreate(CRuntimeClass * pRTC=0x01128a00, IMalloc * pMalloc=0x01f95510, bool bThrowException=false) Line 13505 + 0x8 C++
ProfUIS242md.dll!CExtGridDataProviderMemory::CellGet(unsigned long nColNo=2, unsigned long nRowNo=3, CRuntimeClass * pInitRTC=0x01128a00, bool bAutoFindValue=true, bool bUseColumnDefaultValue=true) Line 30983 + 0x12 C++
ProfUIS242md.dll!CExtTreeGridDataProvider::ExtractGridCell(CExtTreeGridCellNode * pNode=0x01f959b0, unsigned long nColNo=2, CRuntimeClass * pInitRTC=0x01128a00, bool bAutoFindValue=true, bool bUseColumnDefaultValue=true) Line 1319 + 0x21 C++
ProfUIS242md.dll!CExtTreeGridWnd::ItemGetCell(_TREEITEM * hTreeItem=0x01f959b0, long nColNo=1, int nColType=0, CRuntimeClass * pInitRTC=0x01128a00, bool bAutoFindValue=true, bool bUseColumnDefaultValue=true) Line 1813 + 0x38 C++
ProfUIS242md.dll!CExtPropertyGridWnd::PropertyItemInsert(CExtPropertyItem * pPropertyItem=0x01fb4d78, long nIndex=-1, _TREEITEM * htiParent=0x01f9594c, bool bRedraw=false) Line 3477 + 0x18 C++
ProfUIS242md.dll!CExtPropertyGridWnd::PropertyStoreSynchronizeOneLevel(CExtPropertyItem * pPropertyItem=0x01fb4d78, CExtPropertyItem * pParentItem=0x01f8dc40) Line 3390 + 0x1c C++
ProfUIS242md.dll!CExtPropertyGridWnd::PropertyStoreSynchronizeOneLevel(CExtPropertyItem * pPropertyItem=0x01f8dc40, CExtPropertyItem * pParentItem=0x01f92ff0) Line 3406 + 0x18 C++
ProfUIS242md.dll!CExtPropertyGridWnd::PropertyStoreSynchronizeOneLevel(CExtPropertyItem * pPropertyItem=0x01f92ff0, CExtPropertyItem * pParentItem=0x00000000) Line 3406 + 0x18 C++
ProfUIS242md.dll!CExtPropertyGridWnd::PropertyStoreSynchronizeAll() Line 3314 + 0x16 C++
ProfUIS242md.dll!CExtPropertyGridCtrl::PropertyStoreSynchronize() Line 5632 + 0x10 C++
krusty.dll!CDlgTree::OnClickTree(tagNMHDR * pNMHDR=0x0012f6a8, long * pResult=0x0012f09c) Line 147 + 0x24 C++
|
|
Technical Support
|
Sep 7, 2005 - 5:21 AM
|
Please ensure that the IMPLEMENT_ExtGridCell_Clone macro is used in the declaration of your grid cell class. This macro is required for the grid data provider object that creates your cell type in its internal memory storage using a custom C++ new operator with the IMalloc parameter.
|
|
Krustys Donuts
|
Sep 7, 2005 - 6:47 AM
|
Hi, here’s my declaration:
class EllipsisCell : public CExtGridCellString
{
DECLARE_DYNCREATE(EllipsisCell)
IMPLEMENT_ExtGridCell_Clone( EllipsisCell, CExtGridCellString)
IDonut* pDonut;
public:
EllipsisCell( CExtGridDataProvider * pDataProvider=0);
virtual ~EllipsisCell();
virtual void OnButtonPressed( CExtGridWnd& wndGrid, INT nButtonType, const RECT& rcCellExtra, const RECT& rcCell,
LONG nVisibleColNo, LONG nVisibleRowNo, LONG nColNo, LONG nRowNo, INT nColType, INT nRowType);
void setDonut( IDonut& donut);
};
I don’t ever make use of pDataProvider, but that should be okay, as I’m not using external data, like a database... right?
|
|
Technical Support
|
Sep 13, 2005 - 7:37 AM
|
This cell class should work without problems in the property grid control.
|
|
Simon DESEE
|
Sep 4, 2005 - 5:44 AM
|
Hello all, I need to insert a CExtGridWnd on a CView with splitters. How can I do this please ? Thanks.
|
|
Technical Support
|
Sep 4, 2005 - 11:23 AM
|
Just create an instance of CExtGridWnd inside the splitter window. Please note that the dialog control identifier value of the grid window depends on the grid location in the splitter window. You should invoke the CSplitterWnd::IdFromRowCol() method to the the dialog control identifier for the window inserted into splitter. Of course, we can provide you with a start-up sample application if you let us know all the details about it.
|
|
Simon DESEE
|
Sep 26, 2005 - 2:28 AM
|
Hello, I want that the user can edit CExtGridWnd numeric data and show at the bottom different calculates value (depends of the number written in the grid). The grid will have one column with ComboBox and antoher with checkbox (I use your SimpleGrid sample). At the left, I place a CExtResizableDialog (like CProfStudioHelpIndexView of the ProfStudio sample). Regards,
|
|
Technical Support
|
Sep 26, 2005 - 9:57 AM
|
We coded a sample application which implements the features you requested. This is a simple SDI application with a grid view window. The grid consists of two columns with check box cells and combo box cells. There is also a total bottom line, in which we sum all values of checked rows.
|
|
Mel Sampat
|
Sep 3, 2005 - 12:12 PM
|
Is there a way for buttons to remain "3D" and not completely flat when using the Office 2003 skin? I want to use the CExtResizablePropertySheet but I don’t want the OK, Cancel and Apply buttons to become flat. Same for CExtColorButton - is there a way to make it appear like standard Windows buttons (3D) instead of flat? Thanks!
|
|
Technical Support
|
Sep 4, 2005 - 9:42 AM
|
You can provide buttons in the resizable property sheet with a look of the classic buttons but the solution is a bit tricky. You need to use a CExtResizablePropertySheet -derived class in which Prof-UIS buttons should not be subclassed by the parent class: LRESULT C_YOUR_ResizablePropertySheet::
WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
{
if( message == (WM_USER+10) && (!bSheetInitialized) )
{
m_bSheetInitialized = true;
CRect rcWnd;
GetWindowRect( &rcWnd );
CSize sizeWnd = rcWnd.Size();
SetMinTrackSize( sizeWnd );
::SetWindowPos(
m_hWnd, NULL, 0,0,0,0,
SWP_NOSIZE|SWP_NOMOVE
|SWP_NOZORDER|SWP_NOOWNERZORDER
|SWP_NOREPOSITION
|SWP_FRAMECHANGED
);
CTabCtrl * pTabCtrl = CExtResPS::GetTabControl();
CWnd * pWnd = GetWindow( GW_CHILD );
for( ; pWnd != NULL; pWnd = pWnd->GetWindow(GW_HWNDNEXT) )
{
if( pTabCtrl == pWnd )
{
pTabCtrl->ModifyStyle( 0, WS_CLIPSIBLINGS );
AddAnchor( pTabCtrl->GetSafeHwnd(), __RDA_LT, __RDA_RB );
continue;
}
CExtSafeString sClassName;
::GetClassName(
pWnd->GetSafeHwnd(),
sClassName.GetBuffer( _MAX_PATH+1 ),
_MAX_PATH
);
sClassName.ReleaseBuffer();
sClassName.MakeLower();
if( sClassName == LPCTSTR( _T("static") ) )
{
pWnd->ModifyStyle( 0, WS_CLIPSIBLINGS );
#if _MFC_VER >= 0x700
if( (m_psh.dwFlags&PSH_WIZARD97) != 0 )
{
if( pWnd->GetDlgCtrlID() == 0x3027 )
{
AddAnchor(
pWnd->GetSafeHwnd(),
__RDA_LT,
__RDA_RT
);
continue;
}
}
#endif // #if _MFC_VER >= 0x700
AddAnchor(
pWnd->GetSafeHwnd(),
__RDA_LB,
__RDA_RB
);
continue;
}
} // for( ; pWnd != NULL; pWnd = pWnd->GetWindow(GW_HWNDNEXT) )
_SyncActivePage();
CExtPaintManager::monitor_parms_t _mp;
CExtPaintManager::stat_GetMonitorParms( _mp, this );
SetMaximizedRect( &_mp.m_rcWorkArea );
SetMaxTrackSize( _mp.m_rcWorkArea.Size() );
CRect _rcWnd;
GetWindowRect( &_rcWnd );;
CSize _size = _rcWnd.Size();
::SendMessage(
m_hWnd, WM_SIZE,
WPARAM(SIZE_RESTORED),
MAKELPARAM( _size.cx, _size.cy )
);
if( GetStyle() & WS_VISIBLE )
RedrawWindow();
OnResizablePropertySheetInitialized();
return 0L;
}
return
CExtResizablePropertySheet::
WindowProc(message,wParam,lParam);
} Then you need to make one more change. This code will not compile until you make the CExtResizablePropertySheet::m_bSheetInitialized property protected instead of private . To provide the color button with the classic look, create a CExtColorButton -derived class and implement the CExtColorButton::_RenderImpl() virtual method. Your method should paint the button using the classic Win32 API.
|
|
Michael Morrison
|
Sep 2, 2005 - 11:59 AM
|
What is the most likely cause for the assert fail:
ASSERT( !(pCmdItem->StateIsBasic()) );
On line 1798 of ExtCmdManager.cpp? This is happening inside g_CmdManager->SerializeState at startup when it loads the state from the registry.
If I delete my registry entries I can run the app once without problems - but on the second run it assert fails in that spot.
Thanks.
|
|
Technical Support
|
Sep 2, 2005 - 1:21 PM
|
With regard to expandable menus, there are two types of commands: 1) The basic command is always initially visible in menus regardelss of how often the user clicks it (or the same command in toolbars). 2) Any other command is not initially visible in menus. It becomes visible depending on how often it is used in comparisson with other commands. The command usage statistics information is tracked by the Prof-UIS command manager component. This information is loaded/saved to/from the system registry or MFC archive object when your application invokes the g_CmdManager->SerializeState(...) code. The assertion described in your message may occur when you have defined some command as basic and then your application tries to load the state of the command manager that contains command usage statistics of this basic command. Of course, if the problem persists, you can send us your project so that we can help you.
|
|
Srinivasan Natarajan
|
Sep 2, 2005 - 5:13 AM
|
Hi, During installation of Prof-UIS , i found 2 libraries are failed Library build for Visual Studio 6.0 Build "ProfUIS240ud - Unicode/Debug (profuisdll - Win32 Unicode Debug)" - failed Output file: "C:\Program Files\FOSS Software Inc\Prof-UIS\BIN_600\ProfUIS240ud.dll" 1 errors, 0 warnings Report file: "C:\Program Files\FOSS Software Inc\Prof-UIS\BIN_600\UnicodeDebug\profuisdll\buildlog.htm" Library build for Visual Studio 6.0 Build "ProfUIS240u - Unicode/Release (profuisdll - Win32 Unicode Release)" - failed Output file: "C:\Program Files\FOSS Software Inc\Prof-UIS\BIN_600\ProfUIS240u.dll" 1 errors, 0 warnings Report file: "C:\Program Files\FOSS Software Inc\Prof-UIS\BIN_600\UnicodeRelease\profuisdll\buildlog.htm". I am not sure what went wrong. Anyway i would like to see the "Arabic" language in the Language Switcher Demo, how do i see that ? regards sundar
|
|
Technical Support
|
Sep 2, 2005 - 8:25 AM
|
To see the Arabic language in the LanguageSwitcher sample application, you need the UNICODE version of the Prof-UIS DLL and appropriate version of the sample’s EXE file. You can build either Debug or Release Unicode configurations of the profuisdll and LanguageSwitcher projects. To compile them with Visual Studio, select the "Unicode Debug" or "Unicode Release" build configuration and compile both projects. The Prof-UIS Integration Wizard may fail to compile the library configurations due to sharing problems in some of project files. Could you send us the buildlog.htm files? This will let us to come to a conclusion about what’s wrong.
|
|
Michael Morrison
|
Sep 1, 2005 - 1:15 PM
|
How do i receive the real-time messages to track the CExtBarSliderButton while it is being pressed and dragged? I have tried a number of different things with no success. CExtBarButton has a OnPressedTracking[Start|Stop] but no OnTrack() or similar. Thanks.
|
|
Michael Morrison
|
Sep 7, 2005 - 6:11 PM
|
Is there an easy way to get this control to continue to call the ScrollPosSet method even if they stop moving the mouse? Basically I would like continuous messages while the button is pressed.
Thanks.
|
|
Technical Support
|
Sep 8, 2005 - 9:10 AM
|
You need a solution which is based on the timer. The slider button is not based on the HWND handle. So, create a CExtToolControlBar -derived class, receive timer events in it and re-direct them to the slider button. You can implement the CExtBarSliderButton::OnClick() virtual method in your CExtBarSliderButton -derived class and receive toolbar’s timer messages in it. Your method will have the same body as the original and track the same message loop while slider’s thumb button is being drag-and-dropped. Additionally this message loop should receive toolbar’s timer messages and periodically invoke the CExtBarSliderButton::ScrollPosSet() method as you need.
|
|
Michael Morrison
|
Sep 4, 2005 - 9:33 AM
|
Thanks for the response. I was using the "Zoom" control from AviFrames as a baseline. The problem was that I converted the "g_bSinchronizing" variable to be an instance variable rather than static. The CZoomBarSliderButton constructor does not initialize this to FALSE (because the static initializer did). This uninitialized variable, coupled with the "if( g_bSinchronizing ) return;" at the top of the ScrollPosSet fooled me into thinking this routine was not being called all the time. Initializing it to FALSE in my new constructor fixed the problem.
|
|
Technical Support
|
Sep 2, 2005 - 12:43 PM
|
You need to use a CExtBarSliderButton -derived class and override the ScrollPosSet virtual method which is called when the scroll position is changed. Please take a look at the AviFrames sample in which you can find two classes CSeekBarSliderButton and CZoomBarSliderButton , which represent scroll and slider buttons.
|
|
Krustys Donuts
|
Aug 31, 2005 - 11:37 PM
|
If I try to display an & character as part of a CExtButton caption, prof-uis crashes. Seems like you intended this based on the ASSERT: ASSERT( sBtn.Find( _T(’&’) ) < 0 ); //from ProfUIS242md.dll!CExtPaintManagerXP::PaintPushButton
Why would this be? So we can’t display &s?
Also, if I use a single & to generate a shortcut for a button, unexpected behavior results. For example, if I have a button caption "&Hello" and then press the "h" key, I would normally expect the "Hello" button to be pressed automatically. In CExtButton, the button gets the focus but isn’t pressed. Is there an easy way to automatically press the button?
Thanks.
|
|
Technical Support
|
Sep 2, 2005 - 8:19 AM
|
Thank you for this remark. The quick shortcut activation works for standard buttons, check boxes and radio buttons because they are windows of the "BUTTON" window class and appropriate button style. The CExtButton class subclasses the button common control and changes its style to the owner-draw button type. We had to do this because it is not possible to redraw the button common control correctly using any other technique. But the dialog’s window procedure does not allow any owner draw button control to be clicked or checked because the owner draw button control is treated as something unknown with custom behavior and meaning. We added support for quick shortcut activation to the CExtButton , CExtColorButton , CExtCheckBox and CExtRadioButton classes. Besides, push buttons with the drop-down arrow now feature configurable behavior with quick shortcut activation: they can treat pressing a shortcut either as clicking the main button area or clicking the drop-down arrow with further displaying the pop-up menu. If you need the updated code for these buttons right now, then please drop us an e-mail at support@prof-uis.com.
|
|
Krustys Donuts
|
Sep 2, 2005 - 11:27 AM
|
Thanks. But what about the && crash bug?
|
|
Technical Support
|
Sep 2, 2005 - 1:05 PM
|
This "unwanted" assertion bug should not appear in your application compiled with any version of Prof-UIS if the push button’s text contains only one ampersand character.
|
|
Krustys Donuts
|
Sep 2, 2005 - 1:59 PM
|
If I want my button caption to say "Hello & Goodbye" then in the editor I have to say "Hello && Goodbye". Doing this causes assertions.
|
|
Technical Support
|
Sep 4, 2005 - 9:07 AM
|
Yes, you are right, the assertion occurs because the paint manager assumes that it is incorrect to use more than one ampersand in the button text. We have never come across the ampersand as the shortcut key. Typically more than one ampersand is this case is a type. This assertion is not critical and we can exclude it from the source code.
|
|