Friday, September 11, 2009

[VC++] Catching exception with debugger

You may some times feel crazy about some exceptions in your application. You have no idea where it is happening in the code and what you can do now is debugging the suspicious location in the issue happening scenario. Let me welcome you to a better approach with your VC++ debugger, so that you will get a better context of the issue causing exception. Follow the steps,

1. Debug your application (Either start with debugger or attach your process with the debugger).
2. In the VC 6 debugger choose Debug->Exceptions then you can see a dialog with various exception types.
3. Click and select all the Exceptions, now press OK.
4. Run your scenario.
5. When an exception happen a message box will be shown in the debugger and execution will break.
6. Now you can get the call stack where exception happens. For this check the Context combo box in the debugger IDE.
7. Now select each location in the call stack and interpret the cause (you can get the value of the variables).

Tuesday, September 8, 2009

Change Drive letters

Here is how to change or swap drive letter of the disk drives.

1. Take MyComputer->Manage
2. In the management console select Storage->Disk Management
3. Now Add... , Change... or Remove drive letter.
4. For swapping drive letters between disk drives first remove drive letters of both the drives and then select the needed letters one after another.

Blocking websites in your local machine

Do you want to restrict some of the sites to open up in your machine ? You can do with some browsers but same can be easily find out by others. Here is another way for blocking sites in the local machine.

1. Take C:\Windows\system32\drivers\etc
2. Open file hosts in C:\Windows\system32\drivers\etc
3. Add a new line to the hosts specifying the website name.

For example if you want to block www.youtube.com and www.orkut.com please add the below lines to the file hosts
127.0.0.1 www.youtube.com
127.0.0.1 www.orkut.com

You may need to restart your browser for making it effect.

Renaming file/folder with empty name or funny symbols

You may have tried renaming a file/folder with empty name but windows will never allow it. Here is a way to rename your folder.

1. Right click the file/folder and select Properties.
2. In the Properties dialog take General tab and delete the current name.
3. Keep the cursor in the name box, Press down Alt key and press 255 (from number pad)
4. Now press OK, selected file/folders name will be changed to empty.
5. If you use other combination such as 256, 257 etc with Alt key it will result in creating funny symbols as name of the file/folder.

I tell you there is a blank icon available with WINDOWS for setting blank icon for a folder. In the Customize tab, click Change Icon... and you can select empty icon and press Ok.

Friday, September 4, 2009

[Utility][WinDbg] !htrace for debugging handle leak

Windbg Debugger’s !htrace extension is very good at debugging handle leaks. See the below steps how you can do it.

1. Install Debugging Tool for windows from here.
2. Run WinDbg installed with Debugging Tools in Step 1.
3. Take File->Attach to a process... menu and select your application in the process list
4. Application will break and change in to debug mode
5. Take File->Symbol File path and add the path where your application's pdb file is available
6. In the debug prompt enter !htrace -enable and press enter.
7. Now take Debug->Go menu, then you can operate on your application
8. Now run your scenario where your application is assumed to have handle leak.
9. Now take Debug->Break menu, for changing the application to debug mode.
10. Now enter !htrace -diff in the debug prompt and press enter. Here it list the handle leak logs.

Below is an example of the log generated for 4 opened handle in my test app. From the log you can see where exactly the handle is leaked in the code.
0:001>
!htrace -diff
Handle tracing information snapshot successfully taken.
0x26 new stack traces since the previous snapshot.
Ignoring handles that were already closed...
Outstanding handles opened since the previous snapshot:
--------------------------------------
Handle = 0x0000070c - OPEN
Thread ID = 0x00001758, Process ID = 0x00001248

0x7c8308eb: kernel32!CreateEventA+0x00000068
*** WARNING: Unable to verify checksum for D:\TestFolder\MiscTest\Release\MiscTest.exe
0x0040172b: MiscTest!CMiscTestDlg::OnButtonHandle+0x0000001a
0x73dd24c0: MFC42!_AfxDispatchCmdMsg+0x00000082
0x73dd23bf: MFC42!CCmdTarget::OnCmdMsg+0x0000010a
0x73e3dead: MFC42!CPropertySheet::OnCmdMsg+0x0000001d
0x73dd3244: MFC42!CWnd::OnCommand+0x00000053
0x73dd1bf1: MFC42!CWnd::OnWndMsg+0x0000002f
0x73dd1b9b: MFC42!CWnd::WindowProc+0x00000024
0x73dd1b05: MFC42!AfxCallWndProc+0x00000091
0x73dd1a58: MFC42!AfxWndProc+0x00000036
0x73e6847d: MFC42!AfxWndProcBase+0x00000039
--------------------------------------
Handle = 0x00000710 - OPEN
Thread ID = 0x00001758, Process ID = 0x00001248

0x7c8308eb: kernel32!CreateEventA+0x00000068
0x0040172b: MiscTest!CMiscTestDlg::OnButtonHandle+0x0000001a
0x73dd24c0: MFC42!_AfxDispatchCmdMsg+0x00000082
0x73dd23bf: MFC42!CCmdTarget::OnCmdMsg+0x0000010a
0x73e3dead: MFC42!CPropertySheet::OnCmdMsg+0x0000001d
0x73dd3244: MFC42!CWnd::OnCommand+0x00000053
0x73dd1bf1: MFC42!CWnd::OnWndMsg+0x0000002f
0x73dd1b9b: MFC42!CWnd::WindowProc+0x00000024
0x73dd1b05: MFC42!AfxCallWndProc+0x00000091
0x73dd1a58: MFC42!AfxWndProc+0x00000036
0x73e6847d: MFC42!AfxWndProcBase+0x00000039
--------------------------------------
Handle = 0x00000714 - OPEN
Thread ID = 0x00001758, Process ID = 0x00001248

0x7c8308eb: kernel32!CreateEventA+0x00000068
0x0040172b: MiscTest!CMiscTestDlg::OnButtonHandle+0x0000001a
0x73dd24c0: MFC42!_AfxDispatchCmdMsg+0x00000082
0x73dd23bf: MFC42!CCmdTarget::OnCmdMsg+0x0000010a
0x73e3dead: MFC42!CPropertySheet::OnCmdMsg+0x0000001d
0x73dd3244: MFC42!CWnd::OnCommand+0x00000053
0x73dd1bf1: MFC42!CWnd::OnWndMsg+0x0000002f
0x73dd1b9b: MFC42!CWnd::WindowProc+0x00000024
0x73dd1b05: MFC42!AfxCallWndProc+0x00000091
0x73dd1a58: MFC42!AfxWndProc+0x00000036
0x73e6847d: MFC42!AfxWndProcBase+0x00000039
--------------------------------------
Handle = 0x00000718 - OPEN
Thread ID = 0x00001758, Process ID = 0x00001248

