Wednesday, March 25, 2009

Make Sure Only One Instance of the Application Is Running

Place the following code in your WinMain:

// Look for the running instance of the application
char* szTitle = "My Title";
if (FindWindow(NULL, szTitle)){
SetForegroundWindow(FindWindow(NULL, szTitle));
return FALSE;
}

First, it looks for a window that has the same title as your application. If it finds it, it will make it active.
Another approach is to use a mutex:

BOOL IsFirstInstance()
{
HANDLE hMutex = CreateMutex(NULL, FALSE, "PUT A GUID HERE");
if(hMutex && GetLastError() == ERROR_ALREADY_EXISTS)
{
ReleaseMutex(hMutex);
return FALSE;
}
ReleaseMutex(hMutex);
return TRUE;
}

You call the above-mentioned function in your "InitInstance" method of your application.

How to Launch Internet Properties Control Applet

Use the following code:

WinExec("rundll32 inetcpl.cpl LaunchConnectionDialog", SW_SHOW);

Measure Time In Milliseconds

Use the DWORD GetTickCount(void) function.
The return value is the number of milliseconds that have elapsed since the system was started.
Example Code:

DWORD dwStart = GetTickCount();

Stop if this has taken too long:

if( GetTickCount() - dwStart >= TIMELIMIT )
Cancel();

Measure Time In Milliseconds

Use the DWORD GetTickCount(void); function.


The return value is the number of milliseconds that have elapsed since the system was started.


Example Code:


DWORD dwStart = GetTickCount();



Stop if this has taken too long:


if( GetTickCount() - dwStart >= TIMELIMIT )

Cancel();

Retrieve Menu Item Text with GetMenuItemInfo function


MENUITEMINFO MenuItem;
HMENU hmenu, hsubmenu;
HWND hwnd; //handle to main window
char szString[256];
int countLast =0;
//Initialize MENUITEMINFO structure:
memset(&MenuItem,0, sizeof(MenuItem));
MenuItem.cbSize = sizeof(MenuItem);
MenuItem.fMask =MIIM_TYPE;
MenuItem.fType = MFT_STRING;
//Important - the dwTypeData and cch data members must also be initialized to receive the string.
MenuItem.cch = 256;
MenuItem.dwTypeData = szString;
hmenu = GetMenu(hwnd); //get the menu
hsubmenu = GetSubMenu(hmenu,0); //get the first submenu

countLast = GetMenuItemCount(hsubmenu); //count number of items in the submenu; starts with 0;

GetMenuItemInfo(hsubmenu, 0, --countLast, &MenuItem );

MessageBox(NULL, MenuItem.dwTypeData, "Last Menu Item", MB_OK);

Use Bold or Underlined Font

1. Define a static HFONT variable:

static HFONT hFont;

2. In the response to the WM_INITDIALOG message, create a font with desired features, using CreateFont function:

HFONT CreateFont(
int nHeight, // logical height of font
int nWidth, // logical average character width
int nEscapement, // angle of escapement
int nOrientation, // base-line orientation angle
int fnWeight, // font weight
DWORD fdwItalic, // italic attribute flag
DWORD fdwUnderline, // underline attribute flag
DWORD fdwStrikeOut, // strikeout attribute flag
DWORD fdwCharSet, // character set identifier
DWORD fdwOutputPrecision, // output precision
DWORD fdwClipPrecision, // clipping precision
DWORD fdwQuality, // output quality
DWORD fdwPitchAndFamily, // pitch and family
LPCTSTR lpszFace // pointer to typeface name string
);


Use the pre-defined FW_BOLD parameter for fnWeight for Bold text.
Set fdwUnderline parameter to TRUE for underlined text.

Use default values for most of the other parameters.

Here is a simple helper function:

HFONT SimpleCreateFont( int Height, BOOL Bold, BOOL Italic, BOOL Underline,
BOOL StrikeOut, DWORD Family, char* FaceName )
{
HFONT Ret;
int Weight;
Weight = Bold ? FW_BOLD : FW_NORMAL;
Ret = CreateFont( Height, 0, 0, 0, Weight,
Italic, Underline, StrikeOut, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | Family, FaceName );
return( Ret );
}


3. Use the WM_SETFONT message to tell child control to use new font

SendMessage( GetDlgItem( hwnd, ID_WEB ), WM_SETFONT, (WPARAM)hFont, 0 );

Enable a Button Depending On Whether There is Any Text in the Edit Box

Use this function:

int EntryFieldMessages(HWND hDlg,WPARAM wParam) {
char buffer[1024];
//Get a handle to the button
HWND hIdOk = GetDlgItem(hDlg,1005);
switch (HIWORD(wParam)) {
case EN_CHANGE:
if (GetDlgItemText(hDlg,1004,
buffer, sizeof(buffer))) {
// There is some text in the entry field. Enable the IDOK button.
EnableWindow(hIdOk,1);
}
else // no text, disable the IDOK button
EnableWindow(hIdOk,0);
break;
}
return 1;
}

in response to WM_COMMAND message, i.e.:

case 1004:
{
switch (HIWORD(wParam)){
case EN_CHANGE:
return EntryFieldMessages(hwnd,wParam);
}
break;
}

1004 represents an edit box identifier, of course.