Sie sind auf Seite 1von 4

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 exten
t 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 f
ile and window management functions.
A feature tour is also available online. It is recommended for both new and exp
erienced user!
Version 3.1 Blurbs
The WndTabs source base is quite large (almost 30,000 lines, not including the e
xtension 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 wo
rld of installation.
Versions 3.0x of WndTabs were shipped using an MSI installer I created with Inst
allShield. As good or as bad as InstallShield is as a development platform, the
re is something that it cannot change, namely MSI, the underlying technology. M
SI, for those who don't know, is Microsoft's installer technology/installation p
latform. 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 i
nstallation" when in fact there is no such policy. The fix in this case is remo
ving an even more cryptic registry entry (HKEY_CLASSES_ROOT\Installer\Products\A
7AC1985CAF0BB64FB37E18FB2A89724 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 m
ore issues I frequently had to deal with.
Yet another brain dead feature of MSI is that the user is required to keep the s
ource 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 re
lated 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 i
nstaller, 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 vehicl
e, 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 reall
y 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 la
nguage. If your product is intended for the NT class of operating systems, Unic
ode is the way to go.
How It's Done
Localization is based mostly on a wonderful little MFC function called AfxSetRes
ourceHandle(). MSDN is a little vague about the usefulness of this function, gi
ving the following description:
Use this function to set the HINSTANCE handle that determines where the defa
ult resources of the application are loaded.
In essence, AfxSetResourceHandle() lets you instruct MFC to grab all the resourc
es from a place other than your main executable/DLL. For instance, if you have
a string table with the following entry:
Hide Copy Code
IDS_WELCOME
"Welcome"
You can create a resource DLL (say French.dll) with the following string table e
ntry
Hide Copy Code
IDS_WELCOME
"Bienvenue"
You would then use AfxSetResourceHandle() to grab the French string as needed:
Hide Copy Code
CString cStr;
cStr.LoadString(IDS_WELCOME); // cStr is now "Welcome"
// make the French resources the default resources
AfxSetResourceHandle(AfxLoadLibrary("French.dll"));
cStr.LoadString(IDS_WELCOME); // cStr is now "Bienvenue"
It Gets Better
As I said, MFC will use the specified resource DLL whenever it looks for a resou
rce. 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 unfortuna
te, 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 t
hey 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 AfxSetResourc
eHandle(), 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. An

y bitmap with English text will still be in English (though given time, those wo
uld be easy to address as well).
One large area that was not addressed was the help file. Translating the help f
ile 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 chang
es would also have to be put in place, as I'd have to upgrade my HTML help subsy
stem to support multiple help files. I decided that if the translation packs ar
e a run-off success, that I'd invest time in localized help file in the next rel
ease.
Internet Keyboards
One nice new feature in v3.10 is support for Internet keyboards. These keyboard
s feature extra keys such as back, forward, stop etc. Diligent user Frank Fesev
ur 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 inp
ut 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:
Hide Shrink
Copy Code
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
...
//}}AFX_MSG_MAP
ON_MESSAGE(WM_APPCOMMAND, OnAppCommand)
END_MESSAGE_MAP()
...
LRESULT CMainFrame::OnAppCommand(WPARAM wParam, LPARAM lParam)
{
// see which special button was pressed
const int cmd = GET_APPCOMMAND_LPARAM(lParam);
switch (cmd)
{
case APPCOMMAND_BROWSER_BACKWARD:
{
// do something
return TRUE; // return TRUE to indicate that we processed the butto
n
}
case APPCOMMAND_BROWSER_FORWARD:
// ....
case APPCOMMAND_BROWSER_STOP:
// ....
}
// This was a button we don't care about - return FALSE to indicate
// that we didn't process the command
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 Intelli
mouse is one of them.

The WndTabs Source Code


WndTabs is provided with full source code. Aside from the topics discussed abov
e, 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 Int
ernet users.
Small tricks of the trade:
Dialogs that change at runtime.
Storing your configuration in the registry.
And more...

Das könnte Ihnen auch gefallen