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