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 » vista Collapse All
Subject Author Date
Pawel Kalinowski Sep 17, 2008 - 7:07 AM
Hans Bergmeister Oct 5, 2008 - 7:13 AM

Hello,


we have created ProfUIS-based skinned messages boxes by using another codeguru article. These message boxes worked well on XP, but the buttons disappeared on Vista, too. We found out, that simply removing the BS_OWNERDRAW style from the buttons after subclassing them to CExtButton objects did the job. This simple change caused CExtButton::OnPaint() to be called and skinned buttons became visible in our message boxes as desired. Perhaps this helps here,too.


Regards,


Juergen


 


 


 

Pawel Kalinowski Sep 18, 2008 - 6:03 AM

Can we expect you add your own skinned vista compatible message boxes in the next library release?

Technical Support Sep 18, 2008 - 12:12 PM

Here is the article dedicated to a very interesting implementation of the message box:
http://www.codeproject.com/KB/dialog/xmessagebox.aspx

And here is the modified version of the project from the article above but based on skinned with Prof-UIS windows:
http://www.prof-uis.com/download/forums/MsgBoxTest.zip

It is unlikely that the next version will be released with this feature but we plan to add this later.

Technical Support Sep 17, 2008 - 10:52 AM

We are sorry for the delay with this reply. We performed several tests under Windows Vista and it looks like it handles message boxes in some special way. First of all, we performed delayed subclassing:

int CApp::DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt) 
{
class CMyMsgBox : public CExtNCW < CExtResizableDialog >
{
protected:
      virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
      {
            LRESULT lResult = CExtNCW < CExtResizableDialog > :: WindowProc( message, wParam, lParam );
            switch( message )
            {
            case WM_INITDIALOG:
                  PostMessage( (WM_USER+666) );
            break;
            case (WM_USER+666):
                  ModifyStyle( 0, WS_CLIPCHILDREN|WS_CLIPSIBLINGS, SWP_FRAMECHANGED );
                  if( NcFrameImpl_IsSupported() )
                        NcFrameImpl_SetupRgn();
                  ::SubclassChildControls( this );
            break;
            }
            return lResult;
      }
};
CMyMsgBox dlg;
      AfxHookWindowCreate( &dlg );
      return CWinApp::DoMessageBox( lpszPrompt, nType, nIDPrompt );
}<pre>But the result was also the same. We also tried to save location of visible buttons and then re-create the same buttons on the saved locations, but the result still was the same. Windows Vista does magic things with buttons created inside the message box window. Finally, we tried to re-create the buttons inside container windows created as children of the message box window:<pre>int CApp::DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt) 
{
class CMyMsgBox : public CExtNCW < CExtResizableDialog >
{
      class CDynamicButton : public CExtButton
      {
      protected:
            virtual void PostNcDestroy()
            {
                  delete this;
            }
      };
      class CDynamicContainerWnd : public CWnd
      {
      protected:
            virtual void PostNcDestroy()
            {
                  delete this;
            }
      };
protected:
      virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
      {
            LRESULT lResult = CExtNCW < CExtResizableDialog > :: WindowProc( message, wParam, lParam );
            switch( message )
            {
            case WM_INITDIALOG:
                  PostMessage( (WM_USER+666) );
            break;
            case (WM_USER+666):
                  {
                        ModifyStyle( 0, WS_CLIPCHILDREN|WS_CLIPSIBLINGS, SWP_FRAMECHANGED );
                        if( NcFrameImpl_IsSupported() )
                              NcFrameImpl_SetupRgn();
                        static const TCHAR szButton[]       = _T("BUTTON");  
                        CList < HWND, HWND > _listFoundButtons;
                        CList < CRect, CRect > _listFoundRects;
                        CList < __EXT_MFC_LONG_PTR, __EXT_MFC_LONG_PTR > _listFoundStyles;
                        HWND hWnd = ::GetWindow( m_hWnd, GW_CHILD );
                        for( ; hWnd != NULL; hWnd = ::GetWindow( hWnd, GW_HWNDNEXT ) )
                        {
                              TCHAR szCompare[512] = _T("");
                              ::GetClassName(
                                    hWnd,
                                    szCompare,
                                    sizeof( szCompare )/sizeof( szCompare[0] )
                                    );
                              if( _tcsicmp( szCompare, szButton ) == 0 )
                              {
                                    __EXT_MFC_LONG_PTR dwWndStyle = ::__EXT_MFC_GetWindowLong( hWnd, GWL_STYLE );
                                    if( ( dwWndStyle & WS_VISIBLE ) != 0 )
                                    {
                                          _listFoundButtons.AddTail( hWnd );
                                          _listFoundStyles.AddTail( dwWndStyle );
                                          CRect rc;
                                          ::GetWindowRect( hWnd, &rc );
                                          ScreenToClient( &rc );
                                          _listFoundRects.AddTail( rc );
                                    }
                              }
                        }
                        ::SubclassChildControls( this );
                        POSITION pos = _listFoundButtons.GetHeadPosition();
                        POSITION pos2 = _listFoundRects.GetHeadPosition();
                        POSITION pos3 = _listFoundStyles.GetHeadPosition();
                        for( ; pos != NULL ; )
                        {
                              hWnd = _listFoundButtons.GetNext( pos );
                              ASSERT( pos2 != NULL );
                              CRect rc = _listFoundRects.GetNext( pos2 );
                              ASSERT( pos3 != NULL );
                              __EXT_MFC_LONG_PTR dwWndStyle = _listFoundStyles.GetNext( pos3 );
                              CWnd * pWnd = CWnd::FromHandle( hWnd );
                              bool bFocus = ( GetFocus() == pWnd ) ? true : false;
                              CString s;
                              pWnd->GetWindowText( s );
                              ::ShowWindow( hWnd, SW_HIDE );
                              int nID = pWnd->GetDlgCtrlID();

                              CDynamicContainerWnd * pWDC = new CDynamicContainerWnd;
                              VERIFY(
                                    pWDC->Create(
                                          ::AfxRegisterWndClass( CS_HREDRAW|CS_HREDRAW|CS_DBLCLKS),
                                          LPCTSTR(s),
                                          WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_TABSTOP,
                                          rc,
                                          this,
                                          nID
                                          )
                                    );
                              pWDC->SetWindowPos( pWnd, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );

                              CButton * pButton = new CDynamicButton;
                              VERIFY(
                                    pButton->Create(
                                          LPCTSTR(s),
                                          dwWndStyle,
                                          CRect(0,0,rc.Width(),rc.Height()), // rc,
                                          pWDC, //this,
                                          nID
                                          )
                                    );
                              if( bFocus )
                                    pWDC->SetFocus();
                        }
                  }
            break;
            }
            return lResult;
      }
};
CMyMsgBox dlg;
      AfxHookWindowCreate( &dlg );
      return CWinApp::DoMessageBox( lpszPrompt, nType, nIDPrompt );
}
The same result again. There is a black hole in Vista’s message boxes. Button controls disappear even if they are created as deep children of the message box window. We decided to give up at this point. Even if we found some way to keep buttons visible and working, there would not be guarantee that a new magic will appear in the next Windows versions. It’s easier to re-code our own message box from scratch or use the standard ones.