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 » CExtEdit missing text with PrintClient Collapse All
Subject Author Date
Arjan Sep 9, 2009 - 4:41 AM

Hello,



In an attempt to create an application similar to the Prof-UIS sample "FormEditor" we came across 2 things, of which 1 is possibly a decided-by-design.



Basically, our application would like to paint a dialog and its controls to a memory-DC.



1)

However, we noticed that sending a PrintClient-message to a CExtEdit results in the drawing of the edit-control on a DC, but without the static-text.

After examining the routines, we noticed that the OnPaint-handler draws the text directly, whereas routines like PrintClient are unaware of any text to draw.



How can we solved this ?

(draw a CExtEdit on a memory-DC)





2)

We’re assuming the following is decided-by-design, but any suggestions/corrections/comments are welcome ofcourse.



Painting of the non-client-area for controls like CExtButton, CExtComboBox, CExtDataPicker, CExtLabel, CExtSpin, etc. isn’t done by the controls itself.

(with nc-area for these controls I refer to window-styles like Border, ThickFrame, ClientEdge, etc.)

We’re assuming this is mostly because Prof-UIS-skins aren’t intended to be used in combination with window-styles.

(Interestingly enough, CExtEdit doesn’t draw text, but does draw nc-area if requested)



The problem when trying to print the nc-area of a control to a specific DC, is that messages like Print/PrintClient can’t be used.

This, since these messages are captured and handled by the Prof-UIS controls (which, obviously, is exactly what we would like...if only it included the nc-area as well).

We solved this by drawing all controls twice...once by sending a PrintClient-message to the pre-Prof-UIS-window-procedure for the non-client-area....followed by sending a PrintClient-message to the control itself for the client-area.





Thanks in advance,

Arjan Lukkesen

Ellips B.V.

Arjan Sep 17, 2009 - 2:22 AM

Thank you for reply, it works.


Sorry I wasn’t able to test it right away, but I just did, and it solves the problems we’ve encountered.


Also thank you for checking other controls, and fixing the ComboBox aswell.

Technical Support Sep 10, 2009 - 2:39 AM

The CExtEditBase class and all classes derived from it look like they really have some window surface printing issues. But the real problem is hidden in the CExtED template class. To fix the editor text printing issue, please update the source code for the CExtED::WindowProc() virtual method:

 virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
      {
            switch( message )
            {
            case WM_PRINT:
            case WM_PRINTCLIENT:
                  {
                        _BED::WindowProc(message, wParam, lParam);
                        CDC * pDC = CDC::FromHandle( (HDC) wParam );
                        CExtEditBase::stat_PrintClient( OnQueryWindowEnabledState(), m_bMouseOver, message, lParam, this, this, pDC );
                        return (!0L);
                  }
                  break;
            case WM_TIMER:
                  {
                        if( wParam == __EXT_EDIT_UPDATE_TIMER )
                        {
                              POINT pt;
                              if(         IsWindowVisible()
                                    &&    ::GetCursorPos( &pt ) 
                                    )
                              {
                                    bool bOldMouseOver = m_bMouseOver;
                                    CRect rectItem;
                                    GetWindowRect( &rectItem );
                                    if( !rectItem.PtInRect(pt) )
                                    {
                                          KillTimer( __EXT_EDIT_UPDATE_TIMER );
                                          m_bMouseOver = false;
                                    }
                                    else 
                                          if(   ::WindowFromPoint( pt ) == m_hWnd )
                                                m_bMouseOver = true;
                                          if( bOldMouseOver != m_bMouseOver )
                                                _PostRedraw();
                              }
                              return 0L;
                        }
                  }
                  break;
            case WM_SETFOCUS:
            case WM_KILLFOCUS:
                  {
                        LRESULT lRes = _BED::WindowProc(message, wParam, lParam);
                        _PostRedraw();
                        return lRes;
                  }
                  break;
            case WM_SETCURSOR:
                  {
                        if( HIWORD( lParam ) == WM_MOUSEMOVE )
                        {
                              CRect rcWnd;
                              GetWindowRect( &rcWnd );
                              if( rcWnd.PtInRect( GetCurrentMessage()->pt ) )
                              {
                                    SetTimer( __EXT_EDIT_UPDATE_TIMER, __EXT_EDIT_UPDATE_TIMER_PERIOD, NULL );
                                    SendMessage( WM_TIMER, __EXT_EDIT_UPDATE_TIMER, 0L );
                              }
                        }
                  }
                  break;
            case WM_NCPAINT:
                  {
                        CWindowDC dc( this );
                        _DoPaintNC( &dc );
                        return 0L;
                  }
                  break;
            }
            return _BED::WindowProc(message, wParam, lParam);
      }
Common controls like buttons and combo boxes do not have non-client areas. As a result, the classes like CExtButton and code>CExtComboBox</code> completely repaint the common controls for theming them and do not affect their non-client areas.

