void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) { wxCHECK_RET( IsValidInsert(pos), wxT("invalid index in wxListBox::InsertItems") ); unsigned int nItems = items.GetCount(); for ( unsigned int i = 0; i < nItems; i++ ) { int idx = ListBox_InsertString(GetHwnd(), i + pos, items[i]); #if wxUSE_OWNER_DRAWN if ( m_windowStyle & wxLB_OWNERDRAW ) { wxOwnerDrawn *pNewItem = CreateLboxItem(idx); pNewItem->SetName(items[i]); pNewItem->SetFont(GetFont()); m_aItems.Insert(pNewItem, idx); ListBox_SetItemData(GetHwnd(), idx, pNewItem); } #else wxUnusedVar(idx); #endif // wxUSE_OWNER_DRAWN } m_noItems += nItems; SetHorizontalExtent(); }
LRESULT CHScrollListBox::OnResetContent(WPARAM wParam, LPARAM lParam) { LRESULT lResult = Default(); SetHorizontalExtent(0); return lResult; }
void wxListBox::Clear() { Free(); ListBox_ResetContent(GetHwnd()); m_noItems = 0; SetHorizontalExtent(); }
void wxListBox::OnInternalIdle() { wxWindow::OnInternalIdle(); if (m_updateHorizontalExtent) { SetHorizontalExtent(wxEmptyString); m_updateHorizontalExtent = false; } }
void CHScrollListBox::ResetHExtent() { if (GetCount() == 0) { SetHorizontalExtent(0); return; } CWaitCursor WaitCursor; int iMaxHExtent = 0; for (int i = 0; i < GetCount(); i++) { CString csText; GetText(i, csText); if ( int iExt = GetTextLen(csText) > iMaxHExtent ) iMaxHExtent = iExt; } SetHorizontalExtent(iMaxHExtent); }
void CHorzListBox::InsertNewExtent(int nItem, LPCTSTR lpszStr) { if (m_bLocked) return; CDC* pDC = GetDC(); HFONT hFont = (HFONT)SendMessage(WM_GETFONT); CFont *pFont = CFont::FromHandle(hFont); ASSERT(pFont); CFont* pPrevFont = pDC->SelectObject(pFont); InsertNewExtent(nItem, lpszStr, pDC); SetHorizontalExtent(m_nLongestExtent); pDC->SelectObject(pPrevFont); ReleaseDC(pDC); }
void CResizableComboBox::UpdateHorizontalExtent(LPCTSTR szText) { CClientDC dc(this); CFont* pOldFont = dc.SelectObject(GetFont()); int cx = dc.GetTextExtent(szText, lstrlen(szText)).cx; if (cx > m_iExtent) { m_iExtent = cx; SetHorizontalExtent(m_iExtent + LOWORD(GetDialogBaseUnits())); } dc.SelectObject(pOldFont); }
//============================================================================= void CXListBox::ResetContent() //============================================================================= { if (!::IsWindow(m_hWnd)) { ASSERT(FALSE); } else { CListBox::ResetContent(); m_cxExtent = 0; SetHorizontalExtent(m_cxExtent); } }
void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData) { // avoid flicker - but don't need to do this for a hidden listbox bool hideAndShow = IsShown(); if ( hideAndShow ) { ShowWindow(GetHwnd(), SW_HIDE); } ListBox_ResetContent(GetHwnd()); m_noItems = choices.GetCount(); int i; for (i = 0; i < m_noItems; i++) { ListBox_AddString(GetHwnd(), choices[i]); if ( clientData ) { SetClientData(i, clientData[i]); } } #if wxUSE_OWNER_DRAWN if ( m_windowStyle & wxLB_OWNERDRAW ) { // first delete old items WX_CLEAR_ARRAY(m_aItems); // then create new ones for ( size_t ui = 0; ui < (size_t)m_noItems; ui++ ) { wxOwnerDrawn *pNewItem = CreateLboxItem(ui); pNewItem->SetName(choices[ui]); m_aItems.Add(pNewItem); ListBox_SetItemData(GetHwnd(), ui, pNewItem); } } #endif // wxUSE_OWNER_DRAWN SetHorizontalExtent(); if ( hideAndShow ) { // show the listbox back if we hid it ShowWindow(GetHwnd(), SW_SHOW); } InvalidateBestSize(); }
void wxListBox::SetString(unsigned int n, const wxString& s) { wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::SetString") ); // remember the state of the item bool wasSelected = IsSelected(n); void *oldData = NULL; wxClientData *oldObjData = NULL; if ( m_clientDataItemsType == wxClientData_Void ) oldData = GetClientData(n); else if ( m_clientDataItemsType == wxClientData_Object ) oldObjData = GetClientObject(n); // delete and recreate it SendMessage(GetHwnd(), LB_DELETESTRING, n, 0); int newN = n; if ( n == (m_noItems - 1) ) newN = -1; ListBox_InsertString(GetHwnd(), newN, s); // restore the client data if ( oldData ) SetClientData(n, oldData); else if ( oldObjData ) SetClientObject(n, oldObjData); #if wxUSE_OWNER_DRAWN if ( m_windowStyle & wxLB_OWNERDRAW ) { // update item's text m_aItems[n]->SetName(s); // reassign the item's data ListBox_SetItemData(GetHwnd(), n, m_aItems[n]); } #endif //USE_OWNER_DRAWN // we may have lost the selection if ( wasSelected ) Select(n); SetHorizontalExtent(); }
int wxListBox::DoAppend(const wxString& item) { int index = ListBox_AddString(GetHwnd(), item); m_noItems++; #if wxUSE_OWNER_DRAWN if ( m_windowStyle & wxLB_OWNERDRAW ) { wxOwnerDrawn *pNewItem = CreateLboxItem(index); // dummy argument pNewItem->SetName(item); m_aItems.Insert(pNewItem, index); ListBox_SetItemData(GetHwnd(), index, pNewItem); pNewItem->SetFont(GetFont()); } #endif // wxUSE_OWNER_DRAWN SetHorizontalExtent(item); return index; }
void wxListBox::Delete(unsigned int n) { wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::Delete") ); // for owner drawn objects, the data is used for storing wxOwnerDrawn // pointers and we shouldn't touch it #if !wxUSE_OWNER_DRAWN if ( !(m_windowStyle & wxLB_OWNERDRAW) ) #endif // !wxUSE_OWNER_DRAWN if ( HasClientObjectData() ) { delete GetClientObject(n); } SendMessage(GetHwnd(), LB_DELETESTRING, n, 0); m_noItems--; SetHorizontalExtent(wxEmptyString); }
void CResizableComboBox::InitHorizontalExtent() { CClientDC dc(this); CFont* pOldFont = dc.SelectObject(GetFont()); CString str; m_iExtent = 0; int n = GetCount(); for (int i=0; i<n; i++) { GetLBText(i, str); int cx = dc.GetTextExtent(str).cx; if (cx > m_iExtent) m_iExtent = cx; } SetHorizontalExtent(m_iExtent + LOWORD(GetDialogBaseUnits())); dc.SelectObject(pOldFont); }
//*********************************************************************** // Function: // // CHorzListBox::UpdateHExtent() // // Purpose: // // Updates horizontal extent when auto updating has been turned off // for some period. // // History: // // Date Comment Initials // ======== ================================================= ======== // 1/31/96 Created JMR //*********************************************************************** void CHorzListBox::UpdateHExtent() { m_arrExtents.RemoveAll(); m_nLongestExtent = 0; int nCount = GetCount(); CDC* pDC = GetDC(); HFONT hFont = (HFONT)SendMessage(WM_GETFONT); CFont *pFont = CFont::FromHandle(hFont); ASSERT(pFont); CFont* pPrevFont = pDC->SelectObject(pFont); CString str; for(int i=0; i<nCount; i++) { GetText(i, str); InsertNewExtent(i, str, pDC); } SetHorizontalExtent(m_nLongestExtent); pDC->SelectObject(pPrevFont); ReleaseDC(pDC); }
//*********************************************************************** // Function: // // CHorzListBox::OnDeleteString() // // Purpose: // // Intercepts the LB_DELETESTRING message to update the horizontal extent // // History: // // Date Comment Initials // ======== ================================================= ======== // 1/31/96 Created JMR //*********************************************************************** LRESULT CHorzListBox::OnDeleteString(WPARAM wParam, LPARAM) { LRESULT lResult = Default(); if (LB_ERR == lResult) // check for error first! return lResult; if (m_bLocked) // don't do anything if locked return lResult; int nExtent = m_arrExtents[wParam]; m_arrExtents.RemoveAt(wParam); if (nExtent >= m_nLongestExtent) { m_nLongestExtent = 0; for(int i = 0; i<lResult; i++) { if (m_arrExtents[i] > m_nLongestExtent) m_nLongestExtent = m_arrExtents[i]; } } SetHorizontalExtent(m_nLongestExtent); return lResult; }
CInPlaceList::CInPlaceList(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID, int nRow, int nColumn, CStringArray& Items, CString sInitText, UINT nFirstChar) { m_nNumLines = 4; m_sInitText = sInitText; m_nRow = nRow; m_nCol = nColumn; m_nLastChar = 0; m_bExitOnArrows = FALSE; //(nFirstChar != VK_LBUTTON); // If mouse click brought us here, // Create the combobox DWORD dwComboStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|WS_VSCROLL| CBS_AUTOHSCROLL | dwStyle; int nHeight = rect.Height(); rect.bottom = rect.bottom + m_nNumLines*nHeight + ::GetSystemMetrics(SM_CYHSCROLL); if (!Create(dwComboStyle, rect, pParent, nID)) return; // Add the strings for (int i = 0; i < Items.GetSize(); i++) AddString(Items[i]); // Get the maximum width of the text strings int nMaxLength = 0; CClientDC dc(GetParent()); CFont* pOldFont = dc.SelectObject(pParent->GetFont()); for (i = 0; i < Items.GetSize(); i++) nMaxLength = max(nMaxLength, dc.GetTextExtent(Items[i]).cx); nMaxLength += (::GetSystemMetrics(SM_CXVSCROLL) + dc.GetTextExtent(_T(" ")).cx*2); dc.SelectObject(pOldFont); if (nMaxLength > rect.Width()) rect.right = rect.left + nMaxLength; // Resize the edit window and the drop down window MoveWindow(rect); SetFont(pParent->GetFont()); SetItemHeight(-1, nHeight); SetDroppedWidth(nMaxLength); SetHorizontalExtent(0); // no horz scrolling // Set the initial text to m_sInitText if (SelectString(-1, m_sInitText) == CB_ERR) SetWindowText(m_sInitText); // No text selected, so restore what was there before // Subclass the combobox edit control if style includes CBS_DROPDOWN if ((dwStyle & CBS_DROPDOWNLIST) != CBS_DROPDOWNLIST) { m_edit.SubclassDlgItem(IDC_COMBOEDIT, this); SetFocus(); switch (nFirstChar) { case VK_LBUTTON: case VK_RETURN: m_edit.SetSel((int)_tcslen(m_sInitText), -1); return; case VK_BACK: m_edit.SetSel((int)_tcslen(m_sInitText), -1); break; case VK_DOWN: case VK_UP: case VK_RIGHT: case VK_LEFT: case VK_NEXT: case VK_PRIOR: case VK_HOME: case VK_END: m_edit.SetSel(0,-1); return; default: m_edit.SetSel(0,-1); } SendMessage(WM_CHAR, nFirstChar); } else SetFocus(); }
void CHScrollListBox::SetNewHExtent(LPCTSTR lpszNewString) { int iExt = GetTextLen(lpszNewString); if ( iExt > GetHorizontalExtent()) SetHorizontalExtent(iExt); }
CInPlaceList::CInPlaceList(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID, int nRow, int nColumn, COLORREF crFore, COLORREF crBack, IEnumerator<tstring> *items, CString sInitText, UINT nFirstChar) { m_crForeClr = crFore; m_crBackClr = crBack; m_nNumLines = 20; m_sInitText = sInitText; m_nRow = nRow; m_nCol = nColumn; m_nLastChar = 0; m_bExitOnArrows = FALSE; //(nFirstChar != VK_LBUTTON); // If mouse click brought us here, // Create the combobox DWORD dwComboStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|WS_VSCROLL| CBS_SORT | CBS_AUTOHSCROLL | dwStyle; int nHeight = rect.Height(); rect.bottom = rect.bottom + m_nNumLines*nHeight + ::GetSystemMetrics(SM_CYHSCROLL); if (!Create(dwComboStyle, rect, pParent, nID)) return; // Add the strings tstring item; items->Reset(); while(items->MoveNext(item)) { AddString(item.c_str()); } SetFont(pParent->GetFont()); SetItemHeight(-1, nHeight); int nMaxLength = GetCorrectDropWidth(); /* if (nMaxLength > rect.Width()) rect.right = rect.left + nMaxLength; // Resize the edit window and the drop down window MoveWindow(rect); */ SetDroppedWidth(nMaxLength); SetHorizontalExtent(0); // no horz scrolling // Set the initial text to m_sInitText if (::IsWindow(m_hWnd) && SelectString(-1, m_sInitText) == CB_ERR) SetWindowText(m_sInitText); // No text selected, so restore what was there before ShowDropDown(); // Subclass the combobox edit control if style includes CBS_DROPDOWN if ((dwStyle & CBS_DROPDOWNLIST) != CBS_DROPDOWNLIST) { m_edit.SubclassDlgItem(IDC_COMBOEDIT, this); SetFocus(); switch (nFirstChar) { case VK_LBUTTON: case VK_RETURN: m_edit.SetSel((int)_tcslen(m_sInitText), -1); return; case VK_BACK: m_edit.SetSel((int)_tcslen(m_sInitText), -1); break; case VK_DOWN: case VK_UP: case VK_RIGHT: case VK_LEFT: case VK_NEXT: case VK_PRIOR: case VK_HOME: case VK_END: m_edit.SetSel(0,-1); return; default: m_edit.SetSel(0,-1); } SendMessage(WM_CHAR, nFirstChar); } else SetFocus(); }
CInPlaceList::CInPlaceList(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID, int nRow, int nColumn, Strings& Items, CString sInitText, UINT nFirstChar) { m_nNumLines = 2; m_sInitText = sInitText; m_nRow = nRow; m_nCol = nColumn; m_nLastChar = 0; m_bEdit = FALSE; // Create the combobox DWORD dwComboStyle = WS_BORDER|WS_CHILD|WS_VISIBLE|WS_VSCROLL| CBS_AUTOHSCROLL | dwStyle; if (!Create(dwComboStyle, rect, pParent, nID)) return; COMBOBOXINFO cbInfo; cbInfo.cbSize = sizeof(COMBOBOXINFO); GetComboBoxInfo(&cbInfo); m_edit.SubclassWindow(cbInfo.hwndItem); m_ListBox.SubclassWindow(cbInfo.hwndList); // Add the strings for (size_t i = 0; i < Items.size(); i++) AddString(Items[i]); // Get the maximum width of the text strings int nMaxLength = 0; CClientDC dc(GetParent()); CFont* pOldFont = dc.SelectObject(pParent->GetFont()); for (size_t i = 0; i < Items.size(); i++) nMaxLength = max(nMaxLength, dc.GetTextExtent(Items[i]).cx); nMaxLength += (::GetSystemMetrics(SM_CXVSCROLL) + dc.GetTextExtent(_T(" ")).cx*2); dc.SelectObject(pOldFont); // Resize the edit window and the drop down window SetFont(pParent->GetFont()); SetDroppedWidth(nMaxLength); SetHorizontalExtent(0); // no horz scrolling // Set the initial text to m_sInitText SetWindowText(m_sInitText); // No text selected, so restore what was there before ShowDropDown(); SetFocus(); // Added by KiteFly. When entering DBCS chars into cells the first char was being lost // SenMessage changed to PostMessage (John Lagerquist) switch (nFirstChar) { case VK_RETURN: break; default: PostMessage(WM_CHAR, nFirstChar); } }
void CMineListBox::ResetContent() { m_nMaxWidth = 0; SetHorizontalExtent(0); CListBox::ResetContent(); }
int CMyListBox::AddString(LPCTSTR lpszItem) { //此处加入字符串宽度跟踪、水平滚动条显示等代码 int nRet = CListBox::AddString(lpszItem); /* ---- 接下来调用GetScrollInfo()以获得垂直滚动条的相关信息。这些信息是 通过一个SCROLLINFO结构传递的,下面是对该结构初始化并调用 GetScrollInfo()的代码: */ SCROLLINFO scrollInfo; memset(&scrollInfo, 0, sizeof(SCROLLINFO)); scrollInfo.cbSize = sizeof(SCROLLINFO); scrollInfo.fMask = SIF_ALL; GetScrollInfo(SB_VERT, &scrollInfo, SIF_ALL); /*---- 在调试器内观察SCROLLINFO,可以发现要获得nMax和nPage的正确数值, 列表框至少应含有一个字符串。SCROLLINFO的成员nPage保存了列表框“每页” 能够显示的项目数,nMax是列表框内项目总数。当nMax大于或等于nPage,就 出现了垂直滚动条。我们需要知道垂直滚动条的宽度以正确计算列表框的有效 显示宽度。这里使用一个初始值为0的整数nScrollWidth表示,并在垂直滚动条 显示时将它赋值: */ int nScrollWidth = 0; if(GetCount() >1 && ((int)scrollInfo.nMax >= (int)scrollInfo.nPage)) { nScrollWidth = GetSystemMetrics(SM_CXVSCROLL); } /*---- 接下来声明一个SIZE变量sSize,并实例化对话框的CClientDC: */ SIZE sSize; CClientDC myDC(this); /*---- 对话框所采用的字体,有可能是缺省字体,也有可能是有目的的选择。 在对话框编辑器中右击对话框,并选择Properties可以查看当前值。虽然 MyDC是从列表框取得的,但列表框字体信息并未包含在MyDC中。也就是说, 对话框创建时所用字体并没有“选入”CClientDC。要从 GetTextExtentPoint32()获得真正的字符串大小,应该先调用GetFont()获 得列表框的字体信息,然后将此字体选入MyDC,代码为: */ CFont* pListBoxFont = GetFont(); if(pListBoxFont != NULL) { CFont* pOldFont = myDC.SelectObject(pListBoxFont); /*---- 现在可以调用GetTextExtendPoint32()函数来获得字符串的宽度了。 字符串的宽度由sSize结构的cx成员返回,将该值和已有最大宽度相比较:*/ GetTextExtentPoint32(myDC.m_hDC, lpszItem, strlen(lpszItem), &sSize); m_nMaxWidth = max(m_nMaxWidth, (int)sSize.cx); /*---- 剩下的重要工作之一,就是设置水平滚动条的大小了。这可以通过调 用SetHorizontalExtent()完成。如果传递给它的整形参数比列表框本身宽度小, 则水平滚动条被隐藏。 ---- 这里有一个容易被忽略的地方。如果仔细观察CListBox,可以发现文 本左边有一栏小小的空白,它的大小为3 。这部分宽度应该加到文本宽度 上。如果希望在文本右边也同样空出一栏,则可以在文本宽度上再加3。 */ SetHorizontalExtent(m_nMaxWidth + 3); /*---- 在结束之前,我们需要为MyDC选入原有字体。原有字体保存在pOldFont 中: */ myDC.SelectObject(pOldFont); } return nRet; }
//============================================================================= void CXListBox::DrawItem(LPDRAWITEMSTRUCT lpDIS) //============================================================================= { COLORREF oldtextcolor, oldbackgroundcolor; CDC* pDC = CDC::FromHandle(lpDIS->hDC); pDC->GetCharWidth((UINT) ' ', (UINT) ' ', &m_nSpaceWidth); pDC->GetCharWidth((UINT) 'c', (UINT) 'c', &m_nAveCharWidth); for (int i = 0; i < MAXTABSTOPS; i++) m_nTabStopPositions[i] = (i+1) * m_nAveCharWidth * m_nTabPosition; // draw focus rectangle when no items in listbox if (lpDIS->itemID == (UINT)-1) { if (lpDIS->itemAction & ODA_FOCUS) pDC->DrawFocusRect(&lpDIS->rcItem); return; } else { int selChange = lpDIS->itemAction & ODA_SELECT; int focusChange = lpDIS->itemAction & ODA_FOCUS; int drawEntire = lpDIS->itemAction & ODA_DRAWENTIRE; if (selChange || drawEntire) { BOOL sel = lpDIS->itemState & ODS_SELECTED; int nLen = CListBox::GetTextLen(lpDIS->itemID); if (nLen != LB_ERR) { TCHAR *buf = new TCHAR [nLen + 16]; ASSERT(buf); if (buf && (GetTextWithColor(lpDIS->itemID, buf) != LB_ERR)) { CRect rectItem(lpDIS->rcItem); CSize size; if (m_bLineNumbers) { // draw gutter & line no. UINT index = GetTopIndex(); UINT n = rectItem.top / rectItem.Height(); index += n; //TRACE("index=%d\n", index); CString strLineNo = _T(""); for (int i = 0; i < m_nGutterWidth; i++) strLineNo += _T('9'); if (strLineNo.IsEmpty()) strLineNo = _T('9'); size = pDC->GetTextExtent(strLineNo); strLineNo = _T(""); strLineNo.Format(_T("%d"), index+1); rectItem.right = rectItem.left + size.cx + 6; pDC->SetBkColor(m_ColorGutter); pDC->SetTextColor(m_ColorLineNo); // fill the gutter with the gutter color the fast way pDC->ExtTextOut(0, 0, ETO_OPAQUE, &rectItem, NULL, 0, NULL); rectItem.left += 2; rectItem.right -= 2; pDC->DrawText(strLineNo, &rectItem, DT_RIGHT); // restore drawing rect rectItem.left = rectItem.right + 2; rectItem.right = lpDIS->rcItem.right; } // set text color from first character in string - // NOTE: 1 was added to color index to avoid asserts by CString int itext = int (buf[0] - 1); // set background color from second character in string - // NOTE: 1 was added to color index to avoid asserts by CString int iback = int (buf[1] - 1); buf[0] = _T(' '); buf[1] = _T(' '); COLORREF textcolor = sel ? m_ColorHighlightText : ColorTable[itext]; oldtextcolor = pDC->SetTextColor(textcolor); COLORREF backgroundcolor = sel ? m_ColorHighlight : ColorTable[iback]; oldbackgroundcolor = pDC->SetBkColor(backgroundcolor); // fill the rectangle with the background color the fast way pDC->ExtTextOut(0, 0, ETO_OPAQUE, &rectItem, NULL, 0, NULL); pDC->TabbedTextOut(rectItem.left+2, rectItem.top, &buf[2], (int)_tcslen(&buf[2]), MAXTABSTOPS, (LPINT)m_nTabStopPositions, 0); size = pDC->GetOutputTextExtent(&buf[2]); int nScrollBarWidth = ::GetSystemMetrics(SM_CXVSCROLL); size.cx += nScrollBarWidth; // in case of vertical scrollbar int cxExtent = (size.cx > m_cxExtent) ? size.cx : m_cxExtent; if (cxExtent > m_cxExtent) { m_cxExtent = cxExtent; SetHorizontalExtent(m_cxExtent+(m_cxExtent/32)); } } if (buf) delete [] buf; } } if (focusChange || (drawEntire && (lpDIS->itemState & ODS_FOCUS))) pDC->DrawFocusRect(&lpDIS->rcItem); } }