Sunday, February 28, 2010

Variable Passing

Too often we tend to take the easy way out and pass a new instance of a variable or pass unprotected pointers that could be const.

For example lets take the instance of passing a CString object, [a string wrapper for MFC].

so if we call void Foo(CString bar) when we could have used void Foo(const CString& bar) what's the difference you might ask? Well a couple of things, when passing a new instance of a variable, you now have to add a runtime allocation and deallocation of the memory used by the new local object. Also the memory of the source object must be copied over. You may also be introducing a call to a copy constructor which could cause even more repeated work.

What I consider even worst is defining a function with a non-const pointer which should be const. Who knows what the function may or may not do to your pointer but also, you may end up breaking other designs by forcing the passing of an unprotected buffer. One of the best examples I see of this is when char* is passed instead of const char*. If you have any smart objects like a CString they will automatically cast to const char but will force the user to make explicit calls to return an unprotected buffer, which in turns should make the user think twice [which is a pretty good design move in my opinion]

In Summary:
Always start with const& and const* for your input variables and only use something different when needed.

Tuesday, February 9, 2010

Class Commenting for Doxygen

This is how our company comments our header files.

We include our copyright notice on the top of each file with the provided filename.

/******************************************
/ Filename: Foo.h
/ Copyright 2010, Pathfinder Therapeutics, Inc.
/******************************************/

My VA snippet is:

/*****************************************
/ Filename: $FILE_BASE$.$FILE_EXT$
/ Copyright $YEAR$, Pathfinder Therapeutics, Inc.
/*****************************************/

In order for the Doxygen ouput to work, we have to place the class comment immediately before the start of class. Here we include any information a user needs to know to use the class correctly. An example is:

/**
* Generates data to use.
*
* Long description goes here
*
* MAIN PROCEDURE:
* 1. ...
*
* \author Bob
* \date 2010/02/08
* \version 1.0
*/
class Foo
{
...
};

My VA snippet for this is:

/**
* ShortDescr
*
* \author [YOUR NAME HERE]
* \date $DATE$
* \version 1.0
*/

Mouse Leave Event in MFC

There is several parts to tracking a mouse leaving, first you need to track on mouse move and a new message, WM_MOUSELEAVE

BEGIN_MESSAGE_MAP(CDerived, CWnd)
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
END_MESSAGE_MAP()

Within the mouse move, you need to setup a new condition to check if we have setup our mouse leave flag:

void
CDerived
::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_isInClient) // first time we enter, we need to setup the callback
{
TRACKMOUSEEVENT tme = { sizeof(tme) };
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = GetSafeHwnd();
TrackMouseEvent(&tme);
m_isInClient = 1;
}
else if (point == CPoint(-1,-1))
// We are leaving
{
m_isInClient = 0;
}
}

This is the custom message to loop the on mouse leave back to on mouse move:
afx_msg LRESULT OnMouseLeave(WPARAM,LPARAM)
{
OnMouseMove(0,CPoint(-1,-1));
return 0;
}

Monday, February 8, 2010

Post Build Copying

Often we want to copy a dependent DLL to an output directory. This can often slow up our builds because after every build, we have to wait for the dlls to be copied. If we use xcopy with "\D" flag we can speed up our build times:

For example:
xcopy "\OpenCV2.0\bin\cv200.dll" $(TargetDir) /D
xcopy "\OpenCV2.0\bin\cxcore200.dll" $(TargetDir) /D

MFC Doxygen Compatibility Note

A conflict between the two will cause this code to be misread and mark all your public variables as private. This is really bad because most doxygen outputs hide privates, causing all your functions to vanish, and if they do display, they will be marked as private which is just wrong.

class foo : public CWnd
{
DECLARE_DYNCREATE(foo)

public:
...
};

So, it is very important that you add an semicolon [;] after the dyncreate macro:

class foo : public CWnd
{
DECLARE_DYNCREATE(foo); //Semicolon added here

public:
...
};

Doxygen Function Commenting


A few tips when setting up your function comments for a Doxygen generation:

If you have visual assists, I highly suggest creating a Snippet. You may do this under VA Options:

My Snippet looks like this, and I mapped it to Ctrl + D:

/**
* $SymbolName$
*
* \return $SymbolType$
* \param $MethodArg$
*/

Once you create the snippet you can autogen most of the work for you when documenting a function:

It is important to then fill out the comment with the specific information. The first line will be the short description of the function. Any information after that will be displayed in the long description section. Each variable and return may also be commented, any input or output you do not want to comment, should be deleted from the comment. For example, if the function returns a void, the auto complete will generate the code "* \return void", which should always be deleted. After filling out the comments my function now looks like:


Notice I added an \sa field, which stands for see also. This will allow for a direct link in doxygen to the function that is used to populate the ImageStruct before it is received.

Finally my Doyxgen output for the following function looks like this:


Friday, February 5, 2010

Starting My Coding Blog

For those who want coding suggestions. Particularly I need a place to track coding practices and tips at my job so I created this.