Skip to main content

28 posts tagged with "MFC"

View All Tags

How to avoid Memory Leaks in C++, VC++"

· 4 min read

Contents

  1. Introduction
  2. How to find memory leak
  3. Memory Leak and how to avoid it

Updated on : 17-Oct-2014

1. Introduction

The failure to properly deallocate memory that was previously allocated is known as Memory Leak. The consequences of memory leaks is that the programs that leak large amounts of memory, or leak progressively, may display symptoms ranging from poor (and gradually decreasing) performance to running out of memory completely. Worse, a leaking program may use up so much memory that it causes another program to fail, leaving the user with no clue to where the problem truly lies. In addition, even harmless memory leaks may be symptomatic of other problems.

2. How to Find Memory Leak

Use third-party tools like DevPartner or use the following steps to find the memory leaks

  • Compile the project in "Debug" Mode.
  • Declare the objects CMemoryState msOld, msNew, msDif;
  • Check the memory state at one point. msOld.Checkpoint(); ://code ://code
  • Check the memory state at onother point. msNew.Checkpoint();
  • See for Difference msDif.Difference( msOld, msNew );
  • Display the Leaked blocks in Debug window  msDif.DumpStatistics();

3. Memory Leak and How to avoid it

a. Wrong usage of new/delete.

int* intArr; 
intArr = new int[500];
delete intArr;

Use  delete[]intArr; instead of delete intArr as delete intArr is equal to deleting intArr[0];

b. Improper deletion of Array of Pointers

introwNo = 3; 
intcolsNo = 3;
int *array = new int[rowNo];

for(inti=0; i < rowNo; i++) {
array[i] = new int[i+1];
}

delete[] array;

The cause of memory leak is that the 'array' is an array of pointers, with each of it's elements pointing to a separate memory block, so it is necessary free these blocks before freeing the array that holds the pointers.

for(int i=0; i < rowNo; i++) 
{
delete[] array[i];
}

delete [] array;

c. Resource Handles: GDI Objects- CBrush, CPen, CFont, CBitmap, CPallete, CRgn and respective handles

CBrush myBr, *pOldBr; 
myBr.CreateSolidBrush(RGB(0, 255, 0));
pOldBr = pDC->SelectObject(&myBr);
pDC->SelectObject(& myBr );
pDC->SelectObject(pOldBrush);

For more details Check:http://msdn.microsoft.com/en-us/library/windows/desktop/ms724291(v=vs.85).aspx

The DeleteObject method deletes the GDI object by freeing all system storage associated with it. The storage associated with the CGdiObject object is not affected by this call. An application should not call DeleteObject on a CGdiObject object that is currently selected into a device context. Use myBr.DeleteObject(); after finishing using myBr (Cbrush) object For handles pass handle of the DeleteObject function DeleteObject(hPen);

d. String conversions CString to LPTSTR

CString sName; 
sName= _T("Hello");
int lenName = sName.GetLength();
LPTSTR lpstrg = sName.GetBuffer(lenName);

sName.ReleaseBuffer();
Cstring to BSTR CString csStr = "Hello";
BSTR bStr = csStr.AllocSysString();

SysFreeString(bStr); //finished using the BSTR

Use ReleaseBuffer() when ever we create a buffer. Use SysFreeString() when ever we use AllocSysString() which allocates a new string of the type BSTR.

e. Improper deletion of pointer objects in a CList

CList<CMyData, CMyData> ptList;
CList<CMyData, CMyData> ptList;
ptList.RomoveAll(); //Improper deletion of pointer objects in a CArray CArray<CMyData, CMyData> ptArr;
ptArr.RemoveAll();

Proper deletion of pointer objects in a CList

CList<CMyData, CMyData> ptList;
POSITION pos = ptList.GetHeadPosition();

while(pos!=NULL) {
delete ptList.GetNext(pos);
}

PtList.RomoveAll();

// Proper deletion of pointer objects in a CArray CArray<CMyData_, CMyData_\> ptArr; : : int i = 0;

while(i<ptArr.GetSize()) {
delete ptArr.GetAt(i++);
}

ptArr.RemoveAll();

f. Opening and proper closing of file and databases

CFile file; 
file.Open(szFilePath, CFile::modeCreate | CFile::modeWrite, 0);
file.Write(chFile, chFileSize);
file.Close();

