⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 propertyitemimpl.h

📁 这是一本学习 window编程的很好的参考教材
💻 H
📖 第 1 页 / 共 2 页
字号:
#ifndef __PROPERTYITEMIMPL__H
#define __PROPERTYITEMIMPL__H
#include "util.h"

#pragma once

/////////////////////////////////////////////////////////////////////////////
// CPropertyItemImpl - Property implementations for the Property controls
//
// Written by Bjarke Viksoe (bjarke@viksoe.dk)
// Copyright (c) 2001-2002 Bjarke Viksoe.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed 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 you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.
//

#ifndef __PROPERTYITEM__H
  #error PropertyItemImpl.h requires PropertyItem.h to be included first
#endif

#ifndef __PROPERTYITEMEDITORS__H
  #error PropertyItemImpl.h requires PropertyItemEditors.h to be included first
#endif

#ifndef __ATLBASE_H__
  #error PropertyItem.h requires atlbase.h to be included first
#endif



/////////////////////////////////////////////////////////////////////////////
// Base CProperty class

class CProperty : public IProperty
{
protected:
   HWND   m_hWndOwner;
   LPTSTR m_pszName;
   bool   m_fEnabled;
   LPARAM m_lParam;

public:
   CProperty(LPCTSTR pstrName, LPARAM lParam) : m_fEnabled(true), m_lParam(lParam), m_hWndOwner(NULL)
   {
      ATLASSERT(!::IsBadStringPtr(pstrName,-1));
      ATLTRY(m_pszName = new TCHAR[ (::lstrlen(pstrName) * sizeof(TCHAR)) + 1 ]);
      ATLASSERT(m_pszName);
      ::lstrcpy(m_pszName, pstrName);
   }
   virtual ~CProperty()
   {
      delete [] m_pszName;
   }
   virtual void SetOwner(HWND hWnd, LPVOID /*pData*/)
   {
      ATLASSERT(::IsWindow(hWnd));
      ATLASSERT(m_hWndOwner==NULL); // Cannot set it twice
      m_hWndOwner = hWnd;
   }
   virtual LPCTSTR GetName() const
   {
      return m_pszName; // Dangerous!
   }
   virtual void SetEnabled(BOOL bEnable)
   {
      m_fEnabled = bEnable == TRUE;
   }
   virtual BOOL IsEnabled() const
   {
      return m_fEnabled;
   }
   virtual void SetItemData(LPARAM lParam)
   {
      m_lParam = lParam;
   }
   virtual LPARAM GetItemData() const
   {
      return m_lParam;
   }
   virtual void DrawName(PROPERTYDRAWINFO& di)
   {
      CDCHandle dc(di.hDC);
      COLORREF clrBack, clrFront;
      if( di.state & ODS_DISABLED ) {
         clrFront = di.clrDisabled;
         clrBack = di.clrBack;
      }
      else if( di.state & ODS_SELECTED ) {
         clrFront = di.clrSelText;
         clrBack = di.clrSelBack;
      }
      else {
         clrFront = di.clrText;
         clrBack = di.clrBack;
      }
      RECT rcItem = di.rcItem;
      dc.FillSolidRect(&rcItem, clrBack);
      rcItem.left += 2; // Indent text
      dc.SetBkMode(TRANSPARENT);
      dc.SetBkColor(clrBack);
      dc.SetTextColor(clrFront);
      dc.DrawText(m_pszName, -1, &rcItem, DT_LEFT | DT_SINGLELINE | DT_EDITCONTROL | DT_NOPREFIX | DT_VCENTER);
   }
   virtual void DrawValue(PROPERTYDRAWINFO& /*di*/) 
   { 
   }
   virtual HWND CreateInplaceControl(HWND /*hWnd*/, const RECT& /*rc*/) 
   { 
      return NULL; 
   }
   virtual BOOL Activate(UINT /*action*/, LPARAM /*lParam*/) 
   { 
      return TRUE; 
   }
   virtual BOOL GetDisplayValue(LPTSTR /*pstr*/, UINT /*cchMax*/) const 
   { 
      return FALSE; 
   }
   virtual UINT GetDisplayValueLength() const 
   { 
      return 0; 
   }
   virtual BOOL GetValue(VARIANT* /*pValue*/) const 
   { 
      return FALSE; 
   }
   virtual BOOL SetValue(const VARIANT& /*value*/) 
   { 
      ATLASSERT(false);
      return FALSE; 
   }
   virtual BOOL SetValue(HWND /*hWnd*/) 
   { 
      ATLASSERT(false);
      return FALSE; 
   }
};


