Archive for the ‘Win32 API’ Category

Windows Desktop ListView Handle

Saturday, January 19th, 2013

I have been using a utility function in my TaskbarExt application for years to get the current Desktop ListView window handle (SysListView32 to be exact) to show/hide the icons depending on user preferences.

This has worked well for years, but recently I enabled the Windows Desktop wallpaper rotation, and I noticed that this function randomly stops working. On debugging the issue, I found that when the wallpaper rotation is enabled, instead of loading the “SHELLDLL_DefView” window in the “Progman”, Windows was loading under the “WorkerW” window. BTW, the Spy++ Tool was great help in debugging all this.

Once I know what’s going on, the fix was quite easy. In case your are running into similar issues, here is the sample code which works for me:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
HWND GetDesktopListViewHWND()
{
  HWND hDesktopListView = NULL;
  HWND hWorkerW = NULL;
 
  HWND hProgman = FindWindow(_T("Progman"), 0);
  HWND hDesktopWnd = GetDesktopWindow();
 
  // If the main Program Manager window is found
  if (hProgman)
  {
	// Get and load the main List view window containing the icons (found using Spy++). 
    HWND hShellViewWin = FindWindowEx(hProgman, 0, _T("SHELLDLL_DefView"), 0);
    if (hShellViewWin)
      hDesktopListView = FindWindowEx(hShellViewWin, 0, _T("SysListView32"), 0);
	else
		// When this fails (happens in Windows-7 when picture rotation is turned ON), then look for the WorkerW windows list to get the 
		// correct desktop list handle.
		// As there can be multiple WorkerW windows, so iterate through all to get the correct one
		do
		{
			hWorkerW = FindWindowEx( hDesktopWnd, hWorkerW, _T("WorkerW"), NULL );
			hShellViewWin = FindWindowEx(hWorkerW, 0, _T("SHELLDLL_DefView"), 0);
		} while (hShellViewWin == NULL && hWorkerW != NULL);
 
		// Get the ListView control
		hDesktopListView = FindWindowEx(hShellViewWin, 0, _T("SysListView32"), 0);
  }
 
  return hDesktopListView;
}

Hopefully the comments should explain what’s going on very well. But if you still have any questions or suggestions, please do share with me.

On a side note, any wallpaper with icons turned off looks so beautiful. So I would recommend give this a try. So, if you are a programmer, which you most probably are if are reading so far, then better go ahead and implement this yourself. It will be a nice little utility. If however, busy with some other stuff, you can try my TaskbarExt application and get this in action quickly.

Unicode Programming In Microsoft Visual C/C++

Monday, September 27th, 2010

If you program Unicode applications using Microsoft Visual C/C++ compiler, then you most probably use the TCHAR strings. While using TCHAR strings is very easy, one of the most common problem for me, after a years of ANSI string experience, is to find a correct C/C++ string function to do the same job as I used to do for the ANSI string.

For example, for ANSI string, we use strlen, but for the TCHAR strings, it’s _tcsclen. Though these TCHAR strings functions use a specific naming convention, and one can easily figure out the corresponding function equivalent of ANSI function, but it does require a hit and try. When doing a search today on Google, I found a wonderful reference which I not only bookmarked, but I would like to share with others too. So, here it’s:
http://www.inwa.net/~frog/tcharConversionChart.html

While we are discussing Unicode, here is another wonderful web resource regarding Internationalization and Localization:
http://www.i18nguy.com/

Command Line Arguments Processing in Win32 Application

Wednesday, September 22nd, 2010

It’s common for Windows executable to get and process the additional parameters from the command line. This way you can pass any custom actions when launching an application i.e. open a particular file, print a file, control the application visibility state, etc.

If you are working on C/C++ console application, then you can easily get all the passed command line parameters as the main function arguments. Something like:

1
2
3
4
int main (int argc, char *argv[])
{
    return 0;
}

Here is a nice tutorial for arguments processing for console application:
http://www.crasseux.com/books/ctutorial/argc-and-argv.html

But if you are working in Win32 Windows application, your main entry point may look like this:

1
2
3
4
5
6
7
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
    // Windows initialization code goes here
}

As you can see that in this case, you get a third command line parameter which contains command line string. One straight forward option is to parse all the parameters in lpCmdLine parameter and then use these. This is a bit hassale, but does the job. The good news is that in WinMain function, you can also access two global variables named __argc and __argv which works exactly like argc and argv in console application i.e. __argc contains the count of the parameters passed, and __argv is string array containing those parameters string values.

There is one small catch though (I wasted half an hour to figure this out), and that’s if you are running in Unicode mode, then the __argv will always be NULL, and instead you should use the __wargv for the command lines parameter. Here is the conditional code I used for command line processing:

1
2
3
4
5
6
// Process any command line arguments
#if (UNICODE)
   bool bContinue = ProcessCommandLineArg (__argc, __wargv);
#else
    bool bContinue = ProcessCommandLineArg (__argc, __argv);
#endif

Spent few hours in figuring and making all this works, but in the end it was a fun learning and coding.

Forcing just one instance of an Application to execute at a time

Monday, July 14th, 2008

When developing a desktop application, it’s often required that only one instance of application should be executable at a time. This is usually implemented in different ways depending on Language/Tools you are using to build the application.
Some common techniques used are either using the Mutex or getting a list of active processes and making sure that a process with same executable name is not already running. Here are the different articles which all discuss a bit different techniques to achieve the same goal:
http://dotnet.org.za/ernst/archive/2004/07/20/2887.aspx
http://www.codeproject.com/KB/cs/CSSIApp.aspx
http://www.ddj.com/windows/184416856
http://audiprimadhanty.wordpress.com/2008/06/30/ensuring-one-instance-of-application-running-at-one-time/

If you are developing your application in Visual C++, then there is a relatively simple and straight forward method. The trick is that you declare a shared segment for you executable and you set a variable in the shared data segment when the first instance of the application is run. When you try to run again the same application, it also shares the same data segment and thus you can check the value of the variable to see if another instance of application is running or not.
For this you can add the following code at top of your executable.

1
2
3
4
5
6
// This share data segment section is used to make sure that only instance of the application
// should be running at a time
#pragma data_seg(".singleInstance")
HWND g_hWnd = NULL;
#pragma data_seg()
#pragma comment(linker, "/section:.singleInstance,rws")

Then you can check and set the g_hWnd in your Instance initialization method.

1
2
3
4
5
6
7
8
// Check if another instance of the application is already running
if (g_hWnd)
{
	// Post message to bring the main window to front
 
	// Another instance is already running, so quit.
	return false;
}

Don’t forget to assign the “g_hWnd” variable the reference of main window handle after you create that window. Credit for this technique goes to:
http://www.codeguru.com/cpp/misc/misc/applicationcontrol/article.php/c3763/

Restore Notification Area Icon after Explorer Crash

Monday, July 14th, 2008

If you are writing any application which adds an icon to the Taskbar notification area, it’s recommend to handle the “WM_TASKBARCREATED” the message sent by explorer. This message is sent by explorer when it’s creating the taskbar. As after crash explorer doesn’t remember the original notification icons, you should handle this message and then re-register your application notification icon.

To capture this message, you must first register it like this:

1
const static UINT WM_TASKBARCREATED = ::RegisterWindowMessage(__T("TaskbarCreated"));

Once it’s registered, you should handle this in your Windows Callback Procedure to re-add the icon for your application in the notification area. Something like this:

1
2
3
4
5
6
// Check if the Taskbar is just being created. This message is broadcast by the Explorer
// when it's launched (after any crash)
if (message == WM_TASKBARCREATED)
{
	// Add the code to re-add your application in the notification area.
}

Simple, but yet effective. What do you think?