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