www.pudn.com > vc开发的精美界面.zip > BCGEditListBox.cpp
//******************************************************************************* // COPYRIGHT NOTES // --------------- // This source code is a part of BCGControlBar library. // You may use, compile or redistribute it as part of your application // for free. You cannot redistribute it as a part of a software development // library without the agreement of the author. If the sources are // distributed along with the application, you should leave the original // copyright notes in the source code without any changes. // This code can be used WITHOUT ANY WARRANTIES on your own risk. // // For the latest updates to this library, check my site: // http://welcome.to/bcgsoft // // Stas Levin//******************************************************************************* // BCGEditListBox.cpp : implementation file // #include "stdafx.h" #include "bcgcontrolbar.h" #include "BCGEditListBox.h" #include "KeyHelper.h" #include "bcglocalres.h" #include "bcgbarres.h" #include "globals.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif static const int iListId = 1; static const int nTextMargin = 5; ///////////////////////////////////////////////////////////////////////////// // CBCGEditListBox CBCGEditListBox::CBCGEditListBox() { m_sizeButton = CSize (0, 0); m_uiStandardBtns = 0; m_bNewItem = FALSE; } //************************************************************************** CBCGEditListBox::~CBCGEditListBox() { while (!m_lstButtons.IsEmpty ()) { delete m_lstButtons.RemoveHead (); } } BEGIN_MESSAGE_MAP(CBCGEditListBox, CStatic) //{{AFX_MSG_MAP(CBCGEditListBox) ON_WM_CREATE() ON_WM_PAINT() ON_WM_SIZE() ON_WM_ERASEBKGND() ON_WM_SETFOCUS() //}}AFX_MSG_MAP ON_NOTIFY(LVN_KEYDOWN, iListId, OnKeyDown) ON_NOTIFY(NM_DBLCLK, iListId, OnDblclkList) ON_NOTIFY(LVN_GETDISPINFO, iListId, OnGetdispinfo) ON_NOTIFY(LVN_ENDLABELEDIT, iListId, OnEndLabelEdit) ON_NOTIFY(LVN_ITEMCHANGED, iListId, OnItemChanged) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CBCGEditListBox message handlers void CBCGEditListBox::PreSubclassWindow() { CStatic::PreSubclassWindow(); Init (); } //********************************************************************************** int CBCGEditListBox::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CStatic::OnCreate(lpCreateStruct) == -1) return -1; Init (); return 0; } //********************************************************************************** void CBCGEditListBox::Init () { CRect rectEmpty; rectEmpty.SetRectEmpty (); m_wndList.CreateEx (WS_EX_CLIENTEDGE, _T("SysListView32"), _T(""), WS_VISIBLE | WS_CHILD | LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_EDITLABELS, rectEmpty, this, iListId); m_wndList.SendMessage (LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT); m_wndList.InsertColumn (0, _T("")); AdjustLayout (); } //********************************************************************************** BOOL CBCGEditListBox::SetStandardButtons (UINT uiBtns) { if (GetSafeHwnd () == NULL) { ASSERT (FALSE); return FALSE; } if (!m_lstButtons.IsEmpty ()) { //---------------------- // Already have buttons //---------------------- ASSERT (FALSE); return FALSE; } CBCGLocalResource locaRes; CString strButton; if (uiBtns & BGCEDITLISTBOX_BTN_NEW) { strButton.LoadString (IDS_BCGBARRES_NEW); VERIFY (AddButton (IDB_BCGBARRES_NEW, strButton, VK_INSERT)); } if (uiBtns & BGCEDITLISTBOX_BTN_DELETE) { strButton.LoadString (IDS_BCGBARRES_DELETE); VERIFY (AddButton (IDB_BCGBARRES_DELETE, strButton, VK_DELETE)); } if (uiBtns & BGCEDITLISTBOX_BTN_UP) { strButton.LoadString (IDS_BCGBARRES_MOVEUP); VERIFY (AddButton (IDB_BCGBARRES_UP, strButton, VK_UP, FALT)); } if (uiBtns & BGCEDITLISTBOX_BTN_DOWN) { strButton.LoadString (IDS_BCGBARRES_MOVEDN); VERIFY (AddButton (IDB_BCGBARRES_DOWN, strButton, VK_DOWN, FALT)); } m_uiStandardBtns = uiBtns; return TRUE; } //********************************************************************************** BOOL CBCGEditListBox::AddButton (UINT uiImageResId, LPCTSTR lpszTooltip/* = NULL*/, WORD wKeyAccelerator/* = 0*/, BYTE fVirt/* = 0*/) { if (GetSafeHwnd () == NULL) { ASSERT (FALSE); return FALSE; } if (m_uiStandardBtns != 0) { ASSERT (FALSE); return FALSE; } CRect rectEmpty; rectEmpty.SetRectEmpty (); CBCGButton* pButton = new CBCGButton (); if (!pButton->Create (_T(""), WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_OWNERDRAW, rectEmpty, this, m_lstButtons.GetCount () + 2)) { return FALSE; } pButton->m_nFlatStyle = CBCGButton::BUTTONSTYLE_FLAT; pButton->SetImage (uiImageResId); if (lpszTooltip != NULL) { CString strTooltip = lpszTooltip; if (wKeyAccelerator != 0) { ACCEL acccel; acccel.cmd = 0; acccel.fVirt = (BYTE) (fVirt | FVIRTKEY); acccel.key = wKeyAccelerator; CKeyHelper helper (&acccel); CString strAccellKey; helper.Format (strAccellKey); strTooltip += _T(" ("); strTooltip += strAccellKey; strTooltip += _T(")"); } pButton->SetTooltip (strTooltip); } pButton->SizeToContent (); CRect rectBtn; pButton->GetWindowRect (rectBtn); CSize sizeButton = rectBtn.Size (); if (m_lstButtons.IsEmpty ()) { m_sizeButton = sizeButton; } else { ASSERT (m_sizeButton == sizeButton); } m_lstButtons.AddTail (pButton); if (wKeyAccelerator == 0) { fVirt = 0; } DWORD dwKey = (fVirt << 16) | wKeyAccelerator; m_lstKeyAccell.AddTail (dwKey); AdjustLayout (); return TRUE; } //********************************************************************************** void CBCGEditListBox::OnPaint() { CPaintDC dc(this); // device context for painting dc.FillRect (m_rectCaption, &globalData.brBtnFace); dc.Draw3dRect (m_rectCaption, globalData.clrBtnShadow, globalData.clrBtnHilite); CRect rectText = m_rectCaption; rectText.DeflateRect (nTextMargin, 0); dc.SetBkMode (TRANSPARENT); dc.SetTextColor (globalData.clrBtnText); CFont* pOldFont = dc.SelectObject (GetParent ()->GetFont ()); ASSERT (pOldFont != NULL); CString strCaption; GetWindowText (strCaption); dc.DrawText (strCaption, rectText, DT_LEFT | DT_SINGLELINE | DT_VCENTER); dc.SelectObject (pOldFont); } //********************************************************************************** void CBCGEditListBox::OnSize(UINT nType, int cx, int cy) { CStatic::OnSize(nType, cx, cy); AdjustLayout (); } //*********************************************************************************** void CBCGEditListBox::AdjustLayout () { if (GetSafeHwnd () == NULL) { return; } CRect rectClient; GetClientRect (rectClient); m_rectCaption = rectClient; CClientDC dc (this); CFont* pOldFont = dc.SelectObject (GetParent ()->GetFont ()); ASSERT (pOldFont != NULL); TEXTMETRIC tm; dc.GetTextMetrics (&tm); dc.SelectObject (pOldFont); m_rectCaption.bottom = m_rectCaption.top + max (tm.tmHeight * 4 / 3, m_sizeButton.cy); int x = rectClient.right - 1 - m_sizeButton.cx; for (POSITION pos = m_lstButtons.GetTailPosition (); pos != NULL;) { CBCGButton* pButton = m_lstButtons.GetPrev (pos); ASSERT (pButton != NULL); pButton->MoveWindow (x, rectClient.top + 1, m_sizeButton.cx, m_rectCaption.Height () - 2); x -= m_sizeButton.cx; } m_wndList.MoveWindow ( rectClient.left, rectClient.top + m_rectCaption.Height (), rectClient.Width (), rectClient.Height () - m_rectCaption.Height ()); m_wndList.SetColumnWidth (0, rectClient.Width () - 2 * ::GetSystemMetrics (SM_CXEDGE) - ::GetSystemMetrics (SM_CXVSCROLL)); } //************************************************************************************ BOOL CBCGEditListBox::OnEraseBkgnd(CDC* /*pDC*/) { return TRUE; } //************************************************************************************ BOOL CBCGEditListBox::OnCommand(WPARAM wParam, LPARAM lParam) { HWND hwnd = (HWND) lParam; int iButton = 0; for (POSITION pos = m_lstButtons.GetHeadPosition (); pos != NULL; iButton ++) { CBCGButton* pButton = m_lstButtons.GetNext (pos); ASSERT (pButton); if (pButton->GetSafeHwnd () == hwnd) { m_wndList.SetFocus (); OnClickButton (iButton); return TRUE; } } return CStatic::OnCommand(wParam, lParam); } //************************************************************************************* int CBCGEditListBox::AddItem (const CString& strText, DWORD dwData, int iIndex) { if (GetSafeHwnd () == NULL) { return -1; } if (iIndex < 0) { iIndex = m_wndList.GetItemCount (); } int iItem = m_wndList.InsertItem (iIndex, strText, I_IMAGECALLBACK); m_wndList.SetItemData (iItem, dwData); if (iItem == 0) { SelectItem (0); } return iItem; } //************************************************************************************* int CBCGEditListBox::GetCount () const { if (GetSafeHwnd () == NULL) { return -1; } return m_wndList.GetItemCount (); } //************************************************************************************* CString CBCGEditListBox::GetItemText (int iIndex) const { if (GetSafeHwnd () == NULL) { return _T(""); } return m_wndList.GetItemText (iIndex, 0); } //************************************************************************************* DWORD CBCGEditListBox::GetItemData (int iIndex) const { if (GetSafeHwnd () == NULL) { return 0; } return m_wndList.GetItemData (iIndex); } //************************************************************************************* void CBCGEditListBox::SetItemData (int iIndex, DWORD dwData) { if (GetSafeHwnd () == NULL) { return; } m_wndList.SetItemData (iIndex, dwData); } //************************************************************************************* void CBCGEditListBox::OnKeyDown (LPNMLVKEYDOWN pKeyDown, LRESULT* pResult) { *pResult = 0; if (pKeyDown != NULL) { BYTE fCurrVirt = 0; if (::GetAsyncKeyState (VK_CONTROL) & 0x8000) { fCurrVirt |= FCONTROL; } if (::GetAsyncKeyState (VK_MENU) & 0x8000) { fCurrVirt |= FALT; } if (::GetAsyncKeyState (VK_SHIFT) & 0x8000) { fCurrVirt |= FSHIFT; } int iButton = 0; for (POSITION pos = m_lstKeyAccell.GetHeadPosition (); pos != NULL; iButton ++) { DWORD dwKey = m_lstKeyAccell.GetNext (pos); if (dwKey != 0 && pKeyDown->wVKey == (dwKey & 0xFFFF)) { //------------------- // Check state flags: //------------------- BYTE fVirt = (BYTE) (dwKey >> 16); if (fCurrVirt == fVirt) { OnClickButton (iButton); return; } } } OnKey (pKeyDown->wVKey, fCurrVirt); } } //************************************************************************************* int CBCGEditListBox::GetSelItem () const { if (GetSafeHwnd () == NULL) { return -1; } return m_wndList.GetNextItem (-1, LVNI_SELECTED); } //************************************************************************************* BOOL CBCGEditListBox::SelectItem (int iItem) { if (GetSafeHwnd () == NULL) { return FALSE; } if (!m_wndList.SetItemState (iItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED)) { return FALSE; } return m_wndList.EnsureVisible (iItem, FALSE); } //************************************************************************************* void CBCGEditListBox::OnDblclkList(NMHDR* /*pNMHDR*/, LRESULT* pResult) { *pResult = 0; int iSelItem = GetSelItem (); if ((m_uiStandardBtns & BGCEDITLISTBOX_BTN_NEW) && iSelItem == -1) { CreateNewItem (); return; } if (iSelItem >= 0) { EditItem (iSelItem); } } //************************************************************************************* BOOL CBCGEditListBox::RemoveItem (int iIndex) { if (GetSafeHwnd () == NULL) { return FALSE; } BOOL bIsSelected = (GetSelItem () == iIndex); if (!m_wndList.DeleteItem (iIndex)) { return FALSE; } if (!bIsSelected || GetCount () == 0) { return FALSE; } //------------------- // Restore selection: //------------------- if (iIndex >= GetCount ()) { iIndex --; } SelectItem (iIndex); return TRUE; } //************************************************************************************* void CBCGEditListBox::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult) { ASSERT (pNMHDR != NULL); LV_ITEM* pItem = &((LV_DISPINFO*)pNMHDR)->item; ASSERT (pItem != NULL); if (pItem->mask & LVIF_IMAGE) { pItem->iImage = OnGetImage (pItem); } *pResult = 0; } //************************************************************************** void CBCGEditListBox::OnEndLabelEdit(NMHDR* pNMHDR, LRESULT* pResult) { ASSERT (pNMHDR != NULL); LV_ITEM* pItem = &((LV_DISPINFO*)pNMHDR)->item; ASSERT (pItem != NULL); OnEndEditLabel (pItem->pszText); *pResult = 0; } //************************************************************************** void CBCGEditListBox::OnItemChanged(NMHDR* pNMHDR, LRESULT* pResult) { ASSERT (pNMHDR != NULL); NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; ASSERT (pNMListView != NULL); if (pNMListView->uChanged == LVIF_STATE && (pNMListView->uOldState & LVIS_SELECTED) != (pNMListView->uNewState & LVIS_SELECTED)) { OnSelectionChanged (); } *pResult = 0; } //************************************************************************** BOOL CBCGEditListBox::EditItem (int iIndex) { if (GetSafeHwnd () == NULL) { return FALSE; } m_wndList.SetFocus (); CEdit* pEdit = m_wndList.EditLabel (iIndex); if (pEdit == NULL) { return FALSE; } ASSERT_VALID (pEdit); CRect rectClient; GetClientRect (rectClient); CRect rectEdit; pEdit->GetClientRect (rectEdit); pEdit->SetWindowPos (NULL, -1, -1, rectClient.Width () - 10, rectEdit.Height (), SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); return TRUE; } //*************************************************************************** void CBCGEditListBox::OnSetFocus(CWnd* /*pOldWnd*/) { m_wndList.SetFocus (); } //*************************************************************************** void CBCGEditListBox::OnClickButton (int iButton) { if (m_uiStandardBtns == 0) { return; } int iSelItem = GetSelItem (); if (iButton == GetStdButtonNum (BGCEDITLISTBOX_BTN_NEW)) { CreateNewItem (); } else if (iButton == GetStdButtonNum (BGCEDITLISTBOX_BTN_DELETE)) { if (iSelItem >= 0) { if (OnBeforeRemoveItem (iSelItem)) { RemoveItem (iSelItem); } } } else if (iButton == GetStdButtonNum (BGCEDITLISTBOX_BTN_UP) || iButton == GetStdButtonNum (BGCEDITLISTBOX_BTN_DOWN)) { if (iSelItem >= 0) { BOOL bIsUp = (iButton == GetStdButtonNum (BGCEDITLISTBOX_BTN_UP)); if (bIsUp) { if (iSelItem == 0) { return; } } else { if (iSelItem == GetCount () - 1) { return; } } // Adjust list control: SetRedraw (FALSE); CString strLabel = GetItemText (iSelItem); DWORD dwData = GetItemData (iSelItem); RemoveItem (iSelItem); if (bIsUp) { iSelItem --; } else { iSelItem ++; } AddItem (strLabel, dwData, iSelItem); SelectItem (iSelItem); SetRedraw (); m_wndList.Invalidate (); if (bIsUp) { OnAfterMoveItemUp (iSelItem); } else { OnAfterMoveItemDown (iSelItem); } } } } //**************************************************************************** int CBCGEditListBox::GetStdButtonNum (UINT uiStdBtn) const { if ((m_uiStandardBtns & uiStdBtn) == 0) { return -1; } int iBtn = 0; switch (uiStdBtn) { case BGCEDITLISTBOX_BTN_NEW: break; case BGCEDITLISTBOX_BTN_DELETE: if (m_uiStandardBtns & BGCEDITLISTBOX_BTN_NEW) { iBtn ++; } break; case BGCEDITLISTBOX_BTN_UP: if (m_uiStandardBtns & BGCEDITLISTBOX_BTN_NEW) { iBtn ++; } if (m_uiStandardBtns & BGCEDITLISTBOX_BTN_DELETE) { iBtn ++; } break; case BGCEDITLISTBOX_BTN_DOWN: if (m_uiStandardBtns & BGCEDITLISTBOX_BTN_NEW) { iBtn ++; } if (m_uiStandardBtns & BGCEDITLISTBOX_BTN_DELETE) { iBtn ++; } if (m_uiStandardBtns & BGCEDITLISTBOX_BTN_UP) { iBtn ++; } break; default: ASSERT (FALSE); iBtn = -1; } return iBtn; } //*********************************************************************************** void CBCGEditListBox::CreateNewItem () { int iLastItem = AddItem (_T("")); ASSERT (iLastItem >= 0); m_bNewItem = TRUE; EditItem (iLastItem); } //************************************************************************** void CBCGEditListBox::OnEndEditLabel (LPCTSTR lpszLabel) { int iSelItem = GetSelItem (); if (iSelItem < 0) { ASSERT (FALSE); return; } CString strLabel = (lpszLabel != NULL) ? lpszLabel : _T(""); if (!strLabel.IsEmpty ()) { m_wndList.SetItemText (iSelItem, 0, strLabel); if (m_bNewItem) { OnAfterAddItem (iSelItem); } else { OnAfterRenameItem (iSelItem); } } else { if (m_bNewItem) { RemoveItem (iSelItem); } } m_bNewItem = FALSE; } //************************************************************************** void CBCGEditListBox::OnKey (WORD wKey, BYTE fFlags) { int iSelItem = GetSelItem (); TCHAR cKey = (TCHAR) LOWORD (::MapVirtualKey (wKey, 2)); if (fFlags == 0 && // No Ctrl, Shift or Alt iSelItem >= 0 && (cKey == _T(' ') || wKey == VK_F2)) { int iSelItem = GetSelItem (); if (iSelItem >= 0) { EditItem (iSelItem); } } }