CPropertySheetから自己描画機能を持つ新しいクラスが派生



//CPropertySheetから新しいクラスが派生
//自己描画ヘッダー機能付き
 
#pragma once
// OwnerDraw_PropertySheet.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// COwnerDraw_PropertySheet

class COwnerDraw_PropertySheet : public CPropertySheet
{
  DECLARE_DYNAMIC(COwnerDraw_PropertySheet)

// Construction
public:
  COwnerDraw_PropertySheet();
  COwnerDraw_PropertySheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
  COwnerDraw_PropertySheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);


// Attributes
public:

// Operations
public:
  INT InsertPage(CPropertyPage* pPage, INT nIndex=-1);

// Overrides
  // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(COwnerDraw_PropertySheet)
  public:
  virtual BOOL OnInitDialog();
  //}}AFX_VIRTUAL

// Implementation
public:
  virtual ~COwnerDraw_PropertySheet();

  // Generated message map functions
protected:
  //{{AFX_MSG(COwnerDraw_PropertySheet)
  afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
  afx_msg void OnSize(UINT nType, int cx, int cy);
  //}}AFX_MSG
  DECLARE_MESSAGE_MAP()
  virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
  virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);

protected:
  void Comm_Init();


protected:
  COLORREF m_crSelColour, m_crGrayColour;
  CFont m_SelFont, m_UnselFont;


};

 
// OwnerDraw_PropertySheet.cpp : implementation file
//

#include "stdafx.h"
#include "OwnerDraw_PropertySheet.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// COwnerDraw_PropertySheet

IMPLEMENT_DYNAMIC(COwnerDraw_PropertySheet, CPropertySheet)

COwnerDraw_PropertySheet::COwnerDraw_PropertySheet():CPropertySheet()
{
  Comm_Init();
}

COwnerDraw_PropertySheet::COwnerDraw_PropertySheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
  :CPropertySheet(nIDCaption, pParentWnd, iSelectPage)
{
  Comm_Init();
}

COwnerDraw_PropertySheet::COwnerDraw_PropertySheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
  :CPropertySheet(pszCaption, pParentWnd, iSelectPage)
{
  Comm_Init();
}

void COwnerDraw_PropertySheet::Comm_Init()
{

}

COwnerDraw_PropertySheet::~COwnerDraw_PropertySheet()
{
  m_SelFont.DeleteObject();
  m_UnselFont.DeleteObject();
}


BEGIN_MESSAGE_MAP(COwnerDraw_PropertySheet, CPropertySheet)
  //{{AFX_MSG_MAP(COwnerDraw_PropertySheet)
  ON_WM_DRAWITEM()
  ON_WM_SIZE()
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// COwnerDraw_PropertySheet message handlers

BOOL COwnerDraw_PropertySheet::OnInitDialog() 
{
  BOOL bResult = CPropertySheet::OnInitDialog();
  
  // TODO: Add your specialized code here
  CTabCtrl *pTabCtrl = GetTabControl();
  pTabCtrl->ModifyStyle(0, TCS_OWNERDRAWFIXED ); // 

  m_crSelColour = RGB(0,0,255); // 
  m_crGrayColour = RGB(128,128,128); // 

  // 
  CFont *pFont = pTabCtrl->GetFont();
  LOGFONT mLogFont, mSelLogFont;
  pFont->GetLogFont(&mLogFont);
  mSelLogFont = mLogFont;
  mSelLogFont.lfWeight = FW_ULTRABOLD;
  m_SelFont.DeleteObject();
  m_SelFont.CreateFontIndirect(&mSelLogFont);
  m_UnselFont.DeleteObject();
  m_UnselFont.CreateFontIndirect(&mLogFont);

  return bResult;
}