e. Usage of Static Arrays

int Sample[500]; 

Never use static arrays if the array is dynamically growing. Instead of using static arrays use CArray or OCArray Example:

 CArray<int, int> Sample; 

MFC: Enumerate all views of the document

· One min read

To Enumerate all views of the document the CDocument class provides GetFirstViewPosition and GetNextView member functions to enumerate all views associated with the document. We call view’s OnUpdate function to communicate with them.

void EnumerateViews()
{
//get the position of the first view in the list
//of views associated with the document.
POSITION pos = GetFirstViewPosition();

//terate through all of the document's views.
while (pos != NULL)
{
CView* pView = GetNextView(pos);

//update view
pView-&gt;OnUpdate(pSender, lHint, pHint);
}
}

Unit Testing Native C++ App with out clr

· One min read

Unit Testing Native C++ Applications with out “/clr” flag or fall back to 3rd party frameworks

Visual Studio 11 provides the ability to do Unit Testing Native C++ Applications with a new C++ unit testing framework shipping with VS 11.

So the C++ developers no longer need to use the “/clr” flag or fall back to 3rd party frameworks.

To learn more about native unit testing in Visual Studio 11, please visit MSDN.

How to Expand and Contract a MFC Dialog ?

· 3 min read

This article gives the ability to make MFC dialogs expand or contract. The CExpandContractHelper simplifies the process to  expand or contract MFC Dialog.

Steps to use CExpandContractHelper :

  1. Create Dialog Based application
  2. Place the controls as shown below
  3. Add the CExpandContractHelper.cpp & CExpandContractHelper.h files to the project
  4. Create the in the Dialog class CExpandContractHelper* m_pECH;
CExpandDialogDlg::CExpandDialogDlg(CWnd* pParent =NULL)
: CDialog(CExpandDialogDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
//Step - 1 Create CExpandContractHelper
m_pECH = new CExpandContractHelper(IDC_PIC_START, IDC_PIC_END, this);
}
  1. Call ExpandContract in the OnInitDialog
BOOL CExpandDialogDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
//Step - 2 Call ExpandContract
m_pECH->ExpandContract((CButton*)GetDlgItem(IDC_BN_EXPAND_CONTRACT));
return TRUE;
}
  1. Call ExpandContract in the button handler OnBnClickedBnExpandContract
void CExpandDialogDlg::OnBnClickedBnExpandContract()
{
//Step - 3 Call ExpandContract
m_pECH->ExpandContract((CButton*)GetDlgItem(IDC_BN_EXPAND_CONTRACT));
}

CExpandContractHelper class

//////////////////////////////////////////////////
// Purpose: To expand or contract a dialog control
//////////////////////////////////////////////////
class CExpandContractHelper
{
public:
CExpandContractHelper(UINT nStart, UINT nEnd, CDialog\* dlg);
~CExpandContractHelper(void);
protected:
// ID of start picture control
UINT m_nStart;
// ID of end picture control
UINT m_nEnd;
CDialog* m_dlg;
CButton* m_pButton;
CString m_sExpand;
CString m_sContract;
public:
void ExpandContract(CButton* pButton);
protected:
BOOL IsExpand();
};

CExpandContractHelper.cpp

