Professional UI Solutions
Site Map   /  Register
 
 

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.

Forums » Prof-UIS Tech Support » FormEditor - GroupBox Collapse All
Subject Author Date
Suhai Gyorgy Nov 30, 2006 - 8:22 AM

Dear Support,

Again I’m having problem with your FormEditor sample. What I’m trying to achieve is that controls placed onto a groupbox shall be visible at all times. When testing around this issue, I saw a strange behaviour of your original sample: no matter how many controls I try to create, last created control is always drawn "under" groupbox, all others are drawn above it (as I’d like all of them to be). Could you please check this issue?

Thank you,
Chris

Technical Support Nov 30, 2006 - 12:21 PM

Please update the source code for the CFormEditorView::SyncDocItems() method in the FormEditor sample to fix the Z-order issue:

void CFormEditorView::SyncDocItems()
{
    ASSERT_VALID( this );
CFormEditorDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    SetRedraw( FALSE );
 
    m_mapSelection.RemoveAll();
 
HWND hWndChild = ::GetWindow( m_hWnd, GW_CHILD );
    for( ;    hWndChild != NULL;
            hWndChild = ::GetWindow( m_hWnd, GW_CHILD )
            )
        ::DestroyWindow( hWndChild );
 
CClientDC dc( this );
    OnPrepareDC( &dc, NULL );
 
    for( int nItem = 0; nItem < pDoc->m_vItems.GetSize(); nItem++ )
    {
        CFormEditorDoc::DOC_ITEM_DATA & _did =
            pDoc->m_vItems[ nItem ];
        CString sClassName;
        VERIFY(
            CFormEditorToolBoxWnd::g_mapIdToWndClassName.Lookup(
                _did.m_dwItemID,
                sClassName
                )
            );
        ASSERT( !sClassName.IsEmpty() );
        DWORD dwAdditionalWindowStyles = 0L;
        VERIFY(
            CFormEditorToolBoxWnd::g_mapIdToWndStyle.Lookup(
                _did.m_dwItemID,
                dwAdditionalWindowStyles
                )
            );
        CRect rcItem( _did.m_rcItem );
        dc.LPtoDP( &rcItem );
        hWndChild =
            ::CreateWindowEx(
                WS_EX_TRANSPARENT,
                _T("STATIC"),
                NULL,
                WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
                rcItem.left,
                rcItem.top,
                rcItem.Width(),
                rcItem.Height(),
                m_hWnd,
                (HMENU)NULL,
                ::AfxGetInstanceHandle(),
                0L
                );
        ASSERT( hWndChild != NULL );
        ::EnableWindow( hWndChild, FALSE );
        HWND hWndControl =
            ::CreateWindowEx(
                WS_EX_TRANSPARENT,
                (LPCTSTR)sClassName,
                NULL,
                WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN
                    |dwAdditionalWindowStyles,
                0,
                0,
                _did.m_rcItem.Width(),
                _did.m_rcItem.Height(),
                hWndChild,
                (HMENU)NULL,
                ::AfxGetInstanceHandle(),
                0L
                );
        ASSERT( hWndControl != NULL );
        hWndControl;
        //////////////////////////////////////////////
        //////////////////////////////////////////////
        //////////////////////////////////////////////
        //
        // ADDED:
        //
        ::SetWindowPos(
            hWndChild, HWND_TOP, 0, 0, 0, 0,
            SWP_NOMOVE|SWP_NOSIZE
            );
        //////////////////////////////////////////////
        //////////////////////////////////////////////
        //////////////////////////////////////////////
    }
    SetRedraw( TRUE );
    RedrawWindow(
        NULL,
        NULL,
        RDW_INVALIDATE|RDW_ERASE
            |RDW_UPDATENOW|RDW_ERASENOW
            |RDW_ALLCHILDREN
        );
    RedrawRuler( true );
    RedrawRuler( false );
}


Suhai Gyorgy Nov 30, 2006 - 2:07 PM

Sorry, this won’t be good, it messes up the other functions, which depend on the HWND order being the same as the order in m_vItems. Adding those lines, now when I resize any of the controls, the control types switch.

