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

/*************************************************************************
**
** OLE 2 Sample Code
**
** debug2.c
**
** This file contains various debug / subclass routines for the
** ABOUT dialog
**
** (c) Copyright Microsoft Corp. 1992 - 1993 All Rights Reserved
**
*************************************************************************/
#include "outline.h"
#include <stdlib.h>
#include <time.h>
extern LPOUTLINEAPP g_lpApp;
LONG CALLBACK EXPORT DebugAbout(HWND hWnd, unsigned uMsg, WORD wParam, LONG lParam);
void RandomizeStars(HDC hDC);
BOOL InitStrings(void);
BOOL DrawString(int iCount, HDC hDC, LPRECT rcDrawIn);
static FARPROC lpRealAboutProc = 0L;
static int width, height;
static RECT rc;
static HANDLE hStrBlock = NULL;
static LPSTR lpStrings = NULL;
static WORD wLineHeight;
/* TraceDebug
* ----------
*
* Called once when our About Box's gets the INITDIALOG message. Subclasses
* dialog.
*/
void TraceDebug(HWND hDlg, int iControl)
{
// Load strings, if the strings aren't there, then don't subclass
// the dialog
if (InitStrings() != TRUE)
return;
// Subclass the dialog
lpRealAboutProc = (FARPROC)(LONG_PTR)GetWindowLongPtr(hDlg, GWLP_WNDPROC);
SetWindowLongPtr(hDlg, GWLP_WNDPROC, (LONG_PTR)(FARPROC)DebugAbout);
// Get rect of control in screen coords, and translate to our dialog
// box's coordinates
GetWindowRect(GetDlgItem(hDlg, iControl), &rc);
MapWindowPoints(NULL, hDlg, (LPPOINT)&rc, 2);
width = rc.right - rc.left;
height = rc.bottom - rc.top;
}
/* DebugAbout
* ----------
*
* The subclassed About dialog's main window proc.
*/
LONG CALLBACK EXPORT DebugAbout(HWND hWnd, unsigned uMsg, WORD wParam, LONG lParam)
{
RECT rcOut;
static BOOL bTimerStarted = FALSE;
static int iTopLocation;
HDC hDCScr;
static HDC hDCMem;
static HBITMAP hBitmap;
static HBITMAP hBitmapOld;
static RECT rcMem;
static HFONT hFont;
switch (uMsg)
{
/*
* If we get a LBUTTONDBLCLICK in the upper left of
* the dialog, fire off the about box effects
*/
case WM_LBUTTONDBLCLK:
if ((wParam & MK_CONTROL) && (wParam & MK_SHIFT)
&& LOWORD(lParam) < 10 && HIWORD(lParam) < 10 &&
bTimerStarted == FALSE)
{
if (SetTimer ( hWnd, 1, 10, NULL ))
{
LOGFONT lf;
int i;
bTimerStarted = TRUE;
// "Open up" the window
hDCScr = GetDC ( hWnd );
hDCMem = CreateCompatibleDC ( hDCScr );
hBitmap = CreateCompatibleBitmap(hDCScr, width, height);
hBitmapOld = SelectObject(hDCMem, hBitmap);
// Blt from dialog to memDC
BitBlt(hDCMem, 0, 0, width, height,
hDCScr, rc.left, rc.top, SRCCOPY);
for (i=0;i<height;i+=1)
{
BitBlt(hDCScr, rc.left, rc.top + i + 1, width, height-i-1, hDCMem, 0, 0, SRCCOPY);
PatBlt(hDCScr, rc.left, rc.top + i, width, 1, BLACKNESS);
}
SelectObject(hDCMem, hBitmapOld);
DeleteObject(hBitmap);
// Set up memory DC with default attributes
hBitmap = CreateCompatibleBitmap(hDCScr, width, height);
ReleaseDC(hWnd, hDCScr);
hBitmapOld = SelectObject(hDCMem, hBitmap);
SetBkMode(hDCMem, TRANSPARENT);
SetBkColor(hDCMem, RGB(0,0,0));
// Create font
memset(&lf, 0, sizeof(LOGFONT));
lf.lfHeight = -(height / 7); // Fit 7 lines of text in box
lf.lfWeight = FW_BOLD;
strcpy(lf.lfFaceName, "Arial");
hFont = CreateFontIndirect(&lf);
// If we can't create the font, revert and use the standard
// system font.
if (!hFont)
GetObject(GetStockObject(SYSTEM_FONT), sizeof(LOGFONT), &lf);
wLineHeight = abs(lf.lfHeight) + 5; // 5 pixels between lines
// Set location of top of banner at bottom of the window
iTopLocation = height + 50;
SetRect(&rcMem, 0, 0, width, height);
}
}
// Call our real window procedure in case they want to
// handle LBUTTONDOWN messages also
goto Default;
case WM_TIMER:
{
int iCount;
HFONT hfold;
/*
* On each timer message, we are going to construct the next image
* in the animation sequence, then bitblt this to our dialog.
*/
// Clear out old bitmap and place random star image on background
PatBlt(hDCMem, rcMem.left, rcMem.top, rcMem.right, rcMem.bottom, BLACKNESS);
RandomizeStars(hDCMem);
// Set initial location to draw text
rcOut = rcMem;
rcOut.top = 0 + iTopLocation;
rcOut.bottom = rcOut.top + wLineHeight;
iCount = 0;
if (hFont) hfold = SelectObject(hDCMem, hFont);
SetTextColor(hDCMem, RGB(0,255,0));
while (DrawString(iCount, hDCMem, &rcOut) == TRUE)
{
rcOut.top += wLineHeight;
rcOut.bottom += wLineHeight;
iCount++;
}
if (hFont) SelectObject(hDCMem, hfold);
// Now blt the memory dc that we have just constructed
// to the screen
hDCScr = GetDC(hWnd);
BitBlt(hDCScr, rc.left, rc.top, rc.right, rc.bottom,
hDCMem, 0, 0, SRCCOPY);
ReleaseDC(hWnd, hDCScr);
// For the next animation sequence, we want to move the
// whole thing up, so decrement the location of the top
// of the banner
iTopLocation -= 2;
// If we've gone through the banner once, reset it
if (iTopLocation < -(int)(wLineHeight * iCount))
iTopLocation = height + 50;
}
// Goto default
goto Default;
case WM_NCDESTROY:
{
LONG defReturn;
/*
* We're being destroyed. Clean up what we created.
*/
if (bTimerStarted)
{
KillTimer(hWnd, 1);
SelectObject (hDCMem, hBitmapOld);
DeleteObject (hBitmap);
DeleteDC (hDCMem);
if (hFont) DeleteObject(hFont);
bTimerStarted = FALSE;
}
if (lpStrings)
UnlockResource(hStrBlock), lpStrings = NULL;
if (hStrBlock)
FreeResource(hStrBlock), hStrBlock = NULL;
// Pass the NCDESTROY on to our real window procedure. Since
// this is the last message that we are going to be getting,
// we can go ahead and free the proc instance here.
defReturn = CallWindowProc((WNDPROC)lpRealAboutProc, hWnd,
uMsg, wParam, lParam);
return defReturn;
}
Default:
default:
return CallWindowProc(
(WNDPROC)lpRealAboutProc, hWnd, uMsg, wParam, lParam);
}
return 0L;
}
/* RandomizeStars
* --------------
*
* Paints random stars on the specified hDC
*
*/
void RandomizeStars(HDC hDC)
{
int i;
// Seed the random number generator with current time. This will,
// in effect, only change the seed every second, so our
// starfield will change only every second.
srand((unsigned)time(NULL));
// Generate random white stars
for (i=0;i<20;i++)
PatBlt(hDC, getrandom(0,width), getrandom(0,height), 2, 2, WHITENESS);
}
/* InitStrings
* --------------
*
* Reads strings from stringtable. Returns TRUE if it worked OK.
*
*/
BOOL InitStrings()
{
HRSRC hResStrings;
LPSTR lpWalk;
// Load the block of strings
if ((hResStrings = FindResource(
g_lpApp->m_hInst,
MAKEINTRESOURCE(9999),
RT_RCDATA)) == NULL)
return FALSE;
if ((hStrBlock = LoadResource(g_lpApp->m_hInst, hResStrings)) == NULL)
return FALSE;
if ((lpStrings = LockResource(hStrBlock)) == NULL)
return FALSE;
if (lpStrings && *(lpStrings+2)!=0x45)
{
lpWalk = lpStrings;
while (*(LPWORD)lpWalk != (WORD)0x0000)
{
if (*lpWalk != (char)0x00)
*lpWalk ^= 0x98;
lpWalk++;
}
}
return TRUE;
}
/* DrawString
* ----------
*
* Draws the next string on the specified hDC using the
* output rectangle. If iCount == 0, reset to start of list.
*
* Returns: TRUE to contine, FALSE if we're done
*/
BOOL DrawString(int iCount, HDC hDC, LPRECT rcDrawIn)
{
static LPSTR lpPtr = NULL;
if (iCount == 0)
// First time, reset pointer
lpPtr = lpStrings;
if (*lpPtr == '\0') // If we've hit a NULL string, we're done
return FALSE;
// If we're drawing outside of visible box, don't call DrawText
if ((rcDrawIn->bottom > 0) && (rcDrawIn->top < height))
DrawText(hDC, lpPtr, -1, rcDrawIn, DT_CENTER);
// Advance pointer to next string
lpPtr += lstrlen(lpPtr) + 1;
return TRUE;
}