/////////////////////////////////////////////////////////////////////////////
// Simple property (displays text)

class CPropertyItem : public CProperty
{
protected:
   CComVariant m_val;

public:
   CPropertyItem(LPCTSTR pstrName, LPARAM lParam) : CProperty(pstrName, lParam)
   {
   }
   BYTE GetKind() const 
   { 
      return PROPKIND_SIMPLE; 
   }
   void DrawValue(PROPERTYDRAWINFO& di)
   {
	try{
		UINT cchMax = GetDisplayValueLength() + 1;
		LPTSTR pszText = (LPTSTR) _alloca(cchMax * sizeof(TCHAR));
		ATLASSERT(pszText);
		if( !GetDisplayValue(pszText, cchMax) ) return;
		CDCHandle dc(di.hDC);
		dc.SetBkMode(TRANSPARENT);
		dc.SetTextColor(di.state & ODS_DISABLED ? di.clrDisabled : di.clrText);
		dc.SetBkColor(di.clrBack);
		RECT rcText = di.rcItem;
		rcText.left += PROP_TEXT_INDENT;
		dc.DrawText(pszText, -1, 
			&rcText, 
			DT_LEFT | DT_SINGLELINE | DT_EDITCONTROL | DT_NOPREFIX | DT_END_ELLIPSIS | DT_VCENTER);
	   }
	  	catch (_com_error &e)
		{

		

		}
		catch(...)
		{
			
		
		}

   }
   BOOL GetDisplayValue(LPTSTR pstr, UINT cchMax) const
   {      
      ATLASSERT(!::IsBadStringPtr(pstr, cchMax));
      // Convert VARIANT to string and use that as display string...
      CComVariant v;
      if( FAILED( v.ChangeType(VT_BSTR, &m_val) ) ) return FALSE;
      USES_CONVERSION;
      ::lstrcpyn(pstr, OLE2CT(v.bstrVal), cchMax);
      return TRUE;
   }
   UINT GetDisplayValueLength() const
   {
      // Hmm, need to convert it to display string first and
      // then take the length...
      // TODO: Call GetDisplayValue() instead...
      CComVariant v;
      if( FAILED( v.ChangeType(VT_BSTR, &m_val) ) ) return 0;
      return v.bstrVal == NULL ? 0 : ::lstrlenW(v.bstrVal);
   }
   BOOL GetValue(VARIANT* pVal) const
   {
      return SUCCEEDED( CComVariant(m_val).Detach(pVal) );
   }
   BOOL SetValue(const VARIANT& value)
   {
      m_val = value;
      return TRUE;
   }
};


/////////////////////////////////////////////////////////////////////////////
// ReadOnly property (enhanced display feature)

