I have written an ActiveX control based on the BUTTON. The only problem I am having at present is when the mouse hovers over the button it doesn't paint the control image in the HOT state. Could some kind person explain where I have gone wrong.
My .CPP file is below:
<br />
<br />
#include "stdafx.h"<br />
#include "CmdButton.h"<br />
#include "CmdButtonCtl.h"<br />
#include "CmdButtonPpg.h"<br />
<br />
<br />
#ifdef _DEBUG<br />
#define new DEBUG_NEW<br />
#undef THIS_FILE<br />
static char THIS_FILE[] = __FILE__;<br />
#endif<br />
<br />
<br />
IMPLEMENT_DYNCREATE(CCmdButtonCtrl, COleControl)<br />
<br />
<br />
<br />
BEGIN_MESSAGE_MAP(CCmdButtonCtrl, COleControl)<br />
ON_WM_CREATE()<br />
ON_WM_MOUSEMOVE()<br />
ON_WM_LBUTTONDOWN()<br />
ON_WM_LBUTTONUP()<br />
ON_MESSAGE(OCM_COMMAND, OnOcmCommand)<br />
ON_MESSAGE(OCM_DRAWITEM, OnOcmDrawItem)<br />
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)<br />
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)<br />
END_MESSAGE_MAP()<br />
<br />
<br />
<br />
BEGIN_DISPATCH_MAP(CCmdButtonCtrl, COleControl)<br />
DISP_PROPERTY_NOTIFY(CCmdButtonCtrl, "Caption", m_szCaption, OnCaptionChanged, VT_BSTR)<br />
DISP_STOCKPROP_FONT()<br />
END_DISPATCH_MAP()<br />
<br />
<br />
<br />
BEGIN_EVENT_MAP(CCmdButtonCtrl, COleControl)<br />
END_EVENT_MAP()<br />
<br />
<br />
<br />
BEGIN_PROPPAGEIDS(CCmdButtonCtrl, 1)<br />
PROPPAGEID(CCmdButtonPropPage::guid)<br />
PROPPAGEID(CLSID_CFontPropPage)<br />
END_PROPPAGEIDS(CCmdButtonCtrl)<br />
<br />
<br />
<br />
IMPLEMENT_OLECREATE_EX(CCmdButtonCtrl, "CMDBUTTON.CmdButtonCtrl.1",<br />
0xe1b9af4b, 0x701e, 0x4d9d, 0x94, 0xf0, 0x36, 0x43, 0x1f, 0x70, 0x3c, 0xee)<br />
<br />
<br />
<br />
IMPLEMENT_OLETYPELIB(CCmdButtonCtrl, _tlid, _wVerMajor, _wVerMinor)<br />
<br />
<br />
<br />
const IID BASED_CODE IID_DCmdButton =<br />
{ 0xb0c488ad, 0x8522, 0x4fbf, { 0xa3, 0xa5, 0xa8, 0x1c, 0x4d, 0x9f, 0x6a, 0x3a } };<br />
const IID BASED_CODE IID_DCmdButtonEvents =<br />
{ 0x4bbc4b44, 0xa6ae, 0x49e3, { 0x8d, 0xaf, 0x91, 0x2e, 0x6e, 0x48, 0xee, 0x9e } };<br />
<br />
<br />
<br />
static const DWORD BASED_CODE _dwCmdButtonOleMisc =<br />
OLEMISC_ACTIVATEWHENVISIBLE |<br />
OLEMISC_SETCLIENTSITEFIRST |<br />
OLEMISC_INSIDEOUT |<br />
OLEMISC_CANTLINKINSIDE |<br />
OLEMISC_RECOMPOSEONRESIZE;<br />
<br />
IMPLEMENT_OLECTLTYPE(CCmdButtonCtrl, IDS_CMDBUTTON, _dwCmdButtonOleMisc)<br />
<br />
<br />
<br />
BOOL CCmdButtonCtrl::CCmdButtonCtrlFactory::UpdateRegistry(BOOL bRegister)<br />
{<br />
<br />
if (bRegister)<br />
return AfxOleRegisterControlClass(<br />
AfxGetInstanceHandle(),<br />
m_clsid,<br />
m_lpszProgID,<br />
IDS_CMDBUTTON,<br />
IDB_CMDBUTTON,<br />
afxRegApartmentThreading,<br />
_dwCmdButtonOleMisc,<br />
_tlid,<br />
_wVerMajor,<br />
_wVerMinor);<br />
else<br />
return AfxOleUnregisterClass(m_clsid, m_lpszProgID);<br />
}<br />
<br />
<br />
<br />
CCmdButtonCtrl::CCmdButtonCtrl()<br />
{<br />
InitializeIIDs(&IID_DCmdButton, &IID_DCmdButtonEvents);<br />
<br />
m_bMouseOverButton = false;<br />
m_bLMouseButtonDown = false;<br />
}<br />
<br />
<br />
<br />
CCmdButtonCtrl::~CCmdButtonCtrl()<br />
{<br />
}<br />
<br />
<br />
<br />
void CCmdButtonCtrl::OnDraw(<br />
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)<br />
{<br />
DoSuperclassPaint(pdc, rcBounds);<br />
}<br />
<br />
<br />
<br />
void CCmdButtonCtrl::DoPropExchange(CPropExchange* pPX)<br />
{<br />
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));<br />
COleControl::DoPropExchange(pPX);<br />
<br />
PX_String( pPX, _T("Caption"), m_szCaption, _T("Caption"));<br />
}<br />
<br />
<br />
<br />
void CCmdButtonCtrl::OnResetState()<br />
{<br />
COleControl::OnResetState();
<br />
}<br />
<br />
<br />
<br />
BOOL CCmdButtonCtrl::PreCreateWindow(CREATESTRUCT& cs)<br />
{<br />
cs.lpszClass = _T("BUTTON");<br />
return COleControl::PreCreateWindow(cs);<br />
}<br />
<br />
<br />
<br />
BOOL CCmdButtonCtrl::IsSubclassedControl()<br />
{<br />
return TRUE;<br />
}<br />
<br />
<br />
<br />
LRESULT CCmdButtonCtrl::OnOcmCommand(WPARAM wParam, LPARAM lParam)<br />
{<br />
#ifdef _WIN32<br />
WORD wNotifyCode = HIWORD(wParam);<br />
#else<br />
WORD wNotifyCode = HIWORD(lParam);<br />
#endif<br />
<br />
switch(wNotifyCode)<br />
{<br />
case BN_CLICKED:<br />
FireClick();<br />
break;<br />
case BN_KILLFOCUS:<br />
<br />
break;<br />
}<br />
<br />
return 0;<br />
}<br />
<br />
LRESULT CCmdButtonCtrl::OnOcmDrawItem(WPARAM wParam, LPARAM lParam)<br />
{<br />
UINT nIDCtl = (UINT) wParam;<br />
LPDRAWITEMSTRUCT lpDrawItemStruct = (LPDRAWITEMSTRUCT) lParam;<br />
HDC dc = lpDrawItemStruct->hDC;<br />
CDC* pDC = CDC::FromHandle(dc);<br />
<br />
BOOL bIsSelected = (lpDrawItemStruct->itemState & ODS_SELECTED);<br />
BOOL bIsFocussed = (lpDrawItemStruct->itemState & ODS_FOCUS);<br />
BOOL bIsDisabled = (lpDrawItemStruct->itemState & ODS_DISABLED);<br />
<br />
CRect rect;<br />
rect.CopyRect(&lpDrawItemStruct->rcItem);<br />
<br />
#ifdef _VISUALSTYLE_XP_H_<br />
if( g_xpStyle.IsAppThemed() )<br />
{<br />
HTHEME hTheme = g_xpStyle.OpenThemeData(GetSafeHwnd(), L"BUTTON");<br />
int state = 1;<br />
<br />
if(bIsSelected)<br />
state = 2;<br />
if(m_bLMouseButtonDown)<br />
state = 3;<br />
<br />
CRect rcContent = rect;<br />
InflateRect(&rcContent, -3, -3);<br />
<br />
HRESULT hr = g_xpStyle.DrawThemeBackground(hTheme, dc, 1, state , &rect, NULL);<br />
hr = g_xpStyle.GetThemeBackgroundContentRect(hTheme, dc, 1, state, &rect, &rcContent);<br />
<br />
if(!m_szCaption.IsEmpty())<br />
{<br />
LPWSTR lpszCaption = new WCHAR[m_szCaption.GetLength()];<br />
LPSTR lpStr = m_szCaption.GetBuffer(m_szCaption.GetLength());<br />
int nLen = MultiByteToWideChar(CP_ACP, 0, lpStr, -1, NULL, NULL);<br />
MultiByteToWideChar(CP_ACP, 0, lpStr, -1, lpszCaption, nLen);<br />
<br />
CFont* pOldFont = SelectStockFont(pDC);<br />
hr = g_xpStyle.DrawThemeText(hTheme, dc, 1, state, lpszCaption, wcslen(lpszCaption), <br />
DT_CENTER | DT_VCENTER | DT_SINGLELINE,<br />
0, &rect);<br />
pDC->SelectObject(pOldFont);<br />
hr = g_xpStyle.CloseThemeData(hTheme);<br />
}<br />
}<br />
else<br />
{<br />
#endif<br />
CBrush brBackground;<br />
brBackground.CreateSolidBrush(GetSysColor(COLOR_BTNFACE));<br />
<br />
if(bIsFocussed)<br />
{<br />
HBRUSH br = CreateSolidBrush(RGB(0, 0 ,0));<br />
FrameRect(dc, &rect, br);<br />
InflateRect(&rect, -1, -1);<br />
DeleteObject(br);<br />
}<br />
<br />
FillRect(dc, &rect ,brBackground);<br />
<br />
if(bIsSelected)<br />
{<br />
HBRUSH br = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));<br />
FrameRect(dc, &rect, br);<br />
DeleteObject(br);<br />
}<br />
else<br />
{<br />
UINT uState = DFCS_BUTTONPUSH | ((m_bMouseOverButton) ? 0x1000 : 0) | <br />
((bIsSelected) ? DFCS_PUSHED : 0);<br />
DrawFrameControl(dc, &rect, DFC_BUTTON, uState);<br />
}<br />
<br />
if(!m_szCaption.IsEmpty())<br />
{<br />
CFont* pOldFont = SelectStockFont(pDC);<br />
int iOldMode = pDC->GetBkMode();<br />
COLORREF crOldText = pDC->GetTextColor();<br />
<br />
CRect rcContent = rect;<br />
InflateRect(&rcContent, -3, -3);<br />
CSize Extent = pDC->GetTextExtent(m_szCaption);<br />
CPoint pt(rcContent.CenterPoint().x - Extent.cx/2, rcContent.CenterPoint().y - Extent.cy/2);<br />
<br />
pDC->SetBkMode(TRANSPARENT);<br />
pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT));<br />
<br />
if(bIsDisabled)<br />
{<br />
CBrush brGray;<br />
brGray.CreateSolidBrush(GetSysColor(COLOR_GRAYTEXT));<br />
pDC->GrayString(&brGray, NULL, (LPARAM)((LPCSTR)m_szCaption), -1, rcContent.left, rcContent.top, rcContent.Width(), rcContent.Height());<br />
}<br />
else<br />
{<br />
pDC->DrawText(m_szCaption, rcContent, DT_CENTER | DT_VCENTER | DT_SINGLELINE);<br />
}<br />
<br />
if(bIsFocussed)<br />
{<br />
DrawFocusRect(dc, &rcContent);<br />
}<br />
<br />
pDC->SetBkMode(iOldMode);<br />
pDC->SetTextColor(crOldText);<br />
}<br />
#ifdef _VISUALSTYLE_XP_H_<br />
}<br />
#endif<br />
<br />
return 0;<br />
}<br />
<br />
<br />
void CCmdButtonCtrl::PreSubclassWindow() <br />
{ <br />
COleControl::PreSubclassWindow();<br />
ModifyStyle(0, BS_OWNERDRAW|BS_NOTIFY);<br />
}<br />
<br />
int CCmdButtonCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) <br />
{<br />
if (COleControl::OnCreate(lpCreateStruct) == -1)<br />
return -1;<br />
<br />
<br />
return 0;<br />
}<br />
<br />
void CCmdButtonCtrl::OnMouseMove(UINT nFlags, CPoint point) <br />
{<br />
COleControl::OnMouseMove(nFlags, point);<br />
<br />
if(!m_bMouseOverButton)<br />
{<br />
TRACKMOUSEEVENT t = {sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_hWnd, 0};<br />
if(::_TrackMouseEvent(&t))<br />
{<br />
m_bMouseOverButton = true;<br />
Invalidate();<br />
}<br />
}<br />
}<br />
<br />
LRESULT CCmdButtonCtrl::OnMouseLeave(WPARAM, LPARAM)<br />
{<br />
ASSERT(m_bMouseOverButton);<br />
m_bMouseOverButton = false;<br />
Invalidate();<br />
return 0;<br />
}<br />
<br />
void CCmdButtonCtrl::OnCaptionChanged() <br />
{<br />
<br />
SetModifiedFlag();<br />
}<br />
<br />
void CCmdButtonCtrl::OnLButtonDown(UINT nFlags, CPoint point) <br />
{<br />
COleControl::OnLButtonDown(nFlags, point);<br />
if(m_bMouseOverButton)<br />
{<br />
m_bLMouseButtonDown = true;<br />
Invalidate();<br />
}<br />
}<br />
<br />
void CCmdButtonCtrl::OnLButtonUp(UINT nFlags, CPoint point) <br />
{<br />
COleControl::OnLButtonUp(nFlags, point);<br />
if(m_bMouseOverButton)<br />
{<br />
m_bLMouseButtonDown = false;<br />
Invalidate();<br />
}<br />
}<br />
|