|
|
//
// MyPrSht.cpp
//
// Implementation of the extensions made to the PropertySheet API
// in IE5, but which we need on all platforms.
//
// History:
//
// 10/11/1999 KenSh Created
//
#include "stdafx.h"
#include "TheApp.h"
#include "MyPrSht.h"
#include "CWnd.h"
#include "unicwrap.h"
// Thunk up to propsheetpage v6 for XP
typedef struct _PROPSHEETPAGEV6W { DWORD dwSize; DWORD dwFlags; HINSTANCE hInstance; union { LPCWSTR pszTemplate; #ifdef _WIN32
LPCDLGTEMPLATE pResource; #else
const VOID *pResource; #endif
} DUMMYUNIONNAME; union { HICON hIcon; LPCWSTR pszIcon; } DUMMYUNIONNAME2; LPCWSTR pszTitle; DLGPROC pfnDlgProc; LPARAM lParam; LPFNPSPCALLBACKW pfnCallback; UINT *pcRefParent;
#if (_WIN32_IE >= 0x0400)
LPCWSTR pszHeaderTitle; // this is displayed in the header
LPCWSTR pszHeaderSubTitle; ///
#endif
HANDLE hActCtx; } PROPSHEETPAGEV6W, *LPPROPSHEETPAGEV6W;
// Local data
//
static CMyPropSheet* g_pMyPropSheet;
static const TCHAR c_szProp_ClassPointer[] = _T("CP");
#define DEFAULTHEADERHEIGHT 58 // in pixels
#define DEFAULTTEXTDIVIDERGAP 5
#define DEFAULTCTRLWIDTH 501 // page list window in new wizard style
#define DEFAULTCTRLHEIGHT 253 // page list window in new wizard style
#define TITLEX 22
#define TITLEY 10
#define SUBTITLEX 44
#define SUBTITLEY 25
// fixed sizes for the bitmap painted in the header section
#define HEADERBITMAP_Y 5
#define HEADERBITMAP_WIDTH 49
#define HEADERBITMAP_CXBACK (5 + HEADERBITMAP_WIDTH)
#define HEADERBITMAP_HEIGHT 49
#define HEADERSUBTITLE_WRAPOFFSET 10
// Fixed sizes for the watermark bitmap (Wizard97IE5 style)
#define BITMAP_WIDTH 164
#define BITMAP_HEIGHT 312
#define DRAWTEXT_WIZARD97FLAGS (DT_LEFT | DT_WORDBREAK | DT_NOPREFIX | DT_EDITCONTROL)
#define IDD_PAGELIST 0x3020
#define IDD_DIVIDER 0x3026
#define IDD_TOPDIVIDER 0x3027
#ifndef IS_INTRESOURCE
#define IS_INTRESOURCE(psz) (HIWORD((DWORD_PTR)(psz)) == 0)
#endif
/////////////////////////////////////////////////////////////////////////////
// MyPropertySheet
INT_PTR MyPropertySheet(LPCPROPSHEETHEADER pHeader) { // If IE5 is present, use the built-in property sheet code
// REVIEW: should we bother checking for IE5 on older OS's?
if (theApp.IsWin98SEOrLater() && (! theApp.IsBiDiLocalized()) ) { // ISSUE-2002/01/16-roelfc: THUNK THIS (but which way???)
return PropertySheet(pHeader); }
// ISSUE-2002/01/16-roelfc: nobody destroys g_pMyPropSheet, nobody does g_pMyPropSheet->Release()
ASSERT(g_pMyPropSheet == NULL); g_pMyPropSheet = new CMyPropSheet(); if (g_pMyPropSheet) return g_pMyPropSheet->DoPropSheet(pHeader); else return NULL; }
/////////////////////////////////////////////////////////////////////////////
// MyCreatePropertySheetPage
HPROPSHEETPAGE MyCreatePropertySheetPage(LPPROPSHEETPAGE ppsp) { // If IE5 is present, use the built-in property sheet code
// REVIEW: should we bother checking for IE5 on older OS's?
if (theApp.IsWin98SEOrLater() && (! theApp.IsBiDiLocalized()) ) { if (g_fRunningOnNT) { PROPSHEETPAGEV6W spv6;
ASSERT(sizeof (spv6) >= sizeof (PROPSHEETPAGE)); memcpy(&spv6, ppsp, sizeof (PROPSHEETPAGE)); spv6.dwSize = sizeof (spv6); spv6.hActCtx = NULL;
return CreatePropertySheetPage((PROPSHEETPAGE*) &spv6); } else { return CreatePropertySheetPage(ppsp); } }
PROPSHEETPAGE psp; CopyMemory(&psp, ppsp, ppsp->dwSize);
// REVIEW: this memory is never freed
LPPROPSHEETPAGE ppspOriginal = (LPPROPSHEETPAGE)malloc(sizeof(PROPSHEETPAGE)); if (ppspOriginal) { CopyMemory(ppspOriginal, ppsp, ppsp->dwSize);
psp.dwSize = PROPSHEETPAGE_V1_SIZE; psp.dwFlags &= ~(PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE | PSP_HIDEHEADER); psp.lParam = (LPARAM)ppspOriginal;
return ::CreatePropertySheetPage(&psp); }
return NULL; }
/////////////////////////////////////////////////////////////////////////////
// IsIMEWindow
BOOL IsIMEWindow(HWND hwnd, LPCREATESTRUCT lpcs) { // check for cheap CS_IME style first...
if (GetClassLong(hwnd, GCL_STYLE) & CS_IME) return TRUE;
// get class name of the window that is being created
LPCTSTR pszClassName; TCHAR szClassName[_countof("ime")+1]; if (HIWORD(lpcs->lpszClass)) { pszClassName = lpcs->lpszClass; } else { szClassName[0] = _T('\0'); GlobalGetAtomName((ATOM)lpcs->lpszClass, szClassName, _countof(szClassName)); pszClassName = szClassName; }
// a little more expensive to test this way, but necessary...
if (StrCmpI(pszClassName, _T("ime")) == 0) return TRUE;
return FALSE; // not an IME window
}
void CMyPropSheet::SetHeaderFonts() { if (m_hFontBold == NULL) { LOGFONT LogFont; GetObject(GetWindowFont(m_hWnd), sizeof(LogFont), &LogFont);
LogFont.lfWeight = FW_BOLD; m_hFontBold = CreateFontIndirect(&LogFont); } }
// Kensh: Copied and modified from _ComputeHeaderHeight in prsht.c (comctl32.dll)
//
// In Wizard97 only:
// The subtitles user passed in could be larger than the two line spaces we give
// them, especially in localization cases. So here we go through all subtitles and
// compute the max space they need and set the header height so that no text is clipped
int CMyPropSheet::ComputeHeaderHeight(int dxMax) { SetHeaderFonts();
int dyHeaderHeight; int dyTextDividerGap; HDC hdc; dyHeaderHeight = DEFAULTHEADERHEIGHT; hdc = ::GetDC(m_hWnd);
// First, let's get the correct text height and spacing, this can be used
// as the title height and the between-lastline-and-divider spacing.
{ HFONT hFont, hFontOld; TEXTMETRIC tm; if (m_hFontBold) hFont = m_hFontBold; else hFont = GetWindowFont(m_hWnd);
hFontOld = (HFONT)SelectObject(hdc, hFont); if (GetTextMetrics(hdc, &tm)) { dyTextDividerGap = tm.tmExternalLeading; m_ySubTitle = max ((tm.tmHeight + tm.tmExternalLeading + TITLEY), SUBTITLEY); } else { dyTextDividerGap = DEFAULTTEXTDIVIDERGAP; m_ySubTitle = SUBTITLEY; }
if (hFontOld) SelectObject(hdc, hFontOld); }
// Second, get the subtitle text block height
// should make into a function if shared
{ RECT rcWrap; // UINT uPages;
//
// WIZARD97IE5 subtracts out the space used by the header bitmap.
// WIZARD97IE4 uses the full width since the header bitmap
// in IE4 is a watermark and occupies no space.
//
// if (ppd->psh.dwFlags & PSH_WIZARD97IE4)
// rcWrap.right = dxMax;
// else
rcWrap.right = dxMax - HEADERBITMAP_CXBACK - HEADERSUBTITLE_WRAPOFFSET;
// Note (kensh): the "real" wizard code computes the max height across
// all pages. Our cheap version only computes the current page's height
LPPROPSHEETPAGE ppsp = GetCurrentPropSheetPage(); if (ppsp != NULL) { if (!(ppsp->dwFlags & PSP_HIDEHEADER) && (ppsp->dwFlags & PSP_USEHEADERSUBTITLE)) { int iSubHeaderHeight = WriteHeaderTitle(hdc, &rcWrap, ppsp->pszHeaderSubTitle, FALSE, DT_CALCRECT | DRAWTEXT_WIZARD97FLAGS); if ((iSubHeaderHeight + m_ySubTitle) > dyHeaderHeight) dyHeaderHeight = iSubHeaderHeight + m_ySubTitle; } } }
// If the header height has been recomputed, set the correct gap between
// the text and the divider.
if (dyHeaderHeight != DEFAULTHEADERHEIGHT) { ASSERT(dyHeaderHeight > DEFAULTHEADERHEIGHT); dyHeaderHeight += dyTextDividerGap; }
::ReleaseDC(m_hWnd, hdc); return dyHeaderHeight; }
// Kensh: Copied and modified from _WriteHeaderTitle in prsht.c (comctl32.dll)
//
int CMyPropSheet::WriteHeaderTitle(HDC hdc, LPRECT prc, LPCTSTR pszTitle, BOOL bTitle, DWORD dwDrawFlags) { SetHeaderFonts();
LPCTSTR pszOut; int cch; int cx, cy; UINT ETO_Flags=0; SIZE Size; TCHAR szTitle[MAX_PATH*4]; HFONT hFontOld = NULL; HFONT hFont; int yDrawHeight = 0;
if (IS_INTRESOURCE(pszTitle)) { LPPROPSHEETPAGE ppsp = GetCurrentPropSheetPage(); if (NULL != ppsp) { LoadString(ppsp->hInstance, (UINT)LOWORD(pszTitle), szTitle, _countof(szTitle)); } else { *szTitle = 0; }
pszOut = szTitle; } else pszOut = pszTitle;
cch = lstrlen(pszOut);
if (bTitle && m_hFontBold) hFont = m_hFontBold; else hFont = GetWindowFont(m_hWnd);
hFontOld = (HFONT)SelectObject(hdc, hFont);
if (bTitle) { cx = TITLEX; cy = TITLEY;
if (theApp.IsBiDiLocalized()) { ETO_Flags |= ETO_RTLREADING; if (GetTextExtentPoint32(hdc, pszOut, lstrlen (pszOut), &Size)) cx = prc->right - Size.cx; } ExtTextOut(hdc, cx, cy, ETO_Flags, prc, pszOut, cch, NULL); } else { RECT rcWrap; CopyRect(&rcWrap, prc);
rcWrap.left = SUBTITLEX; rcWrap.top = m_ySubTitle; if (theApp.IsBiDiLocalized()) { dwDrawFlags |= DT_RTLREADING | DT_RIGHT; } yDrawHeight = DrawText(hdc, pszOut, cch, &rcWrap, dwDrawFlags); }
if (hFontOld) SelectObject(hdc, hFontOld);
return yDrawHeight; }
/////////////////////////////////////////////////////////////////////////////
// CMyPropSheet
CMyPropSheet::CMyPropSheet() { m_pRealHeader = NULL; m_hHook = NULL; m_hbrWindow = NULL; m_hbrDialog = NULL; m_hwndActive = NULL; m_hbmWatermark = NULL; m_hbmHeader = NULL; m_hpalWatermark = NULL; m_hFontBold = NULL; }
CMyPropSheet::~CMyPropSheet() { free(m_pRealHeader); ASSERT(m_hHook == NULL);
if (m_hbrWindow != NULL) DeleteObject(m_hbrWindow); if (m_hbrDialog != NULL) DeleteObject(m_hbrDialog); }
void CMyPropSheet::InitColorSettings() { if (m_hbrWindow != NULL) DeleteObject(m_hbrWindow); m_hbrWindow = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
if (m_hbrDialog != NULL) DeleteObject(m_hbrDialog); m_hbrDialog = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); }
void CMyPropSheet::LoadBitmaps() { LPPROPSHEETHEADER ppsh = m_pRealHeader; if (ppsh) { if (ppsh->dwFlags & PSH_USEHBMHEADER) m_hbmHeader = ppsh->hbmHeader; else m_hbmHeader = LoadBitmap(ppsh->hInstance, ppsh->pszbmHeader);
if (ppsh->dwFlags & PSH_USEHBMWATERMARK) m_hbmWatermark = ppsh->hbmWatermark; else m_hbmWatermark = LoadBitmap(ppsh->hInstance, ppsh->pszbmWatermark);
// Note: might need a palette later, but so far it hasn't been necessary
} }
INT_PTR CMyPropSheet::DoPropSheet(LPCPROPSHEETHEADER ppsh) { INT_PTR nResult = 0;
ASSERT(m_pRealHeader == NULL); m_pRealHeader = (LPPROPSHEETHEADER)malloc(ppsh->dwSize); if (m_pRealHeader) { CopyMemory(m_pRealHeader, ppsh, ppsh->dwSize);
InitColorSettings();
// Create header and watermark bitmaps
LoadBitmaps();
PROPSHEETHEADER psh; ASSERT(sizeof(psh) >= ppsh->dwSize); CopyMemory(&psh, ppsh, ppsh->dwSize);
psh.dwSize = PROPSHEETHEADER_V1_SIZE; psh.dwFlags &= 0x00000fff; // W95 gold comctl32 prop sheet mask.
psh.dwFlags |= PSH_WIZARD;
ASSERT(m_hHook == NULL); m_hHook = SetWindowsHookEx(WH_CBT, HookProc, NULL, GetCurrentThreadId());
nResult = ::PropertySheet(&psh);
if (m_hHook != NULL) { UnhookWindowsHookEx(m_hHook); m_hHook = NULL; } }
return nResult; }
LRESULT CALLBACK CMyPropSheet::HookProc(int nCode, WPARAM wParam, LPARAM lParam) { ASSERT(g_pMyPropSheet != NULL);
LRESULT lResult = CallNextHookEx(g_pMyPropSheet->m_hHook, nCode, wParam, lParam);
if (nCode == HCBT_CREATEWND) { HWND hwnd = (HWND)wParam; LPCBT_CREATEWND pCbt = (LPCBT_CREATEWND)lParam;
// Make sure this isn't an IME window
if (IsIMEWindow(hwnd, pCbt->lpcs)) goto done;
if (g_pMyPropSheet->m_hWnd == NULL) // The main wizard window
{ // Add the WS_EX_DLGMODALFRAME extended style to the window
// Remove WS_EX_CONTEXTHELP extended style from the window
SHSetWindowBits(hwnd, GWL_EXSTYLE, WS_EX_DLGMODALFRAME|WS_EX_CONTEXTHELP, WS_EX_DLGMODALFRAME);
// Add the WS_SYSMENU style to the window
SHSetWindowBits(hwnd, GWL_STYLE, WS_SYSMENU, WS_SYSMENU);
// Subclass the window
g_pMyPropSheet->Attach(hwnd); } else if (pCbt->lpcs->hwndParent == g_pMyPropSheet->m_hWnd && pCbt->lpcs->hMenu == NULL && (pCbt->lpcs->style & WS_CHILD) == WS_CHILD) { // It's a wizard page sub-dialog -- subclass it so we can
// draw its background
CMyPropPage* pPropPage = new CMyPropPage; if (pPropPage) { pPropPage->Attach(hwnd); pPropPage->Release(); } } } else if (nCode == HCBT_DESTROYWND) { HWND hwnd = (HWND)wParam; if (hwnd == g_pMyPropSheet->m_hWnd) { // Main window being destroyed -- stop hooking window creation
UnhookWindowsHookEx(g_pMyPropSheet->m_hHook); g_pMyPropSheet->m_hHook = NULL; } }
done: return lResult; }
LPPROPSHEETPAGE CMyPropSheet::GetCurrentPropSheetPage() { CMyPropPage* pPage = CMyPropPage::FromHandle(GetActivePage()); if (pPage) { return pPage->GetPropSheetPage(); } return NULL; }
LRESULT CMyPropSheet::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_SETTINGCHANGE: { InitColorSettings(); return Default(message, wParam, lParam); }
case PSM_SETCURSEL: { InvalidateRect(m_hWnd, NULL, TRUE); return Default(message, wParam, lParam); } break;
/*
case WM_ERASEBKGND: { TRACE("Main window - WM_ERASEBKGND - active page = %X\r\n", GetActivePage()); LPPROPSHEETPAGE ppsp = GetCurrentPropSheetPage();
HDC hdc = (HDC)wParam; RECT rcClient; GetClientRect(&rcClient);
if (ppsp->dwFlags & PSP_HIDEHEADER) { RECT rcDivider; GetDlgItemRect(hwnd, IDD_DIVIDER, &rcDivider); rcClient.top = rcDivider.bottom; FillRect(hdc, &rcClient, m_hbrDialog); rcClient.bottom = rcClient.top; rcClient.top = 0; FillRect(hdc, &rcClient, m_hbrWindow); return TRUE; } else { RECT rcHeader; CopyRect(&rcHeader, &rcClient); rcHeader.bottom = DEFAULTHEADERHEIGHT; FillRect(hdc, &rcHeader, m_hbrWindow); rcClient.top = rcHeader.bottom; FillRect(hdc, &rcClient, m_hbrDialog); } } return FALSE; */
case WM_PAINT: { PAINTSTRUCT ps; LPPROPSHEETPAGE ppsp = GetCurrentPropSheetPage();
HDC hdc = ::BeginPaint(m_hWnd, &ps);
if (ppsp != NULL) { if (ppsp->dwFlags & PSP_HIDEHEADER) { // Draw the watermark
PaintWatermark(hdc, ppsp); } else { // Draw the header
PaintHeader(hdc, ppsp); } }
::EndPaint(m_hWnd, &ps); } break;
case WM_CTLCOLOREDIT: case WM_CTLCOLORDLG: case WM_CTLCOLOR: case WM_CTLCOLORMSGBOX: case WM_CTLCOLORLISTBOX: case WM_CTLCOLORBTN: case WM_CTLCOLORSCROLLBAR: case WM_CTLCOLORSTATIC: { return (LRESULT)OnCtlColor(message, (HDC)wParam, (HWND)lParam); }
default: { return Default(message, wParam, lParam); } }
return 0; }
HBRUSH CMyPropSheet::OnCtlColor(UINT message, HDC hdc, HWND hwndControl) { HBRUSH hbr = (HBRUSH)Default(message, (WPARAM)hdc, (LPARAM)hwndControl);
if (message == WM_CTLCOLOREDIT || message == WM_CTLCOLORDLG) return hbr;
SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT)); SetBkColor(hdc, GetSysColor(COLOR_WINDOW)); return m_hbrWindow; }
//
// lprc is the target rectangle.
// Use as much of the bitmap as will fit into the target rectangle.
// If the bitmap is smaller than the target rectangle, then fill the rest with
// the pixel in the upper left corner of the hbmpPaint.
//
void PaintWithPaletteBitmap(HDC hdc, LPRECT lprc, HPALETTE hplPaint, HBITMAP hbmpPaint) { HDC hdcBmp = CreateCompatibleDC(hdc); if (hdcBmp) { BITMAP bm; int cxRect, cyRect, cxBmp, cyBmp;
GetObject(hbmpPaint, sizeof(BITMAP), &bm); SelectObject(hdcBmp, hbmpPaint);
if (hplPaint) { SelectPalette(hdc, hplPaint, FALSE); RealizePalette(hdc); }
cxRect = RECTWIDTH(*lprc); cyRect = RECTHEIGHT(*lprc);
// Never use more pixels from the bmp as we have room in the rect.
cxBmp = min(bm.bmWidth, cxRect); cyBmp = min(bm.bmHeight, cyRect);
BitBlt(hdc, lprc->left, lprc->top, cxBmp, cyBmp, hdcBmp, 0, 0, SRCCOPY);
// If bitmap is too narrow, then StretchBlt to fill the width.
if (cxBmp < cxRect) StretchBlt(hdc, lprc->left + cxBmp, lprc->top, cxRect - cxBmp, cyBmp, hdcBmp, 0, 0, 1, 1, SRCCOPY);
// If bitmap is to short, then StretchBlt to fill the height.
if (cyBmp < cyRect) StretchBlt(hdc, lprc->left, cyBmp, cxRect, cyRect - cyBmp, hdcBmp, 0, 0, 1, 1, SRCCOPY);
DeleteDC(hdcBmp); } }
void CMyPropSheet::PaintWatermark(HDC hdc, LPPROPSHEETPAGE ppsp) { RECT rcClient; RECT rcClient_Dlg;
GetClientRect(m_hWnd, &rcClient); GetClientRect(m_hWnd, &rcClient_Dlg);
RECT rcDivider; GetDlgItemRect(m_hWnd, IDD_DIVIDER, &rcDivider);
if (m_hbmWatermark) { // Bottom gets gray
rcClient.top = rcDivider.bottom; FillRect(hdc, &rcClient, m_hbrDialog); rcClient.bottom = rcClient.top; rcClient.top = 0; // Right-hand side gets m_hbrWindow.
if (theApp.IsBiDiLocalized()) rcClient.right = rcClient_Dlg.right - BITMAP_WIDTH; else rcClient.left = BITMAP_WIDTH; FillRect(hdc, &rcClient, m_hbrWindow); // Left-hand side gets watermark in top portion with autofill...
if (theApp.IsBiDiLocalized()) { rcClient.right = rcClient_Dlg.right; rcClient.left = rcClient_Dlg.right - BITMAP_WIDTH; } else { rcClient.right = rcClient.left; rcClient.left = 0; }
PaintWithPaletteBitmap(hdc, &rcClient, m_hpalWatermark, m_hbmWatermark); } }
void CMyPropSheet::PaintHeader(HDC hdc, LPPROPSHEETPAGE ppsp) { RECT rcClient, rcHeaderBitmap; GetClientRect(m_hWnd, &rcClient); int cyHeader = ComputeHeaderHeight(rcClient.right);
// Bottom gets gray
rcClient.top = cyHeader; FillRect(hdc, &rcClient, m_hbrDialog);
// Top gets white
rcClient.bottom = rcClient.top; rcClient.top = 0; FillRect(hdc, &rcClient, m_hbrWindow);
// Draw the fixed-size header bitmap
int bx= RECTWIDTH(rcClient) - HEADERBITMAP_CXBACK; ASSERT(bx > 0); SetRect(&rcHeaderBitmap, bx, HEADERBITMAP_Y, bx + HEADERBITMAP_WIDTH, HEADERBITMAP_Y + HEADERBITMAP_HEIGHT); PaintWithPaletteBitmap(hdc, &rcHeaderBitmap, m_hpalWatermark, m_hbmHeader);
// Draw header title & subtitle
rcClient.right = bx - HEADERSUBTITLE_WRAPOFFSET; WriteHeaderTitle(hdc, &rcClient, ppsp->pszHeaderTitle, TRUE, DRAWTEXT_WIZARD97FLAGS); WriteHeaderTitle(hdc, &rcClient, ppsp->pszHeaderSubTitle, FALSE, DRAWTEXT_WIZARD97FLAGS); }
/////////////////////////////////////////////////////////////////////////////
// CMyPropPage
CMyPropPage* CMyPropPage::FromHandle(HWND hwnd) { return (CMyPropPage*)(CWnd::FromHandle(hwnd)); }
LPPROPSHEETPAGE CMyPropPage::GetPropSheetPage() { return m_ppspOriginal; }
LRESULT CMyPropPage::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: { LPPROPSHEETPAGE ppspBogus = (LPPROPSHEETPAGE)lParam; LPPROPSHEETPAGE ppspOriginal = (LPPROPSHEETPAGE) ppspBogus->lParam; m_ppspOriginal = ppspOriginal; lParam = (LPARAM)ppspOriginal; } break;
case WM_ERASEBKGND: { if ((m_ppspOriginal->dwFlags & PSP_HIDEHEADER) != 0) { // Let the parent window bleed through
return FALSE; } } break;
case WM_CTLCOLORSTATIC: { if ((m_ppspOriginal->dwFlags & PSP_HIDEHEADER) != 0) { return (LRESULT)g_pMyPropSheet->OnCtlColor(message, (HDC)wParam, (HWND)lParam); } } break;
case WM_NOTIFY: { NMHDR* pHdr = (NMHDR*)lParam; switch (pHdr->code) { case PSN_KILLACTIVE: { // TRACE("PSN_KILLACTIVE - hwnd = %X\r\n", hwnd);
} break;
case PSN_SETACTIVE: { // TRACE("PSN_SETACTIVE - hwnd = %X\r\n", hwnd);
HWND hwndParent = GetParent(m_hWnd);
RECT rcParent; ::GetClientRect(hwndParent, &rcParent);
RECT rcTopDivider; HWND hwndTopDivider = GetDlgItemRect(hwndParent, IDD_TOPDIVIDER, &rcTopDivider);
// Hide the tab control (not sure why it's showing up, but it shouldn't)
ShowWindow(::GetDlgItem(hwndParent, IDD_PAGELIST), SW_HIDE);
RECT rcDivider; HWND hwndDivider = GetDlgItemRect(hwndParent, IDD_DIVIDER, &rcDivider); // Set the proper size and position for the dialog
if ((m_ppspOriginal->dwFlags & PSP_HIDEHEADER) != 0) { // Reposition the divider
SetWindowPos(hwndDivider, NULL, 0, rcDivider.top, rcParent.right, RECTHEIGHT(rcDivider), SWP_NOZORDER | SWP_NOACTIVATE);
// Hide the top divider
if (hwndTopDivider != NULL) ShowWindow(hwndTopDivider, SW_HIDE);
// Reposition the dialog
SetWindowPos(m_hWnd, NULL, rcParent.left, rcParent.top, RECTWIDTH(rcParent), rcDivider.top - rcParent.top, SWP_NOZORDER | SWP_NOACTIVATE);
} else { int cyHeader = g_pMyPropSheet->ComputeHeaderHeight(rcParent.right);
// Reposition and show the top divider
if (hwndTopDivider != NULL) { SetWindowPos(hwndTopDivider, NULL, 0, cyHeader, rcParent.right, RECTHEIGHT(rcTopDivider), SWP_NOZORDER | SWP_NOACTIVATE); ShowWindow(hwndTopDivider, SW_SHOW); }
// Reposition the dialog
SetWindowPos(m_hWnd, NULL, rcParent.left + 7, cyHeader + 7, RECTWIDTH(rcParent) - 14, rcDivider.top - cyHeader - 14, SWP_NOZORDER | SWP_NOACTIVATE); } g_pMyPropSheet->OnSetActivePage(m_hWnd); } break; } } break;
default: break; }
return CWnd::Default(message, wParam, lParam); }
|