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
;
36 CResizableComboBox::~CResizableComboBox()
38 if (m_ctrlListBox
.GetSafeHwnd() != NULL
)
39 m_ctrlListBox
.UnsubclassWindow();
43 BEGIN_MESSAGE_MAP(CResizableComboBox
, CComboBox
)
44 //{{AFX_MSG_MAP(CResizableComboBox)
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
);
72 LRESULT
CResizableComboBox::WindowProc(UINT message
, WPARAM wParam
, LPARAM lParam
)
76 case CB_GETDROPPEDCONTROLRECT
:
77 *(LPRECT
)lParam
= m_rectDropDown
;
78 MapWindowPoints(NULL
, (LPRECT
)lParam
);
82 LRESULT lResult
= CComboBox::WindowProc(message
, wParam
, lParam
);
84 // if listbox is attached, update horizontal extent
90 if (lResult
!= CB_ERR
&& lResult
!= CB_ERRSPACE
)
91 UpdateHorizontalExtent((LPCTSTR
)lParam
);
95 if (lResult
!= CB_ERR
&& lResult
!= CB_ERRSPACE
)
96 InitHorizontalExtent();
100 InitHorizontalExtent();
107 void CResizableComboBox::InitHorizontalExtent()
110 CFont
* pOldFont
= dc
.SelectObject(GetFont());
116 for (int i
=0; i
<n
; i
++)
119 int cx
= dc
.GetTextExtent(str
).cx
;
124 SetHorizontalExtent(m_iExtent
125 + LOWORD(GetDialogBaseUnits()));
127 dc
.SelectObject(pOldFont
);
130 void CResizableComboBox::UpdateHorizontalExtent(LPCTSTR szText
)
133 CFont
* pOldFont
= dc
.SelectObject(GetFont());
135 int cx
= dc
.GetTextExtent(szText
, lstrlen(szText
)).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
166 DWORD dwStyle
= GetStyle();
168 if (!m_bIntegralHeight
|| n
== 0)
171 if (dwStyle
& CBS_OWNERDRAWVARIABLE
)
173 inth
= 0; // try to reach availh by integral steps
175 // use items below the first visible
176 for (i
=GetTopIndex(); availh
>0 && i
<n
; i
++)
178 int h
= GetItemHeight(i
);
185 // to fill the remaining height, use items above
186 for (i
=GetTopIndex()-1; availh
>0 && i
>=0; i
--)
188 int h
= GetItemHeight(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);
204 inth
+= availh
- availh
% h
;
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
)
220 if (n
- rows
< GetTopIndex())