Jul 022008
 

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 ūüôā

May 072008
 

Introduction

OnInitDialog is a special function earmarked for dialog UI related sub components to initialize. A good place to sub-class or to set properties on controls, to position controls, to set text on controls etc. Default code in OnInitDialog makes changes to system menu and to set icons.

Functions called before and after OnInitDialog

Two functions to look up would be…

  • _AfxPreInitDialog
  • _AfxPostInitDialog

As the name suggests:

  • _AfxPreInitDialog gets called before OnInitDialog is called.
  • _AfxPostInitDialog gets called after OnInitDialog is called.

What happens in _AfxPreInitDialog and _AfxPostInitDialog?

_AfxPostInitDialog¬†centers 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!

Jan 232008
 

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.

Jun 282007
 

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.