0x7c8308eb: kernel32!CreateEventA+0x00000068
0x0040172b: MiscTest!CMiscTestDlg::OnButtonHandle+0x0000001a
0x73dd24c0: MFC42!_AfxDispatchCmdMsg+0x00000082
0x73dd23bf: MFC42!CCmdTarget::OnCmdMsg+0x0000010a
0x73e3dead: MFC42!CPropertySheet::OnCmdMsg+0x0000001d
0x73dd3244: MFC42!CWnd::OnCommand+0x00000053
0x73dd1bf1: MFC42!CWnd::OnWndMsg+0x0000002f
0x73dd1b9b: MFC42!CWnd::WindowProc+0x00000024
0x73dd1b05: MFC42!AfxCallWndProc+0x00000091
0x73dd1a58: MFC42!AfxWndProc+0x00000036
0x73e6847d: MFC42!AfxWndProcBase+0x00000039
--------------------------------------
Displayed 0x4 stack traces for outstanding handles opened since the previous snapshot.

Thursday, September 3, 2009

Ghostzilla - The Invisible browser

Are you looking for an idea to browse the internet with out leaving any trace for your boss, colleagues or roomies? You may be having difficulty in hiding your browser window if some one is over your shoulders all of a sudden. Let me say you about a browser which will save you from such mess, Ghostzilla - The Invisible browser.
Ghostzilla browser for Windows is a tool that shields you from the looks of people around you, when they try to see if you are surfing the Web. With Ghostzilla, they see your normal work screen. You see the Web page, drawn to appear inside your work application and to look like that application to a bystander. If someone comes too close, move the mouse away from the Web page and it disappears, leaving the original application frame.

If you wanna try this follow the below steps,
1. Download it from here.
2. Extract the downloaded GhostzillaCD-1.0.1-free-v1.zip
3. Run the Start-Ghostzilla-CD.exe from the path \GhostzillaCD-1.0.1-free-v1\program\
4. Press No in the dialog shown.
5. You can see GhostZilla browser displayed and embeded in topmost window.
6. If it is disappeared, do the following to make it visible
- Click the left most edge of your screen
- Now click the right most edge of your screen
- Now click the left most edge of the screen again. Ahh it is displayed !
7. For hiding the Ghostzilla just move your mouse away from the Ghostzilla.
8. By default it will appear black&white(to have privacy), to have color view choose Setup->Hiding Level 1 menu.


Ghostzilla embeded in explorer window.
For getting a hand full of options and short keys read Instructions.html in the downloaded zip. Remember one thing if you brows with Ghostzilla history and usage details can be tracked as with other browsers, this browser is only meant for hiding what you doing in your screen (huh are you still browsing??)

Saturday, July 25, 2009

Fixing MSMQ re installation issue

Have you ever got the below error when you try to install MSMQ ?
Error Code: 0x42C Error Description: The dependency service or group failed to start.

How To Fix ?
For fixing this issue we need to make sure that all the depended services of MSMQ service should be started.

Following are the depended services of MSMQ in various operating system.
Windows XP
* Distributed Transaction Coordinator
* Message Queuing access control
* NT LM Security Support Provider
* Reliable Multicast Protocol Driver
* Remote Procedure Call (RPC)
* Security Accounts Manager

Windows 2003 server

* Message Queuing access control
* NT LM Security Support Provider
* Remote Procedure Call (RPC)
* RMCAST (Pgm) Protocol Driver
* Security Accounts Manager

Windows Vista

* Message Queuing access control
* Remote Procedure Call (RPC)
* Windows Event Log

For starting a service,
1. Right click on "My Computer" and select "Manage"
2. Select "Services and Applications" in left pane and Select "Services" right pane.
3. Right click and "start" the needed service. For disabled services you need to change it to Automatic/Manual before Starting

Now Start the depended service and try installing MSMQ again.

Wednesday, June 17, 2009

Restore your Windows system

Have you ever caught up with a situation, that you have installed something or did some manual registry edits and result in an unrecoverable situation? This may be due to - registry got corrupted or some other registration errors. In such a situation, most of us may go for some trials to get rid of the issues facing and if found unsuccessful, end up in deciding reinstalling windows. But you have to understand about the System Restore tool (Start->Programs->Accessories->System Tools->System Restore) supplied with Windows Accessories from Windows XP and later versions.

System Restore
System Restore helps you restore your computer's system files to an earlier point in time. It's a way to undo system changes to your computer without affecting your personal files, such as e‑mail, documents, or photos.
If the installation of a program or a driver cause an unexpected change to your computer or cause Windows to behave unpredictably. Usually, uninstalling the program or driver corrects the problem. If uninstalling does not fix the problem, you can try restoring your computer's system to an earlier date when everything worked correctly.
System Restore uses a feature called System Protection to regularly create and save restore points on your computer. These restore points contain information about registery settings and other system information that Windows uses. You can also create restore points manually.
System Restore is not intended for backing up personal files, so it cannot help you recover a personal file that has been deleted or damaged. You should regularly back up your personal files and important data using a backup program.

See the below steps in Windows Vista showing Restoring to a previous point
.
.

Wednesday, April 29, 2009

Fixing windows installer not working

Have you ever come up with some problems while using windows installer for installing components ? Here is an issue which is widely seen, when trying to install some application using msi installer you will be shown with a message "The Windows Installer service on Local Computer started and then stopped. Some services stop automatically if they have no work to do, for example, the Performance Logs and Alerts service." and installation stops. This may be due to the reason, the Windows Installer files that are on your hard disk are damaged or are missing.

Solution
For fixing this issue you may need to register the Windows installer or reinstall windows installer. For registering Windows installer do the below steps,
1. Take Start->Run
2. In the Run window enter msiexec /unregister and press OK
3. Again in the Run window enter msiexec /regserver and press OK

Now try installing with Windows installer everything will work fine!.

Monday, April 27, 2009

[Utility] 'Over Disk' visualize your disk usage with a Radial map

In my previous post I introduced you a tool SpaceSniffer for visualizing your disk usage. Let me show you one more disk usage visualizer OverDisk, which display the disk usage as a radial map. You can select a drive or directory for analyzing with OverDisk and you will be provided with a radial map showing each items inside the selection. On mouse over the details of the folders will be shown. On further selection on the items displayed you will be traversed to the selected folder's radial map. This Windows tool can download from here.

Saturday, April 25, 2009

[Utility] Visualize drive space with 'SpaceSniffer'

