Feedback Search Top Backward Forward
EDM/2

Questions and Answers

Written by Larry Salomon, Jr.

  Welcome to this month's "Questions and Answers"! Each month, I collect various questions sent to me via email and try to answer each directly; the ones that I feel contribute the most to developers, whether in terms of information or as a nifty trick to tuck into your cap, get published in this column (being able to answer the questions also influences my decision *grin*).

To submit a question, send mail to my email address and be sure to grant permission to publish your question (those that forget will not be considered for publication).

This month's deluge of questions covered the following topics:

Dynamically adding and removing the min/max/size buttons?

David John Marotta (djm5g@virginia.edu) writes:

I am trying to dynamically remove and add the min/max/size buttons and menu selections. I am having trouble doing this especially with the buttons. I can't determine which Win calls to use. Can someone help me? Thanks.

A: David, what you need to do is create or destroy the appropriate windows with the id's corresponding to the frame controls you wish to add or delete and send the frame a WM_UPDATEFRAME message, specifying the FCF_ flags that have changed in mpParm1.

Disabling hard error popups?

Christopher Fernandes (fernand@slinky.cs.nyu.edu) writes:

I want to let users add files to a list using an add dialog. Since I could only find canned "open" and "save as" dialogs in the toolkit, I modified code from a freeware program (earlier version of OS/2 I believe) that works very well except that when the user selects a floppy drive that does not have a floppy in it, and I DosSetDefaultDrive to it I get that huge screen. Is there a call that is essentially a DosSetDefaultDrive that quietly returns an error code if there is no diskette?

A: The solution is to use the DosError function, specifying FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION as its argument.

Online help for dialogs

Christopher Fernandes (fernand@slinky.cs.nyu.edu) has another question:

I don't have a main screen, just directly go into a dialog. I have a help push button that explains the program. The help text can be viewed using the VIEW.EXE program, so I know that I can spawn a "view file.inf" when the help push button is pushed. But I want to do it in a more standard way, using WinCreateHelpInstance and WinAssociateHelpInstance so that when the help push button is pushed in different child dialogs the user directly goes to the appropriate help topic. However, all the examples that I've seen use HELPTABLES. I don't want that since I don't even have a main window. Would it be possible to get some code that did this?

A: Nowhere does it state that you have to have a "main" window in order to use HELPTABLE's. Since WinAssociateHelpInstance requires a frame window handle, with the following knowledge you can accomplish what you desire:

  • A dialog is a subclassed frame window
  • WinDlgBox is equivalent to the three calls WinLoadDlg, WinProcessDlg, WinDestroyWindow

Thus, if you call those three calls instead of WinDlgBox, you can insert a call to WinAssociateHelpInstance after the call to WinLoadDlg, allowing you to use HELPTABLE's as you would in any other program.

Spawing a batch file

Christopher Fernandes (fernand@slinky.cs.nyu.edu) has yet another question:

My app generates a text file or optionally a Postscript file and spawns a lister/editor on these files if requested. I also want to allow printing of these files from within the program. I want to let the user specify a batch file, and then call that batch file with the file as the argument. However i'm getting an error of bad EXE type, so my question is could I have the line of code that spawns a batch file.

A: Try spawning CMD.EXE with the arguments "/K batch_file arguments".

Deleting profile data

Christopher Fernandes (fernand@slinky.cs.nyu.edu) can't stop himself:

I save data across program invocations using the profile functions on a program-specific INI file. That works fine, but I can't find calls to delete data or to compact the file. Do the profile functions automatically compact if I write a zero-length object to that setting.

A: If you call PrfWriteProfileData (or any of the other profile writing functions) specifying NULL for the pointer to the data, the data in the INI file is erased. Unfortunately, there is no explicit way to compact the file from a API viewpoint.

As a side note, it is possible to create a new copy of an INI file that is compacted. You simply enumerate all of the applications and keys, query the data in the original INI file, and write the data to the new INI file. Unfortunately, you cannot copy the new version of the file over the original unless no application is currently using it - for OS2.INI and OS2SYS.INI, this is impossible unless you boot from your installation disks.

A 'Q' about Notebook controls

Gordon W. Zeglinski (zeglins@ccu.umanitoba.ca) writes:

I've read through all of IBM's docs on Notebook controls and I cannot find out how to determine if the page is being turned to via a "tab" or the directional arrows.

It would seem that there is a way to do this because Borland seems to do this in their C++ compiler for OS/2. The reason this is useful, is that it would make using "dummy" section seperator pages much easier to implement.

I guess the question is how can one tell if the tab or arrow sections of a notebook control have brought the window to the top? Alternatively, How does Borland do it?

One last question: I've noticed that double clicking the top tab, would occasionally cause the top page to go blank. I have set the control up to take care of all the redrawing automatically. Is this a know bug? or am I doing something wrong?

A: There is no exposed way to determine if the directional arrows were used or not, but if you assume that the arrows always have the same id (a safe assumption in this case because there are always at most 1 set of these per notebook), then you can use WinWindowFromID to get the window handle of the arrows and then subclass them instead.

In reference to your last question, I must say that I've never noticed this behavior in my applications that use notebooks, nor does the desktop suffer from this symptom, so it would appear that you have done something incorrectly.