home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / v / vlistbox.zip / VLRARE.C < prev    next >
C/C++ Source or Header  |  1993-01-18  |  8KB  |  293 lines

  1. #include "vlistint.h"
  2.  
  3. LONG VLBNcCreateHandler( HWND hwnd, LPCREATESTRUCT lpcreateStruct)
  4. {
  5.   PVLBOX pVLBox;
  6.  
  7.   //
  8.   // Allocate storage for the vlbox structure
  9.   //
  10.   pVLBox = (PVLBOX) LocalAlloc(LPTR, sizeof(VLBOX));
  11.  
  12.   if (!pVLBox)
  13.       // Error, no memory
  14.       return((long)NULL);
  15.  
  16. #ifdef WIN32
  17.   SetWindowLong(hwnd, 0, (WPARAM)pVLBox);
  18. #else
  19.   SetWindowWord(hwnd, 0, (WPARAM)pVLBox);
  20. #endif
  21.  
  22.   pVLBox->styleSave = lpcreateStruct->style;
  23.  
  24.   //
  25.   // Make sure that ther are no scroll bar styles
  26.   //
  27.   SetWindowLong(hwnd, GWL_STYLE,
  28.                 (LPARAM)(DWORD)( pVLBox->styleSave &
  29.                 ~WS_VSCROLL & ~WS_HSCROLL));
  30.  
  31.  
  32.   return((LONG)hwnd);
  33.  
  34. }
  35.  
  36.  
  37. LONG VLBCreateHandler( PVLBOX pVLBox, HWND hwnd, LPCREATESTRUCT lpcreateStruct)
  38. {
  39.   LONG           windowStyle = pVLBox->styleSave;
  40.   RECT           rc;
  41.   TEXTMETRIC     TextMetric;
  42.   HDC            hdc;
  43.  
  44.   //
  45.   // Initialize Variables
  46.   //
  47.   pVLBox->hwnd            = hwnd;
  48.   pVLBox->hwndParent      = lpcreateStruct->hwndParent;
  49.   pVLBox->nId             = (int) lpcreateStruct->hMenu;
  50.   pVLBox->hInstance       = lpcreateStruct->hInstance;
  51.   pVLBox->nvlbRedrawState = 1;
  52.   pVLBox->lNumLogicalRecs = -2L;
  53.   pVLBox->lSelItem        = -1L;
  54.   pVLBox->wFlags          = 0;
  55.   pVLBox->hwndList        = NULL;
  56.  
  57.   //
  58.   // Check for USEDATAVALUES
  59.   //
  60.   if ( windowStyle & VLBS_USEDATAVALUES )
  61.       pVLBox->wFlags  |= USEDATAVALUES;
  62.   else
  63.       pVLBox->wFlags &= ~USEDATAVALUES;
  64.  
  65.   //
  66.   // Dertermine if this VLB is storing string
  67.   //
  68.   pVLBox->wFlags |= HASSTRINGS;
  69.   if ((windowStyle & VLBS_OWNERDRAWFIXED )
  70.      && (!(windowStyle & VLBS_HASSTRINGS)))
  71.      pVLBox->wFlags &= ~HASSTRINGS;
  72.  
  73.   //
  74.   // Get the font height and Number of lines
  75.   //
  76.   hdc = GetDC(hwnd);
  77.   GetTextMetrics(hdc, &TextMetric);
  78.   ReleaseDC(hwnd,hdc);
  79.   pVLBox->nchHeight = TextMetric.tmHeight;
  80.   GetClientRect(hwnd,&rc);
  81.   pVLBox->nLines = ((rc.bottom - rc.top) / pVLBox->nchHeight);
  82.  
  83.   //
  84.   // Remove borders and scroll bars, add keyboard input
  85.   //
  86.   windowStyle = windowStyle & ~WS_BORDER & ~WS_THICKFRAME;
  87.   windowStyle = windowStyle & ~WS_VSCROLL & ~WS_HSCROLL;
  88.  
  89.   //
  90.   // Remove regular list box we don't support
  91.   //
  92.   windowStyle = windowStyle & ~LBS_SORT;
  93.   windowStyle = windowStyle & ~LBS_MULTIPLESEL;
  94.   windowStyle = windowStyle & ~LBS_OWNERDRAWVARIABLE;
  95.   windowStyle = windowStyle & ~LBS_MULTICOLUMN;
  96.   windowStyle = windowStyle & ~VLBS_USEDATAVALUES;
  97.  
  98.   //
  99.   // Add List box styles we have to have
  100.   //
  101.   windowStyle = windowStyle | LBS_WANTKEYBOARDINPUT;
  102.   windowStyle = windowStyle | LBS_NOINTEGRALHEIGHT;
  103.   windowStyle = windowStyle | LBS_NOTIFY;
  104.  
  105.   //
  106.   // create the list box window
  107.   //
  108.   pVLBox->hwndList =
  109.     CreateWindowEx((DWORD)0L,
  110.                  (LPSTR)"LISTBOX",(LPSTR)NULL,
  111.                  windowStyle | WS_CHILD,
  112.                  0,
  113.                  0,
  114.                  rc.right,
  115.                  rc.bottom,
  116.                  pVLBox->hwnd,
  117.                  (HMENU)VLBLBOXID,
  118.                  pVLBox->hInstance,
  119.                  NULL);
  120.  
  121.   if (!pVLBox->hwndList)
  122.       return((LONG)-1L);
  123.  
  124.   if ( pVLBox->styleSave & VLBS_DISABLENOSCROLL ) {
  125.      ShowScrollBar(pVLBox->hwndList, SB_VERT, TRUE);
  126.      EnableScrollBar(pVLBox->hwndList, SB_VERT, ESB_DISABLE_BOTH);
  127.      if ( pVLBox->styleSave & WS_HSCROLL) {
  128.         pVLBox->bHScrollBar = TRUE;
  129.         ShowScrollBar(pVLBox->hwndList, SB_HORZ, TRUE);
  130.         EnableScrollBar(pVLBox->hwndList, SB_HORZ, ESB_DISABLE_BOTH);
  131.         VLBCountLines(pVLBox);
  132.      }
  133.   }
  134.   else {
  135.      pVLBox->bHScrollBar = FALSE;
  136.   }
  137.  
  138.   //
  139.   // Subclass the list box
  140.   //
  141.   pVLBox->lpfnLBWndProc = (WNDPROC)SetWindowLong(pVLBox->hwndList, GWL_WNDPROC,
  142.                                         (LONG)(WNDPROC)LBSubclassProc);
  143.  
  144.   return((LONG)hwnd);
  145. }
  146.  
  147. void VLBNcDestroyHandler(HWND hwnd,  PVLBOX pVLBox, WPARAM wParam, LPARAM lParam)
  148. {
  149.  
  150.   if (pVLBox)
  151.       LocalFree((HANDLE)pVLBox);
  152.  
  153.   //
  154.   // In case rogue messages float through after we have freed the pVLBox, set
  155.   // the handle in the window structure to FFFF and test for this value at the
  156.   // top of the WndProc
  157.   //
  158. #ifdef WIN32
  159.   SetWindowLong(hwnd, 0, (WPARAM)-1);
  160. #else
  161.   SetWindowWord(hwnd, 0, (WPARAM)-1);
  162. #endif
  163.  
  164.   DefWindowProc(hwnd, WM_NCDESTROY, wParam, lParam);
  165. }
  166.  
  167.  
  168. void VLBSetFontHandler( PVLBOX pVLBox, HANDLE hFont, BOOL fRedraw)
  169. {
  170.   pVLBox->hFont = hFont;
  171.  
  172. #ifdef WIN32
  173.   SendMessage(pVLBox->hwndList, WM_SETFONT, (WPARAM)hFont, (LPARAM)MAKELPARAM(FALSE,0));
  174. #else
  175.   SendMessage(pVLBox->hwndList, WM_SETFONT, (WPARAM)hFont, (LPARAM)FALSE);
  176. #endif
  177.  
  178.   VLBSizeHandler(pVLBox, 0);
  179.  
  180.   if (fRedraw)
  181.     {
  182.       InvalidateRect(pVLBox->hwnd, NULL, TRUE);
  183.     }
  184. }
  185.  
  186.  
  187. void VLBSizeHandler( PVLBOX pVLBox, int nItemHeight)
  188. //
  189. // Recalculates the sizes of the internal control in response to a
  190. // resizing of the Virtual List Box window.
  191. //
  192. {
  193.   HDC             hdc;
  194.   TEXTMETRIC      TextMetric;
  195.   RECT            rcWindow;
  196.   RECT            rcClient;
  197.   HANDLE          hOldFont;
  198.  
  199.   //
  200.   // Set the line height
  201.   //
  202.   if ( nItemHeight ) {
  203.     pVLBox->nchHeight = nItemHeight;
  204.   }
  205.   else if ( (pVLBox->styleSave & VLBS_OWNERDRAWFIXED) ) {
  206.     pVLBox->nchHeight = (int) SendMessage(pVLBox->hwndList, LB_GETITEMHEIGHT, 0,0L);
  207.   }
  208.   else {
  209.     hdc = GetDC(pVLBox->hwndList);
  210.     if (pVLBox->hFont)
  211.        hOldFont = SelectObject(hdc, pVLBox->hFont);
  212.     GetTextMetrics(hdc, &TextMetric);
  213.     pVLBox->nchHeight = TextMetric.tmHeight;
  214.     if (pVLBox->hFont)
  215.        SelectObject(hdc, hOldFont);
  216.     ReleaseDC(pVLBox->hwndList,hdc);
  217.   }
  218.  
  219.   //
  220.   // Get the main windows client area
  221.   //
  222.   GetClientRect(pVLBox->hwnd,&rcClient);
  223.  
  224.   //
  225.   // If there is a Window and
  226.   // If the list box is integral height ...
  227.   //
  228.   if ( pVLBox->hwnd && !(pVLBox->styleSave & VLBS_NOINTEGRALHEIGHT) ) {
  229.       //
  230.       // Does it need adjusting ??????
  231.       //
  232.       if (rcClient.bottom % pVLBox->nchHeight) {
  233.           //
  234.           // Adjust
  235.           //
  236.              GetWindowRect(pVLBox->hwnd,&rcWindow);
  237.              SetWindowPos(pVLBox->hwnd, NULL, 0, 0,
  238.                  rcWindow.right - rcWindow.left,
  239.                  ((rcClient.bottom / pVLBox->nchHeight) * pVLBox->nchHeight)
  240.                      + ((rcWindow.bottom-rcWindow.top) - (rcClient.bottom)),
  241.                  SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
  242.       }
  243.   }
  244.  
  245.   //
  246.   // Now adjust the child list box to fill the new main window's
  247.   // client area.
  248.   //
  249.   if ( pVLBox->hwndList ) {
  250.       //
  251.       // Get the main windows client area
  252.       //
  253.       GetClientRect(pVLBox->hwnd,&rcClient);
  254.       SetWindowPos(pVLBox->hwndList, NULL, 0, 0,
  255.          rcClient.right+(GetSystemMetrics(SM_CXBORDER)*2),
  256.          rcClient.bottom+(GetSystemMetrics(SM_CXBORDER)*2),
  257.          SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
  258.   }
  259.  
  260.   VLBCountLines( pVLBox);
  261. }
  262.  
  263.  
  264.  
  265. void VLBCountLines( PVLBOX pVLBox)
  266. {
  267.   RECT            rcClient;
  268.  
  269.   //
  270.   // calculate the number of lines
  271.   //
  272.   GetClientRect(pVLBox->hwndList,&rcClient);
  273.   pVLBox->nLines = rcClient.bottom / pVLBox->nchHeight;
  274.  
  275.   //
  276.   // If there is stuff already int the list box
  277.   // update the display ( more items or fewer items now )
  278.   //
  279.   if ( pVLBox->lNumLogicalRecs != -2L ) {
  280.       if ( pVLBox->lNumLogicalRecs <= pVLBox->nLines ) {
  281.          VLBFirstPage(pVLBox);
  282.       }
  283.       else if ( pVLBox->wFlags & USEDATAVALUES ) {
  284.           VLBFindPage(pVLBox, SendMessage(pVLBox->hwndList, LB_GETITEMDATA, 0, 0L), FALSE );
  285.       }
  286.       else {
  287.           VLBFindPage(pVLBox, pVLBox->lToplIndex, FALSE);
  288.       }
  289.  
  290.   }
  291.  
  292. }
  293.