|
|
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.