Technical Support Dec 2, 2006 - 1:34 PM

The z-order based painting you noticed is provided by Windows OS. There is an alternative design of the form editor’s view window. It is based on invisible controls inside the form area. The invisible controls are painted into a bitmap buffer and later are painted to the form area. You can download the updated version of the FormEditor sample from our website.


Please also update the source code for the CExtPaintManager::stat_PrintWnd() method in ..\Prof-UIS\Src\ExtPaintManager.cpp and its declaration in ..\Prof-UIS\Include\ExtPaintManager.h:

HBITMAP CExtPaintManager::stat_PrintWnd(
    HWND hWnd,
    UINT nMessage, // = WM_PRINTCLIENT
    LPARAM lParamPrint, // = PRF_NONCLIENT|PRF_CLIENT|PRF_ERASEBKGND|PRF_CHILDREN
    HDC hSrcDC, // = NULL
    const RECT * pRectFillSrc // = NULL
    )
{
    ASSERT( hWnd != NULL && ::IsWindow(hWnd) );
    ASSERT( nMessage == WM_PRINT || nMessage == WM_PRINTCLIENT );
CRect rcWnd, rcClient;
    ::GetWindowRect( hWnd, &rcWnd );
    ::GetClientRect( hWnd, &rcClient );
CSize _sizeDest =
        ( (lParamPrint&PRF_NONCLIENT) != 0 )
            ? rcWnd.Size()
            : rcClient.Size()
            ;
HDC hDC = ::CreateCompatibleDC( NULL );
    if( hDC == NULL )
    {
        ASSERT( FALSE );
        return NULL;
    }
BITMAPINFOHEADER bih;
    ::memset( &bih, 0, sizeof(BITMAPINFOHEADER) );
    bih.biSize = sizeof(BITMAPINFOHEADER);
    bih.biWidth = _sizeDest.cx;
    bih.biHeight = _sizeDest.cy;
    bih.biPlanes = 1;
    bih.biBitCount = 32;
    bih.biCompression = BI_RGB;
    bih.biSizeImage = _sizeDest.cx * _sizeDest.cy;
COLORREF * pSurface = NULL;
HBITMAP hBmpSufrace =
        ::CreateDIBSection(
            hDC,
            (LPBITMAPINFO)&bih,
            DIB_RGB_COLORS,
            (void **)&pSurface,
            NULL,
            NULL
            );
    ASSERT( hBmpSufrace != NULL );
    if( hBmpSufrace == NULL )
    {
        ::DeleteDC( hDC );
        ASSERT( FALSE );
        return NULL;
    }
    ASSERT( pSurface != NULL );
HGDIOBJ hBmpOld = ::SelectObject( hDC, (HGDIOBJ)hBmpSufrace );
    if(     hSrcDC != NULL
        &&  pRectFillSrc != NULL
        &&  pRectFillSrc->left < pRectFillSrc->right
        &&  pRectFillSrc->top < pRectFillSrc->bottom
        )
        ::BitBlt(
            hDC,
            0,
            0,
            pRectFillSrc->right - pRectFillSrc->left,
            pRectFillSrc->bottom - pRectFillSrc->top,
            hSrcDC,
            pRectFillSrc->left,
            pRectFillSrc->top,
            SRCCOPY
            );
LRESULT lResult =
    ::SendMessage(
        hWnd,
        nMessage,
        (WPARAM)hDC,
        lParamPrint
        );
    if( lResult != 0 )
    {
        COLORREF clrBk = ::GetSysColor( COLOR_WINDOW );
        COLORREF clrBkOld = ::SetBkColor( hDC, clrBk );
        CRect rect( 0, 0, _sizeDest.cx, _sizeDest.cy );
        ::ExtTextOut( hDC, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL );
        ::SetBkColor( hDC, clrBkOld );
    }
    ::SelectObject( hDC, (HGDIOBJ)hBmpOld );
    ::DeleteDC( hDC );
    return hBmpSufrace;
}


Suhai Gyorgy Dec 4, 2006 - 4:27 AM

1. I’ve updated CExtPaintManager::stat_PrintWnd(), rebuilt my lib file and tested the new sample you provided, but some controls were not painted correctly. Could it be that I need the latest of your source code? (I’m using v2.55 now.)