#include "StdAfx.h"
#include "ExpandContractHelper.h"
CExpandContractHelper::~CExpandContractHelper(void)
{
}
CExpandContractHelper::CExpandContractHelper(
UINT nStart, // Start Picture control ID
UINT nEnd, // End Picture control ID
CDialog *dlg // Dialog pointer
)
{
m_nStart = nStart;
m_nEnd = nEnd;
m_dlg = dlg;
}
BOOL CExpandContractHelper::IsExpand()
{
// 1 - Load button caption Expand/Contact
m_sExpand = "&amp;Expand >>";
m_sContract = "&lt;&lt; &amp;Contract";
// 2 - Find out if we need to expand or collapse the dialog
CString strCaption;
m_pButton->GetWindowText( strCaption );
BOOL bExpand = ( strCaption == m_sExpand ); // Collapse by default
return bExpand;
}
void CExpandContractHelper::ExpandContract(
CButton* pButton // Expand Contract button pointer
)
{
m_pButton = pButton;
// 3 - Get current dialog window rectangle
CRect rcDialog;
m_dlg->GetWindowRect( &amp;rcDialog );
int nNewHeight = -1;
if( IsExpand() )
{
// 4a - Change Expand/Contract button caption
pButton->SetWindowText( m_sContract );
// 4b - Calculate new dialog height
CWnd* pWndLarge = m_dlg->GetDlgItem( m_nEnd );
ASSERT_VALID( pWndLarge );
CRect rcLarge;
pWndLarge->GetWindowRect( &amp;rcLarge );
nNewHeight = rcLarge.top-rcDialog.top;
}
else
{
// 5a - Change Expand/Contract button caption
pButton->SetWindowText( m_sExpand );
// 5b - Calculate new dialog height
CWnd* pWndSmall = m_dlg->GetDlgItem( m_nStart );
ASSERT_VALID( pWndSmall );
pWndSmall->ShowWindow(FALSE);
CRect rcSmall;
pWndSmall->GetWindowRect( &amp;rcSmall );
nNewHeight = rcSmall.top-rcDialog.top;
}
// 6 - Set new dialog height
ASSERT( nNewHeight > 0 );
m_dlg->SetWindowPos( NULL, 0, 0,
rcDialog.Width(), nNewHeight,
SWP_NOMOVE | SWP_NOZORDER );
// 7 - Set the enabled state for each control depending on whether
// the control is currently visible or not
CWnd* pWndControl = m_dlg->GetWindow( GW_CHILD );
while( pWndControl != NULL )
{
CRect rcControl;
pWndControl->GetWindowRect( &amp;rcControl );
pWndControl->EnableWindow( rcControl.top &lt;= rcDialog.top + nNewHeight );
pWndControl = pWndControl->GetWindow( GW_HWNDNEXT );
}
// 8 - Check if a control still has the focus
// (can lose it if the active control becomes disabled)
CWnd* pWndActiveControl = CWnd::GetFocus();
if( pWndActiveControl == NULL )
{
// 9 - Set focus to "first" control on dialog
CWnd* pWndFirstControl = m_dlg->GetNextDlgTabItem( NULL );
ASSERT_VALID( pWndFirstControl );
ASSERT( pWndFirstControl->IsWindowEnabled() );
pWndFirstControl->SetFocus();
}
}

Tutorial to create MFC ActiveX Control which can be used in HTML Pages

· One min read

Definition: ActiveX controls are COM components which are self-registering and Implements standard interfaces that deal specifically with GUI-based tasks such as rendering, sizing, activation, and property persistence.

An ActiveX control is anything you might see in the Toolbox of Visual studio (i.e. EditBox, combobox e.t.c) we can even use the Activex controls in web pages using and handling events with Javascript.

For complete tutorial Refer ActiveX Control Tutorial

Invoke Native C++ DLL from .NET Code

· One min read

There are 4 Approaches to accomplish this.

Approach

  1. (Explicit) P/Invoke Approach  
  2. Dynamic P/Invoke Approach
  3. Implicit P/Invoke (Use a C++/CLI wrapper) Approach
  4. Convert C++ DLL to a COM server, and call it from .NET code through .NET-COM interop

I don't like to reinvent the wheel so please go through msdn forum answer here

Center an MFC Dialog

· One min read

Use the CWnd::CenterWindow method to center the dialog. Write CenterWindow() method in the OnInitDialog() method.

BOOL CMyDialog::OnInitDialog() { 
CenterWindow();
return TRUE;
}

Creating a CDC from a HDC

· One min read

If we get handle to a DC and sometimes we might want to create a CDC from that. One example is owner-drawn lists, combos, and buttons. we will receive a draw item message with a hDC. The below code can be used to convert hdc into CDC.

 void MyList::DrawItem(LPDRAWITEMSTRUCT lpDrawItem) { 
CDC* pDC;
pDC = CDC:FromHandle(lpDrawItem->hDC);
}

NOTE: This technique for any of the other MFC class/ Windows handle pairs too.

How do I maximize my MDI child ?

· One min read

In CMainFrame class ad the following code.

void CMainFrame::ActivateFrame(int nCmdShow)
{
if (!m_bActivated)
{
m_bActivated = TRUE;
nCmdShow = SW_SHOWMAXIMIZED;
}

CFrameWnd::ActivateFrame(nCmdShow);
}

where m_bActivated is a member variable of your frame object.