// PropTreeItemCombo.cpp : implementation file // // Copyright (C) 1998-2001 Scott Ramsay // sramsay@gonavi.com // http://www.gonavi.com // // This material is provided "as is", with absolutely no warranty expressed // or implied. Any use is at your own risk. // // Permission to use or copy this software for any purpose is hereby granted // without fee, provided the above notices are retained on all copies. // Permission to modify the code and to distribute modified code is granted, // provided the above notices are retained, and a notice that the code was // modified is included with the above copyright notice. // // If you use this code, drop me an email. I'd like to know if you find the code // useful. #include "stdafx.h" #include "Resource.h" #include "PropCtrl.h" #include "PropItemCombo.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define DROPDOWN_HEIGHT 150 ///////////////////////////////////////////////////////////////////////////// // CPropItemCombo CPropItemCombo::CPropItemCombo() { m_nDropHeight = DROPDOWN_HEIGHT, m_pText = NULL; m_pDouble = NULL; m_pInt = NULL; m_nItemType = ITEMTYPE_COMBOBOX; } CPropItemCombo::~CPropItemCombo() { } BEGIN_MESSAGE_MAP(CPropItemCombo, CComboBox) //{{AFX_MSG_MAP(CPropItemCombo) ON_CONTROL_REFLECT(CBN_SELCHANGE, OnSelchange) ON_CONTROL_REFLECT(CBN_EDITCHANGE, OnEditchange) ON_CONTROL_REFLECT(CBN_KILLFOCUS, OnKillfocus) ON_CONTROL_REFLECT(CBN_DROPDOWN, OnDropdown) // ON_BN_CLICKED(IDC_BUTTON, OnButtonClick) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CPropItemCombo message handlers void CPropItemCombo::DrawAttribute(CDC* pDC, const RECT& rc) { ASSERT(m_pProp!=NULL); // verify the window has been created if (!IsWindow(m_hWnd)) { TRACE0("CPropItemCombo::DrawAttribute() - The window has not been created\n"); return; } // pDC->SelectObject(IsReadOnly() ? m_pProp->GetNormalFont() : m_pProp->GetBoldFont()); pDC->SelectObject(m_pProp->GetNormalFont()); if (IsReadOnly()) pDC->SetTextColor(RGB(140,140,140)); else pDC->SetTextColor(RGB(0,0,0)); pDC->SetBkMode(TRANSPARENT); CRect r = rc; CString csText = GetValueText(); pDC->DrawText(csText, r, DT_SINGLELINE|DT_VCENTER); } void CPropItemCombo::OnMove() { if (IsWindow(m_hWnd) && IsWindowVisible()) SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width() + 1, m_rc.Height(), SWP_NOZORDER|SWP_SHOWWINDOW); } void CPropItemCombo::OnActivate() { // activate the combo box SetWindowPos(NULL, m_rc.left, m_rc.top, m_rc.Width(), m_rc.Height() + m_nDropHeight, SWP_NOZORDER|SWP_SHOWWINDOW); SetWindowText(GetValueText()); if (!m_bEdit && GetCount()) ShowDropDown(TRUE); // 原来有按钮的话先隐藏先隐藏 ShowButton(FALSE); ShowSpinCtrl(FALSE); // add button on right if (m_bHasBt) CreateButton(this); if (m_bHasSpinCtrl) CreateSpinCtrl(this); SetFocus(); } BOOL CPropItemCombo::CreateDropListComb(int* pInt) { DWORD dwStyle = WS_VISIBLE|WS_CHILD|WS_VSCROLL|CBS_DROPDOWNLIST; m_pInt = pInt; m_bEdit = FALSE; return CreateComb(dwStyle); } BOOL CPropItemCombo::CreateDropListComb(CString* pCString) { DWORD dwStyle = WS_VISIBLE|WS_CHILD|WS_VSCROLL|CBS_DROPDOWNLIST; m_pText = pCString; m_bEdit = FALSE; return CreateComb(dwStyle); } BOOL CPropItemCombo::CreateDropDownComb(CString* pCString) { DWORD dwStyle = WS_VISIBLE|WS_CHILD|WS_VSCROLL|CBS_DROPDOWN; m_pText = pCString; m_bEdit = TRUE; return CreateComb(dwStyle); } BOOL CPropItemCombo::CreateDropDownComb(double* pDouble) { DWORD dwStyle = WS_VISIBLE|WS_CHILD|WS_VSCROLL|CBS_DROPDOWN; m_pDouble = pDouble; m_bEdit = TRUE; return CreateComb(dwStyle); } BOOL CPropItemCombo::CreateComb(DWORD dwStyle) { ASSERT(m_pProp!=NULL); if (IsWindow(m_hWnd)) DestroyWindow(); // force as not visible child window dwStyle = (WS_CHILD|WS_VSCROLL|dwStyle) & ~WS_VISIBLE; if (!Create(dwStyle, CRect(0,0,0,0), m_pProp->GetCtrlParent(), GetCtrlID())) { TRACE0("CPropItemCombo::CreateComboBox() - failed to create combo box\n"); return FALSE; } SendMessage(WM_SETFONT, (WPARAM)m_pProp->GetNormalFont()->m_hObject); return TRUE; } LONG CPropItemCombo::FindCBData(LPARAM lParam) { LONG idx; for (idx = 0; idx < GetCount(); idx++) { if (GetItemData(idx)==(DWORD)lParam) return idx; } return CB_ERR; } void CPropItemCombo::OnRefresh() { } void CPropItemCombo::OnCommit() { } void CPropItemCombo::OnSelchange() { CommitChanges(); ShowWindow(SW_HIDE); CString csText; GetLBText(GetCurSel(), csText); if (NULL != m_pText) *m_pText = csText; else if (NULL != m_pDouble) *m_pDouble = _tstof(csText); else if (NULL != m_pInt) *m_pInt = GetCurSel(); CWnd* pWnd = m_pProp->GetParent(); if (NULL != pWnd) { ::SendMessage(pWnd->m_hWnd, WM_SELECTCHANGED, (WPARAM)ITEMTYPE_COMBOBOX, (LPARAM)this); } } /*----------------------------------------------------------------------------* * 描述: 编辑修改事件,肯定是DropDown,没有int型,只取当前字符 * 备注: -----------------------------------------------------------------------------*/ void CPropItemCombo::OnEditchange() { CommitChanges(); CString csText; GetWindowText(csText); if (NULL != m_pText) *m_pText = csText; else if (NULL != m_pDouble) *m_pDouble = _tstof(csText); } void CPropItemCombo::OnKillfocus() { CommitChanges(); ShowWindow(SW_HIDE); } void CPropItemCombo::OnDropdown() { RecalcDropWidth(); } void CPropItemCombo::SetDropDownHeight(LONG nDropHeight) { m_nDropHeight = nDropHeight; } LONG CPropItemCombo::GetDropDownHeight() { return m_nDropHeight; } /*----------------------------------------------------------------------------* * 描述: 得到要Draw画出显示的字符 * 备注: -----------------------------------------------------------------------------*/ CString CPropItemCombo::GetValueText() { CString csText; if (NULL != m_pText) csText = *m_pText; else if (NULL != m_pDouble) { csText.Format(_T("%.10f"), *m_pDouble); csText.TrimRight(_T("0")); csText.TrimRight(_T(".")); } else if (NULL != m_pInt && *m_pInt > -1 && *m_pInt < GetCount()) { GetLBText(*m_pInt, csText); } return csText; } /*----------------------------------------------------------------------------* * 描述: 切换到给定的字符串 * 备注: 如果没有,则添加 -----------------------------------------------------------------------------*/ void CPropItemCombo::SetSelText(CString csText) { int nIndex = FindStringExact(0, csText); if (nIndex < 0 && !csText.IsEmpty()) nIndex = AddString(csText); SetCurSel(nIndex); if (NULL != m_pInt) *m_pInt = nIndex; else if (NULL != m_pText) *m_pText = csText; } // 自动计算宽度 void CPropItemCombo::RecalcDropWidth() { // Reset the dropped width int nNumEntries = GetCount(); int nWidth = 0; CString str; CClientDC dc(this); int nSave = dc.SaveDC(); dc.SelectObject(GetFont()); int nScrollWidth = ::GetSystemMetrics(SM_CXVSCROLL); int nLength(0); for (int i = 0; i < nNumEntries; i++) { GetLBText(i, str); nLength = dc.GetTextExtent(str).cx + nScrollWidth; nWidth = max(nWidth, nLength); } // Add margin space to the calculations nWidth += dc.GetTextExtent(_T("0")).cx; dc.RestoreDC(nSave); SetDroppedWidth(nWidth); }