版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、用自定义的CCheckComboBox类做带复选框的下拉列表1、添加Combo Box控件2.、改属性Style:DropList ; Owner Draw:Fixed ; Has string:true ;Sort:false3、头文件中添加: CCheckComboBox m_comboBox;4、DoDataExchange(CDataExchange* pDX)中添加: DDX_Control(pDX, IDC_COMBO1, m_comb
2、oBox);5、对话框初始化时添加 m_comboBox.AddString(_T("1");/加入项目 m_comboBox.AddString(_T("2"); m_comboBox.AddString(_T("3"); m_comboBox.AddString(_T("4"); m_comboBox.SetCheck(0, TRUE
3、);/设置选择状态 m_comboBox.SetCheck(1, FALSE); m_comboBox.SetCheck(2, TRUE); m_comboBox.SetCheck(3, TRUE); #if !defined(AFX_CHECKCOMBOBOX_H_66750D93_95DB_11D3_9325_444553540000_INCLUDED_)#define AFX_CHECKCOMBOBOX_H_66750D93_95DB_
4、11D3_9325_444553540000_INCLUDED_#if _MSC_VER > 1000#pragma once#endif / _MSC_VER > 1000class CCheckComboBox : public CComboBoxpublic:CCheckComboBox();virtual CCheckComboBox();BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);/ Selects all/unselects the specified item
5、INT SetCheck(INT nIndex, BOOL bFlag);/ Returns checked stateBOOL GetCheck(INT nIndex);/ Selects all/unselects allvoid SelectAll(BOOL bCheck = TRUE);protected:/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(CCheckComboBox)protected:virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruc
6、t);virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);/AFX_VIRTUAL/AFX_MSG(CCheckComboBox)afx_msg LRESULT OnCtlColorListBox(WPARAM wParam, LPARAM lParam);afx_msg LRESULT OnGetText(WPARAM wParam, LPARAM lParam);afx_msg LRESULT OnGetTextLength(WPARAM wParam, LPARAM lParam);afx_msg void
7、OnDropDown();/AFX_MSGDECLARE_MESSAGE_MAP()public: CString m_strText;protected:/ Routine to update the textvoid RecalcText();/ The subclassed COMBOLBOX window (notice the 'L')HWND m_hListBox;/ The string containing the text to displayBOOL m_bTextUpdated;/ A flag used in MeasureIte
8、m, see comments thereBOOL m_bItemHeightSet;/AFX_INSERT_LOCATION/ Microsoft Visual C+ will insert additional declarations immediately before the previous line.#endif / !defined(AFX_CHECKCOMBOBOX_H_66750D93_95DB_11D3_9325_444553540000_INCLUDED_) /* CheckComboBox.cpp */ CheckComboBox.c
9、pp / Written by Magnus Egelberg (magnus.egelberglundalogik.se)/ Copyright (C) 1999, Lundalogik AB, Sweden. All rights reserved./ /#include "stdafx.h"/ #include "CheckCombo.h"#include "CheckComboBox.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FIL
10、E = _FILE_;#endifstatic WNDPROC m_pWndProc = 0;static CCheckComboBox *m_pComboBox = 0;BEGIN_MESSAGE_MAP(CCheckComboBox, CComboBox)/AFX_MSG_MAP(CCheckComboBox)ON_MESSAGE(WM_CTLCOLORLISTBOX, OnCtlColorListBox)ON_MESSAGE(WM_GETTEXT, OnGetText)ON_MESSAGE(WM_GETTEXTLENGTH, OnGetTextLength)ON_CONTROL_REFL
11、ECT(CBN_DROPDOWN, OnDropDown)/AFX_MSG_MAPEND_MESSAGE_MAP()/ The subclassed COMBOLBOX message handler/extern "C" LRESULT FAR PASCAL ComboBoxListBoxProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)switch (nMsg) case WM_RBUTTONDOWN: / If you want
12、to select all/unselect all using the / right button, remove this ifdef. Personally, I don't really like it #if FALSE if (m_pComboBox != 0) INT nCount = m_pComboBox->GetCount();
13、160; INT nSelCount = 0; for (INT i = 0; i < nCount; i+) if (m_pComboBox->GetCheck(i) nSelCount+; m_pComboBox->SelectAll(n
14、SelCount != nCount); / Make sure to invalidate this window as well InvalidateRect(hWnd, 0, FALSE); m_pComboBox->GetParent()->SendMessage(WM_COMMAND, MAKELONG(GetWindowLong(m_pComboBox->m_hWnd, GWL_ID),
15、 CBN_SELCHANGE), (LPARAM)m_pComboBox->m_hWnd); #endif break; / Make the combobox always return -1 as the current selection. This / causes the lpDrawItemStruct->itemID in DrawItem() to be -1 &
16、#160; / when the always-visible-portion of the combo is drawn case LB_GETCURSEL: return -1; case WM_CHAR: if (wParam = VK_SPACE) / Get the current selection INT nIndex = CallWi
17、ndowProcA(m_pWndProc, hWnd, LB_GETCURSEL, wParam, lParam); CRect rcItem; SendMessage(hWnd, LB_GETITEMRECT, nIndex, (LONG)(VOID *)&rcItem); InvalidateRect(hWnd, rcItem, FALSE); / Invert the check mark&
18、#160; m_pComboBox->SetCheck(nIndex, !m_pComboBox->GetCheck(nIndex); / Notify that selection has changed m_pComboBox->GetParent()->SendMessage(WM_COMMAND, MAKELONG(GetWindowLong(m_pComboBox->m_hWnd, GWL_ID), CBN_SELCHANG
19、E), (LPARAM)m_pComboBox->m_hWnd); return 0; break; case WM_LBUTTONDOWN: CRect rcClient; GetClientRect(hWnd, rcClient); CPoint pt; pt.x = L
20、OWORD(lParam); pt.y = HIWORD(lParam); if (PtInRect(rcClient, pt) INT nItemHeight = SendMessage(hWnd, LB_GETITEMHEIGHT, 0, 0); INT nTopIndex = SendMessage(hWnd, LB_GETTOPINDEX, 0, 0);
21、60; / Compute which index to check/uncheck INT nIndex = nTopIndex + pt.y / nItemHeight; CRect rcItem; SendMessage(hWnd, LB_GETITEMRECT, nIndex, (LONG)(VOID *)&rcItem); if (PtInRect(rcItem, pt) &
22、#160; / Invalidate this window InvalidateRect(hWnd, rcItem, FALSE); m_pComboBox->SetCheck(nIndex, !m_pComboBox->GetCheck(nIndex); / Notify that selection has changed
23、60; m_pComboBox->GetParent()->SendMessage(WM_COMMAND, MAKELONG(GetWindowLong(m_pComboBox->m_hWnd, GWL_ID), CBN_SELCHANGE), (LPARAM)m_pComboBox->m_hWnd); / Do the default handling now (such as close the popup &
24、#160; / window when clicked outside) break; case WM_LBUTTONUP: / Don't do anything here. This causes the combobox popup / windows to remain open after a selection has been made return 0;
25、 return CallWindowProc(m_pWndProc, hWnd, nMsg, wParam, lParam); CCheckComboBox:CCheckComboBox()m_hListBox = 0;m_bTextUpdated = FALSE;m_bItemHeightSet = FALSE;CCheckComboBox:CCheckComboBox()BOOL CCheckComboBox:Create(DWORD dwStyle, const RECT&
26、rect, CWnd* pParentWnd, UINT nID)/ Remove the CBS_SIMPLE and CBS_DROPDOWN styles and add the one I'm designed fordwStyle &= 0xF;dwStyle |= CBS_DROPDOWNLIST;/ Make sure to use the CBS_OWNERDRAWVARIABLE styledwStyle |= CBS_OWNERDRAWVARIABLE;/ Use default strings. We need the itemdata to store
27、checkmarksdwStyle |= CBS_HASSTRINGS;return CComboBox:Create(dwStyle, rect, pParentWnd, nID);LRESULT CCheckComboBox:OnCtlColorListBox(WPARAM wParam, LPARAM lParam) / If the listbox hasn't been subclassed yet, do so.if (m_hListBox = 0) HWND hWnd = (HWND)lParam; if (hWnd !=
28、 0 && hWnd != m_hWnd) / Save the listbox handle m_hListBox = hWnd; / Do the subclassing m_pWndProc = (WNDPROC)GetWindowLong(m_hListBox, GWL_WNDPROC); SetWindowLong(m_hListBox, GWL_WNDPROC, (LONG)ComboB
29、oxListBoxProc); return DefWindowProc(WM_CTLCOLORLISTBOX, wParam, lParam);void CCheckComboBox:DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) HDC dc = lpDrawItemStruct->hDC;CRect rcBitmap = lpDrawItemStruct->rcItem;CRect rcText = lpDrawItemStruct->rcItem;CString strText;/
30、 0 - No check, 1 - Empty check, 2 - CheckedINT nCheck = 0;/ Check if we are drawing the static portion of the comboboxif (LONG)lpDrawItemStruct->itemID < 0) / Make sure the m_strText member is updated RecalcText(); / Get the text strText = m_str
31、Text; / Don't draw any boxes on this item nCheck = 0;/ Otherwise it is one of the itemselse GetLBText(lpDrawItemStruct->itemID, strText); nCheck = 1 + (GetItemData(lpDrawItemStruct->itemID) != 0); TEXTMETRIC metrics;
32、GetTextMetrics(dc, &metrics); rcBitmap.left = 0; rcBitmap.right = rcBitmap.left + metrics.tmHeight + metrics.tmExternalLeading + 6; rcBitmap.top += 1; rcBitmap.bottom -= 1; rcText.left = r
33、cBitmap.right; if (nCheck > 0) SetBkColor(dc, GetSysColor(COLOR_WINDOW); SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT); UINT nState = DFCS_BUTTONCHECK; if (nCheck > 1) nState |= DFCS_CHECKED; / Draw the checkm
34、ark using DrawFrameControl DrawFrameControl(dc, rcBitmap, DFC_BUTTON, nState);if (lpDrawItemStruct->itemState & ODS_SELECTED) SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT); SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT);else SetBkColor(dc, Ge
35、tSysColor(COLOR_WINDOW); SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT);/ Erase and drawExtTextOut(dc, 0, 0, ETO_OPAQUE, &rcText, 0, 0, 0);DrawText(dc, ' ' + strText, strText.GetLength() + 1, &rcText, DT_SINGLELINE|DT_VCENTER|DT_END_ELLIPSIS);if (lpDrawItemStruct->item
36、State & (ODS_FOCUS|ODS_SELECTED) = (ODS_FOCUS|ODS_SELECTED) DrawFocusRect(dc, &rcText);void CCheckComboBox:MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) CClientDC dc(this);CFont *pFont = dc.SelectObject(GetFont();if (pFont != 0) TEXTMETRIC metrics;
37、 dc.GetTextMetrics(&metrics); lpMeasureItemStruct->itemHeight = metrics.tmHeight + metrics.tmExternalLeading; / An extra height of 2 looks good I think. / Otherwise the list looks a bit crowded. lpMeasureItemStruct->itemHeight += 2;
38、60; / This is needed since the WM_MEASUREITEM message is sent before / MFC hooks everything up if used in i dialog. So adjust the / static portion of the combo box now if (!m_bItemHeightSet) m_bItemHeightSet = TRUE; SetItemHeig
39、ht(-1, lpMeasureItemStruct->itemHeight); dc.SelectObject(pFont);/ Make sure the combobox window handle is updated since/ there may be many CCheckComboBox windows active/void CCheckComboBox:OnDropDown() m_pComboBox = this;/ Selects/unselects all items in the list/void CChe
40、ckComboBox:SelectAll(BOOL bCheck)INT nCount = GetCount();for (INT i = 0; i < nCount; i+) SetCheck(i, bCheck);/ By adding this message handler, we may use CWnd:GetText()/LRESULT CCheckComboBox:OnGetText(WPARAM wParam, LPARAM lParam)/ Make sure the text is updatedRecalcText();if (lParam
41、 = 0) return 0;/ Copy the 'fake' window textlstrcpyn(LPWSTR)lParam, m_strText, (INT)wParam);return m_strText.GetLength();/ By adding this message handler, we may use CWnd:GetTextLength()/LRESULT CCheckComboBox:OnGetTextLength(WPARAM, LPARAM)/ Make sure the text is updatedRecalcText();return m_strText.GetLength();/ This routine steps thru all the items and builds/ a string containing the checked items/void CCheckComboBox:RecalcText()i
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论