SpaceSniffer is drive space visualizer utility for windows user. It is a utility that gives you an idea of how folders and files are structured on your disks. You will have immediate perception of where big folders and files are situated on your devices.
Start a scan process and see the overall situation. Bigger are the elements on the view, bigger are folders and files on your disk. You need more detail on a big folder? Just single click on it. The selected element will be detailed with its content. Start a scan process and see the overall situation. Bigger are the elements on the view, bigger are folders and files on your disk. You need more detail on a big folder? Just single click on it. The selected element will be detailed with its content. You can also filter on file size, file date and combine all filters.



Download SpaceSniffer and give a try.

Friday, April 24, 2009

[Utility] 'Jing' screen/video capture tool

Do you want to try a sophisticated Screen/Video capture tool ? I suggest Jing. I found myself comfortable with this free tool. I was taking snapshots and mark on the same in a traditional way, Prnt Screen -> Paste to mspaint -> Mark there -> Save and use. If everything available in a single easy to use tool then you will opt the same right ?


You can take snapshot, mark, highlight and quote on it. Jing also provides video capture. So go for below steps and make a trial run,
2. Install Jing.
3. Run Jing, you can see a round sun appearing at middle of your screen and set to the top middle screen.
4. Mouse over the yellow sun.
5. Select the capture option.
6. Select the area/window.
7. Press Save button displayed in the button panel shown.
You can run video capture in similar way. Just see a snapshot created/edited with Jing.

Share what you captured to Every one !!!
Just tell Jing where to send the screenshot and—BAM!—it's there and ready to share. When you send to a destination like Screencast.com or Flickr, Jing even places a hyperlink on your clipboard.
Remember, if you are a Windows user, you should have Windows XP or Vista and .NET Framework 3.0 for running Jing. Mac users need Mac OS X 10.4.11, or 10.5.5 or later and QuickTime 7.5.5 or later.

Thursday, April 23, 2009

[Utility] 'Circle Dock' a quick launcher for you!

Are you thinking of having a Circular & Spiral dock with cool looks, as a quick launcher for your Windows ? Then here is a cool open source Circle Dock for you.



As the name suggest its circular and spiral ! Its time for removing the messy desktop icons and bring Circular Dock, save the space/time and spice your desktop. I am sure your colleague will say wow !
For taking this to your desktop just follow the below steps,
1. Download Circle Dock from here.
2. Run Circle Dock.
3. Drag and drop the applications to the Circle Dock.
4. Click on the icon shown on Circle Dock of the application will launch it!

Remember you should have WindowsXP or Vista, .Net Framework 2.0 should be installed and a some what recent graphics card. So just try it and discover lot more (untold by me) features available !!!

Sunday, April 19, 2009

[VC++] Change color of Progress bar

Have you ever thought of changing the color of the progress bar you created using CProgressCtrl? PBM_SETBARCOLOR is the message which will help you to change the color of progress bar. See the below code snippet showing how to send the above said message for changing the progress bar color.
// Change progress bar color to yellow
m_ProgressCtrl.SendMessage( PBM_SETBARCOLOR, 0, RGB ( 255, 255, 0 ));

[VC++] Disabling Ctrl+Alt+Del key

Simplest way to disable the Ctrl+Alt+Del key press is to use the API SystemParametersInfo(). See the below code snippet.
SystemParametersInfo ( SPI_SETSCREENSAVERRUNNING, TRUE, NULL, 0 );

[VC++] MFC Collection classes

Collection class
A collection class is characterized by its "shape" and by the types of its elements. The shape refers to the way the objects are organized and stored by the collection. MFC provides three basic collection shapes: lists, arrays, and maps (also known as dictionaries).


MFC provides collection classes of three categories.
Array
List
Map


Below is a list of classes under each category and type of elements each store,

MFC Array Classes

CByteArray - 8-bit bytes (BYTEs)
CWordArray - 16-bit words (WORDs)
CUIntArray - Unsigned integers (UINTs)
CPtrArray - void pointers
CObArray - CObject pointers

CStringArray - CStrings

MFC List Classes
CObList - CObject pointers
CPtrList - void pointers
CStringList - CStrings

MFC Map Classes
CMapWordToPtr - Stores void pointers keyed by WORDs
CMapPtrToWord - Stores WORDs keyed by void pointers
CMapPtrToPtr - Stores void pointers keyed by other void pointers
CMapWordToOb - Stores CObject pointers keyed by WORDs
CMapStringToOb - Stores CObject pointers keyed by strings
CMapStringToPtr - Stores void pointer keyed by strings
CMapStringToString - Stores strings keyed by other strings

[VC++] Expanding MFC macros

You may be seeing the MFC macros DECLARE_MESSAGE_MAP, BEGIN_MESSAGE_MAP etc from the day one you started using MFC. Have you ever thought of what goes inside these macros ?
Follow the below steps and you can see these macros expanded,
1. Select Project->Settings->Link tabs in the Visual Studio editor.
2. In the 'Project Options' edit box delete all the options and type /EP in it.
3. Now compile the file. You will see the expanded code in the output window.

Tuesday, April 7, 2009

Google tips for effective googling

Most of us use Google in our daily life, in one way or other. Here are a few tips to Google more effectively:



  • Use quotation marks for searching exact phrases. For e.g.: "Your exact phrase" will return results containing the exact phrase Your exact phrase.
  • Use "tilde" for getting search with synonym. For e.g.: "~Health decission" will display the results for the synonyms of Health decission.
  • Use "minus sign" for filtering the search results removing the word you do not want. For e.g.: "nano -ipod" results nano results other than ipod nano.
  • Use "define:" for getting the defnition/meaning of a given word/phrase. For e.g.: "define: electromagnetic spectrum" will show the definitions of electromagnetic spectrum.
  • Use "site:" for limiting the search to the specified site or domain only. For e.g.: "site:freshtechies.blogspot.com" will display the search result for the pages from the site freshtechies.blogspot.com. If you give "VC++" site:freshtechies.blogspot.com it will display the VC++ result from the pages of that site.
  • Use "link:" for displaying the search result of all the sites which are linked to the specified link. For e.g.: "link:clustermaps.com" will display all the sites linking to the clustermaps.com
  • Use "info:" for accessing the above specified tips. For e.g.: "info:http://google.com" will show the options for searching similar to, link to, google's cache, from the site options.
  • Use "related:" for searching related sites of the specified site. For e.g.: "related:http://google.com" will display the results with sites similar/related to google.
  • Use "filetype:" for specifying the file type of the search results. For e.g.: ".net tutorial filetype:ppt" will display .net PPT Tutorials.
  • Use google as a calculator simply enter the expression in the search box and Go.
  • Use google as a convertor. For eg: try "1 USD to JPY"

See more search operators and usages here.


Saturday, March 28, 2009

[Utility] Process Explorer for Software Developers

