Wednesday, December 30, 2009

How to pick folder with OpenFileDialog?

OpenFileDialog allows selection of files, and FolderBrowserDialog allows selection of folders. For various legitimate reasons, I prefer to use OpenFileDialog for folders instead. The question is, how?

Overriding FileDialog.HookProc to obtain the dialog handle to change the dialog behavior is my first attempt, but it is immediately obvious that OpenFileDialog is sealed and cannot be inherited, and I don't feel like reimplementing everything with GetOpenFileName. So an alternative way to get the dialog handle is to cook up a dummy window (as in FileDialog > DummyOwner > RealOwner) and watch for WM_ACTIVATE in the overriden WndProc. As always, be extra careful when playing with window activation.

Now, with the dialog handle, and later the child notification dialog handle, I can do pretty much what I want. I can hide and rename various controls on the dialog, handle BN_CLICKED to accept folder, and more.

A few gotchas include having to do manual marshaling using COM task memory, but no big deal.

Next up is the Vista version.

Friday, October 30, 2009

What good is new TTS voice if you are unable to select?

Some people purchase new Text-to-Speech voices to spice up their home automation or screen reader. Or they just want a divorce of Sam or Anna. Regardless, one of the problems when moving to 64-bit Windows is, those voices designed for 32-bit system can't be selected!

Loss of investment? Not yet! While it's true that 64-bit applications can't use those voices, and 64-bit Control Panel Speech Applet can't see them, the 32-bit applet can set one of those as the default voice for 32-bit applications. On Server 2008 R2, its at C:\Windows\SysWOW64\Speech\SpeechUX\sapi.cpl.

Sometimes Microsoft Anna may insist to stay with you. She will if you have used TTS in any 64-bit application.

Now, what if you use TTS in JScript or VBScript in Windows Script Host? Simply run the script in the 32-bit version of wscript.exe or cscript.exe in C:\Windows\SysWOW64.

Monday, October 19, 2009

Where is Windows Calendar?

One of the useful applications removed in Windows 7/Server 2008 R2 is the Windows Calendar. I especially missed it because I never want any email/calendar bundle like Windows Live Mail. Here is how to get it back:
  • Copy the Windows Calendar program folder from an earlier Windows installation to your new Windows 7/Server 2008 R2
  • Optionally import your existing iCalendar (.ics) file.
Easy! Isn't it? Now to get the reminder feature to work:
  • Create a WindowsCalendar folder in C:\Windows\System32\Tasks\Microsoft\Windows (or whereever that is in your install)
  • Set the security on that folder to NOT inherit but add existing parent permissions, and to allow Authenticated Users to create files/folders, write attributes/extended attributes, and read permissions.
  • Optionally remove the permissions for Local Service and Network Service, and to change the owner to SYSTEM
Done!

Wednesday, September 9, 2009

What's up with the Server 2008 desktop graphics bugs?

When Desktop Experience is installed, Server 2008 provides similar visuals as Vista. One thing I noticed though, is that the desktop doesn't act the same as in Vista:
  1. The drop shadow on icon text may disappear on hover.
  2. The selection rectangle has dotted outline as in Windows XP* instead of translucent.
  3. The selected icons don't have translucent background.
It turns out that the desktop SysListView32 control is styled differently. So now I have a simple startup program that finds the Progman window, then the SHELLDLL_DefView window, then the SysListView32 window, and adds the missing extended styles LVS_EX_DOUBLEBUFFER, LVS_EX_TRANSPARENTBKGND, and LVS_EX_TRANSPARENTSHADOWTEXT.

A more robust solution would create a message-only window in the background, listen for the TaskbarCreated message, and reapply the styles to the recreated SysListView32.

These would take care of 1 and 2, but not 3. May be a call to SetWindowTheme would work, but I haven't tried.

* Similar techniques can be used on XP to get the translucent selection rectangle, but will clear the wallpaper.

Why doesn't WTSConnectSession work when I first tried it?

Because the MSDN documentation on WTSConnectSession is wrong.

If you follow it:

Parameters

LogonId [in]

The logon ID of the current session, where the user of that session has permissions to connect to an existing session.

TargetLogonId [in]

The logon ID of the session that you want to connect to.


And call the function this way, your program will merely disconnect your current session with ERROR_NOT_CONNECTED, leaving you to wonder if the execution of the program stops in the middle of the call.

Once you find out that WTSConnectSession is just a wrapper for the undocumented WinStationConnect, which exists in earlier versions of Windows than its wrapper, you should realize that the first two parameters as documented are swapped.

Friday, February 27, 2009

What's the scope of window handles?

Someone stated (though I've yet to find any supporting MSDN documents) that window handles are global to all processes belonging to the same window station. Yet, if you somehow obtain a handle to a window belonging to another desktop, and try to send messages to it, SendMessage may fail with ERROR_INVALID_WINDOW_HANDLE. Why?

If window handles are truly global, then, say, thread 'a' on desktop 'A' should be able to use handles from thread 'b' on desktop 'B', assuming that both desktops belong to the same window station, right? It seems that some magic needs to happen for the handle table to be visible to other desktops, that is, thread 'a' needs to obtain a handle to desktop 'B' with read access.

It appears logical, but needs to be clearly documented!