How To Improve Insert/Delete Speed in Controls
When we need to add/delete a lot of data in a control such a CTreeCtrl or a CListBox the process could be very slow because the control is redrawn each time an item is added or deleted. To avoid this, we should deactivate the redrawing function while performing the lengthy task.MyTreeCtrl.SetRedraw(FALSE); // Lengthy Operation MyTreeCtrl.DeleteAllItems(); MyTreeCtrl.SetRedraw(TRUE); MyTreeCtrl.Invalidate(FALSE); 2。How to Add Horizontal Scrolling to a List Box
A normal Windows list box does not implement a default horizontal scrolling. In order to do that, the horizontal extent must be modified:
// Add string to the ListBox m_listBox.AddString(m_sAddString); // Adjust Horizontal Scrolling Extent (if necessary) CClientDC dc(m_listBox); CSize size = dc.GetTextExtent(m_sAddString, m_sAddString.GetLength()); if (size.cx > m_listBox.GetHorizontalExtent()) m_listBox.SetHorizontalExtent(size.cx);3。How To Set a Different Font Style for each item in a ListBox
I wanted to have a ListBox with the ability to change the font style of each item from normal to bold (like in the Message Maps property page of the ClassWizard).
![]()
In order to do that, I extended the CListBox class by adding two public methods that let users set/get the font style of each item.
typedef enum {NORMAL = 0, BOLD, ITALIC} FONTSTYLE; class CFontStyleListBox : public CListBox { // Construction public: CFontStyleListBox(); // (...) public: FONTSTYLE GetFontStyle(int nIndex); void SetFontStyle(int nIndex, FONTSTYLE fontStyle); }For the implementation, I overrided the DrawItem method. It is clear that the information about the font style must be kept individually for each item. The easiest way I found (not necessarily the best) was to keep this information in the data associated to each item. That means that the user should not invoke the SetItemData/GetItemData methods.void CFontStyleListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // TODO: Add your code to draw the specified item CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); CRect rect; // Draw the colored rectangle portion rect.CopyRect(&lpDrawItemStruct->rcItem); pDC->SetBkMode(TRANSPARENT); if (lpDrawItemStruct->itemState & ODS_SELECTED) { pDC->FillSolidRect (rect, GetSysColor(COLOR_HIGHLIGHT)); pDC->SetTextColor (GetSysColor(COLOR_HIGHLIGHTTEXT)); } else { pDC->FillSolidRect (rect, GetSysColor (COLOR_WINDOW)); pDC->SetTextColor (GetSysColor(COLOR_WINDOWTEXT)); } if ((int)(lpDrawItemStruct->itemID) >= 0) // Valid ID { CString sText; int nIndex; CFont newFont; CFont *pOldFont; nIndex = lpDrawItemStruct->itemID; GetText(nIndex, sText); FONTSTYLE fontStyle = (FONTSTYLE)GetItemData(nIndex); // To avoid unnecessary processing if (fontStyle == NORMAL) { pDC->DrawText(sText, rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE); return; } LOGFONT logFont; CFont *pFont = GetFont(); pFont->GetLogFont(&logFont); switch (fontStyle) { //case NORMAL: logFont.lfWeight = FW_NORMAL; // break; case BOLD: logFont.lfWeight = FW_BOLD; break; case ITALIC: logFont.lfItalic = TRUE; break; } newFont.CreatePointFontIndirect (&logFont); pOldFont = pDC->SelectObject (&newFont); pDC->DrawText(sText, rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE); pDC->SelectObject (pOldFont); newFont.DeleteObject (); } } FONTSTYLE CFontStyleListBox::GetFontStyle(int nIndex) { return (FONTSTYLE) GetItemData(nIndex); } void CFontStyleListBox::SetFontStyle(int nIndex, FONTSTYLE fontStyle) { SetItemData (nIndex, (DWORD) fontStyle); Invalidate(); }If you use this class with a dialog resource, you must select in the Style Properties Owner Draw: Fixed and Has Strings options.
![]()
4
How To Center CFormView on the screen
void CMyFormView::OnInitialUpdate() { // TODO: calculate the total size of this view // (...) GetParentFrame()->RecalcLayout(); ResizeParentToFit(FALSE); // Center the application's main window after size has been calculated AfxGetMainWnd()->CenterWindow(); }5How To Use a Dialog Resource as a View (CFormView)
1) Create a dialog resourceStyles:
Style: Child
Border: None
Title Bar: None2) With the ClassWizard, derive a new class from CFormView. If you are going to replace the default CView class for this one, it could be a good idea to choose the same class and file name.
3) If you chose a different class and/or file name for the CFormView class, you have to made some modifications on the CWinApp derived class. First, you must add the new include file at the top of the .cpp file. Second, in the InitInstance method you must modify the application template.
//#include "MyProjectView.h" #include "MyProjectNewView.h" BOOL CMyProjectApp::InitInstance() { // ... // Register the application's document templates. Document templates // serve as the connection between documents, frame windows and views. CSingleDocTemplate* pDocTemplate; pDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CMyProjectDoc), RUNTIME_CLASS(CMainFrame), // main SDI frame window //RUNTIME_CLASS(CMyProjectView)); RUNTIME_CLASS(CMyProjectNewView)); // *** New view AddDocTemplate(pDocTemplate); // ... return TRUE; }4) To have access to the document class, we define a GetDocument method in the CFormView class. In the .h file:// Operations public: CMyProjectDoc* GetDocument();at the end of the file (after the class declaration):#ifndef _DEBUG // debug version in MyProjectNewView.cpp inline CMyProjectDoc* CMyProjectNewView::GetDocument() { return (CMyProjectDoc*)m_pDocument; }In the .cpp file:#include "MyProjectDoc.h" / // CMyProjectNewView diagnostics #ifdef _DEBUG // ... CMyProjectDoc* CMyProjectNewView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyProjectDoc))); return (CMyProjectDoc*)m_pDocument; } #endif //_DEBUGTo access the document:CMyProjectDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);5) To let the Mainframe get the size of the dialog, put the following lines on the OnInitialUpdate() method of the CFormView class:void CMyNewView::OnInitialUpdate() { CFormView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit(FALSE); }