In my previous post I told you about the Microsoft TechNet site and in the features I have mentioned about Windows SystInternals free utilities for software developers. Let me introduce a tool Process Explorer to show you the relevance of SystInternals tools for a Software Developer. It is an extended TaskManager and can replace Task Manager.

What is Process Explorer ?

Process Explorer is a system monitoring utility which can be used to track down system problems. Process Explorer is an advanced process management utility that picks up where Task Manager leaves off.




Key Features
  • Detailed information about a process including its icon, command-line, full image path, memory statistics, user account, security attributes etc can be viewed.
  • A particular process can be selected and list the DLLs it has loaded or the operating system resource handles it has open.
  • Powerful search capability that will quickly show you which processes have particular handles opened or DLLs loaded.
  • System Information & Performance graph can be shown for whole system and for each process.

Download
It is a free ware, you can download Process Explorer from here. .

Note: If you have any memory or process related issue, just try process explorer, you will get additional information about the issue for sure !

Microsoft TechNet for Software Developers

Are you a windows (based) application developer and have you ever heared of Microsoft Technet or visited it's website ? If you have not then you have missed strong knowledge support.
Microsoft TechNet is a Microsoft site for techical information, developer utilities, news, blogs, events for software professionals. It can be accessed through the link http://technet.microsoft.com.


Website features include,
  • TechNet Library is a source of technical information for IT professionals and advanced users. The technical content is freely available on the web
  • TechNet Forums are the web-based forums used by the community to discuss a wide variety of IT professional topics.
  • TechNet Blogs is an exclusive blogging platform of Microsoft employees.
  • Windows SysInternals show cases a collection of free utilities for Software Developers.

So software developers please visit and see what you have here special to make your life easy !

Tuesday, March 24, 2009

[Utility] Team Viewer for remote desktop Sharing/Access support

Have you ever thought of accessing your friend's computer connected to internet & located in a different place (for example in a different country) and work on it as if you are accessing your local network PC as in remote desktop connection(mstsc) ? Here is an exclusive software utility just for the same and more !!! Let me introduce you Team Viewer (one of the best available tool in this arena).

Team Viewer
TeamViewer is a software package for remote control, desktop sharing and file transfer that works behind firewalls & NAT proxy. Just see the user interface of Team Viewer.


You can download it from here.

License
The personal-use or non-commercial use version is provided for free, while the business editions start at $249. The non-commercial use version of the software has limited features compared to the commercial version, and it is not licensed for use in a commercial environment. Extras which are provided additionally in the licensed version are the customization of the client module (QuickSupport) and the TV Manager, a database AddOn tool which allows the session logging for billing purposes. Below sections are based on the non-commercial use version.

Major Features
Following are the major features available in Team Viewer,
Remote Support
With this we can control our partner's computer. We can view the partner's machine, access his cursor and work on that machine.
Presentation
With this we can present our desktop to our partner.
File transfer
With this we can send/receive files to/from your partner
VPN
With this we can establish a Virtual Private Network connection with your partner's computer.

How to use?
Your and your partner's computer should have Team Viewer installed in their machine. For accessing your partner's remote computer,
1. Run the Team Viewer in both computers.
2. Enter the partner's ID in the ID box (Get the ID and Password that will be shown on starting Team Viewer from your partner).
3. Choose the option/feature you want to activate and press Connect to Partner button.
4. Now it will ask for the partner's Password, enter it and press Log On button.

After all with Team Viewer cross-platform work is possible between Windows and Macintosh systems !

Thursday, March 19, 2009

[VC++] Change cursor using SetClassLong()

You can use SetClassLong() function for changing/setting the cursor of your application. Here is how to do it.
SetClassLong( GetSafeHwnd(),
GCL_HCURSOR,
(LONG)LoadCursor(AfxGetInstanceHandle(),
MAKEINTRESOURCE( IDC_CURSOR1 )));
Please make sure that cursor resource IDC_CURSOR1 is created and available in the .rc file.

Wednesday, March 18, 2009

[VC++] Getting first item selected in CListCtrl

When you start to use CListCtrl, you may come in need of knowing the first selected index of a listcontrol. Here is how to find the same,
int nItemIdx = m_List.GetNextItem( -1, LVNI_SELECTED );
if( nItemIdx == -1 )
{
// No item selected
}
else
{
// nItemIdx holds the index of item selected
}

Sunday, March 8, 2009

[VC++] Showing restart dialog

Simplest way to show a restart dialog is to use the API RestartDialog(). See how to do it !
RestartDialog( NULL, NULL, EWX_REBOOT );
Please note that this function is available through Windows XP Service Pack 2 (SP2) and Windows Server 2003. It might be altered or unavailable in other versions of Windows.

Tuesday, March 3, 2009

[VC++] Finding logical drive letters using GetLogicalDriveStrings()

Below code demonstrates how to find the logical drive letters in your machine using API GetLogicalDriveStrings(). If executed the below code on finding each drive letter it will show a message box displaying the drive letter.
TCHAR tszDriveList[512];
TCHAR tszDrive [3*sizeof(TCHAR)];
// Get the logical drive strings
int nDriveStrLen = GetLogicalDriveStrings( sizeof( tszDriveList ), tszDriveList );
if( 0 != nDriveStrLen )
{
// Parse the returned multi-string array.
int nIdx = 0;
while( 0 != tszDriveList[nIdx])
{
_tcscpy( tszDrive, &(tszDriveList[nIdx]));
// Show the drive obtained
AfxMessageBox( tszDrive );
// Skipping index for getting the whole :\ with drive letter
while( 0 != tszDriveList[nIdx] )
{
nIdx++;
}
nIdx++;
}
}

[VC++] Finding executable filename for a document

You can find a document's executable file name and path using FindExecutable() API. For example if you want to know the executable file path of a *.doc file it will return winword.exe installed path. Below code demonstrate how to use this.
TCHAR wcsExecutablePath[MAX_PATH];
// Find Executable path of the document
if( 32 < (int)FindExecutable( _T( "C:\\Test.doc" ),// Document Name
NULL, // Current working directory
wcsExecutablePath )) // Executable path returned
{
// Show the executable path obtained
AfxMessageBox( wcsExecutablePath );
}

[VC++] Open file dialog using GetFileNameFromBrowse()

You may be familiar with the File Open Dialog in application such as notepad, do you know how to make the same ? Its simple with a shell API GetFileNameFromBrowse() which is a wrapper of GetOpenFileName(). See the below code and see the appearance of the File open dialog in vista,
wchar_t wszFilepath[MAX_PATH] = L"C:\\";