void COwnerDraw_PropertySheet::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
  // TODO: Add your message handler code here and/or call default  
  CPropertySheet::OnDrawItem(nIDCtl, lpDrawItemStruct);

  if(lpDrawItemStruct->CtlType == ODT_TAB)
  {  
    CTabCtrl *pTabCtrl = GetTabControl();

    CRect rect = lpDrawItemStruct->rcItem;
    INT nTabIndex = lpDrawItemStruct->itemID;
    if (nTabIndex < 0) return;

    TCHAR label[64];
    TC_ITEM tci;
    tci.mask = TCIF_TEXT|TCIF_IMAGE;
    tci.pszText = label;     
    tci.cchTextMax = 63;      
    pTabCtrl->GetItem(nTabIndex, &tci );

    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    if (!pDC) return;
    int nSavedDC = pDC->SaveDC();

    // For some bizarre reason the rcItem you get extends above the actual drawing area. We have to workaround this "feature".
    rect.top += ::GetSystemMetrics(SM_CYEDGE);

    pDC->SetBkMode(TRANSPARENT);
    //pDC->FillSolidRect(rect, ::GetSysColor(COLOR_BTNFACE));

    // Draw image
    CImageList* pImageList = pTabCtrl->GetImageList();
    if (pImageList && tci.iImage >= 0) 
    {
      rect.left += pDC->GetTextExtent(_T(" ")).cx;    // Margin

      // Get height of image so we 
      IMAGEINFO info;
      pImageList->GetImageInfo(tci.iImage, &info);
      CRect ImageRect(info.rcImage);
      INT nYpos = rect.top;

      pImageList->Draw(pDC, tci.iImage, CPoint(rect.left, nYpos), ILD_TRANSPARENT);
      rect.left += ImageRect.Width();
    }

    COLORREF txtColor = GetSysColor(COLOR_WINDOWTEXT);
    CFont *pSelFont = 0;
    if (lpDrawItemStruct->itemState & CDIS_SELECTED  ) 
    {
      rect.top -= ::GetSystemMetrics(SM_CYEDGE);

      txtColor = m_crSelColour;
      pSelFont = &m_SelFont;
    }
    else if(lpDrawItemStruct->itemState & (CDIS_DISABLED | CDIS_GRAYED) ) 
    {
      txtColor = m_crGrayColour;
      pSelFont = &m_UnselFont;
    }
    else
    {
    }

    pDC->SetTextColor(txtColor);
    if(pSelFont)
      pDC->SelectObject(pSelFont);
    pDC->DrawText(label, rect, DT_SINGLELINE|DT_VCENTER|DT_CENTER);

    pDC->RestoreDC(nSavedDC);

  }
}

void COwnerDraw_PropertySheet::OnSize(UINT nType, int cx, int cy) 
{
  CPropertySheet::OnSize(nType, cx, cy);
  
  // TODO: Add your message handler code here
  if(!GetSafeHwnd())
    return;

  CTabCtrl *pCtrl = GetTabControl();
  if(pCtrl)
  {
    CRect SheetRect;
    GetClientRect(&SheetRect);
    CRect PageRect = SheetRect;
    pCtrl->AdjustRect(0, PageRect);

    for(INT nPage=0; nPage<GetPageCount(); nPage++)
    {
      CPropertyPage *pPage = GetPage(nPage);
      if(pPage && pPage->GetSafeHwnd())
      {
        pPage->MoveWindow( &PageRect );
        //pPage->PostMessage(WM_SIZE);
      }
    }
  }  
}


LRESULT COwnerDraw_PropertySheet::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
  // TODO:  / 
  if(WM_ERASEBKGND == message)
    return TRUE;
  if(WM_PAINT == message)
  {
    PAINTSTRUCT ps;
    CDC *pDC = BeginPaint(&ps); 
    EndPaint(&ps); 
    return(0);
  }
  return CPropertySheet::WindowProc(message, wParam, lParam);
}

INT COwnerDraw_PropertySheet::InsertPage(CPropertyPage* pPage, INT nIndex)
{
  ASSERT_VALID(this);
  ENSURE_VALID(pPage);
  ASSERT_KINDOF(CPropertyPage, pPage);

  if(nIndex < 0 || nIndex > GetPageCount())//add to end
  {
    nIndex = GetPageCount();
  }

  // add page to internal list
  m_pages.InsertAt(nIndex, pPage);

  // add page externally
  if (m_hWnd != NULL)
  {
    // build new prop page
    HPROPSHEETPAGE hPSP = AfxCreatePropertySheetPage(&pPage->GetPSP());
    if (hPSP == NULL)
      AfxThrowMemoryException();

    if (!SendMessage(PSM_INSERTPAGE, nIndex, (LPARAM)hPSP))
    {
      AfxDestroyPropertySheetPage(hPSP);
      AfxThrowMemoryException();
    }
    ++m_psh.nPages;
  }

  return nIndex;
}

BOOL COwnerDraw_PropertySheet::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
  // TODO:  / 
  static NMHDR nmh;
  nmh = *((LPNMHDR)lParam);
  nmh.hwndFrom = GetSafeHwnd();

  BOOL bRet = CPropertySheet::OnNotify(wParam, lParam, pResult);
  GetParent()->PostMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmh);
  return bRet;
}