From: lhoang@orion.oac.uci.edu (Long Hoang)
Subject: Re: Multicolumn Listboxes
Newsgroups: comp.os.os2.programmer
Organization: University of California, Irvine
Date: 19 Dec 92 11:38:55 GMT

In article <BzCttq.569@aplcenmp.apl.jhu.edu> robbar@aplcenmp.apl.jhu.edu (Robert Baruch) writes:
>Anyone have any code to perform multicolumn listbox insertions?
>This would be a great help to me if someone knew or had the source
>to do this!
>
>Thanks,
>
>Rob Baruch

   Here is my clumsy solution:

   In resource file, the list box has the style LS_OWNERDRAW

   Upon receiving LM_INSERTITEM, either from WinSendMsg() or the macro
       WinInsertLboxItem(), the window procedure for the parent window
       of the list box will receive the 2 message:

      WM_MEASUREITEM:
                // must return a value here for the height of the item
                // in the list box. This value can be determind correctly
                // when you have the information passed to you in WM_DRAWITEM
                // which includes the presentation space handle, you then
                // can approximate item height.
          return(MRFROM2SHORT((SHORT)item_height, 0));
          break;

      WM_DRAWITEM:
          {
              POWNERITEM powneritem;

              powneritem = (POWNERITEM)mp2;

                        // if un/hightlighting resulting from selection
                        // I let the listbox do it.
              if (powneritem->fsState != pwoneritem->fsStateOld)
                  return((MRESULT)1);

              if (!itemheight) {    // set item height, once
                  temprecl.xLeft = 0;       // make it large enough
                  temprecl.xRight = 10000;
                  temprecl.yBottom = 0;
                  temprecl.yTop = 10000;
                  WinDrawText(powneritem->hps,
                              -1,
                              "AAAAA",  // dummy string, should be worst case
                              &temprecl,
                              0L,
                              0L,
                              DT_QUERYEXTENT);
                  itemheight = temprecl.yTop - temprecl.yBottom;
                  WinSendDlgItemMsg(hwndDlg,
                                    VIEWART_LISTBOX,
                                    LM_SETITEMHEIGHT,
                                    (MPARAM)itemheight,
                                    (MPARAM)0);
              }
              WinSendDlgItemMsg(hwndDlg,
                                SHORT1FROMMP(mp1),
                                LM_QUERYITEMTEXT,
                                MPFROM2SHORT(powneritem->idItem, sizeof(str)),
                                MPFROMP(str));
              p = str;   // str holds the record of fields delimited by blanks
                         // You can design your own format. 

                         // gettoken parses the fields for seperate drawings
              p = gettoken(p, firstfield, FIRSTFIELD_LEN);
              p = gettoken(p, secondfield, SECONDFIELD_LEN);
              p = gettoken(p, thirdfield, THIRDFIELD_LEN);

              increment = powneritem->rclItem.xRight / 10; 

                    // first field occupies 40 percent of the list box witdh
                    // second field occupies 20 percent of the list box witdh
                    // third field occupies the rest

              WinDrawText(powneritem->hps,
                          -1,
                          firstfield,
                          &powneritem->rclItem,
                          0L,
                          0L,
                          DT_TEXTATTRS | DT_ERASERECT);

              powneritem->rclItem.xLeft += 4 * increment;
              WinDrawText(powneritem->hps,
                          -1,
                          secondfield,
                          &powneritem->rclItem,
                          0L,
                          0L,
                          DT_TEXTATTRS | DT_ERASERECT);

              powneritem->rclItem.xLeft += 2 * increment;
              WinDrawText(powneritem->hps,
                          -1,
                          thirdfield,
                          &powneritem->rclItem,
                          0L,
                          0L,
                          DT_TEXTATTRS | DT_ERASERECT);
                  // We achieve proportionality this way going from one
                  // graphic resolution to the other, especially when you have
                  // static text header for each column.

              return((MRESULT)1);
          }
          break;

     I got the idea from the book 
         Programming Guide, Volume II. OS/2 2.0 Technical Library.
         Chapter 9. List Box Controls.

     Your list box might be more complicated than this. However, I'm
     almost sure that the list box must be LS_OWNERDRAW'ed. Please correct
     me if otherwise.

==========================================================================