Subject |
Author |
Date |
|
Gevork Odabashyan
|
Dec 4, 2009 - 6:59 AM
|
Dear support,
the two monitor problem not completely resolved in version 2.8.7.
To reproduced this problem we used ’FormulaGrid’ sample from url: http://www.prof-uis.com/download/samples/win32/FormulaGrid.zip
running on Windows XP SP3 with two monitors.
To reproduced bug we used the next steps:
- Expand task main frame on two monitors.
- Block current session (Ctrl+Alt+Del, Enter)
- Unblock session and see that task main frame reposition to one monitor (instead two monitors).
The same problem appear when new icon adds to system tray (for example Outlook Express notifies about new message).
We and our users waiting for resolving this problem from version 2.8.4 but it still in 2.8.7.
When you plan to resolve this problem?
|
|
Technical Support
|
Dec 14, 2009 - 9:28 AM
|
We just want to notify you we are working on the fix. We use the two monitors with different resolutions because we didn’t reproduce this size jumping issue on a single monitor environments.
|
|
Gevork Odabashyan
|
Dec 11, 2009 - 6:35 AM
|
Have we chance to get work around for this bug?
|
|
Gevork Odabashyan
|
Dec 11, 2009 - 7:08 AM
|
Attention!
The bug reproduced on ProfStudio sample builded from 2.87 release sample sources.
If download ProfStudio sample from you site the bug not reproduced.
Maybe its help to fix the bug.
We need to get work around for this bug in the short time!
|
|
Emmanuel V.
|
Dec 4, 2009 - 1:27 AM
|
I have a CExtSpinWnd associated to a CExtEdit control. <o:p></o:p>The CExtEdit control is associated to an integer : DDX_Text(pDX, IDC_NUMBER, m_nNumber); <o:p></o:p> When you increase the value using the CExtSpinWnd, it adds a space for the thousand separator character (French regional settings). <o:p></o:p> But the DDX can’t accept a value with a space. So it displays a message as “input an integer value”<o:p></o:p> How can I solve that ?<o:p></o:p> Thanks.
|
|
Technical Support
|
Dec 4, 2009 - 10:51 AM
|
We used the System Number and Currency Editors dialog page of the ProfUIS_Controls sample application for testing the reported issue:
http://www.prof-uis.com/download/forums/tmp/SpinTestingWithEditors000.png
We added the following properties into the CPageSystemNumberCurrencyEditors class:
INT m_nTestNumberWholeDigits, m_nTestNumberFractionDigits;
And we added the DDX entries for them: CPageSystemNumberCurrencyEditors::DoDataExchange() DDX_Text( pDX, IDC_EDIT_MAX_WHOLE_DIGITS, m_nTestNumberWholeDigits );
DDX_Text( pDX, IDC_EDIT_MAX_FRACTION_DIGITS, m_nTestNumberFractionDigits );
But the issue you reported didn’t appear. So, we need additional information and your help with reproducing it.
|
|
Borremans Pierre
|
Nov 30, 2009 - 6:43 AM
|
I create a context menu with help of CExtPopupMenuWnd. But if I dinamycaly change the item’s text. Sometimes all characteres aren’t visible. how to correct my problem ?
|
|
Robert Webb
|
Nov 27, 2009 - 1:07 AM
|
When using ProfUIS, various things may pop up, such as menus, tooltips, etc. These may overlap with the main workspace. Our application uses OpenGL for graphics, and rendering a scene can be quite computationally expensive, so we wish to avoid redraws whenever possible.
Now some things that pop up cause a paint message to be sent, and some do not. For example, with a ribbon bar, the main application menu may be quite large, but it does not send a paint message for the view area, although it overlaps. I believe it grabs a bitmap and replaces it afterwards?
Drop-downs from ribbon bar items also avoid sending a paint message.
However, tooltips and old-style menus from a menu bar DO send a paint message. Tooltips are particularly troublesome, because just pausing the mouse somewhere can cause the main window to redraw. A tooltip comes up, and when it goes away a paint message is sent. Tooltips may also appear while browsing through a drop-down menu from the ribbon bar. A redraw at this point draws over the drop-down, since it overlaps our drawing area, leaving a bit of a mess on the screen, and it seems to almost hang sometimes just when moving the mouse up and down on such a menu, until the mouse is moved off the edge.
Anyway, is there a way to avoid the redraw for tooltips? Can they be handled the same way as the application menu and other ribbon bar drop-downs? And same question for old-style menus from the menubar.
On the other hand, sometimes we actually want to redraw while the application menu is open. For example, we select a recently used file. It loads and redraws while the menu is still fading out. However, as the menu fades out it is replaced by the previous contents of the window, after which the view remains drawn incorrectly until next forced to redraw. So I’m also wondering if you have any advice for this.
Thanks,
Rob.
|
|
Technical Support
|
Dec 8, 2009 - 10:57 AM
|
We cannot confirm this. How do we test the background repainting issue? We run the ReportGrid sample application and made its main window non-maximized. Then we made the Visual Studio window restored two. Both windows are floating over the desktop and not intersected with each other. Then we set breakpoint to the beginning of the CExtScrollWnd::OnPaint() method. This is where report grid control handles the WM_PAINT message. Then we clicked the main frame caption of the ReportGrid app and passed the WM_PAINT message to let the main frame activate itself. Now we can invoke the menu bar’s menus. The menu bar is at the top and displayed popup menus always cover the report grid control. We can navigate popup menus and we never receive the WM_PAINT message in the report grid control. We checked Windows XP SP3, Windows Vista SP 2 and Windows 7 systems on NVidia and ATI cards. All the systems have all the possible latest updates installed. We also checked Visual C++ 6.0 compiled application, Visual C++ 2005 and 2008. We checked both Win32 and x64 platforms with Visual C++ 2005 and 2008. Some additional information. The problem really can be provided by not-updated video card drivers. It can also depend from some desktop sharing software capturing the desktop surface.
|
|
Robert Webb
|
Dec 11, 2009 - 1:07 AM
|
I test redraws by drawing the background in a slightly different colour each time, so it’s obvious when it happens. I will try to put some sample code together sometime and see if I can demonstrate the redraws due to menus. In the meantime, here are some more redraw issues: (1) The MDI tabs menu always causes a redraw when it disappears. (2) To avoid screen flicker when I fill data into a tree control (CExtTreeCtrl), I use tree.LockWindowUpdate() before and tree.UnlockWindowUpdate() afterwards. This should prevent redrawing until I’ve finished filling up the tree. However when unlocked, the entire screen redraws! Not just my potentially slow view, but you can also see desktop icons flicker and menus in other programs flicker. If I don’t do the lock it fixes the problem, so for now that’s my workaround. I would expect that at worst the locking should cause the whole tree control to be redrawn after the unlock, but not anything else. Thanks, Rob.
|
|
Technical Support
|
Dec 11, 2009 - 3:17 PM
|
The reported repainting issues look like specific for your app. We would like to ask to create a test project reproducing them and send it to us.
|
|
Robert Webb
|
Nov 27, 2009 - 1:25 AM
|
Actually, here’s something even weirder: - I open a drop-down menu from an item on the ribbon bar. (Note opening and closing such menus does not cause a repaint for a view behind it - this is good).
- Hover over an item to bring up its tooltip
- Move away which closes the tooltip. This also sends a repaint message to the view beneath it - this is what I want to avoid.
- Click somewhere else to close the menu. Now the bizarre thing is that it not only puts back what was there before from the underlying view, but also the tooltip is back! If the menu stores a bitmap of what’s behind it before it goes up, it is weird that somehow the tooltip is also being put in that bitmap. I notice the menu does flash though when we redraw due to the tooltip vanishing. I guess it decides to redraw too and grabs another bitmap, but I can’t quite work out how it would end up with what I’m seeing.
Any thoughts? Thanks, Rob.
|
|
Technical Support
|
Nov 30, 2009 - 5:00 AM
|
Thank you for reporting these issues. Please drop us an e-mail so we can provide you with the source code update.
|
|
Robert Webb
|
Dec 2, 2009 - 7:01 PM
|
Thanks, that did indeed fix the issue with the tooltips (ie no more redraw is required). Old-style menus from a menu bar still seem to cause a redraw though. Dialog boxes also cause a redraw when closed or moved. Is there a way I can tell them to store and recover their backgrounds? Thanks, Rob.
|
|
Robert Webb
|
Dec 2, 2009 - 7:59 PM
|
Oh, something additional: if our users move a dialog box around, then each move of the mouse causes a redraw of the view behind. If their model is complex this can be quite slow, so the dialog movement is very jerky. But worse than this is the fact that it gets stuck to the mouse. So even when they release the mouse button it just keeps following the mouse anyway. You can get it to let go by clicking and holding for a while before releasing, but in the meantime, the dialog keeps following the mouse regardless which in turn causes lots of slow redraws. This is presumably the same bug that means sometimes when moving the main window I can’t release it. Happens when I click on the top titlebar of the window to bring it to the foreground. This triggers a redraw of course, and because it takes a moment, Prof-UIS somehow doesn’t notice that the mouse button has been released and the whole window then follows the mouse around when it shouldn’t. Also I presume related to a similar thing when resizing the window. Sometimes when you release the mouse button it keeps resizing with the mouse anyway. Aren’t other people having these problems? Rob.
|
|
Technical Support
|
Dec 5, 2009 - 1:28 PM
|
First of all, please re-upload the latest source code from the same location. Now looks like the popup menu and tooltip control improvements really complete.
The dialog windows are normal windows. They does not guarantee the automatic background saving restoring. You can do one of the following improvements:
1) Improve your complex painted view window and make it keeping a bitmap containing cached image of view surface. This bitmap should be recreated only if the view window is resized or if displayed on it information is changed. This solution will really work.
2) Replace your popup dialog window with a custom coded popup window which is based on the CS_SAVEBITS window class style. This window should be a container for the child dialog window. I.e. your popup dialog should be converted int child dialog type and created inside a popup container window which saves its background. This solution also should work but the CS_SAVEBITS window class style does not provide 100% guaranteed window background restoring especially for big size windows.
|
|
Robert Webb
|
Dec 7, 2009 - 5:08 PM
|
I downloaded the latest version, but it doesn’t seem any different. In particular menus from a menubar still cause a redraw when closed. Re (1) keeping a bitmap, this is tricky with OpenGL. If OpenGL is used to render direct to a bitmap, then generally you don’t get hardware acceleration. The other option is to copy a bitmap from what’s already rendered on screen, but then there are problems if another window or dialog is partly obscuring the window. Re (2) it sounds like this is unreliable and maybe depends on the OS. Is there some way to make use of the system you employ for tooltips? Would be great if you could provided a function to call before opening a dialog box that would make it behave that way. Rob.
|
|
Dennis Ioakim
|
Nov 25, 2009 - 1:04 AM
|
Good day, when testing our software created with ProfUIS under Windows7, greek text in our PropertyGrid isn’t displayed correctly i.e. random glyphs appear. Are there any issues of ProfUIS with Unicode and Windows7? Also please clarify this: What is the default font used in your various controls (especially the PropertyGrid) and how can they be changed? Thanx in advance.
|
|
Technical Support
|
Nov 25, 2009 - 12:16 PM
|
Prof-UIS runs OK on Windows 7. You should use a Unicode Prof-UIS configuration to see the correct Greek characters. The CExtPaintManager::m_FontNormal font is default for most of controls. The CExtPaintManager::m_FontCaption font is the window caption font for skinned windows (used only when paint manager supports window non client area skinning). The CExtPaintManager::m_FontNormalBC font is the floating control bar caption font and docked resizable bar caption font.
|
|
tera tera
|
Nov 25, 2009 - 12:48 AM
|
Hello. It is a former question.
When I use System proportional font in large quantities.
Why will application become slow? http://www.prof-uis.com/prof-uis/tech-support/support-forum/when-i-add-300-dialog-to-cexttabpagecontainerflatwnd-63049.aspx >If you allocate 10000 GDI handles, Windows will start using the "System" proportional font everywhere. So, you should not allocated 10000 GDI handles.
>Approximately the same we can say about allocating 300 tab pages. Besides, keeping 300 items in the single line tab control is not a a user friendly design.
>This design should be replaced with something else. For instance, you can use a list box inside tab control and created only one page window which corresponds to the selected list box item.
|
|
tera tera
|
Nov 26, 2009 - 5:24 PM
|
Hello. I examine problems of the GDI.
By using a lot of handles.
Because the OS transmits Windows message to the handle.
Will application become slow?
|
|
Technical Support
|
Nov 27, 2009 - 1:26 PM
|
|
|
tera tera
|
Nov 27, 2009 - 6:04 PM
|
|
|
tera tera
|
Nov 25, 2009 - 5:45 PM
|
|
|
Technical Support
|
Nov 26, 2009 - 2:06 AM
|
Sorry for this delay. The type of the font is not important. It can use be variable or fixed width characters. The counts of GDI and other handles is the critical question. Prof-UIS minimizes the count of GDI handles. It caches only a few font and brush GDI handles. Bitmap handles are mostly never allocated because the CExtBitmap class is handle-less. Did you check the count of handles allocated by your application at run-time?
|
|
Roberto Manes
|
Nov 23, 2009 - 11:28 AM
|
Since when I upgraded my application from prof-ius release 2.60 to release 2.84 when I get a tool tip displayed on the screen which it is not in proximity of the tool bar button but it isdisplayed a couple of centimeter down from it. I’ve just linked the new library. Could you help me ? thanks in advance
|
|
Roberto Manes
|
Nov 23, 2009 - 3:33 AM
|
In have an application using 5 different tools bars. When I start the application after the first installation all the tools bars are automatically positioned one on top the other. Is it possible to place the tools bars in a predefined position, for example two tools bars sideway ? Thanks in advance
|
|
Roberto Manes
|
Nov 23, 2009 - 11:23 AM
|
Thanks for your suggestion it worked. Also I have another question. Since when I upgraded my application from prof-ius release 2.60 to release 2.84 when I get a tool tip displayed on the screen it is not in proximity of the tool bar button but it isdisplayed a couple of centimeter down from it. I’ve just linked the new library. Could you help me ? thanks in advance
|
|
Technical Support
|
Nov 25, 2009 - 3:45 AM
|
Prof-UIS 2.84 uses its own themed tooltip like looking windows instead of tooltip common controls. We implemented the tooltip behavior for toolbar buttons similar to Visual Studio .NET/2005/2008 and Office 2003/2007 tooltips. The tooltip window is displayed on a distance which is closed to the toolbar button but does not intersect with the mouse cursor shape.
|
|
Roberto Manes
|
Nov 23, 2009 - 11:09 AM
|
Thanks for your suggestion it worked. Also I have another question. Since when I upgraded my application from prof-ius release 2.60 to release 2.84 when I get a tool tip displayed on the screen it is not in proximity of the tool bar button but it isdisplayed a couple of centimeter down from it. I’ve just linked the new library. Could you help me ? thanks in advance
|
|
Technical Support
|
Nov 23, 2009 - 9:35 AM
|
|
|
Adrian M
|
Nov 22, 2009 - 4:06 PM
|
Hi,
Can you please post a sample on how to use CRichEditCtrl with one of the CExt edit controls. Basically, I want the control to match the general visual theme of the application, for example if I set the CRichEditCtrl to be read only, I want it to have the same background as a regular CExtEdit that’s read only.
Thanks,
Adrian
|
|
Technical Support
|
Nov 25, 2009 - 3:47 AM
|
|
|
Rolf Boerkoel
|
Nov 20, 2009 - 9:40 AM
|
Dear support,
Could you please explain a little about the Alt Key Code Mode in CExtEditBase (m_bAltKeyCodeMode )? I can’t find any info on it, and analyzing the source code doesn’t make me any wiser.
I bumped into this feature by accident (pressing arrow keys while holding down ALT) and saw strange characters appear or even clipboard text being pasted into edit controls. As regular edit controls do not behave like this I was wondering if this is something useful, because it is enabled by default.
Kind regards, Marco
|
|
Technical Support
|
Nov 23, 2009 - 9:36 AM
|
Yes, you are right. To fix this issue please update the source code for the following method:
LRESULT CExtEditBase::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch( message )
{
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
{ // block - clipboard commands
bool bAlt = ( (::GetAsyncKeyState(VK_MENU)&0x8000) != 0 ) ? true : false;
bool bCtrl = ( (::GetAsyncKeyState(VK_CONTROL)&0x8000) != 0 ) ? true : false;
bool bShift = ( (::GetAsyncKeyState(VK_SHIFT)&0x8000) != 0 ) ? true : false;
if( ! bAlt )
{
if( bCtrl && ! bShift
&& ( INT(wParam) == VK_INSERT
|| INT(wParam) == INT( _T(’C’) )
)
)
{
if( message == WM_KEYDOWN )
SendMessage( WM_COPY, 0, 0 );
return 0L;
}
if( ( bCtrl && (!bShift) && int(wParam) == int( _T(’V’) ) )
|| ( (!bCtrl) && bShift && int(wParam) == VK_INSERT )
)
{
if( message == WM_KEYDOWN && ( GetStyle() & ES_READONLY ) == 0 )
{
//SendMessage( WM_PASTE, 0, 0 );
Default();
}
return 0L;
}
if( ( bCtrl && (!bShift) && int(wParam) == int( _T(’X’) ) )
|| ( (!bCtrl) && bShift && int(wParam) == VK_DELETE )
)
{
if( message == WM_KEYDOWN )
SendMessage( ( ( GetStyle() & ES_READONLY ) == 0 ) ? WM_CUT : WM_COPY, 0, 0 );
return 0L;
}
}
} // block - clipboard commands
// if( ( GetStyle() & ES_READONLY ) != 0 )
// {
// bool bAlt = ( (::GetAsyncKeyState(VK_MENU)&0x8000) != 0 ) ? true : false;
// if( ! bAlt )
// {
// bool bCtrl = ( (::GetAsyncKeyState(VK_CONTROL)&0x8000) != 0 ) ? true : false;
// bool bShift = ( (::GetAsyncKeyState(VK_SHIFT)&0x8000) != 0 ) ? true : false;
// if( ( bCtrl
// && ( wParam == WPARAM(’X’)
// || wParam == WPARAM(’x’)
// || wParam == WPARAM(’V’)
// || wParam == WPARAM(’v’)
// || wParam == WPARAM(’Z’)
// || wParam == WPARAM(’z’)
// )
// )
// || ( bShift
// && ( wParam == VK_INSERT
// || wParam == VK_DELETE
// )
// )
// || ( ( ! ( bCtrl || bShift ) )
// && ( wParam == VK_DELETE || wParam == VK_BACK )
// )
// )
// return 0L;
// }
// else
// {
// if( wParam == VK_BACK )
// return 0L;
// }
// }
if( m_bHandleAltKeyCodes )
{
bool bKeyDown = ( message == WM_KEYDOWN || message == WM_SYSKEYDOWN ) ? true : false;
switch( wParam )
{
case VK_MENU:
if( bKeyDown )
{
if( ( GetStyle() & ES_READONLY ) != 0 )
{
m_bAltKeyCodeMode = false;
if( g_hWndEditInAltKeyCodeMode == m_hWnd )
g_hWndEditInAltKeyCodeMode = NULL;
m_nTrackedAltKeyCode = 0L;
break;
}
m_bAltKeyCodeMode = true;
g_hWndEditInAltKeyCodeMode = m_hWnd;
m_nTrackedAltKeyCode = 0L;
return 0L;
} // if( bKeyDown )
else if( m_bAltKeyCodeMode )
{
m_bAltKeyCodeMode = false;
if( g_hWndEditInAltKeyCodeMode == m_hWnd )
g_hWndEditInAltKeyCodeMode = NULL;
if( m_nTrackedAltKeyCode > 0L )
{
USES_CONVERSION;
WCHAR wstr[2] = { WCHAR(m_nTrackedAltKeyCode), L’\0’ };
LPCTSTR str = W2CT( wstr );
//ReplaceSel( str );
m_nTrackedAltKeyCode = 0L;
for( MSG _msg; ::PeekMessage( &_msg, m_hWnd, WM_CHAR, WM_CHAR, PM_REMOVE ); );
SendMessage( WM_CHAR, WPARAM(str[0]), 1L );
}
return 0L;
} // else if( m_bAltKeyCodeMode )
break;
case VK_INSERT:
case VK_END:
case VK_DOWN:
case VK_NEXT:
case VK_LEFT:
case 0x0C: // VK_CLEAR
case VK_RIGHT:
case VK_HOME:
case VK_UP:
case VK_PRIOR:
if( m_bAltKeyCodeMode )
{
if( ! CExtPopupMenuWnd::IsKeyPressed( VK_MENU ) )
{
m_bAltKeyCodeMode = false;
if( g_hWndEditInAltKeyCodeMode == m_hWnd )
g_hWndEditInAltKeyCodeMode = NULL;
m_nTrackedAltKeyCode = 0L;
break;
}
if( bKeyDown )
{
LONG nAdd = -1L;
bool bIsExtendedKey = ( ( lParam & (1L<<24L) ) == 0 ) ? true : false;
if( bIsExtendedKey )
{
switch( wParam )
{
case VK_INSERT: nAdd = 0L; break;
case VK_END: nAdd = 1L; break;
case VK_DOWN: nAdd = 2L; break;
case VK_NEXT: nAdd = 3L; break;
case VK_LEFT: nAdd = 4L; break;
case 0x0C: nAdd = 5L; break; // VK_CLEAR
case VK_RIGHT: nAdd = 6L; break;
case VK_HOME: nAdd = 7L; break;
case VK_UP: nAdd = 8L; break;
case VK_PRIOR: nAdd = 9L; break;
} // switch( wParam )
} // if( bIsExtendedKey )
if( nAdd >= 0L )
{
m_nTrackedAltKeyCode *= 10;
ASSERT( 0L <= nAdd && nAdd <= 9L );
m_nTrackedAltKeyCode += nAdd;
}
} // if( message == WM_KEYDOWN )
return 0L;
} // if( m_bAltKeyCodeMode )
break;
case VK_NUMPAD0:
case VK_NUMPAD1:
case VK_NUMPAD2:
case VK_NUMPAD3:
case VK_NUMPAD4:
case VK_NUMPAD5:
case VK_NUMPAD6:
case VK_NUMPAD7:
case VK_NUMPAD8:
case VK_NUMPAD9:
if( m_bAltKeyCodeMode )
{
if( ! CExtPopupMenuWnd::IsKeyPressed( VK_MENU ) )
{
m_bAltKeyCodeMode = false;
if( g_hWndEditInAltKeyCodeMode == m_hWnd )
g_hWndEditInAltKeyCodeMode = NULL;
m_nTrackedAltKeyCode = 0L;
break;
}
if( bKeyDown )
{
bool bIsExtendedKey = ( ( lParam & (1L<<24L) ) == 0 ) ? true : false;
if( bIsExtendedKey )
{
m_nTrackedAltKeyCode *= 10;
LONG nAdd = LONG(wParam) - LONG(VK_NUMPAD0);
ASSERT( 0L <= nAdd && nAdd <= 9L );
m_nTrackedAltKeyCode += nAdd;
} // if( bIsExtendedKey )
} // if( message == WM_KEYDOWN )
return 0L;
} // if( m_bAltKeyCodeMode )
break;
case WPARAM(’0’):
case WPARAM(’1’):
case WPARAM(’2’):
case WPARAM(’3’):
case WPARAM(’4’):
case WPARAM(’5’):
case WPARAM(’6’):
case WPARAM(’7’):
case WPARAM(’8’):
case WPARAM(’9’):
if( m_bAltKeyCodeMode )
{
if( ! CExtPopupMenuWnd::IsKeyPressed( VK_MENU ) )
{
m_bAltKeyCodeMode = false;
if( g_hWndEditInAltKeyCodeMode == m_hWnd )
g_hWndEditInAltKeyCodeMode = NULL;
m_nTrackedAltKeyCode = 0L;
break;
}
if( bKeyDown )
{
bool bIsExtendedKey = ( ( lParam & (1L<<24L) ) == 0 ) ? true : false;
if( bIsExtendedKey )
{
m_nTrackedAltKeyCode *= 10;
LONG nAdd = LONG(wParam) - LONG(’0’);
ASSERT( 0L <= nAdd && nAdd <= 9L );
m_nTrackedAltKeyCode += nAdd;
} // if( bIsExtendedKey )
} // if( message == WM_KEYDOWN )
return 0L;
} // if( m_bAltKeyCodeMode )
break;
default:
m_bAltKeyCodeMode = false;
if( g_hWndEditInAltKeyCodeMode == m_hWnd )
g_hWndEditInAltKeyCodeMode = NULL;
m_nTrackedAltKeyCode = 0L;
break;
} // switch( wParam )
} // if( m_bHandleAltKeyCodes )
else
{
m_bAltKeyCodeMode = false;
if( g_hWndEditInAltKeyCodeMode == m_hWnd )
g_hWndEditInAltKeyCodeMode = NULL;
m_nTrackedAltKeyCode = 0L;
} // else from if( m_bHandleAltKeyCodes )
break;
case WM_CANCELMODE:
case WM_ACTIVATE:
case WM_ACTIVATEAPP:
case WM_KILLFOCUS:
case WM_DESTROY:
case WM_SETTINGCHANGE:
case WM_DISPLAYCHANGE:
case WM_SHOWWINDOW:
case WM_SIZE:
case WM_WINDOWPOSCHANGING:
case WM_WINDOWPOSCHANGED:
case EM_SETSEL:
case EM_REPLACESEL:
case EM_UNDO:
case EM_REDO:
m_bAltKeyCodeMode = false;
if( g_hWndEditInAltKeyCodeMode == m_hWnd )
g_hWndEditInAltKeyCodeMode = NULL;
m_nTrackedAltKeyCode = 0L;
break;
case WM_STYLECHANGED:
if( ( GetStyle() & ES_READONLY ) != 0 )
{
m_bAltKeyCodeMode = false;
if( g_hWndEditInAltKeyCodeMode == m_hWnd )
g_hWndEditInAltKeyCodeMode = NULL;
m_nTrackedAltKeyCode = 0L;
break;
}
break;
case WM_SYSCHAR:
case WM_CHAR:
if( ( GetStyle() & ES_READONLY ) != 0
&& (! CExtPopupMenuWnd::IsKeyPressed( VK_CONTROL ) )
)
return 0L;
break;
case WM_PASTE:
{
m_bAltKeyCodeMode = false;
if( g_hWndEditInAltKeyCodeMode == m_hWnd )
g_hWndEditInAltKeyCodeMode = NULL;
m_nTrackedAltKeyCode = 0L;
}
break;
} // switch( message )
if( message == WM_NOTIFY
&& m_wndToolTip.GetSafeHwnd() != NULL
&& IsWindow( m_wndToolTip.GetSafeHwnd() )
&& ((LPNMHDR)lParam) != NULL
&& ((LPNMHDR)lParam)->hwndFrom == m_wndToolTip.GetSafeHwnd()
&& ((LPNMHDR)lParam)->code == TTN_SHOW
)
::SetWindowPos(
m_wndToolTip.GetSafeHwnd(),
HWND_TOP,
0,0,0,0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE
);
LRESULT lResult = CEdit::WindowProc( message, wParam, lParam );
return lResult;
}
|
|
Rolf Boerkoel
|
Nov 25, 2009 - 1:21 AM
|
Thanks, works fine now.
The only remark I have left is that pressing ALT + regular keys 0-9 (case WPARAM(’0’) through WPARAM(’9’)) normally doesn’t allow entering characters in this way as far as I know. But this feature doesn’t bother me.
|
|
Technical Support
|
Nov 20, 2009 - 2:43 PM
|
The CExtEditBase control implements the Alt-key based character input from scratch. The CExtEditBase::m_bAltKeyCodeMode flat is the internal protected property of the CExtEditBase class. It’s set to false if the Alt key is not pressed. It’s set to true if the Alt key was pressed and number characters are entered. The CExtEditBase class keeps it set to true in this case until the Alt key kept pressed. When the Alt key is released, then the CExtEditBase class inserts the character corresponding to the character entered code. If you know any issues related to the Alt-key based character input in the CExtEditBase control, then please let us know exact sequence of steps to reproduce them.
|
|
Rolf Boerkoel
|
Nov 23, 2009 - 3:56 AM
|
Ah wait a minute, this is for entering characters using ALT + numpad keys, of course! I did not expect to see this behaviour when pressing the regular arrow/pageup/pagedown etc. keys.
Perhaps it is an idea to test on the WM_KEYDOWN lParam bit 24 to see if it really is a numpad key?
BOOL bIsExtendedKey = ((lParam & 0x01000000) != 0);
|
|
Bertil Morefält
|
Nov 20, 2009 - 9:24 AM
|
Hi! I have an MDI application with 28 dll:s (MFC Extenstion DLL:s) and I am trying to bild a new MFC Extenstin DLL where I want to use yours ProfUIS 2.85. One of my Dll:s are a resource_only_dll where all my resources resides. When I try to use radio button yours CExtImageList can´t find the resource and objBitmap.Attach allways fails . When I checked your source code I found i very odd that you in the CExtImageList constrructor have ’ HINSTANCE hInstResource = AfxGetInstanceHandle()’ shouldn’t it be ’ HINSTANCE hInstResource = AfxGetResourceHandle()’. How do I solve this problem? Best Regards, Bertil Morefält
|
|
Technical Support
|
Nov 20, 2009 - 2:44 PM
|
Thank you for reporting us this issue. Here is the updated source code:
class __PROF_UIS_API CExtImageList : public CImageList
{
public:
CExtImageList()
{
}
CExtImageList(
UINT nResourceID,
COLORREF clrTransparencyMask = RGB(255,0,255),
int nButtonWidth = 16,
HINSTANCE hInstResource = AfxGetInstanceHandle(),
UINT nColorFlag = ILC_COLOR24,
UINT nColorAddionalFlag = ILC_MASK
)
{
VERIFY(
Load(
nResourceID,
clrTransparencyMask,
nButtonWidth,
hInstResource,
nColorFlag,
nColorAddionalFlag
)
);
}
BOOL Load(
UINT nResourceID,
COLORREF clrTransparencyMask = RGB(255,0,255),
int nButtonWidth = 16,
HINSTANCE hInstResource = AfxGetInstanceHandle(),
UINT nColorFlag = ILC_COLOR24,
UINT nColorAddionalFlag = ILC_MASK
)
{
ASSERT(
nColorFlag == ILC_COLOR4
|| nColorFlag == ILC_COLOR8
|| nColorFlag == ILC_COLOR16
|| nColorFlag == ILC_COLOR24
|| nColorFlag == ILC_COLOR32
);
if( hInstResource == NULL )
{
hInstResource = ::AfxGetResourceHandle();
if( hInstResource == NULL )
{
hInstResource = ::AfxGetInstanceHandle();
if( hInstResource == NULL )
{
ASSERT( FALSE );
return FALSE;
}
}
}
CBitmap objBitmap;
if( ! objBitmap.Attach( LoadImage( hInstResource, MAKEINTRESOURCE( nResourceID ), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_CREATEDIBSECTION ) ) )
{
ASSERT( FALSE );
return FALSE;
}
BITMAP infoBitmap;
::memset( &infoBitmap, 0, sizeof(BITMAP) );
if( ! objBitmap.GetBitmap( &infoBitmap ) )
{
ASSERT( FALSE );
return FALSE;
}
CSize sizeBitmap( infoBitmap.bmWidth, infoBitmap.bmHeight );
int nCountOfButtons = sizeBitmap.cx / nButtonWidth;
if( ! Create( nButtonWidth, sizeBitmap.cy, nColorFlag|nColorAddionalFlag, nCountOfButtons, 0 ) )
{
ASSERT( FALSE );
return FALSE;
}
if( Add( &objBitmap, clrTransparencyMask ) == -1 )
{
ASSERT( FALSE );
return FALSE;
}
return TRUE;
}
}; // class CExtImageList
|
|
Bertil Morefält
|
Nov 21, 2009 - 6:39 AM
|
This code segment will not work in my case BOOL Load(
UINT nResourceID,
COLORREF clrTransparencyMask = RGB(255,0,255),
int nButtonWidth = 16,
HINSTANCE hInstResource = AfxGetInstanceHandle(), This will always give a correct pointer
UINT nColorFlag = ILC_COLOR24,
UINT nColorAddionalFlag = ILC_MASK
)
{
ASSERT(
nColorFlag == ILC_COLOR4
|| nColorFlag == ILC_COLOR8
|| nColorFlag == ILC_COLOR16
|| nColorFlag == ILC_COLOR24
|| nColorFlag == ILC_COLOR32
);
if( hInstResource == NULL ) this if-statement will newer return true, and leave me with no pointer to my resourse. When you use AfxGetResourceHandle() you will allways get the
correct resource wether it is a resource_only_dll or not. {
hInstResource = ::AfxGetResourceHandle();
if( hInstResource == NULL )
{
hInstResource = ::AfxGetInstanceHandle();
if( hInstResource == NULL )
{
ASSERT( FALSE );
return FALSE;
}
}
}
CBitmap objBitmap;
if( ! objBitmap.Attach( LoadImage( hInstResource, MAKEINTRESOURCE( nResourceID ), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_CREATEDIBSECTION ) ) )
{
ASSERT( FALSE );
return FALSE;
} Best Regards,
Bertil Morefält
|
|
Technical Support
|
Nov 23, 2009 - 7:20 AM
|
We changed all the default values for all the hInstResource parameters:
class __PROF_UIS_API CExtImageList : public CImageList
{
public:
CExtImageList()
{
}
CExtImageList(
UINT nResourceID,
COLORREF clrTransparencyMask = RGB(255,0,255),
int nButtonWidth = 16,
HINSTANCE hInstResource = NULL,
UINT nColorFlag = ILC_COLOR24,
UINT nColorAddionalFlag = ILC_MASK
)
{
VERIFY( Load( nResourceID, clrTransparencyMask, nButtonWidth, hInstResource, nColorFlag, nColorAddionalFlag ) );
}
BOOL Load(
UINT nResourceID,
COLORREF clrTransparencyMask = RGB(255,0,255),
int nButtonWidth = 16,
HINSTANCE hInstResource = NULL,
UINT nColorFlag = ILC_COLOR24,
UINT nColorAddionalFlag = ILC_MASK
)
{
ASSERT(
nColorFlag == ILC_COLOR4
|| nColorFlag == ILC_COLOR8
|| nColorFlag == ILC_COLOR16
|| nColorFlag == ILC_COLOR24
|| nColorFlag == ILC_COLOR32
);
if( hInstResource == NULL )
{
hInstResource = ::AfxGetResourceHandle();
if( hInstResource == NULL )
{
hInstResource = ::AfxGetInstanceHandle();
if( hInstResource == NULL )
{
ASSERT( FALSE );
return FALSE;
}
}
}
CBitmap objBitmap;
if( ! objBitmap.Attach( LoadImage( hInstResource, MAKEINTRESOURCE( nResourceID ), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE|LR_CREATEDIBSECTION ) ) )
{
ASSERT( FALSE );
return FALSE;
}
BITMAP infoBitmap;
::memset( &infoBitmap, 0, sizeof(BITMAP) );
if( ! objBitmap.GetBitmap( &infoBitmap ) )
{
ASSERT( FALSE );
return FALSE;
}
CSize sizeBitmap( infoBitmap.bmWidth, infoBitmap.bmHeight );
int nCountOfButtons = sizeBitmap.cx / nButtonWidth;
if( ! Create( nButtonWidth, sizeBitmap.cy, nColorFlag|nColorAddionalFlag, nCountOfButtons, 0 ) )
{
ASSERT( FALSE );
return FALSE;
}
if( Add( &objBitmap, clrTransparencyMask ) == -1 )
{
ASSERT( FALSE );
return FALSE;
}
return TRUE;
}
}; // class CExtImageList
|
|
Bertil Morefält
|
Nov 24, 2009 - 4:01 AM
|
Hi! It just dosn’t work. So I went back to basics. I declared two Buttons one wihe CExtRadioButton and the other as CButton in my class declaration. CExtRadioButton m_ctlSysOff;
CButton m_ctlKvittaOff; and in void CAnvView::DoDataExchange(CDataExchange* pDX)
{
DDX_Control(pDX, IDC_ANV_USER_RADIO1, m_ctlUserOff);
DDX_Control(pDX, IDC_ANV_SYS_RADIO1, m_ctlSysOff); ...... } and in my resource_only_dll file I set up two radiobutton-controls. The control m_ctlSysOff disapear and m_ctlKvittaOff is visible and works correctly. Why? Best Regards, Bertil Morefält
|
|
Technical Support
|
Nov 24, 2009 - 2:09 PM
|
We guess this question is not related to image lists and bitmap resources. The information in your message is not enough to come to any conclusions about disappeared radio button. The only thing we can suppose is that the disappeared radio button has no WS_VISIBLE style. Could you create two simple possible test projects reproducing this magic and sent them to us to the support mail box at this web site? We mean one is EXE app and second is resource DLL.
|
|
Eric Houvenaghel
|
Nov 19, 2009 - 2:48 PM
|
Thank you for the reply to my last post.
Turns out the bug was on my side.
There is another bug that I can’t get around and I’m hoping that you can fix it.
Basically, the tabs of a CExtTabPageContainerWhidbeyWnd are only shown when I put my mouse pointer on the tab area.
When I initially show the tab control, it looks like this:
When I put my mouse pointer over the tab area I get what the tab control should initially look like.
Any idea what’s wrong?
|
|
Technical Support
|
Nov 20, 2009 - 2:38 PM
|
Please check the parent dialog of the tab page container window and all the page dialogs have both the clip children and clip sibling options set on in the dialog template properties.
|
|
Eric Houvenaghel
|
Nov 24, 2009 - 8:30 AM
|
|
|
Ulrich Heinicke
|
Nov 19, 2009 - 10:36 AM
|
Hi, i download the version 2.87 and install it under windows 7. But i can’t run the integration wizard. I get the following message (i translate ist from german to english): A reference evaluation has been reset by the server Please tell me how i can integrate the software into my visual studio ans build the libs. Thanks Ulrich
|
|
2C|!2C
|
Feb 4, 2010 - 2:29 AM
|
Yes I have Version 2.88. If there is another way to add it that would be fine as well.
|
|
Technical Support
|
Feb 4, 2010 - 1:49 PM
|
|
|
2C|!2C
|
Feb 2, 2010 - 7:37 PM
|
I have the same problem with 2.88 on Windows 7 64 Bit & VS 2008. The install worked except the IntegrationWizard which didn’t start during istallation. Running it after the installation returns : "A referral was returned from the server" My account has Admin rights.
|
|
Technical Support
|
Feb 3, 2010 - 12:06 PM
|
The Prof-UIS Integration Wizard provided with 2.88 is an EXE module which contains manifest describing required administrator rights. I.e. Integration Wizard automatically elevates its rights to administrative level. We saw this error in previous versions of Prof-UIS Integration Wizard, but not in 2.88. Please check whether you have 2.88 - not an older version. If you have an older version, then edit the Integration Wizard’s short shortcut options and mark it running as administrator both in the extended options and compatibility options.
|
|
Ulrich Heinicke
|
Nov 23, 2009 - 11:32 PM
|
Hi, when i run the integration wizard in compatible mode (xp with sp3) and with administrator rights, then it is running. But the wiazrd can’t build the libraries. So i build the libraries by my self. The next problem is to run the wizard to create a new project inside Visual Studio. It will terminate with an error. My visual studio version is 2008 in german and i run it under windows 7 - 64bit on german.
|
|
Technical Support
|
Nov 24, 2009 - 2:06 PM
|
The application compatibility options are very formal in Windows 7. That’s why Microsoft released the Windows XP Mode. It’s very recommended to run any Visual Studio version under Windows 7 only as an administrator. Please check this.
|
|
Ulrich Heinicke
|
Dec 13, 2009 - 11:10 PM
|
I run Visual Studio several times as an administrator, but i can’t run the wizard.
|
|
Technical Support
|
Dec 14, 2009 - 9:27 AM
|
The Integration Wizard application requires the administrator permissions. We added required manifest records and it always force runs as administrator independently from the shortcut settings. This application was tested using Windows 7 compatibility toolkit and it passes all the tests. But sometimes the situation you reported occurs on a some particular computers. It’s not difficult to fix it. Please invoke the properties dialog, select the Compatibility tab and check the Run as Administrator check box on it.
|
|
Technical Support
|
Nov 19, 2009 - 1:50 PM
|
We tested all the tasks performed by the Prof-UIS Integration Wizard on Windows 7 and it runs OK. But in particular cases and on particular machines it runs OK only if you run it as administrator (you can use the Run as Administrator menu item from context menu). We solved this issue before releasing Prof-UIS 2.87: we added the manifest record which force requests the Run as Administrator mode even if you run the Prof-UIS Integration Wizard with the access rights of the currently logged in user. In any case, we never saw similar messages. Please provide us with more details about this error message. Who displays it? You can use the Windows Task Manager to detect this.
|
|
Jeroen Walter
|
Nov 18, 2009 - 6:36 AM
|
Hi I’ve noticed that ProfUis (using 2.85) doesn’t support controls that are created in a separate UI thread. One of the things that goes wrong is that CExtHookSpy has no regard for threads and just uses some global static arrays and maps to store information related to CWnd classes such as the profuis controls. For this reason the hooking mechanism in the main thread accesses information that is only available in the other thread. For instance, the MFC macro ASSERT_VALID is called from the profuis controls from for instance CExtScrollBar::OnHookSpyPreTranslateMessage(). This macro tries to find the CWnd corresponding with a HWND in the calling thread. MFC does this correctly, it maintains thread specific maps with CWnd to HWND mapping etc. Therefore, if CExtScrollBar::OnHookSpyPreTranslateMessage is called from a thread other than the thread in which the CExtScrollBar was created (which profuis does unfortunately...), this method will crash the application. Our application uses multiple ui threads, which is supported by MFC. I find it therefore very annoying that a library such as ProfUIS which builds heavily on MFC has no support for multiple ui threads. For us it is not an option to not use multiple ui threads. Do you plan to add support for multiple ui threads in the future? If so, when? Kind regards, Jeroen Walter
|
|
Jeroen Walter
|
Nov 23, 2009 - 3:59 AM
|
I gathered as much and I understand it is not a change that can be implemented easily. I’ve been able to rewrite my code to use only 1 thread, but I don’t like the consequences it had for my application. So my question still stands, are you planning on providing multitheaded support, even if it has the same restrictions as MFC? If so, when? If not, why not?
|
|
Technical Support
|
Nov 23, 2009 - 9:37 AM
|
The main difficulties are hidden in testing - not in development. But this is not why we didn’t get into multithreading yet and this is why latest Microsoft’s also keeping UI single threaded. The UI theming code contains enough large bitmap based skinning elements. The HBITMAP handles are not thread safe because GDI is not multithreaded. Prof-UIS solves this problem. The CExtBitmap class is handle-less. We can potentially keep one paint manager with all the skinning bitmaps in one thread. But making the painting code based on synchronization locks is not really a good idea. So, we think we had to keep one paint manager instance for one thread and do not think about amount of allocated memory. For instance, the XML/PNG skins are defined by approximately 300 bitmaps and this count an only grow with next releases. This means the multithreaded Prof-UIS paint managers will allocate enough small memory only for themes like classic Windows 2000, Windows XP theme API based and non-bitmap-based themes like Office XP, Office 2003, Studio 2005/2008.
We are thinking about multithreaded implementation details right now. This task raises some additional tasks. For instance, automatic synchronization of paint managers installed in different threads.
|
|
Jeroen Walter
|
Nov 24, 2009 - 3:24 AM
|
Alright, thanks. Painting using locks is indeed not something you want to do :) I’m glad you’re considering making a multithreaded implementation.
|
|
Technical Support
|
Nov 18, 2009 - 2:04 PM
|
Adding multiple UI thread support for us means moving all the global variables into thread local storage (TLS) data areas. But the __declspec( thread ) specification has serious limitations: it cannot be applied to classes which have member functions and it’s not safe for dynamically loaded DLLs. This automatically means we should replace all the global smart pointer objects (command manager, resource manager, paint manager) with the thread aware smart pointers. Most of the MFC classes and features, are limited for using inside one thread only: all the window wrappers, CObject and, as result, ASSERT_VALID too. The CWnd::FromHandle() API returns different CWnd* pointers in different threads. I.e. different threads are using different global MFC states including even runtime class descriptions. Simply and dirty saying, different threads are using different copies of MFC. Besides, the GDI library is not multithread safe. All the bitmaps, brushes and fonts stored inside the currently installed paint manager can be used only in one thread where they are created. It’s possible to make Prof-UIS multithreaded, but this requires very strong and heavy testing.
|
|
Jeroen Walter
|
Nov 18, 2009 - 5:41 AM
|
Hi using profuis 2.85: I want to be able to selectively allow or prohibit the editing of a label in the CExtTreeCtrl. For this I thought the notification TVN_BEGINLABELEDIT should be used. However, the CExtTreeCtrl doesn’t use TVN_BEGINLABELEDIT and TVN_ENDLABELEDIT notifications. Instead it breaks the notification mechanism by calling EditLabel somewhere in its message spy hook thingy. For the TVN_ENDLABELEDIT this is fixed by calling the virtual method OnInplaceControlComplete. However, for the TVN_BEGINLABELEDIT there is no such callback. CExtTreeCtrl::OnInplaceControlCreate would seem the logical counterpart, but is not called for label editing, only for the additional control. Could you please fix CExtCtrl so we can have the behavior back that is available in a normal tree ctrl? It’s nice to have a tree ctrl with extended functionality and skinning, but it’s nicer to have one that actually functions like the default CTreeCtrl from which it is derived.... For instance, call OnInplaceControlCreate with an additional parameter pEditingLabel like in OnInplaceControlComplete. Kind regards Jeroen Walter Ellips B.V.
|
|
Technical Support
|
Nov 23, 2009 - 9:36 AM
|
We added the TVN_BEGINLABELEDIT / TVN_ENDLABELEDIT notifications. Please update the source code for the following methods:
LRESULT CExtTreeCtrl::WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
{
switch( message )
{
case TVM_EDITLABEL:
{
KillTimer( m_nDelayedEditingTimerID );
m_wndContentExpand.Deactivate();
HTREEITEM hti = (HTREEITEM)lParam; //GetFocusedItem();
if( hti == NULL
|| (! HasItem( hti ) )
)
return LRESULT(NULL);
SendMessage( WM_CANCELMODE );
EnsureVisible( hti );
HWND hWndParent = ::GetParent( m_hWnd );
UINT nOwnID = GetDlgCtrlID();
CExtSafeString strItemText;
TV_DISPINFO _data;
::memset( &_data, 0, sizeof(TV_DISPINFO) );
_data.hdr.hwndFrom = m_hWnd;
_data.hdr.idFrom = nOwnID;
_data.hdr.code = TVN_BEGINLABELEDIT;
_data.item.mask = TVIF_CHILDREN|TVIF_HANDLE|TVIF_PARAM|TVIF_STATE;
_data.item.hItem = hti;
GetItem( &_data.item );
strItemText = GetItemText( hti );
_data.item.cchTextMax = INT(strItemText.GetLength());
_data.item.pszText = strItemText.IsEmpty() ? _T("") : LPTSTR(LPCTSTR(strItemText));
_data.item.mask |= TVIF_TEXT;
if( ::SendMessage( hWndParent, WM_NOTIFY, WPARAM(nOwnID), LPARAM(&_data) ) != 0 )
return TRUE;
CRect rcLabel;
if( ! TreeItemRectGet( hti, rcLabel, e_tirt_label ) )
return LRESULT(NULL);
rcLabel.right += 6;
CExtSafeString s;
const TREEITEMINFO_t & _TII = TreeItemInfoGet( hti );
CInplaceEdit * pEdit = new CInplaceEdit( true );
if( ! pEdit->Create(
WS_CHILD | WS_VISIBLE
| WS_CLIPSIBLINGS | ES_AUTOHSCROLL | ES_WANTRETURN
| ( ReadOnlyLabelsGet() ? ES_READONLY : 0 )
| _TII.m_dwAdditionalLabelEditorStyles
,
rcLabel,
this,
UINT(IDC_STATIC)
)
)
return LRESULT(NULL);
CFont * pFont = NULL;
pFont = OnQueryItemFont( hti );
if( pFont == NULL )
pFont = GetFont();
pEdit->SetFont( pFont );
s = GetItemText( hti );
pEdit->SetWindowText( s );
pEdit->SetSel(0, -1);
pEdit->SetFocus();
m_hWndChildControl = pEdit->m_hWnd;
if( m_hWndChildControl != NULL )
m_htiInplaceEdited = hti;
}
// continue falling:
case TVM_GETEDITCONTROL:
return LRESULT(m_hWndChildControl);
case WM_NCLBUTTONDOWN:
case WM_NCMBUTTONDOWN:
case WM_NCRBUTTONDOWN:
SendMessage( WM_CANCELMODE );
if( ::GetFocus() != m_hWnd )
SetFocus();
break;
case TVM_SETINSERTMARK:
{
m_bInsertMarkAfter = ( wParam != 0 ) ? true : false;
HTREEITEM htiInsertMarkOld = m_htiInsertMark;
m_htiInsertMark = (HTREEITEM) lParam;
if( ! HasItem( m_htiInsertMark ) )
m_htiInsertMark = NULL;
if( htiInsertMarkOld != m_htiInsertMark && IsWindowVisible() )
Invalidate();
}
break;
case TVM_SETINSERTMARKCOLOR:
if( IsWindowVisible() )
Invalidate();
break;
} // switch( message )
LRESULT lResult = CTreeCtrl::WindowProc( message, wParam, lParam );
switch( message )
{
case WM_COMMAND:
m_wndContentExpand.Deactivate();
if( HIWORD(wParam) == CBN_KILLFOCUS
&& m_hWndChildControl == ((HWND)lParam)
)
{
SendMessage( WM_CANCELMODE );
}
break;
case TVM_INSERTITEM:
{
m_wndContentExpand.Deactivate();
if( m_hWndChildControl != NULL )
SendMessage( WM_CANCELMODE );
HTREEITEM hti = (HTREEITEM)lResult;
if( hti != NULL )
m_mapItemInfo.SetAt( hti, new TREEITEMINFO_t );
}
break;
case TVM_DELETEITEM:
{
HTREEITEM hti = (HTREEITEM)lParam;
if( m_htiDelayedFocus == hti )
{
m_htiDelayedFocus = NULL;
KillTimer( m_nDelayedFocusTimerID );
KillTimer( m_nDelayedEditingTimerID );
}
m_wndContentExpand.Deactivate();
if( m_hWndChildControl != NULL )
SendMessage( WM_CANCELMODE );
_UnregisterItemsFromMap( hti );
#ifdef _DEBUG
if( hti == NULL || hti == TVI_ROOT )
{
ASSERT( m_mapItemInfo.GetCount() == 0 );
}
#endif // _DEBUG
}
break;
case TVM_EXPAND:
m_wndContentExpand.Deactivate();
break;
} // switch( message )
return lResult;
}
void CExtTreeCtrl::OnInplaceControlComplete(
__EXT_MFC_SAFE_LPCTSTR strEditedText,
bool bEditingLabel
)
{
ASSERT_VALID( this );
HTREEITEM hti = GetInPlaceEditedItem();
if( hti == NULL )
return;
if( ! bEditingLabel )
{
TREEITEMINFO_t & _TII = TreeItemInfoGet( hti );
_TII.m_strEditText = LPCTSTR(strEditedText);
} // if( ! bEditingLabel )
else
{
HWND hWndParent = ::GetParent( m_hWnd );
UINT nOwnID = GetDlgCtrlID();
CExtSafeString strItemText;
TV_DISPINFO _data;
::memset( &_data, 0, sizeof(TV_DISPINFO) );
_data.hdr.hwndFrom = m_hWnd;
_data.hdr.idFrom = nOwnID;
_data.hdr.code = TVN_ENDLABELEDIT;
_data.item.mask = TVIF_CHILDREN|TVIF_HANDLE|TVIF_PARAM|TVIF_STATE;
_data.item.hItem = hti;
GetItem( &_data.item );
strItemText = GetItemText( hti );
if( strItemText == LPCTSTR(strEditedText) )
{
_data.item.cchTextMax = 0;
_data.item.pszText = 0;
}
else
{
_data.item.cchTextMax = INT(strItemText.GetLength());
_data.item.pszText = strItemText.IsEmpty() ? _T("") : LPTSTR(LPCTSTR(strItemText));
_data.item.mask |= TVIF_TEXT;
}
if( ::SendMessage( hWndParent, WM_NOTIFY, WPARAM(nOwnID), LPARAM(&_data) ) != 0 )
return;
SetItemText( hti, LPCTSTR(strEditedText) );
} // else from if( ! bEditingLabel )
}
|
|
Jeroen Walter
|
Nov 24, 2009 - 3:19 AM
|
Thanks. It’s almost correct, as the msdn documentation of TVN_ENDLABELEDIT states: "Return Value If the pszText member is non-NULL, return TRUE to set the item’s label to the edited text. Return FALSE to reject the edited text and revert to the original label."
So the if-statement around the SendMessage for TVN_ENDLABELEDIT is incorrect, it should return if SendMessage returns FALSE instead of TRUE.
|
|
Technical Support
|
Nov 24, 2009 - 2:07 PM
|
Yes, you are right. Here is the correct version:
void CExtTreeCtrl::OnInplaceControlComplete(
__EXT_MFC_SAFE_LPCTSTR strEditedText,
bool bEditingLabel
)
{
ASSERT_VALID( this );
HTREEITEM hti = GetInPlaceEditedItem();
if( hti == NULL )
return;
if( ! bEditingLabel )
{
TREEITEMINFO_t & _TII = TreeItemInfoGet( hti );
_TII.m_strEditText = LPCTSTR(strEditedText);
} // if( ! bEditingLabel )
else
{
HWND hWndParent = ::GetParent( m_hWnd );
UINT nOwnID = GetDlgCtrlID();
CExtSafeString strItemText;
TV_DISPINFO _data;
::memset( &_data, 0, sizeof(TV_DISPINFO) );
_data.hdr.hwndFrom = m_hWnd;
_data.hdr.idFrom = nOwnID;
_data.hdr.code = TVN_ENDLABELEDIT;
_data.item.mask = TVIF_CHILDREN|TVIF_HANDLE|TVIF_PARAM|TVIF_STATE;
_data.item.hItem = hti;
GetItem( &_data.item );
strItemText = GetItemText( hti );
bool bModeNotNULL = true;
if( strItemText == LPCTSTR(strEditedText) )
{
bModeNotNULL = false;
_data.item.cchTextMax = 0;
_data.item.pszText = 0;
}
else
{
_data.item.cchTextMax = INT(strItemText.GetLength());
_data.item.pszText = strItemText.IsEmpty() ? _T("") : LPTSTR(LPCTSTR(strItemText));
_data.item.mask |= TVIF_TEXT;
}
if( ! ::SendMessage( hWndParent, WM_NOTIFY, WPARAM(nOwnID), LPARAM(&_data) ) != 0 )
{
if( bModeNotNULL )
return;
}
SetItemText( hti, LPCTSTR(strEditedText) );
} // else from if( ! bEditingLabel )
}
|
|
Jeroen Walter
|
Nov 26, 2009 - 2:07 AM
|
|
|
Technical Support
|
Nov 18, 2009 - 12:34 PM
|
The CExtTreeCtrl control is completely re-painted version of tree view common control with a set of unique features. We had to handle all the mouse/keyboard input in it for implementing its extended features. As result, we also had to implement emulations for standard TVN_*** notifications. The best approach to implement selective item editing is to enable editing of all the item labels and override the CExtTreeCtrl::OnInplaceControlCreate() virtual method. Your method should return NULL for non-editable tree items and invoke parent class method in other case.
|
|
Lars Mohr
|
Nov 19, 2009 - 5:00 AM
|
The CExtTreeCtrl::OnInplaceControlCreate virtual methode will call only if you want to editing the lable of the control not of the item themselfes.
if( ( dwHitTestFlags & __EXT_TVHT_ONCONTROL ) != 0 )
{
CRect rcControl;
VERIFY( TreeItemRectGet( hti, rcControl, e_tirt_control ) );
ASSERT( ! rcControl.IsRectEmpty() );
if( m_hWndChildControl != NULL )
{
CRect rc;
::GetWindowRect( m_hWndChildControl, &rc );
if( rc == rcControl )
return true;
SendMessage( WM_CANCELMODE );
}
m_hWndChildControl = OnInplaceControlCreate( hti, rcControl );
if( m_hWndChildControl != NULL )
m_htiInplaceEdited = hti;
return true;
}
|
|
Technical Support
|
Nov 19, 2009 - 1:52 PM
|
Yes, you are right. The CExtTreeCtrl::WindowProc() virtual method and handles the TVM_EDITLABEL message and runs the in-place activate label editor window. You should override this virtual method in your CExtTreeCtrl -derived class, catch the TVM_EDITLABEL message and not invoke the parent class method for non-editable labels. The LPARAM parameter is the HTREEITEM handle for label editing.
|
|
Jeroen Walter
|
Nov 23, 2009 - 3:55 AM
|
Thanks, I already saw that option in the code, but again, it relies on knowing the implementation of the CExtTreeCtrl, which may change in next releases of profuis, so for me it’s a bad idea. "As result, we also had to implement emulations for standard TVN_*** notifications." Clearly the emulation is not complete. I will try your suggestion though, but I still think that you should’ve emulated the default tree ctrl behaviour better.
|
|
Lars Mohr
|
Nov 18, 2009 - 6:21 AM
|
Hi, I solved the problem with the OnTimer function and the nIDEvent == m_nDelayedEditingTimerID Event ID. Best regards
|
|
Jeroen Walter
|
Nov 18, 2009 - 6:39 AM
|
Not an option. It implies knowledge about the internal working of the CExtTreeCtrl, which may be different in a next release. For me, clearly, the interface of CExtTreeCtrl is lacking features and default CTreeCtrl behavior is broken.
|
|
John Ritzenthaler
|
Nov 16, 2009 - 3:24 PM
|
I’n using a CExtScrollBar to scroll an image. I expect to get messages such as SB_LINEUP, SB_LINEDOWN, etc. But all I get is SB_THUMBTRACK. I have user preferences on how much a line or a page should scroll. It’s not a linear scale so I can’t do what I want by setting the scrollbar range. There’s is similar dicsucssion about this in the thread titled "bug inside CExtScrollBar" Aug 5, 2008. I’m on 2.83
|
|
Technical Support
|
Nov 18, 2009 - 6:49 AM
|
This is fixed on the later Prof-UIS versions. You can get the source code of the CExtScrollBar class from the new Prof-UIS version or switch to just released Prof-UIS 2.87.
|
|
Eric Houvenaghel
|
Nov 16, 2009 - 10:21 AM
|
There is a slight problem with the CompareEx function.
Here is a recap of what I want to do.
For comaprison when sorting by clicking on the column header, I want to compare dates numerically.
To perform this comparison, I test for the __EGCCT_GENERIC_GRID_SORTING flag in the CompareEx function.
No problem there.
For comparison when grouping, I want a textual comparison of the dates based on a user defined format.
To perform this comparison, I SHOULD be able to test for the __EGCCT_REPORT_GRID_GROUPING flag only in the CompareEx function.
However, when grouping a column, you first recieve the __EGCCT_GENERIC_GRID_SORTING flag and some time later, your receive __EGCCT_REPORT_GRID_GROUPING.
For grouping, shouldn’t the CompareEx function only recieve the __EGCCT_REPORT_GRID_GROUPING flag?
The bug is that I get sepperate groups when they should be together.
In the image below, I want to group by year only.
Some of the cells only have a time component. They should all be grouped together but they are not. Is this fixable on your end or not?
|
|
Technical Support
|
Nov 16, 2009 - 1:46 PM
|
The sorting/grouping algorithm of the report grid control does it work in several steps:
1) It removes all the existing group rows. Only the data rows left.
2) It sorts the data rows by all the columns. Fist by group columns, second by sort columns. The __EGCCT_GENERIC_GRID_SORTING flag is used at this step.
3) It walks through the sorted rows and inserts the group rows where they needed. This step also requires the grid cell comparison. The __EGCCT_REPORT_GRID_GROUPING flag is used at this step.
So, if you compared several year 2007 and several year 2008 date time cells as date time values and the step 2, then they sorted correctly: all the year 2007 rows are near each other and all the year 2008 rows are also near each other. Then, at the 3rd step, you should did a different comparison. Your date time cell class should compare years only to let the report grid to group its rows by year only. Additionally, the report data rows under each year group row will be correctly sorted ascending or descending by entire date value. This is absolutely correct and the 2nd step is really needed for that.
Please provide us with the source code of your date time cell class and we will test it.
|
|
Rolf Boerkoel
|
Nov 16, 2009 - 3:50 AM
|
Dear support,
If I hover over a nonclient MDI button (close, minimize or maximize) and then close the frame, I get a "Warning: calling DestroyWindow in CWnd::~CWnd; OnDestroy or PostNcDestroy in derived class will not be called" in the debug output window. This apparently comes from the CExtPopupMenuTipWnd. This does only occur with Office-themed CExtNCW frame windows. It is probably not the most important of things, but I’ll report it anyway.
I sent you a simple sample application by email so that you can see it right away for yourselves.
Kind regards,
Marco
|
|
Technical Support
|
Nov 16, 2009 - 1:45 PM
|
Thank you for reporting this issue. The fix consists of two parts: 1) The CExtNcFrameImpl::NcFrameImpl_PreWindowProc() method is organized into big switch statement. Please update the following part of it:
case WM_SYSCOMMAND:
{
if( ! NcFrameImpl_IsSupported() )
break;
if( NcFrameImpl_IsDwmBased() )
break;
CExtPopupMenuWnd::CancelMenuTracking();
CWnd::CancelToolTips();
CExtPopupMenuSite::g_DefPopupMenuSite.GetTip().Hide();
m_wndNcFrameImpl_Tip.Hide();
if( m_wndNcFrameImpl_Tip.GetSafeHwnd() != NULL )
m_wndNcFrameImpl_Tip.DestroyWindow();
UINT nSC = UINT( wParam );
if( nSC == SC_SIZE || nSC == SC_NEXTWINDOW || nSC == SC_PREVWINDOW )
break;
if( ! NcFrameImpl_OnQuerySystemCommandEnabled( nSC ) )
{
lResult = 0;
return true;
}
pWndFrameImpl->ModifyStyle( 0, WS_CAPTION|WS_BORDER, 0 );
if( NcFrameImpl_OnQueryQuickWindowPlacement() )
{
if( nSC == SC_MAXIMIZE
|| nSC == SC_MINIMIZE
|| nSC == SC_RESTORE
)
{
WINDOWPLACEMENT _wp;
::memset( &_wp, 0, sizeof(WINDOWPLACEMENT) );
if( GetWindowPlacement( &_wp ) )
{
switch( nSC )
{
case SC_MAXIMIZE:
_wp.showCmd = SW_SHOWMAXIMIZED;
break;
case SC_MINIMIZE:
m_nNcFrameImpl_LastShowCmd = _wp.showCmd;
_wp.showCmd = SW_SHOWMINIMIZED;
break;
case SC_RESTORE:
_wp.showCmd =
( m_nNcFrameImpl_LastShowCmd != SW_HIDE )
? m_nNcFrameImpl_LastShowCmd
: SW_RESTORE // SW_SHOWNORMAL
;
m_nNcFrameImpl_LastShowCmd = SW_HIDE;
if( _wp.showCmd == SW_SHOWMAXIMIZED && pWndFrameImpl->IsZoomed() )
_wp.showCmd = SW_RESTORE;
break;
#ifdef _DEBUG
default:
ASSERT( FALSE );
break;
#endif // _DEBUG
} // switch( nSC )
SetWindowPlacement( &_wp );
} // if( GetWindowPlacement( hWndOwn, &_wp ) )
lResult = 0;
return true;
}
} // if( NcFrameImpl_OnQueryQuickWindowPlacement() )
if( message == WM_SYSCOMMAND && nSC == SC_MINIMIZE && pWndFrameImpl->IsKindOf(RUNTIME_CLASS(CMDIChildWnd)) )
{ // fix for minimizing of maximized MDI child frame
HWND hWndMdiClient = ::GetParent( pWndFrameImpl->m_hWnd );
BOOL bMax = FALSE;
HWND hWndActiveMdiChildFrame = (HWND) ::SendMessage( hWndMdiClient, WM_MDIGETACTIVE, 0, (LPARAM)&bMax );
if( hWndActiveMdiChildFrame != NULL && bMax )
{
bool bNextAvailable = false;
HWND hWnd = ::GetWindow( hWndActiveMdiChildFrame, GW_HWNDNEXT );
for( ; hWnd != NULL; hWnd = ::GetWindow( hWnd, GW_HWNDNEXT ) )
{
__EXT_MFC_LONG_PTR dwWndStyle = ::__EXT_MFC_GetWindowLong( hWnd, GWL_STYLE );
if( ( dwWndStyle & WS_VISIBLE ) == 0 )
continue;
if( IsIconic( hWnd ) )
continue;
bNextAvailable = true;
break;
}
if( ! bNextAvailable )
{
hWnd = ::GetWindow( hWndActiveMdiChildFrame, GW_HWNDPREV );
for( ; hWnd != NULL; hWnd = ::GetWindow( hWnd, GW_HWNDPREV ) )
{
__EXT_MFC_LONG_PTR dwWndStyle = ::__EXT_MFC_GetWindowLong( hWnd, GWL_STYLE );
if( ( dwWndStyle & WS_VISIBLE ) == 0 )
continue;
if( IsIconic( hWnd ) )
continue;
bNextAvailable = true;
break;
}
}
if( bNextAvailable )
{
CRect rcSurface;
::GetClientRect( hWndMdiClient, &rcSurface );
HWND hWndSurface =
::CreateWindowEx(
0, _T("Static"), _T(""), WS_CHILD, rcSurface.left, rcSurface.top, rcSurface.Width(), rcSurface.Height(),
hWndMdiClient, (HMENU)NULL, ::AfxGetInstanceHandle(), NULL
);
if( hWndSurface != NULL )
{
::EnableWindow( hWndSurface, FALSE );
::ShowWindow( hWndSurface, SW_SHOWNOACTIVATE );
}
::SendMessage( hWndMdiClient, WM_MDINEXT, WPARAM(pWndFrameImpl->m_hWnd), 0L );
struct friendly_wnd_t : public CWnd { friend class CExtNcFrameImpl; };
lResult = ((friendly_wnd_t*)pWndFrameImpl)->DefWindowProc( message, wParam, lParam );
hWndActiveMdiChildFrame = (HWND) ::SendMessage( hWndMdiClient, WM_MDIGETACTIVE, 0, (LPARAM)&bMax );
if( hWndActiveMdiChildFrame != NULL )
{
::SendMessage( hWndMdiClient, WM_MDIMAXIMIZE, WPARAM(hWndActiveMdiChildFrame), 0L );
::SendMessage( hWndMdiClient, WM_MDIACTIVATE, WPARAM(hWndActiveMdiChildFrame), 0L );
}
::DestroyWindow( hWndSurface );
return true;
} // if( bNextAvailable )
} // if( hWndActiveMdiChildFrame != NULL && bMax )
} // fix for minimizing of maximized MDI child frame
if( m_bNcFrameImpl_IsEnabled
&& ( ! m_bNcFrameImpl_RestoreEnabledState )
&& nSC != SC_MOVE
&& nSC != SC_SIZE
&& pWndFrameImpl->IsKindOf( RUNTIME_CLASS( CMDIChildWnd ) )
)
m_bNcFrameImpl_RestoreEnabledState = true;
if( nSC != SC_CLOSE )
NcFrameImpl_NcLock( true );
}
break;
2) The CExtNcFrameImpl::~CExtNcFrameImpl() destructor: CExtNcFrameImpl::~CExtNcFrameImpl()
{
m_wndNcFrameImpl_Tip.Hide();
if( m_wndNcFrameImpl_Tip.GetSafeHwnd() != NULL )
m_wndNcFrameImpl_Tip.DestroyWindow();
m_BridgeNC.NcFrameImpl_Set( NULL );
NcFrameImpl_MapHtRects_Clean();
}
|
|
Lars Mohr
|
Nov 15, 2009 - 5:11 PM
|
Dear Support Team, there is a bug in the CExtPropertyItem::Serialize function. If you store the data everything is ok, but if you want to load it then the try/catch block throw an exception. You can try it with the PropertyGrid example. Just uncomment the function call ValueDefaultFromActive .
CStarButtonProperty_Animation::CStarButtonProperty_Animation(
CStarButton * pStarButton // = NULL
)
: CStarPropertyValueBase(
_T("Animation"),
pStarButton
)
{
DescriptionSet( _T("Specifies the star animation effect.") );
CExtGridCellComboBox * pValue =
STATIC_DOWNCAST(
CExtGridCellComboBox,
ValueActiveGetByRTC( RUNTIME_CLASS(CExtGridCellComboBox) )
);
ASSERT_VALID( pValue );
pValue->InsertString( _T("None"), DWORD(CStarButton::__EAT_NONE) );
pValue->InsertString( _T("Slow"), DWORD(CStarButton::__EAT_SLOW) );
pValue->InsertString( _T("Middle"), DWORD(CStarButton::__EAT_MIDDLE) );
pValue->InsertString( _T("Fast"), DWORD(CStarButton::__EAT_FAST) );
pValue->SetEnumMode();
if( m_pStarButton != NULL )
pValue->SetCurSel(
(INT)m_pStarButton->AnimationGet()
);
// ValueDefaultFromActive(); <- UNCOMMENT And I think, I have found the problem:
void CExtPropertyItem::Serialize( CArchive & ar )
{
ASSERT_VALID( this );
if( ar.IsStoring() )
{
...
CExtGridCell * pCellDefault = ValueDefaultGet(), * pCellActive = ValueActiveGet();
if( pCellDefault != NULL && LPVOID(pCellDefault) != LPVOID(pCellActive) )
{
ASSERT_VALID( pCellDefault );
dwFlags |= 0x00000001;
} // if( pCellDefault != NULL )
if( pCellDefault != NULL && LPVOID(pCellDefault) != LPVOID(pCellActive) )
{
ASSERT_VALID( pCellActive );
dwFlags |= 0x00000002;
} // if( pCellActive != NULL )
...
} // if( ar.IsStoring() )
else
{
...
} // else from if( ar.IsStoring() ) should be replaced with
if( pCellActive != NULL ) Thanks...
|
|
Technical Support
|
Nov 20, 2009 - 2:39 PM
|
There is a typo in the CExtPropertyItem::Serialize() method’s source code. Here is the fixed version:
void CExtPropertyItem::Serialize( CArchive & ar )
{
ASSERT_VALID( this );
if( ar.IsStoring() )
{
ar << m_strName;
ar << m_strDescription;
DWORD dwTmp = DWORD( m_lParam );
ar << dwTmp;
dwTmp = DWORD(m_nHeightPx);
ar << dwTmp;
DWORD dwFlags = 0;
CExtGridCell * pCellDefault = ValueDefaultGet(), * pCellActive = ValueActiveGet();
if( pCellDefault != NULL && LPVOID(pCellDefault) != LPVOID(pCellActive) )
{
ASSERT_VALID( pCellDefault );
dwFlags |= 0x00000001;
}
if( pCellActive != NULL )
{
ASSERT_VALID( pCellActive );
dwFlags |= 0x00000002;
}
if( ExpandedGet() )
dwFlags |= 0x00000004;
if( InputEnabledGet() )
dwFlags |= 0x00000008;
ar << dwFlags;
if( pCellDefault != NULL && LPVOID(pCellDefault) != LPVOID(pCellActive) )
{
CRuntimeClass * pRTC = pCellDefault->GetRuntimeClass();
ASSERT( pRTC != NULL );
ar.WriteClass( pRTC );
pCellDefault->Serialize( ar );
} // if( pCellDefault != NULL && LPVOID(pCellDefault) != LPVOID(pCellActive) )
if( pCellActive != NULL )
{
CRuntimeClass * pRTC = pCellActive->GetRuntimeClass();
ASSERT( pRTC != NULL );
ar.WriteClass( pRTC );
pCellActive->Serialize( ar );
} // if( pCellActive != NULL )
DWORD dwIndex, dwCount = ItemGetCount();
ar << dwCount;
for( dwIndex = 0; dwIndex < dwCount; dwIndex ++ )
{
CExtPropertyItem * pItem =
ItemGetAt( INT(dwIndex) );
ASSERT_VALID( pItem );
ASSERT_KINDOF( CExtPropertyItem, pItem );
CRuntimeClass * pRTC = pItem->GetRuntimeClass();
ASSERT( pRTC != NULL );
ar.WriteClass( pRTC );
pItem->Serialize( ar );
} // for( dwIndex = 0; dwIndex < dwCount; dwIndex ++ )
} // if( ar.IsStoring() )
else
{
if( ItemGetCount() > 0 )
ItemRemove();
ar >> m_strName;
ar >> m_strDescription;
DWORD dwTmp;
ar >> dwTmp;
m_lParam = LPARAM(dwTmp);
ar >> dwTmp;
m_nHeightPx = INT(dwTmp);
DWORD dwFlags;
ar >> dwFlags;
if( (dwFlags&0x00000001) != 0 )
{
CRuntimeClass * pRTC = ar.ReadClass();
ASSERT( pRTC != NULL );
CExtGridCell * pCellDefault = (CExtGridCell*)pRTC->CreateObject();
ASSERT_VALID( pCellDefault );
ASSERT_KINDOF( CExtGridCell, pCellDefault );
pCellDefault->Serialize( ar );
ASSERT_VALID( pCellDefault );
VERIFY( ValueDefaultSet( pCellDefault ) );
} // if( (dwFlags&0x00000001) != 0 )
if( (dwFlags&0x00000002) != 0 )
{
CRuntimeClass * pRTC = ar.ReadClass();
ASSERT( pRTC != NULL );
CExtGridCell * pCellActive = (CExtGridCell*)pRTC->CreateObject();
ASSERT_VALID( pCellActive );
ASSERT_KINDOF( CExtGridCell, pCellActive );
pCellActive->Serialize( ar );
ASSERT_VALID( pCellActive );
VERIFY( ValueActiveSet( pCellActive ) );
} // if( (dwFlags&0x00000002) != 0 )
if( (dwFlags&0x00000004) != 0 )
ExpandedSet( true );
else
ExpandedSet( false );
if( (dwFlags&0x00000008) != 0 )
InputEnabledSet( true );
else
InputEnabledSet( false );
DWORD dwIndex, dwCount;
ar >> dwCount;
for( dwIndex = 0; dwIndex < dwCount; dwIndex ++ )
{
CRuntimeClass * pRTC = ar.ReadClass();
ASSERT( pRTC != NULL );
CExtPropertyItem * pItem = (CExtPropertyItem*)pRTC->CreateObject();
ASSERT_VALID( pItem );
ASSERT_KINDOF( CExtPropertyItem, pItem );
pItem->Serialize( ar );
ASSERT_VALID( pItem );
VERIFY( ItemInsert( pItem ) );
} // for( dwIndex = 0; dwIndex < dwCount; dwIndex ++ )
} // else from if( ar.IsStoring() )
}
|
|
Technical Support
|
Nov 16, 2009 - 1:32 PM
|
This is not a bug. The CExtPropertyValue object requires both active and default grid cells instantiated inside it and they should be different grid cells. Only such fully initialized property values should be inserted into the property store before assigning it to the property grid control.
|
|
Lars Mohr
|
Nov 17, 2009 - 2:53 AM
|
So the function call ValueDefaultFromActive is important and necessary!? But if I don’t want to have the default and reset to default feature?
|
|
Lars Mohr
|
Nov 17, 2009 - 5:07 AM
|
Oh I have found it: CExtPropertyValueSingleCell... sorry for my mistake!
|
|
Lars Mohr
|
Nov 19, 2009 - 3:38 PM
|
sorry but I have stille the problem with the CExtPropertyItem::Serialize methode. Now I use a CExtPropertyValueSingleCell instead of a CExtPropertyValue . But the problem ist still there. If you store a CExtPropertyValueSingleCell or CExtPropertyValue you check if pCellActive != NULL and store the CExtGridCell :
if( pCellActive != NULL )
{
CRuntimeClass * pRTC = pCellActive->GetRuntimeClass();
ASSERT( pRTC != NULL );
ar.WriteClass( pRTC );
pCellActive->Serialize( ar );
} // if( pCellActive != NULL ) But you don’t set the flag to 0x00000002, because the flag condition is: if( pCellDefault != NULL && LPVOID(pCellDefault) != LPVOID(pCellActive) )
{
ASSERT_VALID( pCellActive );
dwFlags |= 0x00000002;
} // if( pCellActive != NULL ) So if you want to load it again, the app crashed because the flag 0x00000002 is missing.
|
|
Offer Har
|
Nov 14, 2009 - 2:10 PM
|
Dear Support, Do you have mode details and samples of this new flag? Thanks, Ron.
|
|
Technical Support
|
Nov 16, 2009 - 1:23 PM
|
The scroll bar control provided by the __EPCWS_USE_SCROLLBAR_CTRL style is the replacement for the scroll bar like looking area present in the previous version of the page container control. Please run the PageContainer sample application, select the 3DS MAX like style preset from menu, then check the Use Scroll Bar check box and scroll bar will appear. Both scroll bar and scroll area are displayed by the page container which is not configured for displaying only one expanded page stretched to entire page container area.
|