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 |
|
Robert Webb
|
Aug 25, 2009 - 1:32 AM
|
Hi, I call CExtControlBar::ProfileBarStateSerialize to serialize the state of control bars. The first time a user runs the program, this function returns false and I know to set my control bars up in the default way instead. However, if I add a new control bar to the program, then the function returns true for previous users because they still have old serialization data, but the new control bar neither gets serialized (because it wasn’t in the old version of the data) nor does it get initialised to a default layout. How should I handle this? How do I reckonise after calling CExtControlBar::ProfileBarStateSerialize that a particular control bar failed to load any data? Thanks, Rob.
|
|
Technical Support
|
Aug 26, 2009 - 5:10 AM
|
The control bar state serialization code requires exact matching between the state data and bars created in the main frame window. There are two additional subsystems which support dynamic count of bars:
- The CExtCustomizeSite class supports dynamic count of toolbars because the user can create new toolbars in the customize dialog.
- The CExtDynamicBarSite class manages dynamically allocated resizable control bars (CExtDynamicControlBar ).
The states of these subsystems should be loaded before loading bar states. These subsystems should create dynamic bars first. Both subsystems can really make your application using version dependent counts of control bars and provide support for version independent bar states.
|
|
Robert Webb
|
Aug 25, 2009 - 2:30 AM
|
Also, even though I call SetInitDesiredSizeFloating(CSize(144, 219)) for my new control bar, it’s floating size after the first serialization (using old data that doesn’t include the new bar) is set back to (16,16), which gives me a tiny and useless control bar. Does this happen to everyone using ProfUIS? Surely I must be doing something wrong, but what? Finally, an assertion is hit during startup:
> ProfUIS285nd.dll!CExtCustomizeSite::CustomizeStateSerialize(CArchive & ar={...}, bool bEnableThrowExceptions=false) Line 10758 + 0x22 bytes C++ But there’s no error. A new control bar has been added since the user last ran the program, so the control bar can’t be found in the last serialisation data. I don’t think there should be an assertion unless something has gone wrong. Thanks, Rob.
|
|
Robert Webb
|
Aug 25, 2009 - 2:46 AM
|
Seems a lot of the default data in a control bar is overridden with rubbish when no serialisation data is found, including the initial floating size, horizontal docking size, vertical docking size, and the bar becomes hidden.
|
|
Robert Webb
|
Aug 25, 2009 - 2:18 AM
|
I just tried to solve this by overriding CExtControlBar::OnExtBarStateSerializationComplete() to set a flag when the control bar has been serialised. Unfortunately it seems this gets called even when the control bar did not find any serialisation data. Maybe there should be an extra arg to say whether the bar really was initialised from setup data. Rob.
|
|
tera tera
|
Aug 24, 2009 - 3:32 AM
|
Hello. I want to connect a dialogue to CExtShellDialogFile
I ask for the offer of the sample program.
I ask as soon as possible. Thanks,
|
|
Technical Support
|
Aug 26, 2009 - 5:09 AM
|
We modified your project. The CExtResizableDialog class does not support scrolling. So, we created a CExtScrollContainerWnd window and then we created a CExtResizableDialog dialog inside it. Please take a look at the source code related to the new CExtScrollContainerWnd m_wndScrollContainer; property in the CNxcMainDlg class. Here is the modified version of your project:
http://www.prof-uis.com/download/forums/tmp/MODIFIED-SampleSplit2.zip
|
|
tera tera
|
Aug 24, 2009 - 7:10 PM
|
Hello. >shell list view control with some other window. I do not want to perform changing of ShellListView.
I want to realize a screen such as CFormView.
However, cannot CFormView be realized with the Dialog form. Therefore I intended to use CExtSplitterWnd of FOSS. I made a sample first of all.
I got possible to display the dialogue, but am troubled because scroll bar is not displayed. http://ifreeta.dee.cc/20090824/SampleSplit2.lzh
|
|
Technical Support
|
Aug 24, 2009 - 11:24 AM
|
The current version of the CExtShellDialogFile class does not allow you to replace the shell list view control with some other window. It expects the shell list view control should be created successfully and it synchronizes the list view with other dialog controls. So, we will need to copy the source code of the CExtShellDialogFile class into the test project, rename it, remove the shell list view control and all the source code working with it and, finally, create some child dialog instead it. But first of all we need additional details about child dialog which you want to create instead the shell list view control. What it should do? Ho should we synchronize it with other dialog controls?
|
|
Offer Har
|
Aug 21, 2009 - 8:41 AM
|
Dear Support, I have a node with two children leafs, and I have my own derive cell type in both of the leafs. I override OnClick of my cell, and I want to catch double-click, waiting for nRepCnt==2 . The problem is that if I click once on the first node, and then once on the second node, I get nRepCnt equals to 2, and I think there was a double-click, which there was not. Please fix and let me know. Thanks, Ron.
|
|
Technical Support
|
Aug 22, 2009 - 11:35 AM
|
We fixed this issue some time ago. The void CExtGridBaseWnd::OnLButtonDown() method should begin with the following code:
void CExtGridBaseWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
ASSERT_VALID( this );
if( m_eMTT != __EMTT_NOTHING )
{
SendMessage( WM_CANCELMODE );
if( m_eMTT != __EMTT_NOTHING )
return;
} // if( m_eMTT != __EMTT_NOTHING )
UINT nRepCnt = 1;
static clock_t g_nLastClock = 0;
static HWND g_hWndLastClick = NULL;
static CPoint g_ptLastClick(-32767,-32767);
CPoint ptLastClick = point;
ClientToScreen( &ptLastClick );
clock_t nCurrClock = ::clock();
if( g_hWndLastClick == m_hWnd
&& g_ptLastClick == ptLastClick
)
{
clock_t nDiff = (clock_t)::abs( nCurrClock - g_nLastClock );
clock_t nDoubleClickTime = (clock_t)::GetDoubleClickTime();
if( nDiff <= nDoubleClickTime )
nRepCnt = 2;
}
g_ptLastClick = ptLastClick;
g_hWndLastClick = m_hWnd;
g_nLastClock = nCurrClock;
HWND hWndOwn = m_hWnd, hWndFocus = ::GetFocus();
. . .
There is only one case when a double click can be generated not for the same cell which received the first click: this can happen when grid’s scrolling position changed between clicks. Is it your case?
|
|
Offer Har
|
Aug 21, 2009 - 8:45 AM
|
I would like to add that I think I know where this bugs begins - You remember the last click, and the HWND it was clicked in (g_hWndLastClick and g_nLastClock ) but this does not work for cells, as they are not HWND entities, and as they are in the same grid, they have the same HWND... Take a look at this code: void CExtGridBaseWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
ASSERT_VALID( this );
if( m_eMTT != __EMTT_NOTHING )
{
SendMessage( WM_CANCELMODE );
if( m_eMTT != __EMTT_NOTHING )
return;
} // if( m_eMTT != __EMTT_NOTHING )
UINT nRepCnt = 1;
static clock_t g_nLastClock = 0;
static HWND g_hWndLastClick = NULL;
clock_t nCurrClock = ::clock();
if( g_hWndLastClick == m_hWnd )
{
clock_t nDiff = (clock_t)::abs( nCurrClock - g_nLastClock );
clock_t nDoubleClickTime = (clock_t)::GetDoubleClickTime();
if( nDiff <= nDoubleClickTime )
nRepCnt = 2;
} ...
I put a break-point there and it is reached... Please fix. Thanks, Ron.
|
|
Offer Har
|
Aug 21, 2009 - 4:50 AM
|
Dear Support, We have a drop-list with many items, we would like to group them into a tree. Is there any ready-to-use control in Prof-UIS that does that? Thanks, Ron.
|
|
Technical Support
|
Aug 22, 2009 - 2:23 PM
|
You can find a lot of articles on the Internet like these:
http://www.codeguru.com/cpp/controls/combobox/dropdown/article.php/c1791 http://www.codeproject.com/KB/combobox/TreeCombo.aspx
But they typically describe how to create something that looks like a combo box common control but not based on it. So, we spent a couple of hours and coded the following simplest possible combo box control with a popup tree control instead of the list box:
http://www.prof-uis.com/download/forums/tmp/TestTreeComboBoxForRon.zip
This is basic implementation which was written just to prove whether this is possible. It’s probably not a ready-to-use control yet. So, we need to know your wishes and task details. The main feature of our tree combo box is that it’s based on the CExtComboBox and CExtTreeCtrl controls - it’s not derived directly from CWnd . But we need to add a lot of additional features. For example, we need to make it working in several specific modes like display comma separated text of all the checked tree items.
|
|
Chris Anderson
|
Aug 20, 2009 - 5:17 PM
|
Is it possible to disable a tab of ribbon bar ( the ribbon nodes in the tab could be either enabled or disalbed ) ? The riibbon node can be disabled, but I didn’t see any function or attribute in the ribbon bar class to disable a tab
|
|
Technical Support
|
Aug 21, 2009 - 11:10 AM
|
We follow the Microsoft’s Ribbon UI Guidelines and Vista UI Guidelines document. The ribbon bar is not designed to be with disabled tabs. You should hide tab pages instead of disabling them.
|
|
Antonio Pelli Neto
|
Aug 20, 2009 - 7:51 AM
|
Hello, Please, take a look at the attached picture. The size of the button file is wrong (not the icon) and the background color of the Quick Acces Menu is wrong too. The code is from FormulaGrid merged with code from RibonBar sample. How to fix them? Best regards, Pelli
|
|
Technical Support
|
Aug 24, 2009 - 11:25 AM
|
We checked both XP and Vista. We used Prof-UIS 2.85. Is it your current version?
|
|
Antonio Pelli Neto
|
Aug 24, 2009 - 12:44 PM
|
Hello, Yes, 2.85 is my current version. But I think that’s not the problem, once you provided static linked binary files. The file menu is in a wrong position. I tested in more two computers and the result are the same.
|
|
Technical Support
|
Aug 26, 2009 - 5:11 AM
|
Do you use any specific DPI settings on your desktops?
|
|
Antonio Pelli Neto
|
Aug 26, 2009 - 8:08 AM
|
No, I use the default settings. Pelli
|
|
Technical Support
|
Aug 22, 2009 - 11:43 AM
|
|
|
Antonio Pelli Neto
|
Aug 24, 2009 - 7:18 AM
|
Hello, It didn’t work. We run the compiled binary on Windows XP and Windows Vista, both Professional (business) and Home Edition (English and Portuguese version). Again, the Ribbon Bar and Formula Grid samples run well, while modified version on the link provided by you looks like the picture above. What’s wrong? Best regards, Pelli, Antonio
|
|
Antonio Pelli Neto
|
Aug 20, 2009 - 10:32 AM
|
|
|
Technical Support
|
Aug 20, 2009 - 9:48 AM
|
Please let us know whether this incorrect layout can be seen in the RibbonBar sample application running on your computer? Or whether it can be seen in the modified version of the FormulaGrid sample application only?
|
|
Antonio Pelli Neto
|
Aug 21, 2009 - 2:45 PM
|
Hello, I reproduced the sample FormulaGrid, only including the Ribbon Button File and the same problem occurs. Is the FormulaGrid incompatible with RibbonFile Button.
|
|
tera tera
|
Aug 20, 2009 - 3:42 AM
|
An example
|
|
Technical Support
|
Aug 20, 2009 - 7:46 AM
|
Yes. For example, the CExtShellDialogFile class uses a splitter with two panes: the left is a shell tree control, the right is a shell list control.
|
|
tera tera
|
Aug 19, 2009 - 7:46 PM
|
|
|
Technical Support
|
Aug 20, 2009 - 7:47 AM
|
We tried to connect to your PC remotely several times. There are more than one computer in list. But the computer you meant was always off.
|
|
Robert Webb
|
Aug 19, 2009 - 3:07 AM
|
Hi, I want to be able to drag and drop items from a tree control to an MDI tab. Calling WindowFromPoint() returns a CWnd* which I can DYNAMIC_DOWNCAST to various things, such as a CExtTabMdiWnd. But once I have the CExtTabMdiWnd, how do I find out which tab was clicked on? That is, how do I find the tab given a CPoint? And how do I find out which CView that represents? I couldn’t see any useful methods to help with this. Thanks, Rob.
|
|
Technical Support
|
Aug 20, 2009 - 9:47 AM
|
|
|
Technical Support
|
Aug 20, 2009 - 7:48 AM
|
The tab items have the LPARAM user defined property. It’s the HWND handle of MDI child frame window in case of MDI tabs:
CExtTabMdiWnd * pWndMdiTabs = . . .
LONG nCurSel = pWndMdiTabs->SelectionGet();
if( nCurSel < 0 L )
return . . .
HWND hWnd = pWndMdiTabs->ItemLParamGet( nCurSel );
ASSERT( hWnd != NULL && ::IsWindow(hWnd) );
CWnd * pWndMdiChildFrame = CWnd::FromHandlePermanent( hWnd );
CWnd * pWndViewInsideMdiChildFrame = pWndMdiChildFrame->GetDlgItem( AFX_IDW_PANE_FIRST );
The update version of the CExtTreeCtrl::EnableItem()</code> method repaints enabled/disabled items.
<pre>void CExtTreeCtrl::EnableItem(
HTREEITEM hti,
bool bEnable // = true
)
{
ASSERT_VALID( this );
if( hti == NULL )
return;
TREEITEMINFO_t & _TII = TreeItemInfoGet( hti );
if( ( _TII.m_bDisabled && bEnable ) || ( (!_TII.m_bDisabled) && (!bEnable) ) )
return;
_TII.m_bDisabled = ! bEnable;
if( GetSafeHwnd() == NULL )
return;
CRect rcItemEntire;
TreeItemRectGet( hti, rcItemEntire, e_tirt_entire );
if( rcItemEntire.IsRectEmpty() )
return;
CRect rcClient;
GetClientRect( &rcClient );
if( ( rcClient.top <= rcItemEntire.top && rcItemEntire.top <= rcClient.bottom )
|| ( rcClient.top <= rcItemEntire.bottom && rcItemEntire.bottom <= rcClient.bottom )
)
InvalidateRect( &rcItemEntire );
}
The SetInsertMark() method is not implemented yet. We didn’t implemented it because Prof-UIS classes use the non-rectangular window with form of red arrows displayed over other windows to highlight the dropping target. These red arrows are used instead of any insertion marks. We can assume the SetInsertMark() method is a feature request.
|
|
Robert Webb
|
Aug 20, 2009 - 9:19 PM
|
Thanks, although it seems this version of EnableItem() acts a little worse than the old one. Previously I called Invalidate() for the tree after EnableItem(), which made sure it got redrawn right. Now even this leaves all items shown as enabled! It may be something to do with me using this call: AutoDisableChildrenItemsSet(). I am calling EnableItem() on the root node in order to enable/disable the entire tree. Maybe you are only invalidating the root node. But I don’t know why my subsequent call to Invalidate() would not redraw it properly anyway. Oh, and you didn’t answer this: "Is there an article about drag/drop with ProfUIS?". In particular I don’t understand how to do it in conjunction with a tree control. Thanks, Rob.
|
|
Technical Support
|
Aug 22, 2009 - 11:38 AM
|
There was a typo in the CExtTreeCtrl::EnableItem() method. We are sorry for this inconvenience. Here is the correct version:
void CExtTreeCtrl::EnableItem(
HTREEITEM hti,
bool bEnable // = true
)
{
ASSERT_VALID( this );
if( hti == NULL )
return;
TREEITEMINFO_t & _TII = TreeItemInfoGet( hti );
if( ( _TII.m_bDisabled && (!bEnable) ) || ( (!_TII.m_bDisabled) && bEnable ) )
return;
_TII.m_bDisabled = ! bEnable;
if( GetSafeHwnd() == NULL )
return;
CRect rcItemEntire;
TreeItemRectGet( hti, rcItemEntire, e_tirt_entire );
if( rcItemEntire.IsRectEmpty() )
return;
CRect rcClient;
GetClientRect( &rcClient );
if( ( rcClient.top <= rcItemEntire.top && rcItemEntire.top <= rcClient.bottom )
|| ( rcClient.top <= rcItemEntire.bottom && rcItemEntire.bottom <= rcClient.bottom )
)
InvalidateRect( &rcItemEntire );
}
The drag-n-drop number one in Windows world is OLE drag-n-drop. It’s used in the FormEditor sample application. It’s used by customizable toolbars and menus in Prof-UIS. It’s supported by Prof-UIS grid controls starting from version 2.85 and it’s demonstrated in the FormulaGrid sample application. It’s simple. It’s convenient. It can work between threads and processes. It’s so easy so you can either use Win32 or MFC APIs. It’s equally easy to use COleDataSource / COleDropSource / COleDropTargent classes from MFC or to implement IDataSource / IDropSource / IDropTargent interfaces from Win32. The OLE drag-n-drop and clipboard support code is always in intersected. If you decided to code one of these features, then you can code both of them. Here is the theoretical basics: http://msdn.microsoft.com/en-us/library/96826a87(VS.80).aspxThere are many articles on the Internet like these: http://www.codeproject.com/KB/shell/dragdrop.aspx?msg=180749http://www.codeproject.com/KB/clipboard/dragsource.aspx
|
|
Technical Support
|
Aug 19, 2009 - 2:32 PM
|
Please take a look at the FormEditor sample application. It implements drag-n-drop from the toolbox control into MDI form view window. You should use the same OLE drag-n-drop in your application. It the most widely used drag-n-drop implementation because it’s simple and convenient. The MDI tabs and resizable control bar tabs in Prof-UIS support dragging-over event handling and perform tab item selection automatically.
|
|
Robert Webb
|
Aug 20, 2009 - 2:38 AM
|
Hmm, I don’t really understand how the FormEditor code is working. Is there an article about drag/drop with ProfUIS? I initially looked at doing it the OLE way, but couldn’t see how to use it when dragging items from a tree control, so I started doing it another way instead. This is mostly working, except for a few things: (1) Given the index of a tab on the MDI bar, how do I find the matching CView? Seems like this should be easy, but I can’t find a way. (2) CExtTreeCtrl::SetInsertMark() doesn’t seem to work. No insertion mark is drawn. (3) CExtTreeCtrl::EnableItem() doesn’t cause the tree to be redrawn. Thanks, Rob.
|
|
tera tera
|
Aug 18, 2009 - 6:52 PM
|
Hello. When there is a focus to a docking bar
class CMainFrame : public CMDIFrameWnd
, public CExtHookSpy I want to do hook of key input in OnHookSpyPreTranslateMessage.
However, OnHookSpyPreTranslateMessage and CMainFrame-PreTranslateMessage are called each.
When there is a focus to a bar,I want you to call only OnHookSpyPreTranslateMessage.
|
|
tera tera
|
Aug 19, 2009 - 7:38 PM
|
When there is a focus to a docking bar When I want to transmit Del Key to only CEdit,
In OnHookSpyPreTranslateMessage, I do not return false
It is not transmitted a message.
And Del Key of MainFrame side reacts. Is not there the good method?
|
|
Technical Support
|
Aug 20, 2009 - 7:45 AM
|
The message hooking mechanism is not what you need:
CEdit * pEdit = . . .
pEdit->SendMessage( WM_KEYDOWN, VK_DELETE );
|
|
Technical Support
|
Aug 19, 2009 - 2:29 PM
|
The application’s CWinThread::PreTranslateMessage() virtual method and the main frame’s CFrameWnd::PreTranslateMessage() virtual method are invoked by MFC before messages will be delivered to window procedures. The CExtHoolSpy::OnHookSpyPreTranslateMessage() virtual methods are invoked earlier than MFC’s message pre-translation virtual methods because the CExtHoolSpy -based mechanism is based on the thread wide windows hooks. If some OnHookSpyPreTranslateMessage() virtual method returns true , then all the other OnHookSpyPreTranslateMessage() methods and MFC message pre-translation methods are not invoked too. This means the OnHookSpyPreTranslateMessage() method works exactly in the same way like MFC’s PreTranslateMessage() methods do. If you want to hook keyboard messages in your OnHookSpyPreTranslateMessage() method and hide them from MFC and window procedures, then your OnHookSpyPreTranslateMessage() method should return true for the intercepted messages.
|
|
Rado Manzela
|
Aug 17, 2009 - 1:08 PM
|
|
|
Technical Support
|
Aug 17, 2009 - 1:59 PM
|
Thank you for reporting this issue. Please update the source code for the following method:
bool CExtTabWnd::_ProcessMouseClick(
CPoint point,
bool bButtonPressed,
INT nMouseButton, // MK_... values
UINT nMouseEventFlags
)
{
ASSERT_VALID( this );
if( GetSafeHwnd() == NULL )
return false;
if( bButtonPressed )
{
CWnd * pWndTestChildFrame = GetParentFrame();
if( pWndTestChildFrame != NULL && pWndTestChildFrame->IsKindOf( RUNTIME_CLASS( CMDIChildWnd ) ) )
{
CFrameWnd * pWndFrame = pWndTestChildFrame->GetParentFrame();
if( pWndFrame != NULL )
{
CMDIFrameWnd * pWndMDIFrame = DYNAMIC_DOWNCAST( CMDIFrameWnd, pWndFrame );
if( pWndMDIFrame != NULL )
{
CMDIChildWnd * pActive = pWndMDIFrame->MDIGetActive();
if( pWndTestChildFrame != pActive )
((CMDIChildWnd*)pWndTestChildFrame)->MDIActivate();
}
}
}
} // if( bButtonPressed )
LONG nHitTest = ItemHitTest( point );
switch( nHitTest )
{
case __ETWH_BUTTON_LEFTUP:
case __ETWH_BUTTON_RIGHTDOWN:
case __ETWH_BUTTON_SCROLL_HOME:
case __ETWH_BUTTON_SCROLL_END:
case __ETWH_BUTTON_HELP:
case __ETWH_BUTTON_CLOSE:
case __ETWH_BUTTON_TAB_LIST:
return OnTabWndClickedButton( nHitTest, bButtonPressed, nMouseButton, nMouseEventFlags );
default:
if( nHitTest < __ETWH_TAB_FIRST )
{
OnTabWndMouseTrackingPushedStop();
Invalidate();
UpdateWindow();
return false; //true;
}
break;
}
ASSERT( nHitTest >= 0 && nHitTest < ItemGetCount() );
if( bButtonPressed )
m_ptStartDrag = point;
else
{
if( m_nPushedTrackingButton >= 0 && m_bPushedTrackingCloseButton )
{
CPoint ptCursor;
if( ::GetCursorPos( &ptCursor ) )
{
LONG nPushedTrackingButton = m_nPushedTrackingButton;
ScreenToClient( &ptCursor );
if( ItemGet( m_nPushedTrackingButton )->CloseButtonRectGet().PtInRect( ptCursor ) )
{
if( ::GetCapture() == m_hWnd )
::ReleaseCapture();
OnTabWndClickedItemCloseButton( nPushedTrackingButton );
}
}
return true;
}
}
return OnTabWndClickedItem( nHitTest, bButtonPressed, nMouseButton, nMouseEventFlags );
}
|
|
tera tera
|
Aug 17, 2009 - 12:55 AM
|
An error is displayed at the time of grid making.
I do DestroyWindow of a dialog grid.
Assert is displayed when I do Create again. http://ifreeta.dee.cc/20090817/SampleMuGridbugtest.lzh void CSampleDialog10Dlg::OnButton11()
{
OnButton10(); pSunpoInpHojyoDlg->DestroyWindow( ); OnButton10();
} static CNxfKakouEditSunpoInpHojyoDlg *pSunpoInpHojyoDlg = NULL; void CSampleDialog10Dlg::OnButton10()
{
if ( pSunpoInpHojyoDlg == NULL ){
//pSunpoInpHojyoDlg = new CNxfKakouEditSunpoInpHojyoDlg ;
pSunpoInpHojyoDlg = new CNxfKakouEditSunpoInpHojyoDlg ;
} pSunpoInpHojyoDlg->Create(
CNxfKakouEditSunpoInpHojyoDlg::IDD ,
this
); }
|
|
Technical Support
|
Aug 17, 2009 - 1:48 PM
|
Thank you for the test project. We found two issues. One is in your project. Please update the source code for the following method:
void CSampleDialog10Dlg::OnButton10()
{
if ( pSunpoInpHojyoDlg == NULL ){
//pSunpoInpHojyoDlg = new CNxfKakouEditSunpoInpHojyoDlg ;
pSunpoInpHojyoDlg = new CNxfKakouEditSunpoInpHojyoDlg ;
}
if( pSunpoInpHojyoDlg->GetSafeHwnd() == NULL ) /// WE JUST ADDED THIS LINE
pSunpoInpHojyoDlg->Create(
CNxfKakouEditSunpoInpHojyoDlg::IDD ,
this
);
}
Second is in Prof-UIS. Please update the source code for the following two methods: #ifdef _DEBUG
LONG CExtGridWnd::ColumnCountSet(
LONG nCount, // = -1L
bool bRedraw // = true
)
{
ASSERT_VALID( this );
ASSERT(
m_bDebugModifyingColumns
|| nCount == ColumnCountGet()
|| nCount < 0L // switching to virtual mode
|| nCount == 0L // presubclassing/initializing
);
return
CExtGridBaseWnd::ColumnCountSet(
nCount,
bRedraw
);
}
LONG CExtGridWnd::RowCountSet(
LONG nCount, // = -1L
bool bRedraw // = true
)
{
ASSERT_VALID( this );
ASSERT(
m_bDebugModifyingRows
|| nCount == RowCountGet()
|| nCount < 0L // switching to virtual mode
|| nCount == 0L // presubclassing/initializing
);
return
CExtGridBaseWnd::RowCountSet(
nCount,
bRedraw
);
}
#endif // _DEBUG
|
|
Robert Webb
|
Aug 14, 2009 - 2:32 AM
|
Hi, I’m trying to transfer some of our old CTreeCtrl’s to the Prof-UIS CExtTreeCtrl instead. There are two problems though. (1) CExtTreeCtrl seems to eat some mouse events and not pass them through. Our derived tree class required the NM_CLICK, NM_DBLCLK and NM_RCLICK notifications, but when I change the base class to CExtTreeCtrl, these notifications are no longer received. Can this be fixed? (2) Just a minor incompatibility: SelectItem() now requires at least two arguments, whereas it previously only required one. I suggest you make the second argument default to true (for selection rather than deselection). This was easy enough to work-around by deriving my own tree control and over-riding SelectItem() to provide this default second arg, but I suggest you do it in the Prof-UIS code too. Thanks, Rob.
|
|
Robert Webb
|
Aug 24, 2009 - 3:32 AM
|
I think I found another problem with CExtTreeCtrl. It doesn’t always call OnLButtonUp() when the left button is released. It does get called if you drag between the button down and up, or if you click to expand an item, but if you just click on an item and release without moving the mouse, then OnLButtonUp() is not called. Thanks, Rob.
|
|
Technical Support
|
Aug 24, 2009 - 11:33 AM
|
Thank you for reporting this issue. Please update the source code for the following two methods: bool CExtControlBar::stat_DragDetect_ImplStep(
HWND hWnd,
POINT pt,
UINT nUpMessage // = WM_LBUTTONUP
)
{
if( hWnd == NULL || (! ::IsWindow( hWnd ) ) )
return false;
CSize sizeDrag( ::GetSystemMetrics( SM_CXDRAG ), ::GetSystemMetrics( SM_CYDRAG ) );
CRect rc( pt.x - sizeDrag.cx, pt.y - sizeDrag.cy, pt.x + sizeDrag.cx, pt.y + sizeDrag.cy );
::SetCapture( hWnd );
for( MSG _msg; ::IsWindow( hWnd ) ; )
{
for( ;
::IsWindow( hWnd )
&& ( ::PeekMessage( &_msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE )
|| ::PeekMessage( &_msg, 0, WM_CANCELMODE, WM_CANCELMODE, PM_NOREMOVE )
|| ::PeekMessage( &_msg, 0, WM_ACTIVATEAPP, WM_ACTIVATEAPP, PM_NOREMOVE )
)
;
)
{
if( _msg.message == nUpMessage
|| _msg.message == WM_CANCELMODE
|| _msg.message == WM_ACTIVATEAPP
)
{
::ReleaseCapture();
return false;
}
::PeekMessage( &_msg, 0, _msg.message, _msg.message, PM_REMOVE );
if( _msg.message == WM_MOUSEMOVE )
{
CPoint ptMessage( LOWORD( _msg.lParam ), HIWORD( _msg.lParam ) );
if( ! rc.PtInRect( ptMessage ) )
{
ReleaseCapture();
return true;
}
}
}
::WaitMessage();
}
return false;
}
bool CExtControlBar::stat_DoDragDetect(
HWND hWnd,
const POINT & ptWndClient,
UINT nUpMessage // = WM_LBUTTONUP
)
{
if( hWnd == NULL || (! ::IsWindow( hWnd ) ) )
return false;
CPoint ptScreen = ptWndClient;
::ClientToScreen( hWnd, &ptScreen );
for( ; stat_DragDetect_ImplStep( hWnd, ptScreen, nUpMessage ) ; )
{
POINT ptCursorPos = { -32767, -32767 };
if( ! ::GetCursorPos( &ptCursorPos ) )
return false;
if( ptScreen == ptCursorPos )
continue; //only drag time elapsed but mouse is not moved
return true;
}
return false;
}
|
|
Robert Webb
|
Aug 24, 2009 - 8:07 PM
|
Something strange is still happening. Now my OnLButtonUp callback gets called, but sometimes a drag operation starts AFTER the button up message. Doesn’t happen if you click and hold before releasing, or if the mouse moves while the button is down, but if you just click and release quickly, the TVN_BEGINDRAG message arrives AFTER the button up message. This causes problems of course because button-up is supposed to mark the end of the drag. Thanks, Rob.
|
|
Robert Webb
|
Aug 24, 2009 - 8:14 PM
|
More info: the button-up event is sent downstream fromCExtTreeCtrl::OnLButtonDown. That doesn’t seem right. Then the begin-drag event is sent after button-up. Here’s a stack trace showing button-up being called downstream from button-down. As I said this only happens if you tap the button quickly.
> cadwind.exe!ViewTreeCtrl::OnLButtonUp(unsigned int nFlags=0, CPoint point={...}) Line 258 C++
mfc80d.dll!CWnd::OnWndMsg(unsigned int message=514, unsigned int wParam=0, long lParam=12058691, long * pResult=0x0013a47c) Line 2169 C++
mfc80d.dll!CWnd::WindowProc(unsigned int message=514, unsigned int wParam=0, long lParam=12058691) Line 1741 + 0x20 bytes C++
ProfUIS285nd.dll!CExtTreeCtrl::WindowProc(unsigned int message=514, unsigned int wParam=0, long lParam=12058691) Line 4500 + 0x14 bytes C++
cadwind.exe!CExtNCSB_Impl<CExtTreeCtrl>::WindowProc(unsigned int message=514, unsigned int wParam=0, long lParam=12058691) Line 1145 + 0x17 bytes C++
mfc80d.dll!AfxCallWndProc(CWnd * pWnd=0x0fd84a18, HWND__ * hWnd=0x000e1752, unsigned int nMsg=514, unsigned int wParam=0, long lParam=12058691) Line 240 + 0x1c bytes C++
mfc80d.dll!AfxWndProc(HWND__ * hWnd=0x000e1752, unsigned int nMsg=514, unsigned int wParam=0, long lParam=12058691) Line 389 C++
mfc80d.dll!AfxWndProcBase(HWND__ * hWnd=0x000e1752, unsigned int nMsg=514, unsigned int wParam=0, long lParam=12058691) Line 411 + 0x15 bytes C++
user32.dll!7e418734()
[Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]
user32.dll!7e418816()
user32.dll!7e4189cd()
user32.dll!7e41ca67()
user32.dll!7e4196c7()
cadwind.exe!gr_intr(int * type=0x0013a880, int clearbuffer=0) Line 5107 + 0xc bytes C++
cadwind.exe!CheckUserAbort() Line 491 + 0xb bytes C++
cadwind.exe!CGLRenderer::DrawSurfaces(CGLRenderer::enumDrawType drawtype=drawSurfaceAll) Line 959 + 0x5 bytes C++
cadwind.exe!CGLRenderer::DrawSubwin(bool bClear=false) Line 273 C++
cadwind.exe!CGLRenderer::RenderScene(bool bClear=false) Line 2027 C++
cadwind.exe!CCadView::ViewDrawSubWindow(int nSubno=0, int nAction=1, bool bClear=true) Line 366 + 0xa bytes C++
cadwind.exe!CCadView::ViewDraw(int iSubno=-1, int nAction=1) Line 122 + 0x14 bytes C++
cadwind.exe!dr_update(int clear=-1, int nAction=1) Line 465 + 0x13 bytes C++
cadwind.exe!dr_update(int clear=-1) Line 478 + 0xd bytes C++
cadwind.exe!vw_ChangeView(int subno=1, int nViewNum=10) Line 1164 + 0xb bytes C++
cadwind.exe!vw_select(int * redrawn=0x0013af80, int autoselect=1, const char * viewname=0x00000000) Line 1139 + 0xd bytes C++
cadwind.exe!CDockableViewDlg::SelectView(_TREEITEM * item=0x00232350) Line 444 + 0x10 bytes C++
cadwind.exe!CDockableViewDlg::OnSelectView(tagNMHDR * pNMHDR=0x0013baf4, long * pResult=0x0013b2a4) Line 642 C++
mfc80d.dll!_AfxDispatchCmdMsg(CCmdTarget * pTarget=0x0fd84898, unsigned int nID=1308, int nCode=65134, void (void)* pfn=0x00ba1e9e, void * pExtra=0x0013b17c, unsigned int nSig=60, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 112 C++
mfc80d.dll!CCmdTarget::OnCmdMsg(unsigned int nID=1308, int nCode=65134, void * pExtra=0x0013b17c, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 381 + 0x27 bytes C++
mfc80d.dll!CDialog::OnCmdMsg(unsigned int nID=1308, int nCode=5176942, void * pExtra=0x0013b17c, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 85 + 0x18 bytes C++
cadwind.exe!CDockableViewDlg::OnCmdMsg(unsigned int nID=1308, int nCode=5176942, void * pExtra=0x0013b17c, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 674 C++
mfc80d.dll!CWnd::OnNotify(unsigned int __formal=1308, long lParam=1293044, long * pResult=0x0013b2a4) Line 2326 C++
mfc80d.dll!CWnd::OnWndMsg(unsigned int message=78, unsigned int wParam=1308, long lParam=1293044, long * pResult=0x0013b2dc) Line 1767 + 0x2a bytes C++
mfc80d.dll!CWnd::WindowProc(unsigned int message=78, unsigned int wParam=1308, long lParam=1293044) Line 1741 + 0x20 bytes C++
ProfUIS285nd.dll!CExtWS<CExtADLG<CExtResDlg>,301>::WindowProc(unsigned int message=78, unsigned int wParam=1308, long lParam=1293044) Line 1197 C++
ProfUIS285nd.dll!CExtWA<CExtWS<CExtADLG<CExtResDlg>,301> >::WindowProc(unsigned int message=78, unsigned int wParam=1308, long lParam=1293044) Line 1844 + 0x14 bytes C++
ProfUIS285nd.dll!CExtResizableDialog::WindowProc(unsigned int message=78, unsigned int wParam=1308, long lParam=1293044) Line 378 + 0x14 bytes C++
mfc80d.dll!AfxCallWndProc(CWnd * pWnd=0x0fd84898, HWND__ * hWnd=0x002216d8, unsigned int nMsg=78, unsigned int wParam=1308, long lParam=1293044) Line 240 + 0x1c bytes C++
mfc80d.dll!AfxWndProc(HWND__ * hWnd=0x002216d8, unsigned int nMsg=78, unsigned int wParam=1308, long lParam=1293044) Line 389 C++
mfc80d.dll!AfxWndProcBase(HWND__ * hWnd=0x002216d8, unsigned int nMsg=78, unsigned int wParam=1308, long lParam=1293044) Line 411 + 0x15 bytes C++
user32.dll!7e418734()
user32.dll!7e418816()
user32.dll!7e41b4c0()
user32.dll!7e41b50c()
ntdll.dll!_KiUserCallbackDispatcher@12() + 0x13 bytes
user32.dll!7e4194be()
user32.dll!7e41d4e4()
user32.dll!7e41b903()
comctl32.dll!773eab19()
comctl32.dll!77407392()
comctl32.dll!77407720()
user32.dll!7e41bf78()
comctl32.dll!7740885c()
comctl32.dll!774096bd()
comctl32.dll!7740af3f()
mfc80d.dll!CWnd::OnWndMsg(unsigned int message=4363, unsigned int wParam=9, long lParam=2302800, long * pResult=0x0fd84a18) Line 1866 + 0x19 bytes C++
mfc80d.dll!CWnd::WindowProc(unsigned int message=4363, unsigned int wParam=9, long lParam=2302800) Line 1742 + 0x1c bytes C++
ProfUIS285nd.dll!CExtTreeCtrl::WindowProc(unsigned int message=4363, unsigned int wParam=9, long lParam=2302800) Line 4500 + 0x14 bytes C++
cadwind.exe!CExtNCSB_Impl<CExtTreeCtrl>::WindowProc(unsigned int message=4363, unsigned int wParam=9, long lParam=2302800) Line 1145 + 0x17 bytes C++
mfc80d.dll!AfxCallWndProc(CWnd * pWnd=0x0fd84a18, HWND__ * hWnd=0x000e1752, unsigned int nMsg=4363, unsigned int wParam=9, long lParam=2302800) Line 240 + 0x1c bytes C++
mfc80d.dll!AfxWndProc(HWND__ * hWnd=0x000e1752, unsigned int nMsg=4363, unsigned int wParam=9, long lParam=2302800) Line 389 C++
mfc80d.dll!AfxWndProcBase(HWND__ * hWnd=0x000e1752, unsigned int nMsg=4363, unsigned int wParam=9, long lParam=2302800) Line 411 + 0x15 bytes C++
user32.dll!7e418734()
user32.dll!7e418816()
user32.dll!7e41b4c0()
user32.dll!7e41b50c()
ntdll.dll!_KiUserCallbackDispatcher@12() + 0x13 bytes
user32.dll!7e4194be()
user32.dll!7e41d890()
user32.dll!7e42f3cc()
mfc80d.dll!CTreeCtrl::SelectItem(_TREEITEM * hItem=0x00232350) Line 288 + 0x44 bytes C++
ProfUIS285nd.dll!CExtTreeCtrl::FocusItem(_TREEITEM * hti=0x00232350, bool bSelect=true, bool bUnselectOtherItems=true, bool bMouseClickEvent=true) Line 5129 C++
ProfUIS285nd.dll!CExtTreeCtrl::OnTreeMouseClick(_TREEITEM * hti=0x00232350, unsigned long dwHitTestFlags=4, int nMouseButton=1, int nClick=0, unsigned int nMouseEventFlags=1, CPoint point={...}) Line 5545 C++
ProfUIS285nd.dll!CExtTreeCtrl::_OnTreeMouseClickImpl(int nMouseButton=1, int nClick=0, unsigned int nMouseEventFlags=1, CPoint point={...}) Line 5236 + 0x2e bytes C++
> ProfUIS285nd.dll!CExtTreeCtrl::OnLButtonDown(unsigned int nFlags=1, CPoint point={...}) Line 5146 + 0x18 bytes C++
cadwind.exe!ViewTreeCtrl::OnLButtonDown(unsigned int nFlags=1, CPoint point={...}) Line 246 + 0x17 bytes C++
mfc80d.dll!CWnd::OnWndMsg(unsigned int message=513, unsigned int wParam=1, long lParam=12058691, long * pResult=0x0013c4c4) Line 2169 C++
mfc80d.dll!CWnd::WindowProc(unsigned int message=513, unsigned int wParam=1, long lParam=12058691) Line 1741 + 0x20 bytes C++
ProfUIS285nd.dll!CExtTreeCtrl::WindowProc(unsigned int message=513, unsigned int wParam=1, long lParam=12058691) Line 4500 + 0x14 bytes C++
cadwind.exe!CExtNCSB_Impl<CExtTreeCtrl>::WindowProc(unsigned int message=513, unsigned int wParam=1, long lParam=12058691) Line 1145 + 0x17 bytes C++
mfc80d.dll!AfxCallWndProc(CWnd * pWnd=0x0fd84a18, HWND__ * hWnd=0x000e1752, unsigned int nMsg=513, unsigned int wParam=1, long lParam=12058691) Line 240 + 0x1c bytes C++
mfc80d.dll!AfxWndProc(HWND__ * hWnd=0x000e1752, unsigned int nMsg=513, unsigned int wParam=1, long lParam=12058691) Line 389 C++
mfc80d.dll!AfxWndProcBase(HWND__ * hWnd=0x000e1752, unsigned int nMsg=513, unsigned int wParam=1, long lParam=12058691) Line 411 + 0x15 bytes C++
user32.dll!7e418734()
user32.dll!7e418816()
user32.dll!7e4189cd()
user32.dll!7e418a10()
user32.dll!7e42d99d()
user32.dll!7e43c69b()
mfc80d.dll!CWnd::IsDialogMessageA(tagMSG * lpMsg=0x0013cee0) Line 198 C++
mfc80d.dll!CWnd::PreTranslateInput(tagMSG * lpMsg=0x0013cee0) Line 4268 C++
mfc80d.dll!CDialog::PreTranslateMessage(tagMSG * pMsg=0x0013cee0) Line 80 C++
ProfUIS285nd.dll!CExtWS<CExtADLG<CExtResDlg>,301>::PreTranslateMessage(tagMSG * pMsg=0x0013cee0) Line 622 C++
ProfUIS285nd.dll!CExtResizableDialog::PreTranslateMessage(tagMSG * pMsg=0x0013cee0) Line 593 C++
mfc80d.dll!CWnd::WalkPreTranslateTree(HWND__ * hWndStop=0x00161586, tagMSG * pMsg=0x0013cee0) Line 2882 + 0x14 bytes C++
mfc80d.dll!AfxInternalPreTranslateMessage(tagMSG * pMsg=0x0013cee0) Line 233 + 0x12 bytes C++
mfc80d.dll!CWinThread::PreTranslateMessage(tagMSG * pMsg=0x0013cee0) Line 773 + 0x9 bytes C++
cadwind.exe!gr_event(int * type=0x0013d250, double * x=0x0013d21c, double * y=0x0013d20c, int * outside=0x0013d244, int * buttons=0x0013d238, std::basic_string<char,std::char_traits<char>,std::allocator<char> > & sReturnString="", long * returnparam=0x00000000, int UseResult=0) Line 4087 + 0x22 bytes C++
cadwind.exe!mn_get(const char * prompt=0x0013d418, const menu_def_t * menu=0x0013df60, int * mn_base=0x0013d2c0, int * item_no=0x0013d498, char * * string=0x0013d470, int * valid=0x0013d48c, int contextmenu=0, bool bWantWords=false, int default_number=-1) Line 698 + 0x24 bytes C++
cadwind.exe!mn_get(const char * prompt=0x0013d418, const menu_def_t * menu=0x0013df60, int * mn_base=0x0013d2c0, int * item_no=0x0013d498, char * * string=0x0013d470, int * valid=0x0013d48c, int contextmenu=0, bool bWantWords=false) Line 568 + 0x27 bytes C++
cadwind.exe!mn_select(const char * prompt=0x0013d418, const menu_def_t * menu=0x0013df60, int * item_no=0x0013d498, char * * string=0x0013d470, int * valid=0x0013d48c, int contextmenu=0, bool bWantWords=false) Line 406 + 0x25 bytes C++
cadwind.exe!CWinCadApp::RunTextMenuLoop(CCadApp::nRunMode Mode=ModeMODEL) Line 1322 + 0x2c bytes C++
cadwind.exe!CWinCadApp::RunModelLoop() Line 1260 C++
cadwind.exe!CCadApp::RunMainLoop() Line 325 + 0x12 bytes C++
cadwind.exe!mdmain(int iargc=2, char * * argc=0x04cbe7c8) Line 518 + 0x17 bytes C++
cadwind.exe!CWinCadApp::Run() Line 520 + 0x18 bytes C++
mfc80d.dll!AfxWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00162339, int nCmdShow=1) Line 47 + 0xd bytes C++
cadwind.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00162339, int nCmdShow=1) Line 33 C++
cadwind.exe!__tmainCRTStartup() Line 589 + 0x35 bytes C
cadwind.exe!WinMainCRTStartup() Line 414 C
kernel32.dll!7c816fd7()
|
|
Technical Support
|
Aug 26, 2009 - 5:11 AM
|
The call stack really shows that the WM_LBUTTONUP message is delivered when the WM_LBUTTONUP message is processes. But this is the normal situation. It occurred because some API invocations between ViewTreeCtrl::OnLButtonUp() and CExtTreeCtrl::OnLButtonDown() APIs in the call stack listing caused invocation of the message delivery.
|
|
Robert Webb
|
Aug 26, 2009 - 7:39 PM
|
OK, but the actual problems I’m experiencing are clearly errors. Could you address those? Firstly, I am receiving begin-drag events AFTER button-up events. Standard practice is to end the drag when button-up arrives, which would mean that the drag never ends. Secondly, resizing the window often gets "stuck", where you release the mouse button but it keeps resizing anyway, but only to make it smaller. This frustrates me and users of our software. I have seen the effect in your ribbon bar sample, especially in the debug build (I think just because it slows the program down), so it is not our error. I have reported this several times over many months and never even got a reply to say whether or not you can reproduce it. Thanks, Rob.
|
|
Technical Support
|
Aug 29, 2009 - 4:40 AM
|
Here is the latest source code for the CExtTreeCtrl class:
http://www.prof-uis.com/download/forums/tmp/ExtCommonControls-27-August-2009-for-RobertWebb.zip
Here is the latest source code for the drag-n-drop detection methods:
bool CExtControlBar::stat_DragDetect_ImplStep(
HWND hWnd,
POINT pt,
UINT nUpMessage // = WM_LBUTTONUP
)
{
if( hWnd == NULL || (! ::IsWindow( hWnd ) ) )
return false;
CSize sizeDrag( ::GetSystemMetrics( SM_CXDRAG ), ::GetSystemMetrics( SM_CYDRAG ) );
CRect rc( pt.x - sizeDrag.cx, pt.y - sizeDrag.cy, pt.x + sizeDrag.cx, pt.y + sizeDrag.cy );
::SetCapture( hWnd );
for( MSG _msg; ::IsWindow( hWnd ) ; )
{
for( ;
::IsWindow( hWnd )
&& ( ::PeekMessage( &_msg, hWnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE )
|| ::PeekMessage( &_msg, 0, WM_CANCELMODE, WM_CANCELMODE, PM_NOREMOVE )
|| ::PeekMessage( &_msg, 0, WM_ACTIVATEAPP, WM_ACTIVATEAPP, PM_NOREMOVE )
)
;
)
{
if( _msg.message == nUpMessage
|| _msg.message == WM_CANCELMODE
|| _msg.message == WM_ACTIVATEAPP
)
{
::ReleaseCapture();
return false;
}
::PeekMessage( &_msg, hWnd, _msg.message, _msg.message, PM_REMOVE );
if( _msg.message == WM_MOUSEMOVE )
{
CPoint ptMessage( LOWORD( _msg.lParam ), HIWORD( _msg.lParam ) );
if( ! rc.PtInRect( ptMessage ) )
{
ReleaseCapture();
return true;
}
}
}
::WaitMessage();
}
return false;
}
bool CExtControlBar::stat_DoDragDetect(
HWND hWnd,
const POINT & ptWndClient,
UINT nUpMessage // = WM_LBUTTONUP
)
{
if( hWnd == NULL || (! ::IsWindow( hWnd ) ) )
return false;
CPoint ptScreen = ptWndClient;
::ClientToScreen( hWnd, &ptScreen );
for( ; stat_DragDetect_ImplStep( hWnd, ptScreen, nUpMessage ) ; )
{
POINT ptCursorPos = { -32767, -32767 };
if( ! ::GetCursorPos( &ptCursorPos ) )
return false;
if( ptScreen == ptCursorPos )
continue; //only drag time elapsed but mouse is not moved
return true;
}
return false;
}
We made the several left and right mouse button based drag-n-dropping tests with the ProfUIS_Controls sample application. We set breakpoints at the beginning of the CExtTreeCtrl::OnLButtonUp and CExtTreeCtrl::OnRButtonUp methods in Prof-UIS source code. We used the Tree View dialog page in the ProfUIS_Controls sample application because the CPageTreeCtrl::OnBegindragTree1 and CPageTreeCtrl::OnBeginRdragTree1 methods are displaying message boxes when the TVN_BEGINDRAG and TVN_BEGINRDRAG notifications are sent. The message boxes are displayed always earlier than the debugger breaks at the set breakpoints. It looks like we fixed the window resizing behavior. Please open the source .../Prof-UIS/Src/ExtNcFrame.cpp file and find the WM_ENTERSIZEMOVE text in it. There are two cases. Both code snippets are looking very similar. You will find the following lines in both cases: ::SendMessage( hWnd, WM_ENTERSIZEMOVE, 0L, 0L );
Then you will find the following nested code statements a bit closer from the line above in the both cases: bool bStop = false;
for( ; ! bStop ; )
{
::WaitMessage();
MSG msg;
// Process all the messages in the message queue
while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{
switch( msg.message )
{
The switch( msg.message ) statement contains the following in both cases: case WM_MOUSEMOVE:
::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
if( msg.hwnd == hWnd )
{
while( ::PeekMessage( &msg, hWnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE ) );
The while( ::PeekMessage( &msg, hWnd, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE ) ); line of code should be simply commented/removed in both cases.
|
|
Robert Webb
|
Aug 31, 2009 - 3:03 AM
|
Thanks for the code updates. Unfortunately it doesn’t seem to fix anything. I still get the window frame resizing after the mouse button is up, and clicking quickly on tree items can still cause the up-event to be sent before the begin-drag event. I have worked around the tree problem by setting a flag on mouse-down and clearing it again on mouse-up, then checking that the flag is set in my begin-drag handler. If it’s not set, then the drag is disallowed. I also override OnCaptureChanged() in case my capture was lost while the button was down, meaning I might miss the mouse-up event. You could do a similar thing I imagine to fix both the tree and frame-resizing problems. Aside from the persistant resizing, we also have problems with the frame moving and resizing briefly after releasing the mouse button (to end a move or resize). Our users have to move the mouse slowly to avoid this. I often want to resize the window and quickly move the mouse elsewhere after letting go. This can cause the window to follow my mouse back across the screen before stopping. Very annoying. In this case, I think it probably just handles one extra mouse-move event AFTER the mouse-up event. Maybe it is similar to the other problem, with a mouse-move and mouse-up event being handled below mouse-down in the stack, meaning that mouse-down hasn’t finished being processed before the next mouse-move. Or maybe you are polling the mouse position in mouse-up instead of using the position sent with the event? That always causes problems. Rob.
|
|
Technical Support
|
Sep 1, 2009 - 11:36 AM
|
We solved this issue in Prof-UIS 2.87. Please drop us an e-mail to the support mail box at this web site so we will provide you with the FTP download for the latest Prof-UIS version.
|
|
Robert Webb
|
Sep 14, 2009 - 7:49 PM
|
I’m using 2.8.7 now and don’t see any difference. I haven’t tested the tree stuff since I now have a work-around that works anyway, so maybe that was fixed. But I still have the problem of the window resizing getting stuck, and now also sometimes moving the whole window gets stuck. By stuck I mean that the operation continues to occur after the mouse button has been released. It seems to have lost mouse-capture though, so the resizing only starts up again when you move the mouse back inside the window. It’s quite difficult to get out of this situation when it happens. Even clicking doesn’t always fix it. Getting stuck moving the window is a new one, but that may be due to stuff I’m doing which slows down redraws in the view. The ProfUIS problems seem worst when the view takes some time to redraw. You could probably simulate it by putting a one-second sleep in your MDI ribbon bar sample in the redraw/resize. Getting stuck moving the window happens as follows: I click on the title bar to bring the window to the front (when another window was previously obscuring part of our window). Then, although I just did a quick click and release with no intention of moving the window, the window moves and follows the mouse anyway. Along with the highly CPU-intensive and slow ribbon bar, these are probably the two most frustrating issues. If it’s similar to the issue with tree control events arriving out of order, you could probably fix these by setting a flag on button-down and clearing it on button-up, then testing before any kind of drag operation (ie resizing or moving) and not doing it unless the flag is set. Rob.
|
|
Robert Webb
|
Aug 25, 2009 - 8:53 PM
|
This problem of getting messages out of order reminds me of some of the more fundamental problems with ProfUIS. For example, I’ve often seen the problem where ProfUIS doesn’t realise when you stop resizing the main window. That is, you click on the resizable border, drag it to change the size, then release, but sometimes it keeps resizing anyway. Well, sort of. When it gets stuck in this state, you can move the mouse around outside the window without it resizing, but as soon as you move the mouse inside the window, the window starts resizing smaller again. Very frustrating and hard to escape from. I’ve seen it in our software on multiple machines, and also in ProfUIS’s own ribbon bar samples. I think it’s made worse if the app does other computationally expensive stuff, so it isn’t usually noticable in the ProfUIS samples, although I have seen it several times when running the debug version of the ribbon bar sample. Maybe the debug version is enough slower to make the effect more prevalent. As for our software, it happens all the time. This strikes me as similar because if you get your mouse events out of order, then you can miss the button-up event that should have stopped the window resizing. Could this all be related? Thanks, Rob.
|
|
Robert Webb
|
Aug 21, 2009 - 1:03 AM
|
I noticed another problem with CExtTreeCtrl. The TVN_ITEMEXPANDED notification is not sent when the user expands or collapses an item in the tree. I’m using the Vista icons if that makes a difference. I presume TVN_ITEMEXPANDING is also missing, although I didn’t test that. Note: the TVN_ITEMEXPANDED notification IS sent when ExpandItem() is called in the code, but not when the user manually expands/collapses an item. Thanks, Rob.
|
|
Technical Support
|
Aug 22, 2009 - 11:37 AM
|
Thank you for reporting this issue. Please update the source code for the following method: BOOL CExtTreeCtrl::Expand( HTREEITEM hti, UINT nCode )
{
ASSERT_VALID( this );
HWND hWndOwn = m_hWnd;
if( hWndOwn == NULL || ( ! ::IsWindow( hWndOwn ) ) )
return FALSE;
if( hti == TVI_ROOT )
{
hti = GetRootItem();
if( hti == NULL )
return FALSE;
}
HWND hWndParent = ::GetParent( m_hWnd );
UINT nOwnID = GetDlgCtrlID();
CExtSafeString strItemText;
NM_TREEVIEW _data;
::memset( &_data, 0, sizeof(NM_TREEVIEW) );
_data.hdr.hwndFrom = m_hWnd;
_data.hdr.idFrom = nOwnID;
_data.hdr.code = TVN_ITEMEXPANDING;
_data.action = nCode;
_data.itemOld.mask = TVIF_CHILDREN|TVIF_HANDLE|TVIF_PARAM|TVIF_STATE;
_data.itemOld.hItem = hti;
GetItem( &_data.itemOld );
strItemText = GetItemText( hti );
_data.itemOld.cchTextMax = INT(strItemText.GetLength());
_data.itemOld.pszText = strItemText.IsEmpty() ? _T("") : LPTSTR(LPCTSTR(strItemText));
_data.itemOld.mask |= TVIF_TEXT;
::memcpy( &_data.itemNew, &_data.itemOld, sizeof(TVITEM) );
if( ! ::GetCursorPos( &_data.ptDrag ) )
_data.ptDrag.x = _data.ptDrag.y = 0;
if( ::SendMessage( hWndParent, WM_NOTIFY, WPARAM(nOwnID), LPARAM(&_data) ) != 0 )
return TRUE;
if( ! CTreeCtrl::Expand( hti, nCode ) )
return FALSE;
::memset( &_data, 0, sizeof(NM_TREEVIEW) );
_data.hdr.hwndFrom = m_hWnd;
_data.hdr.idFrom = nOwnID;
_data.hdr.code = TVN_ITEMEXPANDED;
_data.action = nCode;
_data.itemOld.mask = TVIF_CHILDREN|TVIF_HANDLE|TVIF_PARAM|TVIF_STATE;
_data.itemOld.hItem = hti;
GetItem( &_data.itemOld );
strItemText = GetItemText( hti );
_data.itemOld.cchTextMax = INT(strItemText.GetLength());
_data.itemOld.pszText = strItemText.IsEmpty() ? _T("") : LPTSTR(LPCTSTR(strItemText));
_data.itemOld.mask |= TVIF_TEXT;
::memcpy( &_data.itemNew, &_data.itemOld, sizeof(TVITEM) );
if( ! ::GetCursorPos( &_data.ptDrag ) )
_data.ptDrag.x = _data.ptDrag.y = 0;
::SendMessage( hWndParent, WM_NOTIFY, WPARAM(nOwnID), LPARAM(&_data) );
return TRUE;
}
|
|
Technical Support
|
Aug 17, 2009 - 11:46 AM
|
The WM_CREATE message cannot be handled by any dialog controls. The dialog template loading code creates all the dialog’s child windows. Then MFC subclasses them. Please use the PreSubclassWindow() virtual method.
The CExtTreeCtrl control does not support themed scroll bars. The CExtListCtrl does not supports them either. But the CExtNCSB template class can skin scroll bars of common controls. This means you should use the following class:
//
// In .H file:
//
class CAdvTreeCtrl : public CExtNCSB < CExtTreeCtrl >
{
public:
DECLARE_DYNCREATE( CAdvTreeCtrl );
CAdvTreeCtrl();
virtual ~CAdvTreeCtrl();
//{{AFX_VIRTUAL(CAdvTreeCtrl)
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL
protected:
//{{AFX_MSG(CAdvTreeCtrl)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//
// In .CPP file:
//
IMPLEMENT_DYNCREATE( CAdvTreeCtrl, CExtTreeCtrl );
CAdvTreeCtrl::CAdvTreeCtrl()
: CExtNCSB < CExtTreeCtrl > ( true )
{
}
CAdvTreeCtrl::~CAdvTreeCtrl()
{
}
BEGIN_MESSAGE_MAP( CAdvTreeCtrl, CExtTreeCtrl )
//{{AFX_MSG_MAP(CAdvTreeCtrl)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CAdvTreeCtrl::PreSubclassWindow()
{
CExtNCSB < CExtTreeCtrl > :: PreSubclassWindow();
//
// TO-DO: put your tree control initialization code here
//
}
|
|
Robert Webb
|
Aug 18, 2009 - 1:30 AM
|
Thanks. One remaining problem with CExtTreeCtrl is that SelectItem() now seems to leave the previous item selected as well, even though the tree has multiple selection disabled. Surely when multi-select is disabled, SelectItem() should deselect any other items before doing the selection? Otherwise it’s incompatible with CTreeCtrl. I notice the new method FocusItem(), which allows all other items to be deselected. I’ll try that, although I’m not sure what additional side-effects giving focus to an item might have beyond just selecting it. Thanks, Rob.
|
|
Technical Support
|
Aug 18, 2009 - 12:46 PM
|
Thank you for reporting this issue. Please update the source code for the CExtTreeCtrl::SelectItem() method:
void CExtTreeCtrl::SelectItem(
HTREEITEM hti,
bool bSelect, // = true
bool bSubtract // = false
)
{
ASSERT_VALID( this );
if( hti == NULL )
return;
TREEITEMINFO_t & _TII = TreeItemInfoGet( hti );
if( bSelect && bSubtract && _TII.m_bSelected )
_TII.m_bSelected = false;
else
_TII.m_bSelected = bSelect;
if( _TII.m_bSelected && (! MultipleSelectionGet() ) )
{
CList < HTREEITEM, HTREEITEM > _listSelectedItems;
GetSelectedItemsList( _listSelectedItems );
POSITION pos = _listSelectedItems.GetHeadPosition();
for( ; pos != NULL; )
{
HTREEITEM htiSel = _listSelectedItems.GetNext( pos );
if( htiSel == hti )
continue;
TREEITEMINFO_t & _TII_Sel = TreeItemInfoGet( htiSel );
_TII_Sel.m_bSelected = false;
}
}
}
|
|
Robert Webb
|
Aug 19, 2009 - 2:30 AM
|
Thanks. There still seem to be some issues though: (1) After calling SelectItem() the tree is not redrawn, so the old selection appears to remain selected until it redraws for another reason. (2) The focus rectangle is still visible around the previously selected item. What is this for? Is it at all relevant in a single-selection tree? It’s visually confusing to have one item highlighted and another with a rectangle around it in a tree that only allows a single item to be selected. Thanks, Rob.
|
|
Technical Support
|
Aug 19, 2009 - 2:32 PM
|
Here is the updated CExtTreeCtrl::SelectItem() method:
void CExtTreeCtrl::SelectItem(
HTREEITEM hti,
bool bSelect, // = true
bool bSubtract // = false
)
{
ASSERT_VALID( this );
if( hti == NULL )
return;
HWND hWndOwn = GetSafeHwnd();
TREEITEMINFO_t & _TII = TreeItemInfoGet( hti );
bool bWasSelected = _TII.m_bSelected;
if( bSelect && bSubtract && _TII.m_bSelected )
_TII.m_bSelected = false;
else
_TII.m_bSelected = bSelect;
CList < HTREEITEM, HTREEITEM > _listInvalidateItems;
if( _TII.m_bSelected && (! MultipleSelectionGet() ) )
{
CList < HTREEITEM, HTREEITEM > _listSelectedItems;
GetSelectedItemsList( _listSelectedItems );
POSITION pos = _listSelectedItems.GetHeadPosition();
for( ; pos != NULL; )
{
HTREEITEM htiSel = _listSelectedItems.GetNext( pos );
if( htiSel == hti )
continue;
TREEITEMINFO_t & _TII_Sel = TreeItemInfoGet( htiSel );
_TII_Sel.m_bSelected = false;
if( hWndOwn != NULL )
_listInvalidateItems.AddTail( htiSel );
}
}
if( hWndOwn == NULL || (! IsWindowVisible() ) )
return;
if( ( bWasSelected && (!_TII.m_bSelected) ) || ( (!bWasSelected) && _TII.m_bSelected ) )
_listInvalidateItems.AddTail( hti );
POSITION pos = _listInvalidateItems.GetHeadPosition();
if( pos == NULL )
return;
CRect rcClient, rcItemEntire;
GetClientRect( &rcClient );
for( ; pos != NULL; )
{
HTREEITEM htiRedraw = _listInvalidateItems.GetNext( pos );
TreeItemRectGet( htiRedraw, rcItemEntire, e_tirt_entire );
if( rcItemEntire.IsRectEmpty() )
continue;
if( ( rcClient.top <= rcItemEntire.top && rcItemEntire.top <= rcClient.bottom )
|| ( rcClient.top <= rcItemEntire.bottom && rcItemEntire.bottom <= rcClient.bottom )
)
InvalidateRect( &rcItemEntire );
}
}
Now it repaints changed selection. But we cannot make it exactly similar to the CTreeCtrl::SelectItem() method because the focus and selection are two different features in the CExtTreeCtrl control. We did several other improvements in the tree control: http://www.prof-uis.com/download/forums/tmp/UpdatedExtTreeCtrl-For-RobertWebb.zip
|
|
Technical Support
|
Aug 14, 2009 - 1:00 PM
|
|
|
Robert Webb
|
Aug 16, 2009 - 7:26 PM
|
Thanks. There’s a compile error though: ..\Src\ExtControlsCommon.cpp(5077) : error C2660: ’CExtControlBar::stat_DoDragDetect’ : function does not take 3 arguments Do I need the new version of ExtControlBar.cpp/h too? Thanks, Rob.
|
|
Technical Support
|
Aug 17, 2009 - 11:45 AM
|
The CExtControlBar::stat_DoDragDetect() static method is a better version of the DragDetect() Win32 API. Now this static method supports drag-n-drop starting detection by any mouse button - not only by left mouse button:
static bool stat_DragDetect_ImplStep(
HWND hWnd,
POINT pt,
UINT nUpMessage = WM_LBUTTONUP
);
static bool stat_DoDragDetect(
HWND hWnd,
const POINT & ptWndClient,
UINT nUpMessage = WM_LBUTTONUP
);
bool CExtControlBar::stat_DragDetect_ImplStep(
HWND hWnd,
POINT pt,
UINT nUpMessage // = WM_LBUTTONUP
)
{
if( hWnd == NULL || (! ::IsWindow( hWnd ) ) )
return false;
CSize sizeDrag( ::GetSystemMetrics( SM_CXDRAG ), ::GetSystemMetrics( SM_CYDRAG ) );
CRect rc( pt.x - sizeDrag.cx, pt.y - sizeDrag.cy, pt.x + sizeDrag.cx, pt.y + sizeDrag.cy );
::SetCapture( hWnd );
for( MSG _msg; ::IsWindow( hWnd ) ; )
{
for( ; ::IsWindow( hWnd ) && ::PeekMessage( &_msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE ) ; )
{
if( _msg.message == nUpMessage
|| _msg.message == WM_CANCELMODE
|| _msg.message == WM_ACTIVATEAPP
)
{
::ReleaseCapture();
return false;
}
if( _msg.message == WM_MOUSEMOVE )
{
CPoint ptMessage( LOWORD( _msg.lParam ), HIWORD( _msg.lParam ) );
if( ! rc.PtInRect( ptMessage ) )
{
ReleaseCapture();
return true;
}
}
}
::WaitMessage();
}
return false;
}
bool CExtControlBar::stat_DoDragDetect(
HWND hWnd,
const POINT & ptWndClient,
UINT nUpMessage // = WM_LBUTTONUP
)
{
if( hWnd == NULL || (! ::IsWindow( hWnd ) ) )
return false;
CPoint ptScreen = ptWndClient;
::ClientToScreen( hWnd, &ptScreen );
for( ; stat_DragDetect_ImplStep( hWnd, ptScreen, nUpMessage ) ; )
{
POINT ptCursorPos = { -32767, -32767 };
if( ! ::GetCursorPos( &ptCursorPos ) )
return false;
if( ptScreen == ptCursorPos )
continue; //only drag time elapsed but mouse is not moved
return true;
}
return false;
}
|
|
Robert Webb
|
Aug 17, 2009 - 2:17 AM
|
I tried just removing the third argument in the call to stat_DoDragDetect() and it seems to be working. Is that a safe work-around? Will it cause any problems with drag/drop when I get to that? There are two remaining problems with using CExtTreeCtrl now: (1) For some reason, I can’t get OnCreate() to be called in my class derived from CExtTreeCtrl. I added ON_WM_CREATE() to the message map, and my function header is copy/pasted from the MSDN docs: int CAdvTreeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) Any idea why it wouldn’t be getting called in this case? What I want to do is call LoadWinVistaTreeBox() and TreeBoxStyleSet(CExtTreeCtrl::tree_box_style_bitmap) so that these are the default for all my tree controls. Maybe there is a better way to do this? (2) The tree’s scroll bars are still old-style un-themed. The ProfUIS Controls demo shows a tree with a nice new themed scroll bar. Do I have to do something to make it use these? Thanks, Rob.
|
|
Robert Hofstetter
|
Aug 13, 2009 - 1:27 AM
|
Does Prof-UIS compile with Windows Server 2003 Platform SDK (the latest Platform SDK comptiable with Visual C++ 6.0)? My Visual C++ 6.0 project was statically linked to Prof-UIs 2.85 and compiled without any problems. But it does not complie when I started using the Window Platform SDK in my project. The errors are: Compiling...
StdAfx.cpp
Prof-UIS multiple monitor support:
built-in
Automatically linking with Prof-UIS library: ProfUIS285ymd.lib
(Professional User Interface Suite)
c:\program files\microsoft visual studio\vc98\include\transact.h(226) : error C2059: syntax error : ’constant’
c:\program files\microsoft visual studio\vc98\include\transact.h(271) : error C2143: syntax error : missing ’;’ before ’}’
c:\program files\microsoft visual studio\vc98\include\oledb.h(17149) : error C2143: syntax error : missing ’;’ before ’}’
c:\program files\microsoft visual studio\vc98\include\oledb.h(17149) : error C2143: syntax error : missing ’;’ before ’}’
c:\program files\microsoft visual studio\vc98\include\oledb.h(17149) : error C2143: syntax error : missing ’;’ before ’}’ Any suggestions? Regards Robert
|
|
Technical Support
|
Aug 14, 2009 - 11:58 AM
|
This is the easiest solution. The Prof-UIS source code does not need to be modified in this case. Then you can include only newer headers the new Platform SDK into your project. But this solution is not always can be applied. The Platform SDKs are often funny. For instance, the OLE automation APIs often contain the same functions with the same names but with larger parameter counts. This will require modification of Prof-UIS source code. We can make Prof-UIS compatible with Platform SDK 2003, but it will become incompatible with all the supported Visual C++ versions without installing appropriate Platform SDK additionally. We already did similar work several times by customer requests. The fix is simple but it can be different for different Platform SDKs. Only the ...\Prof-UIS\Include\Prof-UIS.h file needs to be modified. In some cases there is enough to add the #include < atlbase.h > line of code. In other cases we need to include particular Platform SDK header files. For instance, you encountered error in the transact.h file. This means you should try to include this file into the ...\Prof-UIS\Include\Prof-UIS.h file. If this does not solves problem, then you should find other Platform SDK’s header files which include the transact.h file and try to include other files into the ...\Prof-UIS\Include\Prof-UIS.h file.
|
|
Technical Support
|
Aug 14, 2009 - 11:58 AM
|
This is the easiest solution. The Prof-UIS source code does not need to be modified in this case. Then you can include only newer headers the new Platform SDK into your project. But this solution is not always can be applied. The Platform SDKs are often funny. For instance, the OLE automation APIs often contain the same functions with the same names but with larger parameter counts. This will require modification of Prof-UIS source code. We can make Prof-UIS compatible with Platform SDK 2003, but it will become incompatible with all the supported Visual C++ versions without installing appropriate Platform SDK additionally. We already did similar work several times by customer requests. The fix is simple but it can be different for different Platform SDKs. Only the ...\Prof-UIS\Include\Prof-UIS.h file needs to be modified. In some cases there is enough to add the #include < atlbase.h > line of code. In other cases we need to include particular Platform SDK header files. For instance, you encountered error in the transact.h file. This means you should try to include this file into the ...\Prof-UIS\Include\Prof-UIS.h file. If this does not solves problem, then you should find other Platform SDK’s header files which include the transact.h file and try to include other files into the ...\Prof-UIS\Include\Prof-UIS.h file.
|
|
Robert Hofstetter
|
Aug 13, 2009 - 6:08 PM
|
That’s not a solution. I need to use the Windows SDK in my project thus have to keep the Platform SDK include folders before Visual C++ include folders. Otherwise, my project will not compile. I tried to open the ProfUISLIB_600.dsw and build the Prof-Uis static lib manually (without using integration wizard) and had the same errors. Does that mean Prof-Uis can not work with Windows Platfrom SDK?
|
|
Technical Support
|
Aug 13, 2009 - 12:53 PM
|
It will compile ok if you move the Platform SDK include folders to the bottom of the include folders list in you Visual C++ settings.
|
|
Robert Hofstetter
|
Aug 13, 2009 - 6:10 PM
|
Sorry. Should reply yours here. That’s not a solution. I need to use the Windows SDK in my project thus have to keep the Platform SDK include folders before Visual C++ include folders. Otherwise, my project will not compile. I tried to open the ProfUISLIB_600.dsw and build the Prof-Uis static lib manually (without using integration wizard) and had the same errors. Does that mean Prof-Uis can not work with Windows Platfrom SDK?
|
|
Peter Meier
|
Aug 10, 2009 - 6:55 AM
|
Hi How is it possible to label a CExtBarButton or a CExtBarColorButton so that it would i.e diaplay "Pattern:" or "Color:" left of it? Thanks - Peter
|
|
Technical Support
|
Aug 10, 2009 - 7:42 AM
|
It’s possible to implement your CExtBarButton -derived and/or CExtBarButton -derived classes which implement custom measuring/painting. But it’s easier to insert the CExtBarLabelButton toolbar buttons before other buttons. You can insert any type of toolbar button into toolbar using the CExtToolControlBar::InsertSpecButton() method. But the preferred solution is the following:
1) Create and use your CExtToolControlBar -derived class.
2) Define additional buttons in toolbar resource for the label buttons. The icon image is not important and can display anything.
3) Implement the CExtToolControlBar::OnCreateBarCommandBtn() virtual method in CExtToolControlBar -derived class. Your method should instantiate the CExtBarLabelButton objects for label buttons and invoke the parent class method for other buttons.
This approach can be used for instantiating any non-push buttons in toolbar, including color picker buttons. Please note, the label buttons are displaying command’s toolbar text stored in the command manager. I.e. they display the same text as the CExtBarButton toolbar push/command buttons can display. You should invoke the following code to assign toolbar button text:
g_CmdManager->CmdGetPtr( . . . )->m_sToolbarText = _T("text in toolbar");
|
|
Martin Ashton
|
Aug 9, 2009 - 9:35 PM
|
Hi, I have embedded a CExtZoomScrollBar in a CMainFrame’s status bar. The CMainFrame is derived from CExtNCW<CFrameWnd> and it’s status bar from CExtStatusControlBar. The result looks great and is just what I want but I am not getting any ON_WM_HSCROLL messages via the CMainFrame’s message map. I derived the code from your ZoomScrollBar example. I noticed that in the example you embed the CExtZoomScollBar in a ChildView’s status bar. I replaced CMainFrame * pMainFrame = _GetMainFrame(); with CMainFrame * pMainFrame = this; Could this be the cause of the problem? Your help with this is much appreciated. Rgds, Martin Ashton
|
|
Technical Support
|
Aug 10, 2009 - 6:21 AM
|
The zoom scroll bar control is based on the standard scroll bar common control. All the command controls always send notification messages to their parent window. So, your CExtZoomScrollBar zoom scroll bar sends the WM_HSCROLL messages to its parent CExtStatusControlBar status bar window. The ZoomScrollBar sample application has the CMainFrame::CMyStatusBar status bar class which is defined locally in the scope of the CMainFrame class:
class CMyStatusBar : public CExtStatusControlBar
{
protected:
virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
{
if( message == WM_HSCROLL || message == WM_VSCROLL )
return GetParent()->GetDlgItem(AFX_IDW_PANE_FIRST)->SendMessage( message, wParam, lParam );
return CExtStatusControlBar::WindowProc( message, wParam, lParam );
}
}; // class CMyStatusBar
As you can see, the WindowProc() virtual method simply redirects the scrolling messages to the child window of the main frame. This child window has the AFX_IDW_PANE_FIRST standard dialog control identifier. This child window is the view window in SDI frame based applications. The CFrameWnd class automatically detects its child window with the AFX_IDW_PANE_FIRST dialog control identifier and resizes it to cover entire center area of the frame which is free of any control bars placed near the frame borders. The view window inside the SDI frame window always have the AFX_IDW_PANE_FIRST dialog control identifier. You can redirect the scrolling messages to main frame window instead of view: class CMyStatusBar : public CExtStatusControlBar
{
protected:
virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
{
if( message == WM_HSCROLL || message == WM_VSCROLL )
return GetParentFrame()->SendMessage( message, wParam, lParam );
return CExtStatusControlBar::WindowProc( message, wParam, lParam );
}
}; // class CMyStatusBar
|
|
tera tera
|
Aug 8, 2009 - 2:08 AM
|
Hello. The background color of the point of the red arrow is dark.
It is hard to look.
I want to display it with a bright color. Or can you change it by the setting of this place?
|
|
Technical Support
|
Aug 10, 2009 - 1:41 PM
|
Please update the source code for the following method: void CExtPaintManager::Ribbon_PaintPushButton(
CDC & dc,
CExtPaintManager::PAINTPUSHBUTTONDATA & _ppbd
)
{
ASSERT_VALID( this );
ASSERT( dc.GetSafeHdc() != NULL );
if( _ppbd.m_rcClient.IsRectEmpty() )
return;
if( ! dc.RectVisible( &_ppbd.m_rcClient ) )
return;
ASSERT_VALID( _ppbd.m_pHelperSrc );
CExtBarButton * pTBB = DYNAMIC_DOWNCAST( CExtBarButton, _ppbd.m_pHelperSrc );
ASSERT( pTBB != NULL );
CExtBarButton * pParentTBB = pTBB->ParentButtonGet();
CExtRibbonButton * pRibbonTBB = DYNAMIC_DOWNCAST( CExtRibbonButton, _ppbd.m_pHelperSrc );
CExtSafeString strText = pTBB->GetText();
INT nTextLength = strText.GetLength();
enum e_layout_case_t { __ELC_TOOL, __ELC_SMALL, __ELC_LARGE, };
e_layout_case_t eLC = __ELC_TOOL;
if( pRibbonTBB != NULL )
{
if( pParentTBB == NULL || pParentTBB->IsKindOf( RUNTIME_CLASS( CExtRibbonButtonToolGroup ) ) )
{
if( pParentTBB == NULL )
{
const CExtRibbonNode * pRibbonNode = pTBB->Ribbon_GetNode();
if( pRibbonNode != NULL )
{
const CExtCustomizeCmdTreeNode * pParentNode = pRibbonNode->GetParentNode();
if( pParentNode != NULL
&& ( pParentNode->IsKindOf( RUNTIME_CLASS( CExtRibbonNodeRightButtonsCollection ) )
|| pParentNode->IsKindOf( RUNTIME_CLASS( CExtRibbonNodeQuickAccessButtonsCollection ) )
)
)
eLC = __ELC_SMALL;
}
}
}
else
{
if( pRibbonTBB->RibbonILV_Get() == __EXT_RIBBON_ILV_SIMPLE_LARGE )
eLC = __ELC_LARGE;
else
eLC = __ELC_SMALL;
}
}
else
{
if( pParentTBB == NULL || ( ! pParentTBB->IsKindOf( RUNTIME_CLASS( CExtRibbonButtonToolGroup ) ) ) )
eLC = __ELC_SMALL;
}
INT nILV = pTBB->RibbonILV_Get();
CRect rcCP = pTBB->OnRibbonGetContentPadding();
CRect rcIcon = _ppbd.m_rcClient;
rcIcon.DeflateRect( rcCP.left, rcCP.top, rcCP.right, rcCP.bottom );
INT nTextToIconDistance = 0;
CRect rcText = rcIcon;
CSize _sizeIcon( 0, 0 );
CExtCmdIcon * pCmdIcon = pTBB->GetIconPtr();
if( pCmdIcon != NULL && (! pCmdIcon->IsEmpty() ) )
{
_sizeIcon = Ribbon_GetIconSize( pTBB, nILV, _ppbd.m_lParam );
if( nTextLength >= 0 )
nTextToIconDistance = Ribbon_GetTextToIconDistance( dc, nILV, pTBB, _ppbd.m_lParam );
if( eLC == __ELC_LARGE )
{
rcIcon.bottom = rcIcon.top + _sizeIcon.cy;
rcIcon.OffsetRect( ( rcIcon.Width() - _sizeIcon.cx ) / 2, 4 );
if( nTextLength > 0 )
{
rcText.top = rcIcon.bottom;
rcText.top += nTextToIconDistance;
};
}
else
{
if( nTextLength > 0 )
{
rcIcon.right = rcText.left = rcIcon.left + _sizeIcon.cx;
rcText.left += nTextToIconDistance;
}
else
{
rcIcon = _ppbd.m_rcClient;
if( pTBB->IsAbleToTrackMenu() && (! pTBB->IsKindOf( RUNTIME_CLASS( CExtRibbonButtonGroup ) ) ) )
rcIcon.right -= GetDropDownButtonWidth( _ppbd.m_pHelperSrc, _ppbd.m_lParam );
rcIcon.OffsetRect( ( rcIcon.Width() - _sizeIcon.cx ) / 2 + 1, 0 );
}
rcIcon.OffsetRect( 0, ( rcIcon.Height() - _sizeIcon.cy ) / 2 );
}
}
else
pCmdIcon = NULL;
bool bDrawDropDownWithText = _ppbd.m_bDropDown;
switch( eLC )
{
case __ELC_TOOL:
{
bDrawDropDownWithText = false;
PAINTPUSHBUTTONDATA _ppbd2 = _ppbd;
_ppbd2.m_pHelperSrc = NULL;
_ppbd2.m_pIcon = NULL;
_ppbd2.m_sText = _T("");
_ppbd2.m_bTransparentBackground = false;
_ppbd2.m_bFlat = false;
if( ! ( _ppbd2.m_bHover || _ppbd2.m_bPushed || _ppbd2.m_bIndeterminate ) )
_ppbd2.m_clrForceBk = GetColor( CLR_3DFACE_OUT, _ppbd2.m_pHelperSrc, _ppbd2.m_lParam );
PaintPushButton( dc, _ppbd2 );
if( _ppbd2.m_bDropDown )
rcIcon.OffsetRect( _ppbd.m_rcClient.left - rcIcon.left + 5, 0 );
}
break;
case __ELC_LARGE:
ASSERT_VALID( pTBB );
rcText = Ribbon_CalcLargeDropDownRect( pTBB );
if( ! pTBB->IsKindOf( RUNTIME_CLASS( CExtRibbonButton ) ) )
bDrawDropDownWithText = false;
case __ELC_SMALL:
{
if( _ppbd.m_bEnabled && ( _ppbd.m_bHover || _ppbd.m_bPushed || _ppbd.m_bIndeterminate ) )
{
PAINTPUSHBUTTONDATA _ppbd2 = _ppbd;
_ppbd2.m_pHelperSrc = NULL;
_ppbd2.m_pIcon = NULL;
_ppbd2.m_sText = _T("");
_ppbd2.m_bTransparentBackground = false;
_ppbd2.m_bNoDropDownArrow = true;
bool bDrawSepH = false;
if( eLC == __ELC_LARGE )
{
_ppbd2.m_bDropDown = false;
_ppbd2.m_bSeparatedDropDown = false;
_ppbd2.m_bPushedDropDown = false;
bDrawSepH = _ppbd.m_bDropDown && _ppbd.m_bSeparatedDropDown;
}
_ppbd2.m_bFlat = true;
PaintPushButton( dc, _ppbd2 );
if( bDrawSepH )
{
CRect rcSepH = rcText;
rcSepH.bottom = rcSepH.top + 3;
rcSepH.DeflateRect( 3, 0, 2, 0 );
PaintSeparator( dc, rcSepH, false, true, NULL );
}
}
}
break;
}
if( pCmdIcon != NULL )
{
ASSERT( ! pCmdIcon->IsEmpty() );
CSize _sizeRealIcon = pCmdIcon->GetSize();
if( _sizeRealIcon != _sizeIcon )
rcIcon.OffsetRect( ( _sizeIcon.cx - _sizeRealIcon.cx ) / 2, ( _sizeIcon.cy - _sizeRealIcon.cy) / 2 );
rcIcon.right = rcIcon.left + _sizeRealIcon.cx;
rcIcon.bottom = rcIcon.top + _sizeRealIcon.cy;
CExtCmdIcon::e_paint_type_t ePT = CExtCmdIcon::__PAINT_DISABLED;
if( _ppbd.m_bEnabled )
{
if( _ppbd.m_bPushed )
ePT = CExtCmdIcon::__PAINT_PRESSED;
else if( _ppbd.m_bHover )
ePT = CExtCmdIcon::__PAINT_HOVER;
else
ePT = CExtCmdIcon::__PAINT_NORMAL;
}
pCmdIcon->Paint( this, dc.m_hDC, rcIcon, ePT );
}
if( nTextLength > 0 || _ppbd.m_bDropDown )
{
UINT nDT = 0;
if( eLC != __ELC_LARGE )
{
strText.Replace( _T("\r"), _T(" ") );
strText.Replace( _T("\n"), _T(" ") );
strText.Replace( _T("\t"), _T(" ") );
strText.Replace( _T(" "), _T(" ") );
strText.TrimLeft( _T(" ") );
strText.TrimRight( _T(" ") );
nTextLength = INT( strText.GetLength() );
nDT = DT_CENTER|DT_VCENTER|DT_SINGLELINE;
}
else
nDT = DT_CENTER|DT_TOP;
if( nTextLength > 0 || _ppbd.m_bDropDown )
{
CFont * pFont = pTBB->GetBar()->OnGetToolbarFont( false, false );
ASSERT( pFont->GetSafeHandle() != NULL );
CFont * pOldFont = dc.SelectObject( pFont );
int nOldBkMode = dc.SetBkMode( TRANSPARENT );
COLORREF clrText = GetColor( _ppbd.m_bEnabled ? COLOR_BTNTEXT : CLR_TEXT_DISABLED );
COLORREF clrOldText = dc.SetTextColor( clrText );
Ribbon_PaintText(
dc, ( nTextLength > 0 ) ? LPCTSTR(strText) : _T(""), rcText, nDT,
bDrawDropDownWithText, NULL, _ppbd.m_pHelperSrc, _ppbd.m_lParam
);
dc.SetTextColor( clrOldText );
dc.SetBkMode( nOldBkMode );
dc.SelectObject( pOldFont );
}
}
}
|
|
Antonio Pelli Neto
|
Aug 7, 2009 - 3:06 PM
|
Hi I’m facing a big problem trying to include the RibbonNodeFile in the Formula Grid Sample. I tried everything including copying the example from RibbonBars, but it didn’t work. I’m moving from CodeJock to Prof-UIS, but the help really didn’t help me. Pelli
|
|
Antonio Pelli Neto
|
Aug 10, 2009 - 8:54 PM
|
Hello, Thank you for the information. It worked. Best regards, Pelli
|
|
Technical Support
|
Aug 10, 2009 - 6:20 AM
|
The FormulaGrid sample application demonstrates a simplified ribbon bar layout without the ribbon file button (a.k.a. application button). Some applications does not require rich and big ribbon file menu and we just used the FormulaGrid sample application to demonstrate such ribbon bar layout. The CMyRibbonBar class in this sample application have the following implementations of the ribbon bar’s virtual methods:
virtual bool Ribbon_FileButtonInit() { return false; }
bool RibbonLayout_IsFrameIntegrationEnabled() const { return false; }
If you want to initialize the ribbon file menu, then you should remove these virtual methods from the CMyRibbonBar class. Then you should initialize the ribbon file button like the RibbonBar sample application does.
|
|
tera tera
|
Aug 6, 2009 - 7:18 PM
|
Hello. My program became gigantic.
It is necessary to appoint /Zm500.
If there is not optional appointment, it is not possible for build. However, I appoint /Zm1000 and build.
Then the following build error comes. Fatal Error C1060
http://msdn.microsoft.com/ja-jp/library/cc396351.aspx The memory capacity of the PC.
Main memory 1GB.
Virtual memory 8GB. Why does this happen?
I do not understand causes well.
|
|
Technical Support
|
Aug 10, 2009 - 6:19 AM
|
The /Zm compiler options specifies how much memory should compiler allocate for compiling a .CPP file. Prof-UIS library becomes enough large and the default amount of memory allocated by the C++ compiler of any supported Visual C++ version is not enough. The /Zm200 option solves this problem. But we used the /Zm512 option because of two reasons: we would like to avoid the compiler’s "not enough memory" problem in the future and the 512 megabytes can be allocated successfully by the C++ compiler when running on the most of computers. The theoretical limit of memory which can be allocated by the 32-bit application is 4 gigabytes. But compilers may have internal implementation limits which does not allow to allocate even 1 gigabyte.
|
|
tera tera
|
Aug 6, 2009 - 6:29 PM
|
|
|