Skip to main content

28 posts tagged with "MFC"

View All Tags

Programmatically terminate MFC application

· One min read

MFC does not provide a public function to exit an application. The following method shutdowns the Application. The method simply sends a WM_CLOSE message to application's mainframe window.

void CmfcApp::ExitApplication()
{
if(AfxGetApp()->m_pMainWnd != NULL))
{
AfxGetApp()->m_pMainWnd->SendMessage(WM_CLOSE);
}
}

Limiting the maximum and minimum sizing of a Frame Window

· One min read

To limit the maximum and minimum size of a Frame Window.

  1. Define Min and Mix size in pixels

  2. Handle the WM_GETMINMAXINFO message in a CFrameWnd derived class.  The MINMAXINFO struct sets limits on the entire window, we need to take into account scroll bars, toolbars,  etc

 // Min and Mix size in pixels
# define MINX 500
# define MINY 300
# define MAXX 600
# define MAXY 400

void CMainFrame::OnGetMinMaxInfo(MINMAXINFO* lpMMI) {
CRect rectWnd; CRect rectClient;
GetWindowRect(&rectWnd);
GetClientRect(&rectClient);

// get offset of toolbars, scrollbars, etc.
int nWidthOffset = rectWnd.Width() - rectClient.Width();
int nHeightOffset = rectWnd.Height() - rectClient.Height();

lpMMI->ptMinTrackSize.x = MINX + nWidthOffset;
lpMMI->ptMinTrackSize.y = MINY + nHeightOffset;
lpMMI->ptMaxTrackSize.x = MAXX + nWidthOffset;
lpMMI->ptMaxTrackSize.y = MAXY + nHeightOffset;

CFrameWnd::OnGetMinMaxInfo(lpMMI);

}

Centering an Application Frame Window to desktop

· One min read

To center Application's Frame Window call CenterWindow() in MainFrame's OnCreate() function.

See the code snippet below

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;

//////////////////////////////////////////////////////////
// Center Application Frame Window //
/////////////////////////////////////////////////////////
CWnd* pWnd = GetDesktopWindow();
CenterWindow(pWnd);
//////////////////////////////////////////////////////////

return 0;
}

How to create a minimal MFC Window ?

· One min read

We need at least two classes derived to construct an window

  1. Window class / Frame class (CMainFrame) which is derived from CFrameWnd
  2. Application class (CMyApp) which is derived from CWinApp
#include <afxwin.h>;

class CMainFrame : public CFrameWnd
{
public:
CMainFrame()
{
Create(NULL, "HELLO MFC");
}
protected:
afx_msg void OnPaint()
{
CPaintDC dc(this);
dc.TextOut(100, 100, "This is the my MFC window");
}

afx_msg void OnLButtonDown(UINT nFlags, CPoint point)
{
AfxMessageBox("Mouse OnLButtonDown !!");
CFrameWnd::OnLButtonDown(nFlags, point);
}
// Declare the Message Map
DECLARE_MESSAGE_MAP()
};

// Define the Message Map out side the class Definition
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_PAINT() // Paint Message
ON_WM_LBUTTONDOWN() // Mouse LButton down message
END_MESSAGE_MAP()

class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance()
{
m_pMainWnd = new CMainFrame();
m_pMainWnd-&gt;ShowWindow(SW_SHOWNORMAL);
m_pMainWnd-&gt;UpdateWindow();
return TRUE;
}
};

// The one and only Application Object
CMyApp theApp;

Remove MAXIMIZE BOX and MINIMIZE BOX from an MFC Window

· One min read

In order to remove MAXIMIZE BOX and MINIMIZE BOX from an MFC Window see the below code snippet.

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT&amp; cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;

cs.dwExStyle &amp;= ~WS\_EX\_CLIENTEDGE;
cs.lpszClass = AfxRegisterWndClass(0);

//////////////////////////////////////////////////////////
// To remove MAXIMIZE BOX from window //
//////////////////////////////////////////////////////////
cs.style &amp;= ~WS\_MAXIMIZEBOX;

//////////////////////////////////////////////////////////
// To remove MINIMIZE BOX from window //
//////////////////////////////////////////////////////////
cs.style &amp;= ~WS\_MINIMIZEBOX;

return TRUE;
}

Making first MDI child window start out maximized

· One min read

To make first MDI child window start out maximized

  1. Add a ActivateFrame() which is a CChildFrame virtual function
  2. Modify the function with the below code snippet
void CChildFrame::ActivateFrame(int nCmdShow) { 
////////////////////////////////////////////////////////////////////////////
// To make first MDI child window start out maximized
// ////////////////////////////////////////////////////////////////////////////
m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);

// if another window is open, use default
if(GetMDIFrame()->MDIGetActive()) {
CMDIChildWnd::ActivateFrame(nCmdShow);
} else // else open the child window maximized.
{
CMDIChildWnd::ActivateFrame(SW_SHOWMAXIMIZED);
}

//////////////////////////////////////////////////////////////////////////// }

Creating an SDI/MDI application that is initially maximized

· One min read

To Creating an SDI/MDI application that is initially maximized Pass SW_SHOWMAXIMIZED as paramater to m_pMainWnd->ShowWindow() in the  in the CWinApp::InitInstance()

Code Snippet:

BOOL CWindowTitleApp::InitInstance() { 
////////////////////////////////////////////////////////////////////////////
// To Create an SDI/MDI application that is initially maximized
// /////////////////////////////////////////////////////////////////////////

m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);
m_pMainWnd->UpdateWindow();
m_pMainWnd->DragAcceptFiles();

return TRUE;
}

Change a Window's title of an SDI/MDI Application

· One min read

Call SetWindowText method by passing required title as a string in the CWinApp::InitInstance() method after ProcessShellCommand() method. Please see the below code snippet

m_pMainWnd->SetWindowText("My New Window Title");

BOOL CWindowTitleApp::InitInstance()
{
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&amp;InitCtrls);

CWinApp::InitInstance();
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(4);

CSingleDocTemplate\* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CWindowTitleDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CWindowTitleView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);

EnableShellOpen();
RegisterShellFileTypes(TRUE);

CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);

if (!ProcessShellCommand(cmdInfo))
return FALSE;
////////////////////////////////////////////////////////////////////////////
// To Change Window Title //
////////////////////////////////////////////////////////////////////////////
m_pMainWnd-&gt;SetWindowText("My New Window Title");
////////////////////////////////////////////////////////////////////////////

m_pMainWnd-&gt;ShowWindow(SW_SHOW);
m_pMainWnd-&gt;UpdateWindow();
m_pMainWnd-&gt;DragAcceptFiles();

return TRUE;
}

How do remove 'Untitled' in main window caption

· One min read

To remove 'Untitled' in main window caption

  1. Override the PreCreateWindow() function in CMainFrame class
  2. Modify the CREATESTRUCT style by adding the below code cs.style &= ~FWS_ADDTOTITLE ;

Code snippet:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT&amp; cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;

////////////////////////////////////////////////////////////////////////////
// To remove 'Untitled' in main window caption //
////////////////////////////////////////////////////////////////////////////
cs.style &amp;= ~FWS\_ADDTOTITLE ;
////////////////////////////////////////////////////////////////////////////

return TRUE;
}

Message Map vs Virtual Functions

· One min read

Message Map is a logical table that maps the windows messages to the member functions of the class. Message map is preferred than virtual functions due  to avoid following drawbacks:

  1. Most windows only process a small number of messages, yet each window require to giant virtual function table with the entries of each message.

  2. More efficient and use less space then virtual functions.

  3. Virtual functions don't handle user defined messages and other custom cases.