The latest versions of these downloads can be found at www.wndtabs.com/downloads
Overview
Most people know what WndTabs is by now. If you don't, then I suggest
you visit the overview page, which also
highlights the new features in every release.
In general, WndTabs is an add-in for Visual C++ 5/6 and eVC 3 (and to some
extent eVC4 *)
which adds a much needed tab strip to the Visual Studio MDI workspace. The
tabs are much more than a window switching vehicle, exposing many useful file
and window management functions.
A feature tour is also
available online. It is recommended for both new and experienced user!
Version 3.1 Blurbs
The WndTabs source base is quite large (almost 30,000 lines, not including the
extension module) and is too big to cover in one article. Instead, I would
like to focus on the things that were added during the latest release.
The Installer
Though not a programmer topic per se, I wanted to share my experiences in the world of installation.
Versions 3.0x of WndTabs were shipped using an MSI installer I created with InstallShield.
As good or as bad as InstallShield is as a development platform, there is
something that it cannot change, namely MSI, the underlying technology. MSI,
for those who don't know, is Microsoft's installer technology/installation platform. It supports
advanced features such as
install on demand (as you see in Office) and auto-healing as well as the more
trivial installation tasks.
I'll spare you the gorgy details, and go straight to the bottom line: For
small, web based software products, MSI is unsuitable. Here are
some reasons why (in no particular order):
- It's buggy. There's no pretty way of saying it. And it's
cryptic. A user can get an error such as "The system
administrator has set policies to prevent the installation" when in
fact there is no such policy. The fix in this case is removing an even
more cryptic registry entry (
HKEY_CLASSES_ROOT\Installer\Products\A7AC1985CAF0BB64FB37E18FB2A89724
for WndTabs). That's not good for either you or your users.
Many other bugs exist, and I won't list them all here. If you are curious,
have a look at the installation
FAQ (questions marked as "Versions 3.0x") for some more issues
I frequently had to deal with.
- Yet another brain dead feature of MSI is that the user is required to keep
the source installation package in order to uninstall. This is fine if
your product ships on a CD (the installer asks you to pop in the CD, which
is fine). But if you downloaded the installer from the web, then
deleted or moved it (which is a common thing users do), you will not be able
to uninstall the software. On a related note, this issue also
affects "patch" installations.
- Minor complaint - authoring anything but the simplest installers is a
nightmare in MSI. This, even with tools like InstallShield at your
side.
As you can guess, the support nightmare eventually drove me to use a different
installer, one which I am much more pleased with. Again, MSI is not
necessarily evil in general, but I suggest that if you choose it as your
installation vehicle, make sure you do your homework and know what you're doing.
User Interface Localization - WndTabs in Multiple Languages
One of the biggest changes in WndTabs 3.10 involved the addition of
localization capabilities. This might not be a big feature for us English speakers
(as end users at least). However, with the increasingly global
economy, many of us will find ourselves with requirements for a multi-lingual user
interface.
First off, I'd like to mention that WndTabs still supports Win9x, so it
doesn't use Unicode (and yes, I know there's a version of Unicode for Win9x, but
I really don't need another support nightmare). A user
downloading a language pack in his/her language would be required to use the
appropriate code page for their language. If your product is intended for
the NT class of operating systems, Unicode is the way to go.
How It's Done
Localization is based mostly on a wonderful little MFC function called AfxSetResourceHandle()
.
MSDN is a little vague about the usefulness of this function, giving the
following description:
Use this function to set the HINSTANCE
handle that determines where the default resources of the application are
loaded.
In essence, AfxSetResourceHandle()
lets you instruct MFC to grab all the
resources from a place other than your main executable/DLL. For instance,
if you have a string table with the following entry:
IDS_WELCOME "Welcome"
You can create a resource DLL (say French.dll
) with the following string
table entry
IDS_WELCOME "Bienvenue"
You would then use AfxSetResourceHandle()
to grab the French string as
needed:
CString cStr;
cStr.LoadString(IDS_WELCOME);
AfxSetResourceHandle(AfxLoadLibrary("French.dll"));
cStr.LoadString(IDS_WELCOME);
It Gets Better
As I said, MFC will use the specified resource DLL whenever it looks for a
resource. But at least for one resource (strings), it will automatically
"fall-back" to your executable/DLL if it can't find something in the
resource DLL. In our previous example, assume that IDS_WELCOME
wasn't defined in the French DLL. In that case, the final LoadString()
will result in cStr="Welcome"
(MFC won't find IDS_WELCOME
in the resource DLL, so it will just grab it from the main resources). Don't
expect this behavior for bitmaps or dialogs though. This is unfortunate,
because it means that (unless you want to spend a lot of time coding around
this), you will need to include all your bitmaps in the language DLLs, even if
they are the same as the bitmaps in the main resources.
Loading Resources Yourself
One last note. If you want to load resources manually after using AfxSetResourceHandle()
,
you should use the AfxGetResourceHandle()
function to get the
pointer to the active resource DLL.
What Was (and Was Not) Translated
For this release, only the dialogs, menus and string tables were
translated. Any bitmap with English text will still be in English (though
given time, those would be easy to address as well).
One large area that was not addressed was the help file. Translating
the help file would require tremendous effort from the translators. These
are people who volunteer to translate WndTabs into their native language for
nothing more than a thank you (thanks guys!), and I didn't want to drown them in work.
Code changes would also have to be put in place, as I'd have to upgrade my HTML
help subsystem to support multiple help files. I decided that if the
translation packs are a run-off success, that I'd invest time in localized help
file in the next release.
Internet Keyboards
One nice new feature in v3.10 is support for Internet keyboards. These
keyboards feature extra keys such as back, forward, stop etc. Diligent
user Frank Fesevur suggested the feature and was kind enough to send me an MSDN
link. To sum up, these keyboard work through a new message call WM_APPCOMMAND
. An enhanced input device will send this message, with the
LPARAM value holding information such which special key was pressed and from
which device the message originated (see the note below). Here is some
sample code for handling this message:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
...
ON_MESSAGE(WM_APPCOMMAND, OnAppCommand)
END_MESSAGE_MAP()
...
LRESULT CMainFrame::OnAppCommand(WPARAM wParam, LPARAM lParam)
{
const int cmd = GET_APPCOMMAND_LPARAM(lParam);
switch (cmd)
{
case APPCOMMAND_BROWSER_BACKWARD:
{
return TRUE;
}
case APPCOMMAND_BROWSER_FORWARD:
case APPCOMMAND_BROWSER_STOP:
}
return FALSE;
}
One final note - only talking about keyboards is half the truth. Any
device can issue WM_APPCOMMAND
messages. For example, I'm sure that the
Microsoft Intellimouse is one of them.
The WndTabs Source Code
WndTabs is provided with full source code. Aside from the topics discussed
above, the code also demonstrates the following techniques:
- Writing DevStudio add-ins that handle events and export commands.
- Interfacing with other add-ins using the AddInComm library.
- "Stealing" events from other windows by using subclassing.
- Installing and using system message hooks (SetWindowsHookEx).
- Enumerating the shell namespace / full support for file context menus
including the elusive "Send To..." menu.
- Use of common controls (tabs, images, etc.)
- Use of the MFC template based collections (CTypedPtrArray, CTypedPtrList, etc.).
- Reusable components for HTML Help integration in MFC applications!
- Use MFC to access Internet files.
- Using language specific resource DLLs. NEW!
- Detect version updates over the net unobtrusively for both direct and
dialup Internet users.
- Small tricks of the trade:
- Dialogs that change at runtime.
- Storing your configuration in the registry.
- And more...
What's New
Below I list the new features and fixes in this release (3.10) and the
previous (3.05). You can find a full list version history list here.
Entries marked with
WndTabsExt
relate to features of the
WndTabs
Extension Module.
Version 3.10 (June 17, 2002)
- New Feature: Full support for localized menus and dialogs.
- New Feature: Copy File Name (without path) command added to Clipboard commands.
- New Feature: Support for Internet keyboards for tab cycling and other commands.
- New Feature: The middle mouse button can now be mapped to any WndTabs command.
- New Feature: Shift+Close button ("X") now does "Close All Except". WndTabsExt
- New Feature: Right click on Close button displays a context menu. WndTabsExt
- New Feature: Grouping of files from different directories can be constrained to just files from the same project.1 WndTabsExt
1 The freeware Workspace Whiz! Interface package must be installed for this feature to work.
- New Feature: Buttons on grouped tab can now be sorted. WndTabsExt
- New Feature: Added new commands for cycling through windows in Tab Order.
- Improvement: Grouping of files from different directories is more accurate. WndTabsExt
- Improvement: Greatly reduced flickering while single-stepping in the debugger.
- Bug Fixed: In rare conditions, some WndTabs commands could cause a crash if activated from a keyboard shortcut.
- Bug Fixed: Close button would still work when disabled from options dialog. WndTabsExt
- Bug Fixed: Closing a resource tab with the close button ("X") would close all resources. WndTabsExt
- Bug Fixed: Better handling of files with an ampersand ("&") in their name.
- Bug Fixed: The window limits functionality was broken with WndTabsExt enabled. WndTabsExt
- Bug Fixed: Loading of workspaces could cause WndTabs to hang if a previously open file was deleted.
- Other minor bug fixes.
Version 3.05 (June 19, 2001)
- New Feature: Close ("X") button for tabs on the advanced tab control.
WndTabsExt
- New Feature: Tabs without a group can now appear with a mini-toolbar, for consistent tab appearance.
WndTabsExt
- Bug Fixed: The prefix/suffix trim characters could not be set through the options dialog.
- Bug Fixed: Auto-row count feature caused problems when updating some tab styles in the options dialogs.
- Bug Fixed: WndTabsExt registration wasn't working on some systems.
WndTabsExt
Previous releases...
Note
Make sure to check out the WndTabs web site which is more likely to have updates and betas:
http://www.wndtabs.com