// PropListCtl.cpp : Implementation of the CPropListCtrl ActiveX Control class.
#include "stdafx.h"
#include "PropList.h"
#include "PropListCtl.h"
#include "PropListPpg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define BorderNone 0
#define BorderRaized 1
#define BorderSunken 2
#define BorderFlat 3
#define BorderStatic 4
IMPLEMENT_DYNCREATE(CPropListCtrl, COleControl)
CPropListCtrl* pControl = NULL;
/////////////////////////////////////////////////////////////////////////////
// Message map
BEGIN_MESSAGE_MAP(CPropListCtrl, COleControl)
//{{AFX_MSG_MAP(CPropListCtrl)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_CTLCOLOR()
//}}AFX_MSG_MAP
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// Dispatch map
BEGIN_DISPATCH_MAP(CPropListCtrl, COleControl)
//{{AFX_DISPATCH_MAP(CPropListCtrl)
DISP_PROPERTY_EX(CPropListCtrl, "Precision", GetPrecision, SetPrecision, VT_I2)
DISP_PROPERTY_EX(CPropListCtrl, "BorderStyle", GetBorderStyle, SetBorderStyle, VT_I2)
DISP_FUNCTION(CPropListCtrl, "Clear", Clear, VT_EMPTY, VTS_NONE)
DISP_FUNCTION(CPropListCtrl, "AddProperty", AddProperty, VT_EMPTY, VTS_BSTR VTS_BSTR VTS_VARIANT VTS_BSTR VTS_I2 VTS_BOOL)
DISP_FUNCTION(CPropListCtrl, "SetValue", SetValue, VT_EMPTY, VTS_BSTR VTS_VARIANT)
//}}AFX_DISPATCH_MAP
DISP_FUNCTION_ID(CPropListCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()
/////////////////////////////////////////////////////////////////////////////
// Event map
BEGIN_EVENT_MAP(CPropListCtrl, COleControl)
//{{AFX_EVENT_MAP(CPropListCtrl)
EVENT_CUSTOM("PropertyChanged", FirePropertyChanged, VTS_BSTR VTS_VARIANT)
EVENT_CUSTOM("ButtonClicked", FireButtonClicked, VTS_BSTR VTS_I2 VTS_PVARIANT)
//}}AFX_EVENT_MAP
END_EVENT_MAP()
/////////////////////////////////////////////////////////////////////////////
// Property pages
/*
// TODO: Add more property pages as needed. Remember to increase the count!
BEGIN_PROPPAGEIDS(CPropListCtrl, 1)
PROPPAGEID(CPropListPropPage::guid)
END_PROPPAGEIDS(CPropListCtrl)
*/
/////////////////////////////////////////////////////////////////////////////
// Initialize class factory and guid
IMPLEMENT_OLECREATE_EX(CPropListCtrl, "PROPLIST.PropListCtrl.1",
0x75c461d9, 0x9588, 0x415a, 0x8d, 0x8f, 0x4e, 0xa2, 0x43, 0x7, 0x3, 0xb9)
/////////////////////////////////////////////////////////////////////////////
// Type library ID and version
IMPLEMENT_OLETYPELIB(CPropListCtrl, _tlid, _wVerMajor, _wVerMinor)
/////////////////////////////////////////////////////////////////////////////
// Interface IDs
const IID BASED_CODE IID_DPropList =
{ 0x384ef845, 0x4e35, 0x4a9f, { 0xb8, 0x53, 0xc8, 0x98, 0xa5, 0xb5, 0xd, 0x23 } };
const IID BASED_CODE IID_DPropListEvents =
{ 0x29fd1dc1, 0x292c, 0x4823, { 0x97, 0x51, 0xc5, 0xd1, 0x60, 0xdb, 0xb0, 0x65 } };
/////////////////////////////////////////////////////////////////////////////
// Control type information
static const DWORD BASED_CODE _dwPropListOleMisc =
OLEMISC_ACTIVATEWHENVISIBLE |
OLEMISC_SETCLIENTSITEFIRST |
OLEMISC_INSIDEOUT |
OLEMISC_CANTLINKINSIDE |
OLEMISC_RECOMPOSEONRESIZE;
IMPLEMENT_OLECTLTYPE(CPropListCtrl, IDS_PROPLIST, _dwPropListOleMisc)
/////////////////////////////////////////////////////////////////////////////
// CPropListCtrl::CPropListCtrlFactory::UpdateRegistry -
// Adds or removes system registry entries for CPropListCtrl
BOOL CPropListCtrl::CPropListCtrlFactory::UpdateRegistry(BOOL bRegister)
{
// TODO: Verify that your control follows apartment-model threading rules.
// Refer to MFC TechNote 64 for more information.
// If your control does not conform to the apartment-model rules, then
// you must modify the code below, changing the 6th parameter from
// afxRegApartmentThreading to 0.
if (bRegister)
return AfxOleRegisterControlClass(
AfxGetInstanceHandle(),
m_clsid,
m_lpszProgID,
IDS_PROPLIST,
IDB_PROPLIST,
afxRegApartmentThreading,
_dwPropListOleMisc,
_tlid,
_wVerMajor,
_wVerMinor);
else
return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}
/////////////////////////////////////////////////////////////////////////////
// Licensing strings
static const TCHAR BASED_CODE _szLicFileName[] = _T("PropList.lic");
static const WCHAR BASED_CODE _szLicString[] =
L"Copyright (c) 2004 Meidan";
/////////////////////////////////////////////////////////////////////////////
// CPropListCtrl::CPropListCtrlFactory::VerifyUserLicense -
// Checks for existence of a user license
BOOL CPropListCtrl::CPropListCtrlFactory::VerifyUserLicense()
{
return 1;
return AfxVerifyLicFile(AfxGetInstanceHandle(), _szLicFileName,
_szLicString);
}
/////////////////////////////////////////////////////////////////////////////
// CPropListCtrl::CPropListCtrlFactory::GetLicenseKey -
// Returns a runtime licensing key
BOOL CPropListCtrl::CPropListCtrlFactory::GetLicenseKey(DWORD dwReserved,
BSTR FAR* pbstrKey)
{
if (pbstrKey == NULL)
return FALSE;
*pbstrKey = SysAllocString(_szLicString);
return (*pbstrKey != NULL);
}
/////////////////////////////////////////////////////////////////////////////
// CPropListCtrl::CPropListCtrl - Constructor
CPropListCtrl::CPropListCtrl()
{
InitializeIIDs(&IID_DPropList, &IID_DPropListEvents);
// TODO: Initialize your control's instance data here.
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT)); // Clear out structure.
lf.lfHeight = 13; // Request a 20-pixel-high font
strcpy(lf.lfFaceName, "Tahoma"); // with face name "Arial".
fntReg.CreateFontIndirect(&lf);
lf.lfWeight = FW_BOLD;
fntBold.CreateFontIndirect(&lf);
m_brush.CreateSolidBrush(RGB(255,255,255));
pControl = this;
}
/////////////////////////////////////////////////////////////////////////////
// CPropListCtrl::~CPropListCtrl - Destructor
CPropListCtrl::~CPropListCtrl()
{
// TODO: Cleanup your control's instance data here.
}
/////////////////////////////////////////////////////////////////////////////
// CPropListCtrl::OnDraw - Drawing function
void CPropListCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
// TODO: Replace the following code with your own drawing code.
pdc->FillSolidRect(rcInvalid,RGB(255,255,255));
CRect rc = rcBounds;
switch (m_border)
{
case BorderRaized:
pdc->DrawEdge(rc,EDGE_RAISED,BF_RECT);
break;
case BorderSunken:
pdc->DrawEdge(rc,EDGE_SUNKEN,BF_RECT);
break;
case BorderFlat:
pdc->DrawEdge(rc,BDR_RAISEDOUTER|BDR_RAISEDINNER,BF_RECT|BF_FLAT);
break;
case BorderStatic:
pdc->DrawEdge(rc,BDR_SUNKENINNER,BF_RECT);
break;
}
rc.top = rc.bottom-60;
CFont* pOldFont = (CFont*)pdc->SelectObject(&fntBold);
rc.DeflateRect(2,1);
pdc->DrawEdge(rc,EDGE_ETCHED,BF_RECT);
rc.DeflateRect(3,2);
pdc->DrawText("Description:",rc,DT_SINGLELINE|DT_LEFT|DT_TOP);
if (IsWindow(m_list.m_hWnd))
{
pdc->SaveDC();
CRect rcList;
m_list.GetWindowRect(rcList);
ScreenToClient(&rcList); // relative to this view
CPoint ptOffset = rcBounds.TopLeft();
ptOffset += rcList.TopLeft();
pdc->LPtoDP(&ptOffset);
pdc->OffsetViewportOrg(ptOffset.x, ptOffset.y);
m_list.Print(pdc,PRF_CLIENT);
pdc->RestoreDC(-1);
}
// m_list.PrintClient(pdc,PRF_CLIENT);
if (!IsOptimizedDraw())
{
// The container does not support optimized drawing.
// TODO: if you selected any GDI objects into the device context *pdc,
// restore the previously-selected objects here.
// For more information, please see MFC technical note #nnn,
// "Optimizing an ActiveX Control".
if (pOldFont)
pdc->SelectObject(pOldFont);
}
}
/////////////////////////////////////////////////////////////////////////////
// CPropListCtrl::DoPropExchange - Persistence support
void CPropListCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
// TODO: Call PX_ functions for each persistent custom property.
PX_Short(pPX,"BorderStyle",m_border,4);
}
/////////////////////////////////////////////////////////////////////////////
// CPropListCtrl::GetControlFlags -
// Flags to customize MFC's implementation of ActiveX controls.
//
// For information on using these flags, please see MFC technical note
// #nnn, "Optimizing an ActiveX Control".
DWORD CPropListCtrl::GetControlFlags()
{
DWORD dwFlags = COleControl::GetControlFlags();
// The control can optimize its OnDraw method, by not restoring
// the original GDI objects in the device context.
dwFlags |= canOptimizeDraw;
return dwFlags;
}
/////////////////////////////////////////////////////////////////////////////
// CPropListCtrl::OnResetState - Reset control to default state
void CPropListCtrl::OnResetState()
{
COleControl::OnResetState(); // Resets defaults found in DoPropExchange
// TODO: Reset any other control state here.
}
/////////////////////////////////////////////////////////////////////////////
// CPropListCtrl::AboutBox - Display an "About" box to the user
void CPropListCtrl::AboutBox()
{
CDialog dlgAbout(IDD_ABOUTBOX_PROPLIST);
dlgAbout.DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CPropListCtrl message handlers
int CPropListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
CRect rectCl;
GetClientRect(rectCl);
rectCl.bottom -= 60;
m_list.Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|LBS_HASSTRINGS|LBS_NOTIFY|LBS_NOINTEGRALHEIGHT|LBS_OWNERDRAWVARIABLE,
rectCl,this,100);
m_info.Create ("",WS_CHILD|WS_VISIBLE,rectCl,this);
m_info.SetFont(&fntReg);
m_list.info = &m_info;
return 0;
}
void CPropListCtrl::OnSize(UINT nType, int cx, int cy)
{
COleControl::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
CRect rectCl;
GetClientRect(rectCl);
rectCl.DeflateRect(2,2);
rectCl.bottom -= 60;
if (IsWindow(m_list.m_hWnd))
m_list.MoveWindow(rectCl);
rectCl.top = rectCl.bottom+16;
rectCl.bottom+=60;
rectCl.DeflateRect(3,2);
if (IsWindow(m_info.m_hWnd))
m_info.MoveWindow(rectCl);
}
void CPropListCtrl::Clear()
{
// TODO: Add your dispatch handler code here
m_list.Clear();
}
short CPropListCtrl::GetPrecision()
{
// TODO: Add your property handler here
return m_precision;
}
void CPropListCtrl::SetPrecision(short nNewValue)
{
// TODO: Add your property handler here
if (nNewValue >= 0 && nNewValue < 10)
m_precision = nNewValue;
SetModifiedFlag();
}
void CPropListCtrl::AddProperty(LPCTSTR Category, LPCTSTR Caption, const VARIANT FAR& Value, LPCTSTR Description, short ButtonType, BOOL IsEnabled)
{
// TODO: Add your dispatch handler code here
m_list.AddProperty(Category,Caption,Value,Description,ButtonType,IsEnabled);
}
HBRUSH CPropListCtrl::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
// TODO: Change any attributes of the DC here
pDC->SetBkColor(RGB(255,255,255));
// TODO: Return a different brush if the default is not desired
return m_brush;
}
void CPropListCtrl::OnPropertyChanged(LPCTSTR PropertyName, const VARIANT &NewValue)
{
FirePropertyChanged(PropertyName,NewValue);
}
void CPropListCtrl::OnButtonClicked(LPCTSTR PropertyName, short ButtonType, VARIANT *Value)
{
FireButtonClicked(PropertyName,ButtonType,Value);
}
short CPropListCtrl::GetBorderStyle()
{
// TODO: Add your property handler here
return m_border;
}
void CPropListCtrl::SetBorderStyle(short nNewValue)
{
// TODO: Add your property handler here
m_border = nNewValue;
SetModifiedFlag();
Invalidate();
}
void CPropListCtrl::SetValue(LPCTSTR PropertyName, const VARIANT FAR& Value)
{
// TODO: Add your dispatch handler code here
HRESULT res = m_list.SetValue(PropertyName,Value);
CString str;
str.Format("Property \"%s\" does not exist",PropertyName);
if (res == E_FAIL)
ThrowError(CTL_E_PROPERTYNOTFOUND,str);
if (res == E_INVALIDARG)
ThrowError(CTL_E_INVALIDPROPERTYVALUE,"Wrong parameter type");
}