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 |
|
Mike Van Duzee
|
May 31, 2011 - 10:06 AM
|
While looking at the RichContentFeatures sample I realized the style attribute does not appear to be supported.
<html>
<head>
<title></title>
</head>
<body>
<p style="font-family:Courier New;font-size:8mm;color:rgb(0,0,0);text-decoration:underline line-through;">Test Text</p>
</body>
</html>
The above HTML does not render as expected. Is the style attribute supported? If not will it be supported it future versions?
I did not use font tag as it has been deprecated in HTML 4 and removed from HTML5.
Any additional information you can provide regarding HTML Everywhere feature (rich content) would be appreciated.
Thanks
|
|
Technical Support
|
Jun 1, 2011 - 1:39 PM
|
hank you again. But now we have only a temporary fix for font name parser:
void CExtRichContentItem::stat_css_parm_handler_font_family( CExtRichContentItem * pRCI, CExtRichContentItem * pFoundHI, CExtRichStyleRule & styleChanging, const CExtRichStyleDescription & )
{
/*
POSITION pos = pFoundHI->m_listParms.GetHeadPosition();
for( ; pos != NULL; )
{
CExtRichContentItem * pStylesParmHI = pFoundHI->m_listParms.GetNext( pos );
CExtSafeString str = LPCTSTR(pStylesParmHI->m_strTagPV);
str.TrimLeft( __EXT_RICH_CONTENT_TRIM_CHARS_AND_QUOTES );
str.TrimRight( __EXT_RICH_CONTENT_TRIM_CHARS_AND_QUOTES );
if( pRCI->ParseFontFamily( styleChanging, LPCTSTR( str ) ) )
break;
}
*/
CExtSafeString strReCompose;
POSITION pos = pFoundHI->m_listParms.GetHeadPosition();
bool bFirst = true;
for( ; pos != NULL; )
{
CExtRichContentItem * pStylesParmHI = pFoundHI->m_listParms.GetNext( pos );
CExtSafeString str = LPCTSTR(pStylesParmHI->m_strTagPV);
str.TrimLeft( __EXT_RICH_CONTENT_TRIM_CHARS_AND_QUOTES );
str.TrimRight( __EXT_RICH_CONTENT_TRIM_CHARS_AND_QUOTES );
if( ! bFirst )
strReCompose += _T(" ");
else
bFirst = false;
strReCompose += str;
int nPos = strReCompose.Find( _T(",") );
if( nPos > 0 )
{
CExtSafeString strTry = strReCompose.Left( nPos );
strTry.TrimLeft( __EXT_RICH_CONTENT_TRIM_CHARS_AND_QUOTES );
strTry.TrimRight( __EXT_RICH_CONTENT_TRIM_CHARS_AND_QUOTES );
if( pRCI->ParseFontFamily( styleChanging, LPCTSTR( strTry ) ) )
return;
strReCompose = strReCompose.Right( strReCompose.GetLength() - nPos - 1 );
bFirst = true;
}
}
if( ! strReCompose.IsEmpty() )
{
strReCompose.TrimLeft( __EXT_RICH_CONTENT_TRIM_CHARS_AND_QUOTES );
strReCompose.TrimRight( __EXT_RICH_CONTENT_TRIM_CHARS_AND_QUOTES );
if( pRCI->ParseFontFamily( styleChanging, LPCTSTR( strReCompose ) ) )
return;
}
}
The final parser fix will require more than one method modification and it will be fixed a few hours later today. Please drop us an e-mail to the support mail box at this web site and we will provide you with the fix.
|
|
Mike Van Duzee
|
Jun 1, 2011 - 7:09 AM
|
Again thanks for the quick reply. I may have stumbled upon another CExtRichContentLayout class bug. CExtRichContentItem::ParseCSSValue is parsing "Comic Sans MS" into "comic".
Pasting the below HTML into a document and loading in IE and pasting in the RichContentFeatures sample generate different results.
<html>
<head>
<title></title>
</head>
<body>
<p>
<span style="font-family:Comic Sans MS;font-size:8.46666666666667mm;color:rgb(0,0,0);font-weight:bold;font-style:italic;text-decoration:underline line-through;">Rich Text</span>
</p>
<p></p>
</body>
</html>
|
|
Technical Support
|
Jun 1, 2011 - 2:37 AM
|
You found a bug in the CExtRichContentLayout class. The mm units are converted to target device units incorrectly. Thank you. Please update the source code for the following method:
LONG CExtRichContentLayout::ConvMm2Px( DOUBLE lgMm, bool bHorz ) const
{
DOUBLE lfRes = lgMm * ( bHorz ? DOUBLE(g_PaintManager.m_nLPX) : DOUBLE(g_PaintManager.m_nLPY) ) / 2.54 / 10.0;
DOUBLE lfResCeil = ::ceil( lfRes );
DOUBLE lfFraction = 1.0 - ( lfResCeil - lfRes );
if( lfFraction >= 0.5 )
lfRes = lfResCeil;
else
lfRes = ::floor( lfRes );
return LONG(lfRes);
}
Both updated methods are inside 2.92. You can drop us an e-mail to the support mail box and we will provide you with 2.92 download.
|
|
Mike Van Duzee
|
May 31, 2011 - 1:33 PM
|
Thanks for the quick reply. The code provided allows multiple text-decoration’s to be applied. Will this be included in Prof-UIS 2.9.2?
On another CSS style attribute note, font-size:8mm appears to be converted to 3px which doesn’t match other HTML renders (I.E., Firefox, Etc.).
Pasting the below HTML into a document and loading in IE and pasting in the RichContentFeatures sample generate different results.
<html>
<head>
<title></title>
</head>
<body>
<p>
<span style="font-family:Gabriola Bold Italic;font-size:8mm;color:rgb(0,0,0);font-weight:bold;font-style:italic;text-decoration:underline line-through;">Rich Text Format</span>
<span style="font-family:Gabriola Bold Italic;font-size:3px;color:rgb(0,0,0);font-weight:bold;font-style:italic;text-decoration:underline line-through;">Rich Text Format</span>
<span style="font-family:Gabriola Bold Italic;font-size:30px;color:rgb(0,0,0);font-weight:bold;font-style:italic;text-decoration:underline line-through;">Rich Text Format</span>
</p>
<p></p>
</body>
</html>
|
|
Technical Support
|
May 31, 2011 - 11:19 AM
|
Thank you for reporting this issue. We implemented a single value text-decoration CSS attribute. I.e. you can only specify text-decoration:underline; or text-decoration:line-through; . But it’s not difficult to extend text-decoration support for multiple values. Please update the source code for the following method:
void CExtRichContentItem::stat_css_parm_handler_text_decoration( CExtRichContentItem *, CExtRichContentItem * pFoundHI, CExtRichStyleRule & styleChanging, const CExtRichStyleDescription & )
{
int nCount = int(pFoundHI->m_listParms.GetCount());
if( nCount < 1 )
return;
POSITION pos = pFoundHI->m_listParms.GetHeadPosition();
for( ; pos != NULL; )
{
CExtRichContentItem * pStylesParmHI = pFoundHI->m_listParms.GetNext( pos );
CExtSafeString str = LPCTSTR(pStylesParmHI->m_strTagPV);
str.TrimLeft( __EXT_RICH_CONTENT_TRIM_CHARS );
str.TrimRight( __EXT_RICH_CONTENT_TRIM_CHARS );
if( str.IsEmpty() )
continue;
str.MakeLower();
if( str == _T("underline") )
styleChanging.m_nUnderline = 1;
if( str == _T("line-through") )
styleChanging.m_nStrikeOut = 1;
// if( str == _T("overline") )
// styleChanging.m_nOverline = 1;
// if( str == _T("blink") )
// styleChanging.m_nBlink = 1;
}
}
|
|
Eric
|
May 25, 2011 - 11:17 AM
|
Small problem.
We have many dialogs that use the EnableSaveRestore function.
If one changes the DPI (right click desktop, Properties, Settings, Advanced) from 96 to 120, the dialogs will end up being to small because the settings in the registry we set using 96 DPI.
Is there a way to detect a change in DPI to set the correct dialog size.
Or, I guess, in the worst case, shoot the directory; If you do this, the dialogs will end up having the right size.
|
|
Technical Support
|
May 30, 2011 - 3:02 AM
|
The problem is a bit more complex because an application can start next time and use a different UI theme where the non client area skin uses some other caption and different border sizes. The problem is not critical because the restored window size will not be smaller then the enabled minimal tracking size and larger than the maximal one. Besides, DPI changing is performed rarely. For instance, when you install Windows on a new PC or when you have a new monitor. The shoot the directory approach can be coded directly in your project. It requires all resizable dialogs to use the same directory. I.e. the same first parameter value in invocation of the EnableSaveRestore() API.
|
|
John Frederickson
|
May 17, 2011 - 8:44 AM
|
Mode is set to "all", time format is set to "h24". While it is not in-place editing the date/time displays as, "5/11/2002 12:36:57". All good. As soon as I click on it to edit it, it changes to, "5MayMay/11/200212:36:57". What’s up with that?
|
|
Technical Support
|
May 17, 2011 - 1:31 PM
|
This issue is already fixed. Please drop us an e-mail to the support mail box at this web site so we will provide you with the source code update download.
|
|
John Frederickson
|
May 12, 2011 - 12:07 PM
|
We are using v2.90.
The drawing slows to a crawl during any redraw (clicking on a menu, switching tabs, etc.).
The Task manager shows memory utilization spiking, and heavy disk I/O during the slow down, but no process is reported as using the memory.
So far this seems to mostly occur on Windows XP 64 bit or Windows Server 2003 machines and seems to be greatly exaggerated when viewing the machine via a Remote Desktop Connection.
Any idea as to what could be causing this, or how we might fix it?
|
|
Technical Support
|
Jun 22, 2011 - 11:42 AM
|
We cannot avoid creating a memory DC. There are no chances to implement clipping without a memory DC. Please add DT_NOCLIP flags into invocation of the CExtRichContentLayout::stat_DrawText() API in your project.
|
|
John Frederickson
|
Jun 3, 2011 - 9:49 AM
|
None of these seem to be the problem. We don’t use OnIdle(), and timers only rarely (and not at the time we are seeing this painting issue) and our command updating uses cached values wherever possible. Yet this is still a problem even after we updated to v2.92.
As I said, this only seems to happen over a Remote Desktop Connection, and then only sometimes. Do you have any other ideas?
|
|
Technical Support
|
Jun 3, 2011 - 11:13 AM
|
Does this problem go away if your app uses a simple UI theme (Office 2000, Office XP) while running over a remote desktop connection? These themes are light and fast as possible because everything is painted without bitmap based skins and gradient fills.
|
|
John Frederickson
|
Jun 9, 2011 - 5:24 PM
|
We aren’t using themes. But it does go away if I change CExtRichContentLayout::stat_DrawPlainText() to not increase the rectangle by 32767x32767 when it comes in empty, thus NOT allocating a 2GB DC (on a machine that only has 2 GB RAM to begin with).
|
|
Technical Support
|
Jun 10, 2011 - 10:31 AM
|
Please provide us with more details about 32767x32767 painting device surface. How does CExtRichContentLayout::stat_DrawPlainText() method create such big memory surfaces in your app?
|
|
John Frederickson
|
Jun 13, 2011 - 4:23 PM
|
int CExtRichContentLayout::stat_DrawPlainText( CExtRichContentLayout::e_layout_orientation_t eLO, HDC hDC, __EXT_MFC_SAFE_LPTSTR str, int nCount, LPRECT lpRect, UINT nDTF /*= 0*/, UINT nExtDTF /*= 0*/, HWND hWndOpenThemeData /*= NULL*/, LPCVOID wstrOpenThemeDataClassList /*= NULL*/, DWORD dwOpenThemeDataFlags /*= 0*/, int nDtThemePartID /*= 0*/, int nDtThemeStateID /*= 0*/, CExtUxTheme::__EXT_UX_DTTOPTS * pDTO /*= NULL*/, CExtRichContentLayout::DRAWSTATE_data_t * pDSD /*= NULL*/ ) {
//NOTE: lpRect = {0,0,0,0} (possibly because the string we are trying to render is, " " (9 spaces)?) [...snip...]
CRect rcDocRenderTarget, rcTmpSrc;
//NOTE: takes the ’else’ path
if( lpRect == NULL ) { dc.GetClipBox( &rcDocRenderTarget ); rcTmpSrc = rcDocRenderTarget; lpRect = &rcTmpSrc; } else { rcDocRenderTarget = (*lpRect); if( rcDocRenderTarget.Width() <= 0 ) rcDocRenderTarget.right = rcDocRenderTarget.left + 32767; if( rcDocRenderTarget.Height() <= 0 ) rcDocRenderTarget.bottom = rcDocRenderTarget.top + 32767; }
//NOTE: rcDocRenderTarget rect now has width = 32767, height = 32767
if( ( nDTF & (DT_NOCLIP|DT_CALCRECT) ) == 0 ) { CExtMemoryDC dcMem( &dc, &rcDocRenderTarget, CExtMemoryDC::MDCOPT_TO_MEMORY | CExtMemoryDC::MDCOPT_FILL_BITS | CExtMemoryDC::MDCOPT_RTL_COMPATIBILITY ); //NOTE: very BIG dcMem now :-(
[...snip...]
|
|
Technical Support
|
Jun 15, 2011 - 11:27 AM
|
Unfortunately, we cannot exclude this memory DC usage because we need to provide optional support for plain text and HTML clipping. Why do you need extra a large rectangle for text output and clipping at the same time?
|
|
John Frederickson
|
Jun 16, 2011 - 2:01 PM
|
I don’t. The real question is, why do you?
Like I said, I changed your code to use (a much more reasonable, but still excessive) 4096 x 2048 and it solved my problem.
|
|
Jeroen Walter
|
Jun 22, 2011 - 4:54 AM
|
Is there any news on this issue? I find it very disturbing that ProfUis can decide to create a 32kx32k bitmap of 32bit color, i.e. about 4 billion bytes...... This is not yet fixed in profuis 2.92....
|
|
Technical Support
|
May 13, 2011 - 12:32 PM
|
First of all, there are three things to check:
1) Idle time processing. If your application overrides the CWinApp::OnIdle() virtual method, then it should not be heavy. It should return execution control as fast as possible.
2) Timers. Do not use many timers in the main UI thread. Do not use very frequent timers. Timer handler methods also should not be heavy and return execution control as fast as possible.
3) Command updating methods. These methods should be especially short and simple. The should just invoke CCmdIU class methods and immediately return execution control.
In all the cases, the handler methods should not access any slow APIs like database queries, network requests, etc. The last case is especially important. If you need to set checked or enabled state of some toolbar button or menu item, then the command updating method should be based on some bool flags which are preliminary computed in command handler method(s).
|
|
John Frederickson
|
Jun 3, 2011 - 9:51 AM
|
(Sorry, my reply post was out of order. Please refer to the June 3rd post above.)
|
|
Bogdan Munteanu
|
May 11, 2011 - 8:08 PM
|
This thread is related to the jittery behavior of docking windows while hidden/shown. I mentioned this a few times before when I compared that behavior with the one found in Visual Studio.
Looking in ExtControllerTabbedFeatures.cpp, there a couple of places where the duration of an eventual ’sleep’ is calculated:
clock_t nNewAnimTime = clock(); clock_t nDuration = nLastAnimTime - nNewAnimTime; if( nDuration < CExtControlBar::g_nAutoHideAnimationStepTime ) ::Sleep( CExtControlBar::g_nAutoHideAnimationStepTime - nDuration ); nLastAnimTime = clock();
Shouldn’t the duration be calculated instead as:
clock_t nDuration = nNewAnimTime - nLastAnimTime; ?
nDuration in the official source code is always negative, which makes nDuration smaller than the animation step time and therefore, a Sleep is always triggered since CExtControlBar::g_nAutoHideAnimationStepTime - nDuration is always positive. In fact, the slower the machine, the longer Sleep() time because nDuration is probably proportional with time taken to redraw...
I changed the nDuration using the second formula and the jitter is far less noticeable (comparable now with Visual Studio). Can you please confirm and if necessary fix that code in the next release.
Thank you,
Bogdan
|
|
Technical Support
|
May 13, 2011 - 12:39 PM
|
Thank you for reporting this issue. Two integer values returned by two invocations of clock() API can be less than each other because clocks can overflow the integer limit after long time. So, a valid solution is to check whether the difference is positive or negative in any case: clock_t nDuration = nLastAnimTime - nNewAnimTime;
if( nDuration < 0 )
nDuration = -nDuration;
There are two places of nDuration computation in the .../Prof-UIS/Src/ExtControllerTabbedFeatures.cpp file.
|
|
Bogdan Munteanu
|
May 14, 2011 - 10:36 AM
|
While theoretically it is possible to have an overflow on a long integer, what it’s eventually being calculated there is the difference between two moments in time.
According to MSDN, the clock() routine calculates how much time the calling process has used since the start (in milliseconds). Let’s assume nLastAnimTime is a very large integer, while for nNewAnimTime clock() has rolled over and is a very small integer: even in that case nNewAnimTime-nLastAnimTime is a positive difference. The difference should also be positive if both values are negative. The only case where the difference is negative is when between nLastAnimTime and nNewAnimTime there are more than 2ˆ31 milliseconds (i.e., hundreds of hours). Given the fact we are talking about two subsequent redrawings of a sliding docking window, there are probably other things you should worry about and not the overflow.
Calculating the duration as nNewAnimTime-nLastAnimTime is less obscure and doesn’t need the post check if (nDuration<0).
Thank you, Bogdan
|
|
Eric
|
May 11, 2011 - 2:02 PM
|
Hello, I’m using the CExtPropertyGridCtrl control. I would like to customize the background color of the cell that contains the property’s name(the left one). I can change the background color of the cell at the right(a checkbox) with BackColorSet, but I’d like to do the same with the cell at the left(the one with the property’s name). I need to be able to change the background color of any cell individually, at any time. Thanks
|
|
Technical Support
|
May 13, 2011 - 12:42 PM
|
Here is how to paint a red background for all cells:
bool CYourTreeGrid::OnGridHookCellPaintBackground( const CExtGridCell & _cell, CDC & dc, LONG nVisibleColNo, LONG nVisibleRowNo, LONG nColNo, LONG nRowNo, INT nColType, INT nRowType, const RECT & rcCellExtra, const RECT & rcCell, const RECT & rcVisibleRange, DWORD dwAreaFlags, DWORD dwHelperPaintFlags ) const
{
dc.FillSolidRect( &rcCell, RGB(255,0,0) );
return false;
}
Here is how to paint red background for property values, green for categories: bool CYourTreeGrid::OnGridHookCellPaintBackground( const CExtGridCell & _cell, CDC & dc, LONG nVisibleColNo, LONG nVisibleRowNo, LONG nColNo, LONG nRowNo, INT nColType, INT nRowType, const RECT & rcCellExtra, const RECT & rcCell, const RECT & rcVisibleRange, DWORD dwAreaFlags, DWORD dwHelperPaintFlags ) const
{
HTREEITEM hti = ItemGetByVisibleRowIndex( nRowNo );
ASSERT( hti != NULL );
CExtPropertyItem * pPI = PropertyItemFromTreeItem( hti );
ASSERT( pPI != NULL );
if( pPropertyItem->IsKindOf( RUNTIME_CLASS(CExtPropertyValue) ) )
dc.FillSolidRect( &rcCell, RGB(255,0,0) );
else if( pPropertyItem->IsKindOf( RUNTIME_CLASS(CExtPropertyCategory) ) )
dc.FillSolidRect( &rcCell, RGB(0,255,0) );
return false;
}
If this virtual method paints a custom background and returns false , the tree grid control assumes there is no custom background and paints only the selected background for selected tree rows. The normal background (not selected) is not painted: it is a white background of the tree grid control. If this virtual method returns true , the tree grid assumes your code is completely responsible for painting cell backgrounds.
|
|
Technical Support
|
May 13, 2011 - 2:07 AM
|
Please override the CExtPropertyGridCtrl::OnPgcCreateGrids() virtual method. Your method should be similar to original but it should instantiate and create your tree grid classes. There are two tree grids. Please create your CExtPropertyGridWndCategorized -derived and CExtPropertyGridWndSorted -derived tree grid classes. They will be used by your property grid control. They are needed for providing particular tree rows with custom background color. Your tree grid controls should implement the CExtGridWnd::OnGridHookCellPaintBackground() virtual method and it should paint custom colored background for grid cells. This method has the nRowNo parameter which specifies plain zero based tree row index. The CExtTreeGridWnd::ItemGetByVisibleRowIndex() method can convert it into HTREEITEM tree row handle. The CExtPropertyGridWnd::PropertyItemFromTreeItem() method can the HTREEITEM tree row handle into the CExtPropertyItem * pointer that can be either CExtPropertyValue * or CExtPropertyCategory * . So, your overriden OnGridHookCellPaintBackground() method will always know which background it should paint. Please note, both tree grids always have two columns. Column with index 0 displays property value/category name. Column with index 1 displays active value of property value. The sorted tree grid does not display property categories. The property categories are displayed by categorized tree grid and their grid cells in column with index 0 are stretched horizontally to cover both columns.
|
|
Eric
|
May 13, 2011 - 11:04 AM
|
Thanks for your answer How are we supposed to use OnGridHookCellPaintBackground()? There is no doc on it and the Prof-UIS implementation looks like this: bool CExtGridWnd::OnGridHookCellPaintBackground( const CExtGridCell & _cell, CDC & dc, LONG nVisibleColNo, LONG nVisibleRowNo, LONG nColNo, LONG nRowNo, INT nColType, INT nRowType, const RECT & rcCellExtra, const RECT & rcCell, const RECT & rcVisibleRange, DWORD dwAreaFlags, DWORD dwHelperPaintFlags ) const
{
__EXT_DEBUG_GRID_ASSERT_VALID( this ); _cell; dc; nVisibleColNo; nVisibleRowNo; nColNo; nRowNo; nColType; nRowType; rcCellExtra; rcCell; rcVisibleRange; dwAreaFlags; dwHelperPaintFlags;
return false;
} I don’t understand this code... Where do we specify the custom color?
|
|
Lars Mohr
|
May 11, 2011 - 10:44 AM
|
Dear Support Team,
I have a problem with CExtTabMdiWnd and I can reproduce this with the ProfStudio sample but not with the DrawCLI sample.
If I activate a window by click on the caption bar of the window and release the mouse button and move the mouse, than the window move to the new mouse position. But this happens only if you activate a inactivate window. And the tabMdiWnd switch very slow to the new activate window. This is not the case by the DrawCLI sample. The change is much faster. Do you have an idea?
Regards
|
|
Lars Mohr
|
May 12, 2011 - 2:56 AM
|
I have
- Windows 7 and Windows XP
- VS 2008
- ProfUIS 2.90
I have checked again, and it happens only in the Office 2007 and Office 2010. If you run the ProfStudio sample and create 3 or 4 new (File->New) ProfStudio child windows. Than go to Window->Windows... and in the Window Manager dialog select all child windows and click on the overlapped button. And now if you change a window by clicking an inactivate window on the caption bar (release and move the mouse quickly) the window will move to the new mouse position.
|
|
Technical Support
|
May 13, 2011 - 12:31 PM
|
This issue can be reproduced using Prof-UIS 2.90, debug build and slow computer. We cannot reproduce it with 2.91. We used 30 open MDI child windows in our tests. When you use a fewer MDI child windows, you cannot reproduce it.
|
|
Technical Support
|
May 12, 2011 - 2:05 AM
|
We cannot reproduce this. We tried UI themes with skinned and standard window non-client areas. Which versions of Windows, Visual Studio and Prof-UIS are you using in your tests?
|
|
Andreas Spachtholz
|
May 5, 2011 - 4:10 AM
|
Hi, we had several strange crashes in our application, and now we could reproduce them. And at least some of them are related to crashes in CExtPopupMenuWnd. Sometimes it happens, that by calling the function
CExtPaintManager
::stat_PassPaintMessages(); the destructor of the object is called, and when comming back, the application crashes.
The destructur is call due to a NCDestroy windows message. The easiest way to reproduce it, is to set breakpoints in the file CExtPopupMenuWnd.cpp in the function
BOOL
.....
here---> SetWindowPos(CWnd::wndTopMost, 0, 0, 0, 0,SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZESWP_SHOWWINDOW|SWP_NOZORDERif( bFadeOut || bForceLayered )ASSERT( g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL );CExtPaintManager::stat_PassPaintMessages();g_PaintManager.m_pfnSetLayeredWindowAttributes( m_hWnd, 0, 255, __EXT_MFC_LWA_ALPHA );// if( bFadeOut )else if( ! g_PaintManager.m_bIsWin2000orLater )CExtPaintManager::stat_PassPaintMessages();here---> ASSERT( IsWindowVisible() );if( ! _FindCustomizeMode() )_SetCapture(); (!defined __EXT_MFC_NO_CUSTOMIZE)elseCExtCustomizeSite * pSite = _FindCustomizeSite();ASSERT( pSite != NULL );pSite->RegisterCommandDropTarget( this, this ); // (!defined __EXT_MFC_NO_CUSTOMIZE)if( m_bTopLevel && (! m_bExpandWasPressed ) && m_bExpandAvailable && g_nAutoExpandTime > 0 )SetTimer( ID_TIMER_AUTO_EXPAND, g_nAutoExpandTime, NULL );return TRUE;
&
|
);
{
}
{
}
#if
{
}
#endif
}
Due to the debugger, the window looses the focus and it will be destroyed. Unfortunately this also can happen sometimes during a normal run of the application.
Any solution for this issue?
Thanks
BR,
Andreas CExtPopupMenuWnd::_TrackPopupMenu
|
|
Technical Support
|
May 10, 2011 - 4:53 AM
|
The crash occurs because application execution is paused and this lets you activate and focus different windows on the desktop. The code being debugged does not expect this. This is normal situation. The crash will never occur in normal execution mode.
If your app uses some thread wide hooks, the hook handlers can be invoked before the assertion line in popup menu code. If the hook handler displays some modal dialog boxes, the popup menu code generates an assertion failure and crashes. We confirm this. But the solution is: do not to perform heavy user interaction in hook handlers. Hooks must do some work as fast as possible and return execution control.
If the assertion line brings problems, we can comment it. It will not bring any problems in release build.
|
|
Andreas Spachtholz
|
May 11, 2011 - 4:11 AM
|
Sorry, but we do not use threads in an unnormal way. And the we have many of those crashes in the field. I think our customer are not really happy about that issue, because you never know when the application will disappear suddenly. We have to find a solution for this issue! Any idea, how we can make a workaround or a fix? Thanks Andreas
|
|
Technical Support
|
May 11, 2011 - 7:24 AM
|
The CExtPaintManager::stat_PassPaintMessages() static method extracts the WM_NCPAINT , WM_ERASEBKGND and WM_PAINT messages and delivers them to appropriate window procedures. This should not cause destructor invocations and generate crashes in your app. Setting break point to the ASSERT( IsWindowVisible() ); line of code can generate crash in debug mode - not in release. But this is just incorrect place for setting break point. How this issue can make the release version of your app disappear?
|
|
Andreas Spachtholz
|
May 15, 2011 - 11:54 PM
|
We got many crash dumps of the release version (post mortem dumps) which show us always the same call stack in the CExtPopupMenuWnd. The problem is, that during the stat_PassPaintMessages the WindowProc Funtion of the CExtPopupMenuWnd is call with all WM_... messages, not only the filtered ones. Thus if a messages (e.g. ACTIVE_APP) is received which will remove the CExtPopupMenuWnd the destructor is called and the object is deleted. Which may happen in the release version e.g. if another application popups during the call of the stat:_PassPaintMessages. From our point of view this is a bug, and has to be fixed! BR, Andreas
|
|
Technical Support
|
May 16, 2011 - 12:06 PM
|
The CExtPaintManager::stat_PassPaintMessages() method delivers only painting messages. This should not cause any destructor invocations, any window handle destroying or exiting your application. We suspect this is specific for your application only. So, we need to reproduce the same using Prof-UIS sample applications, any test projects or debugging your application remotely. I.e. we need your help to fix this issue.
|
|
Andreas Spachtholz
|
May 16, 2011 - 11:21 PM
|
Sorry, but this is not correct. The filter in the PeekMessage function is valid only for the result you get back from the PeekMessage function. During the PeekMessage call the hooks and WindowProc functions get ALL windows messages! And this is the problem. If an ACTIVE_APP message is in the queue, the application crashes. You can reproduce this, as I described with the ProdUIS Control Demo Application. To enforce the critical situtation set the breakpoints as described. The breakpoints only help to construc the critical situation which will occu sometimes, e.g. we have a instant messenger which pops up for a new messages. If this happens during the stat_PAssPaintMessages, the application crashes! I test on Windows 7 32bit and 64bit. But we also got the crash reports from XP systems. BR, Andreas
|
|
Christian Dangl
|
Apr 30, 2015 - 5:32 AM
|
Hi,
I got to this page because we have exactly the same problem: The stat_PassPaintMessages triggers an ACTIVE_APP message which causes a deletion of the PopUpMenuWnd. Although Andreas encountered this problem 4 years ago, it is not fixed in ProfUIS 3.01! Were you able to overcome this annoying problem? any suggestions would be appreciated thanks, Manuel
|
|
Technical Support
|
May 17, 2011 - 1:31 PM
|
The following improved version of the CExtPopupMenuWnd::_TrackPopupMenu() method should allow your application to survive:
BOOL CExtPopupMenuWnd::_TrackPopupMenu(
DWORD dwTrackFlags,
int x,
int y,
LPCRECT lpRect,
LPVOID pCbPaintCombinedCookie, // = NULL
pCbPaintCombinedContent pCbPCC, // = NULL
bool bCookieIsObject // = false
)
{
///////////////////////////// dwTrackFlags |= TPMX_COMBINE_NONE|TPMX_FORCE_NO_ANIMATION|TPMX_NO_DYNAMIC_SHADOWS|TPMX_NO_SHADOWS;
ASSERT_VALID( this );
m_bCanceling = false;
CExtPaintManager::stat_PassPaintMessages();
::GetCursorPos( &m_ptTrackInvoked );
m_ptTrackWatched = m_ptTrackInvoked;
if( _IsTopLevelPopup() )
m_bHelperMouseBtnDownOnStart =
( IsKeyPressed( VK_LBUTTON )
|| IsKeyPressed( VK_RBUTTON )
) ? true : false;
else
m_bHelperMouseBtnDownOnStart = false;
if( m_bHelperMouseBtnDownOnStart )
::GetCursorPos( &m_ptStartMousePos );
bool bForceExpandRarelyUsed = (dwTrackFlags&TPMX_NO_HIDE_RARELY)
? true : false;
if( ! g_bMenuExpanding )
bForceExpandRarelyUsed = true;
ASSERT( m_hWndCmdReceiver != NULL );
ASSERT( ::IsWindow(m_hWndCmdReceiver) );
if( GetSafeHwnd() != NULL )
::DestroyWindow( m_hWnd ); // fade out animation effect
CExtPopupMenuSite & _site = GetSite();
if( (!_FindCustomizeMode())
&& ( _site.IsTopPopup(this)
|| GetParentMenuWnd() == NULL
)
)
{
ASSERT( m_bTopLevel );
MsgPrepareMenuData_t _mpmEntireTree( this );
_mpmEntireTree.SendMessage( m_hWndCmdReceiver, false );
if( _mpmEntireTree.m_bMenuCanceled )
return FALSE;
if( _mpmEntireTree.m_bMenuChanged )
{
_SyncItems();
_UpdateCmdUI();
}
ASSERT( m_bTopLevel );
// ASSERT( _site.IsTopPopup(this) );
}
MsgPrepareMenuData_t _mpmOneTreeLevel( this );
_mpmOneTreeLevel.SendMessage( m_hWndCmdReceiver, true );
if( _mpmOneTreeLevel.m_bMenuCanceled )
return FALSE;
if( _mpmOneTreeLevel.m_bMenuChanged )
{
_SyncItems();
_UpdateCmdUI();
}
if( !_FindCustomizeMode() )
{ // BLOCK: update system commands
INT iter = 0;
for(; iter < m_items_all.GetSize(); ++iter )
{
MENUITEMDATA & mi = ItemGetInfo( iter );
if( mi.IsSeparator() )
continue;
UINT nCmdID = mi.GetCmdID();
if( ! CExtCmdManager::IsSystemCommand( nCmdID ) )
continue;
WINDOWPLACEMENT wndpl;
::memset(&wndpl,0,sizeof(WINDOWPLACEMENT));
wndpl.length = sizeof(WINDOWPLACEMENT);
VERIFY(
::GetWindowPlacement(
mi.GetCmdReceiver(),
&wndpl
)
);
__EXT_MFC_LONG_PTR dwWndStyle = ::__EXT_MFC_GetWindowLong( mi.GetCmdReceiver(), GWL_STYLE );
__EXT_MFC_LONG_PTR dwWndExStyle = ::__EXT_MFC_GetWindowLong( mi.GetCmdReceiver(), GWL_EXSTYLE );
bool bSysCmdEnabled = false;
switch( nCmdID )
{
case SC_CLOSE:
{
bSysCmdEnabled = true;
HMENU hSysMenu = ::GetSystemMenu( mi.GetCmdReceiver(), FALSE );
MENUITEMINFO _mii;
::memset( &_mii, 0, sizeof(MENUITEMINFO) );
_mii.cbSize = sizeof(MENUITEMINFO);
_mii.fMask = MIIM_STATE;
if( hSysMenu != NULL
&& ::GetMenuItemInfo(
hSysMenu,
SC_CLOSE,
FALSE,
&_mii
)
)
{
if( (_mii.fState & MFS_DISABLED) != 0 )
bSysCmdEnabled = false;
} // if( hSysMenu != NULL ...
}
break;
case SC_SIZE:
case SC_MOVE:
if( wndpl.showCmd != SW_SHOWMINIMIZED
&& wndpl.showCmd != SW_SHOWMAXIMIZED
&& !g_bFullScreenMode
)
bSysCmdEnabled = true;
break;
case SC_MINIMIZE:
if( (dwWndStyle & WS_MINIMIZEBOX) != 0
&& wndpl.showCmd != SW_SHOWMINIMIZED
)
bSysCmdEnabled = true;
break;
case SC_MAXIMIZE:
if( (dwWndStyle & WS_MAXIMIZEBOX) != 0
&& wndpl.showCmd != SW_SHOWMAXIMIZED
&& !g_bFullScreenMode
)
bSysCmdEnabled = true;
break;
case SC_RESTORE:
if( (dwWndStyle & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX)) != 0
&& ( wndpl.showCmd == SW_SHOWMAXIMIZED
|| wndpl.showCmd == SW_SHOWMINIMIZED
//||wndpl.showCmd == SW_SHOWNORMAL
)
)
bSysCmdEnabled = true;
break;
case SC_CONTEXTHELP:
if( (dwWndExStyle & WS_EX_CONTEXTHELP) != 0 )
bSysCmdEnabled = true;
break;
// case SC_NEXTWINDOW:
// case SC_PREVWINDOW:
// case SC_VSCROLL:
// case SC_HSCROLL:
// case SC_MOUSEMENU:
// case SC_KEYMENU:
// case SC_ARRANGE:
// case SC_TASKLIST:
// case SC_SCREENSAVE:
//#if(WINVER >= 0x0400)
// case SC_DEFAULT:
// case SC_MONITORPOWER:
// case SC_SEPARATOR:
//#endif /* WINVER >= 0x0400 */
case SC_HOTKEY:
default:
continue;
} // switch( nCmdID )
CExtCmdItem * pCmdItem =
g_CmdManager->CmdGetPtr(
g_CmdManager->ProfileNameFromWnd( m_hWndCmdReceiver ),
nCmdID
);
if( pCmdItem == NULL )
{
pCmdItem =
g_CmdManager->CmdAllocPtr(
g_CmdManager->ProfileNameFromWnd( m_hWndCmdReceiver ),
nCmdID
);
ASSERT( pCmdItem != NULL );
}
pCmdItem->StateEnable( bSysCmdEnabled );
mi.Enable( bSysCmdEnabled );
ASSERT( CExtCmdManager::IsSystemCommand( nCmdID ) );
HWND hWndItemCmdReceiver = mi.GetCmdReceiver();
HMENU hSysMenu = ::GetSystemMenu( hWndItemCmdReceiver, FALSE );
if( hSysMenu != NULL )
{
MENUITEMINFO _mii;
::memset( &_mii, 0, sizeof(MENUITEMINFO) );
_mii.cbSize = sizeof(MENUITEMINFO);
_mii.fMask =
MIIM_CHECKMARKS|MIIM_DATA|MIIM_ID|MIIM_STATE
|MIIM_SUBMENU|MIIM_TYPE;
_mii.cch = __MAX_UI_ITEM_TEXT;
CExtSafeString sMenuItemText;
_mii.dwTypeData = sMenuItemText.GetBuffer( __MAX_UI_ITEM_TEXT );
ASSERT( _mii.dwTypeData != NULL );
if( _mii.dwTypeData != NULL )
{
if( ::GetMenuItemInfo(
hSysMenu,
nCmdID,
FALSE,
&_mii
)
)
{
sMenuItemText.ReleaseBuffer();
sMenuItemText.Replace( _T("\n"), _T("") );
sMenuItemText.Replace( _T("\r"), _T("") );
sMenuItemText.TrimLeft();
sMenuItemText.TrimRight();
if( ! sMenuItemText.IsEmpty() )
{
int nSep =
sMenuItemText.ReverseFind( _T(’\t’) );
if( nSep >= 0 )
{
int nLen = sMenuItemText.GetLength();
pCmdItem->m_sAccelText = sMenuItemText.Right( nLen - nSep );
pCmdItem->m_sAccelText.TrimLeft();
pCmdItem->m_sAccelText.TrimRight();
pCmdItem->m_sMenuText = sMenuItemText.Left( nSep );
pCmdItem->m_sMenuText.TrimLeft();
pCmdItem->m_sMenuText.TrimRight();
}
else
{
pCmdItem->m_sMenuText = sMenuItemText;
pCmdItem->m_sAccelText = _T("");
}
if( pCmdItem->m_nCmdID == SC_CLOSE )
{
CWnd * pWnd = CWnd::FromHandlePermanent( hWndItemCmdReceiver );
if( pWnd != NULL
&& pWnd->IsKindOf( RUNTIME_CLASS(CMDIChildWnd) )
)
pCmdItem->m_sAccelText = _T("Ctrl+F4");
}
mi.SetPopupText( pCmdItem->m_sMenuText );
mi.SetAccelText( pCmdItem->m_sAccelText );
} // if( ! sMenuItemText.IsEmpty() )
}
else
sMenuItemText.ReleaseBuffer();
} // if( _mii.dwTypeData != NULL )
if( (_mii.fState&MFS_DEFAULT) != 0 )
mi.SetDefault();
} // if( hSysMenu != NULL )
} // for(; iter < m_items_all.end(); ++iter )
} // BLOCK: update system commands
CWnd * pWndCmdReceiver =
CWnd::FromHandle( m_hWndCmdReceiver );
ASSERT_VALID( pWndCmdReceiver );
// pWndCmdReceiver->ActivateTopParent();
// pWndCmdReceiver->BringWindowToTop();
// pWndCmdReceiver->SetFocus();
//_site._Hook( true );
// adjust own data
bool bOldTopLevel = m_bTopLevel;
bool bOldExpandAvailable = m_bExpandAvailable;
DWORD dwPortedTrackFlags = m_dwTrackFlags&(TPMX_PALETTE|TPMX_PALETTE_TB_BKGND);
_Init();
m_bTopLevel = bOldTopLevel;
m_bExpandAvailable = bOldExpandAvailable;
m_dwTrackFlags = dwTrackFlags | dwPortedTrackFlags;
m_pCbPaintCombinedCookie = pCbPaintCombinedCookie;
m_pCbPaintCombinedContent = pCbPCC;
m_bCookieIsObject = bCookieIsObject;
if( !m_bTopLevel )
{
ASSERT( m_pWndParentMenu != NULL );
if( m_pWndParentMenu->m_bExpandWasPressed )
{
if( m_bExpandAvailable )
{
m_bExpandAvailable = false;
m_bExpandWasPressed = true;
_SyncItems();
}
else
m_bExpandWasPressed = true;
}
} // if( !m_bTopLevel )
else
{
if( bForceExpandRarelyUsed )
{
if( m_bExpandAvailable )
{
m_bExpandAvailable = false;
m_bExpandWasPressed = true;
_SyncItems();
}
else
m_bExpandWasPressed = true;
} // if( bForceExpandRarelyUsed )
else
_SyncItems();
} // else from if( !m_bTopLevel )
// adjust screen position
m_ptTrack.x = m_ptTrackOriginal.x = x;
m_ptTrack.y = m_ptTrackOriginal.y = y;
if( ( m_ptTrack.x < -32000 || m_ptTrack.y < -32000 )
&& (dwTrackFlags&TPMX_RIBBON_MODE) == 0
)
{
if( ! ::GetCursorPos(&m_ptTrack) )
return FALSE;
}
if( lpRect != NULL )
{
m_rcExcludeArea = *lpRect;
m_bExcludeAreaSpec = true;
}
else
{
m_bExcludeAreaSpec = false;
m_rcExcludeArea.left = m_ptTrack.x - __EXCLUDE_AREA_GAP_DX;
m_rcExcludeArea.right = m_ptTrack.x + __EXCLUDE_AREA_GAP_DX;
m_rcExcludeArea.top = m_ptTrack.y - __EXCLUDE_AREA_GAP_DY;
m_rcExcludeArea.bottom = m_ptTrack.y + __EXCLUDE_AREA_GAP_DY;
}
// adjust combine with exclude area mode
m_bCombineWithEA = false;
if( m_bExcludeAreaSpec )
{
switch( (dwTrackFlags&TPMX_COMBINE_MASK) )
{
case TPMX_COMBINE_ANY_SUITABLE:
m_bCombineWithEA = true;
break;
case TPMX_COMBINE_DEFAULT:
m_bCombineWithEA =
PmBridge_GetPM()->
IsMenuMustCombineExcludeArea(
bCookieIsObject
? ((CObject*)pCbPaintCombinedCookie)
: NULL
);
break;
} // switch( (dwTrackFlags&TPMX_COMBINE_MASK) )
} // if( m_bExcludeAreaSpec )
CSize _size = _CalcTrackSize();
bool bPointAdjusted = true;
if( m_bExcludeAreaSpec )
{
bool bRTL = OnQueryLayoutRTL();
if( bRTL && (!m_bTopLevel) )
{
CExtPopupMenuWnd * pTop = m_pWndParentMenu;
for( ; pTop != NULL; pTop = pTop->GetParentMenuWnd() )
{
if( pTop->_IsTopLevelPopup() )
break;
} // for( ; pTop != NULL; pTop = pTop->GetParentMenuWnd() )
if( pTop != NULL )
{
switch( (pTop->m_dwTrackFlags & TPMX_ALIGN_MASK) )
{
case TPMX_TOPALIGN:
case TPMX_BOTTOMALIGN:
m_dwTrackFlags &= ~(TPMX_ALIGN_MASK);
m_dwTrackFlags |= TPMX_RIGHTALIGN;
break;
} // switch( (pTop->m_dwTrackFlags & TPMX_ALIGN_MASK) )
} // if( pTop != NULL )
} // if( bRTL && (!m_bTopLevel) )
switch( (m_dwTrackFlags & TPMX_ALIGN_MASK) )
{
case TPMX_LEFTALIGN:
m_ptTrack.x = m_rcExcludeArea.right;
m_ptTrack.y = m_rcExcludeArea.top;
break;
case TPMX_RIGHTALIGN:
m_ptTrack.x = m_rcExcludeArea.left - _size.cx;
m_ptTrack.y = m_rcExcludeArea.top;
break;
case TPMX_TOPALIGN:
m_ptTrack.x = m_rcExcludeArea.left;
m_ptTrack.y = m_rcExcludeArea.bottom;
break;
case TPMX_BOTTOMALIGN:
m_ptTrack.x = m_rcExcludeArea.left;
m_ptTrack.y = m_rcExcludeArea.top - _size.cy;
break;
default:
bPointAdjusted = false;
break;
} // switch( (m_dwTrackFlags & TPMX_ALIGN_MASK) )
} // if( m_bExcludeAreaSpec )
if( ! bPointAdjusted )
{
if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_RIGHTALIGN )
m_ptTrack.x -= _size.cx;
else
{
if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_CENTERALIGN )
m_ptTrack.x -= _size.cx/2;
}
if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_BOTTOMALIGN )
m_ptTrack.y -= _size.cy;
else
{
if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_VCENTERALIGN )
m_ptTrack.y -= _size.cy/2;
}
} // if( !bPointAdjusted )
//#ifdef _DEBUG
bool bCreateResult =
//#endif // _DEBUG
_CreateHelper( pWndCmdReceiver );
//ASSERT( bCreateResult );
if( !bCreateResult )
return FALSE;
if( dwTrackFlags & TPMX_SELECT_ANY )
{
int nItem = _GetNextItem(__NI_ANY);
if( nItem >= 0 )
{
HWND hWndOwn = m_hWnd;
_ItemFocusSet(
nItem,
FALSE,
FALSE
);
if( ! ::IsWindow( hWndOwn ) )
return FALSE;
}
}
HWND hWndOwn = m_hWnd;
if( (dwTrackFlags&TPMX_FORCE_NO_ANIMATION) != 0
|| _FindCustomizeMode()
)
m_AnimationType = __AT_NONE;
else
{
m_AnimationType = g_DefAnimationType;
if( CExtToolControlBar::g_bMenuTracking )
m_AnimationType = __AT_NONE;
m_ePlaySoundOnAnimationFinished =
CExtSoundPlayer::__ON_MENU_POPUP_DISPLAYED;
_StartAnimation();
if( ! ::IsWindow( hWndOwn ) )
return FALSE;
} // if( _FindCustomizeMode() )
if( m_AnimationType == __AT_NONE )
{
m_AnimationType = __AT_CONTENT_DISPLAY;
m_ePlaySoundOnAnimationFinished =
CExtSoundPlayer::__ON_MENU_POPUP_DISPLAYED;
_StartAnimation();
if( ! ::IsWindow( hWndOwn ) )
return FALSE;
ASSERT( m_AnimationType == __AT_CONTENT_DISPLAY );
}
if( m_rgnWnd.GetSafeHandle() != NULL )
{
ASSERT( m_bExcludeAreaSpec );
ASSERT( m_bCombineWithEA );
ASSERT( m_eCombineAlign != __CMBA_NONE );
CRgn rgnTmp;
VERIFY( rgnTmp.CreateRectRgn(0,0,0,0) );
rgnTmp.CopyRgn( &m_rgnWnd );
ASSERT( rgnTmp.GetSafeHandle() != NULL );
VERIFY(
SetWindowRgn(
(HRGN)rgnTmp.Detach(),
FALSE
)
);
} // if( m_rgnWnd.GetSafeHandle() != NULL )
if( ! g_PaintManager.m_bIsWin2000orLater )
CExtPaintManager::stat_PassPaintMessages();
bool bFadeOut = _IsFadeOutAnimation();
bool bForceLayered = false;
if( (! bFadeOut)
&& g_PaintManager.m_bIsWin2000orLater
&& g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL
&& ( m_AnimationType == __AT_NONE || m_AnimationType == __AT_CONTENT_DISPLAY )
//&& ( TrackFlagsGet() & TPMX_RIBBON_RESIZING ) == 0
)
bForceLayered = true;
if( bFadeOut || bForceLayered )
{
ASSERT( g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL );
g_PaintManager.m_pfnSetLayeredWindowAttributes( m_hWnd, 0, 1, __EXT_MFC_LWA_ALPHA );
} // if( bFadeOut )
if( g_PaintManager.m_bIsWinVistaOrLater
&& g_PaintManager.m_DWM.IsCompositionEnabled()
)
{
CRect rcCapture;
GetWindowRect( &rcCapture );
HBITMAP hBmpScreenSrcAlt = CExtPaintManager::stat_GetScreenSurfacePart( rcCapture );
if( hBmpScreenSrcAlt != NULL )
{
if( m_bmpScreenSrcAlt.GetSafeHandle() != NULL )
m_bmpScreenSrcAlt.DeleteObject();
m_bmpScreenSrcAlt.Attach( hBmpScreenSrcAlt );
}
}
SetWindowPos(
&CWnd::wndTopMost, 0, 0, 0, 0,
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE
|SWP_SHOWWINDOW|SWP_NOZORDER
);
if( bFadeOut || bForceLayered )
{
ASSERT( g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL );
CExtPaintManager::stat_PassPaintMessages();
g_PaintManager.m_pfnSetLayeredWindowAttributes( m_hWnd, 0, 255, __EXT_MFC_LWA_ALPHA );
} // if( bFadeOut )
else if( ! g_PaintManager.m_bIsWin2000orLater )
CExtPaintManager::stat_PassPaintMessages();
if( ! ::IsWindow( hWndOwn ) )
return FALSE;
ASSERT( IsWindowVisible() );
if( ! _FindCustomizeMode() )
{
_SetCapture();
}
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
else
{
CExtCustomizeSite * pSite = _FindCustomizeSite();
ASSERT( pSite != NULL );
pSite->RegisterCommandDropTarget( this, this );
}
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
if( m_bTopLevel && (! m_bExpandWasPressed ) && m_bExpandAvailable && g_nAutoExpandTime > 0 )
SetTimer( ID_TIMER_AUTO_EXPAND, g_nAutoExpandTime, NULL );
return TRUE;
}
|
|
Technical Support
|
May 6, 2011 - 1:32 AM
|
Please provide us with the following information:
1) Content copied from the Call Stack window in your Visual Studio when your app crashed and break into debugger.
2) Prof-UIS library configuration used in your app.
3) Visual Studio version.
4) Windows OS version.
|
|
Andreas Spachtholz
|
May 6, 2011 - 1:59 AM
|
Hi, here is the information: But it’s completely clear why it crashes. You can reproduce it with the demo application ProfUI:Controls It would be much easier to send all the stuff to an email. Do you have one where I can send the information to? Thanks. A) set a breakpoint at the following lines File: ExtPopupMenuWnd.cpp CExtPopupMenuWnd::_TrackPopupMenu
at the and of the function: ( &CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE |SWP_SHOWWINDOW|SWP_NOZORDER );if( bFadeOut || bForceLayered )ASSERT( g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL );CExtPaintManager::stat_PassPaintMessages();g_PaintManager.m_pfnSetLayeredWindowAttributes( m_hWnd, 0, 255, __EXT_MFC_LWA_ALPHA );// if( bFadeOut ) else if( ! g_PaintManager.m_bIsWin2000orLater )CExtPaintManager::stat_PassPaintMessages();-->>>>HERE ASSERT( IsWindowVisible() );return TRUE;
B) Start the application C) Open a Menu D) The compiler breaks at the first breakpoint - CLICK into the compiler so that the ProfUIS_Control application looses the focus E) Continue debugging F) you get the assertion, continue and CRASH! Here the information you asked for: 1) > mfc100d.dll!CWnd::IsWindowVisible() Line 160 + 0x2d bytes C++
ProfUIS290nd.dll!CExtPopupMenuWnd::_TrackPopupMenu(unsigned long dwTrackFlags, int x, int y, const tagRECT * lpRect, void * pCbPaintCombinedCookie, void (void *, CDC &, const CWnd &, const CRect &, int)* pCbPCC, bool bCookieIsObject) Line 11515 + 0x8 bytes C++
ProfUIS290nd.dll!CExtPopupMenuWnd::TrackPopupMenu(unsigned long dwTrackFlags, int x, int y, const tagRECT * lpRect, void * pCbPaintCombinedCookie, void (void *, CDC &, const CWnd &, const CRect &, int)* pCbPCC, unsigned int * lpnResultCmdID, bool bCookieIsObject) Line 10393 + 0x2f bytes C++
ProfUIS290nd.dll!CExtBarButton::OnTrackPopup(CPoint point, bool bSelectAny, bool bForceNoAnimation) Line 4150 + 0x42 bytes C++
ProfUIS290nd.dll!CExtBarButton::OnClick(CPoint point, bool bDown) Line 4336 + 0x1e bytes C++
ProfUIS290nd.dll!CExtToolControlBar::OnLButtonDown(unsigned int nFlags, CPoint point) Line 11457 + 0x1c bytes C++
ProfUIS290nd.dll!CExtMenuControlBar::OnLButtonDown(unsigned int nFlags, CPoint point) Line 3279 C++
mfc100d.dll!CWnd::OnWndMsg(unsigned int message, unsigned int wParam, long lParam, long * pResult) Line 2495 C++
mfc100d.dll!CWnd::WindowProc(unsigned int message, unsigned int wParam, long lParam) Line 2067 + 0x20 bytes C++
mfc100d.dll!CControlBar::WindowProc(unsigned int nMsg, unsigned int wParam, long lParam) Line 506 + 0x14 bytes C++
ProfUIS290nd.dll!CExtControlBar::WindowProc(unsigned int message, unsigned int wParam, long lParam) Line 8686 C++
ProfUIS290nd.dll!CExtToolControlBar::WindowProc(unsigned int message, unsigned int wParam, long lParam) Line 13400 C++
mfc100d.dll!AfxCallWndProc(CWnd * pWnd, HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 248 + 0x1c bytes C++
mfc100d.dll!AfxWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 411 C++
mfc100d.dll!AfxWndProcBase(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 420 + 0x15 bytes C++
user32.dll!_InternalCallWinProc@20() + 0x23 bytes
user32.dll!_UserCallWinProcCheckWow@32() + 0xb7 bytes
user32.dll!_DispatchMessageWorker@8() + 0xed bytes
user32.dll!_DispatchMessageA@4() + 0xf bytes
mfc100d.dll!AfxInternalPumpMessage() Line 183 C++
mfc100d.dll!CWinThread::PumpMessage() Line 900 C++
mfc100d.dll!CWinThread::Run() Line 629 + 0xd bytes C++
mfc100d.dll!CWinApp::Run() Line 822 C++
Romesd.exe!CRomesApp::Run() Line 1005 + 0x8 bytes C++
mfc100d.dll!AfxWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 47 + 0xd bytes C++
Romesd.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 26 C++
Romesd.exe!__tmainCRTStartup() Line 547 + 0x2c bytes C
Romesd.exe!WinMainCRTStartup() Line 371 C
kernel32.dll!@BaseThreadInitThunk@12() + 0x12 bytes
ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes 2) MFC ANSI , ProfUIS 2.90 3) 2010 4) It happens on XP and Windows 7 Function: ->>>>>HERE SetWindowPos { } }
|
|
Technical Support
|
May 6, 2011 - 11:29 AM
|
This is not a bug. You just came across the code which cannot be debugged using breakpoints. The ASSERT( IsWindowVisible() ) generates an assertion failure because Visual Studio window covers the menu window.
|
|
Andreas Spachtholz
|
May 9, 2011 - 4:38 AM
|
This is clear. The assertion is not the problem, but after the assertion a crash occurs! And this crash can and does occur also during the release version. If for any reason the user clicks at the wrong moment into another applation the ProfUIS application crashes. For sure, this doesn’t occur very often, but it does occur, and we think, that crashes must not happen at all. And if you read my explainations, it’s quite clear why it crashes. So we really would appreciate, if you could fix this problem. Thanks BR, Andreas
|
|
Andreas Spachtholz
|
May 5, 2011 - 5:37 AM
|
Hi, the problem is the following loop. During the PeekMessage function, the WindowsProc Function of the PopupWindow is called with ALL messages, not just the PAINT messages. If it get an ACTIVE_APP messages, the crash occurs. How to fix with problem? BR, Andreas LONG CExtPaintManager::stat_PassPaintMessages(HWND hWnd,bool bPassNcPaint, // = truebool bPassEraseBkgnd, // = truebool bPassPaint // = true nCountPassed = 0L; msg;if( bPassNcPaint )while( ::PeekMessage( &msg, hWnd, WM_NCPAINT, WM_NCPAINT, PM_NOREMOVE ) )if( ! ::PeekMessage( &msg, hWnd, WM_NCPAINT, WM_NCPAINT, PM_REMOVE ) )break;DispatchMessage( &msg );nCountPassed ++;// while( ::PeekMessage( &msg, NULL, WM_NCPAINT, WM_NCPAINT, PM_NOREMOVE ) )// if( bPassNcPaint )if( bPassEraseBkgnd )while( ::PeekMessage( &msg, hWnd, WM_ERASEBKGND, WM_ERASEBKGND, PM_NOREMOVE ) )if( ! ::PeekMessage( &msg, hWnd, WM_ERASEBKGND, WM_ERASEBKGND, PM_REMOVE ) )break;DispatchMessage( &msg );nCountPassed ++;// while( ::PeekMessage( &msg, NULL, WM_ERASEBKGND, WM_ERASEBKGND, PM_NOREMOVE ) )// if( bPassEraseBkgnd )if( bPassPaint )while( ::PeekMessage( &msg, hWnd, WM_PAINT, WM_PAINT, PM_NOREMOVE ) )if( ! ::PeekMessage( &msg, hWnd, WM_PAINT, WM_PAINT, PM_REMOVE ) )break;DispatchMessage( &msg );nCountPassed ++;// while( ::PeekMessage( &msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE ) )// if( bPassPaint )return nCountPassed; ) { LONG MSG { { :: } } { { :: } } { { :: } } }
|
|
Rado Manzela
|
May 2, 2011 - 4:04 PM
|
In CExtEditSystemCurrency::OnSettingChange( UINT uFlags, __EXT_MFC_SAFE_LPCTSTR lpszSection ) you don’t check whether lpszSection is NULL so sometimes it crashes in _tcscmp( lpszSection, _T("intl") )
(for example when switching windows user ). I’ve overridden this function but you could care. It would be nice if you fix other bug with this class I’ve reported to you weeks ago.
|
|
Technical Support
|
May 3, 2011 - 9:41 AM
|
Thank you for reporting this issue. It’s present in two methods CExtEditSystemNumber::OnSettingChange() and CExtEditSystemCurrency::OnSettingChange() : void CExtEditSystemNumber::OnSettingChange(UINT uFlags, __EXT_MFC_SAFE_LPCTSTR lpszSection)
{
ASSERT_VALID( this );
CExtEditSystemNumberCurrencyBase::OnSettingChange( uFlags, lpszSection );
if( LPCTSTR(lpszSection) != NULL && _tcscmp( LPCTSTR(lpszSection), _T("intl") ) == 0 )
{
long double lfSaved = LongDoubleGet();
_Init();
LongDoubleSet( lfSaved );
SetSel( -1, -1 );
}
}
void CExtEditSystemCurrency::OnSettingChange( UINT uFlags, __EXT_MFC_SAFE_LPCTSTR lpszSection )
{
ASSERT_VALID( this );
CExtEditSystemNumberCurrencyBase::OnSettingChange( uFlags, lpszSection );
if( LPCTSTR(lpszSection) != NULL && _tcscmp( LPCTSTR(lpszSection), _T("intl") ) == 0 )
{
long double lfSaved = LongDoubleGet();
_Init();
LongDoubleSet( lfSaved );
SetSel( -1, -1 );
}
}
|
|
Alastair Watts
|
Apr 27, 2011 - 6:44 AM
|
And if not do you have any plans to support the tree grid?
|
|
Technical Support
|
Apr 27, 2011 - 1:35 PM
|
The CExtTreeGridWnd control supports frozen columns and rows. Though frozen rows may never be needed due to tree like data structure in vertical direction.
|
|
Alastair Watts
|
Apr 27, 2011 - 6:43 AM
|
Hello support. I’ve emailed you may times regarding this issue (dating back the January 22nd 2011) and have yet to receive a satisfactory response. Maybe today will be my lucky day eh? Especially as I’ve just renewed my support agreement ;)
|
|
Alastair Watts
|
Apr 28, 2011 - 12:31 PM
|
Hang on a minute ... I don’t think this is want I asked for. I am after a fix for (Show All) being incorrectly ticked having edited a column that is filtered. Please clarify.
|
|
Technical Support
|
Apr 29, 2011 - 12:01 PM
|
We are sorry. We forgot to provide you with one updated method in your test project:
BOOL CtoolbartestDlg::OnCmdMsg(UINT nID, INT nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
CCmdUI * pCmdUI = (CCmdUI*)pExtra;
// update UI
if(nCode == CN_UPDATE_COMMAND_UI)
{
switch(nID)
{
case ID_ADD:
pCmdUI->Enable();
return true;
}
}
// command
if(nCode == CN_COMMAND && nID == ID_ADD)
{
if(pExtra == NULL)
{
CMemFile _file;
CArchive _arStore( &_file, CArchive::store );
bool bHaveState = m_wndGrid.FilterStateForOuterRowSerialize( _arStore, true, 0L, false, false );
_arStore.Close();
if( bHaveState )
{
_file.SeekToBegin();
m_wndGrid.RowUnHideAll( false );
}
m_wndGrid.RowUnHideAll(false);
m_wndGrid.RowRemove(0, 1, false);
m_wndGrid.RowInsert(0, 1, false);
CExtGridCellStringDM* pCell;
pCell = STATIC_DOWNCAST(CExtGridCellStringDM, m_wndGrid.GridCellGet(0L, 0L, 0, 0, RUNTIME_CLASS(CExtGridCellStringDM)));
pCell->TextSet(_T("00"));
// // m_wndGrid.RowUnHideAll( false );
// // m_wndGrid.UpdateStaticFilterValueForOuterRow(-1);
// m_wndGrid.CExtGridWnd::OnGridFilterUpdateForRows(0L, -1L, true, NULL);
m_wndGrid.OnSwUpdateScrollBars();
if( bHaveState )
{
CArchive _arLoad( &_file, CArchive::load );
VERIFY( m_wndGrid.FilterStateForOuterRowSerialize( _arLoad, true, 0L, false, false ) );
_arLoad.Close();
}
m_wndGrid.OnSwDoRedraw();
}
return true;
}
return CExtResizableDialog::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
|
|
Alastair Watts
|
Apr 28, 2011 - 3:53 AM
|
Thanks ... it was my lucky day after all !!!
|
|
Technical Support
|
Apr 27, 2011 - 1:36 PM
|
To resolve the issue you reported we had to serialize filtering conditions and then un-hide and rescan the value filters. This approach makes dynamic value filters working better. You can re-open value filters list box menu and it will contain all the available values, including hidden. Please update the source code for the following methods:
void CExtGridCellHeaderFilter::stat_CalcPlainUniqueValuesForColumn(
CExtArray < CExtSafeString > & arrUniqueStringValues,
const CExtGridWnd & wndGrid,
LONG nColNo
)
{
__EXT_DEBUG_GRID_ASSERT( int( arrUniqueStringValues.GetSize() ) == 0 );
CExtGridWnd * pWndGrid = const_cast < CExtGridWnd * > ( &wndGrid );
CMemFile _file;
CArchive _arStore( &_file, CArchive::store );
bool bHaveState = pWndGrid->FilterStateForOuterRowSerialize( _arStore, true, 0L, false, false );
_arStore.Close();
if( bHaveState )
{
_file.SeekToBegin();
pWndGrid->RowUnHideAll( false );
}
LONG nRowCount = wndGrid.RowCountGet();
for( LONG nRowNo = 0L; nRowNo < nRowCount; nRowNo++ )
{
const CExtGridCell * pCell = wndGrid.GridCellGet( nColNo, nRowNo );
if( pCell != NULL )
{
CExtSafeString str( _T("") );
pCell->TextGet( str );
arrUniqueStringValues.InsertUnique( str );
}
} // for( LONG nRowNo = 0L; nRowNo < nRowCount; nRowNo++ )
if( bHaveState )
{
CArchive _arLoad( &_file, CArchive::load );
VERIFY( pWndGrid->FilterStateForOuterRowSerialize( _arLoad, true, 0L, false, false ) );
_arLoad.Close();
}
}
void CExtGridCellHeaderFilter::stat_CalcPlainUniqueValuesForRow(
CExtArray < CExtSafeString > & arrUniqueStringValues,
const CExtGridWnd & wndGrid,
LONG nRowNo
)
{
__EXT_DEBUG_GRID_ASSERT( int( arrUniqueStringValues.GetSize() ) == 0 );
CExtGridWnd * pWndGrid = const_cast < CExtGridWnd * > ( &wndGrid );
CMemFile _file;
CArchive _arStore( &_file, CArchive::store );
bool bHaveState = pWndGrid->FilterStateForOuterColumnSerialize( _arStore, true, 0L, false, false );
_arStore.Close();
if( bHaveState )
{
_file.SeekToBegin();
pWndGrid->RowUnHideAll( false );
}
LONG nColCount = wndGrid.ColumnCountGet();
for( LONG nColNo = 0L; nColNo < nColCount; nColNo++ )
{
const CExtGridCell * pCell = wndGrid.GridCellGet( nColNo, nRowNo );
if( pCell != NULL )
{
CExtSafeString str( _T("") );
pCell->TextGet( str );
arrUniqueStringValues.InsertUnique( str );
}
} // for( LONG nColNo = 0L; nColNo < nColCount; nColNo++ )
if( bHaveState )
{
CArchive _arLoad( &_file, CArchive::load );
VERIFY( pWndGrid->FilterStateForOuterColumnSerialize( _arLoad, true, 0L, false, false ) );
_arLoad.Close();
}
}
void CExtGridWnd::OnGridFilterChanged(
CExtGridCellHeaderFilter * pHeaderFilterCell,
CExtGridCell::TrackCellStateInfo_t & _tcsi
)
{
__EXT_DEBUG_GRID_ASSERT_VALID( this );
__EXT_DEBUG_GRID_ASSERT( (&_tcsi.m_wndGrid) == this );
__EXT_DEBUG_GRID_ASSERT(
( _tcsi.m_nColType == 0 || _tcsi.m_nRowType == 0 )
&& (! ( _tcsi.m_nColType == 0 && _tcsi.m_nRowType == 0 ) )
);
if( _tcsi.m_nColType == 0 )
{
if( pHeaderFilterCell != NULL && pHeaderFilterCell->m_bDynamicValueFilters )
{
pHeaderFilterCell->m_bValueFilterShowAllState = false;
OnGridFilterCalcPlainUniqueValuesForRow( pHeaderFilterCell->m_arrUniqueStringValues, _tcsi.m_nRowNo );
}
OnGridFilterUpdateForRows( _tcsi.m_nRowNo, _tcsi.m_nColNo, _tcsi.m_nRowType < 0 ? true : false, pHeaderFilterCell );
}
else
{
if( pHeaderFilterCell != NULL && pHeaderFilterCell->m_bDynamicValueFilters )
{
pHeaderFilterCell->m_bValueFilterShowAllState = false;
OnGridFilterCalcPlainUniqueValuesForColumn( pHeaderFilterCell->m_arrUniqueStringValues, _tcsi.m_nColNo );
}
OnGridFilterUpdateForColumns( _tcsi.m_nColNo, _tcsi.m_nRowNo, _tcsi.m_nColType < 0 ? true : false, pHeaderFilterCell );
}
InvalidateRect( &_tcsi.m_rcCellExtra );
UpdateWindow();
}
void CExtGridCellHeaderFilter::OnPopupFilterListBoxItemCheckSet(
INT nItemIndex,
bool bCheck,
CExtPopupInplaceListBox & wndListBox,
CExtGridCell::TrackCellStateInfo_t & _tcsi
)
{
__EXT_DEBUG_GRID_ASSERT_VALID( this );
__EXT_DEBUG_GRID_ASSERT_VALID( (&wndListBox) );
__EXT_DEBUG_GRID_ASSERT( nItemIndex >= 0 );
_tcsi;
wndListBox.SetItemData( nItemIndex, bCheck ? 1 : 0 );
INT i, nCount = (INT)wndListBox.GetCount();
if( nItemIndex == 0 )
{ // "show all" item
m_arrUniqueStringValues.RemoveAll();
if( bCheck )
{
if( m_bDynamicValueFilters )
{
__EXT_DEBUG_GRID_ASSERT(
( _tcsi.m_nColType == 0 || _tcsi.m_nRowType == 0 )
&& (! ( _tcsi.m_nColType == 0 && _tcsi.m_nRowType == 0 ) )
);
if( _tcsi.m_nColType == 0 )
{
if( ! _tcsi.m_wndGrid.OnGridFilterCalcPlainUniqueValuesForColumn( m_arrUniqueStringValues, _tcsi.m_nColNo ) )
return;
}
else
{
if( ! _tcsi.m_wndGrid.OnGridFilterCalcPlainUniqueValuesForRow( m_arrUniqueStringValues, _tcsi.m_nRowNo ) )
return;
}
} // if( m_bDynamicValueFilters
else
m_arrUniqueStringValues += m_arrStaticStringValues;
m_bValueFilterShowAllState = true;
} // if( bCheck )
else
m_bValueFilterShowAllState = false;
for( i = 1; i < nCount; i++ )
wndListBox.SetItemData( i, bCheck ? 1 : 0 );
return;
} // "show all" item
CString s;
wndListBox.GetText( nItemIndex, s );
CExtSafeString sItemText = LPCTSTR(s);
if( bCheck )
m_arrUniqueStringValues += CExtSafeString(LPCTSTR(s));
else
{
int nPos = m_arrUniqueStringValues.BinarySearch( sItemText );
if( nPos >= 0 )
m_arrUniqueStringValues.RemoveAt( nPos );
}
//INT nCheckedCount = (INT)m_arrUniqueStringValues.GetSize();
INT nCheckedCount = 0;
for( i = 1; i < nCount; i++ )
{
bool bCheck = ( wndListBox.GetItemData( i ) != 0 ) ? true : false;
if( bCheck )
nCheckedCount ++;
}
if( nCheckedCount == (nCount-1) )
{
m_bValueFilterShowAllState = true;
wndListBox.SetItemData( 0, 1 ); // set "show all" item
}
else
{
m_bValueFilterShowAllState = false;
wndListBox.SetItemData( 0, 0 ); // clear "show all" item
}
}
|
|
Eric
|
Apr 21, 2011 - 12:06 PM
|
Hello, we are currently migrating from ProfUIS 2.82 to ProfUIS 2.91 and we get an important regression : "Disabled items menu" are not greyed anymore. They are inactive but the text is not greyed and so it is really difficult to see that the item is really disabled. It is the case with all themes excepted with the "Office 2000" and "Native Windows XP / Vista/ 7" ones. We have this issue when we compile our products with VC6.0 but not when we do it on VC 2010. We are also currently migrating to VC 2010 but we would like to be able to these migrations in two steps. Do you have any ideas ?? Regards,
|
|
Eric
|
Apr 26, 2011 - 10:38 AM
|
Hello, As explained before, I HAVE to change Struct Alignment Member setting, so do not change this setting is not possible. And when I have change it, I have change it both in our projects and while generating the profUIS lib. Moreover, when I did the test with your sample app, I regenerated the profUIS lib with the Struct Alignment Member equal to 1 and recompiled the sample project with that setting set to 1 too. Anyway, if you don’t recompile both the lib and the target project with the same Struct Alignment Member value, you get crashes !! Regards,
|
|
Eric
|
Apr 26, 2011 - 9:31 AM
|
Hello, I succeed to reproduce the issue using Prof-UIS sample apps but not by using your default settings. The issue is related to the fact that we have to compile the Prof-UIS libs with a ’Struct Alignment Member’ equal to 1 in our products (Indeed, we depend of another library that force us to use this particular settings.). I hope it will help. Do you have any ideas to solve our issue? Regards,
|
|
Technical Support
|
Apr 26, 2011 - 9:50 AM
|
Please do not change the Struct Alignment Member setting of your project or change it to equal value both in your project and ProfUISDLL or ProfUISLIB projects.
|
|
Eric
|
Apr 21, 2011 - 2:26 PM
|
Hello, This some screenshots got from our products: - With Office 2010 (Black) => Do not work 
- With Office 2007 (Luna-Blue) => Do not work 
- With Native Windows XP/ Vista /7 => work 
But this issue seems not to be only related to the items menu since I have the same kind of issue with disabled items in dialog: - With Office 2007 (Luna-Blue) => Do not work 

- With Native Windows XP/ Vista /7 => Do not work 

I am using the default Windows desktop theme and all these use cases are working while compiling with VC 2010. Regards,
|
|
Technical Support
|
Apr 22, 2011 - 7:38 AM
|
We cannot reproduce this problem using Prof-UIS sample apps. And nobody reported it before yet. Did you try several PCs? Did you code your own paint manager class(es)?
|
|
Technical Support
|
Apr 21, 2011 - 12:40 PM
|
We cannot confirm this problem. Probably it’s specific for your project. Could you please send us a screen shod demonstrating incorrectly painted disabled menu items? Which Windows desktop theme is used on your PC?
|
|
Bogdan Munteanu
|
Apr 20, 2011 - 5:12 AM
|
Lately your services have become obviously subpar while the performance of Prof-Uis is lagging other equivalent packages. Despite numerous attempts on my part to notify you and to narrow down the problems by becoming a virtual beta-tester, your support practically ignored my messages regarding flickering and jitters in the functionality of your library.
Consequently, unless you define a clear and publicly verifiable path of addressing the performance problems in Prof-Uis, I find myself in the regrettable situation of not being able to renew my subscription.
Regards,
Bogdan
|
|
Bogdan Munteanu
|
Apr 20, 2011 - 5:22 PM
|
Thank you for your response.
My main concern is the flickering I mentioned in my previous messages: it has little to do with the number of control bars... In a MDI application there is only one control bar docked on the right side of the frame and no child view (i.e., the background MDI client window is visible). If one widens the main frame by dragging its left side, Prof-UIS moves first the control bar to the left at the same distance it was in the initial view and only after that if repositions the control bar in its docking positions creating a visible left-right flickering. I sent you a couple of times emails with snapshots of the effect described here (use ’Performance settings’ in the ’System properties’ adjusted for ’Best performance’). Eliminating the useless movement to the left of the control bar would solve the flickering problem. This issue likely gets worse with the number of control bars but it is clearly visible even with one control bar on I7-based computers. The same thing happens with the control bars docked to the bottom of the main frame. As long as Prof-UIS takes over the way child windows are rendered, there is surely a way (albeit difficult) to solve this flickering. I would appreciate any guidance regarding this.
Bogdan
PS As for the jittering while hiding/showing the controlbars whenever not pinned, I guess one could fiddle with g_nAutoHideAnimationStepCount and g_nAutoHideAnimationStepTime to obtain a better behavior.
|
|
Technical Support
|
Apr 21, 2011 - 8:26 AM
|
This is not introduced by Prof-UIS. This is effect of delayed non-client area recalculation. It’s present in all the Windows applications. We checked Office 2010 Word (Clipboard control bar), Visual Studio 6.0 and 2008.
|
|
Bogdan Munteanu
|
Apr 24, 2011 - 8:06 PM
|
But isn’t Prof-UIS controlling the rendering process for the Office-based (skinned) themes?
|
|
Technical Support
|
Apr 26, 2011 - 9:40 AM
|
In any case, the window area consist of the inner client area and the outer non-client area. If you see a skinned window frame in Prof-UIS app, then the Prof-UIS measures the size of non client area and paints it. Otherwise you can see the by default measured and painted window non-client area in the DefWindowProc() function. It’s not important which procedure handles the WM_NC*** messages for measuring, painting and hit testing non-client area. It can be DefWindowProc() or CExtNCW::WindowProc() . The resized window principally cannot be immediately updated. Theoretically, it’s possible to code layered window based on per-pixel transparency (i.e. initialized via UpdateLayeredWindow() API) and code window surface as single memory bitmap. But such approach is incompatible with MFC application design.
|
|
Technical Support
|
Apr 20, 2011 - 1:32 PM
|
We re-checked the flickering issue. The ProfStudio sample application displays 42 bars, which makes the ui quite heavy. We confirm ProfStudio does not show best performance. It depends on the number of control bars. Performance is better in SDI environments and, you may notice, Microsoft’s apps does not use the standard MDI. We are sorry if there were any delays with our response.
|
|
Evgueni Kolossov
|
Apr 19, 2011 - 7:32 AM
|
InitColumnComboBox(long nColNo, long nRowNo, std::vector<std::string> & vItems)
{
ASSERT_VALID( this );
ASSERT_VALID( &m_wndGrid );
CExtGridCellComboBox * pCellComboBox =
STATIC_DOWNCAST(
CExtGridCellComboBox,
m_wndGrid.GridCellGet(
nColNo,
nRowNo,
0,
0,
RUNTIME_CLASS(CExtGridCellComboBox)
)
);
pCellComboBox;
CExtGridCellComboBox * pCellComboBox0 =
STATIC_DOWNCAST(
CExtGridCellComboBox,
m_wndGrid.GridCellGet( nColNo, nRowNo )
);
pCellComboBox0->SetEnumMode( true );
for (unsigned int i=0; i < vItems.size(); i++)
{
CString strItem(vItems[i].c_str());
pCellComboBox0->AddString(strItem);
}
pCellComboBox0->SetCurSel(nSelItem);
pCellComboBox0->ModifyStyle( __EGCS_NO_INPLACE_CONTROL );
pCellComboBox0->ModifyStyle( __EGCS_BUTTON_DROPDOWN ); Without __EGCS_NO_INPLACE_CONTROL combo box is not working at all, with it combo box woks on click cell but not on click dropdown button
|
|
Technical Support
|
Apr 20, 2011 - 1:18 PM
|
We cannot confirm this. The problem with combo box grid cells may depend on grid initialization code. Could you send us a small possible test project demonstrating this problem?
|
|
Eric
|
Apr 18, 2011 - 2:54 PM
|
Hello
I am using the report grid.
When I sort, group, expand or collapse I lose the current selection.
I would really like to avoid setting up a system to save and restore my selection structure.
Is there a way to tell the report grid not to reset the selection during a sorting, grouping, expand or collapse operation?
|
|
Technical Support
|
Apr 20, 2011 - 1:20 PM
|
The focused row remains only if it’s a data row. Group rows are re-created during re-sorting/re-grouping.
|
|
Offer Har
|
Apr 14, 2011 - 6:43 AM
|
Hi, We would like to save the state of the UI when it changed, and not when the application exits, so that if the application crashes or killed it will remember its state. Is there any way to do it without periodically saving the state? For example, is there any event that can be caught when the UI state is changed? Thanks, Ron.
|
|
Technical Support
|
Apr 21, 2011 - 12:39 PM
|
If you have two control bars docked into one vertical column and state of top control bar should not be serialized, then how do we know the bottom control bar’s state should be restored and bottom bar should appear at the bottom side of the top bar? Ron, it’s not possible to serialize state of some bars only. We need to try to take a look at UI design in your app in some different way. Or, we need more details about your app.
|
|
Technical Support
|
Apr 20, 2011 - 1:27 PM
|
1) Yes.
2) It’s not possible to avoid state saving for particular bars. The state of each bar always mutually depend on other bars. This is related for all control bar types. You can simply hide the bars which do not require user attention.
|
|
Technical Support
|
Apr 14, 2011 - 1:48 PM
|
Thank you for the interesting question. Please create and use your own CExtControlBar -derived class which should override the CExtControlBar::OnControlBarPositionChange() virtual method to catch any layout changing. If the bFinal method parameter is true , then user has stopped changing control bar layout (dragging, double clicking, etc.) and you can save control bar state. You can save it immediately. You can also use some timer and flag to implement periodic state saving only when layout is really changed and not more often then some time interval. In the last case the overriden CExtControlBar::OnControlBarPositionChange() virtual method should only set flag value for further usage inside timer handler code. The timer handler should save control bar states only of there are no control bar drag-n-dropping is occurred at the timer event moment (CExtControlBar::_DraggingGetBar() ).
|
|
Offer Har
|
Apr 17, 2011 - 4:33 AM
|
Dear Support, I did a test, and added the virtual function. I see that for every control bar or toolbar I move, the function is invoked for ALL the control and tool bars in my system... this seems to be a lot of overhead over nothing - for example, if a control-bar is floating even on a different monitor, this happens - please check this, as it seems to be a bug. Thanks, Ron.
|
|
Offer Har
|
Apr 17, 2011 - 4:05 AM
|
Dear Support, Thank you for the detailed answer. Before I go and do it, there are two issues that we still need to clarify: 1. Will it work also with toolbars (CExtToolControlBar derived) - I think this is trivial... 2. We have some control-bars that we do not save their state - the way we currently do it, is that we close them when the application is about to exit, and this way their state is not saved. When changing the concept to the one we now want, we need some method of not serializing these controls to the state data - is there any way of doing this? This is a show-stopper for us... Thanks,
Ron.
|
|
Offer Har
|
Apr 20, 2011 - 1:44 PM
|
That’s a MAJOR problem for us. Isn’t there a place where you iterate over all control-bar and save their state? We cannot hide them, as it will flicker when we do it... as we want to do periodically. Please help us solve this problem.
|
|
Technical Support
|
Apr 21, 2011 - 5:16 AM
|
Mutual state dependency of each control bar on other control bars does not allow us to avoid flickering in 100% of cases. If we cannot solve something, then we should hide it from the user. HWND hWndMainFrame = . . .
CRect rcSurface;
::GetWindowRect( hWndMainFrame, &rcSurface );
HWND hWndSurface =
::CreateWindowEx(
0, _T("Static"), _T(""), WS_POPUP,
rcSurface.left,
rcSurface.top,
rcSurface.Width()
+ ( ( _wp.showCmd == SW_SHOWNORMAL
&& g_PaintManager.m_bIsWinXPorLater
) ? 1 : 0 // +1 for recomputing Window HRGN on WindowsXP or Later
),
rcSurface.Height(),
hWndOwn, (HMENU)NULL, ::AfxGetInstanceHandle(), NULL
);
ASSERT( hWndSurface != NULL );
::EnableWindow( hWndSurface, FALSE );
::ShowWindow( hWndSurface, SW_SHOWNOACTIVATE );
//
// TO-DO: do anything you want with control bars inside main frame
//
::DestroyWindow( hWndSurface );
CExtPaintManager::stat_PassPaintMessages();
|
|
Offer Har
|
Apr 21, 2011 - 9:45 AM
|
We cannot have flickers for this task... this will kill our system. Another suggestion - can we add some property to each control-bar if we want to load it - we will save it, but when the system will open and load its state, it will look for this flag, and if the control-bar is marked as no-load it will hide it. This *might* flicker when the application loads, but this will flicker only once. Is it possible to add this to the next version? Thanks, Ron
|
|
Jeroen Walter
|
Apr 11, 2011 - 3:55 AM
|
Hi
There is a bug in CExtSpinWnd (using profuis v2.87, but code in 2.91 is the more or less the same).
The problem:
I want to notify the user when the value associated with the CExtSpinWnd becomes too large and ask the user if he wants to continue.
I do this via the UDN_DELTAPOS notification of the spincontrol. The UDN_DELTAPOS notification should allow me to accept the position change or to reject it.
This notification is called during the OnLButtonDown handler, in the call to CSpinButtonCtrl::OnLButtonDown, right before _ProcessMouseClick is called.
Now, after I have notified the user using a modal dialog in the UDN_DELTAPOS handler, the CExtSpinWnd calls _ProcessMouseClick.
_ProcessMouseClick assumes that the mouse button is still pressed (which it isn’t as the user had to click away the message box).
Consequently, _ProcessMouseClick captures the mouse via ::SetCapture. This should not happen, as the user interaction with the spin control already has ended.
The effect is that the next mouse click always triggers the same OnLButtonDown instead of the OnLButtonUp, even if the mouse is not on the control !
This is caused by _ProcessMouseMove, as it still thinks that the mousebutton is pressed.
This causes the UDN_DELTAPOS notification to be send again, notifying the user again, which it shouldn’t.
Furthermore, the spin control is drawn incorrectly, because the hover state is not determined correctly in this scenario.
I’ve made a small fix, which hopefully is sufficient. If this is not the right way, please let me know.
_ProcessMouseMove must get the nFlags parameter from OnMouseMove and check if the buttons are still pressed.
bool CExtSpinWnd::_ProcessMouseMove(UINT nFlags, CPoint point)
{
ASSERT_VALID( this );
if( CExtPopupMenuWnd::IsMenuTracking()
|| (! CExtPopupMenuWnd::TestHoverEnabledFromActiveHWND( GetSafeHwnd() ) )
)
return false;
// FIX: check if button is still pressed.
if (m_bButtonUpPressed || m_bButtonDownPressed)
{
bool pressed = nFlags & MK_LBUTTON;
m_bButtonUpPressed &= pressed;
m_bButtonDownPressed &= pressed;
_ProcessMouseClick( point, false, MK_LBUTTON );
}
CRect rcButtonUp, rcButtonDown;
.... rest of the original code ....
}
|
|
Technical Support
|
Apr 13, 2011 - 2:20 AM
|
Thank you for reporting this issue. The following version of the fix does not require adding a method parameter, does not perform unnecessary button releasing event emulation and correctly handles Windows swapped mouse buttons setting: bool CExtSpinWnd::_ProcessMouseMove( CPoint point )
{
ASSERT_VALID( this );
if( CExtPopupMenuWnd::IsMenuTracking()
|| (! CExtPopupMenuWnd::TestHoverEnabledFromActiveHWND( GetSafeHwnd() ) )
)
return false;
if( m_bButtonUpPressed || m_bButtonDownPressed )
{
bool bMouseButtonsNotSwapped = ( ::GetSystemMetrics( SM_SWAPBUTTON ) != 0 ) ? false : true;
int nMouseKey = bMouseButtonsNotSwapped ? VK_LBUTTON : VK_RBUTTON;
bool bReallyPressed = CExtPopupMenuWnd::IsKeyPressed( nMouseKey ) ? true : false;
if( ! bReallyPressed )
{
SendMessage( WM_CANCELMODE );
return false;
}
}
CRect rcButtonUp, rcButtonDown;
GetButtonRect( rcButtonUp, rcButtonDown );
bool bButtonUpHoveredPrev = m_bButtonUpHovered;
bool bButtonDownHoveredPrev = m_bButtonDownHovered;
bool bButtonUpHoveredNext = false;
bool bButtonDownHoveredNext = false;
if( ( ! rcButtonUp.IsRectEmpty() ) && rcButtonUp.PtInRect( point ) )
bButtonUpHoveredNext = true;
if( ( ! rcButtonDown.IsRectEmpty() ) && rcButtonDown.PtInRect( point ) )
bButtonDownHoveredNext = true;
if( bButtonUpHoveredNext || bButtonDownHoveredNext )
{
if( ::GetCapture() != GetSafeHwnd() )
::SetCapture( GetSafeHwnd() );
}
else if( ( ! m_bButtonUpPressed ) && ( ! m_bButtonDownPressed) )
{
if( ::GetCapture() == GetSafeHwnd() )
::ReleaseCapture();
}
if( bButtonUpHoveredNext != bButtonUpHoveredPrev || bButtonDownHoveredNext != bButtonDownHoveredPrev )
{
bool bAnimationLocked = AnimationClient_CacheGeneratorIsLocked();
if( ! bAnimationLocked )
{
AnimationClient_CacheGeneratorLock();
AnimationClient_CacheNextStateMinInfo(
false,
( bButtonUpHoveredNext || bButtonDownHoveredNext ) ? __EAPT_BY_HOVERED_STATE_TURNED_ON : __EAPT_BY_HOVERED_STATE_TURNED_OFF
);
}
m_bButtonUpHovered = bButtonUpHoveredNext;
m_bButtonDownHovered = bButtonDownHoveredNext;
if( ! bAnimationLocked )
{
AnimationClient_CacheNextStateMinInfo(
true,
( bButtonUpHoveredNext || bButtonDownHoveredNext ) ? __EAPT_BY_HOVERED_STATE_TURNED_ON : __EAPT_BY_HOVERED_STATE_TURNED_OFF
);
AnimationClient_CacheGeneratorUnlock();
}
Invalidate();
}
return true;
}
|
|
Jeroen Walter
|
Apr 13, 2011 - 2:32 AM
|
|
|
Jeroen Walter
|
Apr 11, 2011 - 4:00 AM
|
mmm a better fix would be:
if (m_bButtonUpPressed || m_bButtonDownPressed)
{
if (!(nFlags & MK_LBUTTON))
{
// Simulate button up event.
_ProcessMouseClick( point, false, MK_LBUTTON );
}
}
Still, I’m not sure if this is the right fix.
|
|
Carsten Pedersen
|
Apr 8, 2011 - 7:08 AM
|
Hi,
I’m subclassing CExtLabel, and am using it as a static image placeholder. I have a CExtBitmap as a member in the class, which I’m initializing like this:
g_ResourceManager->LoadBitmap(m_Image, IDB_BITMAP_QUESTION); m_Image.Make32();
// mark magenta color pixels as transparent COLORREF clrTransparent = RGB(255,255,255); // magenta m_Image.AlphaColor( clrTransparent, RGB(0,0,0), BYTE(0) ); SetImageMode(CExtLabel::eStretch);
SetBitmapEx(&m_Image);
My problem is, even though I set the Image mode to eStretch, the image quality looks like ColorOnColor, not Halftone. I have stepped into CExtLabel::DoPaint method, and it correctly calls if( eImageMode == eStretch ) m_bmp.AlphaBlendSkinParts( dc.GetSafeHdc(), rcClient, CRect(0,0,0,0), CExtBitmap::__EDM_STRETCH, true, bSmootherAsPossible);
Is there something I’m doing wrong?
If I on the other hand, use a ATL::CImage as my image class, and make my class OwnerDraw, I can get the desired quality when using these methods in the DrawItem overloaded function: SetStretchBltMode(lpDrawItemStruct->hDC, HALFTONE); SetBrushOrgEx(lpDrawItemStruct->hDC, 0, 0, nullptr); m_Image.StretchBlt(lpDrawItemStruct->hDC, rc);
(However, this poses a problem, namely that I cannot define a transparent color, hence the border of my circular image is white)
Thanks in advance,
Carsten Pedersen
|
|
Technical Support
|
Apr 12, 2011 - 2:27 AM
|
We confirm this. Here is the test project we used: http://www.prof-uis.com/download/forums/TestImageLabel.zip We found that the problem is actually not a problem. This is behavior of the AlpaBlend() Win32 API from <b>MsImg32.DLL</code> module. This is probably surprising change of Windows 7 because SetStretchBltMode() Win32 API affects both StretchBlt() and AlphaBlend() APIs in older Windows versions. We can provide you with a workaround. Please try to un-comment the following two lines in our test project and see the Adobe Photoshop image stretching quality inside scaled CExtLabel control:
//CExtBitmap:: Filter _f( CExtBitmap::Filter::b_spline );
// VERIFY( m_Image.Scale( 1024, 1024, _f ) );
|
|
Carsten Pedersen
|
Apr 12, 2011 - 1:08 PM
|
Thank you, with the desired scaling input, it yielded satisfactory results! As a side note - I tried to use static libs with your test project, however it asserted in the following line:
VERIFY( m_bmpFilterApplied.LoadBMP_Resource( MAKEINTRESOURCE( IDB_EXT_BITMAP_FILTER_APPLIED ) ) );
In ExtPaintManager.cpp. There is no problem with the DLL version of profUIS. Why is this?
|
|
Technical Support
|
Apr 13, 2011 - 1:07 PM
|
Please drop us an e-mail to the support mail box at this web site so we will provide you with the fix for this resource loading issue.
|
|
Carsten Pedersen
|
Apr 11, 2011 - 12:36 AM
|
I saw that after I posted the message, that I had made a comment error. We want to have white as transparent, so the comment is wrong. There is no problem with transparency, as the white in the image is correctly treated as transparent. So I’m still experiencing the low quality issue. As I wrote, If I replace your code with the ATL::CImage variant, the image i nicely smoothed, but transparency is not done.
|
|
Technical Support
|
Apr 9, 2011 - 7:37 AM
|
First of all, you wrote: COLORREF clrTransparent = RGB(255,255,255); // magenta
The RGB(255,255,255) color is white . The RGB(255,0,255) color is magenta . Second, the eImageMode enumeration defines how to draw image - not which quality of stretching to use. The bSmootherAsPossible flag parameter set to true specifies the halftone stretching should be used. The CExtLabel draws using halftone stretching by default. We suspect the problem is in the incorrect magenta color.
|
|
Rado Manzela
|
Apr 7, 2011 - 6:52 AM
|
I set background color of cell this way:
c->BackColorSet(CExtGridCell::__ECS_NORMAL,bc); c->BackColorSet(CExtGridCell::__ECS_READ_ONLY,bc);
it works, but problem is that when I select the cell (full row selection), then I focus control outside the grid, selection is hidden (it’s ok), but cell is drawn with default white background. Can you fix it please? Thank you.
|
|
Technical Support
|
Apr 13, 2011 - 2:21 AM
|
We fixed colored cells handling code. Now BackColorSet() API works like you requested. Thank you. Please update the source code for the following two methods:
COLORREF CExtGridCell::OnQueryTextColor(
const CExtGridWnd & wndGrid,
CDC & dc,
LONG nVisibleColNo,
LONG nVisibleRowNo,
LONG nColNo,
LONG nRowNo,
INT nColType,
INT nRowType,
DWORD dwAreaFlags,
DWORD dwHelperPaintFlags
) const
{
__EXT_DEBUG_GRID_ASSERT_VALID( this );
if( (dwHelperPaintFlags&__EGCPF_PRINTING_TARGET_MASK) != 0 )
{
COLORREF clr = TextColorGet( CExtGridCell::__ECS_PPV );
if( clr == COLORREF(-1L) )
clr = TextColorGet( CExtGridCell::__ECS_ALL );
return clr;
}
COLORREF clr = // COLORREF(-1L); // use current DC text color if COLORREF(-1L)
wndGrid.OnGridCellQueryTextColor( *this, dc, nVisibleColNo, nVisibleRowNo, nColNo, nRowNo, nColType, nRowType, dwAreaFlags, dwHelperPaintFlags );
if( clr != COLORREF(-1L) )
return clr;
clr = TextColorGet( __ECS_ALL );
if( clr != COLORREF(-1L) )
return clr;
clr = COLORREF(-1L);
bool bHoverByColumn = ( (dwHelperPaintFlags&__EGCPF_HOVER_BY_COLUMN) != 0 ) ? true : false;
bool bHoverByRow = ( (dwHelperPaintFlags&__EGCPF_HOVER_BY_ROW) != 0 ) ? true : false;
bool bHighlightedBySelectedColumn = ( (dwHelperPaintFlags&__EGCPF_HIGHLIGHTED_BY_SELECTED_COLUMN) != 0 ) ? true : false;
bool bHighlightedBySelectedRow = ( (dwHelperPaintFlags&__EGCPF_HIGHLIGHTED_BY_SELECTED_ROW) != 0 ) ? true : false;
bool bHighlightedByFocusedColumn = ( (dwHelperPaintFlags&__EGCPF_HIGHLIGHTED_BY_FOCUSED_COLUMN) != 0 ) ? true : false;
bool bHighlightedByFocusedRow = ( (dwHelperPaintFlags&__EGCPF_HIGHLIGHTED_BY_FOCUSED_ROW) != 0 ) ? true : false;
bool bFocusedControl = ( (dwHelperPaintFlags&__EGCPF_FOCUSED_CONTROL) != 0 ) ? true : false;
bool bHighlightPressing = ( (dwHelperPaintFlags&(__EGCPF_HIGHLIGHTED_BY_PRESSED_COLUMN|__EGCPF_HIGHLIGHTED_BY_PRESSED_ROW)) != 0 ) ? true : false;
bool bReadOnly = ( ( GetStyle() & __EGCS_READ_ONLY ) != 0 ) ? true : false;
if( bHighlightPressing )
clr = TextColorGet( __ECS_HIGHLIGHT_PRESSING );
else if( bHighlightedByFocusedColumn || bHighlightedByFocusedRow )
clr = TextColorGet( __ECS_HIGHLIGHT_BY_FOCUS );
else if( bHighlightedBySelectedColumn || bHighlightedBySelectedRow )
clr = TextColorGet( __ECS_HIGHLIGHT_BY_SELECTION );
else if( bHoverByColumn && bHoverByRow )
clr = TextColorGet( __ECS_HOVERED );
else if( bHoverByColumn || bHoverByRow )
clr = TextColorGet( __ECS_HIGHLIGHT_BY_HOVER );
else if( ( dwAreaFlags & __EGBWA_OUTER_CELLS ) == 0
&& ( bFocusedControl || wndGrid.NoHideSelectionGet() )
&& wndGrid.SelectionGetForCellPainting( nColNo, nRowNo )
)
clr = TextColorGet( __ECS_SELECTED );
else if( bReadOnly )
clr = TextColorGet( __ECS_READ_ONLY );
else
clr = TextColorGet( __ECS_NORMAL );
if( clr != COLORREF(-1L) )
return clr;
if( bFocusedControl )
{
if( bHighlightPressing )
clr = wndGrid.OnSiwGetSysColor( COLOR_HIGHLIGHTTEXT );
else
{
if( ( dwAreaFlags & __EGBWA_OUTER_CELLS ) != 0 )
{
if( bHoverByColumn
|| bHoverByRow
|| bHighlightedBySelectedColumn
|| bHighlightedBySelectedRow
|| bHighlightedByFocusedColumn
|| bHighlightedByFocusedRow
)
clr = wndGrid.OnSiwGetSysColor( COLOR_HIGHLIGHTTEXT );
} // if( ( dwAreaFlags & __EGBWA_OUTER_CELLS ) != 0 )
else
if( wndGrid.SelectionGetForCellPainting( nColNo, nRowNo ) )
clr = wndGrid.OnSiwGetSysColor( COLOR_HIGHLIGHTTEXT );
} // else from if( bHighlightPressing )
} // if( bFocusedControl )
if( clr != COLORREF(-1L) )
return clr;
if( bReadOnly )
clr = wndGrid.OnSiwGetReadOnlyTextColor();
return clr;
}
COLORREF CExtGridCell::OnQueryBackColor(
const CExtGridWnd & wndGrid,
CDC & dc,
LONG nVisibleColNo,
LONG nVisibleRowNo,
LONG nColNo,
LONG nRowNo,
INT nColType,
INT nRowType,
DWORD dwAreaFlags,
DWORD dwHelperPaintFlags
) const
{
__EXT_DEBUG_GRID_ASSERT_VALID( this );
COLORREF clr = // COLORREF(-1L); // use current DC back color if COLORREF(-1L)
wndGrid.OnGridCellQueryBackColor( *this, dc, nVisibleColNo, nVisibleRowNo, nColNo, nRowNo, nColType, nRowType, dwAreaFlags, dwHelperPaintFlags );
if( clr != COLORREF(-1L) )
return clr;
if( IsInvisible() )
return COLORREF(-1L);
if( (dwHelperPaintFlags&__EGCPF_PRINTING_TARGET_MASK) != 0 )
{
COLORREF clr = BackColorGet( CExtGridCell::__ECS_PPV );
if( clr == COLORREF(-1L) )
clr = BackColorGet( CExtGridCell::__ECS_ALL );
return clr;
}
clr = BackColorGet( __ECS_ALL );
if( clr != COLORREF(-1L) )
return clr;
clr = COLORREF(-1L);
bool bHoverByColumn = ( (dwHelperPaintFlags&__EGCPF_HOVER_BY_COLUMN) != 0 ) ? true : false;
bool bHoverByRow = ( (dwHelperPaintFlags&__EGCPF_HOVER_BY_ROW) != 0 ) ? true : false;
bool bHighlightedBySelectedColumn = ( (dwHelperPaintFlags&__EGCPF_HIGHLIGHTED_BY_SELECTED_COLUMN) != 0 ) ? true : false;
bool bHighlightedBySelectedRow = ( (dwHelperPaintFlags&__EGCPF_HIGHLIGHTED_BY_SELECTED_ROW) != 0 ) ? true : false;
bool bHighlightedByFocusedColumn = ( (dwHelperPaintFlags&__EGCPF_HIGHLIGHTED_BY_FOCUSED_COLUMN) != 0 ) ? true : false;
bool bHighlightedByFocusedRow = ( (dwHelperPaintFlags&__EGCPF_HIGHLIGHTED_BY_FOCUSED_ROW) != 0 ) ? true : false;
bool bFocusedControl = ( (dwHelperPaintFlags&__EGCPF_FOCUSED_CONTROL) != 0 ) ? true : false;
bool bHighlightPressing = ( (dwHelperPaintFlags&(__EGCPF_HIGHLIGHTED_BY_PRESSED_COLUMN|__EGCPF_HIGHLIGHTED_BY_PRESSED_ROW)) != 0 ) ? true : false;
bool bReadOnly = ( ( GetStyle() & __EGCS_READ_ONLY ) != 0 ) ? true : false;
if( bHighlightPressing )
clr = BackColorGet( __ECS_HIGHLIGHT_PRESSING );
else if( bHighlightedByFocusedColumn || bHighlightedByFocusedRow )
clr = BackColorGet( __ECS_HIGHLIGHT_BY_FOCUS );
else if( bHighlightedBySelectedColumn || bHighlightedBySelectedRow )
clr = BackColorGet( __ECS_HIGHLIGHT_BY_SELECTION );
else if( bHoverByColumn && bHoverByRow )
clr = BackColorGet( __ECS_HOVERED );
else if( bHoverByColumn || bHoverByRow )
clr = BackColorGet( __ECS_HIGHLIGHT_BY_HOVER );
else if( ( dwAreaFlags & __EGBWA_OUTER_CELLS ) == 0
&& ( bFocusedControl || wndGrid.NoHideSelectionGet() )
&& wndGrid.SelectionGetForCellPainting( nColNo, nRowNo )
)
clr = BackColorGet( __ECS_SELECTED );
else if( bReadOnly )
clr = BackColorGet( __ECS_READ_ONLY );
else
clr = BackColorGet( __ECS_NORMAL );
if( clr != COLORREF(-1L) )
return clr;
if( bFocusedControl )
{
if( bHighlightPressing )
clr = wndGrid.OnSiwGetSysColor( COLOR_HIGHLIGHT );
else
{
if( ( dwAreaFlags & __EGBWA_OUTER_CELLS ) != 0 )
{
if( bHoverByColumn
|| bHoverByRow
|| bHighlightedBySelectedColumn
|| bHighlightedBySelectedRow
|| bHighlightedByFocusedColumn
|| bHighlightedByFocusedRow
)
clr = wndGrid.OnSiwGetSysColor( COLOR_HIGHLIGHT );
} // if( ( dwAreaFlags & __EGBWA_OUTER_CELLS ) != 0 )
else
if( wndGrid.SelectionGetForCellPainting( nColNo, nRowNo ) )
clr = wndGrid.OnSiwGetSysColor( COLOR_HIGHLIGHT );
} // else from if( bHighlightPressing )
} // if( bFocusedControl )
if( clr != COLORREF(-1L) )
return clr;
if( bReadOnly )
clr = wndGrid.OnSiwGetReadOnlyBackgroundColor();
return clr;
}
|
|
Rado Manzela
|
Apr 14, 2011 - 7:55 AM
|
|
|
Technical Support
|
Apr 9, 2011 - 7:38 AM
|
If the CExtGridCell::BackColorSet() method does not cover cover your grid coloring tasks, you should implement the CExtGridCell::OnQueryBackColor() or CExtGridWnd::OnGridCellQueryBackColor() virtual method. If the dwHelperPaintFlags parameter contains both __EGCPF_HIGHLIGHTED_BY_FOCUSED_COLUMN and __EGCPF_HIGHLIGHTED_BY_FOCUSED_ROW flags then the method should return a background color for the focused cell.
|
|
Rado Manzela
|
Apr 12, 2011 - 8:20 AM
|
I’m using more types of cells so it would me lot of overloading and creating of new cell types. I’ve removed all BackColorSet() and tried to do this:
COLORREF CMyGridWnd::OnGbwQueryBackColor( CDC & dc, LONG nVisibleColNo, LONG nVisibleRowNo, LONG nColNo, LONG nRowNo, INT nColType, INT nRowType, DWORD dwAreaFlags, DWORD dwHelperPaintFlags ) const { TRACE("row=%d col=%d PF=%x\n",nRowNo,nColNo,dwHelperPaintFlags); if (nRowType == 0 && nColType == 0 && !(dwHelperPaintFlags&__EGCPF_HIGHLIGHTED_BY_SELECTED_ROW) && !(dwHelperPaintFlags&__EGCPF_HIGHLIGHTED_BY_FOCUSED_ROW) && !(dwHelperPaintFlags& __EGCPF_FOCUSED_CONTROL) ) { return RGB(255,0,0); }
return __super::OnGbwQueryBackColor( dc, nVisibleColNo, nVisibleRowNo, nColNo, nRowNo, nColType, nRowType, dwAreaFlags, dwHelperPaintFlags); }
but it is unusable, because I can see in trace output that when I select one row in grid, it is called for all cells only with __EGCPF_FOCUSED_CONTROL flag set (also for other rows, which are not selected). Is it another bug or am I missing something?
BTW BackColorSet() still has strange behaviour, I think it should correctly handle situation with unfocused grid when selection is hidden.
|
|
Alastair Watts
|
Apr 6, 2011 - 9:06 AM
|
I’m trying to create a CListBoxMenuLike (from your sample) in a splitter in a dialog but it fails. Other controls create OK so what am i doing wrong?
m_wndListBox.Create(WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | LBS_OWNERDRAWVARIABLE | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT,CRect(0, 0, 0), &m_wndSplitter.IdFromRowCol(0, 1));
|
|
Technical Support
|
Apr 9, 2011 - 7:35 AM
|
Then we need more details or a test project.
|
|
Alastair Watts
|
Apr 6, 2011 - 12:11 PM
|
Thats just a typo :) Am I specifying WS_CHILD
|
|
Technical Support
|
Apr 6, 2011 - 12:00 PM
|
Please do not forget to specify the WS_CHILD window style.
|
|