Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

329 lines
7.8 KiB

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