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

📄 propertytree.h

📁 这是一本学习 window编程的很好的参考教材
💻 H
📖 第 1 页 / 共 3 页
字号:
      case _T(' '):
         // Don't want to hear nasty Windows beep sound...
         return 0;
      default:
         bHandled = FALSE;
         return 0;
      }
   }

   LRESULT OnNavigate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
   {
      switch( wParam) {
      case VK_UP:
      case VK_DOWN:
         _DestroyInplaceWindow();
         SelectItem(GetNextItem(GetSelectedItem(), wParam == VK_UP ? TVGN_PREVIOUSVISIBLE : TVGN_NEXTVISIBLE));
         break;
      }
      return 0;
   }
   LRESULT OnSetCheckState(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
   {
      return SetCheckState( (HTREEITEM) wParam, (BOOL) lParam );
   }
   LRESULT OnUpdateProperty(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
   {
      // Updates a property value using an active editor window.
      // The editor window uses this message to update the attached property class.
      // Parameters:
      //   LPARAM = Window (HWND)
      HWND hWnd = reinterpret_cast<HWND>(lParam);     
      ATLASSERT(hWnd);
      if( !::IsWindow(hWnd) || m_iInplaceIndex == NULL ) return 0;
      ATLASSERT(hWnd==m_hwndInplace);
      IProperty* prop = reinterpret_cast<IProperty*>(TBase::GetItemData(m_iInplaceIndex));
      ATLASSERT(prop);
      if( prop == NULL ) return 0;
      // Ask owner about change
      NMPROPERTYITEM nmh = { m_hWnd, GetDlgCtrlID(), PIN_ITEMCHANGING, prop };
      if( ::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh) == 0 ) {
         // Set new value
         if( !prop->SetValue(hWnd) ) ::MessageBeep((UINT)-1);
         // Let owner know
         nmh.hdr.code = PIN_ITEMCHANGED;
         ::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh);
         // Repaint item
         _InvalidateItem(m_iInplaceIndex);
         // Recycle in-place control so it displays the correct value
         // NOTE: Traps condition where the SetValue() fails!
         HTREEITEM hItem = _FindProperty(prop);
         if( hItem && (hItem == m_iInplaceIndex) ) _SpawnInplaceWindow(prop, hItem);
      }
      return 0;
   }
   LRESULT OnCancelProperty(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
   {
      // Updates a property value using an active editor window.
      // The editor window uses this message to update the attached property class.
      // Parameters:
      //   LPARAM = Window (HWND)
      HWND hWnd = reinterpret_cast<HWND>(lParam);     
      ATLASSERT(hWnd);
      if( !::IsWindow(hWnd) || m_iInplaceIndex == NULL ) return 0;
      ATLASSERT(hWnd==m_hwndInplace);
      IProperty* prop = reinterpret_cast<IProperty*>(TBase::GetItemData(m_iInplaceIndex));
      ATLASSERT(prop);
      // Repaint item
      _InvalidateItem(m_iInplaceIndex);
      // Recycle in-place control so it displays the (old) value
      HTREEITEM hItem = _FindProperty(prop);
      if( hItem && (hItem == m_iInplaceIndex) ) _SpawnInplaceWindow(prop, hItem);
      return 0;
   }
   LRESULT OnChangedProperty(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
   {
      // Updates a property value.
      // A property class uses this message to make sure the corresponding editor window
      // is updated as well.
      // Parameters:
      //   WPARAM = New value (VARIANT*)
      //   LPARAM = Property (IProperty*)
      IProperty* prop = reinterpret_cast<IProperty*>(lParam);
      VARIANT* pVariant = reinterpret_cast<VARIANT*>(wParam);
      ATLASSERT(prop && pVariant);
      if( prop == NULL || pVariant == NULL ) return 0;
      // Ask owner about change
      NMPROPERTYITEM nmh = { m_hWnd, GetDlgCtrlID(), PIN_ITEMCHANGING, prop };
      if( ::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh) == 0 ) {
         // Set new value
         // NOTE: Do not call this from IProperty::SetValue(VARIANT*) = endless loop
         if( !prop->SetValue(*pVariant) ) ::MessageBeep((UINT)-1);
         // Let owner know
         nmh.hdr.code = PIN_ITEMCHANGED;
         ::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh);
      }
      // Locate the updated tree item
      HTREEITEM hItem = _FindProperty(prop);
      // Repaint item
      _InvalidateItem(hItem);
      // Recycle in-place control so it displays the new value
      if( hItem && (hItem == m_iInplaceIndex) ) _SpawnInplaceWindow(prop, hItem);
      return 0;
   }

   LRESULT OnDeleteItem(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
   {
      LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) pnmh;
      _DestroyInplaceWindow();
      ATLASSERT(pnmtv->itemOld.lParam);
      delete (IProperty*) pnmtv->itemOld.lParam;
      return 0;
   }
   LRESULT OnClick(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& bHandled)
   {
      m_bSeenClicks = true;

      // Get the item we're clicking on
      DWORD dwPos = ::GetMessagePos();
      POINT pt = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) };
      ScreenToClient(&pt);
      UINT uFlags;
      HTREEITEM hItem = HitTest(pt, &uFlags);
      // Send click event
      if( hItem ) {
         IProperty* prop = reinterpret_cast<IProperty*>(TBase::GetItemData(hItem));
         ATLASSERT(prop);
         // Test for icon-area click restriction
         bool bClick = prop->IsEnabled() == TRUE;
         switch( prop->GetKind() ) {
         case PROPKIND_CHECK:
            bClick = ((m_di.dwExtStyle & PTS_EX_ICONCLICK) == 0) || (uFlags & TVHT_ONITEMICON);
            if( uFlags & TVHT_ONITEMRIGHT ) bClick = false;
            break;
         case PROPKIND_SIMPLE:
            if( uFlags & TVHT_ONITEMRIGHT ) bClick = false;
            break;
         default:
            if( GetSelectedItem() != hItem ) SelectItem(hItem); // When clicking on the right
            if( uFlags & TVHT_ONITEMRIGHT ) bClick = true;
            break;
         }
         if( bClick ) {
            // Ask owner first
            NMPROPERTYITEM nmh = { m_hWnd, GetDlgCtrlID(), PIN_CLICK, prop };
            if( ::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh) == 0 ) {
               // Send Click action
               LPARAM lParam = ::GetMessagePos();
               prop->Activate(PACT_CLICK, lParam);
            }
         }
      }

      bHandled = FALSE;
      return 0;
   }
   LRESULT OnDblClick(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& bHandled)
   {
      HTREEITEM hItem = GetSelectedItem();
      if( hItem ) {
         IProperty* prop = reinterpret_cast<IProperty*>(TBase::GetItemData(hItem));
         ATLASSERT(prop);
         // Ask owner first
         NMPROPERTYITEM nmh = { m_hWnd, GetDlgCtrlID(), PIN_DBLCLICK, prop };
         if( ::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh) == 0 ) {
            // Send DblClick action
            LPARAM lParam = ::GetMessagePos();
            prop->Activate(PACT_DBLCLICK, lParam);
         }
      }
      bHandled = FALSE;
      return 0;
   }
   LRESULT OnSelChanged(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
   {
      IProperty* prop = NULL;
      HTREEITEM hItem = GetSelectedItem();
      if( hItem ) {
         prop = reinterpret_cast<IProperty*>(TBase::GetItemData(hItem));
         ATLASSERT(prop);
         if( prop->IsEnabled() ) {
            _SpawnInplaceWindow(prop, hItem);
            prop->Activate(PACT_ACTIVATE, 0);
            if( m_di.dwExtStyle & PTS_EX_SINGLECLICKEDIT ) {
               if( prop->GetKind() == PROPKIND_EDIT ) prop->Activate(PACT_DBLCLICK, 0);
            }
         }
         else {
            _DestroyInplaceWindow();
         }
      }
      // Let owner know
      NMPROPERTYITEM nmh = { m_hWnd, GetDlgCtrlID(), PIN_SELCHANGED, prop };
      ::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh);
      return 0;
   }
   LRESULT OnExpanding(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled)
   {
      // Test for style that prevents collapsing
      if( (m_di.dwExtStyle & PTS_EX_NOCOLLAPSE) && m_bSeenClicks ) return TRUE;

      // Convert to PropertyTree notifications...
      LPNMTREEVIEW nmtv = (LPNMTREEVIEW) pnmh;
      HTREEITEM hItem = nmtv->itemNew.hItem;
      IProperty* prop = reinterpret_cast<IProperty*>(TBase::GetItemData(hItem));
      ATLASSERT(prop);
      UINT nMsg = nmtv->action == TVE_COLLAPSE ? PIN_COLLAPSING : PIN_EXPANDING;
      NMPROPERTYITEM nmh = { m_hWnd, GetDlgCtrlID(), nMsg, prop };
      if( ::SendMessage(GetParent(), WM_NOTIFY, nmh.hdr.idFrom, (LPARAM) &nmh) != 0 ) return TRUE;
      
      // Let others have a go...
      bHandled = FALSE;
      return 0;
   }

   // Custom painting

   DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
   {
      return CDRF_NOTIFYITEMDRAW;   // We need per-item notifications
   }

   DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
   {
      return CDRF_NOTIFYPOSTPAINT;   // We need more notifications
   }

   DWORD OnItemPostPaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
   {
      T* pT = static_cast<T*>(this);
      pT->DrawTreeItem(lpNMCustomDraw->hdc, (HTREEITEM) lpNMCustomDraw->dwItemSpec, lpNMCustomDraw->uItemState);
      return CDRF_DODEFAULT;
   }

   // Overridables

   void DrawTreeItem(CDCHandle dc, HTREEITEM hItem, UINT iState)
   {
      IProperty* prop = reinterpret_cast<IProperty*>(TBase::GetItemData(hItem));
      ATLASSERT(prop);

      // Get paint rectangle
      RECT rcItem;
      _GetInplaceRect(hItem, &rcItem);

      // Setup drawinfo
      PROPERTYDRAWINFO di = m_di;
      di.hDC = dc;
      di.rcItem = rcItem;
      di.state = 0;
      if( !prop->IsEnabled() ) di.state |= ODS_DISABLED;
      if( hItem == m_iInplaceIndex ) di.state |= ODS_COMBOBOXEDIT;

      // A disabled TreeView control is painted grey in Windows2000
      if( GetStyle() & WS_DISABLED ) {
         di.clrText = di.clrDisabled;
         di.clrBack = ::GetSysColor(COLOR_BTNFACE);
      }

      // Erase background
      dc.FillSolidRect(&rcItem, di.clrBack);

      // Draw border
      bool bDrawBorder;
      switch( prop->GetKind() ) {
      case PROPKIND_SIMPLE:
      case PROPKIND_CHECK:
         bDrawBorder = false;
         break;
      default:
         bDrawBorder = (iState & CDIS_SELECTED) != 0;
      }
      if( bDrawBorder ) {
         RECT rcBorder = rcItem;
         ::OffsetRect(&rcBorder, -1, 0);
         CBrush brBorder;
         brBorder.CreateSolidBrush(di.clrBorder);
         dc.FrameRect(&rcBorder, brBorder);
      }

      // Paint value
      HFONT hOldFont = dc.SelectFont(di.TextFont);
      prop->DrawValue(di);
      dc.SelectFont(hOldFont);
  }

};


class CPropertyTreeCtrl : public CPropertyTreeImpl<CPropertyTreeCtrl>
{
public:
   DECLARE_WND_SUPERCLASS(_T("WTL_PropertyTree"), GetWndClassName())
};


#endif // !defined(AFX_PROPERTYTREE_H__20020106_D62E_63DE_426B_0080AD509054__INCLUDED_)

⌨️ 快捷键说明

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