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