if( GetFileNameFromBrowse( GetSafeHwnd(),
wszFilepath, // Default File Path
MAX_PATH, // Size of file path
NULL, // Working Directory
NULL, // Default Extension
L"*.*", // Filters
L"Open Me" ))// Dialog Title
{
// Show user selected file name/path in a message box
MessageBox( CString( wszFilepath ));
}
See the File Open dialog shown on excuting the above code

[VC++] Getting Drive type using RealDriveType()

Do you want to know what type of a drive is corresponding an index, there is a shell function RealDriveType() which will help you figuring out the same. This function will take first parameter as the drive index, for example if you pass drive index 1 that corresponds to A: if you pass drive index 3 that corresponds to C: similarly it will go on. See the below function for demonstrating how to know the drive type. If you pass a drive index to this function then it will show message box displaying the drive type. For example if you pass 3 it will show message box saying "Fixed Drive".
void ShowDriveType( int nDriveIdx_i )
{
int nDriveType = RealDriveType( nDriveIdx_i, 0 );
switch( nDriveType )
{
case DRIVE_UNKNOWN:
// This is an unknown drive
AfxMessageBox( "Unknow drive type" );
break;
case DRIVE_NO_ROOT_DIR:
// This is an Invalid root path
AfxMessageBox( "Invalid root path" );
break;
case DRIVE_REMOVABLE:
// This is a Removable Drive
AfxMessageBox( "Removable Drive" );
break;
case DRIVE_FIXED:
// This is a fixed drive
AfxMessageBox( "Fixed Drive" );
break;
case DRIVE_REMOTE:
// This is a Network Drive
AfxMessageBox( "Network Drive" );
break;
case DRIVE_CDROM:
// This is a CD/DVD Drive
AfxMessageBox( "CD/DVD Drive" );
break;
case DRIVE_RAMDISK:
// This is a RAM disk drive
AfxMessageBox( "RAMDisk Drive" );
default:
break;
};
}

Friday, February 27, 2009

[VC++] Creating Unique ID with CoCreateGuid()

At some point of a programmers life he will be in need to create some unique name. For example in one of my previous post for Preventing Multiple Instances I have suggested using a unique name for the mutex. Here is a utility function which will help you create a unique string.
// Return Unique String ID each time
const CString CreateUniquieID()
{
GUID UIDObj;
// Create Unique ID
CoCreateGuid( &UIDObj );
unsigned char* pUIDStr;
// Convert Unique ID to String
UuidToString( &UIDObj, &pUIDStr );
CString csUIDStr( pUIDStr );
// Free allocated string memory
RpcStringFree( &pUIDStr );
return csUIDStr;
}
This function uses CoCreateGuid() function which create an absolutely unique number that we can use as a persistent identifier. UuidToString () is used convert this Unique ID to a string. Do not forget to call RpcStringFree() for deallocating the memory if you are calling UuidToString (). You may need to include Rpc.h and link to Rpcrt4.lib for building the function.

Wednesday, February 25, 2009

[VC++] Extracting and using icon from other Applications

If you want to have your application using the icons of some other application in an easy way ExtractIcon() or ExtractIconEx() serves you the best. See the below code snippet demonstrating how to extract and use the icon of calculator as your application icon.
HICON hIcon;
// Extract icon of Windows Calculator
hIcon = ExtractIcon( AfxGetApp()->m_hInstance, "C:\\WINDOWS\\system32\\calc.exe", 0 );
// Set the extracted icon as the application's icon.
SetIcon( hIcon, FALSE );
Do not forget to destroy the icon handle calling DestroyIcon(), when no longer needed.

[VC++] Hiding application button from Taskbar

If you do not want to show your application on Windows Taskbar while it is running, modify the CMainFrame::PreCreateWindow() by adding WS_EX_TOOLWINDOW style and removing WS_EX_APPWINDOW style to Create Structure. See the below code which will do the same.
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// Adding Tool window style
cs.dwExStyle = WS_EX_TOOLWINDOW ;
// Removing App window style
cs.dwExStyle &= ~WS_EX_APPWINDOW ;
return TRUE;
}

Tuesday, February 24, 2009

[VC++] Removing 'Untitled' from Doc/View App Titlebar

Most of you may get wearied of seeing the 'Untitled' caption on your title bar when you create a Document/View Architecture application, say SDI application. What we actually seeing on an SDI title bar is Document Name - Application name, by default your document name will be 'Untitled' and application name will be IDR_MAINFRAME's value in the string table. The reason why you are seeing this is because of a style set by default FWS_ADDTOTITLE to the CREATESTRUCT data structure. So inorder to remove the 'Untitled'(or document name) from your mainframe title bar, remove the FWS_ADDTOTITLE style from the create structure of the mainframe window. There is one more style which worth a mention at this point, FWS_PREFIXTITLE this is the one responsible showing the document name followed by the application name. If we remove this style and if FWS_ADDTOTITLE is not removed then window will show title as Application name - Document Name.

Suppose if my Application name is TestGlobalObjects then see the default title bar with Untitled.


Changing Document Prefix Title to Postfix

See the below code modification in CMainFrame::PreCreateWindow() removing the FWS_PREFIXTITLE and see the change in window title bar caption.
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;

// Removing Pre Fix style
cs.style &= ~FWS_PREFIXTITLE;
return TRUE;
}



Removing document from title

See the below code and see the Untitled removed from window title bar on executing the below code.

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;

// Removing the Add To Title style
cs.style &= ~FWS_ADDTOTITLE;
return TRUE;
}

Monday, February 23, 2009

[VC++] Map or Unmap network drive

Are you looking for a standard 'Map Network Drive' dialog for mapping a network resource as a local drive to your Computer ? Or you may be looking for ‘Disconnect Network Drives' dialog box for disconnecting network resource mapped as your local drive ? Here is how to show such dialogs for mapping or disconnecting network resources using two APIs WNetConnectionDialog() and WNetDisconnectDialog(),

Showing 'Map Network Drive' dialog box

// Show Map Network Drive dialog
DWORD dwNetConnectRes = WNetConnectionDialog( 0, RESOURCETYPE_DISK );
if( NO_ERROR == dwNetConnectRes )
{
// successfully mapped the drive
}
else if( -1 == dwNetConnectRes )
{
// User canceled
}
else
{
// Mapping network drive failed
}
Above code when executed will display the 'Map Network Drive' dialog as shown below. For mapping a network resource press the Browse... button and select the network resource and press Finish.

Showing 'Disconnect Network Drives' dialog box
// Show Disconnect Network Drives dialog
DWORD dwNetDisConnectRes = WNetDisconnectDialog( 0, RESOURCETYPE_DISK );
if( NO_ERROR == dwNetDisConnectRes )
{
// successfully unmapped the drive
}
else if( -1 == dwNetDisConnectRes )
{
// User canceled
}
else
{
// Disconnecting network drive failed
}
See the below Disconnect Drives dialog displayed in my machine(with two network resources mapped already) on executing the above code. To disconect just select and press OK button.
For availing the above APIs you may need to incude header file winnetwk.h and link to mpr.lib.