class CPropertyReadOnlyItem : public CPropertyItem
{
protected:
   UINT m_uStyle;
   HICON m_hIcon;
   COLORREF m_clrBack;
   COLORREF m_clrText;

public:
   CPropertyReadOnlyItem(LPCTSTR pstrName, LPARAM lParam) : 
      CPropertyItem(pstrName, lParam), 
      m_uStyle( DT_LEFT | DT_SINGLELINE | DT_EDITCONTROL | DT_NOPREFIX | DT_END_ELLIPSIS | DT_VCENTER ),
      m_clrBack( (COLORREF) -1 ),
      m_clrText( (COLORREF) -1 ),
      m_hIcon(NULL)
   {
   }
   void DrawValue(PROPERTYDRAWINFO& di)
   {
	   try{
      // Get property text
      UINT cchMax = GetDisplayValueLength() + 1;
      LPTSTR pszText = (LPTSTR) _alloca(cchMax * sizeof(TCHAR));
      ATLASSERT(pszText);
      if( !GetDisplayValue(pszText, cchMax) ) return;
      // Prepare paint
      RECT rcText = di.rcItem;
      CDCHandle dc(di.hDC);
      dc.SetBkMode(OPAQUE);
      // Set background color
      COLORREF clrBack = di.clrBack;
      if( m_clrBack != (COLORREF) -1 ) clrBack = m_clrBack;
      dc.SetBkColor(clrBack);
      // Set text color
      COLORREF clrText = di.clrText;
      if( m_clrText != (COLORREF) -1 ) clrText = m_clrText;
      if( di.state & ODS_DISABLED ) clrText = di.clrDisabled; 
      dc.SetTextColor(clrText);
      // Draw icon if available
      if( m_hIcon ) {
         POINT pt = { rcText.left + 2, rcText.top + 2 };
         SIZE sz = { ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON) };
         ::DrawIconEx(dc, pt.x, pt.y, m_hIcon, sz.cx, sz.cy, 0, NULL, DI_NORMAL);
         rcText.left += sz.cx + 4;
      }
      // Draw text with custom style
      rcText.left += PROP_TEXT_INDENT;
      dc.DrawText(pszText, -1, 
         &rcText, 
         m_uStyle);
	   }
	  	catch (_com_error &e)
		{

		

		}
		catch(...)
		{
			
		}

   }

   // Operations

   // NOTE: To use these methods, you must cast the HPROPERTY 
   //       handle back to the CPropertyReadOnlyItem class.
   //       Nasty stuff, but so far I've settled with this approach.

   COLORREF SetBkColor(COLORREF clrBack)
   {
      COLORREF clrOld = m_clrBack;
      m_clrBack = clrBack;
      return clrOld;
   }
   COLORREF SetTextColor(COLORREF clrText)
   {
      COLORREF clrOld = m_clrText;
      m_clrText = clrText;
      return clrOld;
   }
   HICON SetIcon(HICON hIcon)
   {
      HICON hOldIcon = m_hIcon;
      m_hIcon = hIcon;
      return hOldIcon;
   }
   void ModifyDrawStyle(UINT uRemove, UINT uAdd)
   {
      m_uStyle = (m_uStyle & ~uRemove) | uAdd;
   }
};


/////////////////////////////////////////////////////////////////////////////
// Simple Value property