2. Will this CExtPaintManager::stat_PrintWnd() update be available in the next version of Prof-UIS, or will I have to apply this change after upgrading?

3. As I mentioned earlier, I heavily modified your FormEditor sample, so to my application I would like to apply only the neccessary changes from your original FormEditor to this updated version. For this reason I did some code comparing. Could you please check if I missed any of the changes? These are the ones I found:
a) From CFormEditorView::OnDraw you removed a loop with ExcludeClipRect in it, and added a block of code for drawing the controls between the if blocks of "draw selected layout" and "draw tab orders".
b) In CFormEditorView::SyncDocItems you removed WS_VISIBLE style from creation of hWndChild.
c) In CMainFrame::PreCreateWindow you added a line cs.style |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS; .
d) In CFormEditorToolBoxWnd::arrItems you changed some m_sClassName elements to EDIT.

4. I understand why all these changes are needed except for d). Could you explain?

5. In CFormEditorView::OnDraw can I place the block of code for drawing the controls before block "draw selected layout"? That way the selection rectangles could be visible even when controls are partially hidden by each other.

Technical Support Dec 4, 2006 - 12:38 PM

Here are the answers to your questions:

1 and 3d ) The new approach is based on the WM_PRINTCLIENT standard Windows message which is used for printing window surfaces. We were very surprised to discover that not all standard Windows common controls are handling this message. That is why some controls are drawn incorrectly and some of them are replaced with edit controls.

2) It will be available in Prof-UIS as it is in your copy of Prof-UIS now.

3 and 4) 3a and 3b are essential. 3c is not required. 3d is not required if you are using Prof-UIS controls and/or ActiveX controls. Otherwise, please provide additional information about the controls used in your form designer application.

5) Yes, it is reasonable.

Suhai Gyorgy Dec 5, 2006 - 2:50 AM

I’m using the following controls:
- the ones printing fine: Static, editbox, chechbox, radio button, group box (actually group box prints the border only, but thats fine with me, maybe even better that way)
- the ones I’m having trouble with:
a) combobox (shall I subclass to CExtComboBox?)
b) listbox (prints fine when empty, prints only texts and their backgrounds after inserting some elements into it (no Prof-UIS class to subclass to, maybe I should derive a class of mine and handle WM_PRINTCLIENT myself?)
c) DateTimePicker (right now created as SysDateTimePick32 and then subclassed as CExtDateTimeWnd; doesn’t print background, only text and dropdown-button)
d) Picture control derived from static, I’m using IPicture to draw pictures like .ico, .bmp, .jpg, .gif. I’m still working on that one.

Am I going to the right direction with combobox and listbox? What are your suggestions about DateTimePicker?

Thank you:
Chris.

Technical Support Dec 5, 2006 - 1:14 PM

Switching to CExtComboBox and other Prof-UIS classes should solve the problem because they implement both WM_PRINT and WM_PRINTCLIENT message handlers and paint everything from scratch. The CExtDateTimeWnd class is not based on the date/time picker common control so you have subclassed it incorrectly. The CExtDateTimeWnd class is derived from the CExtDurationWnd class and uses the ProfUIS-DurationWnd window class name that is defined by the __EXT_DURATION_CLASS_NAME preprocessor symbol. You should create the CExtDateTimeWnd window using the MFC apprach -- not Win32’s used in the FormEditor sample. The only solution we can see at the moment for the list box is to replace it with the CExtGridWnd window with a single column being automatically stretched out to fit the entire client area of the grid.

Suhai Gyorgy Dec 6, 2006 - 6:46 AM

- I’ve subclassed to CExtComboBox, but it’s still painted only as a white rectengle, as if it was an editbox. But when debugging, I can see that your painting code is called (CExtComboBox::_OnDrawComboImpl). I’m guessing it is not drawn on the screen correctly because somewhere in your code it might be checked if the control is visible or not. And since the control is not visible, it is not drawn (printed).