Sunday, February 22, 2009

[C/C++] Error tracing using __FILE__ and __LINE__

You might have seen the preprocessor directives __FILE__ and __LINE__. I shall explain how to use the same for error reporting in your application.
__FILE__ This macro holds the file name of the current execution context.
__LINE__ This macro holds the line number of the current source file's execution context.
With these macros you can make your error reporting more effective by specifying the file name and line number where error was occurred. This will help to troubleshoot the issue more effectively and easily. Following is a utility function which you can use to log error message to debug viewer.
// For converting integer line number to string
#define STR(X) #X
#define MAKE_STR(X) STR(X)

// For holding the file name & line number of error context
#define FILE_INFO __FILE__ ":" MAKE_STR( __LINE__ )

// Log the error message with file name and line no to debugview
void TraceError( const char* pcErrorLoc, const char* pcErrorMsg )
{
char szErrorMsg[MAX_PATH];
// Format msg to "Error at <filepath>:<line> - <message>"
sprintf( szErrorMsg, "Error at %s - %s", pcErrorLoc, pcErrorMsg );
OutputDebugString( szErrorMsg );
}
You can call the above utility function as shown below, if some error occur. Use the Debug Viewer for viewing the output.
// Call the function if error occured
TraceError( FILE_INFO, "Invalid input from the user" );

[VC++] Process Information with ZwQueryInformationProcess()