class CPropertyEditItem : public CPropertyItem
{
protected:
   HWND m_hwndEdit;

public:
   CPropertyEditItem(LPCTSTR pstrName, LPARAM lParam) : 
      CPropertyItem(pstrName, lParam), 
      m_hwndEdit(NULL)
   {
   }
   BYTE GetKind() const 
   { 
      return PROPKIND_EDIT; 
   }
   HWND CreateInplaceControl(HWND hWnd, const RECT& rc) 
   {
      // Get default text
      UINT cchMax = GetDisplayValueLength() + 1;
      LPTSTR pszText = (LPTSTR) _alloca(cchMax * sizeof(TCHAR));
      ATLASSERT(pszText);
      if( !GetDisplayValue(pszText, cchMax) ) return NULL;
      // Create EDIT control
      CPropertyEditWindow* win = new CPropertyEditWindow();
      ATLASSERT(win);
      RECT rcWin = rc;
      m_hwndEdit = win->Create(hWnd, rcWin, pszText, WS_VISIBLE | WS_CHILD | ES_LEFT | ES_AUTOHSCROLL);
      ATLASSERT(::IsWindow(m_hwndEdit));
      // Simple hack to validate numbers
      switch( m_val.vt ) {
      case VT_UI1:
      case VT_UI2:
      case VT_UI4:
         win->ModifyStyle(0, ES_NUMBER);
      }
      return m_hwndEdit;
   }
   BOOL SetValue(const VARIANT& value)
   {
      if( m_val.vt == VT_EMPTY ) m_val = value;
      return SUCCEEDED( m_val.ChangeType(m_val.vt, &value) );
   }
   BOOL SetValue(HWND hWnd) 
   { 
      ATLASSERT(::IsWindow(hWnd));
      int len = ::GetWindowTextLength(hWnd) + 1;
      LPTSTR pstr = (LPTSTR) _alloca(len * sizeof(TCHAR));
      ATLASSERT(pstr);
      if( ::GetWindowText(hWnd, pstr, len) == 0 ) {
         // Bah, an empty string AND an error causes the same return code!
         if( ::GetLastError() != 0 ) return FALSE;
      }
      CComVariant v = pstr;
      return SetValue(v);
   }
   BOOL Activate(UINT action, LPARAM /*lParam*/)
   {
      switch( action ) {
      case PACT_TAB:
      case PACT_SPACE:
      case PACT_DBLCLICK:
         if( ::IsWindow(m_hwndEdit) ) {
            ::SetFocus(m_hwndEdit);
            ::SendMessage(m_hwndEdit, EM_SETSEL, 0, -1);
         }
         break;
      }
      return TRUE;
   }
};


/////////////////////////////////////////////////////////////////////////////
// Simple Value property

class CPropertyDateItem : public CPropertyEditItem
{
public:
   CPropertyDateItem(LPCTSTR pstrName, LPARAM lParam) : 
      CPropertyEditItem(pstrName, lParam)
   {
   }
   HWND CreateInplaceControl(HWND hWnd, const RECT& rc) 
   {
      // Get default text
      UINT cchMax = GetDisplayValueLength() + 1;
      LPTSTR pszText = (LPTSTR) _alloca(cchMax * sizeof(TCHAR));
      ATLASSERT(pszText);
      if( !GetDisplayValue(pszText, cchMax) ) return NULL;
      // Create window
      CPropertyDateWindow* win = new CPropertyDateWindow();
      ATLASSERT(win);
      RECT rcWin = rc;
      m_hwndEdit = win->Create(hWnd, rcWin, pszText);
      ATLASSERT(win->IsWindow());
      return *win;
   }
   BOOL GetDisplayValue(LPTSTR pstr, UINT cchMax) const
   {
      if( m_val.date == 0.0 ) {
         ::lstrcpy(pstr, _T(""));
         return TRUE;
      }
      return CPropertyEditItem::GetDisplayValue(pstr, cchMax);
   }
   BOOL SetValue(const VARIANT& value)
   {
      if( value.vt == VT_BSTR && ::SysStringLen(value.bstrVal) == 0 ) {
         m_val.date = 0.0;
         return TRUE;
      }
      return CPropertyEditItem::SetValue(value);
   }
   BOOL SetValue(HWND hWnd)
   {
      if( ::GetWindowTextLength(hWnd) == 0 ) {
         m_val.date = 0.0;
         return TRUE;
      }
      return CPropertyEditItem::SetValue(hWnd);
   }
};


/////////////////////////////////////////////////////////////////////////////
// Checkmark button

class CPropertyCheckButtonItem : public CProperty
{
protected:
   bool m_bValue;

public:
   CPropertyCheckButtonItem(LPCTSTR pstrName, bool bValue, LPARAM lParam) : 
      CProperty(pstrName, lParam),
      m_bValue(bValue)
   {
   }
   BYTE GetKind() const 
   { 
      return PROPKIND_CHECK; 
   }
   BOOL GetValue(VARIANT* pVal) const
   {
      return SUCCEEDED( CComVariant(m_bValue).Detach(pVal) );
   }
   BOOL SetValue(const VARIANT& value)
   {
      // Set a new value
      switch( value.vt ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -