Click here to Skip to main content
11,582,850 members (71,270 online)
Click here to Skip to main content

A Customized Window for MFC Applications

, 1 Dec 2008 CPOL 67.8K 4.5K 69
Rate this:
Please Sign up or sign in to vote.
This article is to basically explain how to create a customized drawn window for MFC applications.

Introduction

This article came as a result of trying to create a custom border for the MFC application. The simplest way to customize the window of an application is to bind it to a specific theme that gives it the look and feel we want. But sometimes we can't get the specific design we want and more importantly, the shape we want. So that gave the idea of removing the existing borders and title bars and making the window handle the basic actions which the borders and title bar can.

So when we remove the title bar and the border from the window, we have to handle some basic actions which they perform. Those are:

  1. Moving the window
  2. Resizing the window
  3. Close, Restore and Minimize

The Code

First we can remove the title bar and clip the region for the window:

BOOL CCustomFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
	CRect rect;
	GetClientRect(rect);
	//Create the custom region for the window
	m_CustomRgn.CreateRoundRectRgn(rect.left + winStats.frm_clp_wdth,
		rect.top + winStats.frm_clp_wdth,
		rect.right - winStats.frm_clp_wdth,
		rect.bottom - winStats.frm_clp_wdth,
		20, 20);
		//Set the window region
        VERIFY(SetWindowRgn(m_CustomRgn , TRUE ));
	return CFrameWnd::OnCreateClient(lpcs, pContext);
}
BOOL CCustomFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle , 
			CWnd* pParentWnd , CCreateContext* pContext)
{
	BOOL bRet = CFrameWnd::LoadFrame
		(nIDResource, dwDefaultStyle, pParentWnd, pContext);
	if(bRet)
	{
	    //Remove the titlebar from the frame using the ModifyStyle
		ModifyStyle(WS_CAPTION, WS_CLIPCHILDREN);
	    //Remove the border
		ModifyStyleEx(WS_EX_CLIENTEDGE,0);
	}
	return true;
}

As above, we can override the functions OnCreateClient and LoadFrame to modify the window.

Next since we remove the borders and title bar, we can use the basic events to capture the actions which now the borderless window cannot. For this, we can use...

afx_msg void OnLButtonDown(UINT nFlags, CPoint point) 

... and capture the default message processing. Based on the region clicked, we can let the window process different messages which will perform the tasks. To process the messages, DefWindowProc can be used.

if (r_windRects.r_Move.PtInRect(point)){
		DefWindowProc(WM_SYSCOMMAND, 
				SC_MOVE + 1 ,MAKELPARAM(point.x,point.y));
		return 0;
	}
	if (Val == -1)
		return 0;

	::SetCursor(AfxGetApp()->LoadStandardCursor(cursor));
	//Send the resize messages
	DefWindowProc(WM_SYSCOMMAND, SC_SIZE + Val ,MAKELPARAM(point.x ,point.y));
	return 0;

With this part of the code, resizing and moving operations are handled. Since it processes the resizing, now we can resize the window and clip it so that we can keep the basic shape we want.

void CCustomFrame::OnSize(UINT nType, int cx, int cy)
{
	CRect rect;
	GetClientRect(rect);
         //Detach the previous region
	m_CustomRgn.Detach();
	//Create and set the new region for the window!
	m_CustomRgn.CreateRoundRectRgn(rect.left + winStats.frm_clp_wdth,
		rect.top + winStats.frm_clp_wdth
		, rect.right- winStats.frm_clp_wdth,
		rect.bottom - winStats.frm_clp_wdth, 30, 30);

	SetWindowRgn(m_CustomRgn, TRUE);
	CFrameWnd::OnSize(nType, cx, cy);
}

Another thing to handle is the maximization and restoration of the frame. We can't use ShowWindow(SW_SHOWMAXIMIZED) since we already clipped some of the area from the window. So the below code is used for that:

int CCustomFrame::maximize(void)
{
	//The custom maximize function. 
	//This is needed since we clipped the frame and the border.
	CRect rect,rectD, rect1;
	GetClientRect(rect);
	GetWindowRect(m_PrevRect);
	//Get the screen size!
	int scrWidth  = GetSystemMetrics(SM_CXSCREEN);
	int scrHeight = GetSystemMetrics(SM_CYSCREEN);

	rect.right = scrWidth + winStats.frm_clp_wdth;
	rect.bottom = scrHeight + winStats.frm_clp_wdth;
	rect.left -= winStats.frm_clp_wdth;
	rect.top -= winStats.frm_clp_wdth;
	//Get the taskbar rect and set the bottom to taskbar rect top parameter
	CWnd* pTray = FindWindow(_T("Shell_TrayWnd"), _T(""));
	pTray->GetWindowRect(&rectD);
	rect.bottom = rectD.top + winStats.frm_clp_wdth;
	MoveWindow(rect);
	b_maximized = TRUE;
	return 0;
}

Points of Interest

The good part of doing this is that by handling some basic window actions and events, we can create the borders as we like. Since we paint the borders, they won't change prior to the Windows platform it runs (e.g.: XP or Vista). We can also use the CDialog class instead of CFrameWnd to create the custom window.

But the bad point is handling processing of many messages. Moreover, there can be small defects in drawing things like flickering. So this code might not have a commercial value, but it can be a good learning material!

History

  • 30th November, 2008: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

PrasadPerera
Student
Canada Canada
Prasad Perera is a software developer who's interested in parallel and distributed computing and graphics programming!

Currently he is following his masters in Concordia University, Montreal.

You may also be interested in...