There is an undocumented native ZwQueryInformationProcess() API available in NTDLL.dll, with which we can get the process information such as process id, base priority, parent process id, affinity mask etc. Below code snippet shows how to use the same,
typedef struct
{
ULONG ulExitStatus;
PVOID pBaseAddress;
ULONG ulAffinityMask;
ULONG uBasePriority;
ULONG_PTR pulUniqueProcessId;
ULONG_PTR pulInheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION;

typedef ULONG (WINAPI * ZwQueryInformationProcess)( HANDLE ProcessHandle,
ULONG ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG ReturnLength );
// Load NTDLL
HMODULE hModule = LoadLibrary( "NTDLL.dll" );
// Get the ZwQueryInformationProcess() address
ZwQueryInformationProcess ZwQueryInformationProcessPtr = (ZwQueryInformationProcess)GetProcAddress( hModule, "ZwQueryInformationProcess");
PROCESS_BASIC_INFORMATION stProcessBasicInformation = { 0 };
if( ZwQueryInformationProcessPtr )
{
// Get the process handle
HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
// Call the function
ZwQueryInformationProcessPtr(hProcess, 0, &stProcessBasicInformation, sizeof(stProcessBasicInformation), 0);
}
FreeLibrary( hModule );
In my previous post I have shown you how to get the parent process id by iterating through the processes and in the above code stProcessBasicInformation.pulInheritedFromUniqueProcessId represents the parent process id.

[VC++] Getting parent Process ID of current process

If you need to get the Process ID of your parent application, after taking a snapshot of all the process you may need to iterate and get the current process information. See the below code snippet for obtaining the parent Process ID.
HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
PROCESSENTRY32 stProcessEntry;
// Get the current process id
DWORD dwPID= GetCurrentProcessId();
// To store Parent process id
DWORD dwParentPID = 0;
// Get the first process
BOOL bContinue = Process32First( hSnapShot, &stProcessEntry );
// Loop for all the process
while( bContinue )
{
// If current process get the parent id
if( dwPID == stProcessEntry.th32ProcessID)
{
// Now dwParentPID have the parent process id
dwParentPID = stProcessEntry.th32ParentProcessID;
break;
}
// If not current process Get next process
bContinue = Process32Next( hSnapShot, &stProcessEntry );
}
// Show the parent Process ID
char szParentPID[5];
itoa( dwParentPID, szParentPID, 10 );
MessageBox( szParentPID );
There is an alternate way for getting parent process id using an undocumented API ZwQueryInformationProcess()

Saturday, February 21, 2009

[VC++] Programmatically empty the Recycle Bin

Suppose in your program if you are in need of more disk space very first thing you can do is empty the recycle bin. There is a shell function SHEmptyRecycleBin() for emptying the recycle bin. Please see the below code snippet showing the usage.
// Empty Recycle bin.
if( S_OK == SHEmptyRecycleBin( NULL,
NULL,
SHERB_NOCONFIRMATION ))
{
// Successfully emptied
}
You can specify options such as do not show delete progress and do not make sounds specifying respective flags in the last parameter of the function. Specifying drive or folder path as the second parameter will remove only content deleted from those folders.

Friday, February 20, 2009

[VC++] Enabling XP style theme in Win32/MFC App

You might have noticed that your application developed in VC6, XP style themes are not enabled. If you want your application to use visual styles, you must add an application manifest that indicates that ComCtl32.dll version 6 should be used if it is available. If you are looking for adding XP visual styles you have two options to deal with, you can either add a manifest file to the path of your executable or you can embed the manifest content to your executable. See how to do the same in each option.

Adding Manifest file method

  • Create a text file with name YourAppName.exe.manifest in your executable path. For eg: if your executable's name is TestApp.exe manifest file's name will be TestApp.exe.manifest
  • Paste the below code to the manifest file you created. Replace CompanyName.ProductName.YourApp and Your application description here with your application details in the manifest file.
  • Now you can run your application and feel the difference !
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly
xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="CompanyName.ProductName.YourApp"
type="win32" />
<description>Your application description here.</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*" />
</dependentAssembly>
</dependency>
</assembly>
Embeding manifest in your executable
  • Take Workspace window->Resource tab of your Visual Studio IDE
  • Right click on the resources and choose insert , then Insert Resource dialog will be shown.
  • Select Custom... button of the Insert Resource dialog and enter the custom resource type as 24 and press OK.
  • Copy and paste the above shown manifest file after specific modifications (mentioned in the previous method)
  • Change the Resource ID of the newly added IDR_DEFAULT1 to 1
  • Call InitCommonControls() (include commctrl.h and link comctl32.lib)from any of your init function such as InitInstace() or Winmain()
  • Rebuild the application, everything is embedded in your application. Execute it and feel the XP style.

[VC++] Changing your screen resolution programmatically

Here is how to change your screen resolution programmatically. For doing this you may need the assistance of two APIs,
  • EnumDisplaySettings() - for getting the current graphics mode.
  • ChangeDisplaySettings() - for setting the modified graphic mode.
Below code demonstrate changing your system screen resolution to 1280X1024.
DEVMODE stGraphicsMode;
// Retrieves the information of current display device
EnumDisplaySettings ( NULL, 0, &stGraphicsMode );
// Change the screen resolution
stGraphicsMode.dmPelsWidth = 1280;
stGraphicsMode.dmPelsHeight = 1024;
stGraphicsMode.dmBitsPerPel = 32;
// Set the modifying items
stGraphicsMode.dmFields = DM_PELSWIDTH DM_PELSHEIGHT DM_BITSPERPEL;
// Change the display settings
if( DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettings( &stGraphicsMode, CDS_FULLSCREEN ))
{
//Successfully changed!
}

Thursday, February 19, 2009

[VC++] Checking your window is visible to the user ?

Are you interested in knowing programmatically, that your application's windows are visible or not ? You might be familiar with IsWindowVisible(), but this function won't give you the right answer to identify whether your window is partially shown or some other window is over your window or so. It is possible to check the window visiblity by clipping the window with GetClipBox(); below function demonstrate the same, what you have to do is call the below function passing handle to the window and check the return value visibile, partial visible or hidden.
// Enumeration for return values
enum VISIBLE_STATS_e
{
WND_ERROR = -1, // Failed getting visiblity
WND_HIDDEN = 0, // Window is hidden
WND_PARTIAL_VISIBLE = 1, // Window is partially shown
WND_FULL_VISIBLE = 2 // Window is fully shown
};

// Utility function which will return depending the windows current status
VISIBLE_STATS_e GetWindowVisibleStatus( HWND hWnd_i )
{
VISIBLE_STATS_e eRetStatus = WND_ERROR;
if( IsWindow( hWnd_i ))
{
CRect ClientRect;
CRect ClipRect;
HDC hWndDC = GetDC( hWnd_i );
// Get the Window associated to the client rectangle
GetClientRect( hWnd_i, &ClientRect );
// Get the clipping rect of window
switch ( GetClipBox( hWndDC, &ClipRect ))
{
case NULLREGION:
eRetStatus = WND_HIDDEN;
break;
case COMPLEXREGION:
eRetStatus = WND_PARTIAL_VISIBLE;
break;
case SIMPLEREGION:
// If client area is visible then treat it as visible
if( EqualRect( &ClipRect, &ClientRect ))
{
eRetStatus = WND_FULL_VISIBLE;
}
else
{
eRetStatus = WND_PARTIAL_VISIBLE;
}
break;
default:
eRetStatus = WND_ERROR;
break;
}
ReleaseDC( hWnd_i, hWndDC );
}
return eRetStatus;
}

Wednesday, February 18, 2009

Syntax Highlighter in blogger for source code publishing

If you are new to blogger and you may not be happy with your source code snippets' appearance when published. I have faced the similar issue and here I shall explain how easy to solve it. I am now using Syntax Highlighter for source code publishing in my blog for code highlighting. For a sample please see how this post looks with source code highlighted. Once you implement source code highlighting with Syntax Highlighter viewers or readers can see your code with a pretty cool look, then they have options like view plain code, print code etc. So start making your code snippets in blogger attractive with Syntax Highlighter, here are the steps
  • Step 1: You may need to download and host Syntax Highlighter's .js scripts to some where at web and make it accessible. If you dont have an option to host over web you can use mine(shown in the step 3).
  • Step 2: Log in to blogger and take Layout. Select Edit HTML in the Layout tab now you can see Edit Template with html of your template.
  • Step 3: In the Edit Template search for /head and add the below code just before the /head. If you have hosted syntax highlighter scripts to some page you can use that address instead of mine.
<link href='http://rinuraj4u.googlepages.com/SyntaxHighlighter.css' rel='stylesheet' type='text/css'>
<script language='javascript' src='http://rinuraj4u.googlepages.com/shCore.js'>
<script language='javascript' src='http://rinuraj4u.googlepages.com/shBrushCSharp.js'>
<script language='javascript' src='http://rinuraj4u.googlepages.com/shBrushPhp.js'>
<script language='javascript' src='http://rinuraj4u.googlepages.com/shBrushJScript.js'>
<script language='javascript' src='http://rinuraj4u.googlepages.com/shBrushJava.js'>
<script language='javascript' src='http://rinuraj4u.googlepages.com/shBrushVb.js'>
<script language='javascript' src='http://rinuraj4u.googlepages.com/shBrushSql.js'>
<script language='javascript' src='http://rinuraj4u.googlepages.com/shBrushXml.js'>
<script language='javascript' src='http://rinuraj4u.googlepages.com/shBrushDelphi.js'>
<script language='javascript' src='http://rinuraj4u.googlepages.com/shBrushPython.js'>
<script language='javascript' src='http://rinuraj4u.googlepages.com/shBrushRuby.js'>
<script language='javascript' src='http://rinuraj4u.googlepages.com/shBrushCss.js'>
<script language='javascript' src='http://rinuraj4u.googlepages.com/shBrushCpp.js'>
  • Step 4: Now search for /html tag in the Edit Template and add the below code just before the /html tag.
<script language='javascript'>
dp.SyntaxHighlighter.BloggerMode();
dp.SyntaxHighlighter.HighlightAll('code');
</script>
  • Step 5: Save your template now.
  • Step 6: Now for highlighting your code snipetts, take Edit Html of your posts and embed code with in suitable tags given below,
<pre name="code" class="Cpp">
... some code here ...
</pre>
For a list of supported languages and class names to be used for syntax highlighter see here.

[VC++] Accessing taskbar from your program & do operations

Are you interested in accessing windows taskbar and its child programs in your program? It's an easy thing; you may know that "Shell_TrayWnd" is the class name of the windows taskbar. You can use FindWindow() for obtaining handle to taskbar and you can get its child windows by using EnumChildWindows() or by explicitly get the window handle specifying the class name in FindWindowEx(). I shall demonstrate how to show/hide taskbar and its child windows programmatically.

Show/Hide Windows Taskbar

// Get the task bar window
HWND hSysTrayWnd = ::FindWindow( "Shell_TrayWnd", 0 );
// Toggle the show or hidden status
if( ::IsWindowVisible( hSysTrayWnd ))
{
::ShowWindow( hSysTrayWnd, SW_HIDE );
}
else
{
::ShowWindow( hSysTrayWnd, SW_SHOW );
}
Show/Hide System tray child window
// Get the shell tray window
HWND hSysTrayWnd = ::FindWindow ("Shell_TrayWnd", 0 );
if( hSysTrayWnd )
{
// Get the tray notification window
HWND hTrayNotifyWnd = ::FindWindowEx( hSysTrayWnd, 0, "TrayNotifyWnd", 0 );
if( hTrayNotifyWnd )
{
// Hide the tray notification window if shown or show if hidden
if( ::IsWindowVisible( hTrayNotifyWnd ))
{
::ShowWindow( hTrayNotifyWnd, SW_HIDE );
}
else
{
::ShowWindow( hTrayNotifyWnd, SW_SHOW );
}
}
}
Show/Hide System Clock
// Get the shell tray window
HWND hSysTrayWnd = ::FindWindow( "Shell_TrayWnd", 0 );
if( hSysTrayWnd )
{
// Get the tray notification window
HWND hTrayNotifyWnd = ::FindWindowEx( hSysTrayWnd, 0, "TrayNotifyWnd", 0 );
if( hTrayNotifyWnd )
{
// Get the tray clock window
HWND hTrayClockWnd = ::FindWindowEx( hTrayNotifyWnd, 0, "TrayClockWClass", 0);
if( hTrayClockWnd )
{
// Hide the tray clock if shown or show if hidden
if( ::IsWindowVisible( hTrayClockWnd ))
{
::ShowWindow( hTrayClockWnd, SW_HIDE );
}
else
{
::ShowWindow( hTrayClockWnd, SW_SHOW );
}
}
}
}
Show/Hide Start button
// Get the shell tray window
HWND hSysTrayWnd = ::FindWindow( "Shell_TrayWnd", 0 );
if( hSysTrayWnd )
{
// Get the start button
HWND hStartBtn = ::FindWindowEx( hSysTrayWnd, 0, "Button", "start" );
if( hStartBtn )
{
// Hide the start button if shown or show if hidden
if( ::IsWindowVisible( hStartBtn ))
{
::ShowWindow( hStartBtn, SW_HIDE );
}
else
{
::ShowWindow( hStartBtn, SW_SHOW );
}
}
}

[VC++] Programmatically starting/stoping screensaver

For starting windows screen saver send WM_SYSCOMMAND message to your own window with parameter SC_SCREENSAVE

PostMessage( WM_SYSCOMMAND, SC_SCREENSAVE );

For stopping windows screen saver - use SystemParametersInfo() for knowing whether screen saver is running or not and if running close the foreground window.

if( ::SystemParametersInfo( SPI_GETSCREENSAVERRUNNING,0,&bSaver,0 ))
{
if( bSaver )
{
::PostMessage (::GetForegroundWindow(), WM_CLOSE, 0L, 0L);
}
}

Tuesday, February 17, 2009

[VC++] Adding icon to system tray

Here is how to create a tray icon for your application and showing system tray menu. For this you need to add an icon to the system tray using Shell_NotifyIcon() and you need to handle the tray message for the added icon. Below is the code for adding tray icon and showing a menu saying Test Tray Icon on clicking the tray icon.
Modify dialog class header creating a member variable for system tray menu and adding declaration of shell tray icon message handler.

protected:
...
afx_msg HRESULT OnSystemTrayIconClick( WPARAM wParam_i, LPARAM lParam_i );

private:
...
CMenu m_TrayMenu;

Modify dialog class Cpp file adding global constants for tray icon message handling and tray icon id

const UINT SHELL_TRAY_ICON = 2001; // Shell Tray icon ID
const UINT SHELL_TRAY_MSG = (WM_APP+2000); // Message name for tray icon messages
const UINT SHELL_TRAY_TEST_ID = 2100; // ID of shell tray menuitem

Modify dialog class Cpp file adding tray icon adding code in OnInitdialog

void CSampleDlg::OnInitDialog()
{
...
NOTIFYICONDATA stNotifyIconData;
stNotifyIconData.cbSize = sizeof( NOTIFYICONDATA );
stNotifyIconData.hWnd = GetSafeHwnd();
stNotifyIconData.uID = SHELL_TRAY_ICON;
stNotifyIconData.uFlags = NIF_MESSAGE NIF_ICON NIF_TIP;
stNotifyIconData.uCallbackMessage = SHELL_TRAY_MSG;
stNotifyIconData.hIcon = AfxGetApp()->LoadIcon( IDR_MAINFRAME );
strncpy( stNotifyIconData.szTip, "TestShellTrayIcon",sizeof"TestShellTrayIcon"));
Shell_NotifyIcon( NIM_ADD, &stNotifyIconData );
m_TrayMenu.CreatePopupMenu();
m_TrayMenu.InsertMenu( 0, MF_BYCOMMAND|MF_POPUP,SHELL_TRAY_TEST_ID, "Test Tray Icon" );
return TRUE;
}