Arjan Sep 11, 2009 - 7:07 AM

Thank you for your reply.

Eventhough I didn’t notice a change in the printing of a CExtEdit after inserting "_BED::WindowProc(message, wParam, lParam);" in the WindowProc function of the CExtEd template,.
I’m guessing it could possibly be a solution since when debugging, i did notice that this caused to draw the text, which then was removed by the painting done by stat_PrintClient.
Perhaps I used a wrong value for lParam ?

However, I was hoping for PrintClient to have the follow the same principle as CExtEditBase::OnPaint(), which it basically first lets Windows paint the edit-control, to then overdraw the text.

Thanks in advance,
Arjan Lukkesen
Ellips B.V.

Technical Support Sep 11, 2009 - 10:42 AM

Yes, we found that the previous solution works only in particular situations. We found a better solution. It consists of two steps. First, please update the following part of the CExtED::WindowProc() virtual method:

       case WM_PRINT:
            case WM_PRINTCLIENT:
                  {
                        _BED::WindowProc(message, wParam, (lParam&(~(PRF_NONCLIENT|PRF_CHECKVISIBLE))|PRF_CLIENT|PRF_ERASEBKGND) );
                        CDC * pDC = CDC::FromHandle( (HDC) wParam );
                        CExtEditBase::stat_PrintClient( OnQueryWindowEnabledState(), m_bMouseOver, message, lParam, this, this, pDC );
                        return (!0L);
                  }
                  break;

Second, please update the source code for the following method:
void CExtEditBase::stat_PrintClient(
      bool bEnabled,
      bool bMouseOver,
      UINT message,
      LPARAM lParam,
      CWnd * pWnd,
      CExtPmBridge * pPmBridge,
      CDC * pDC
      )
{
      ASSERT_VALID( pWnd );
      ASSERT( pWnd->GetSafeHwnd() != NULL );
      ASSERT( pPmBridge != NULL );
      ASSERT_VALID( pDC );
      ASSERT( pDC->GetSafeHdc() != NULL );
CRect rcWnd;
      pWnd->GetWindowRect( &rcWnd );
      rcWnd.OffsetRect( -rcWnd.TopLeft() );
CExtMemoryDC dc( pDC, &rcWnd, CExtMemoryDC::MDCOPT_TO_MEMORY|CExtMemoryDC::MDCOPT_FILL_BITS|CExtMemoryDC::MDCOPT_RTL_COMPATIBILITY );
      if( (lParam&PRF_NONCLIENT) != 0 )
            CExtEditBase::stat_DoPaintNc( bEnabled, bMouseOver, pWnd, pPmBridge, pDC );
      if( (lParam&PRF_CHILDREN) != 0 )
            CExtPaintManager::stat_PrintChildren( pWnd->m_hWnd, message, dc.GetSafeHdc(), lParam, false );
}

Additionally, we found similar issue in the CExtComboBox control. To fix it, please update the source code for the following method:
LRESULT CExtComboBox::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
      if( message == WM_PRINT || message == WM_PRINTCLIENT )
      {
            CExtComboBoxBase::WindowProc( message, wParam, lParam );
            CDC * pDC = CDC::FromHandle( (HDC)wParam );
            CRect rcClient;
            GetClientRect( &rcClient );
            CExtMemoryDC dc( pDC, &rcClient, CExtMemoryDC::MDCOPT_TO_MEMORY|CExtMemoryDC::MDCOPT_FILL_BITS|CExtMemoryDC::MDCOPT_RTL_COMPATIBILITY );
            DWORD dwStyle = GetStyle();
            if(         (dwStyle&CBS_SIMPLE) == CBS_SIMPLE 
                  &&    (dwStyle&CBS_DROPDOWN) != CBS_DROPDOWN
                  &&    (dwStyle&CBS_DROPDOWNLIST) != CBS_DROPDOWNLIST
                  )
            {
                  if(         (! PmBridge_GetPM()->GetCb2DbTransparentMode(this) )
                        ||    (! PmBridge_GetPM()->PaintDockerBkgnd( true, dc, this ) )
                        )
                        dc.FillSolidRect( &rcClient, PmBridge_GetPM()->GetColor( CExtPaintManager::CLR_3DFACE_OUT, this ) );
            }
            _OnDrawComboImpl( GetDroppedState() ? true : false, IsHovered(), &dc );
            if( (lParam&PRF_CHILDREN) != 0 )
                  CExtPaintManager::stat_PrintChildren( m_hWnd, message, dc.GetSafeHdc(), lParam, false );
            return (!0);
      }
      return CExtComboBoxBase::WindowProc( message, wParam, lParam );
}


Arjan Sep 17, 2009 - 2:24 AM

Thank you for reply, it works.


Sorry I wasn’t able to test it right away, but I just did, and it solves the problems we’ve encountered.


Also thank you for checking other controls, and fixing the ComboBox aswell.