ZYZTLB.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:16k
源码类别:

Windows编程

开发平台:

Visual C++

  1. //==========================================================================;
  2. //
  3. //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  4. //  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
  5. //  TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR
  6. //  A PARTICULAR PURPOSE.
  7. //
  8. //  Copyright (C) 1993 - 1997 Microsoft Corporation. All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------;
  11. //
  12. //  zyztlb.c
  13. //
  14. //  Description:
  15. //
  16. //
  17. //  History:
  18. //       5/18/93
  19. //
  20. //==========================================================================;
  21. #include <windows.h>
  22. #include <windowsx.h>
  23. #include <stdlib.h>
  24. #include "appport.h"
  25. #include "zyztlb.h"
  26. #include "debug.h"
  27. //==========================================================================;
  28. //
  29. //
  30. //
  31. //
  32. //==========================================================================;
  33. //--------------------------------------------------------------------------;
  34. //  
  35. //  int GetRealTextMetrics
  36. //  
  37. //  Description:
  38. //      This function gets the textmetrics of the font currently selected
  39. //      into the hdc.  It returns the average char width as the return value.
  40. //
  41. //      This function computes the average character width correctly by
  42. //      using GetTextExtent() on the string "abc...xzyABC...XYZ" which works
  43. //      out much better for proportional fonts. This is also necessary
  44. //      for correct alignment between dialog and client units.
  45. //
  46. //      Note that this function returns the same TEXTMETRIC values that
  47. //      GetTextMetrics() does, it simply has a different return value.
  48. //
  49. //  Arguments:
  50. //      HDC hdc:
  51. //  
  52. //      LPTEXTMETRIC ptm:
  53. //  
  54. //  Return (int):
  55. //  
  56. //  History:
  57. //      05/11/93
  58. //  
  59. //--------------------------------------------------------------------------;
  60. int FNGLOBAL GetRealTextMetrics
  61. (
  62.     HDC             hdc,
  63.     LPTEXTMETRIC    ptm
  64. )
  65. {
  66.     TCHAR       achAlphabet[26 * 2];    // upper and lower case
  67.     SIZE        sSize;
  68.     UINT        u;
  69.     int         nAveWidth;
  70.     //
  71.     //  get the text metrics of the current font. note that GetTextMetrics
  72.     //  gets the incorrect nAveCharWidth value for proportional fonts.
  73.     //
  74.     GetTextMetrics(hdc, ptm);
  75.     nAveWidth = ptm->tmAveCharWidth;
  76.     //
  77.     //  if it's not a variable pitch font GetTextMetrics was correct
  78.     //  so just return.
  79.     //
  80.     if (ptm->tmPitchAndFamily & FIXED_PITCH)
  81.     {
  82. //
  83. //
  84. //
  85. for (u = 0; u < 26; u++)
  86. {
  87.     achAlphabet[u]      = (TCHAR)(u + (UINT)'a');
  88.     achAlphabet[u + 26] = (TCHAR)(u + (UINT)'A');
  89. }
  90. //
  91. //  round up
  92. //
  93. GetTextExtentPoint(hdc, achAlphabet, SIZEOF(achAlphabet), &sSize);
  94. nAveWidth = ((sSize.cx / 26) + 1) / 2;
  95.     }
  96.     //
  97.     //  return the calculated average char width
  98.     //
  99.     return (nAveWidth);
  100. } // GetRealTextMetrics()
  101. //==========================================================================;
  102. //
  103. //
  104. //
  105. //
  106. //==========================================================================;
  107. //--------------------------------------------------------------------------;
  108. //  
  109. //  BOOL TlbPaint
  110. //  
  111. //  Description:
  112. //  
  113. //  
  114. //  Arguments:
  115. //      PZYZTABBEDLISTBOX ptlb:
  116. //  
  117. //      HWND hwnd:
  118. //  
  119. //      HDC hdc:
  120. //  
  121. //  Return (BOOL):
  122. //  
  123. //  History:
  124. //      05/17/93
  125. //  
  126. //--------------------------------------------------------------------------;
  127. BOOL FNGLOBAL TlbPaint
  128. (
  129.     PZYZTABBEDLISTBOX   ptlb,
  130.     HWND                hwnd,
  131.     HDC                 hdc
  132. )
  133. {
  134.     RECT        rc;
  135.     HFONT       hfont;
  136.     COLORREF    crBk;
  137.     COLORREF    crText;
  138.     int         nHeight;
  139.     //
  140.     //
  141.     //
  142.     hfont = GetWindowFont(ptlb->hlb);
  143.     if (NULL == hfont)
  144. hfont = GetStockFont(SYSTEM_FONT);
  145.     hfont = SelectObject(hdc, hfont);
  146.     crBk   = SetBkColor(hdc, GetSysColor(COLOR_ACTIVECAPTION));
  147.     crText = SetTextColor(hdc, GetSysColor(COLOR_CAPTIONTEXT));
  148.     //
  149.     //  compute bounding rect for title only
  150.     //
  151.     rc = ptlb->rc;
  152.     nHeight = min(ptlb->nFontHeight, rc.bottom - rc.top);
  153.     rc.bottom = rc.top + nHeight;
  154.     ExtTextOut(hdc, rc.left, rc.top, ETO_OPAQUE, &rc, NULL, 0, NULL);
  155.     TabbedTextOut(hdc, rc.left, rc.top,
  156.   ptlb->pszTitleText,
  157.   ptlb->cchTitleText,
  158.   ptlb->uTabStops,
  159.   ptlb->panTitleTabs, 0);
  160.     //
  161.     //  restore the dc
  162.     //
  163.     SetBkColor(hdc, crBk);
  164.     SetTextColor(hdc, crText);
  165.     SelectObject(hdc, hfont);
  166.     return (TRUE);
  167. } // TlbPaint()
  168. //--------------------------------------------------------------------------;
  169. //  
  170. //  BOOL TlbMove
  171. //  
  172. //  Description:
  173. //  
  174. //  
  175. //  Arguments:
  176. //      PZYZTABBEDLISTBOX ptlb:
  177. //  
  178. //      PRECT prc:
  179. //  
  180. //      BOOL fRedraw:
  181. //  
  182. //  Return (BOOL):
  183. //  
  184. //  History:
  185. //      05/16/93
  186. //  
  187. //--------------------------------------------------------------------------;
  188. BOOL FNGLOBAL TlbMove
  189. (
  190.     PZYZTABBEDLISTBOX   ptlb,
  191.     PRECT               prc,
  192.     BOOL                fRedraw
  193. )
  194. {
  195.     RECT        rc;
  196.     int         nHeight;
  197.     HWND        hwnd;
  198.     hwnd = GetParent(ptlb->hlb);
  199.     //
  200.     //  invalidate only the region occupied by the current title bar. this
  201.     //  will make sure that area gets repainted. the listbox portion will
  202.     //  be invalidated correctly by the SetWindowPos() function below..
  203.     //
  204.     rc = ptlb->rc;
  205.     nHeight = min(ptlb->nFontHeight, rc.bottom - rc.top);
  206.     rc.bottom = rc.top + nHeight;
  207.     InvalidateRect(hwnd, &rc, TRUE);
  208.     //
  209.     //  now move the listbox--we modify values in the rect structure, so
  210.     //  copy to local storage
  211.     //
  212.     rc = *prc;
  213.     //
  214.     //  leave room at the top of the bounding rect for the title text
  215.     //
  216.     nHeight = min(ptlb->nFontHeight, rc.bottom - rc.top);
  217.     rc.top += nHeight;
  218.     SetWindowPos(ptlb->hlb, NULL, rc.left, rc.top, rc.right - rc.left,
  219.  rc.bottom - rc.top, SWP_NOZORDER);
  220.     //
  221.     //  save the new location and invalidate the area so it is repainted
  222.     //
  223.     ptlb->rc = *prc;
  224.     InvalidateRect(hwnd, prc, TRUE);
  225.     if (fRedraw)
  226.     {
  227. UpdateWindow(hwnd);
  228.     }
  229.     return (TRUE);
  230. } // TlbMove()
  231. //--------------------------------------------------------------------------;
  232. //  
  233. //  BOOL TlbRecalcTabs
  234. //  
  235. //  Description:
  236. //  
  237. //  
  238. //  Arguments:
  239. //      PZYZTABBEDLISTBOX ptlb:
  240. //  
  241. //  Return (BOOL):
  242. //  
  243. //  History:
  244. //      05/18/93
  245. //  
  246. //--------------------------------------------------------------------------;
  247. BOOL FNLOCAL TlbRecalcTabs
  248. (
  249.     PZYZTABBEDLISTBOX   ptlb
  250. )
  251. {
  252.     static TCHAR szGonzoThing[] = TEXT("M");
  253.     int         anTabsList[TLB_MAX_TAB_STOPS];
  254.     HDC         hdc;
  255.     HFONT       hfont;
  256.     TEXTMETRIC  tm;
  257.     int         nAveCharWidth;
  258.     UINT        u;
  259.     int         nWidth;
  260.     int         nPrevTabTitle;
  261.     int         nPrevTabList;
  262.     SIZE        sSize;
  263.     //
  264.     //
  265.     //
  266.     hdc = GetDC(NULL);
  267.     {
  268. //
  269. //  get the average char width and height of the current font so we
  270. //  can compute tabs correctly. note that GetTextMetrics is pretty
  271. //  bogus when it comes to the average char width--it normally gives
  272. //  you the width of the character 'x'. what it should be is the
  273. //  average width of all capitals and lower case letters..
  274. //
  275. hfont = GetWindowFont(ptlb->hlb);
  276. if (NULL == hfont)
  277.     hfont = GetStockFont(SYSTEM_FONT);
  278. hfont = SelectObject(hdc, hfont);
  279. #if 0
  280. GetTextMetrics(hdc, &tm);
  281. nAveCharWidth = tm.tmAveCharWidth;
  282. #else
  283. nAveCharWidth = GetRealTextMetrics(hdc, &tm);
  284. #endif
  285. ptlb->nFontHeight = tm.tmHeight;
  286. //
  287. //
  288. //
  289. GetTextExtentPoint(hdc, szGonzoThing, 1, &sSize);
  290. //
  291. //
  292. //
  293. hfont = SelectObject(hdc, hfont);
  294.     }
  295.     ReleaseDC(NULL, hdc);
  296.     //
  297.     //  calculate the width of each column
  298.     //
  299.     nPrevTabTitle = 0;
  300.     nPrevTabList  = 0;
  301.     for (u = 0; u < ptlb->uTabStops; u++)
  302.     {
  303. //      nWidth = nAveCharWidth * ptlb->panTabs[u] + nAveCharWidth * 2;
  304. nWidth = sSize.cx * ptlb->panTabs[u] + (sSize.cx * 2);
  305. //
  306. //  set tabstop for title text--this is in client units
  307. //  for TabbedTextOut in TlbPaint
  308. //
  309. ptlb->panTitleTabs[u] = nPrevTabTitle + nWidth;
  310. nPrevTabTitle = ptlb->panTitleTabs[u];
  311. //
  312. //  set tabstop for listbox--this is in dialog units
  313. //
  314. anTabsList[u] = nPrevTabList + MulDiv(nWidth, 4, nAveCharWidth);
  315. nPrevTabList  = anTabsList[u];
  316.     }
  317.     //
  318.     //  now setup the tabstops in the listbox
  319.     //
  320.     ListBox_SetTabStops(ptlb->hlb, ptlb->uTabStops, anTabsList);
  321.     return (TRUE);
  322. } // TlbRecalcTabs()
  323. //--------------------------------------------------------------------------;
  324. //  
  325. //  HFONT TlbSetFont
  326. //  
  327. //  Description:
  328. //  
  329. //  
  330. //  Arguments:
  331. //      PZYZTABBEDLISTBOX ptlb:
  332. //  
  333. //      HFONT hfont:
  334. //  
  335. //      BOOL fRedraw:
  336. //  
  337. //  Return (HFONT):
  338. //  
  339. //  History:
  340. //      05/16/93
  341. //  
  342. //--------------------------------------------------------------------------;
  343. HFONT FNGLOBAL TlbSetFont
  344. (
  345.     PZYZTABBEDLISTBOX   ptlb,
  346.     HFONT               hfont,
  347.     BOOL                fRedraw
  348. )
  349. {
  350.     HFONT       hfontOld;
  351.     //
  352.     //
  353.     //
  354.     hfontOld = GetWindowFont(ptlb->hlb);
  355.     SetWindowFont(ptlb->hlb, hfont, FALSE);
  356.     TlbRecalcTabs(ptlb);
  357.     TlbMove(ptlb, &ptlb->rc, fRedraw);
  358.     return (hfontOld);
  359. } // TlbSetFont()
  360. //--------------------------------------------------------------------------;
  361. //  
  362. //  BOOL TlbSetTitleAndTabs
  363. //  
  364. //  Description:
  365. //      This function sets the title text and tab stops for a Tabbed List
  366. //      Box (TLB). The pszTitleFormat specifies the title text for each
  367. //      column along with the tabstop position for each column. The format
  368. //      of this string is as follows:
  369. //
  370. //      <columnname1>t<tab1>!<columnname2>
  371. //
  372. //      TCHAR   szTlbThings[] = TEXT("Indext6!Codet5!Name");
  373. //
  374. //
  375. //  Arguments:
  376. //      PZYZTABBEDLISTBOX ptlb:
  377. //  
  378. //      PTSTR pszTitleFormat:
  379. //
  380. //      BOOL fRedraw:
  381. //  
  382. //  Return (BOOL):
  383. //  
  384. //  History:
  385. //      05/18/93
  386. //  
  387. //--------------------------------------------------------------------------;
  388. BOOL FNGLOBAL TlbSetTitleAndTabs
  389. (
  390.     PZYZTABBEDLISTBOX   ptlb,
  391.     PTSTR               pszTitleFormat,
  392.     BOOL                fRedraw
  393. )
  394. {
  395.     TCHAR       szTitleText[TLB_MAX_TITLE_CHARS];
  396.     int         anTabs[TLB_MAX_TAB_STOPS];
  397.     PTSTR       pch;
  398.     PTSTR       pchTitleText;
  399.     UINT        uTabStops;
  400.     UINT        cchTitleText;
  401.     HWND        hwnd;
  402.     //
  403.     //  parse the title format counting tab stops and actual size of title
  404.     //  text
  405.     //
  406.     uTabStops    = 0;
  407.     pchTitleText = szTitleText;
  408.     for (pch = pszTitleFormat; '' != *pch; )
  409.     {
  410. TCHAR       ch;
  411. //
  412. //  scan to tab
  413. //
  414. while ('' != (ch = *pch))
  415. {
  416.     *pchTitleText++ = *pch++;
  417.     if ('t' == ch)
  418. break;
  419. }
  420. if ('' == ch)
  421.     break;
  422. //
  423. //  grab the next tab stop value
  424. //
  425. anTabs[uTabStops] = atoi(pch);
  426. uTabStops++;
  427. //
  428. //  skip to start of next column name
  429. //
  430. while ('!' != *pch++)
  431.     ;
  432.     }
  433.     //
  434.     //  terminate the converted title text
  435.     //
  436.     *pchTitleText = '';
  437.     cchTitleText = lstrlen(szTitleText);
  438.     //
  439.     //  free the memory used for the previous tab stops and title text
  440.     //
  441.     if (NULL != ptlb->panTabs)
  442.     {
  443. LocalFree((HLOCAL)ptlb->panTabs);
  444. ptlb->uTabStops    = 0;
  445. ptlb->panTabs      = NULL;
  446. ptlb->panTitleTabs = NULL;
  447.     }
  448.     if (NULL != ptlb->pszTitleText)
  449.     {
  450. LocalFree((HLOCAL)ptlb->pszTitleText);
  451. ptlb->cchTitleText = 0;
  452. ptlb->pszTitleText = NULL;
  453.     }
  454.     //
  455.     //  allocate new space for tab stops. there are two different tab
  456.     //  arrays:
  457.     //
  458.     //      panTabs: original tab values as passed by caller. these are
  459.     //      virtual tab locations represented as number of characters. we
  460.     //      need to keep these values for recomputing the real tabs when
  461.     //      the font changes.
  462.     //
  463.     //      panTitleTabs: these values are computed by TlbRecalcTabs and
  464.     //      are actual tab positions in client coordinates for the title
  465.     //      text (needed for TabbedTextOut in TlbPaint).
  466.     //
  467.     //  the tabs for the listbox are computed and set in TlbRecalcTabs
  468.     //
  469.     if (0 != uTabStops)
  470.     {
  471. ptlb->panTabs = (PINT)LocalAlloc(LPTR, (uTabStops * sizeof(int)) * 2);
  472. if (NULL == ptlb->panTabs)
  473.     return (FALSE);
  474. ptlb->uTabStops    = uTabStops;
  475. ptlb->panTitleTabs = ptlb->panTabs + uTabStops;
  476. memcpy(ptlb->panTabs, anTabs, uTabStops * sizeof(int));
  477.     }
  478.     //
  479.     //  allocate space for the converted title text (stripped of the tab
  480.     //  spacing values). this string is passed directly to TabbedTextOut
  481.     //  in TlbPaint.
  482.     //
  483.     if (0 != cchTitleText)
  484.     {
  485. ptlb->pszTitleText = (PTSTR)LocalAlloc(LPTR, (cchTitleText + 1) * sizeof(TCHAR));
  486. if (NULL == ptlb->pszTitleText)
  487.     return (FALSE);
  488. ptlb->cchTitleText = cchTitleText;
  489. lstrcpy(ptlb->pszTitleText, szTitleText);
  490.     }
  491.     //
  492.     //
  493.     //
  494.     TlbRecalcTabs(ptlb);
  495.     //
  496.     //  force a complete repaint of the title text and listbox--redraw
  497.     //  immediately if we are supposed to
  498.     //
  499.     hwnd = GetParent(ptlb->hlb);
  500.     InvalidateRect(hwnd, &ptlb->rc, TRUE);
  501.     if (fRedraw)
  502.     {
  503. UpdateWindow(hwnd);
  504.     }
  505. } // TlbSetTitleAndTabs()
  506. //--------------------------------------------------------------------------;
  507. //  
  508. //  PZYZTABBEDLISTBOX TlbDestroy
  509. //  
  510. //  Description:
  511. //  
  512. //  
  513. //  Arguments:
  514. //      PZYZTABBEDLISTBOX ptlb:
  515. //  
  516. //  Return (PZYZTABBEDLISTBOX):
  517. //  
  518. //  History:
  519. //      05/16/93
  520. //  
  521. //--------------------------------------------------------------------------;
  522. PZYZTABBEDLISTBOX FNGLOBAL TlbDestroy
  523. (
  524.     PZYZTABBEDLISTBOX   ptlb
  525. )
  526. {
  527.     HWND        hwnd;
  528.     int         nHeight;
  529.     //
  530.     //  get rid of the listbox
  531.     //
  532.     if (NULL != ptlb->hlb)
  533.     {
  534. DestroyWindow(ptlb->hlb);
  535. //
  536. //  invalidate area where title text was so it will be clean
  537. //
  538. nHeight = min(ptlb->nFontHeight, ptlb->rc.bottom - ptlb->rc.top);
  539. ptlb->rc.bottom = ptlb->rc.top + nHeight;
  540. hwnd = GetParent(ptlb->hlb);
  541. InvalidateRect(hwnd, &ptlb->rc, TRUE);
  542. //
  543. //  free the memory used for tab stops and title text
  544. //
  545. if (NULL != ptlb->panTabs)
  546.     LocalFree((HLOCAL)ptlb->panTabs);
  547. if (NULL != ptlb->pszTitleText)
  548.     LocalFree((HLOCAL)ptlb->pszTitleText);
  549.     }
  550.     LocalFree((HLOCAL)ptlb);
  551.     return (NULL);
  552. } // TlbDestroy()
  553. //--------------------------------------------------------------------------;
  554. //  
  555. //  PZYZTABBEDLISTBOX TlbCreate
  556. //  
  557. //  Description:
  558. //  
  559. //  
  560. //  Arguments:
  561. //      HWND hwnd:
  562. //  
  563. //      int nId:
  564. //  
  565. //      PRECT prc:
  566. //  
  567. //  Return (PZYZTABBEDLISTBOX):
  568. //  
  569. //  History:
  570. //      05/16/93
  571. //  
  572. //--------------------------------------------------------------------------;
  573. PZYZTABBEDLISTBOX FNGLOBAL TlbCreate
  574. (
  575.     HWND                hwnd,
  576.     int                 nId,
  577.     PRECT               prc
  578. )
  579. {
  580.     #define TLB_DEF_STYLE   (WS_VISIBLE|WS_CHILD|WS_VSCROLL|WS_BORDER|  
  581.      LBS_NOTIFY|LBS_NOINTEGRALHEIGHT|LBS_USETABSTOPS)
  582.     static TCHAR    szNull[]    = TEXT("");
  583.     static TCHAR    szListBox[] = TEXT("ListBox");
  584.     PZYZTABBEDLISTBOX   ptlb;
  585.     HINSTANCE           hinst;
  586.     //
  587.     //  create a new instance data structure..
  588.     //
  589.     ptlb = (PZYZTABBEDLISTBOX)LocalAlloc(LPTR, sizeof(*ptlb));
  590.     if (NULL == ptlb)
  591. return (NULL);
  592.     //
  593.     //  create the listbox
  594.     //
  595.     hinst = GetWindowInstance(hwnd);
  596.     ptlb->hlb = CreateWindow(szListBox, szNull, TLB_DEF_STYLE,
  597.      0, 0, 0, 0, hwnd, (HMENU)nId, hinst, NULL);
  598.     if (NULL == ptlb->hlb)
  599.     {
  600. TlbDestroy(ptlb);
  601. return (NULL);
  602.     }
  603.     TlbRecalcTabs(ptlb);
  604.     if (NULL != prc)
  605.     {
  606. ptlb->rc = *prc;
  607. TlbMove(ptlb, prc, FALSE);
  608.     }
  609.     return (ptlb);
  610. } // TlbCreate()