Add entry to message map for mapping tray icon message

BEGIN_MESSAGE_MAP( CSampleDlg, CDialog )
...
ON_MESSAGE ( SHELL_TRAY_MSG, OnSystemTrayIconClick )
END_MESSAGE_MAP()

Now implement the tray icon message handler which will handle mouse LButton and RButton down by showing a menu

HRESULT CSampleDlg::OnSystemTrayIconClick( WPARAM wParam_i, LPARAM lParam_i )
{
switch( wParam_i )
{
case SHELL_TRAY_ICON:
{
switch( lParam_i )
{
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
{
POINT CurPos ;
GetCursorPos( &CurPos );
SetForegroundWindow();
TrackPopupMenu( m_TrayMenu, TPM_LEFTBUTTON, CurPos.x, CurPos.y, 0, GetSafeHwnd(), 0 );
PostMessage( WM_NULL, 0, 0 );
}
break ;
}
}
break ;
default:
OutputDebugString ("invalid icon id from tray\n");
break ;
}
return TRUE ;
}

Monday, February 16, 2009

[VC++] Getting process name from Process ID

It is easy to obtain the process name from a Process ID.

  • Open the process with Process ID using OpenProcess()
  • Enumerate the loaded modules using EnumProcessModules()
  • Take the first module handle retrieved in the previous step and get the module name using GetModuleBaseName()

See the below code executing the above steps and how to obtain the process name using PID.

HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
FALSE, dwPID_i );
if( hProcess )
{
char szProcessName[MAX_PATH];
HMODULE hMod;
DWORD dwNeeded;
if( EnumProcessModules( hProcess,
&hMod,
sizeof(HMODULE),
&dwNeeded ))
{
if( GetModuleBaseName( hProcess,
hMod,
szProcessName,
sizeof( szProcessName )))
{
// Show the process name
MessageBox( szProcessName );
}
}
CloseHandle( hProcess );
}
Include psapi.h and link psap.lib for getting these APIs. Above program when slightly modified can be used to obtain all the loaded modules by the process, for this you need to specify a HMODULE array to EnumProcessModules() and loop GetModuleBaseName() for each item of the HMODULE obtained.