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.
 
 
 
 
 
 

587 lines
14 KiB

/*---------------------------------------------------------------------------
**
**-------------------------------------------------------------------------*/
#include <pch.h>
#include "dibutil.h"
#include "billbrd.h"
#include "animate.h"
const UINT uiIDSteps[] = {
IDS_STEP1,
IDS_STEP2,
IDS_STEP3,
IDS_STEP4,
IDS_STEP5 };
int g_iCurrentStep = 1;
HFONT g_hfont = NULL;
HFONT g_hfontBold = NULL;
TCHAR g_szBuffer[MAX_STRING];
int GetStepText(int nStep, LPTSTR lpStr);
int PaintStepsText(HDC hdc, RECT rc);
BOOL GetStepsHeight(
IN UINT cxScreen,
IN UINT cyScreen,
IN RECT rcSteps,
OUT UINT* pcyBottom)
{
HDC hdcMem = NULL;
HDC hdcScreen = NULL;
HBITMAP hbmpMem = NULL;
BOOL bRet = FALSE;
hdcScreen = GetDC(NULL);
if (hdcScreen)
{
hdcMem = CreateCompatibleDC(hdcScreen);
hbmpMem = CreateCompatibleBitmap(hdcScreen,
cxScreen,
cyScreen);
if (hdcMem && hbmpMem)
{
SelectObject(hdcMem, hbmpMem);
*pcyBottom = (UINT) PaintStepsText(hdcMem, rcSteps);
bRet = TRUE;
}
if (hbmpMem)
{
DeleteObject(hbmpMem);
}
if (hdcMem)
{
DeleteDC(hdcMem);
}
ReleaseDC(NULL, hdcScreen);
}
return bRet;
}
/*****************************************************************************
* GetInfoBarFontHeight
*
* Export this function to facilities size estimation of g_hwndSteps.
*
******************************************************************************/
int GetInfoBarFontHeight()
{
int iInfobarRegularFontSize = 0;
int idsInfobarFontSize;
int iScreenSize;
TCHAR szBuf[25];
BB_ASSERT(g_hInstance != NULL);
iScreenSize = GetSystemMetrics(SM_CXSCREEN);
if(iScreenSize >= 1024)
{
idsInfobarFontSize = IDS_INFOFONTSIZE_1024;
iInfobarRegularFontSize = UI_INFOBAR_FONT_SIZE_1024;
}
else if(iScreenSize == 800)
{
idsInfobarFontSize = IDS_INFOFONTSIZE_800;
iInfobarRegularFontSize = UI_INFOBAR_FONT_SIZE_800;
}
else
{
idsInfobarFontSize = IDS_INFOFONTSIZE_640;
iInfobarRegularFontSize = UI_INFOBAR_FONT_SIZE_640;
}
if (LoadString(g_hInstance,
idsInfobarFontSize,
szBuf,
sizeof(szBuf)/sizeof(TCHAR)) != 0)
{
iInfobarRegularFontSize = MyAtoI((const TCHAR *)szBuf);
}
return -MulDiv(iInfobarRegularFontSize, 96, 72);
}
/******************************************************************
*
* CreateInfoBarFonts
*
* This function creates two fonts for the infobar based on the
* screen resolution. The fonts are the same size, one is bold
* and the other is normal. These fonts are used throughout infobar.
*
*******************************************************************/
BOOL CreateInfoBarFonts()
{
LOGFONT lf = {0};
TCHAR szSetupFontName[MAX_PATH];
int ifHeight = 0;
ifHeight = GetInfoBarFontHeight();
if (!(LoadString(g_hInstance, IDS_INFOFONTNAME, (LPTSTR)szSetupFontName, MAX_PATH)))
{
lstrcpy(szSetupFontName, TEXT("system"));
}
//Create a font that will be used in the Infobar ui
/*keep font size constant, even with large fonts*/
lf.lfHeight = ifHeight;
lstrcpy(lf.lfFaceName, (LPTSTR)szSetupFontName);
lf.lfItalic = 0;
lf.lfUnderline = 0;
lf.lfStrikeOut = 0;
lf.lfWeight = FW_NORMAL;
lf.lfQuality = PROOF_QUALITY;
#ifdef WINDOWS_THAI
lf.lfCharSet = ANSI_CHARSET; //Thai Textout problem for Infobar font
#else
lf.lfCharSet = g_bCharSet;
#endif
g_hfont = CreateFontIndirect(&lf);
//Create a Bold font
/*keep font size constant, even with large fonts*/
lf.lfHeight = ifHeight;
lstrcpy(lf.lfFaceName, (LPTSTR)szSetupFontName);
lf.lfItalic = 0;
lf.lfUnderline = 0;
lf.lfStrikeOut = 0;
lf.lfWeight = FW_SEMIBOLD;
lf.lfQuality = PROOF_QUALITY;
#ifdef WINDOWS_THAI
lf.lfCharSet = ANSI_CHARSET; //Thai Textout problem for Infobar font
#else
lf.lfCharSet = g_bCharSet;
#endif
g_hfontBold = CreateFontIndirect(&lf);
if(g_hfont && g_hfontBold)
return TRUE;
else
return FALSE;
}
/******************************************************************
*
* DeleteInfoBarFonts()
*
* This function deletes the two global fonts for the infobar.
*
*******************************************************************/
void DeleteInfoBarFonts(void)
{
if(g_hfont)
{
DeleteObject(g_hfont);
g_hfont = NULL;
}
if(g_hfontBold)
{
DeleteObject(g_hfontBold);
g_hfontBold = NULL;
}
}
/**********************************************************************
* PaintStepsText()
*
* Paint the setup steps in the steps window. Highlites the current step.
*
**********************************************************************/
int PaintStepsText(HDC hdc, RECT rc)
{
static TCHAR szSteps[UI_INFOBAR_NUM_STEPS][MAX_STRING];
static int iNumLines[UI_INFOBAR_NUM_STEPS];
static int iMaxNumLines = 1;
static RECT rcSteps = {0, 0, 0, 0};
COLORREF crOld = 0;
int cxStepText;
int cxStepBullet;
int cyStep;
RECT rcStepText;
HFONT hfontOld = NULL;
TEXTMETRIC tm;
BITMAP bm;
HBITMAP hbitmapOn = NULL;
HBITMAP hbitmapOff = NULL;
HBITMAP hbitmapHalf = NULL;
HBITMAP hbitmap = NULL;
int iCurrentStep = 0;
//do gdi stuff
SaveDC(hdc);
SetMapMode(hdc, MM_TEXT);
SetBkMode( hdc, TRANSPARENT );
hbitmapOn = LoadImage(
g_hInstance,
MAKEINTRESOURCE(g_idbSelectedBullet),
IMAGE_BITMAP,
0,
0,
LR_DEFAULTCOLOR );
hbitmapOff = LoadImage(
g_hInstance,
MAKEINTRESOURCE(g_idbReleasedBullet),
IMAGE_BITMAP,
0,
0,
LR_DEFAULTCOLOR );
hbitmapHalf = LoadImage(
g_hInstance,
MAKEINTRESOURCE(g_idbCurrentBullet),
IMAGE_BITMAP,
0,
0,
LR_DEFAULTCOLOR );
// select either one to get the width of the bullets
// assume both type of bullet have same width
hbitmap = (hbitmapOn) ? hbitmapOn : hbitmapOff;
if (hbitmap)
{
GetObject( hbitmap, sizeof(BITMAP), &bm );
}
else
{
bm.bmWidth = 0;
}
crOld = SetTextColor(hdc, g_colStepsTxt);
SelectObject(hdc, g_hfontBold);
GetTextMetrics(hdc, &tm);
if (g_bBiDi)
{
cxStepBullet = rc.right - bm.bmWidth;
cxStepText = 0;
rcStepText.left = rc.left;
rcStepText.right = rc.right - 3 * bm.bmWidth / 2;
rcStepText.top = rc.top;
rcStepText.bottom = rc.bottom;
}
else
{
cxStepBullet = rc.left;
cxStepText = 3 * bm.bmWidth / 2;
rcStepText.left = rc.left;
rcStepText.right = rc.right;
rcStepText.top = rc.top;
rcStepText.bottom = rc.bottom;
}
if (!EqualRect(&rcSteps, &rc))
{
iMaxNumLines = 1;
for (iCurrentStep = 1; iCurrentStep <= UI_INFOBAR_NUM_STEPS; iCurrentStep++)
{
if (!LoadString(g_hInstance, uiIDSteps[iCurrentStep-1],
(LPTSTR)szSteps[iCurrentStep-1], MAX_STRING))
{
szSteps[iCurrentStep-1][0] = TEXT('\0');
}
iNumLines[iCurrentStep-1] =
WrapText(hdc, cxStepText, &rcStepText, szSteps[iCurrentStep-1]);
if (iNumLines[iCurrentStep-1] > iMaxNumLines)
{
iMaxNumLines = iNumLines[iCurrentStep-1];
}
}
for (iCurrentStep = 1; iCurrentStep <= UI_INFOBAR_NUM_STEPS; iCurrentStep++)
{
if (iNumLines[iCurrentStep-1] < iMaxNumLines)
{
TCHAR szStep[MAX_STRING];
INT cchStep;
// ImproveWrap may add a null character to the string.
cchStep = LoadString(g_hInstance, uiIDSteps[iCurrentStep-1],
(LPTSTR)szStep, MAX_STRING - 1);
if (cchStep != 0)
{
ImproveWrap(szSteps[iCurrentStep-1],
&iNumLines[iCurrentStep-1],
szStep,
cchStep);
}
}
}
CopyRect(&rcSteps, &rc);
}
cyStep = rc.top;
for(iCurrentStep = 1; iCurrentStep <= UI_INFOBAR_NUM_STEPS; iCurrentStep++)
{
if(iCurrentStep < g_iCurrentStep)
{
SetTextColor(hdc, g_colStepsMarkTxt);
SelectObject(hdc, g_hfontBold);
hbitmap = hbitmapOn;
}
else if (iCurrentStep == g_iCurrentStep)
{
SetTextColor(hdc, g_colStepsCurrentTxt);
SelectObject(hdc, g_hfontBold);
hbitmap = hbitmapHalf;
}
else
{
SetTextColor(hdc, g_colStepsTxt);
SelectObject(hdc, g_hfont);
hbitmap = hbitmapOff;
}
if(!hbitmap)
{
OutputDebugString(TEXT("Billboard: PaintStepsText failed to load bitmap\r\n"));
}
else
{
DrawTransparentBitmap(
hdc,
hbitmap,
cxStepBullet,
cyStep,
g_colBulletTrans);
}
DrawWrapText(
hdc,
&tm,
0,
cxStepText,
cyStep,
&rcStepText,
LEFT,
iNumLines[iCurrentStep-1],
szSteps[iCurrentStep-1]);
if (iCurrentStep != UI_INFOBAR_NUM_STEPS)
{
cyStep += tm.tmHeight * (iMaxNumLines + 1);
}
else
{
int inc = tm.tmHeight * iMaxNumLines;
if (inc < bm.bmHeight)
{
cyStep += bm.bmHeight;
}
else
{
cyStep += inc;
}
}
}
if (hbitmapOn)
{
DeleteObject(hbitmapOn);
hbitmapOn = NULL;
}
if (hbitmapOff)
{
DeleteObject(hbitmapOff);
hbitmapOff = NULL;
}
hbitmap = NULL;
RestoreDC(hdc, -1);
SelectObject(hdc, hfontOld); // select the original font back into the DC
SetTextColor(hdc, crOld);
return cyStep;
}
LRESULT CALLBACK InfoBarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
RECT rc;
HDC hdc;
RECT rcToParent;
HWND hwndParent;
HDC hdcBG;
HDC hdcMem;
HBITMAP hbmpMem;
// try to draw steps without flickle
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rc);
GetRectInParent(hwnd, &rc, &rcToParent);
hdcBG = GetBackgroundBuffer();
hdcMem = CreateCompatibleDC(hdc);
hbmpMem = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
if (hdcMem && hbmpMem)
{
RECT rcLP;
SelectObject(hdcMem, hbmpMem);
BitBlt(hdcMem,
rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
hdcBG,
rcToParent.left,
rcToParent.top,
SRCCOPY);
CopyRect(&rcLP, &rc);
DPtoLP(hdcMem, (LPPOINT) &rcLP, 2);
PaintStepsText(hdcMem, rcLP);
BitBlt(hdc,
rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
hdcMem,
rc.left,
rc.top,
SRCCOPY);
}
if (hbmpMem != NULL)
{
DeleteObject(hbmpMem);
hbmpMem = NULL;
}
if (hdcMem != NULL) {
DeleteDC(hdcMem);
hdcMem = NULL;
}
EndPaint(hwnd, &ps);
return(0);
}
case WM_SETSTEP:
{
int iPanel;
int ret;
iPanel = (int) lParam;
if (iPanel <= UI_INFOBAR_NUM_STEPS)
{
g_iCurrentStep = iPanel;
ret = 1;
InvalidateRect(hwnd, NULL, FALSE);
UpdateWindow(hwnd);
}
else
{
ret = 0;
}
return ret;
}
case WM_DESTROY:
{
DeleteInfoBarFonts();
return (DefWindowProc(hwnd, msg, wParam, lParam));
}
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
BOOL WINAPI InitInfoBar(HWND hwndParent)
{
WNDCLASS wc;
RECT rc1;
wc.style = (UINT)CS_BYTEALIGNWINDOW;
wc.lpfnWndProc = (WNDPROC)InfoBarWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szStepsClassName;
if (!RegisterClass (&wc))
return FALSE;
GetWindowRect(hwndParent, &rc1);
g_hwndSteps = CreateWindow(
g_szStepsClassName,
TEXT(""),
WS_CHILD,
rc1.left + g_cxSteps,
rc1.top + g_cySteps,
g_cxStepsWidth,
g_cyStepsHeight,
hwndParent,
NULL,
g_hInstance,
NULL );
if (g_hwndSteps == NULL)
{
UnregisterClass(g_szStepsClassName, g_hInstance);
return FALSE;
}
ShowWindow( g_hwndSteps, SW_SHOW );
UpdateWindow( g_hwndSteps );
return TRUE;
}
int GetStepText(int nStep, LPTSTR lpStr)
{
TCHAR szStep[16];
wsprintf(szStep, TEXT("Step%d"), nStep);
return GetPrivateProfileString(TEXT("Steps"), szStep, TEXT(""),
lpStr, MAX_PATH, g_szFileName);
}