January/February 1999
Welcome to the penultimate year of the second millennium! Dr. GUI notes that next year (2000, the ultimate, or last, year of the second millennium), folks will be so happy about the upcoming new millennium (January 1, 2001, thank you very much) that they'll start celebrating a whole year early.
But the good doctor isn't happy about one aspect of this year's celebrations: Dr. GUI's really tired already of hearing over and over and over and over a certain song by the artist formerly known as Prince. Maybe it's time to turn off single song auto-repeat on the CD player (or break the switch).
In any case, who's going to have time to celebrate this year or next with all the Y2K problems, known and unknown, caused by things done and left undone? It's enough to make you want to take refuge in a confessional.
The good doctor happened across an article by Martha Stewart called "My Big Bet on the Net." (Newsweek, Dec. 7, 1998, www.newsweek.com/nw-srv/issue/23_98b/printed/us/st/ty0223_1.htm.) In it, she talks about how in 1994 she decided to do business on the Internet, integrated with her other businesses.
It got him thinking about how quickly the Internet has changed things. Who would have thought in 1994 that almost every TV and print advertisement would display a URL? That Dr. GUI's parents would surf the Web? That he could search the Web to find out about the shockingly short generation time of the two supposedly male Russian dwarf hamsters chez GUI that suddenly became six?
Behind the scenes, of course, is rapidly changing technology as the Web evolves from a set of static HTML pages to an interface to server-side databases, and, thankfully, new tools that make it easier to develop Web applications.
In the New Year, Dr. GUI looks forward to both more social and technological changes. It's an exciting time—and that's a very good thing.
Hi. This seems like an easy question:
How do I export the DevStudio editor formatting settings so that I can restore all my custom colors and so forth when I install VC++ on a new machine?
I haven't found any docs for this and poking around in RegEdit reveals way too much stuff that DevStudio has set that might screw up my new machine. So, exactly what keys should I export?
Thanks,
Robin Rowe
You're right to be cautious. Organ transplants, especially of registry keys, are tricky business. So, of course, you'll want to create a backup of your registry before you do this surgery. Because RegEdit doesn't support Undo, it's a very sharp scalpel indeed—but at least if you sever your computer's jugular vein with it, your backup copy can resuscitate the patient. (Don't try that on an operating table.)
To retain custom colors and fonts for another Visual C++ installation, you will have to import all or some of the following registry keys from your custom VC++ setup machine. The only difference between the key names in versions 5.0 and 6.0 is the version number in the name—I'll show you this once, then let you figure it out.
For Visual Studio 97, the keys you're looking for are all subkeys of:
HKEY_CURRENT_USER\Software\Microsoft\DevStudio\5.0
... and of:
HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0
…for Visual Studio 6.0. Not all of these keys will be present on every system—it depends on whether you customize your environment. (Dr. GUI tends not to customize specifically because it's so @#*&^$*! hard to move customizations around.)
If you search the registry, you'll see these keys under:
HKEY_USERS\S-1-5-21-124525095-708259637-1543119021-18193\Software\Microsoft\DevStudio\5.0
You can ignore the HKEY_USERS key, because importing the other keys automatically updates this one.
The Format key contains the settings for the custom colors and fonts used for the various windows that Visual C++ supports. You get to the UI for this in Visual Studio by selecting the Tools menu, clicking Options, then clicking the Format tab.
So, given this formula, the key name for Visual Studio 97 is:
HKEY_CURRENT_USER\Software\Microsoft\DevStudio\5.0\Format
For Visual C++ 6.0, it's:
HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\Format
The Layout key contains information on the custom menu bars, toolbars, and command buttons. Importing this key will ensure that the new installation retains all the customizations. (Note that the locations of these objects on the screen could be different, depending on the screen resolution.) It's the same as the preceding key except you replace Format with Layout.
The Text Editor
key has information on the tab settings for different file types. You can access the UI for these settings by selecting the Tools menu, clicking Options, then clicking the Tabs tab.
The Tools key contains information on the Tools menu item, including all the default tools that come with Visual C++ and the tools the user has added, along with their absolute paths. Note that you may have to update these paths correctly on the new machine.
The General key contains information on controlling the Window menu and ToolTips. The Graphic Editor key contains information on screen color.
Note that some keys store absolute path information. Make sure these paths are right for your new installation or Visual Studio won't behave as expected.
If this seems like a pain, it is: You may wish to not make changes to these keys through the registry but choose to do it manually from the Tools menu in your new Visual C++ installation instead.
You may also want to look at the following Knowledge Base articles: "How to Modify Windows Registry" (Q136393), and "INFO: RegClean 4.1a Description and General Issues" (Q147769). If you don't have Web access, look for the articles on your MSDN Library CDs or send e-mail to mshelp@microsoft.com with the article ID number on the subject line.
And if you're really interested in getting into the guts of the registry, you might want to read Inside the Registry for Microsoft Windows 95 by Gunter Born, published by Microsoft Press (http://mspress.microsoft.com/mspress/products/1039/).
One more thing: You didn't ask for it, but Dr. GUI's favorite Visual Studio customization is to make it play custom sounds for various events. Go to the Sounds applet in Control Panel and look under "Microsoft Developer" to see the sounds you can customize—they include Breakpoint Hit, Build Complete, Build Error, Build Warning, Error in Output, and Warning in Output. (DOH!) If you ask your favorite Web search engine to search on "WAV Files," you should find a lot of fun sounds to use.
I've been using the Windows Scripting Host (WSH) for a while and have found that it really doesn't like JScript, or maybe I'm overlooking something. I was hoping that an article in MSDN would have at least ONE sample that used JScript, but alas, none to be found.
So, the burning question: does JScript even work with the Windows Scripting host, and if so, how? All of the documentation in the Windows NT Option pack is in VBScript.
I'm not against using VBScript, but I have currently tasked myself to become fluent in JScript as well, and I wanted the practice. Are there any contraindications on prescribing JScript with the Windows Scripting Host?
The following code throws errors:
var ws;
ws = new ActiveXObject("WScript.Application");
// Won't work -- No ProgID
ws.Echo("Hello World."); // Won't work either, due to failure above
this.Echo("Hello World."); // no dice -- No property or method error
Echo("Hello World."); // Sorry Charlie, Object required.
Seems too simple to ask this question, but all of the documentation implies that the WScript object is provided by the wscript/cscript.exe's. JScript doesn't quite get it. I even went so far as troll the registry and view the Type Information with OleView (thanks Charlie Kindel!) and found an unregistered Interface ID for IWinScriptHostApp! The only ProgIDs available are for the Shell and Networking Interfaces. Truly the mystery grows further.
Kirk S. Kuzma
Dr. GUI prides himself on being able to speak to his patients in several computer languages, and is delighted to say that he and the Windows Scripting Host are equally fluent in Visual Basic Scripting Edition (VBScript) and JScript. (In fact, the WSH is compatible with any scripting engine that supports ActiveX—there are PERL and Python engines available, for instance.) Let's take a look at your sample script and see how we would accomplish "Hello World" with both languages.
First of all, when WScript starts up, it creates a global application object called "WScript." While your syntax "WScript.Application" is correct, you need a slightly different context, as this is not a ProgID, but a property reference. So, your variable declaration becomes the following:
var ws = WScript.Application;
This gives you the dispatch interface of the WScript application object. Now you can call the Echo method of the WScript object:
ws.Echo("Hello World.");
If you save the preceding two lines to a text file called "hello.js," you can run it from a command prompt in one of two ways:
CScript hello.js
... will result in the text "Hello World" being printed to the command line.
WScript hello.js
... will result in a message box being displayed with the text "Hello World." (If WScript is registered on your machine to open the .js extension, you can get the same effect by double-clicking "hello.js" in Windows Explorer.)
Now let's look at how we'd accomplish this effect using VBScript. The syntax is remarkably similar, but VBScript does not allow us to initialize a variable as we declare it. So, we will first declare the variable:
Dim ws
... initialize it:
Set ws = WScript.Application
...and then call the Echo method:
ws.Echo("Hello World!")
We will save this script as a text file called "hello.vbs." Testing this script at the command line is left as an exercise for the reader.
Incidentally, Windows Scripting Host comes supplied with sample scripts, which are generally installed in C:\Windows\Samples\WSH. Each sample is written in both VBScript and JScript. A complete reference to the Windows Scripting Host object model is available in a technical white paper at the Microsoft Scripting site (http://msdn.microsoft.com/scripting/). Dr. GUI is pleased to note, as of December 1998, betas of new versions of the scripting languages and something really cool: a script encoder that allows you to keep your scripting source code private.
My company sells an MFC Forms/Grid Extension class that we would also like to make available as an ActiveX control. We would also like to make the control a data-bound control. I saw some information that seemed to imply that ADO and/or OLE DB might replace the old unsupported data binding model, but it did not go into any depth. Please help! Where can I get information about writing data-bound controls for ADO/OLE DB data?
Regards,
Thomas Knorst
You need help getting into a bind? Dr. GUI's more used to getting people out of binds than into them. But to each his own. So, as Auntie Mame might say, "Help is on the way!" Or perhaps it's arrived already, if you've upgraded to Visual Studio version 6.0.
In the new Visual Studio 6.0 package you will find the new Data Access SDK, which provides information on ADO and OLE DB. It also contains the ActiveX Control Writer's Kit. (You can find the documentation under the topic Microsoft Data Access SDK/OLE DB/ActiveX Control Writer—it's just what Dr. GUI prescribes.) This kit gives you the tools you need to write both simple and complex data-bound controls for use with an OLE DB provider. And using ADO and OLE DB is much better than the old technologies—it's a good thing.
To connect to the data source, you will typically use the new Microsoft ADO Data Control that comes with Visual Basic 6.0 and Visual C++ 6.0. Your control will then bind to the ADO Data Control.
Finally, note that Visual C++ 6.0 also contains a new sample called COMPLEXDB, which demonstrates writing a complex data-bound control that can be used as a good starting basis.
This is a very simple question (I thought). I would like to view a defined group of people's Free/Busy time on a web page—i.e., open a web page and an in/out type board is displayed showing whether the members of the group are free or busy. I have searched your books, MSDN discs, and Web site and can find no mention of this idea.
Please can you help?
I have created my own intranet using FrontPage and other components including Java and ASP pages. Due to our firewall I cannot give you access.
Thank you,
Philip Humphries
More help? What would Auntie say? (She'd say, "Certainly!" of course!) And we can solve this one without breaching your firewall.
Assuming you're using Exchange to store your calendars, you can use the Collaboration Data Object to access the Free/Busy information. The following .asp code will logon to an Exchange mailbox, create recipients to an e-mail message, and then retrieve those recipients' Free/Busy information. The Free/Busy information is returned as a string, which is parsed, and colors are assigned to free, tentative, busy, or out-of-office times:
<%@ LANGUAGE="VBSCRIPT" %>
<html>
<head>
<title>Free Busy Information</title>
</head>
<body>
<%
Dim objSession
Dim strProfileInfo
strProfileInfo = "<valid server name>" & vbLF & "<valid mailbox>"
Set objSession = CreateObject("MAPI.Session")
objSession.Logon , , False, True, 0, True, strProfileInfo
set objMessage = objSession.Outbox.Messages.Add
set objRecips = objMessage.Recipients
' Add the users who you would like to see
' free busy information about here
objRecips.Add("<User1>")
objRecips.Add("<User2>")
objRecips.Resolve
response.write("<TABLE border>" & vbLF & "<TR><TH>Name")
for j = 0 to 23
temp = j Mod 12
if temp = 0 then temp= 12
response.write("<TH>" & temp)
next
for each r in objRecips
response.write("<TR><TD>" & r.name)
' When checking the Free/Busy information pass in the start date/time, end date/time, interval in minutes
FreeBusyInfo =r.GetFreeBusy("9/24/98","9/25/98",60)
For i = 1 To Len(FreeBusyInfo)
Select Case Mid(FreeBusyInfo, i, 1)
' if the person is available leave white
' if the person is tenative set to green
' if the person has a commitment set to red
' if the person is oof set to blue
Case "0"
response.write("<TD bgcolor=white> ")
Case "1"
response.write("<TD bgcolor=green> ")
Case "2":
response.write("<TD bgcolor=red> ")
Case "3":
response.write("<TD bgcolor=blue> ")
End Select
next
'end of 1 person's data
response.write("</TR>")
next
set objMessage= nothing
objSession.logoff
set objSession= nothing
%>
</body>
</html>
For more information, please see the Knowledge Base article Q186753, "HOWTO: Check Someone Else's Schedule for Free/Busy Information."
I am writing an application that uses SDI with the CFormView class using the MFC wizard. Now what I have is an application that either a regular user or administrator can log onto. What I want is that when an administrator logs on it will give that person a different view than when a regular user logs on. I have tried to add a user view class but my app doesn't see it as a valid class or namespace. Is there any way that I can accomplish this with SDI?
Thank you,
David Jones
We've got odd questions this time—first someone wants to be bound, now someone wants double vision. Dr. GUI bets he could make a mint as a psychologist for programmers.
Anyway, if you really want to see double, do this: Add a new view to the project. Then, in InitInstance() of the application, place logic to register either the administrator view or user view. For example:
CSingleDocTemplate* pDocTemplate;
CLogonDlg Logon;
//override DoModal() in your dialog and return appropriate value
int iVal = Logon.DoModal();
if (iVal == ADMIN)
{
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CSdiDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CAdminView));
}
else if (iVal == USER)
{
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CSdiDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CUserView));
}
else
return FALSE; //must have not logged on...
AddDocTemplate(pDocTemplate);
This should allow your app to run fine. But be sure the document class can deal with both types of view classes.
I heard that the WhichDll utility finds out which DLLs are loaded when an executable is running. Just confirm and let me know where I can get it.
Thanks,
Amit
Doing registry transplants isn't enough? Now we have to figure out which DLLs are loaded?
As it turns out, this information can be very handy for debugging DLL incompatibility problems. But WhichDll isn't the best tool for this work.
WhichDll is a Rexx script utility that searches the path and locates the first occurrence of a specified DLL. This utility does not list the DLLs actually loaded by a process, only those it thinks should be loaded. As a result, it can give incorrect (and therefore misleading) results.
There are GUI-based utilities that list the currently loaded DLLs of a process. These utilities are: DllView for Windows 95/98 and NtHandleEx for Windows NT 3.51/4.0. These utilities can be found at http://www.sysinternals.com/.
When you create a control with a transparent background, how do you refresh or repaint the background and why do you see remnants of objects and junk from other screens when the control is encapsulated in the picturebox or on a VB form? InvalidateControl and SetModifiedFalse do not seem to work.
First we get someone who wants double vision. Now we get someone who doesn't want to see the background at all. It gets harder and harder to please everyone. But transparent backgrounds are very handy for nonrectangular objects—you could say they're a good thing.
Transparent backgrounds are something of a misnomer in Windows. A "transparent window" in Windows is simply a window whose background is not painted, allowing the underlying window to show through. There is nothing that tells a window that what is below it has changed and to update itself. Thus, you don't actually "see" through the window. You only see what was under the window the last time it was updated. Additionally, because the transparent window is on top, other windows below may not update themselves.
There are two methods you can use to try and work around these problems in an ActiveX control. The first relies on the fact that the ActiveX control window is a child window of the container's window. The second is a new feature of ActiveX control containers that makes effects like transparency much easier to implement—and more efficient, too.
Because an ActiveX control is a child window of the container, you can force the container to update its background every time the control's background changes by sending WM_ERASEBACKGROUND messages to the parent window. The Microsoft Knowledge Base article Q165073, "INFO: Making Transparent Controls with MFC," has the details on this method. The problem with this method is that if the container changes rapidly, the background in the control will not be updated.
The second method is to completely avoid the problem by not creating an ActiveX control window at all. Many new ActiveX control containers, such as Internet Explorer 4.0 and later, Visual C++ 6.0, and Visual Basic 6.0, support windowless controls. These windowless controls draw directly into the container's window instead of creating their own windows. Because no control window is created, they are transparent by default. You can create windowless controls in Visual C++ using Microsoft Foundation Classes (MFC) or Active Template Library (ATL), or in Visual Basic 6.0.
Because all ActiveX containers may not support windowless control activation, you should implement both methods in the same control.
… once more to Dr. GUI's crack team of specialists: Ranga Narasimhan, Nick Dallett, Dan Kirby, Craig Wiand, Nathan Manis, Gerard Collop, and Kelly Ward. And because this is his last Dr. GUI column, special thanks go to Dr. GUI's specialist team coordinator, Rick Caudle. Rick's hard work over this last year has indeed been a very good thing; he'll be missed chez GUI.