1 // ResizableComboBox.cpp : implementation file
3 /////////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2000-2004 by Paolo Messina
6 // (http://www.geocities.com/ppescher - ppescher@hotmail.com)
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 /////////////////////////////////////////////////////////////////////////////
18 #include "ResizableComboBox.h"
23 static char THIS_FILE
[] = __FILE__
;
26 /////////////////////////////////////////////////////////////////////////////
29 CResizableComboBox::CResizableComboBox()
31 m_bClipMaxHeight
= TRUE
;
32 m_bIntegralHeight
= TRUE
;
35 CResizableComboBox::~CResizableComboBox()
37 if (m_ctrlListBox
.GetSafeHwnd() != NULL
)
38 m_ctrlListBox
.UnsubclassWindow();
42 BEGIN_MESSAGE_MAP(CResizableComboBox
, CComboBox
)
43 //{{AFX_MSG_MAP(CResizableComboBox)
48 /////////////////////////////////////////////////////////////////////////////
49 // CResizableComboBox message handlers
51 HBRUSH
CResizableComboBox::OnCtlColor(CDC
* pDC
, CWnd
* pWnd
, UINT nCtlColor
)
53 HBRUSH hbr
= CComboBox::OnCtlColor(pDC
, pWnd
, nCtlColor
);
55 if (nCtlColor
== CTLCOLOR_LISTBOX
)
57 if (!(GetStyle() & CBS_SIMPLE
)
58 && (m_ctrlListBox
.m_hWnd
== NULL
))
60 TRACE("ComboLBox: 0x%08X\n", pWnd
->m_hWnd
);
62 // attach to the owned listbox
63 m_ctrlListBox
.m_pOwnerCombo
= this;
64 m_ctrlListBox
.SubclassWindow(pWnd
->m_hWnd
);
71 LRESULT
CResizableComboBox::WindowProc(UINT message
, WPARAM wParam
, LPARAM lParam
)
75 case CB_GETDROPPEDCONTROLRECT
:
76 *(LPRECT
)lParam
= m_rectDropDown
;
77 MapWindowPoints(NULL
, (LPRECT
)lParam
);
81 LRESULT lResult
= CComboBox::WindowProc(message
, wParam
, lParam
);
83 // if listbox is attached, update horizontal extent
89 if (lResult
!= CB_ERR
&& lResult
!= CB_ERRSPACE
)
90 UpdateHorizontalExtent((LPCTSTR
)lParam
);
94 if (lResult
!= CB_ERR
&& lResult
!= CB_ERRSPACE
)
95 InitHorizontalExtent();
99 InitHorizontalExtent();
106 void CResizableComboBox::InitHorizontalExtent()
109 CFont
* pOldFont
= dc
.SelectObject(GetFont());
115 for (int i
=0; i
<n
; i
++)
118 int cx
= dc
.GetTextExtent(str
).cx
;
123 SetHorizontalExtent(m_iExtent
124 + LOWORD(GetDialogBaseUnits()));
126 dc
.SelectObject(pOldFont
);
129 void CResizableComboBox::UpdateHorizontalExtent(LPCTSTR szText
)
132 CFont
* pOldFont
= dc
.SelectObject(GetFont());
134 int cx
= dc
.GetTextExtent(szText
, lstrlen(szText
)).cx
;
139 SetHorizontalExtent(m_iExtent
140 + LOWORD(GetDialogBaseUnits()));
143 dc
.SelectObject(pOldFont
);
146 void CResizableComboBox::PreSubclassWindow()
148 ASSERT(GetStyle() & CBS_NOINTEGRALHEIGHT
);
150 InitHorizontalExtent();
152 GetDroppedControlRect(&m_rectDropDown
);
153 ::MapWindowPoints(NULL
, GetSafeHwnd(),
154 (LPPOINT
)&m_rectDropDown
, 2);
156 CComboBox::PreSubclassWindow();
159 int CResizableComboBox::MakeIntegralHeight(const int height
)
161 int inth
= height
; // integral height (result)
162 int availh
= height
; // available height
165 DWORD dwStyle
= GetStyle();
167 if (!m_bIntegralHeight
|| n
== 0)
170 if (dwStyle
& CBS_OWNERDRAWVARIABLE
)
172 inth
= 0; // try to reach availh by integral steps
174 // use items below the first visible
175 for (i
=GetTopIndex(); availh
>0 && i
<n
; i
++)
177 int h
= GetItemHeight(i
);
184 // to fill the remaining height, use items above
185 for (i
=GetTopIndex()-1; availh
>0 && i
>=0; i
--)
187 int h
= GetItemHeight(i
);
197 if (!m_bClipMaxHeight
) // it can be higher than all the items
199 // to fill the remaining height, use last item
200 int h
= GetItemHeight(n
-1);
203 inth
+= availh
- availh
% h
;
209 // every item has the same height (take the first)
210 int h
= GetItemHeight(0);
211 if (h
!= CB_ERR
&& n
!= CB_ERR
)
213 int rows
= availh
/ h
;
214 // can't be higher than all the items
215 if (m_bClipMaxHeight
&& rows
> n
)
219 if (n
- rows
< GetTopIndex())