Comments and Discussions

 
GeneralExcellent effort ! Pin
Pravinda Ama.18-Oct-13 18:08
professionalPravinda Ama.18-Oct-13 18:08 
QuestionI Need to increase the width and height both are evenly. can you help me ? Pin
balaji16730-Sep-13 22:49
memberbalaji16730-Sep-13 22:49 
QuestionVery useful, bug free code. Thanks for sharing. 5/5. Pin
Member 143041122-Oct-12 22:28
memberMember 143041122-Oct-12 22:28 
Questionhere you're creating customised window but I want to know how to customise window which is already created ? Pin
chaiein15-Feb-12 19:34
memberchaiein15-Feb-12 19:34 
Questionplease help me how to customise window which is already created? Pin
chaiein15-Feb-12 19:32
memberchaiein15-Feb-12 19:32 
GeneralMy Vote of +5 Pin
Laxmikant_Yadav18-Oct-11 2:06
memberLaxmikant_Yadav18-Oct-11 2:06 
GeneralMy vote of 5 Pin
Homero De la Garza7-Sep-11 3:58
memberHomero De la Garza7-Sep-11 3:58 
GeneralRe: My vote of 5 Pin
PrasadPerera7-Sep-11 6:05
memberPrasadPerera7-Sep-11 6:05 
GeneralSample with an SDI App Pin
JRCooper18-Jun-10 13:40
memberJRCooper18-Jun-10 13:40 
GeneralRe: Sample with an SDI App Pin
PrasadPerera19-Jun-10 9:47
memberPrasadPerera19-Jun-10 9:47 
GeneralI like it very much Pin
dotcpp17-Dec-09 16:53
memberdotcpp17-Dec-09 16:53 
Questionhow to fit an application from winexec in rightpane of splitter window Pin
Member 333413525-Oct-09 22:48
memberMember 333413525-Oct-09 22:48 
GeneralSplitting Window Pin
samal.subhashree29-Sep-09 20:29
membersamal.subhashree29-Sep-09 20:29 
GeneralRe: Splitting Window Pin
PrasadPerera30-Sep-09 3:26
memberPrasadPerera30-Sep-09 3:26 
GeneralMDI Main Frame [modified] Pin
tpchen13-Apr-09 22:54
membertpchen13-Apr-09 22:54 
GeneralRe: MDI Main Frame Pin
PrasadSRCSE16-Apr-09 16:34
memberPrasadSRCSE16-Apr-09 16:34 
GeneralRe: MDI Main Frame Pin
amacg12319-Aug-10 8:25
memberamacg12319-Aug-10 8:25 
GeneralMy vote of 1 Pin
maheshvarma0926-Mar-09 5:50
membermaheshvarma0926-Mar-09 5:50 
GeneralRe: My vote of 1 Pin
PrasadSRCSE26-Mar-09 17:21
memberPrasadSRCSE26-Mar-09 17:21 
QuestionI like the look Pin
roni_rgk9-Feb-09 21:36
memberroni_rgk9-Feb-09 21:36 
AnswerRe: I like the look Pin
PrasadSRCSE11-Feb-09 13:30
memberPrasadSRCSE11-Feb-09 13:30 
GeneralLearning material Pin
AlexEvans15-Dec-08 13:57
memberAlexEvans15-Dec-08 13:57 
GeneralRe: Learning material Pin
PrasadSRCSE15-Dec-08 23:26
memberPrasadSRCSE15-Dec-08 23:26 
GeneralRe: Learning material Pin
AlexEvans16-Dec-08 10:34
memberAlexEvans16-Dec-08 10:34 
GeneralMy vote of 1 Pin
Member 28695518-Dec-08 11:45
memberMember 28695518-Dec-08 11:45 
GeneralRe: My vote of 1 Pin
PrasadSRCSE8-Dec-08 17:16
memberPrasadSRCSE8-Dec-08 17:16 
GeneralMy vote of 1 Pin
Andre xxxxxxx3-Dec-08 1:43
memberAndre xxxxxxx3-Dec-08 1:43 
GeneralRe: My vote of 1 Pin
PrasadSRCSE3-Dec-08 16:22
memberPrasadSRCSE3-Dec-08 16:22 
GeneralUpdated demo! Pin
PrasadSRCSE2-Dec-08 13:34
memberPrasadSRCSE2-Dec-08 13:34 
Questionvery bad Pin
Member 21467681-Dec-08 22:46
memberMember 21467681-Dec-08 22:46 
AnswerRe: very bad Pin
PrasadSRCSE2-Dec-08 0:44
memberPrasadSRCSE2-Dec-08 0:44 
Frown | :( sorry ! I'll update the project ASAP!, its only need to do is setting relative paths for these icons!

PrasadSR

GeneralMy vote of 1 Pin
Kfeeder1-Dec-08 22:16
memberKfeeder1-Dec-08 22:16 
GeneralRe: My vote of 1 Pin
PrasadSRCSE2-Dec-08 0:45
memberPrasadSRCSE2-Dec-08 0:45 
GeneralRe: My vote of 1 Pin
eleqi2-Dec-08 3:42
membereleqi2-Dec-08 3:42 
GeneralRe: My vote of 1 Pin
PrasadSRCSE2-Dec-08 4:33
memberPrasadSRCSE2-Dec-08 4:33 
Generalresource error. Pin
Member #41163381-Dec-08 14:37
memberMember #41163381-Dec-08 14:37 
GeneralRe: resource error. Pin
PrasadSRCSE1-Dec-08 17:21
memberPrasadSRCSE1-Dec-08 17:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150603.1 | Last Updated 1 Dec 2008
Article Copyright 2008 by PrasadPerera
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid