Archive for the ‘Visual C++’ 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.

Passing pointer of class member functions to Windows API

Tuesday, November 20th, 2007

I was developing a small utility in C++, and was using the classes to make my program easy to read and maintain (we all know OOP is better than structured approach most of the time). In one of my class member function, I needed to create a new Window and thus need to populate the WNDCLASSEX structure. Now here is the problem, one of the parameters of this structure contains a function pointer (Windows Callback Procedure). I tried to pass the member function to this, but as I was expecting, I kept getting the compiler error. One dirty option was to make a normal function in that class file and pass its pointer to this call, but I didn’t want to mess my coding with classes and C style functions.

A quick search on Google, and I found the answer (and a solution too). The problem is that member functions also pass a hidden implicit pointer to the class object (this pointer), making the pointer to this function type different and of course OS APIs have no knowledge of how to pass this (unless Windows APIs are written from scratch to support OOP style). The simple solution was to just declare a static member of the class and pass it as parameter. The reason why this works is that in case of state functions, no implicit “this” parameters is passed i.e. the type of member function pointer matched with declared type.

A basic problem with this approach is that static members can’t access the non-static members. Once you know the inner working details, this limitation is obvious (how can it access class data without an object pointer?). There are two workarounds for this, one is to explicitly pass “this” as parameter to the static functions and in the static function use that base class object pointer to access the members. If that’s not possible (in case of API typecast), then one can declare a global pointer to the current object and use that from the static functions (not the best technique, but will work).

If you want to learn more, here are two related very good posts:

http://support.microsoft.com/kb/q102352/

http://www.parashift.com/c++-faq-lite/pointers-to-members.html

 

Embedding DLL and binary files in the Win32 Executable

Wednesday, November 7th, 2007

Embedding DLL and binary files in the Executable applications Though for most of the cases, it’s recommended keep the resources and other libraries separate from the main executable. This makes the main application executable size small, and thus that application will take less memory on load and will load/unload the external resources as required. Yet sometimes, it makes sense to append the external files as part of executable. A popular example of this is self extracting installer. The basic technique behind this whole process is simple. Here is what needs to be done:

Write a resource script file which provides path to the external files you want to append in the final resource object.

  • Use the Resource Compiler to build a RES file from the above script.
  • Bind the RES file with executable.
  • Call the APIs to extract and load the resources from the executable memory space at run-time.
  • First one to add a Resource Script file in the executable project. Here is a sample code to define the binary resource in
  • the resource script file
IDR_TBEHK_DEBUG BINARY MOVEABLE PURE "..\\debug\\TaskbarExtHk.dll"

Please note that “IDR_TBEHK_DEBUG” is user defined constant and must be declared before this line. Here is how I have defined this at top:

#define IDR_TBEHK_DEBUG130

There is catch here. Some of the files are conditional and thus we may need some checks on which version of file to include. One way of doing this is to use the standard C++ compiler directives (these syntax is almost same for Resource Compiler):

#ifdef _DEBUG
IDR_TBEHK_DEBUG BINARY MOVEABLE PURE "..\\debug\\TaskbarExtHk.dll"
#else// _DEBUG
IDR_TBEHK_RELEASE BINARY MOVEABLE PURE "..\\release\\TaskbarExtHk.dll"
#endif

But wait, we also need to define the value for the _DEBUG symbol (the one defined for C++ project will not work here, as this file is read by resource compiler and is a totally different context). In Visual Studio, you can easily define these Resource preprocessor directives in the project properties. Simply add “_DEBUG” for the DEBUG configuration and it will add the conditional embedding of the correct version.

Another simple option for including binary libraries is to change the project settings is to set a single output folder for both Debug and Release configurations and then just include that single file. Once the RC file is ready, it can be compiled to RES file using the Resource Compiler. Here is a sample command line for this: rc.exe /fo”Release/TaskbarExt.res” “.\TaskbarExt.rc” If you are using Visual Studio, then it will automatically call this for you and will build the RES file and will also bind it with executable.

The next big part is finding and loading the resource from the executable. Here is a sample code to do this:

bool ExtractResource(const HINSTANCE hInstance, WORD resourceID, LPCTSTR szOutputFilename)
{
	bool bSuccess = false;
	try
	{
		// First find and load the required resource
		HRSRC hResource = FindResource(hInstance, MAKEINTRESOURCE(resourceID), _T("BINARY"));
		HGLOBAL hFileResource = LoadResource(hInstance, hResource);
 
		// Now open and map this to a disk file
		LPVOID lpFile = LockResource(hFileResource);
		DWORD dwSize = SizeofResource(hInstance, hResource);
 
		// Open the file and filemap
		HANDLE hFile = CreateFile(szOutputFilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
		HANDLE hFilemap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwSize, NULL); LPVOID lpBaseAddress = MapViewOfFile(hFilemap, FILE_MAP_WRITE, 0, 0, 0);
 
		// Write the fileCopyMemory(lpBaseAddress, lpFile, dwSize);
 
		// Unmap the file and close the handles
 
		UnmapViewOfFile(lpBaseAddress);
		CloseHandle(hFilemap);
		CloseHandle(hFile);
	}
	catch(...)
	{
		// Ignore all type of errors
	}
return bSuccess;
}

Once you are done with resource, you can remove it by calling the DeleteFile API.
Simple is that! Isn’t it?