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;
}