Tuesday, September 21, 2010

Using Shortcut Flags for MFC Applications

If you've ever messed around with a shortcut's settings, you've probably noticed that some shortcuts include flags after the target path. Generally, they look something like this:



If we want to use those flags in our MFC applications, this can easily be done by accessing the LPCSTR m_lpCmdLine parameter from the application's class. The flag set in the above shortcut would give that parameter the following value:

-testFlag

Thursday, August 5, 2010

Quickly Find Local Open Ports

While looking for a way to determine what communication ports are in use for your system, I came across the following article.

Typing the following command into the Windows Command Prompt will allow you to see the open ports, as well as the ID of the process using that port:

netstat -ao |find /i "listening"

And to see what process each process ID belongs to, you only need to a little tinkering with the Windows Task Manager settings:


Tuesday, March 30, 2010

CDialog::PostNcDestroy and delete this

Whenever I dynamically create a CDialog object, I like to let it clean itself up by adding the following code:

void CMyDlg::PostNcDestroy()
{
CDialog::PostNcDestroy();
delete this;
}

PostNcDestroy is a virtual function from CDialog that is called after DestroyWindow. Typically you are done with a CDialog object after the window is destroyed so it is nice to let itself clean itself up. Essential the entire CDialog object becomes a free smart pointer.

Another nice trick is if you are calling the same CMyDlg object statically you can execute the following code and be ok...

{
CMyDlg dlg();
dlg.DoSomething();
....
}

and then let the object go out of scope.

BE CAREFUL though, if you called destroy window unnecessarily.

dlg.DestroyWindow(); //Oops

Then you are going to corrupt your heap and delete a static object.

Instead just hide the window until it goes out of scope.

Sunday, March 7, 2010

CPPUnit DLL Debugger Settings

This is simply a reference for fellow Pathfinder employees,

command: "$(TargetDir)TestPlugInRunnerd.exe"
command args: -testsuite "$(TargetPath)"

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.