hide random home http://www.microsoft.com/DEVNEWS/DRGUI5_2.HTM (PC Press Internet CD, 03/1996)

Ask Dr. GUI

March 1, 1996

(Remember: he's not a real doctor, and he doesn't do house calls.)

Out of the desert….

What an adventure it's been! Over the past few months, Dr. GUI has gone through gender and species transformations. (Fixing whole-wheat toast gets rather tiresome, although the crumbs did keep me regular.) Then I went to Comdex but ended up lost in the desert after being put in a taxi late one night as a party was winding down. In the desert, I got really hungry and thirsty and tired. Luckily, I found an odd, spineless, dome-shaped cactus to eat. As I nibbled on its little buttons, my hunger and thirst were satisfied. However, I did seem to be in an altered state--maybe it was that I was sleepy. The last thing I remember was clicking my heels three times while chanting, "There's no place like cyberspace…there's no place like cyberspace…"

…and into the GUI, GUI swamp…

I found myself in a familiar swamp (oops, I mean "protected wetland"). As I waded and squished through it, I recognized the shells of old 286 PCs that had been jettisoned from the building above. It was then that I realized that I was near home: I was outside one of Microsoft's Product Support buildings. I hurried inside to borrow a computer to check my e-mail, and was in for a huge surprise.

…out of the swamp, but still swamped…

I discovered that instead of the usual two or three questions a day from my devoted patients, I was getting between thirty and seventy! Every day! I said to myself, "It's a good thing I only have to answer the ones that get published in the column…"

When I inquired as to what might have happened, my editor said, "Oh, we put you up on the Internet--all they have to do is click an eight ball to e-mail you." Never let them tell you that no one pays attention to the Internet.

One if by e-mail...

Now it's your turn; fire off a stumper question to the 'ole doctor by clicking the 8-ball:

email to Dr. GUI

