Introduction to PM Programming - Jan 1995

Written by Larry Salomon Jr.

Introduction
The purpose of this column is to provide the readers out there who are not familiar with PM application development the information necessary to satisfy their curiosity, educate themselves, and give them an advantage over the documentation supplied by IBM. Of course, much of this stuff could probably be found in one of the many books out there, but the problem with books in general is that they don't answer the questions you have after you read the book the first time through.

I will gladly entertain feedback from the readers about what was "glossed over" or what was detailed well, what tangential topics need to be covered and what superfluous crap should have been removed. This feedback is essential in guaranteeing that you get what you pay for.

It should be said that you must not depend solely on this column to teach you how to develop PM applications; instead, this should be viewed as a supplement to your other information storehouses (books, the network conferences, etc.). Because this column must take a general approach, there will be some topics that you would like to see discussed that really do not belong here. Specific questions can be directed to me via email and I will do my best to answer them in a timely fashion.

Last Month
Last month, we began looking at the WC_LISTBOX class. This month, we will take a good look at the owner draw capabilities of this control class.

A Message For You, Sir
Each month before I write the next instalment of this column, I re-read what I wrote the prior month to discover what I have covered in order to determine in what direction I should continue. As I read last month's column, it became apparent that the message reference which I capitulated each month is nothing more than a rehash of what's available in many sources, including the on-line programming references and many books. I would like to discontinue my inclusion of this information, given this enlightening of mine, unless the teeming masses tell me that I should do otherwise. Any feedback on this would be appreciated.

This Isn't Picasso
But owner draw list boxes give you quite an opportunity to do some interesting things. For the original LaMail product from IBM, I wrote a LaGrep utility which searched mail folders for text. The found text was displayed in a list box in a different colour than the rest. Additionally, the configuration options allowed to you change the colour that the text was displaying using, and the colour selection was displayed in a list box with the name of the colour next to it. Both of these are perfectly valid, real-world examples of owner draw list boxes, and while there might be other window classes better suited for these tasks, knowing how the owner draw capabilities work is a useful asset to have tucked in your cap.

The owner draw architecture with regard to list boxes is represented by two messages, which - incidentally - are used in owner draw menu items in a very similar fashion. These messages are the WM_MEASUREITEM and WM_DRAWITEM and their purpose is just as their names suggest. The former message is sent, usually upon the creation of the list box, to determine the maximum height and (if LS_HORZSCROLL) maximum width of the items to be displayed. The result is returned to the list box as MRFROM2SHORT(height,width). The latter message is where all of the work is done and is sent whenever an item needs to be redrawn. PVOIDFROMMP(mpParm2) points to an OWNERITEM structure, but you won't find its definition in the list box section of PMWIN.H. You have to look in the menu section to find it, which is the following: typedef struct _OWNERITEM { HWND hwnd; HPS hps; ULONG fsState; ULONG fsAttribute; ULONG fsStateOld; ULONG fsAttributeOld; RECTL rclItem; LONG idItem; ULONG hItem; } OWNERITEM, *POWNERITEM hwnd is the handle of the control. hps is the handle to the presentation space which must be used for drawing. fsState and fsStateOld are, when the structure refers to an owner draw list box, BOOLs which are TRUE if the item is selected and FALSE otherwise (fsStateOld is the selection state of the item the last time it was drawn). fsAttribute and fsAttributeOld are not used when dealing with owner draw list boxes. rclItem is the bounding rectangle of the item to be drawn. idItem is the index of the item to be drawn. hItem is the item handle, if set.

It needs to be noted that, if the list box is owner draw, PM will not do anything on your behalf except paint the highlight state of the item to be drawn. It does this using an XOR operation only if fsState and fsStateOld are different. There is no way to change this unless you know that the OWNERITEM structure is what the list box checks upon return from this message when it determines if it needs to highlight the item or not. So, if you set fsState and fsStateOld to the same value before returning, PM will not do anything at all.

The nice thing about the first sentence in the last paragraph is that PM doesn't even look at the item text for you. Thus, you could interpret the text in a different way that would normally be done - for LaGrep, I changed the colour by putting a tab character in the text followed by a BYTE which was an index into an array of CLR_* constants. When I painted the control, I did not draw this special sequence but used it to control the drawing.

The possibilities are endless and are only limited by your imagination.

API of the Month Club
Our API of the month is the one that the list box uses to XOR the highlight of an item. (BOOL)WinInvertRect(HPS hpsWnd,PRECTL prclRect); hpsWnd is the handle to the HPS to invert within. prclRect points to the rectangle specifying the area to be inverted. Inversion here refers to the inversion of the colours within the rectangle. Thus, black becomes white, white becomes black, etc.

Next Month
I need to get upon my soapbox for a moment.

As I looked through the past issues to see where this column has gone already, in order to determine what shall be discussed next, I saw that, much to my embarrassment, the list box window class has already been discussed. Yet, this is the third month in my second treatment of the topic and I never would have known because the silence from my audience is deafening. The embarrassment is not what I am worried about; I am instead concerned about providing a quality column, yet no one bothered to tell me that I was simply rehashing a topic that was discussed just a few months prior.

Please give me feedback! How else can I say it? I need to know what you think, where we should go next, etc. Since I have always considered the button, entry field, and list box classes to be the "simple" classes, it is more important now because I need to know what class should be discussed next. Should it be the menu, or the static? Should it be the scrollbar, or the title bar? Please let me know; this humble request alone I make.