Archive

Posts Tagged ‘CDialog’

A round dialog box!

July 2, 2008 6 comments

Ever wondered how those cute little round dialog boxes are created. I too wondered for some time. But let me tell you it is easy, take a look:

Do this from OnInitDialog!

//Create a region object globally.
CRgn m_EllipticRegion;

//a rect object
CRect crDialogRect;

//get your dialog size
this->GetClientRect(crDialogRect);

//Now create the elliptic region from the client rect
m_EllipticRegion.CreateEllipticRgn(0/*x*/,
0/*y*/,
crDialogRect.Width()/*width*/,
crDialogRect.Height() /*Height*/
);

//create a round dialog
this->SetWindowRgn(m_EllipticRegion, TRUE);

See I told you it’s easy 🙂

What happens before and after OnInitDialog!

Two functions to look up would be…

  • _AfxPreInitDialog
  • _AfxPostInitDialog

As the name suggests _AfxPreInitDialog gets called before OnInitDialog is called and _AfxPostInitDialog gets called after OnInitDialog.

One of the things that happens in _AfxPostInitDialog is centering of a dialog if user hasn’t changed position of the dialog in OnInitDialog, so how is this done? _AfxPreInitDialog stores co-ordinates of the dialog before OnInitDialog was called and if these co-ordinates hasn’t changed then _AfxPostInitDialog calls CenterWindow MFC function.

All of this is taking place in AfxCallWndProc! WM_INITDIALOG is handled as a special case. Also HandleInitDialog function calls PreInitDialog and OnInitDialog functions!

So have fun looking up these functions!

How to make tab control pages transparent while using XP themes?

January 23, 2008 Leave a comment

Having trouble with tab control pages’  gray background while using XP themes? Well to solve this problem we need to do some additional housekeeping(AFAIK)…

Add a message map entry for WM_CTLCOLOR

BEGIN_MESSAGE_MAP(CTabPage, CDialog)
     ON_WM_CTLCOLOR()
END_MESSAGE_MAP()

Override OnCtlColor and add following code…

HBRUSH CTabPage::OnCtlColor( CDC* pDC_i, CWnd* pWnd_i, UINT uCntrlType_i )
{ 

   // First do default always
   HBRUSH hBrTemp = CDialog::OnCtlColor( pDC_i, pWnd_i, uCntrlType_i ); 

   // If we have a static control or a dialog control we should return our brush
   // with the DC having a transparent background
   switch( uCntrlType_i )
   {
      case CTLCOLOR_STATIC:
      case CTLCOLOR_DLG:
          pDC_i->SetBkMode( TRANSPARENT ); // Transparent mode
          hBrTemp = GetSysColorBrush( IsAppThemed() ? COLOR_WINDOW : COLOR_BTNFACE ); // Our brush
   } 

   // Return brush to caller
   return hBrTemp;
}

Note that we don’t need to delete the created brush since we are using a system cached brush. Also it’s good that you create a custom class(something like CTabPage, make this new class derive from CDialog.) and add this code there and then derive all your tab pages from this class instead of CDialog.

Creating a dialog from it’s template!

Here is a sample on how to do it…

CDialogTemplate dlgTemplate;
// Load dialog template into memory
dlgTemplate.Load( MAKEINTRESOURCE( IDD_DIALOG_ID ));
// Change font of dialog
dlgTempl.SetFont( _T( "Courier" ), 10 ); 

// Creates and displays a modal dialog from a template in memory
CDialog dlg;
dlg.InitModalIndirect( dlgTemplate.m_hTemplate, 0 );
dlg.DoModal();

What’s the use of this? Well you can change the font of dialog at runtime? Just call dlgTemplate.SetFont. This changes the font of entire dialog. Cool isn’t it!

To use CDialogTemplate include “afxpriv.h”. Microsoft(R) says that this file could be changed in near future, so use with care.

%d bloggers like this: