Subject |
Author |
Date |
|
Andrew Banks
|
Sep 19, 2007 - 10:27 AM
|
How can I scroll an entire tab right or left when clicking the right and left scroll buttons on the mid tabs. Currently, it scrolls some small number of pixles.
|
|
Technical Support
|
Sep 20, 2007 - 8:40 AM
|
Yes, you are right. We changed our code as you suggested. Thank you.
|
|
Technical Support
|
Sep 19, 2007 - 12:05 PM
|
You should apply the __ETWS_SCROLL_BY_PAGE tab window style by using the CExtTabWnd::ModifyTabWndStyle() method.
|
|
Andrew Banks
|
Sep 19, 2007 - 3:52 PM
|
OK I tired that and I couldn’t get it to work.
Correctly, the code hit the CExtTabWnd::OnTimer with a scroll value of m_nScrollDirectionRest=301 that should have ontimer continue until nScrollDirectionRest reached zero at which the timer is killed.
But, then for some reason immediately
void CExtTabWnd::OnCancelMode() { CWnd::OnCancelMode();
if( m_nScrollDirectionRest != 0 ) { m_nScrollDirectionRest = 0; KillTimer( __EXTTAB_SCROLL_TIMER_ID ); }
OnTabWndMouseTrackingPushedStop( true ); OnTabWndMouseTrackingHoverStop( true ); }
is called, ( I didn’t do it) and the timer is killed and does not complete the entire scroll for the whole tab.
|
|
Andrew Banks
|
Sep 19, 2007 - 4:00 PM
|
OK, now I see what happened., CExtTabWnd::OnLButtonUp eventually calls CExtTabWnd::OnCancelMode() and cancels the timer which should not be canceled .
I think the code should be:
void CExtTabWnd::OnCancelMode() { CWnd::OnCancelMode();
if ( ( GetTabWndStyle() & __ETWS_SCROLL_BY_PAGE ) == 0 ) { if ( m_nScrollDirectionRest != 0 ) { m_nScrollDirectionRest = 0; KillTimer( __EXTTAB_SCROLL_TIMER_ID ); } }
OnTabWndMouseTrackingPushedStop( true ); OnTabWndMouseTrackingHoverStop( true ); }
|
|
David Skok
|
Sep 19, 2007 - 9:29 AM
|
Is it possible to set the indent of CExtTreeGrid items?
Thanks, Dave
|
|
Technical Support
|
Sep 19, 2007 - 12:03 PM
|
There is a CExtTreeGridWnd::OnGbwAdjustRects() virtual method in which the summary indent of each row is calculated. This summary indent includes the indent of the row and indents of its parent rows. The HTREEITEM row handle actually corresponds to the CExtTreeGridCellNode* pointer. You can set a unique indent for each tree row in pixels by invoking the CExtTreeGridCellNode::TreeNodeIndentPxSet() method.
|
|
Debabrata Mukherjee
|
Sep 19, 2007 - 8:56 AM
|
When I close the controlbar using the "X" (close) button, then by default it opens up... on ShowControlBar(SW_SHOW). This I dont want, I want the user to open it from a menu option only if the "X" has been pressed as that means that the user doesnt want the controlbar at all and not just hide it to resurface again....
Can I handle the "X" of a CExtToolControlBar. Please suggest as its very urgent.
|
|
Debabrata Mukherjee
|
Sep 20, 2007 - 8:34 AM
|
Hi,
This is my current implementation. I want to call the OnNcAreaClicked() method when i close the control bar.
class CSaControlToolBar : public CExtToolControlBar { public: // Construction CSaControlToolBar(); virtual void OnNcAreaButtonsReinitialize() { CExtToolControlBar::OnNcAreaButtonsReinitialize(); } virtual CExtBarNcAreaButtonClose OnNcAreaClicked() { AfxMessageBox("Hi"); return NULL; } }; Can you please help me regarding this.
|
|
Suhai Gyorgy
|
Sep 20, 2007 - 8:48 AM
|
This might work, though I didn’t try: class CSaControlToolBar : public CExtToolControlBar
{
class CSaBarNcAreaButtonClose : public CExtBarNcAreaButtonClose
{
public:
CSaBarNcAreaButtonClose(CExtControlBar * pBar) : CExtBarNcAreaButtonClose( pBar ) {}
virtual bool OnNcAreaClicked( CPoint point )
{
AfxMessageBox("Hi");
return CExtBarNcAreaButtonClose::OnNcAreaClicked(point);
}
}; // class CSaBarNcAreaButtonClose
virtual void OnNcAreaButtonsReinitialize()
{
ASSERT_VALID( this );
INT nCountOfNcButtons = NcButtons_GetCount();
if( nCountOfNcButtons > 0 )
return;
NcButtons_Add( new CSaBarNcAreaButtonClose(this) );
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
NcButtons_Add( new CExtBarNcAreaButtonAutoHide(this) );
#endif
NcButtons_Add( new CExtBarNcAreaButtonMenu(this) );
}
}; // class CSaControlToolBar
|
|
Suhai Gyorgy
|
Sep 20, 2007 - 1:56 AM
|
|
|
Suhai Gyorgy
|
Sep 19, 2007 - 4:22 AM
|
Dear Support,
I’ve experienced some painting problem in our grid, and I could successfully reproduce it in your ProfUIS_Controls sample. Please, open your PageGrid.cpp. In OnInitDialog, comment the line m_wndGrid.GridLinesHorzSet( true, bRedraw ); ( I don’t want to show any gridlines, but to reproduce the problem, removing horizontal gridlines is enough ) and in SiwModifyStyle call, change __EGBS_SFB_CELLS style to __EGBS_SFB_FULL_ROWS style ( I need to achieve fullrow selection ).
With these 2 changes the focus rect around the focused row is somehow thicker than before. This wouldn’t be a problem, but if the user opens any popup control from the grid ( e.g. color selection control or listbox of a combobox cell), the focus rect gets partially hidden by this control and when the popup control gets closed, the part of the focus rect (which was painted over by the popup control) is not repainted.
Unfortunately I can’t provide a picture now, I hope you understand, or at least can reproduce the problem.
Thank you, Chris
|
|
Technical Support
|
Sep 19, 2007 - 12:23 PM
|
Thank you for reporting the problem. We will fix it as soon as possible.
|
|
Paul Cowan
|
Sep 18, 2007 - 12:15 PM
|
How do I get a grid to select a cell on a right click?
|
|
Paul Cowan
|
Sep 19, 2007 - 7:15 AM
|
|
|
Suhai Gyorgy
|
Sep 19, 2007 - 1:52 AM
|
I did it with a code similar to this: bool CMyGridWnd::OnGbwAnalyzeCellMouseClickEvent(
UINT nChar, // VK_LBUTTON, VK_RBUTTON or VK_MBUTTON only
UINT nRepCnt, // 0 - button up, 1 - single click, 2 - double click, 3 - post single click & begin editing
UINT nFlags, // mouse event flags
CPoint point // mouse pointer in client coordinates
)
{
if ( CExtGridWnd::OnGbwAnalyzeCellMouseClickEvent( nChar, nRepCnt, nFlags, point ) )
return true;
CExtGridHitTestInfo htInfo( point );
HitTest( htInfo, false, true );
if( !htInfo.IsHoverEmpty() && nChar == VK_RBUTTON && nRepCnt == 1 && ( nFlags & (MK_SHIFT|MK_CONTROL) ) == 0 )
{
SelectionSet( CPoint(htInfo.m_nColNo, htInfo.m_nRowNo) );
return true;
}
return false;
}
|
|
Debabrata Mukherjee
|
Sep 18, 2007 - 9:55 AM
|
What should be the default CWnd* parameter in CExtTabPagecontainerWnd.PageInsert(CWnd*). I have a CView called PresView and I write the following: m_pChildView->PageInsert (m_pPresView->GetSafeHwnd(),_T("Name"));
This process gets repeated gain when i need to add another tab. But now the catch is.... the first tab which was created over the PresView is over wriiten by the tab that was created later. The first tab physically exists but the view which should be associated with it gets overrritten by the latest tab. Do you hav any resolution to this..
Can we have a default CWnd* paranmeter
Please suggest
|
|
Technical Support
|
Sep 28, 2007 - 12:37 PM
|
You can create a view window using the following code: CWnd * pParentWindow = . . . // tab page container in your project
CCreateContext _cc;
_cc.m_pCurrentDoc = NULL;
_cc.m_pCurrentFrame = pParentWindow;
_cc.m_pLastView = NULL;
_cc.m_pNewDocTemplate = NULL;
_cc.m_pNewViewClass = RUNTIME_CLASS( CYourView );
CWnd * pWndView = CreateView( &_cc );
if( pWndView == NULL )
{
TRACE0("Failed to create your view window\n");
return . . .
}
CYourView * pView = STATIC_DOWNCAST( CYourView, pWndView ); After that you should initialize the pView view window so it can display appropriate data.
|
|
Debabrata Mukherjee
|
Sep 28, 2007 - 6:46 AM
|
As we discussed in the call with Sergiy, the same window cannot be used to load more than on Page ContainerWnd. Now I am creating new windows for separate tabpagecontainer windows. But do you have any idea that how can I create a copy of one CView on new windows that I am creating.? Becoz at the end what i want to achieve is show the different versions same view on different windows . I can manage to activate the different versions but not able to create views that can show them.
|
|
Technical Support
|
Sep 21, 2007 - 8:18 AM
|
Yes, if your connection is fast enough, that would be much easier to find what’s wrong by sharing your desktop.
|
|
Debabrata Mukherjee
|
Sep 20, 2007 - 8:59 AM
|
What we need to implement is --
We want to dynamically add tabs at runtime by user action .There is a Mainframe on which I already have 3 tabpage containers representing 3 views. Out of these 3 views the last one is called PresView. Now if I add new tabs with the line m_pChildView->PageInsert (m_pPresView->GetSafeHwnd(),_T("Name"));
For every new entry of tab... at runtime, then the PresView gets updated by the last page and all exisitng pages are overwritten.
I think we should go for a desktop sharing as it could help us mitigate the problem faster. Can we schedule it as soon as possible as it is very very urgent. I will be sending you a mail request for this from my id. Sanket_das1@yahoo.co.in
|
|
Technical Support
|
Sep 19, 2007 - 12:54 PM
|
The CExtTabPagecontainerWnd control is designed in a way that it cannot contain the same window under different tabs. Would you tell us what you need to implement so we can suggest an appropriate solution?
|
|
Brian Horn
|
Sep 17, 2007 - 11:11 PM
|
Hi,
I want to handle events on Autohide button of contorlbar how can we do this?
|
|
Suhai Gyorgy
|
Sep 18, 2007 - 2:20 AM
|
|
|
jb lee
|
Sep 17, 2007 - 1:12 PM
|
If I can, would you please tell me how?
|
|
Technical Support
|
Sep 18, 2007 - 11:15 AM
|
This dialog should be similar to the main dialog window in the ProfUIS_Controls sample, but it should use a tree control instead of the list box.
|
|
Debabrata Mukherjee
|
Sep 17, 2007 - 9:56 AM
|
I have a window in my application which is a CExtToolBoxWnd, and I want to load a tree control derived from CTreeCtrl on it. I have a specific hirerchy in my tree structure and I want to retain the hirerchy.Kindly provide me some concrete way on it..
Will I be able to use features of ToolBox window like collapse and expand and highlight on mouse hover.?
Any sample application would of good help.
|
|
Technical Support
|
Sep 21, 2007 - 5:17 AM
|
Sorry, forgot to provide a link to the sample. Here it is:
SDIDOCVIEW.zip
|
|
Technical Support
|
Sep 20, 2007 - 12:57 PM
|
Here is a modified version of the SDIDOCVIEW sample in which there are two control bars: one with tree controls and another one with a toolbox. At the application initialization in the CMainFrame::OnCreate() method, we invoke a DuplicateTreeInToolbox() method which creates the toolbox items with the same hierarchy as in the tree control. This is done in the _WalkTreeChildBranch() recursive function.
|
|
Debabrata Mukherjee
|
Sep 18, 2007 - 9:44 AM
|
It would be very helpful, if u can give us a sample
|
|
Technical Support
|
Sep 18, 2007 - 3:50 AM
|
It seems you are asking about details specific to your project only. There is only one major difference between the CTreeCtrl and CExtToolBoxWnd controls: the former control has different nested levels of its items when the CExtToolBoxWnd control has a persistent 3-level item structure (invisible root item, group items and group member items). If you want put data of CTreeCtrl into CExtToolBoxWnd , then you should create a recursive function. If it is what you need, we can provide you with a sample. If not, we need more details about your task.
|
|
Offer Har
|
Sep 17, 2007 - 7:34 AM
|
Dear Support,
I have a grid which is sorted. When new rows are added to the grid, I would like them to be added at the correct location according to the sorting order (the user clicks column header to set the sort order - default behavior).
What I do, is add the new rows at the bottom of the grid, and then I want to re-sort it according to the current sort column and order.
I read the FAQ about this GridSortOrderSetup function, but I need to know what is the current sort column and order, and I have no idea how to extract this data from my grid.
|
|
Technical Support
|
Sep 20, 2007 - 5:14 AM
|
You should not remove DYNAMIC_DOWNCAST but you can replace it with STATIC_DOWNCAST if you are sure all the cells in the column are of the the same type. If STATIC_DOWNCAST generates assertions, your grid cellās code is not safe. We believe STATIC_DOWNCAST will raise assertions. The grid cell classes require DECLARE_SERIAL and IMPLEMENT_SERIAL instead of DECLARE_DYNCREATE and IMPLEMENT_DYNCREATE . This should be the main problem with your short version of grid cell class.
|
|
Technical Support
|
Sep 19, 2007 - 12:47 PM
|
We have just checked your class by using Prof-UIS_Controls sample ans found out that the Compare method is called and the other cell after downcasting had the valid type CExtGridCellReadOnlyNumber . So, we cannot confirm this problem. Would you reproduce the problem using any of our sample and send it to us?
|
|
Offer Har
|
Sep 19, 2007 - 1:21 PM
|
Dear Support,
I removed the DYNAMIC_DOWNCAST and it seems to work fine. I guess the problem lies somewhere in this piece of code:
CExtGridCellReadOnlyNumber * pCell =
DYNAMIC_DOWNCAST(
CExtGridCellReadOnlyNumber,
( const_cast < CExtGridCell * > ( &other ) )
); I changed it to: CExtGridCellReadOnlyNumber * pCell = (CExtGridCellReadOnlyNumber*)(&other) And all is well - sorting is done as expected. Any ideas? Best Regards, Ron.
|
|
Technical Support
|
Sep 17, 2007 - 8:46 AM
|
You can get information about the current sorting using the CExtGridWnd::GridSortOrderGet() method. But it seems you do not need this method. You should simply invoke the following code after adding one or more new rows/columns at any location inside the grid: CExtGridWnd & wndGrid = . . .
CExtGridDataProvider & _DataProvider = wndGrid.OnGridQueryDataProvider();
_DataProvider.SortOrderUpdate( true, &wndGrid );
_DataProvider.SortOrderUpdate( false, &wndGrid );
|
|
Offer Har
|
Sep 17, 2007 - 9:37 AM
|
Thanks - problem solved...
I have another problem with sorting - I need to sort some columns accoring to their integer value, and not the default lexicographic sorting. How can I add my custom/integer sorting to a column?
Regards, Ron.
|
|
Technical Support
|
Sep 18, 2007 - 3:42 AM
|
When data is sorted in the grid, the CExtGridCell::Compare() virtual method is called in order to compare each cell pair in each sorted column. Please note that different cell classes have different implementations of this method. We guess you are using some simple text cell class like CExtGridCellString in the column with numeric data. It seems you should use some other cell type for this column (e.g. CExtGridCellNumber ).
|
|
Offer Har
|
Sep 18, 2007 - 4:57 AM
|
Dear Support,
I format my text (number) in a very specific way i add comma, and unit, so using CExtGridCellNumber is not a good option for me. If I understand correctly, I should derive my cell, say CExtCellRange, which will hold the number I need to compare, and add the virtual Compare function?
|
|
Technical Support
|
Sep 18, 2007 - 11:16 AM
|
Your grid cell class may look like as follows: class CRangeCellForRon : public CExtGridCellEx
{
public:
typedef int some_type_t;
some_type_t m_rangeBegin;
some_type_t m_rangeEnd;
DECLARE_SERIAL( CRangeCellForRon );
IMPLEMENT_ExtGridCell_Clone( CRangeCellForRon, CExtGridCellEx );
CRangeCellForRon( CExtGridDataProvider * pDataProvider = NULL )
: CExtGridCellEx( pDataProvider )
, m_rangeBegin( 0 )
, m_rangeEnd( 0 )
{
}
CRangeCellForRon( const CRangeCellForRon & other )
: CExtGridCellEx( other )
{
}
virtual ~CRangeCellForRon()
{
}
bool IsEmpty() const
{
ASSERT_VALID( this );
return false;
}
virtual void Empty()
{
CExtGridCellEx::Empty();
m_rangeBegin = 0;
m_rangeEnd = 0;
}
virtual void Serialize( CArchive & ar )
{
CExtGridCellEx::Serialize( ar );
if( ar.IsStoring() )
{
ar << m_rangeBegin;
ar << m_rangeEnd;
}
else
{
ar >> m_rangeBegin;
ar >> m_rangeEnd;
}
}
virtual void Assign( const CExtGridCell & other )
{
ASSERT_VALID( this );
CExtGridCellEx::Assign( other );
CRangeCellForRon * pCell =
DYNAMIC_DOWNCAST(
CRangeCellForRon,
( const_cast < CExtGridCell * > ( &other ) )
);
if( pCell != NULL )
{
// copy cell
m_rangeBegin = pCell->m_rangeBegin;
m_rangeEnd = pCell->m_rangeEnd;
}
else
{
// clear cell
m_rangeBegin = 0;
m_rangeEnd = 0;
}
}
virtual int Compare(
const CExtGridCell & other,
DWORD dwStyleMask = __EGCS_COMPARE_MASK,
DWORD dwStyleExMask = __EGCS_EX_COMPARE_MASK
) const
{
ASSERT_VALID( this );
CRangeCellForRon * pCell =
DYNAMIC_DOWNCAST(
CRangeCellForRon,
( const_cast < CExtGridCell * > ( &other ) )
);
if( pCell == NULL )
return CExtGridCellEx::Compare( other, dwStyleMask, dwStyleExMask );
if( m_rangeBegin < pCell->m_rangeBegin )
return -1;
if( m_rangeBegin > pCell->m_rangeBegin )
return 1;
if( m_rangeEnd < pCell->m_rangeEnd )
return -1;
if( m_rangeEnd > pCell->m_rangeEnd )
return 1;
return CExtGridCellEx::Compare( other, dwStyleMask, dwStyleExMask );
}
virtual void TextGet( CExtSafeString & strCopy ) const
{
ASSERT_VALID( this );
if( (GetStyleEx()&__EGCS_EX_UNDEFINED_ROLE) != 0
|| IsEmpty()
)
{
strCopy = _T("");
return;
}
strCopy.Format( _T("%d - %d"), int(m_rangeBegin), int(m_rangeEnd) );
}
virtual void TextSet(
__EXT_MFC_SAFE_LPCTSTR str = __EXT_MFC_SAFE_LPCTSTR(NULL), // empty text
bool bAllowChangeDataType = false
)
{
ASSERT_VALID( this );
bAllowChangeDataType;
Empty();
_stscanf( LPCTSTR(str), _T("%d - %d"), (int*)(&m_rangeBegin), (int*)(&m_rangeEnd) );
}
virtual HRESULT OnParseText( __EXT_MFC_SAFE_LPCTSTR sText ) const
{
ASSERT_VALID( this );
ASSERT( sText != NULL );
if( sText == NULL )
return E_INVALIDARG;
int _rangeBegin = 0, _rangeEnd = 0;
if( _stscanf( LPCTSTR(sText), _T("%d - %d"), &_rangeBegin, &_rangeEnd ) != 2 )
return E_FAIL;
return S_OK;
}
};
// this line of code should be placed at the beginning of .CPP file before the definition of
// MFC’s debug version of the new operator
IMPLEMENT_SERIAL( CRangeCellForRon, CExtGridCellEx, VERSIONABLE_SCHEMA|1 );
|
|
Offer Har
|
Sep 18, 2007 - 4:50 PM
|
Dear Support,
Thanks for the explanation. I tried to implement the proposed solution, removing items I don’t need, and ended up with this class:
In the .h file:
class CExtGridCellReadOnlyNumber : public CExtGridCellString
{
double m_dVal;
public:
DECLARE_DYNCREATE( CExtGridCellReadOnlyNumber );
IMPLEMENT_ExtGridCell_Clone( CExtGridCellReadOnlyNumber, CExtGridCellString );
CExtGridCellReadOnlyNumber(CExtGridDataProvider * pDP = NULL)
: CExtGridCellString(pDP)
, m_dVal(0.0)
{
ModifyStyle(__EGCS_NO_INPLACE_CONTROL|__EGCS_TEXT_ELLIPSIS );
}
virtual int Compare(
const CExtGridCell & other,
DWORD dwStyleMask = __EGCS_COMPARE_MASK,
DWORD dwStyleExMask = __EGCS_EX_COMPARE_MASK
) const;
double GetVal() { return m_dVal; }
void SetVal(double dVal);
virtual CString ToString();
}; In the .cpp: IMPLEMENT_DYNCREATE(CExtGridCellReadOnlyNumber, CExtGridCellString);
void CExtGridCellReadOnlyNumber::SetVal(double dVal)
{
m_dVal = dVal;
TextSet(ToString());
}
CString CExtGridCellReadOnlyNumber::ToString()
{
CString str;
str.Format("%.0f", m_dVal);
return str;
}
int CExtGridCellReadOnlyNumber::Compare(const CExtGridCell& other, DWORD dwStyleMask, DWORD dwStyleExMask) const
{
ASSERT_VALID( this );
CExtGridCellReadOnlyNumber * pCell =
DYNAMIC_DOWNCAST(
CExtGridCellReadOnlyNumber,
( const_cast < CExtGridCell * > ( &other ) )
);
if( pCell == NULL )
return CExtGridCellEx::Compare( other, dwStyleMask, dwStyleExMask );
if( m_dVal < pCell->GetVal())
return -1;
if( m_dVal > pCell->GetVal() )
return 1;
return CExtGridCellEx::Compare( other, dwStyleMask, dwStyleExMask );
}
I have a derived class: class CRangeCell : public CExtGridCellReadOnlyNumber
{
public:
DECLARE_DYNCREATE( CRangeCell );
IMPLEMENT_ExtGridCell_Clone( CRangeCell, CExtGridCellReadOnlyNumber );
CRangeCell(CExtGridDataProvider * pDP = NULL) : CExtGridCellReadOnlyNumber(pDP) {}
virtual CString ToString() { return UIUtils::ToStringWith1000Comma(Convert::MeterToYard(GetVal()))+" Y"; }
};
and of-course in the .cpp the IMPLEMENT_DYNCREATE. All is well, the Compare function is called, but the other cell that it gets as a parameter is not of the right type, so the downcast fails, and my numeric comparing code is never reached. What is the problem? Thanks, Ron.
|
|
Debabrata Mukherjee
|
Sep 17, 2007 - 7:01 AM
|
Hi,
I need to load a png file in a CExtToolControlBar. I have included ProfSkin.h as a header and used CExtSkinBitmap to upload that png file. I have taken help from the code snippet given below.
LPCTSTR strPngImageResourceID = MAKEINTRESOURCE( IDR_PNG_RESOURCE_IMAGE ); LPCTSTR strPngResourceSection = _T("PNG"); HINSTANCE hInst = AfxFindResourceHandle( strPngImageResourceID, strPngResourceSection ); ASSERT( hInst ); HRSRC hRsrc = FindResourceHandle( hInst, strPngImageResourceID, strPngResourceSection ); ASSERT( hRsrc ); VERIFY( _bmpTmp.LoadPNG_Resource( hInst, hRsrc ) );
Here, I got an error in the FindResourceHandle method. The Message is "’FindResourceHandle’: identifier not found".
Can you help me to upload the png file into the CExtToolControlBar?
|
|
Suhai Gyorgy
|
Sep 17, 2007 - 7:23 AM
|
Sorry, I gave you a wrong answer in the previous post. You should use
HRSRC hRsrc = ::FindResource( hInst, strPngImageResourceID, strPngResourceSection );
|
|
Suhai Gyorgy
|
Sep 17, 2007 - 7:17 AM
|
Try calling g_ResourceManager->FindResourceHandle(...) .
|
|
Chris Anderson
|
Sep 14, 2007 - 7:12 PM
|
hi there,
I have a question about the theme change event. Our app caches system colors during the startup ( by calling g_PaintManager->GetColor()), when the theme is changed, we have to update the cache colors. From the FAQ, one approach is to derive from CExtPmBridge, and overwrite the PmBridge_OnPaintManagerChanged() method.
Normally should this be done with an existing class, like the main frame wnd, or a global class which live through the life span of the app. I guess once the object is deleted, I will lose track of the event?
Any other light weight approach, like a callback function ?
Thanks
|
|
Chris Anderson
|
Sep 16, 2007 - 11:41 PM
|
|
|
Technical Support
|
Sep 15, 2007 - 11:41 AM
|
The CExtPaintManager::GetColor() method returns COLORREF values from its cache. So, you don’t have to code your own cache. You need the paint manager changing event for re-painting your themed windows only. Here is the class which handles the paint manager changing code: class __PROF_UIS_API CYourClass
: public CBaseClass1
, public CBaseClass2
, public CBaseClass3
. . .
, public CExtPmBridge
{
public:
DECLARE_CExtPmBridge_MEMBERS( CYourClass );
CYourClass();
virtual ~CYourClass();
virtual void PmBridge_OnPaintManagerChanged(
CExtPaintManager * pGlobalPM
);
};
IMPLEMENT_CExtPmBridge_MEMBERS( CYourClass );
CYourClass::CYourClass()
{
PmBridge_Install();
}
CYourClass::~CYourClass()
{
PmBridge_Uninstall();
}
void CYourClass::PmBridge_OnPaintManagerChanged(
CExtPaintManager * pGlobalPM
)
{
}
|
|
Suhai Gyorgy
|
Sep 13, 2007 - 7:41 AM
|
Dear Support,
Our application’s main structure is similar to your SimpleGrids sample. It seems to me that the font used in the grid is different from the font used on the tabs of the TabPageContainer, even though no code in our application (or in SimpleGrids application) changes the font. Shouldn’t all ProfUIS controls use the same default font? If not, what was the reason you chose another font for either the grid or the tabs? What code should we add to our application to have the same font used in both controls?
Thank you! Chris
|
|
Technical Support
|
Sep 13, 2007 - 10:37 AM
|
There is a g_PaintManager->m_FontNormal stored in the global paint manager, which controls the font used In most of Prof-UIS controls. But some Prof-UIS controls when placed on a dialog use the parent dialog’s font. In the latter case, you can assign a custom font using the CWnd::SetFont() method.
|
|
Suhai Gyorgy
|
Sep 13, 2007 - 11:33 AM
|
As I wrote in the first post, these controls are not on a dialog. Just start your SimpleGrids sample (which is not dialog based application) and check out the fonts used in the grids and on the tabs of the TabPageContainer. They are different. So at least one of them is not using g_PaintManager->m_FontNormal . Which of them should I change and how to produce the same fonts? (I’d prefer the font used on the tab items but if you could show me the other way around, as well, it’d be great)
BTW, regarding your answer: when a grid is placed on a dialog, the font used in the grid is not the same as on the dialog. I need to call m_wndGrid->SetFont(GetFont(), false); manually in OnInitDialog.
Best regards, Chris
|
|
Technical Support
|
Sep 14, 2007 - 11:23 AM
|
Here is the method that is used for retrieving a font in the tab page container: HFONT CExtTabPageContainerWnd::OnQueryFont() const
{
ASSERT_VALID( this );
HFONT hFont = (HFONT)
::SendMessage( m_hWnd, WM_GETFONT, 0L, 0L );
if( hFont == NULL )
{
HWND hWndParent = ::GetParent( m_hWnd );
if( hWndParent != NULL )
hFont = (HFONT)
::SendMessage( hWndParent, WM_GETFONT, 0L, 0L );
} // if( hFont == NULL )
if( hFont == NULL )
{
hFont = (HFONT)::GetStockObject( DEFAULT_GUI_FONT );
if( hFont == NULL )
hFont = (HFONT)::GetStockObject( SYSTEM_FONT );
} // if( hFont == NULL )
return hFont;
} In the grid window, some other method is used: CFont & CExtScrollItemWnd::OnSiwGetDefaultFont() const
{
ASSERT_VALID( this );
CFont * pFont = NULL;
if( GetSafeHwnd() != NULL )
pFont = GetFont();
return ( pFont->GetSafeHandle() != NULL ) ? (*pFont) : PmBridge_GetPM()->m_FontNormal;
} So, in the first case is the font specified with DEFAULT_GUI_FONT and in the second case is is m_FontNormal . You can override OnSiwGetDefaultFont() in your grid window and make it the same as CExtTabPageContainerWnd::OnQueryFont() . As for your comment, yes, we agree with you.
|
|
Ivan Shmakov
|
Sep 13, 2007 - 5:51 AM
|
Hello!
I’m trying to open FileOpen and FileSave common dialog looks like all application style (CExtPaintManagerOffice2007_Black).
I try to subclass FileOpen dialog:
class CProfUISFileDialog : public CExtNCW<CExtResizableDialog> { public: CProfUISFileDialog(CWnd* pParent = NULL) : m_pParent(pParent) { m_bAutoSubclassChildControls = true; m_bShowResizingGripper = false; }
virtual ~CProfUISFileDialog() {}
public: virtual INT_PTR DoModal() { // Test Opening OPENFILENAME ofn; // common dialog box structure TCHAR szFile[MAX_PATH]; // buffer for file name HANDLE hf; // file handle
// Initialize OPENFILENAME ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = m_pParent->m_hWnd; ofn.lpstrFile = szFile; ofn.lpstrFile[0] = _T(’\0’); ofn.nMaxFile = sizeof(szFile); ofn.lpstrFilter = _T("All\0*.*\0Text\0*.TXT\0"); ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
AfxHookWindowCreate(this); if (GetOpenFileName(&ofn)==TRUE) {
} return IDOK; } private: CWnd* m_pParent; };
and use by
CProfUISFileDialog dlg(this); dlg.DoModal();
But this solution crashed... at
void CExtComboBoxBase::DrawItem( LPDRAWITEMSTRUCT lpDIS ) { ... if( lpDIS->itemID >= 0 ) { LB_ITEM * pItemDataExt = (LB_ITEM *) lResult; if( pItemDataExt != NULL && AfxIsMemoryBlock( static_cast < LPVOID > ( pItemDataExt ), sizeof( LB_ITEM ) ) // <- Crash here ...
}
Help me to solve this problem or please send me sample how to create CFileDialog in same style as other application.
|
|
Technical Support
|
Sep 13, 2007 - 11:24 AM
|
Actually the combo box in the File Dialog is an extended version of the simple combo box control which provides support for image lists (CComboBoxEx ). So it is incorrect to subclass it with the CExtComboBox class which is derived from the simple CComboBox . We spent a lot of time to create the Prof-UIS skinned extended combo box but failed. It simply ignores the WM_PAINT message and draws itself in some other way. If you find a way how to create a skinned version of CComboBoxEx then you will be able to use it in the File Dialog window.
If you are creating these dialogs from the scratch and encounter this error, please send us the source code so we can test it on our side and find out what is wrong.
|
|
Debabrata Mukherjee
|
Sep 13, 2007 - 3:55 AM
|
How can I handle the right click on a tab item in a CExtTabWnd tabstrip. I suppose theres no overridable method to accomplish this. I want to display a pop-up context menu on right clciking the items on the tabstrip.
How can that be done and where exactly the message maps need to be inserted i.e. for the mainframe class or the tabwnd class etc.Please suggest. Can you just give me a skeletal method /sample for it.
Thanks.
|
|
Suhai Gyorgy
|
Sep 13, 2007 - 6:30 AM
|
Check out Help for CExtTabWnd::OnTabWndClickedItem method. There you can test if right mouse button is clicked/released and on which tab item.
|
|
tera t
|
Sep 13, 2007 - 1:40 AM
|
|
|
tera t
|
Sep 13, 2007 - 10:57 PM
|
Hello
I can seem to cope in SM_CXSIZE ,SM_CYSIZE somehow. Thank you.
|
|
Technical Support
|
Sep 13, 2007 - 10:59 AM
|
If you need to create some custom buttons in the non-client area, you could get the size of buttons in the non-client area by using some paint manager’s API. But please note that in some cases the paint manager will simply overlap these buttons with the caption text. The better solution is to implement your paint manager class which implements the following virtual method: virtual void NcFrame_Paint(
CDC & dc,
const CExtCmdIcon * pIcon,
__EXT_MFC_SAFE_LPCTSTR strCaption,
UINT nDrawTextAlignFlags,
const RECT & rcFrame,
const RECT & rcClient,
const RECT & rcIcon,
const RECT & rcText,
const RECT & rcHelp,
const RECT & rcMinimize,
const RECT & rcMaximizeRestore,
const RECT & rcClose,
bool bFrameActive,
bool bFrameEnabled,
bool bFrameMaximized,
e_nc_button_state_t eStateButtonHelp,
e_nc_button_state_t eStateButtonMinimize,
e_nc_button_state_t eStateButtonMaximizeRestore,
e_nc_button_state_t eStateButtonClose,
const CWnd * pWnd,
LPARAM lParam = 0L
) const; Your virtual method should adjust the rcText.right value for reserving the space for your buttons, invoke parent class methods and paint your custom buttons over the caption painted by default.
|
|
Offer Har
|
Sep 12, 2007 - 1:55 PM
|
Dear Support,
We had a discussion in the past regarding how to implement a custom cell, including in the in-place edit part. I are now in a real need for such tutorial, please try and give this task a higher priority.
Thanks in advance, Ron.
|
|
Technical Support
|
Oct 1, 2007 - 11:46 AM
|
The article will be ready soon. We are sorry for the delay.
|
|
Technical Support
|
Sep 13, 2007 - 7:14 AM
|
We can create such a tutorial right away. But could you give us some clues about some kind of cell and in-place editor that you will be using in your project? We would then use it as an example in this tutorial.
|
|
Offer Har
|
Sep 14, 2007 - 8:07 AM
|
I sent you a link via mail. Please let me know if you got it.
|
|
Technical Support
|
Sep 14, 2007 - 12:31 PM
|
Yes, we did. Thank you. We will prepare and publish the article in the next week.
|
|
Offer Har
|
Oct 1, 2007 - 10:47 AM
|
Dear Support,
Any news? still waiting for this tutorial...
Regards, Ron.
|
|
Offer Har
|
Oct 15, 2007 - 10:02 AM
|
Dear Support,
It’s been more then a month... Any progress? Any estimation when it will be ready? There are other items that you also said that will be ready long time ago, and still not available, like tool-tip to cells excel style. Please try and give a more acurate estimation, as we try to setup out schedule accordingly.
Regards, Ron.
|
|
Paul Cowan
|
Sep 12, 2007 - 10:02 AM
|
How can I disable the report grid group area so the groupings can not be changed? My app sets the grouping, and I don’t want the user to be able to change it, but I do need the display so the user knows what the grouping is.
I would like to keep the sorting enabled within the group area.
|
|
Technical Support
|
Sep 12, 2007 - 12:20 PM
|
The CExtReportGridWnd class does not support read-only group header area. But it is not very difficult to implement it. First, you should override the CExtReportGridWnd::OnReportGridCreateGroupArea() virtual method: CExtReportGridGroupAreaWnd * OnReportGridCreateGroupArea()
{
ASSERT_VALID( this );
CExtReportGridGroupAreaWnd * pGAW = new CYourGroupAreaWnd( *this );
if( ! pGAW->Create(
this,
CRect( 0, 0, 0, 0 ),
7001,
WS_CHILD|WS_CLIPCHILDREN
|WS_CLIPCHILDREN|WS_CLIPSIBLINGS
|WS_TABSTOP
//|WS_VISIBLE
)
)
return NULL;
return pGAW;
} The CYourGroupAreaWnd class implements a non-clickable group area window: class CYourGroupAreaWnd : public CExtReportGridGroupAreaWnd
{
protected:
virtual LRESULT WindowProc( UINT nMsg, WPARAM wp, LPARAM lp )
{
if( ( WM_MOUSEFIRST <= nMsg && nMsg <= WM_MOUSELAST ) || nMsg == WM_CONTEXTMENU )
return 0L;
else
return CExtReportGridGroupAreaWnd::WindowProc( nMsg, wp, lp );
}
public:
virtual LONG ItemHitTest(
const POINT & ptClient,
RECT * pRectItem = NULL
) const
{
ptClient;
pRectItem;
return -1L;
}
virtual LONG ItemDropHitTest(
const POINT & ptClient
) const
{
ptClient;
return -1L;
}
virtual bool ItemDropMarkerGet(
LONG nHT,
POINT & ptTop,
INT & nHeight
) const
{
nHT;
ptTop;
nHeight;
return -1L;
}
}; The CYourGroupAreaWnd class also does not allow you to hit test their items drawn as a stair. As a result, nobody should be able to drop report fields onto it. The next step is to remove all the grouping commands from the context menus. You should override the CExtReportGridWnd::OnReportGridColumnCtxMenuConstruct() virtual method and call the parent class method in it and then remove unnecessary menu items from the menu constructed by default.
|
|
Debabrata Mukherjee
|
Sep 12, 2007 - 7:24 AM
|
The tab strip in my application vanishes if the application is left unused for some time. I find no way of retrieving it. Its just gone... vanished.. What should be done?
Thnx
|
|
Debabrata Mukherjee
|
Sep 20, 2007 - 10:41 AM
|
Ya .. we can go ahead with a desktop sharing session. A mail would be sent to you from my ID today.
|
|
Debabrata Mukherjee
|
Sep 19, 2007 - 8:07 AM
|
Actually I find the tabstrip hidden once i minimize my application. So this seems to be a repaint issue. How to handle that?
|
|
Technical Support
|
Sep 20, 2007 - 5:22 AM
|
Unfortunately we cannot say what what may be wrong in your application without seeing the source code. There are several ways we can help you. You can create a test project and send it to us. You can modify one of our samples so that the problem can be demonstrated with it. Finally, we can help you debug the problem remotely if your connection is fast enough.
|
|
Suhai Gyorgy
|
Sep 19, 2007 - 11:05 AM
|
There is not enough information to find out what could be the problem. Have you tried what Support suggested, have you used SPY++ to see what messages the tab receives around the time it disappears?
I know you think that desktop sharing is time consuming, but it is really much-much more time consuming this way, as the information you share is not really helpful in solving the problem. You should reconsider Support’s offer about desktop sharing.
|
|
Debabrata Mukherjee
|
Sep 19, 2007 - 7:01 AM
|
Actually I find the tabstrip hidden once i minimize my application. So this seems to be a repaint issue. How to handle that?
|
|
Debabrata Mukherjee
|
Sep 12, 2007 - 1:52 PM
|
The CExtTabWnd class is used to create a tab strip. This tab strip object has been used to create tabs and they are working fine.But if ileave my applicatioon open for say 30-45 mins the tab strip gets vanished altogather and doesnot come back on click,dblclick or mouse over.
The tabstrip is gone totally.
Can u give som pointers?
|
|
Technical Support
|
Sep 13, 2007 - 5:36 AM
|
We have never encountered this problem in our samples nor anybody reported such a problem earlier. We suspect you may have some code in your application that causes this problem. What we can suggest is to watch for all the messages for the tab window using the SPY++ utility. We wonder which messages are displayed in SPY++ after this 45 minutes delay?
|
|
Technical Support
|
Sep 12, 2007 - 12:15 PM
|
We are sorry but there is not enough information in your message to come to any conclusion about what is wrong. If the tab window disappears, that can be caused by that it gets hidden by some code or some other window can be moved over the tab window. Could you reproduce this problem using our samples? Is it possible to get some project from you that reproduces this problem?
|
|
David Skok
|
Sep 11, 2007 - 1:47 PM
|
I do not display the toolbar in PropertyGrid controls in my app. I only show the sort by category display. As such there is no need for the sorted property display. Can I safely override OnPgcCreateGrids() and NOT create it without problems?
Thanks
|
|
Technical Support
|
Sep 12, 2007 - 9:28 AM
|
Yes, just override the CExtPropertyGridCtrl::OnPgcCreateGrids() virtual method for that. You need to create at least one tree grid window in the property grid control because, otherwise, if you create no tree windows, the property grid control will no longer be usable. Your version of the OnPgcCreateGrids() method should be similar to the original one: it should create a CExtPropertyGridWndCategorized window and it should not create a CExtPropertyGridWndSorted window. You can use similar approach and remove other build-in parts of the property grid control: the combo box bar, tool bar and help tip bar. To remove any of these bars, you should override the CExtPropertyGridCtrl::OnPgcCreateBars() virtual method and create only those bars that you need.
|