(but, please, remember Dr. GUI doesn't make housecalls, so read the disclaimer first).

Two if by postal mail...

If you still believe in those musty, low-tech ways of consulting with the doc, you can use the postal address: Ask Dr. GUI, c/o Microsoft Developer Network, One Microsoft Way, Redmond, WA 98052-6399



Where am I?

Dear Dr. GUI (whatever it is!):

I want a program (written in Visual C++) to know in which directory it was started (not the working directory). This would allow me to read the .INI file without putting it in the WINDOWS directory or in the WIN.INI.

I've not been able to do this, but I have to admit that I am a newcomer to Windows programming. Digging in your CDs has not helped me; can you? Thank you.

Mauro Silverini

Dr. GUI replies:

"Whatever it is?" Well, I'm back, and I'm a doctor again. But it's been a rough trip. I was praying so hard I thought I was going to change from Dr. GUI to Fr. GUI. But those priestly vows just aren't my style.

In any case, have we got an API for you. Remembering that both .EXEs and .DLLs in Windows are called "modules" and that the name of the function you call when you need to ask Windows something almost always begins with "Get…", a friend found the function GetModuleFileName. (Dr. GUI had yet to recover from the nice cactus, so he couldn't quite see the screen.)

GetModuleFileName takes the module handle (NULL will work for an .EXE), a pointer to a buffer to receive the module name, and the size of the buffer. It returns the length of the string placed in the buffer. When it returns, the full file path, including directory information, will be in the buffer. You'll have to parse the buffer to isolate the path name. (Hint: Start at the end and look for the first backslash using the C run-time library function strrchr.) I used the following code:

char acPath[256];
if ( GetModuleFileName( NULL,, acPath,, 256 ) != 0) {
   // guaranteed file name of at least one character after path \
   * ( strrchr( acPath, '\+ 1 ) = '\0';
   AfxMessageBox( acPath );   // Use it 
}
else ; // error--GetModuleFileName failed

Cholesterol warning: This text is too rich for my blood

Dear Dr. GUI:

HELP!!!!!!!!!!! I am new to Visual Basic (32 bit for Windows 95) and have been trying to use rich text boxes but there isn't enough "how-to" info in the documentation. I've checked a lot of books, called Microsoft tech support, even tried news groups--nothing! For instance, they tell you what RTF codes are supported but don't tell you how to use them. I know I'm probably missing something real simple, but I sure wish someone would point it out.

Thanks.

Jesse Johnson

Dr. GUI replies:

Interpreting and producing RTF files is a rather advanced and mysterious topic, rivaling brain surgery in its complexity. To take full advantage of the Visual Basic RichTextBox control, you may instead wish to employ the LoadFile() and SaveFile() methods. These features allow the RichTextBox control to handle the interpretation for you, while hiding all of the ugly details. However, if you absolutely must become an accomplished RTF hacker, here are a couple of suggestions:

  1. The RTF version 1.3 specification (Microsoft Product Support Services Application Note 1/95-GC0165) is available on the MSDN Library CD (look under Product Documentation, Applications, Word for Windows 6.0). This specification contains a wealth of information about the minutiae of RTF documents, and should satisfy your curiosity.
    Use an RTF-enabled word processor (such as WordPad or Microsoft Word for Windows) to produce a document with the desired formatting. WordPad is especially handy since it's based on the same Windows 95 rich-text edit control used in the Visual Basic's implementation of RichTextBox.
    Save the document in RTF format, then view the document as an ASCII text file so that the RTF tags are visible. By comparing the formatted document with the underlying RTF tags, and referring to the aforementioned specification, you should start to gain an understanding of how the tags are actually employed in producing an RTF document. This is a trial-and-error approach, but Dr. GUI has never been averse to addressing complex problems through trial and error. After all, this approach carried the good doctor through his surgical residency with nary a complaint!

I have a need…a need for speed…

Dear Dr. GUI:

This is not a GUI question really, but I didn't know a better place to pose it. So, what is the benefit of using precompiled header files if a compiler supports incremental linking? Or, perhaps more correctly stated, is there any point to putting any file other than a system header file in the precompiled header if a compiler can handle "patching" any change of user code incrementally? The obvious assumption I'm making is that a compiler that supports incremental compiling can incrementally update an object file (from a C or C++ file) whether that change occurred in the source file or the header file. Is this true?

Larry Hall

Dr. GUI replies:

Dr. GUI has seen a lot of confusion about this. If you take two aspirin , I'm sure you'll feel better.

Precompiled headers, incremental linking, incremental compilation, and minimal rebuild. They all speed up builds in different ways. For the fastest builds, you should use them all. Otherwise you'll get through the latest Dilbert cartoons on the Web before your first coffee break, and you'll have to do real work while waiting for builds the rest of the day.

Precompiled headers save the compiler from having to parse the header (.H) files for each .CPP file in which the headers are included. It's much faster to load the precompiled header, large as it is, into memory than to parse the 50,000+ lines of the system header files for each .CPP module you compile. Since the system headers are so large, it doesn't usually make sense to include your project's own headers in the precompiled header, especially if they're changing. (One little change in a precompiled header means that the entire project has to be rebuilt from scratch, regardless of whether the sources have changed.) However, if your project has headers (such as headers for your own libraries) that don't change, including them in your precompiled header can speed up builds somewhat.

Incremental linking allows you to make relatively simple changes to your program without having to relink the entire program. If you make major changes, however, you'll have to do a full link. Visual C++ 4.0 can use incremental linking much more often than previous versions could.

Incremental compilation allows the build system to compile only the functions that have changed, rather than entire modules. If you have long source files, this can be a big win.

Minimal rebuild is new in Visual C++ 4.0. It examines changes you've made to header files, then compiles only the source files that actually depend on that particular set of changes. (Before, you had to recompile every source module that included a header that was changed, even if you changed only comments in the header.)

As you can see, the combination of these technologies can markedly reduce build times. For more information on these technologies, look them up in Visual C++ 4.0 Books Online or the MSDN Library.

Where am I? continued…

Dear Doctor:

How can you get the domain a user is logged onto?

It'd be nice to have a T-shirt (X-LG).

Thank you,

Jay Shillington

Dr. GUI replies:

I'm beginning to think you folks only ask questions to get T-shirts, not because you really appreciate Dr. GUI. Sniff. In any case, I appreciate having good questions to answer.

There's a really good Knowledge Base article in the MSDN Library that explains how to do this by using the LookupAccountSid function in Windows NT. It's called "Looking Up the Current User and Domain," and the ID is Q111544. The code, at 15 or so lines, is a little long to reproduce here.

Outbreak of right-button fever

Dr. GUI has received several questions about the beta of Windows NT 4.0.

Some of these questions just go to show how much people love Dr. GUI's T-shirts:

Dear Dr. GUI:

I have just a simple and short question:

How can I get Windows NT 3.51 running with the "new" Windows 95 interface? I really love the new interface and I struggle to get it running but...

We are members of MSDN Level 2 and get all the wonderful CDs, but I didn't find any information about it.

Greetings,

Michael Stettner

P.S. This seems to be a wonderful question to get a T-shirt--isn't it :-)

…and others are more businesslike:

Dear Dr. GUI:

Hi, is there a Windows 95 GUI personality for Windows NT? If so, how much does it cost and where can I get it?

Thanks,

J Chu

Dr. GUI replies:

Dr. GUI has just the prescription for your right-button fever: The Windows NT 4.0 beta premium release! Oh, and he has T-shirts for both of you.

If you're an MSDN Professional or MSDN Enterprise subscriber (our new names for Levels 2 and 3; see the Editor's Note, page 2), you will be getting this premium release shortly (if you haven't already) at no extra charge. See? It pays to belong.

If you're not an MSDN Professional or MSDN Enterprise member, why not join today? It's good preventative medicine.

Those little pop-up thingies

Dear Dr. GUI:

I want to add pop-up hints to my Windows applications that look and act like Microsoft Word's "ToolTips." Is there an SDK function call or class library somewhere that contains this type of functionality?

Thomas A. Silvious

Dr. GUI replies:

You think those little windows are cool, do you?

Well, frankly, so does Dr. GUI.

If you're using the Win32 API, check out Nancy Winnick Cluts' book Programming the Windows 95 User Interface. She has a section in the first chapter entitled "Supporting ToolTips."

If you're using Microsoft Foundation Classes (MFC) and you want ToolTips on your toolbars, you're in luck--they're supported automatically in MFC, starting with MFC 3.0 (which shipped with Visual C++ 2.0). All you have to do is edit the string table properly. You can use an AppWizard-generated app as a guide.

For non-toolbar ToolTips in 32-bit MFC, check out the CToolTipCtrl class.

If you're using 16-bit MFC, check out Dale Rogerson's article "Extending MFC's Toolbars" in the MSDN Library.

If you search on ToolTips in the MSDN Library, you'll find a wealth of pertinent information, including information about adding ToolTips to a Visual Basic app.

Ear problems: Ive got CD-ROMs coming out of mine

Dear Dr. GUI:

Every quarter, the MS Development Platform CD-ROMs arrive with more and more CDs. Though it's fun looking at all the characters of the Korean Hangeul distribution, we need only about a quarter of all the discs. Of course we could use the other three quarters to decorate the walls, but in the end it's a waste of polycarbonate. As we are aware of environmental issues, we would like to have a more individual set of CD-ROMs. Is that possible?

Christian Treber

Dr. GUI replies:

My--you DO have interesting ears--with CD-ROMs spilling out of them. But Dr. GUI has just the thing to keep some of the CD-ROMs from coming out of your ears.

Recently, the Developer Network started shipping the MSDN Platform in three packages. Pack 1, the U.S. Pack, contains all of the SDKs and U.S. versions of the operating systems. Pack 2, the International Pack, contains all of the non-U.S. operating systems, drivers, extensions, and SDKs, including Far East versions. Pack 3, the DDK Pack, contains device driver kits for all Microsoft operating systems.

Contact the Developer Network to change the packs you receive. (See The Right Numbers)

In your situation, you probably want European, but not Far Eastern, operating systems, since you're in Germany. We don't have a way to do that today, but we're working to figure out a distribution system that will better match customers' exact needs.

Thanks for the memory…

Dear Dr. GUI:

When developing for Win32, the GlobalAllocPtr macro still seems to work fine. Is there any point in still using it ? Or will the operator new() do just as well?

Is the memory available to operator new() restricted by the current stack size and/or stack allocation ?

Please help me, I'm in pain! It hurts so bad that if you do not know how to cure me, I'm going to cure myself.

Sigurd Stenersen

Dr. GUI replies:

Dr. GUI certainly doesn't want you to cure yourself. He's here to help. Sit down and have a tranquilizer.

Besides, there's not much to fret about: It's really your choice how to allocate memory in Win32. Unlike Win16 memory allocation methods, Win32 methods have very few efficiency differences. LocalAlloc and GlobalAlloc are the same in Win32, and both malloc and new eventually call a similar function called HeapAlloc. The VirtualAlloc API is the closest to the kernel, but the most difficult to use.

The one time it does matter is when you're allocating C++ objects. If you're programming in C++, you'll want to use new exclusively when allocating C++ objects so that the objects' constructors are called.

Whatever method you choose, be sure to free memory with the corresponding function and no other.

Doing two things at once

Dear Dr. GUI:

I am developing Internet chatting. I have a question on which I need you to help me out.

Because it is for Internet use, our application is sort of a real-time application on Windows NT and Windows 95. My question is while the program is downloading and playing a wave file through the Internet, if the user clicks on some pull-down menu (actually just using a mouse to hold it) or hits F1 to activate context-sensitive Help, the program will stop playing the audio clip. Is there any way to solve this problem? I noticed that the Sound Recorder in Accessories of Windows NT will not halt under this kind of condition.

My application is SDI, and for some reason we used OnIdle() to check the event to make the program continue to play sound. Do you think PeekMessage will still work for this?

BTW, if you still have a DR. GUI T-shirt, would you mind sending me one?

Mr. Victor Dong

Dr. GUI replies:

Wouldn't we all like to do two things at once--and do them well? As it turns out, this is a lot easier with Win32 than it was with Win16. Programs that keep doing whatever they do while the UI is working most probably use multiple background threads (which execute independently of the UI). Specifically, a strategy using OnIdle or PeekMessage won't work if your program isn't idle--and it won't be idle while a menu is being held down or while a help context is being loaded. So what you need is a background thread to play the sound.

There's tons of material on multithreading on the MSDN Library CD. As starters, I'd recommend the articles "Multithreading for Rookies" and "Multiple Threads in the User Interface." And since you're using MFC, be sure to check out the article on multithreading in the MFC Encyclopedia.

Another technique that helps applications remain responsive is to use asynchronous I/O rather than waiting for I/O to complete--this is especially important when doing I/O over a network.

© 1996 Microsoft Corporation


Previous Up One Level Next Developers Home Page