CommitDlg: Update index using libgit2 incrementally
[TortoiseGit.git] / ext / ResizableLib / ResizableComboBox.cpp
blob0af7c633b0205300f15c1d4370a905b950edc967
1 // ResizableComboBox.cpp : implementation file
2 //
3 /////////////////////////////////////////////////////////////////////////////
4 //
5 // Copyright (C) 2000-2004 by Paolo Messina
6 // (http://www.geocities.com/ppescher - ppescher@hotmail.com)
7 //
8 // The contents of this file are subject to the Artistic License (the "License").
9 // You may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at:
11 // http://www.opensource.org/licenses/artistic-license.html
13 // If you find this code useful, credits would be nice!
15 /////////////////////////////////////////////////////////////////////////////
17 #include "stdafx.h"
18 #include "ResizableComboBox.h"
20 #ifdef _DEBUG
21 #define new DEBUG_NEW
22 #undef THIS_FILE
23 static char THIS_FILE[] = __FILE__;
24 #endif
26 /////////////////////////////////////////////////////////////////////////////
27 // CResizableComboBox
29 CResizableComboBox::CResizableComboBox()
31 m_bClipMaxHeight = TRUE;
32 m_bIntegralHeight = TRUE;
33 m_iExtent = 0;
36 CResizableComboBox::~CResizableComboBox()
38 if (m_ctrlListBox.GetSafeHwnd() != NULL)
39 m_ctrlListBox.UnsubclassWindow();
43 BEGIN_MESSAGE_MAP(CResizableComboBox, CComboBox)
44 //{{AFX_MSG_MAP(CResizableComboBox)
45 ON_WM_CTLCOLOR()
46 //}}AFX_MSG_MAP
47 END_MESSAGE_MAP()
49 /////////////////////////////////////////////////////////////////////////////
50 // CResizableComboBox message handlers
52 HBRUSH CResizableComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
54 HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);
56 if (nCtlColor == CTLCOLOR_LISTBOX)
58 if (!(GetStyle() & CBS_SIMPLE)
59 && (m_ctrlListBox.m_hWnd == NULL))
61 TRACE("ComboLBox: 0x%08X\n", pWnd->m_hWnd);
63 // attach to the owned listbox
64 m_ctrlListBox.m_pOwnerCombo = this;
65 m_ctrlListBox.SubclassWindow(pWnd->m_hWnd);
69 return hbr;
72 LRESULT CResizableComboBox::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
74 switch (message)
76 case CB_GETDROPPEDCONTROLRECT:
77 *(LPRECT)lParam = m_rectDropDown;
78 MapWindowPoints(NULL, (LPRECT)lParam);
79 return TRUE;
82 LRESULT lResult = CComboBox::WindowProc(message, wParam, lParam);
84 // if listbox is attached, update horizontal extent
86 switch (message)
88 case CB_INSERTSTRING:
89 case CB_ADDSTRING:
90 if (lResult != CB_ERR && lResult != CB_ERRSPACE)
91 UpdateHorizontalExtent((LPCTSTR)lParam);
92 break;
94 case CB_DIR:
95 if (lResult != CB_ERR && lResult != CB_ERRSPACE)
96 InitHorizontalExtent();
97 break;
99 case CB_RESETCONTENT:
100 InitHorizontalExtent();
101 break;
104 return lResult;
107 void CResizableComboBox::InitHorizontalExtent()
109 CClientDC dc(this);
110 CFont* pOldFont = dc.SelectObject(GetFont());
112 CString str;
114 m_iExtent = 0;
115 int n = GetCount();
116 for (int i=0; i<n; i++)
118 GetLBText(i, str);
119 int cx = dc.GetTextExtent(str).cx;
120 if (cx > m_iExtent)
121 m_iExtent = cx;
124 SetHorizontalExtent(m_iExtent
125 + LOWORD(GetDialogBaseUnits()));
127 dc.SelectObject(pOldFont);
130 void CResizableComboBox::UpdateHorizontalExtent(LPCTSTR szText)
132 CClientDC dc(this);
133 CFont* pOldFont = dc.SelectObject(GetFont());
135 int cx = dc.GetTextExtent(szText, lstrlen(szText)).cx;
136 if (cx > m_iExtent)
138 m_iExtent = cx;
140 SetHorizontalExtent(m_iExtent
141 + LOWORD(GetDialogBaseUnits()));
144 dc.SelectObject(pOldFont);
147 void CResizableComboBox::PreSubclassWindow()
149 ASSERT(GetStyle() & CBS_NOINTEGRALHEIGHT);
151 InitHorizontalExtent();
153 GetDroppedControlRect(&m_rectDropDown);
154 ::MapWindowPoints(NULL, GetSafeHwnd(),
155 (LPPOINT)&m_rectDropDown, 2);
157 CComboBox::PreSubclassWindow();
160 int CResizableComboBox::MakeIntegralHeight(const int height)
162 int inth = height; // integral height (result)
163 int availh = height; // available height
164 int n = GetCount();
166 DWORD dwStyle = GetStyle();
168 if (!m_bIntegralHeight || n == 0)
169 return inth;
171 if (dwStyle & CBS_OWNERDRAWVARIABLE)
173 inth = 0; // try to reach availh by integral steps
174 int i = 0;
175 // use items below the first visible
176 for (i=GetTopIndex(); availh>0 && i<n; i++)
178 int h = GetItemHeight(i);
179 if (h == CB_ERR)
180 break;
182 inth += h;
183 availh -= h;
185 // to fill the remaining height, use items above
186 for (i=GetTopIndex()-1; availh>0 && i>=0; i--)
188 int h = GetItemHeight(i);
189 if (h == CB_ERR)
190 break;
192 inth += h;
193 availh -= h;
195 // scroll into view
196 SetTopIndex(i);
198 if (!m_bClipMaxHeight) // it can be higher than all the items
200 // to fill the remaining height, use last item
201 int h = GetItemHeight(n-1);
202 if (h != CB_ERR)
204 inth += availh - availh % h;
208 else
210 // every item has the same height (take the first)
211 int h = GetItemHeight(0);
212 if (h != CB_ERR && n != CB_ERR)
214 int rows = availh / h;
215 // can't be higher than all the items
216 if (m_bClipMaxHeight && rows > n)
217 rows = n;
218 inth = rows * h;
219 // scroll into view
220 if (n - rows < GetTopIndex())
221 SetTopIndex(n-rows);
225 return inth;