- I’ve switched to use __EXT_DURATIONWND_CLASS_NAME classname instead of SysDateTimePick32. I didn’t really understand what you meant by MFC approach in your last post, but if I call CExtDurationWnd::RegisterWndClass(); before ::CreateWindowEx, it works fine, I can subclass to CExtDateTimeWnd without crash. But nothing is painted on the form where the control should be. I checked this subclassing with the original painting approach (using visible controls and ExcludeClipRect), and I can see the control is subclassed just fine. I did a search for WM_PRINTCLIENT in your source code, but only CExtControlBar and CExtComboBox handles this message. I’m still wondering: do I need higher version of ProfUIS? (I’m using v2.55)

- I’m still deciding if I should go for your suggestion with CExtGridWnd. The problem is, if I want it to act exactly like CListBox, that single column should be stretched not to the client area, but to the longest string in the grid if the longest string is longer than the width of the grid.
I’m working on it.

Technical Support Dec 8, 2006 - 2:29 PM

We tried to find the cause of the Z-order problem in the FormEditor sample. We came to conclusion it is possible to fix the problem using both ways: visible child controls like in the original version of the sample and invisible child controls as we tried to implement for you. The new version of this sample shows both ways and has a new Prof-UIS Controls group inside the toolbox:

FormEditor-Advanced.zip

The following line in the MainFrm.h file is commented by default and the visible controls are used on the form view://#define __FORM_EDITOR_INVISIBLE_MODE__You can uncomment this line to make the FormEditor sample using invisible controls and form painting based on the window printing. We think this mode is not the best, but it is supported.

When the application started, please invoke the Reset ToolBox command from the context menu over toolbox window. This is needed to make the new Prof-UIS Controls group visible. All the Prof-UIS controls are initialized using the MFC window creation way in the CFormEditorView::SyncDocItems() method. We have also changed control moving/resizing code to make it compatible with both form view modes.

Suhai Gyorgy Dec 12, 2006 - 5:15 AM

Thank you very much for your efforts! I tried the latest version of the sample with my original Prof-UIS (v2.55) but it looked so bad that (although you didn’t mention I needed) I’ve downloaded v2.63 to check it with that, as well. New lib didn’t compile. It had problem with first parameter of _tcsncmp in this code in CExtPaintManager::stat_PrintWnd:

			CRuntimeClass * pRTC = pWnd->GetRuntimeClass();
			ASSERT( pRTC != NULL );
			if( _tcsncmp( pRTC->m_lpszClassName, _T("CExt"), 4 ) == 0 )
			bOverPaint = false;
, so I changed that line to if( strncmp( pRTC->m_lpszClassName, "CExt", 4 ) == 0 ) . I’m not sure if this is good fix for all the configurations, but we are only using Static Unicode Debug and Static Unicode Release configurations and they compiled fine. Please, check this issue.

As for the new FormEditor: Looks great! Since I need the selection rectangles even when over groupbox, I’d go for the invisible mode. But in both modes controls inside a groupbox flicker when moving any other control. And in invisible mode when moving control over a groupbox, it is not visible while still dragging it but not moving the mouse. As soon as I release the mouse button, control is visible as expected. Flickering is not such a big problem, but is there anything we could do about this second issue?

Thank you,
Chris.

Technical Support Dec 12, 2006 - 1:12 PM

Please download the latest code from our ftp site. The new version of the FormEditor sample is based on the "invisible" form editing algorithm by default and moving/resizing code is updated to show correct z-order of controls.

Suhai Gyorgy Dec 12, 2006 - 8:55 AM

One little thing though, which has nothing to do with previous problems, but it’s in your new FormEditor_Advanced:
When placing a CExtGrid on the form, its scrollbars are not drawn. Actually while resizing the control, I can see the scrollbars drawn, but as soon as I release the mouse button, there are only theme-specific colored rectangles drawn where scrollbars should be.

Suhai Gyorgy Dec 12, 2006 - 8:12 AM

Dear Support,

I’ve put some of the changes you made to the advanced FormEditor into my own application. Some changes I skipped, like the ones around control moving/resizing code. After all, it works like a charm for me, no flickering, no disappearing during moving, everything is as expected. So I’m calling off my last question about these problems :)

Thank you very much,
Chris