|
|
#include "precomp.h"
#include "adjustui.h"
#pragma warning(disable: 4244) // disable loss of data warning since we do so
// much casting in this file
#pragma pack(push, 2)
typedef struct tagDLGTEMPLATEEX { WORD dlgVer; WORD signature; DWORD helpID; DWORD exStyle; DWORD style; WORD cDlgItems; short x; short y; short cx; short cy; } DLGTEMPLATEEX, *PDLGTEMPLATEEX; typedef const DLGTEMPLATEEX* PCDLGTEMPLATEEX;
typedef struct { DWORD helpID; DWORD exStyle; DWORD style; short x; short y; short cx; short cy; WORD id; WORD reserved; } DLGITEMTEMPLATEEX, *PDLGITEMTEMPLATEEX; typedef const DLGITEMTEMPLATEEX* PCDLGITEMTEMPLATEEX; #pragma pack(pop)
// globals for banner
HBITMAP g_hBannerBmp = NULL; HFONT g_hFont = NULL;
static HWND s_hBannerWnd = NULL; static WNDPROC s_lpfnBannerTextCtrlProc = NULL; static HWND s_hBannerText = NULL; TCHAR s_szBannerText[MAX_PATH]; static WNDPROC s_lpfnPSWndProc = NULL;
// PrepareDlgTemplate and ChangeDlgTemplateFont helpers
BOOL getBitmapDimensions(HINSTANCE hinstBmp, UINT nID, PSIZE psizeBmp); BOOL mapPixelsToDlgUnits(const LOGFONT *plf, PSIZE psize); BOOL createStaticControl(PCSTATICCTRL pCtrl, BOOL fEx, PVOID *ppvDIT, PDWORD pcbDIT); HRESULT getDlgTemplateSize(LPCVOID pvDlg, LPDWORD pcbDlg); BOOL loadDialogTemplate (HINSTANCE hinstDlg, UINT nID, PVOID *ppvDT, PDWORD pcbDT);
PBYTE skipDlgString(PBYTE pb); PBYTE alignDWORD(PBYTE pb);
// IsTahomaFontExist helpers
int CALLBACK enumFontFamExProc(ENUMLOGFONTEX *, NEWTEXTMETRICEX *, int, LPARAM lParam);
// PropSheetProc helpers
void initializeBannerTextCtrlFont(HWND hWnd, INT nId); BOOL CALLBACK bannerTextCtrlProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void paintBmpInHdcRect(HBITMAP hBmp, HDC hDC, RECT rect); void handleEraseBkgndMsg(HWND hDlg, HDC hDC); BOOL CALLBACK propertySheetWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HRESULT PrepareDlgTemplate(PCMODIFYDLGTEMPLATE pmdt, LPCVOID pvDlg, PVOID *ppvDT, LPDWORD pcbDlg) { LOGFONT lf; SIZE sizeBmpOffset; PCDLGTEMPLATEEX pdt2; LPCDLGTEMPLATE pdt; // for some weird reason there is no PCDLGTEMPLATE
PDLGITEMTEMPLATEEX pdit2; PDLGITEMTEMPLATE pdit; PBYTE pb; HRESULT hr; DWORD cbDlg; WORD cDlgItems, cbCreateParams; BOOL fEx, fResult;
USES_CONVERSION;
//----- Initialization and parameter validation -----
if (pmdt == NULL) return E_INVALIDARG;
if (pmdt->hinst == NULL) return E_INVALIDARG;
if (pmdt->scBmpCtrl.nCtrlType == CTRL_BITMAP && pmdt->scBmpCtrl.nID == 0) return E_INVALIDARG;
if (pvDlg == NULL) return E_INVALIDARG;
if (ppvDT == NULL) return E_POINTER; *ppvDT = NULL;
if (pcbDlg == NULL) return E_INVALIDARG; *pcbDlg = 0;
hr = getDlgTemplateSize(pvDlg, &cbDlg); if (FAILED(hr)) return hr;
ZeroMemory(&lf, sizeof(lf));
//----- Resource allocation -----
*ppvDT = CoTaskMemAlloc(cbDlg * 2); if (*ppvDT == NULL) return E_OUTOFMEMORY; ZeroMemory(*ppvDT, cbDlg * 2); hr = S_OK;
//----- Parse through Dialog Template -----
UINT nStyleOffset, nDlgItemsOffset, nWidthOffset, nHeightOffset;
pdt = NULL; pdt2 = (PCDLGTEMPLATEEX)pvDlg; // assume extended style
if (pdt2->signature == 0xFFFF) { if (pdt2->dlgVer != 1) return E_UNEXPECTED; // Chicago sanity check
nStyleOffset = (PBYTE)&pdt2->style - (PBYTE)pdt2; nDlgItemsOffset = (PBYTE)&pdt2->cDlgItems - (PBYTE)pdt2; nWidthOffset = (PBYTE)&pdt2->cx - (PBYTE)pdt2; nHeightOffset = (PBYTE)&pdt2->cy - (PBYTE)pdt2;
pb = (PBYTE)(pdt2 + 1); fEx = TRUE; } else { pdt = (LPCDLGTEMPLATE)pvDlg; pdt2 = NULL;
nStyleOffset = (PBYTE)&pdt->style - (PBYTE)pdt; nDlgItemsOffset = (PBYTE)&pdt->cdit - (PBYTE)pdt; nWidthOffset = (PBYTE)&pdt->cx - (PBYTE)pdt; nHeightOffset = (PBYTE)&pdt->cy - (PBYTE)pdt;
pb = (PBYTE)(pdt + 1); fEx = FALSE; }
// skip over menu, window class and window text
pb = skipDlgString(pb); pb = skipDlgString(pb); pb = skipDlgString(pb);
// skip over font info: point size and typeface name
if (((*(PDWORD)((PBYTE)pvDlg + nStyleOffset)) & DS_SETFONT) != 0) { if (fEx) { lf.lfHeight = *(PWORD)pb; pb += sizeof(WORD); lf.lfWeight = *(PWORD)pb; pb += sizeof(WORD); lf.lfItalic = (BYTE)*(PWORD)pb; pb += sizeof(WORD); } else { lf.lfHeight = *(PWORD)pb; pb += sizeof(WORD); }
StrCpyN(lf.lfFaceName, W2CT((LPCWSTR)pb), LF_FACESIZE); pb = skipDlgString(pb); }
// finally, adjust to DWORD boundary
pb = alignDWORD(pb);
//----- Make new sence out of Dialog Template -----
SIZE sizeIncrease; DWORD cbDlgTemplate;
cbDlgTemplate = pb - (PBYTE)pvDlg; CopyMemory(*ppvDT, pvDlg, cbDlgTemplate);
fResult = getBitmapDimensions(pmdt->hinst, pmdt->scBmpCtrl.nID, &sizeBmpOffset); if (!fResult) { hr = E_FAIL; goto Exit; }
// ok, they are in dialog units now, kinda, really ;-)
fResult = mapPixelsToDlgUnits(&lf, &sizeBmpOffset); if (!fResult) { hr = E_FAIL; goto Exit; }
sizeIncrease.cx = sizeIncrease.cy = 0; if (pmdt->sizeCtrlsOffset.cx != 0) sizeIncrease.cx = pmdt->scBmpCtrl.rect.left + sizeBmpOffset.cx + pmdt->sizeCtrlsOffset.cx;
if (pmdt->sizeCtrlsOffset.cy != 0) sizeIncrease.cy = pmdt->scBmpCtrl.rect.top + sizeBmpOffset.cy + pmdt->sizeCtrlsOffset.cy;
*(PWORD)((PBYTE)*ppvDT + nDlgItemsOffset) += 2; *(PWORD)((PBYTE)*ppvDT + nWidthOffset) += (WORD)sizeIncrease.cx; *(PWORD)((PBYTE)*ppvDT + nHeightOffset) += (WORD)sizeIncrease.cy;
//----- Add control with the bitmap -----
PVOID pvCtrl; DWORD cbCtrl; DWORD cbCtrlsOffset;
fResult = createStaticControl(&pmdt->scBmpCtrl, fEx, &pvCtrl, &cbCtrl); if (!fResult) { hr = E_FAIL; goto Exit; }
CopyMemory((PBYTE)*ppvDT + cbDlgTemplate, pvCtrl, cbCtrl); cbCtrlsOffset = cbCtrl;
ASSERT(pvCtrl != NULL); CoTaskMemFree(pvCtrl);
//----- Add static text control -----
STATICCTRL scTextCtrl;
scTextCtrl = pmdt->scTextCtrl; scTextCtrl.rect.left = 7; scTextCtrl.rect.top = (sizeBmpOffset.cy / 2) - 11; scTextCtrl.rect.right = sizeBmpOffset.cx - 7; scTextCtrl.rect.bottom = scTextCtrl.rect.top + 18;
fResult = createStaticControl(&scTextCtrl, fEx, &pvCtrl, &cbCtrl); if (!fResult) { hr = E_FAIL; goto Exit; }
CopyMemory((PBYTE)*ppvDT + cbDlgTemplate + cbCtrlsOffset, pvCtrl, cbCtrl); cbCtrlsOffset += cbCtrl;
ASSERT(pvCtrl != NULL); CoTaskMemFree(pvCtrl);
//----- Parse through Dialog Item Templates -----
cDlgItems = *(PWORD)((PBYTE)pvDlg + nDlgItemsOffset); if (cDlgItems > 0) { ASSERT(cbDlg > cbDlgTemplate); CopyMemory((PBYTE)*ppvDT + cbDlgTemplate + cbCtrlsOffset, pb, cbDlg - cbDlgTemplate); pb = (PBYTE)*ppvDT + cbDlgTemplate + cbCtrlsOffset;
while (cDlgItems-- > 0) { pdit = NULL; pdit2 = NULL; if (fEx) { pdit2 = (PDLGITEMTEMPLATEEX)pb;
if (pmdt->sizeCtrlsOffset.cx != 0) pdit2->x += (WORD)sizeIncrease.cx;
if (pmdt->sizeCtrlsOffset.cy != 0) pdit2->y += (WORD)sizeIncrease.cy; } else { pdit = (PDLGITEMTEMPLATE)pb;
if (pmdt->sizeCtrlsOffset.cx != 0) pdit->x += (WORD)sizeIncrease.cx;
if (pmdt->sizeCtrlsOffset.cy != 0) pdit->y += (WORD)sizeIncrease.cy; }
pb += fEx ? sizeof(DLGITEMTEMPLATEEX) : sizeof(DLGITEMTEMPLATE);
// skip over window class and window text
pb = skipDlgString(pb); pb = skipDlgString(pb);
// skip create parameters
cbCreateParams = *((PWORD)pb); if (fEx) pb += sizeof(WORD) + cbCreateParams; else pb += cbCreateParams > 0 ? cbCreateParams : sizeof(WORD);
// point at the next dialog item
pb = alignDWORD(pb); } }
*pcbDlg = cbDlg + cbCtrlsOffset;
Exit: if (FAILED(hr)) { CoTaskMemFree(*ppvDT); *ppvDT = NULL; }
return hr; }
HRESULT SetDlgTemplateFont(HINSTANCE hInst, UINT nDlgID, const LOGFONT *plf, PVOID *ppvDT) { PCDLGTEMPLATEEX pdt2; LPCDLGTEMPLATE pdt; // for some weird reason there is no PCDLGTEMPLATE
PBYTE pb; HRESULT hr; PVOID pvDlg; DWORD cbDlg; BOOL fEx, fResult;
USES_CONVERSION;
//----- Initialization and parameter validation -----
if (plf == NULL || *plf->lfFaceName == TEXT('\0')) return E_INVALIDARG;
if (plf->lfHeight == 0) return E_INVALIDARG;
if (ppvDT == NULL) return E_POINTER; *ppvDT = NULL;
//----- Resource allocation -----
fResult = loadDialogTemplate(hInst, nDlgID, &pvDlg, &cbDlg); if (!fResult) return E_FAIL;
*ppvDT = CoTaskMemAlloc(cbDlg * 2); if (*ppvDT == NULL) return E_OUTOFMEMORY; ZeroMemory(*ppvDT, cbDlg * 2); hr = S_OK;
//----- Parse through Dialog Template -----
PBYTE pbDest; DWORD cbSize; UINT nStyleOffset;
pdt = NULL; pdt2 = (PCDLGTEMPLATEEX)pvDlg; // assume extended style
if (pdt2->signature == 0xFFFF) { if (pdt2->dlgVer != 1) return E_UNEXPECTED; // Chicago sanity check
nStyleOffset = (PBYTE)&pdt2->style - (PBYTE)pdt2;
pb = (PBYTE)(pdt2 + 1); fEx = TRUE; } else { pdt = (LPCDLGTEMPLATE)pvDlg; pdt2 = NULL;
nStyleOffset = (PBYTE)&pdt->style - (PBYTE)pdt;
pb = (PBYTE)(pdt + 1); fEx = FALSE; }
// skip over menu, window class and window text
pb = skipDlgString(pb); pb = skipDlgString(pb); pb = skipDlgString(pb);
cbSize = pb - (PBYTE)pvDlg; CopyMemory(*ppvDT, pvDlg, cbSize); pbDest = (PBYTE)*ppvDT + cbSize;
// change font info: point size and typeface name
if (((*(PDWORD)((PBYTE)pvDlg + nStyleOffset)) & DS_SETFONT) != 0) { UINT nLen;
if (fEx) { *(PWORD)pbDest = (int)plf->lfHeight; pb += 3 * sizeof(WORD); pbDest += 3 * sizeof(WORD); } else { *(PWORD)pbDest = (int)plf->lfHeight; pb += sizeof(WORD); pbDest += sizeof(WORD); }
nLen = StrLen(plf->lfFaceName);
CopyMemory(pbDest, T2CW(plf->lfFaceName), (nLen + 1)*sizeof(WCHAR));
pb = skipDlgString(pb); // don't know the length of the old font
//pbDest += (nLen + 1) * sizeof(WCHAR); // know the length of the new font already
pbDest = skipDlgString(pbDest); }
// finally, adjust to DWORD boundary
pb = alignDWORD(pb); pbDest = alignDWORD(pbDest);
// copy rest of the template
CopyMemory(pbDest, pb, cbDlg - (pb - (PBYTE)pvDlg));
return hr; }
BOOL IsTahomaFontExist(HWND hWnd) { static fFontExist = FALSE; static fFontChecked = FALSE; LOGFONT lf; HDC hDC;
if (!fFontChecked) { hDC = GetDC(hWnd); ZeroMemory(&lf, sizeof(lf)); lf.lfCharSet = DEFAULT_CHARSET; StrCpy(lf.lfFaceName, TEXT("Tahoma")); EnumFontFamiliesEx(hDC, &lf, (FONTENUMPROC)enumFontFamExProc, (LPARAM)&fFontExist, 0); ReleaseDC(hWnd, hDC); fFontChecked = TRUE; } return fFontExist; }
int CALLBACK PropSheetProc(HWND hDlg, UINT uMsg, LPARAM lParam) { MODIFYDLGTEMPLATE mdt; LPVOID pvDlg; DWORD cbDlg;
if (uMsg == PSCB_PRECREATE) { ZeroMemory(&mdt, sizeof(mdt));
mdt.hinst = g_rvInfo.hInst; mdt.sizeCtrlsOffset.cy = -9;
// bitmap control parameters
mdt.scBmpCtrl.nCtrlType = CTRL_BITMAP; mdt.scBmpCtrl.nID = IDB_WIZARD; mdt.scBmpCtrl.nCtrlID = IDC_BANNERBMPCTRL;
// text control parameters
mdt.scTextCtrl.nCtrlType = CTRL_TEXT; mdt.scTextCtrl.nCtrlID = IDC_BANNERTXTCTRL;
if (FAILED(PrepareDlgTemplate(&mdt, (LPCVOID)lParam, &pvDlg, &cbDlg))) return 1;
// replace the old template
CopyMemory((LPVOID)lParam, pvDlg, cbDlg); CoTaskMemFree(pvDlg);
// take out the context help button
if( lParam ) { DLGTEMPLATE *pDlgTemplate; DLGTEMPLATEEX *pDlgTemplateEx;
pDlgTemplateEx = (DLGTEMPLATEEX *)lParam; if (pDlgTemplateEx->signature == 0xFFFF) { if (pDlgTemplateEx->dlgVer == 1) pDlgTemplateEx->style &= ~DS_CONTEXTHELP; } else { pDlgTemplate = (DLGTEMPLATE *)lParam; pDlgTemplate->style &= ~DS_CONTEXTHELP; } } } else if (uMsg == PSCB_INITIALIZED) { // BUGBUG: (a-saship) for some reason the bitmap is not loaded within the static control,
// hence force it to display the bitmap.
s_hBannerWnd = GetDlgItem(hDlg, IDC_BANNERBMPCTRL); if (s_hBannerWnd) { g_hBannerBmp = LoadBitmap(g_rvInfo.hInst, MAKEINTRESOURCE(IDB_WIZARD)); if (g_hBannerBmp) SendMessage(s_hBannerWnd, STM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) g_hBannerBmp); }
// initialize the text control to set the required font style and subclass it
// so that it paints itself.
s_hBannerText = GetDlgItem(hDlg, IDC_BANNERTXTCTRL); if (s_hBannerText) { initializeBannerTextCtrlFont(hDlg, IDC_BANNERTXTCTRL); //subclass the text control
if(s_lpfnBannerTextCtrlProc == NULL) s_lpfnBannerTextCtrlProc = (WNDPROC)GetWindowLongPtr(s_hBannerText, GWLP_WNDPROC); SetWindowLongPtr(s_hBannerText, GWLP_WNDPROC, (LONG_PTR)bannerTextCtrlProc); }
// subclass propertysheet window to draw the border and bitmap
if(s_lpfnPSWndProc == NULL) s_lpfnPSWndProc = (WNDPROC)GetWindowLongPtr(hDlg, GWLP_WNDPROC); SetWindowLongPtr(hDlg, GWLP_WNDPROC, (LONG_PTR)propertySheetWndProc); } return 0; }
void SetBannerText(HWND hDlg) { GetWindowText(hDlg, s_szBannerText, countof(s_szBannerText)); InvalidateRect(s_hBannerWnd, NULL, TRUE); InvalidateRect(s_hBannerText, NULL, TRUE); }
void ChangeBannerText(HWND hDlg) { SetWindowText(hDlg, s_szBannerText); InvalidateRect(s_hBannerWnd, NULL, TRUE); InvalidateRect(s_hBannerText, NULL, TRUE); }
/////////////////////////////////////////////////////////////////////////////
// Implementation helpers routines (private)
//----- PrepareDlgTemplate and ChangeDlgTemplateFont helpers -----
BOOL getBitmapDimensions(HINSTANCE hinstBmp, UINT nID, PSIZE psizeBmp) { BITMAP bm; HBITMAP hbmp; int iResult;
if (hinstBmp == NULL) return FALSE;
if (psizeBmp == NULL) return FALSE; psizeBmp->cx = psizeBmp->cy = 0;
hbmp = (HBITMAP)LoadImage(hinstBmp, MAKEINTRESOURCE(nID), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR | LR_SHARED); if (hbmp == NULL) return FALSE;
iResult = GetObject(hbmp, sizeof(bm), &bm); DeleteObject(hbmp);
if (iResult == 0) return FALSE;
psizeBmp->cx = bm.bmWidth; psizeBmp->cy = bm.bmHeight; return TRUE; }
// BUGBUG: (andrewgu) Big, big bummer!
// the limitation to this whole approach is that there is no easy way to convert pixels into
// dlg units of not yet existent dialog. i looked at the code in user32 and there is way too
// much stuff to try to duplicate here. for now i'm going to use rude and cruel method of
// multipling it by 2/3 which is good enough for english systems (no matter big fonts or not).
// will see if international or accessibility folks complain.
BOOL mapPixelsToDlgUnits(const LOGFONT *plf, PSIZE psize) { if (plf == NULL) return FALSE;
if (psize == NULL) return FALSE;
psize->cx = MulDiv(psize->cx, 2, 3); psize->cy = MulDiv(psize->cy, 2, 3);
return TRUE; }
BOOL createStaticControl(PCSTATICCTRL pCtrl, BOOL fEx, PVOID *ppvDIT, PDWORD pcbDIT) { PDLGITEMTEMPLATEEX pdit2; PDLGITEMTEMPLATE pdit; DWORD dwStyle, cbCtrl; PBYTE pb;
if (pCtrl == NULL) return FALSE;
if ((pCtrl->nCtrlType != CTRL_BITMAP && pCtrl->nCtrlType != CTRL_TEXT) || (pCtrl->nCtrlType == CTRL_BITMAP && pCtrl->nID == 0)) return FALSE;
if (ppvDIT == NULL) return FALSE; *ppvDIT = NULL;
if (pcbDIT == NULL) return FALSE; *pcbDIT = 0;
// REVIEW: (andrewgu) 4 * sizeof(DWORD) is for the extra stuff
cbCtrl = sizeof(DLGITEMTEMPLATEEX) + 4 * sizeof(DWORD); dwStyle = pCtrl->dwStyle; if (dwStyle == 0) dwStyle = WS_VISIBLE | WS_CHILD | WS_GROUP;
if (pCtrl->nCtrlType == CTRL_BITMAP) dwStyle |= SS_BITMAP; else if (pCtrl->nCtrlType == CTRL_TEXT) dwStyle |= SS_LEFT;
*ppvDIT = CoTaskMemAlloc(cbCtrl); if (*ppvDIT == NULL) return FALSE; ZeroMemory(*ppvDIT, cbCtrl);
pdit = NULL; pdit2 = NULL; if (fEx) { pdit2 = (PDLGITEMTEMPLATEEX)*ppvDIT;
pdit2->helpID = 0xFFFFFFFF; pdit2->exStyle = 0; pdit2->style = dwStyle; pdit2->x = (short)pCtrl->rect.left; pdit2->y = (short)pCtrl->rect.top; pdit2->cx = (short)(pCtrl->rect.right - pCtrl->rect.left); pdit2->cy = (short)(pCtrl->rect.bottom - pCtrl->rect.top); pdit2->id = (short)pCtrl->nCtrlID;
pb = (PBYTE)*ppvDIT + sizeof(DLGITEMTEMPLATEEX); } else { pdit = (PDLGITEMTEMPLATE)*ppvDIT;
pdit->style = dwStyle; pdit->dwExtendedStyle = 0; pdit->x = (short)pCtrl->rect.left; pdit->y = (short)pCtrl->rect.top; pdit->cx = (short)(pCtrl->rect.right - pCtrl->rect.left); pdit->cy = (short)(pCtrl->rect.bottom - pCtrl->rect.top); pdit->id = (short)pCtrl->nCtrlID;
pb = (PBYTE)*ppvDIT + sizeof(DLGITEMTEMPLATE); }
// class
*(PWORD)pb = 0xFFFF; pb += sizeof(WORD); *(PWORD)pb = 0x0082; // static
pb += sizeof(WORD);
// window text
if(pCtrl->nCtrlType == CTRL_BITMAP) { *(PWORD)pb = 0xFFFF; pb += sizeof(WORD);
*(PWORD)pb = (WORD)pCtrl->nID; pb += sizeof(WORD); } else // skip over one WORD, it's zero initialized already
pb += sizeof(WORD);
// empty create parameters
pb += sizeof(WORD); pb = alignDWORD(pb);
*pcbDIT = (UINT)(pb - (PBYTE)*ppvDIT); return TRUE; }
HRESULT getDlgTemplateSize(LPCVOID pvDlg, LPDWORD pcbDlg) { PCDLGTEMPLATEEX pdt2; LPCDLGTEMPLATE pdt; // for some weird reason there is no PCDLGTEMPLATE
PBYTE pb; WORD cDlgItems, cbCreateParams; BOOL fEx;
//----- Initialization and parameter validation -----
if (pvDlg == NULL) return E_INVALIDARG;
if (pcbDlg == NULL) return E_INVALIDARG; *pcbDlg = 0;
//----- Parse through Dialog Template -----
UINT nStyleOffset, nDlgItemsOffset;
pdt = NULL; pdt2 = (PCDLGTEMPLATEEX)pvDlg; // assume extended style
if (pdt2->signature == 0xFFFF) { if (pdt2->dlgVer != 1) return E_UNEXPECTED; // Chicago sanity check
nStyleOffset = (PBYTE)&pdt2->style - (PBYTE)pdt2; nDlgItemsOffset = (PBYTE)&pdt2->cDlgItems - (PBYTE)pdt2;
pb = (PBYTE)(pdt2 + 1); fEx = TRUE; } else { pdt = (LPCDLGTEMPLATE)pvDlg; pdt2 = NULL;
nStyleOffset = (PBYTE)&pdt->style - (PBYTE)pdt; nDlgItemsOffset = (PBYTE)&pdt->cdit - (PBYTE)pdt;
pb = (PBYTE)(pdt + 1); fEx = FALSE; }
// skip over menu, window class and window text
pb = skipDlgString(pb); pb = skipDlgString(pb); pb = skipDlgString(pb);
// skip over font info: point size and typeface name
if (((*(PDWORD)((PBYTE)pvDlg + nStyleOffset)) & DS_SETFONT) != 0) { pb += fEx ? sizeof(WORD) * 3 : sizeof(WORD); pb = skipDlgString(pb); }
// finally, adjust to DWORD boundary
pb = alignDWORD(pb);
//----- Parse through Dialog Item Templates -----
cDlgItems = *(PWORD)((PBYTE)pvDlg + nDlgItemsOffset); if (cDlgItems > 0) { while (cDlgItems-- > 0) { pb += fEx ? sizeof(DLGITEMTEMPLATEEX) : sizeof(DLGITEMTEMPLATE);
// skip over window class and window text
pb = skipDlgString(pb); pb = skipDlgString(pb);
// skip create parameters
cbCreateParams = *((PWORD)pb); if (fEx) pb += sizeof(WORD) + cbCreateParams; else pb += cbCreateParams > 0 ? cbCreateParams : sizeof(WORD);
// point at the next dialog item
pb = alignDWORD(pb); } }
*pcbDlg = pb - (PBYTE)pvDlg; return S_OK; }
BOOL loadDialogTemplate(HINSTANCE hinstDlg, UINT nID, PVOID *ppvDT, PDWORD pcbDT) { PVOID p; HANDLE h;
if (hinstDlg == NULL) return FALSE;
if (ppvDT == NULL) return FALSE; *ppvDT = NULL;
if (pcbDT == NULL) return FALSE; *pcbDT = 0;
h = FindResource(hinstDlg, MAKEINTRESOURCE(nID), RT_DIALOG); if (h == NULL) return FALSE;
*pcbDT = SizeofResource(hinstDlg, (HRSRC)h); if (*pcbDT == 0) return FALSE;
h = LoadResource(hinstDlg, (HRSRC)h); if (h == NULL) return FALSE;
p = LockResource(h); if (p == NULL) return FALSE;
*ppvDT = p; return TRUE; }
inline PBYTE skipDlgString(PBYTE pb) { PWCHAR pwch;
if (*((PWORD)pb) == 0xFFFF) return (pb + sizeof(DWORD));
pwch = (PWCHAR)pb; while (*pwch++ != L'\0') ;
return (PBYTE)pwch; }
inline PBYTE alignDWORD(PBYTE pb) { return (PBYTE)(((UINT_PTR)pb + 3) & ~((UINT_PTR)3)); }
//----- IsTahomaFontExist helpers -----
int CALLBACK enumFontFamExProc(ENUMLOGFONTEX *, NEWTEXTMETRICEX *, int, LPARAM lParam) { (*(LPBOOL)lParam) = TRUE; return 0; }
//----- PropSheetProc helpers -----
void initializeBannerTextCtrlFont(HWND hWnd, INT nId) { NONCLIENTMETRICS ncm = {0}; TCHAR szFontSize[24]; INT nBigFontSize = 0; LOGFONT BigBoldLogFont; BOOL fUpdateFont = TRUE;
ZeroMemory(&BigBoldLogFont, sizeof(BigBoldLogFont));
ncm.cbSize = sizeof(ncm); if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0)) { BigBoldLogFont = ncm.lfMessageFont; fUpdateFont = FALSE; }
BigBoldLogFont.lfWeight = FW_NORMAL; if (!LoadString(g_rvInfo.hInst, IDS_BANNERFONT, BigBoldLogFont.lfFaceName, LF_FACESIZE)) StrCpy(BigBoldLogFont.lfFaceName, TEXT("Verdana"));
if (LoadString(g_rvInfo.hInst, IDS_BANNERFONTSIZE, szFontSize, countof(szFontSize))) nBigFontSize = StrToInt(szFontSize); if (nBigFontSize < 18) nBigFontSize = 18;
HDC hdc = GetDC(hWnd); if (hdc != NULL) { int dyLogPixPerInch = GetDeviceCaps(hdc, LOGPIXELSY);
BigBoldLogFont.lfHeight = -MulDiv(dyLogPixPerInch, nBigFontSize, 72);
if (fUpdateFont) { TEXTMETRIC tm;
GetTextMetrics(hdc, &tm); // get the current textmetrics
BigBoldLogFont.lfCharSet = tm.tmCharSet; }
g_hFont = CreateFontIndirect(&BigBoldLogFont); ReleaseDC(hWnd, hdc);
if (g_hFont != NULL) { HWND hControl = GetDlgItem(hWnd, nId);
if (hControl) SendMessage(hControl, WM_SETFONT, (WPARAM)g_hFont, 0); } } }
BOOL CALLBACK bannerTextCtrlProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_PAINT) { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps);
int iBkModeOld = SetBkMode(hdc, TRANSPARENT);
HFONT hfont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0); HFONT hfontOld = (HFONT)SelectObject(hdc, hfont);
COLORREF rgbSav = SetTextColor(hdc, RGB(0xff, 0xff, 0xff)); RECT rect;
GetClientRect(hWnd, &rect); DrawText(hdc, s_szBannerText, -1, &rect, DT_WORDBREAK | DT_LEFT);
SetTextColor(hdc, rgbSav); SelectObject(hdc, hfontOld); SetBkMode(hdc, iBkModeOld); EndPaint(hWnd, &ps);
return (FALSE); }
if (uMsg == WM_ERASEBKGND) return (FALSE);
return (CallWindowProc(s_lpfnBannerTextCtrlProc, hWnd, uMsg, wParam, lParam)); }
void paintBmpInHdcRect(HBITMAP hBmp, HDC hDC, RECT rect) { BITMAP bm; if(!GetObject(hBmp, sizeof(BITMAP), (LPVOID)(&bm))) return;
HDC hdcMem = CreateCompatibleDC(hDC); SelectObject(hdcMem, hBmp);
SetStretchBltMode(hDC, COLORONCOLOR); StretchBlt(hDC, 0, 0, rect.right - rect.left, rect.bottom - rect.top, hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
DeleteDC(hdcMem); }
void handleEraseBkgndMsg(HWND hDlg, HDC hDC) { RECT rectBmp;
GetClientRect(GetDlgItem(hDlg, IDC_BANNERBMPCTRL), &rectBmp);
RECT rect; GetClientRect(hDlg, &rect); rect.top = rectBmp.bottom;
HBRUSH hbr = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); HBRUSH hbrSav = (HBRUSH)SelectObject(hDC, hbr); Rectangle(hDC, rect.left, rect.top, rect.right, rect.bottom);
paintBmpInHdcRect(g_hBannerBmp, hDC, rectBmp);
SelectObject(hDC, hbrSav); DeleteObject((HGDIOBJ)hbr); }
BOOL CALLBACK propertySheetWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_ERASEBKGND) { handleEraseBkgndMsg(hWnd, (HDC)wParam); return TRUE; } else if (uMsg == WM_SIZE) { HWND hBannerWnd = GetDlgItem(hWnd, IDC_BANNERBMPCTRL);
// set the bitmap control width to the property sheet window width
if (hBannerWnd) { RECT rectBmp; RECT rectText;
GetClientRect(s_hBannerWnd, &rectBmp); SetWindowPos(s_hBannerWnd, HWND_TOP, 0, 0, LOWORD(lParam), rectBmp.bottom - rectBmp.top, SWP_NOMOVE | SWP_NOZORDER);
GetClientRect(s_hBannerText, &rectText); SetWindowPos(s_hBannerText, HWND_TOP, 0, 0, LOWORD(lParam) - 14, rectText.bottom - rectText.top, SWP_NOMOVE | SWP_NOZORDER); } } return (CallWindowProc(s_lpfnPSWndProc, hWnd, uMsg, wParam, lParam)); }
|