|
|
1.1 root 1: /*************************************************************************
2: **
3: ** OLE 2 Sample Code
4: **
5: ** debug2.c
6: **
7: ** This file contains various debug / subclass routines for the
8: ** ABOUT dialog
9: **
10: ** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
11: **
12: *************************************************************************/
13:
14: #include "outline.h"
15: #include <stdlib.h>
16: #include <time.h>
17:
18: extern LPOUTLINEAPP g_lpApp;
19:
20: LONG CALLBACK EXPORT DebugAbout(HWND hWnd, unsigned uMsg, WORD wParam, LONG lParam);
21: void RandomizeStars(HDC hDC);
22: BOOL InitStrings(void);
23: BOOL DrawString(int iCount, HDC hDC, LPRECT rcDrawIn);
24:
25: static FARPROC lpRealAboutProc = 0L;
26: static int width, height;
27: static RECT rc;
28: static HANDLE hStrBlock = NULL;
29: static LPSTR lpStrings = NULL;
30: static WORD wLineHeight;
31:
32:
33: /* Macro to get a random integer within a specified range */
34: #define getrandom( min, max ) ((rand() % (int)(((max)+1) - (min))) + (min))
35:
36:
37: /* TraceDebug
38: * ----------
39: *
40: * Called once when our About Box's gets the INITDIALOG message. Subclasses
41: * dialog.
42: */
43:
44: void TraceDebug(HWND hDlg, int iControl)
45: {
46:
47: // Load strings, if the strings aren't there, then don't subclass
48: // the dialog
49: if (InitStrings() != TRUE)
50: return;
51:
52: // Subclass the dialog
53: lpRealAboutProc = (FARPROC)(LONG)GetWindowLong(hDlg, GWL_WNDPROC);
54: SetWindowLong(hDlg, GWL_WNDPROC, (LONG)(FARPROC)DebugAbout);
55:
56: // Get rect of control in screen coords, and translate to our dialog
57: // box's coordinates
58: GetWindowRect(GetDlgItem(hDlg, iControl), &rc);
59: MapWindowPoints(NULL, hDlg, (LPPOINT)&rc, 2);
60:
61: width = rc.right - rc.left;
62: height = rc.bottom - rc.top;
63: }
64:
65: /* DebugAbout
66: * ----------
67: *
68: * The subclassed About dialog's main window proc.
69: */
70:
71: LONG CALLBACK EXPORT DebugAbout(HWND hWnd, unsigned uMsg, WORD wParam, LONG lParam)
72: {
73: RECT rcOut;
74: static BOOL bTimerStarted = FALSE;
75: static int iTopLocation;
76: HDC hDCScr;
77: static HDC hDCMem;
78: static HBITMAP hBitmap;
79: static HBITMAP hBitmapOld;
80: static RECT rcMem;
81: static HFONT hFont;
82:
83: switch (uMsg)
84: {
85:
86: /*
87: * If we get a LBUTTONDBLCLICK in the upper left of
88: * the dialog, fire off the about box effects
89: */
90:
91: case WM_LBUTTONDBLCLK:
92: if ((wParam & MK_CONTROL) && (wParam & MK_SHIFT)
93: && LOWORD(lParam) < 5 && HIWORD(lParam) < 5 &&
94: bTimerStarted == FALSE)
95: {
96: if (SetTimer ( hWnd, 1, 10, NULL ))
97: {
98: LOGFONT lf;
99: int i;
100:
101: bTimerStarted = TRUE;
102:
103: // "Open up" the window
104: hDCScr = GetDC ( hWnd );
105: hDCMem = CreateCompatibleDC ( hDCScr );
106:
107: hBitmap = CreateCompatibleBitmap(hDCScr, width, height);
108: hBitmapOld = SelectObject(hDCMem, hBitmap);
109:
110: // Blt from dialog to memDC
111: BitBlt(hDCMem, 0, 0, width, height,
112: hDCScr, rc.left, rc.top, SRCCOPY);
113:
114: for (i=0;i<height;i+=1)
115: {
116: BitBlt(hDCScr, rc.left, rc.top + i + 1, width, height-i-1, hDCMem, 0, 0, SRCCOPY);
117: PatBlt(hDCScr, rc.left, rc.top + i, width, 1, BLACKNESS);
118: }
119:
120: SelectObject(hDCMem, hBitmapOld);
121: DeleteObject(hBitmap);
122:
123: // Set up memory DC with default attributes
124: hBitmap = CreateCompatibleBitmap(hDCScr, width, height);
125: ReleaseDC(hWnd, hDCScr);
126:
127: hBitmapOld = SelectObject(hDCMem, hBitmap);
128:
129: SetBkMode(hDCMem, TRANSPARENT);
130: SetBkColor(hDCMem, RGB(0,0,0));
131:
132: // Create font
133: memset(&lf, 0, sizeof(LOGFONT));
134: lf.lfHeight = -(height / 7); // Fit 7 lines of text in box
135: lf.lfWeight = FW_BOLD;
136: strcpy(lf.lfFaceName, "Arial");
137: hFont = CreateFontIndirect(&lf);
138:
139: // If we can't create the font, revert and use the standard
140: // system font.
141: if (!hFont)
142: GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT), &lf);
143:
144: wLineHeight = abs(lf.lfHeight) + 5; // 5 pixels between lines
145:
146: // Set location of top of banner at bottom of the window
147: iTopLocation = height + 50;
148:
149: SetRect(&rcMem, 0, 0, width, height);
150: }
151: }
152: // Call our real window procedure in case they want to
153: // handle LBUTTONDOWN messages also
154: goto Default;
155:
156: case WM_TIMER:
157: {
158: int iCount;
159: HFONT hfold;
160:
161: /*
162: * On each timer message, we are going to construct the next image
163: * in the animation sequence, then bitblt this to our dialog.
164: */
165:
166: // Clear out old bitmap and place random star image on background
167: PatBlt(hDCMem, rcMem.left, rcMem.top, rcMem.right, rcMem.bottom, BLACKNESS);
168: RandomizeStars(hDCMem);
169:
170: // Set initial location to draw text
171: rcOut = rcMem;
172: rcOut.top = 0 + iTopLocation;
173: rcOut.bottom = rcOut.top + wLineHeight;
174:
175: iCount = 0;
176: if (hFont) hfold = SelectObject(hDCMem, hFont);
177:
178: SetTextColor(hDCMem, RGB(0,255,0));
179: while (DrawString(iCount, hDCMem, &rcOut) == TRUE)
180: {
181: rcOut.top += wLineHeight;
182: rcOut.bottom += wLineHeight;
183: iCount++;
184: }
185: if (hFont) SelectObject(hDCMem, hfold);
186:
187: // Now blt the memory dc that we have just constructed
188: // to the screen
189: hDCScr = GetDC(hWnd);
190: BitBlt(hDCScr, rc.left, rc.top, rc.right, rc.bottom,
191: hDCMem, 0, 0, SRCCOPY);
192: ReleaseDC(hWnd, hDCScr);
193:
194: // For the next animation sequence, we want to move the
195: // whole thing up, so decrement the location of the top
196: // of the banner
197:
198: iTopLocation -= 2;
199:
200: // If we've gone through the banner once, reset it
201: if (iTopLocation < -(int)(wLineHeight * iCount))
202: iTopLocation = height + 50;
203: }
204: // Goto default
205: goto Default;
206:
207: case WM_NCDESTROY:
208: {
209: LONG defReturn;
210:
211: /*
212: * We're being destroyed. Clean up what we created.
213: */
214:
215: if (bTimerStarted)
216: {
217: KillTimer(hWnd, 1);
218: SelectObject (hDCMem, hBitmapOld);
219: DeleteObject (hBitmap);
220: DeleteDC (hDCMem);
221: if (hFont) DeleteObject(hFont);
222: bTimerStarted = FALSE;
223: }
224:
225: if (lpStrings)
226: UnlockResource(hStrBlock), lpStrings = NULL;
227: if (hStrBlock)
228: FreeResource(hStrBlock), hStrBlock = NULL;
229:
230: // Pass the NCDESTROY on to our real window procedure. Since
231: // this is the last message that we are going to be getting,
232: // we can go ahead and free the proc instance here.
233:
234: defReturn = CallWindowProc((WNDPROC)lpRealAboutProc, hWnd,
235: uMsg, wParam, lParam);
236: return defReturn;
237: }
238:
239: Default:
240: default:
241: return CallWindowProc(
242: (WNDPROC)lpRealAboutProc, hWnd, uMsg, wParam, lParam);
243: }
244: return 0L;
245: }
246:
247:
248: /* RandomizeStars
249: * --------------
250: *
251: * Paints random stars on the specified hDC
252: *
253: */
254:
255: void RandomizeStars(HDC hDC)
256: {
257: int i;
258:
259: // Seed the random number generator with current time. This will,
260: // in effect, only change the seed every second, so our
261: // starfield will change only every second.
262: srand((unsigned)time(NULL));
263:
264: // Generate random white stars
265: for (i=0;i<20;i++)
266: PatBlt(hDC, getrandom(0,width), getrandom(0,height), 2, 2, WHITENESS);
267: }
268:
269: /* InitStrings
270: * --------------
271: *
272: * Reads strings from stringtable. Returns TRUE if it worked OK.
273: *
274: */
275:
276: BOOL InitStrings()
277: {
278: HRSRC hResStrings;
279: LPSTR lpWalk;
280:
281: // Load the block of strings
282: if ((hResStrings = FindResource(
283: g_lpApp->m_hInst,
284: MAKEINTRESOURCE(9999),
285: RT_RCDATA)) == NULL)
286: return FALSE;
287: if ((hStrBlock = LoadResource(g_lpApp->m_hInst, hResStrings)) == NULL)
288: return FALSE;
289: if ((lpStrings = LockResource(hStrBlock)) == NULL)
290: return FALSE;
291:
292: if (lpStrings && *(lpStrings+2)!=0x45)
293: {
294: lpWalk = lpStrings;
295: while (*(LPWORD)lpWalk != (WORD)0x0000)
296: {
297: if (*lpWalk != (char)0x00)
298: *lpWalk ^= 0x98;
299: lpWalk++;
300: }
301: }
302: return TRUE;
303: }
304:
305: /* DrawString
306: * ----------
307: *
308: * Draws the next string on the specified hDC using the
309: * output rectangle. If iCount == 0, reset to start of list.
310: *
311: * Returns: TRUE to contine, FALSE if we're done
312: */
313:
314: BOOL DrawString(int iCount, HDC hDC, LPRECT rcDrawIn)
315: {
316: static LPSTR lpPtr = NULL;
317:
318: if (iCount == 0)
319: // First time, reset pointer
320: lpPtr = lpStrings;
321:
322: if (*lpPtr == '\0') // If we've hit a NULL string, we're done
323: return FALSE;
324:
325: // If we're drawing outside of visible box, don't call DrawText
326: if ((rcDrawIn->bottom > 0) && (rcDrawIn->top < height))
327: DrawText(hDC, lpPtr, -1, rcDrawIn, DT_CENTER);
328:
329: // Advance pointer to next string
330: lpPtr += lstrlen(lpPtr) + 1;
331:
332: return TRUE;
333: }
334:
335:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.