home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / winnt / ddespy / testsubs.c < prev   
C/C++ Source or Header  |  1997-10-05  |  10KB  |  355 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993-1997 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. /*
  13.  * TESTSUBS.C
  14.  *
  15.  *   String formatting class, window procedure and helper functions
  16.  */
  17.  
  18. #define UNICODE
  19. #include <windows.h>
  20. #include <windowsx.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include "ddespy.h"
  24. #include "globals.h"
  25.  
  26. #define OFF2P(psw, off)  ((TCHAR *)psw + off)
  27. #define BOUND(n, min, max) ((n) < (min) ? (min) : ((n) > (max) ? (max) : n))
  28.  
  29. INT cyChar;                     /* Height of a line */
  30. INT cxChar;
  31. INT cyDescent;
  32.  
  33.  
  34. /***************************** Public  Function ****************************\
  35. * BOOL InitTestSubs( )
  36. *
  37. * This routine MUST be called before using anything in this file.  Registers
  38. * window classes, loads brushes, etc.  Returns TRUE if successful, FALSE
  39. * otherwise.
  40. *
  41. \***************************************************************************/
  42.  
  43. BOOL InitTestSubs()
  44. {
  45.     WNDCLASS cls;
  46.  
  47.     cls.style =         0;
  48.     cls.lpfnWndProc =   (WNDPROC)StrWndProc;
  49.     cls.cbClsExtra =    0;
  50.     cls.cbWndExtra =    sizeof(HANDLE);
  51.     cls.hInstance =     hInst;
  52.     cls.hIcon =         NULL;
  53.     cls.hCursor =       LoadCursor(NULL, IDC_ARROW);
  54.     cls.hbrBackground = (HBRUSH)COLOR_WINDOW;
  55.     cls.lpszMenuName =  NULL;
  56.     cls.lpszClassName = (LPCTSTR) RefString(IDS_STRINGCLASS);
  57.  
  58.     if (!RegisterClass((WNDCLASS FAR * ) & cls))
  59.         return(FALSE);
  60.  
  61.     return(TRUE);
  62. }
  63.  
  64.  
  65. VOID CloseTestSubs(
  66. HANDLE hInst)
  67. {
  68.     UnregisterClass((LPCTSTR) RefString(IDS_STRINGCLASS), hInst);
  69. }
  70.  
  71.  
  72.  
  73. VOID NextLine( STRWND *psw)
  74. {
  75.     psw->offBottomLine += psw->cchLine;
  76.     if (psw->offBottomLine == psw->offBufferMax)
  77.         psw->offBottomLine = psw->offBuffer;
  78.     psw->offOutput = psw->offBottomLine;
  79.     *OFF2P(psw, psw->offOutput) = TEXT('\0');
  80. }
  81.  
  82.  
  83. /***************************** Public  Function ****************************\
  84. * VOID DrawString(hwnd, sz)
  85. *
  86. * This routine prints a string in the specified StringWindow class window.
  87. * sz is a NEAR pointer to a zero-terminated string, which can be produced
  88. * with wsprintf().
  89. \***************************************************************************/
  90.  
  91. VOID DrawString( HWND hwnd, TCHAR *sz)
  92. {
  93.     register STRWND *psw;
  94.     INT cLines = 1;
  95.     HANDLE hpsw;
  96.  
  97.     hpsw = (HANDLE)GetWindowLong(hwnd, 0);
  98.     psw = (STRWND *)LocalLock(hpsw);
  99.  
  100.     NextLine(psw);
  101.     while (*sz) {
  102.         switch (*sz) {
  103.         case TEXT('\r'):
  104.             break;
  105.  
  106.         case TEXT('\n'):
  107.             *OFF2P(psw, psw->offOutput++) = TEXT('\0');
  108.             NextLine(psw);
  109.             cLines++;
  110.             break;
  111.  
  112.         default:
  113.             *OFF2P(psw, psw->offOutput++) = *sz;
  114.         }
  115.         sz++;
  116.     }
  117.     *OFF2P(psw, psw->offOutput++) = TEXT('\0');
  118.     LocalUnlock(hpsw);
  119.  
  120.     ScrollWindow(hwnd, 0, -((cyChar + cyDescent) * cLines), (LPRECT)NULL,
  121.             (LPRECT)NULL);
  122.     UpdateWindow(hwnd);
  123. }
  124.  
  125. /***************************** Public  Function ****************************\
  126. * "StringWindow" window class
  127. *
  128. * Windows of the "StringWindow" window class are simple scrolling text output
  129. * windows that are refreshed properly as windows are rearranged.  A text buffer
  130. * is maintained to store the characters as they are drawn.
  131. *
  132. * When creating a StringWindow window, lpCreateParams is actually a UINT
  133. * containing the dimensions of the text buffer to be created, if 0L, then
  134. * a 80 by 25 buffer is created.
  135. *
  136. \***************************************************************************/
  137.  
  138. LONG  CALLBACK StrWndProc(HWND hwnd, UINT msg, WPARAM wParam, UINT lParam)
  139. {
  140.     HANDLE hpsw;
  141.     PAINTSTRUCT ps;
  142.     RECT rc;
  143.  
  144.     switch (msg) {
  145.     case WM_CREATE:
  146.         cyChar = 14;
  147.         cxChar = 8;
  148.         cyDescent = 2;
  149.         if (*(PUINT)lParam     == 0L) {
  150.             *(PUINT)lParam     = MAKELONG(80, 50);
  151.         }
  152.         if (!StrWndCreate(hwnd, LOWORD(*(PUINT)lParam), HIWORD(*(PUINT)lParam)))
  153.             return(TRUE);
  154.         break;
  155.  
  156.     case WM_SIZE:
  157.         InvalidateRect(hwnd, NULL, TRUE);
  158.         break;
  159.  
  160.     case WM_DESTROY:
  161.         if ((hpsw = (HANDLE)GetWindowLong(hwnd, 0)) != NULL)
  162.             LocalFree(hpsw);
  163.         break;
  164.  
  165.     case WM_ERASEBKGND:
  166.         GetClientRect(hwnd, (LPRECT) &rc);
  167.         FillRect((HDC) wParam, (LPRECT) &rc, GetStockObject(WHITE_BRUSH));
  168.         break;
  169.  
  170.     case WM_VSCROLL:
  171.         scroll(hwnd, GET_WM_VSCROLL_CODE(wParam, lParam),
  172.                 GET_WM_VSCROLL_POS(wParam, lParam), SB_VERT);
  173.         break;
  174.  
  175.     case WM_HSCROLL:
  176.         scroll(hwnd, GET_WM_HSCROLL_CODE(wParam, lParam),
  177.                 GET_WM_HSCROLL_POS(wParam, lParam), SB_HORZ);
  178.         break;
  179.  
  180.     case WM_PAINT:
  181.         BeginPaint(hwnd, &ps);
  182.         PaintStrWnd(hwnd, &ps);
  183.         EndPaint(hwnd, &ps);
  184.         break;
  185.  
  186.     default:
  187.         return(DefWindowProc(hwnd, msg, wParam, lParam));
  188.         break;
  189.     }
  190.     return(0L);
  191. }
  192.  
  193.  
  194.  
  195. VOID scroll(HWND hwnd, UINT msg, UINT sliderpos, UINT style)
  196. {
  197.     RECT rc;
  198.     INT iPos;
  199.     INT dn;
  200.     HANDLE hpsw;
  201.     register STRWND *psw;
  202.  
  203.     GetClientRect(hwnd, (LPRECT) &rc);
  204.     iPos = GetScrollPos(hwnd, style);
  205.     hpsw = (HANDLE)GetWindowLong(hwnd, 0);
  206.     psw = (STRWND *)LocalLock(hpsw);
  207.  
  208.     switch (msg) {
  209.     case SB_LINEDOWN:
  210.         dn =  1;
  211.         break;
  212.  
  213.     case SB_LINEUP:
  214.         dn = -1;
  215.         break;
  216.  
  217.     case SB_PAGEDOWN:
  218.         if (style == SB_VERT) {
  219.             dn = rc.bottom / (cyChar + cyDescent);
  220.         } else {
  221.             dn = rc.right / cxChar;
  222.         }
  223.         break;
  224.  
  225.     case SB_PAGEUP:
  226.         if (style == SB_VERT) {
  227.             dn = -rc.bottom / (cyChar + cyDescent);
  228.         } else {
  229.             dn = -rc.right / cxChar;
  230.         }
  231.         break;
  232.  
  233.     case SB_THUMBTRACK:
  234.     case SB_THUMBPOSITION:
  235.         dn = sliderpos-iPos;
  236.         break;
  237.  
  238.     default:
  239.         dn = 0;
  240.     }
  241.     if (style == SB_VERT) {
  242.         if (dn = BOUND (iPos + dn, 0, psw->cLine) - iPos) {
  243.             psw->cBottomLine -= dn;
  244.             ScrollWindow (hwnd, 0, -dn * (cyChar + cyDescent), NULL, NULL);
  245.             SetScrollPos (hwnd, SB_VERT, iPos + dn, TRUE);
  246.         }
  247.     } else /* style == SB_HORZ */ {
  248.         if (dn = BOUND (iPos + dn, 0, psw->cchLine) - iPos) {
  249.             psw->cLeftChar += dn;
  250.             ScrollWindow (hwnd, -dn * cxChar, 0, NULL, NULL);
  251.             SetScrollPos (hwnd, SB_HORZ, iPos + dn, TRUE);
  252.         }
  253.     }
  254.     LocalUnlock(hpsw);
  255. }
  256.  
  257.  
  258.  
  259. BOOL StrWndCreate(HWND hwnd, INT cchLine, INT cLine)
  260. {
  261.     register INT off;
  262.     STRWND *psw;
  263.     HANDLE hpsw;
  264.  
  265.     if ((hpsw = LocalAlloc(LMEM_MOVEABLE, sizeof(STRWND)
  266.        + (sizeof (TCHAR) * cchLine * cLine))) == NULL)
  267.         return(FALSE);
  268.     SetWindowLong(hwnd, 0, (UINT)hpsw);
  269.  
  270.  
  271.     psw = (STRWND *)LocalLock(hpsw);
  272.     psw->cchLine       = cchLine;
  273.     psw->cLine         = cLine;
  274.     off                = sizeof(STRWND);
  275.     psw->offBuffer     = off;
  276.     psw->offBufferMax  = off + cchLine * cLine;
  277.     psw->offBottomLine = off;
  278.     psw->offOutput     = off;
  279.     psw->cBottomLine   = 0;
  280.     psw->cLeftChar     = 0;
  281.  
  282.     ClearScreen(psw);
  283.  
  284.     SetScrollRange(hwnd, SB_VERT, 0, cLine, FALSE);
  285.     SetScrollPos(hwnd, SB_VERT, cLine, TRUE);
  286.     SetScrollRange(hwnd, SB_HORZ, 0, cchLine, TRUE);
  287.     LocalUnlock(hpsw);
  288.     return(TRUE);
  289. }
  290.  
  291.  
  292. VOID ClearScreen(register STRWND *psw)
  293. {
  294.     register INT off;
  295.     /*
  296.      * Make all the lines empty
  297.      */
  298.     off = psw->offBuffer;
  299.     while (off < psw->offBufferMax) {
  300.         *OFF2P(psw, off) = TEXT('\0');
  301.         off += psw->cchLine;
  302.     }
  303. }
  304.  
  305.  
  306.  
  307.  
  308. VOID PaintStrWnd( HWND hwnd, LPPAINTSTRUCT pps)
  309. {
  310.     register STRWND *psw;
  311.     register INT off;
  312.     INT x;
  313.     INT y;
  314.     RECT rc, rcOut;
  315.     HANDLE hpsw;
  316.  
  317.  
  318.     SelectObject(pps->hdc, GetStockObject(SYSTEM_FIXED_FONT));
  319.     hpsw = (HANDLE)GetWindowLong(hwnd, 0);
  320.     psw = (STRWND *)LocalLock(hpsw);
  321.  
  322.     GetClientRect(hwnd, (LPRECT)&rc);
  323.     if (!pps->fErase)
  324.         FillRect(pps->hdc, (LPRECT)&rc, GetStockObject(WHITE_BRUSH));
  325.  
  326.     x = rc.left - cxChar * psw->cLeftChar;
  327.     y = rc.bottom - cyDescent + (cyChar + cyDescent) * psw->cBottomLine;
  328.     off = psw->offBottomLine;
  329.  
  330.     if (&pps->rcPaint != NULL)
  331.         IntersectRect((LPRECT)&rc, (LPRECT)&rc, &pps->rcPaint);
  332.  
  333.     do {
  334.         if (y <= rc.top - cyDescent)
  335.             break;
  336.         if (y - cyChar <= rc.bottom) {
  337.             rcOut.left = x;
  338.             rcOut.bottom = y + cyDescent;
  339.             rcOut.right = 1000;
  340.             rcOut.top = y - cyChar;
  341.             DrawText(pps->hdc, (LPTSTR)OFF2P(psw, off), -1, (LPRECT)&rcOut,
  342.                     DT_LEFT | DT_VCENTER | DT_NOCLIP | DT_EXPANDTABS |
  343.                     DT_EXTERNALLEADING | DT_NOPREFIX | DT_TABSTOP | 0x0400);
  344.         }
  345.         y -= cyChar + cyDescent;
  346.         /*
  347.          * Back up to previous line
  348.          */
  349.         if (off == psw->offBuffer)
  350.             off = psw->offBufferMax;
  351.         off -= psw->cchLine;
  352.     } while (off != psw->offBottomLine);
  353.     LocalUnlock(hpsw);
  354. }
  355.