home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / docview.pak / ODLISTBX.CPP < prev    next >
C/C++ Source or Header  |  1997-07-23  |  5KB  |  160 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1992, 1993 by Borland International
  3. //   Implements class TODListBox
  4. //----------------------------------------------------------------------------
  5. #include <owl\owlpch.h>
  6. #include "odlistbx.h"
  7.  
  8. TODListBox::TODListBox(int id)
  9.           : TControl(0, id, 0, 0,0, 100,100), BufTemp(0), BufLen(0), MaxWidth(0)
  10. {
  11.   Attr.Style &= ~(LBS_SORT | LBS_HASSTRINGS | LBS_MULTIPLESEL);
  12.   Attr.Style |= (LBS_NOTIFY | WS_VSCROLL | WS_HSCROLL | WS_BORDER | LBS_OWNERDRAWVARIABLE);
  13. }
  14.  
  15. char far *
  16. TODListBox::GetClassName()
  17. {
  18.   return "LISTBOX";
  19. }
  20.  
  21. void TODListBox::ItemRedraw(int index)   // force item to be redrawn
  22. {
  23.   TRect rect;
  24.   if (GetItemRect(index, rect) <= 0)
  25.     return;   // return 1 if OK, -1 if error
  26.   InvalidateRect(rect);
  27. }
  28.  
  29. void TODListBox::DrawItem(DRAWITEMSTRUCT far & dis)
  30. {
  31.   ODItemInfo item;
  32.   UINT action = dis.itemAction;
  33.   item.Hdc = dis.hDC;
  34.   item.State = dis.itemState;
  35.   item.Data  = (void far*) dis.itemData;
  36.   item.Index = dis.itemID;
  37.   item.Bound.Set(dis.rcItem.left, dis.rcItem.top,
  38.                  dis.rcItem.right,dis.rcItem.bottom);
  39.  
  40.   if (item.Index < 0)
  41.     return; // ignore if empty listbox, no focus rect?
  42.   GetItemInfo(item);       // must fill in: Extent,Text,TextLen,Offset
  43.   if (action & ODA_DRAWENTIRE){
  44. //   // shift the item rect to account for horizontal scrolling
  45. //if (item.Bound.right > clientrect.right)
  46. //      item.Bound.left = -(item.Bound.right - clientrect.right);
  47.   if (item.Extent.cx > MaxWidth) {
  48.     SetHorizontalExtent(MaxWidth = item.Extent.cx);
  49.   }
  50.   DrawItemData(item);      
  51.   action = 0;  // redraw destoys previous focus and selection painting
  52.   if (item.State & ODS_SELECTED) action |= ODA_SELECT;
  53.   if (item.State & ODS_FOCUS)    action |= ODA_FOCUS;
  54.   }
  55.   if (action & ODA_SELECT) {
  56.     ChangeHilight(item);
  57.   }
  58.   if (action & ODA_FOCUS){
  59.    item.Bound.right = item.Extent.cx;  // focus drawn around entire item
  60.    ChangeFocus(item);
  61.   }
  62. }
  63.  
  64. void TODListBox::MeasureItem (MEASUREITEMSTRUCT far& mis)
  65. {
  66.   ODItemInfo item;
  67.   item.Hdc = ::GetDC(*this);
  68.   item.Data  = (void far*) mis.itemData;
  69.   item.Index = mis.itemID;
  70.   item.State = 0;
  71.   GetItemInfo(item);
  72.   mis.itemHeight = item.Extent.cy;
  73.   mis.itemWidth  = item.Extent.cx;
  74.   if (item.Extent.cx > MaxWidth) {
  75.      SetHorizontalExtent(MaxWidth = item.Extent.cx);
  76.   }
  77.   ::ReleaseDC(*this, item.Hdc);
  78. }
  79.  
  80. // The following methods are defaults for use with text string items only.
  81. // These must be overridden if for data items that are not standard text.
  82. // If the style LBS_HASSTRINGS is set, strings are stored within the list box.
  83. // Otherwise only the pointers are stored; data must be managed by the caller.
  84.  
  85. BOOL TODListBox::GetItemInfo(ODItemInfo& item) {
  86.   LPSTR str;
  87.   int len;
  88.   if (Attr.Style & LBS_HASSTRINGS) {   // strings stored in list box
  89.     len = GetStringLen(item.Index);
  90.     if (len == 0) {
  91.       str = 0;
  92.     } else {
  93.       if (len >= BufLen){  // check temporary buffer size
  94.         if (BufTemp) delete BufTemp;
  95.         BufTemp = new char[BufLen = len+1];
  96.       }
  97.       GetString(str = BufTemp, item.Index);
  98.     }
  99.   } else { // assume text pointer is allocated data stored in item data     
  100.     str = (char far*)item.Data;
  101.     len = str ? lstrlen(str) : 0;
  102.   }
  103.   item.TextLen = len;
  104.   item.Text = str;
  105.   if (!len) {
  106.     str = " ";     // must have text to measure
  107.     len++;
  108.   }
  109.   GetTextExtentPoint(item.Hdc, str, len, &item.Extent);
  110.   item.Extent.cx += 2; // room for focus rectangle
  111.   item.Extent.cy += 2; // room for focus rectangle
  112.   item.Offset.x = 1;   // room for focus rectangle, no indentation
  113.   item.Offset.y = 1;   // room for focus rectangle
  114.   return TRUE;         // OK to draw
  115. }
  116.  
  117. void TODListBox::ChangeHilight(ODItemInfo& item)
  118. {
  119.   InvertRect(item.Hdc, &item.Bound);  // need to fix to do nicer!!
  120. }
  121.  
  122. void TODListBox::ChangeFocus(ODItemInfo& item)
  123. {
  124.   int brushtype = item.State & ODS_FOCUS ? LTGRAY_BRUSH
  125.                 :(item.State & ODS_SELECTED ? BLACK_BRUSH : WHITE_BRUSH);
  126.   FrameRect(item.Hdc, &item.Bound, (HBRUSH)GetStockObject(brushtype));
  127. }
  128.  
  129. void TODListBox::DrawItemData(ODItemInfo& item)
  130. {
  131. //HFONT oldfont = SelectObject(item.Hdc, StdFont);  // need member HFONT StdFont
  132.   ExtTextOut(item.Hdc, 
  133.          item.Bound.left + item.Offset.x,
  134.          item.Bound.top  + item.Offset.y,
  135.          ETO_CLIPPED | ETO_OPAQUE, 
  136.          &item.Bound,
  137.          item.Text, item.TextLen,
  138.          (LPINT) NULL); /* default char spacing */ 
  139. //SelectObject(item.Hdc, oldfont);
  140. }
  141.  
  142. IMPLEMENT_STREAMABLE1(TODListBox, TControl);
  143.  
  144. void*
  145. TODListBox::Streamer::Read(ipstream& is, uint32 /*version*/) const
  146. {
  147.   ReadBaseObject((TControl*)GetObject(), is);
  148.   is >> GetObject()->MaxWidth;
  149.   GetObject()->BufTemp = 0;
  150.   GetObject()->BufLen  = 0;
  151.   return GetObject();
  152. }
  153.  
  154. void
  155. TODListBox::Streamer::Write(opstream& os) const
  156. {
  157.   WriteBaseObject((TControl*)GetObject(), os);
  158.   os << GetObject()->MaxWidth;
  159. }
  160.