P
paulmcd
Recently I was trying to get this working. I solved it. Here it is:
I used a great sample from here:
http://thecodeproject.com/wtl/ThemedDialog.asp#xx1149261xx
////////////////////////////////////////////////////////////////////////////
// Copyright : Amit Dey 2002
//
// Email :[email protected]
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name is included.
//
// This file is provided 'as is' with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to your
computer.
//
// Do expect bugs.
// Please let me know of any bugs/mods/improvements.
// and I will try to fix/incorporate them into this file.
// Enjoy!
//
// Description : Outlook2K Addin
////////////////////////////////////////////////////////////////////////////
// PropPage.h : Declaration of the CPropPage
#ifndef __PROPPAGE_H_
#define __PROPPAGE_H_
#include "resource.h" // main symbols
#include <atlctl.h>
#import "c:\src\loop.old\include\msoutl9.olb" raw_interfaces_only
#include <c:\src\loop.old\include\atlcontrols.h>
using namespace ATLControls;
/////////////////////////////////////////////////////////////////////////////
// CPropPage
class ATL_NO_VTABLE CPropPage :
public CComObjectRootEx<CComSingleThreadModel>,
public IDispatchImpl<IPropPage, &IID_IPropPage,
&LIBID_OUTLOOKADDINLib>,
public CComCompositeControl<CPropPage>,
public IPersistStreamInitImpl<CPropPage>,
public IOleControlImpl<CPropPage>,
public IOleObjectImpl<CPropPage>,
public IOleInPlaceActiveObjectImpl<CPropPage>,
public IViewObjectExImpl<CPropPage>,
public IOleInPlaceObjectWindowlessImpl<CPropPage>,
public IPersistStorageImpl<CPropPage>,
public ISpecifyPropertyPagesImpl<CPropPage>,
public IQuickActivateImpl<CPropPage>,
public IDataObjectImpl<CPropPage>,
public IProvideClassInfo2Impl<&CLSID_PropPage, NULL,
&LIBID_OUTLOOKADDINLib>,
public CComCoClass<CPropPage, &CLSID_PropPage>,
public IPersistPropertyBagImpl<CPropPage>,
public
IDispatchImpl<PropertyPage,&__uuidof(PropertyPage),&LIBID_OUTLOOKADDINLib>
{
public:
CPropPage()
{
m_bWindowOnly = TRUE;
CalcExtent(m_sizeExtent);
m_hBrush = NULL;
m_bThemeActive = FALSE;
}
DECLARE_REGISTRY_RESOURCEID(IDR_PROPPAGE)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CPropPage)
COM_INTERFACE_ENTRY(IPropPage)
COM_INTERFACE_ENTRY2(IDispatch,IPropPage)
COM_INTERFACE_ENTRY(IViewObjectEx)
COM_INTERFACE_ENTRY(IViewObject2)
COM_INTERFACE_ENTRY(IViewObject)
COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceObject)
COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
COM_INTERFACE_ENTRY(IOleControl)
COM_INTERFACE_ENTRY(IOleObject)
COM_INTERFACE_ENTRY(IPersistStreamInit)
COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
COM_INTERFACE_ENTRY(IQuickActivate)
COM_INTERFACE_ENTRY(IPersistStorage)
COM_INTERFACE_ENTRY(IDataObject)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
COM_INTERFACE_ENTRY(IPersistPropertyBag)
COM_INTERFACE_ENTRY(Outlook:ropertyPage)
END_COM_MAP()
BEGIN_PROP_MAP(CPropPage)
PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
// Example entries
// PROP_ENTRY("Property Description", dispid, clsid)
// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()
BEGIN_MSG_MAP(CPropPage)
MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColor)
CHAIN_MSG_MAP(CComCompositeControl<CPropPage>)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
END_MSG_MAP()
// Handler prototypes:
// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled);
// LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl,
BOOL& bHandled);
// LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
BEGIN_SINK_MAP(CPropPage)
//Make sure the Event Handlers have __stdcall calling convention
END_SINK_MAP()
STDMETHOD(GetControlInfo)(LPCONTROLINFO pCI);
STDMETHOD(SetClientSite)(IOleClientSite *pSite);
STDMETHOD(OnAmbientPropertyChange)(DISPID dispid)
{
if (dispid == DISPID_AMBIENT_BACKCOLOR)
{
SetBackgroundColorFromAmbient();
FireViewChange();
}
return IOleControlImpl<CPropPage>::OnAmbientPropertyChange(dispid);
}
// IViewObjectEx
DECLARE_VIEW_STATUS(0)
// IPropPage
public:
enum { IDD = IDD_PROPPAGE };
// PropertyPage
STDMETHOD(GetPageInfo)(BSTR * HelpFile, LONG * HelpContext);
STDMETHOD(get_Dirty)(VARIANT_BOOL * Dirty);
STDMETHOD(Apply)();
private:
CComVariant m_fDirty;
CComPtr<Outlook:ropertyPageSite> m_pPropPageSite;
HBRUSH m_hBrush;
BOOL m_bThemeActive;
CWindow m_Control;
void UpdateBackgroundBrush()
{
m_bThemeActive = IsAppThemed();
// Destroy old brush
if (m_hBrush)
:eleteObject(m_hBrush);
m_hBrush = NULL;
// Only do this if the theme is active
if (m_bThemeActive)
{
RECT rc;
// Get tab control dimensions
m_Control.GetWindowRect(&rc);
// Get the tab control DC
HDC hDC = m_Control.GetDC();
// Create a compatible DC
HDC hDCMem = ::CreateCompatibleDC(hDC);
HBITMAP hBmp = ::CreateCompatibleBitmap(hDC, rc.right - rc.left,
rc.bottom - rc.top);
HBITMAP hBmpOld = (HBITMAP):SelectObject(hDCMem, hBmp));
// Tell the tab control to paint in our DC
m_Control.SendMessage(WM_PRINTCLIENT, (WPARAM)(hDCMem),
(LPARAM)(PRF_ERASEBKGND | PRF_CLIENT | PRF_NONCLIENT));
// Create a pattern brush from the bitmap selected in our DC
m_hBrush = ::CreatePatternBrush(hBmp);
// Restore the bitmap
::SelectObject(hDCMem, hBmpOld);
// Cleanup
:eleteObject(hBmp);
:eleteDC(hDCMem);
m_Control.ReleaseDC(hDC);
}
}
void test();
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
HRESULT hr = EnableThemeDialogTexture(GetParent(),
ETDT_ENABLETAB);
m_Control = GetParent();
DrawThemeParentBackground(m_hWnd, (HDC)wParam, NULL);
UpdateBackgroundBrush();
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Return the created background brush
//
LRESULT OnCtlColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*
bHandled */)
{
if (m_bThemeActive)
{
RECT rc;
// Set the background mode to transparent
::SetBkMode((HDC)(wParam), TRANSPARENT);
// Get the controls window dimensions
::GetWindowRect((HWND)(lParam), &rc);
// Map the coordinates to coordinates with the upper left corner of
dialog control as base
::MapWindowPoints(NULL, m_Control, (LPPOINT)(&rc), 2);
// Adjust the position of the brush for this control (else we see
the top left of the brush as background)
::SetBrushOrgEx((HDC)(wParam), -rc.left, -rc.top, NULL);
// Return the brush
return (LRESULT)(m_hBrush);
}
return FALSE;
}
};
#endif //__PROPPAGE_H_
I used a great sample from here:
http://thecodeproject.com/wtl/ThemedDialog.asp#xx1149261xx
////////////////////////////////////////////////////////////////////////////
// Copyright : Amit Dey 2002
//
// Email :[email protected]
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed unmodified by any means PROVIDING it is
// not sold for profit without the authors written consent, and
// providing that this notice and the authors name is included.
//
// This file is provided 'as is' with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to your
computer.
//
// Do expect bugs.
// Please let me know of any bugs/mods/improvements.
// and I will try to fix/incorporate them into this file.
// Enjoy!
//
// Description : Outlook2K Addin
////////////////////////////////////////////////////////////////////////////
// PropPage.h : Declaration of the CPropPage
#ifndef __PROPPAGE_H_
#define __PROPPAGE_H_
#include "resource.h" // main symbols
#include <atlctl.h>
#import "c:\src\loop.old\include\msoutl9.olb" raw_interfaces_only
#include <c:\src\loop.old\include\atlcontrols.h>
using namespace ATLControls;
/////////////////////////////////////////////////////////////////////////////
// CPropPage
class ATL_NO_VTABLE CPropPage :
public CComObjectRootEx<CComSingleThreadModel>,
public IDispatchImpl<IPropPage, &IID_IPropPage,
&LIBID_OUTLOOKADDINLib>,
public CComCompositeControl<CPropPage>,
public IPersistStreamInitImpl<CPropPage>,
public IOleControlImpl<CPropPage>,
public IOleObjectImpl<CPropPage>,
public IOleInPlaceActiveObjectImpl<CPropPage>,
public IViewObjectExImpl<CPropPage>,
public IOleInPlaceObjectWindowlessImpl<CPropPage>,
public IPersistStorageImpl<CPropPage>,
public ISpecifyPropertyPagesImpl<CPropPage>,
public IQuickActivateImpl<CPropPage>,
public IDataObjectImpl<CPropPage>,
public IProvideClassInfo2Impl<&CLSID_PropPage, NULL,
&LIBID_OUTLOOKADDINLib>,
public CComCoClass<CPropPage, &CLSID_PropPage>,
public IPersistPropertyBagImpl<CPropPage>,
public
IDispatchImpl<PropertyPage,&__uuidof(PropertyPage),&LIBID_OUTLOOKADDINLib>
{
public:
CPropPage()
{
m_bWindowOnly = TRUE;
CalcExtent(m_sizeExtent);
m_hBrush = NULL;
m_bThemeActive = FALSE;
}
DECLARE_REGISTRY_RESOURCEID(IDR_PROPPAGE)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CPropPage)
COM_INTERFACE_ENTRY(IPropPage)
COM_INTERFACE_ENTRY2(IDispatch,IPropPage)
COM_INTERFACE_ENTRY(IViewObjectEx)
COM_INTERFACE_ENTRY(IViewObject2)
COM_INTERFACE_ENTRY(IViewObject)
COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceObject)
COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
COM_INTERFACE_ENTRY(IOleControl)
COM_INTERFACE_ENTRY(IOleObject)
COM_INTERFACE_ENTRY(IPersistStreamInit)
COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
COM_INTERFACE_ENTRY(IQuickActivate)
COM_INTERFACE_ENTRY(IPersistStorage)
COM_INTERFACE_ENTRY(IDataObject)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
COM_INTERFACE_ENTRY(IPersistPropertyBag)
COM_INTERFACE_ENTRY(Outlook:ropertyPage)
END_COM_MAP()
BEGIN_PROP_MAP(CPropPage)
PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
// Example entries
// PROP_ENTRY("Property Description", dispid, clsid)
// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()
BEGIN_MSG_MAP(CPropPage)
MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColor)
CHAIN_MSG_MAP(CComCompositeControl<CPropPage>)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
END_MSG_MAP()
// Handler prototypes:
// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled);
// LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl,
BOOL& bHandled);
// LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
BEGIN_SINK_MAP(CPropPage)
//Make sure the Event Handlers have __stdcall calling convention
END_SINK_MAP()
STDMETHOD(GetControlInfo)(LPCONTROLINFO pCI);
STDMETHOD(SetClientSite)(IOleClientSite *pSite);
STDMETHOD(OnAmbientPropertyChange)(DISPID dispid)
{
if (dispid == DISPID_AMBIENT_BACKCOLOR)
{
SetBackgroundColorFromAmbient();
FireViewChange();
}
return IOleControlImpl<CPropPage>::OnAmbientPropertyChange(dispid);
}
// IViewObjectEx
DECLARE_VIEW_STATUS(0)
// IPropPage
public:
enum { IDD = IDD_PROPPAGE };
// PropertyPage
STDMETHOD(GetPageInfo)(BSTR * HelpFile, LONG * HelpContext);
STDMETHOD(get_Dirty)(VARIANT_BOOL * Dirty);
STDMETHOD(Apply)();
private:
CComVariant m_fDirty;
CComPtr<Outlook:ropertyPageSite> m_pPropPageSite;
HBRUSH m_hBrush;
BOOL m_bThemeActive;
CWindow m_Control;
void UpdateBackgroundBrush()
{
m_bThemeActive = IsAppThemed();
// Destroy old brush
if (m_hBrush)
:eleteObject(m_hBrush);
m_hBrush = NULL;
// Only do this if the theme is active
if (m_bThemeActive)
{
RECT rc;
// Get tab control dimensions
m_Control.GetWindowRect(&rc);
// Get the tab control DC
HDC hDC = m_Control.GetDC();
// Create a compatible DC
HDC hDCMem = ::CreateCompatibleDC(hDC);
HBITMAP hBmp = ::CreateCompatibleBitmap(hDC, rc.right - rc.left,
rc.bottom - rc.top);
HBITMAP hBmpOld = (HBITMAP):SelectObject(hDCMem, hBmp));
// Tell the tab control to paint in our DC
m_Control.SendMessage(WM_PRINTCLIENT, (WPARAM)(hDCMem),
(LPARAM)(PRF_ERASEBKGND | PRF_CLIENT | PRF_NONCLIENT));
// Create a pattern brush from the bitmap selected in our DC
m_hBrush = ::CreatePatternBrush(hBmp);
// Restore the bitmap
::SelectObject(hDCMem, hBmpOld);
// Cleanup
:eleteObject(hBmp);
:eleteDC(hDCMem);
m_Control.ReleaseDC(hDC);
}
}
void test();
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
HRESULT hr = EnableThemeDialogTexture(GetParent(),
ETDT_ENABLETAB);
m_Control = GetParent();
DrawThemeParentBackground(m_hWnd, (HDC)wParam, NULL);
UpdateBackgroundBrush();
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// Return the created background brush
//
LRESULT OnCtlColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*
bHandled */)
{
if (m_bThemeActive)
{
RECT rc;
// Set the background mode to transparent
::SetBkMode((HDC)(wParam), TRANSPARENT);
// Get the controls window dimensions
::GetWindowRect((HWND)(lParam), &rc);
// Map the coordinates to coordinates with the upper left corner of
dialog control as base
::MapWindowPoints(NULL, m_Control, (LPPOINT)(&rc), 2);
// Adjust the position of the brush for this control (else we see
the top left of the brush as background)
::SetBrushOrgEx((HDC)(wParam), -rc.left, -rc.top, NULL);
// Return the brush
return (LRESULT)(m_hBrush);
}
return FALSE;
}
};
#endif //__PROPPAGE_H_