Feedback Search Top Backward Forward
EDM/2

Questions and Answers

Written by Larry Salomon, Jr.

  Brian Stark (stark@saturn.sdsu.edu) writes:

Q: While building entry fields I noticed the style option ES_AUTOTAB, which moves the cursor to the next "control window" automatically when the maximum number of characters are entered (Ref. OS/2 2.0 Technical Library, Programming Guide Volume II). My assumption is that this is done by sending a WM_CONTROL message to the current control windows owner. However I was unable to verify this in the document, or any other document. Currently I am only able to establish control of an entry field using the mouse, I would like to be able to use the arrow keys and the tab to move from field to field. Is the application responsible for this? If so, is there a document available that gives a clear description of this process, or am I just doing something wrong when I create the fields.

A: After checking the toolkit header files (mainly pmwin.h) and not finding any notifications that would indicate what you are hoping (EN_* constants), a quick test application yielded that no WM_CONTROL messages are indeed sent that indicate the auto-tab feature has been invoked. However, the EN_KILLFOCUS and EN_SETFOCUS notifications are sent to the entryfield losing the focus and to the one receiving the focus, respectively.

While these are not sent only when the auto-tab takes place (a mouse click in another entryfield will generate the same two notifications), a little thought and hocus-pocus will help you figure out how to do what you want to do.

Regarding arrow keys and tabs, the system treats the keys in the following ways:

Tab/Down arrow Moves the focus to the next control ("next" is defined using Z-order) with the WS_TABSTOP style.

Backtab/Up arrow Moves the focus to the previous control ("previous" is defined using Z-order) with the WS_TABSTOP style.

In entryfields, the left/right arrows maneuver the cursor within the control.

Dominique Beauchamp (beaucham@phy.ulaval.ca) writes:

Q: What is the difference between a "string" and a "message" in a resource file? Each can be loaded with WinLoadString and WinLoadMessage but afterwards it seems we can use them the same way. If I want to program an error message box, should I use "string" or "message" to do it? (No, it's not obvious!)

A: To be honest, often times I have asked the same question. Within PM, there seem to be a few items whose usefulness are questionable (this being one of them). To my knowledge, there is no difference between the two; one of the two might exist for historical reasons (SAA comes to mind), or there might be other logic at work here. In any case, I personally prefer WinLoadString since its name implies that it is used for more than just messages; whatever you choose, be consistent in your coding.

Problem with BN_PAINT

I have a confession to make: I have yet to upgrade my machine at work to OS/2 2.1, so the following problem might have been fixed in 2.1. I will try to remember to check at home, but if anyone else knows the answer already I would appreciate email. The problem is with buttons created with the style BS_USERBUTTON; the documentation states that, when the button needs to be repainted, you will receive a BN_PAINT notification and mpParm2 will point to a USERBUTTON structure which contains four fields:


hwnd        handle of the button window
hps         presentation space in which drawing should be performed
fsState     the current state of the button
fsStateOld  the previous state of the button

According to the documentation, the fields fsState and fsStateOld can be one of three values - BDS_DEFAULT, BDS_HILITED, or BDS_DISABLED. When creating a 32-bit application utilizing "ownerdraw" buttons, this did not seem to work, so I added a few calls to fprintf() and below is what I got (the labelling of the events were added later):

Upon window creation
Button state = 0x00000000
Button state (old) = 0x00040010

First down
Button state = 0x00000100
Button state (old) = 0xD0DF032B

First up
Button state = 0x01000000
Button state (old) = 0x01000100

Second down
Button state = 0x00000100
Button state (old) = 0xD0DF032B

Second up
Button state = 0x01000000
Button state (old) = 0x01000100
If you will accept the notion that my code is correct, you can see that the documentation appears to be completely wrong. I tried to reinterpret the values but still I ran into problems. Several calls to printf() later, a pattern emerged. I quickly followed my hunch and all of my problems went away.

IBM defined the USERBUTTON structure incorrectly! The fsState and fsStateOld fields which are defined as ULONG's should be USHORT's instead. That simplified the problem to having to undefine BDS_DEFAULT (0x0400) and redefining it as 0x0000.

Workaround

The workaround should be obvious - either change your toolkit header files or define your own structure and redefine the BDS_DEFAULT constant. The former is preferred since you will not have to "kludge" every program that utilizes user-buttons to get this to work.