1 ///////////////////////////////////////////////////////////////////////////
4 // Updated: 19-Jul-1998
6 // Copyright: Ferdinand Prantl
7 // E-mail: prantl@ff.cuni.cz
9 // Combo-box saving last typed expressions
11 // You are free to use or modify this code to the following restrictions:
12 // - Acknowledge me somewhere in your about box, simple "Parts of code by.."
13 // will be enough. If you can't (or don't want to), contact me personally.
14 // - LEAVE THIS HEADER INTACT
15 ////////////////////////////////////////////////////////////////////////////
20 #include "../utils/registry.h"
26 #define REMEMBER_COUNT 64
28 /////////////////////////////////////////////////////////////////////////////
31 BEGIN_MESSAGE_MAP (CMemComboBox, CComboBox)
32 //{{AFX_MSG_MAP(CMemComboBox)
33 ON_CONTROL_REFLECT (CBN_SETFOCUS, OnSetfocus)
37 ////////////////////////////////////////////////////////////////////////////////
40 CMemComboBox::CMemComboBox () : m_bFirstFocus (true)
44 CMemComboBox::~CMemComboBox ()
48 /////////////////////////////////////////////////////////////////////////////
49 // CMemComboBox message handlers
51 CMap < CString, LPCTSTR, CString, LPCTSTR > CMemComboBox::groups;
53 void SetComboBoxHeight(CComboBox &Control)
55 int nHeight = Control.GetCount(), nMax = ::GetSystemMetrics(SM_CYSCREEN) - 48;
58 Control.GetClientRect(rc);
59 Control.ClientToScreen(rc);
60 nHeight = rc.Height() * nHeight + 16;
61 if(rc.top + nHeight > nMax)
62 nHeight = nMax - rc.top;
63 Control.SetWindowPos(nullptr, 0, 0, rc.Width(), nHeight, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOREDRAW);
66 void SetComboBoxWidth(CComboBox &Control, LPCTSTR lpszText = nullptr)
68 int cnt = Control.GetCount();
72 CClientDC dc(&Control);
73 NONCLIENTMETRICS info = { 0 };
74 CFont oFont, *oldFont;
75 int width = 0, nMax = ::GetSystemMetrics(SM_CXSCREEN) - 48;
79 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);
80 info.lfMenuFont.lfHeight = -MulDiv(9, dc.GetDeviceCaps(LOGPIXELSY), 72);
81 info.lfMenuFont.lfWidth = 0;
82 info.lfMenuFont.lfWeight = FW_THIN;
83 info.lfMenuFont.lfItalic = false;
84 info.lfMenuFont.lfUnderline = false;
85 info.lfMenuFont.lfCharSet = DEFAULT_CHARSET;
86 info.lfMenuFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
87 info.lfMenuFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
88 info.lfMenuFont.lfQuality = DEFAULT_QUALITY;
89 info.lfMenuFont.lfPitchAndFamily = FF_SWISS;
90 _tcscpy_s(info.lfMenuFont.lfFaceName, _T("MS Sans Serif"));
91 oFont.CreateFontIndirect(&info.lfMenuFont);
92 oldFont = dc.SelectObject(&oFont);
93 if(lpszText != nullptr && *lpszText != 0) {
94 size = dc.GetTextExtent(lpszText);
99 for(int i = 0; i < cnt; i++) {
100 Control.GetLBText(i, item);
101 size = dc.GetTextExtent(item);
106 Control.GetClientRect(rc);
107 Control.ClientToScreen(rc);
108 if(rc.left + width > nMax)
109 width = nMax - rc.left;
110 Control.SetDroppedWidth(width);
111 dc.SelectObject(oldFont);
114 void CMemComboBox::FillCurrent ()
117 GetWindowText (strText);
126 int ol = GetCount ();
127 int nPos = FindStringExact (-1, text);
130 InsertString (0, text);
132 if (l > REMEMBER_COUNT)
135 SetComboBoxHeight (*this);
136 SetComboBoxWidth (*this);
138 if (!m_sGroup.IsEmpty ())
141 for (int i = 0; i < l; i++)
144 items += item + _T ('\n');
146 groups.SetAt (m_sGroup, items);
155 if (reg.Open (HKEY_CURRENT_USER, REG_EDITPAD, KEY_READ))
157 static LPCTSTR name[] = { _T("FindText"), _T("ReplaceText") };
160 for (int i = 0; i < sizeof (name) / sizeof (name[0]); i++)
162 if (reg.LoadString (name[i], value))
164 groups.SetAt (name[i], value);
174 if (reg.Create (HKEY_CURRENT_USER, REG_EDITPAD, KEY_WRITE))
176 POSITION pos = groups.GetStartPosition ();
181 groups.GetNextAssoc (pos, name, value);
182 VERIFY (reg.SaveString (name, value));
190 if (m_bFirstFocus && !m_sGroup.IsEmpty ())
192 m_bFirstFocus = false;
193 // create the dropdown list
195 if (groups.Lookup (m_sGroup, items))
198 while ((p = items.Find (_T ('\n'))) != -1)
200 AddString (items.Left (p));
201 items = items.Mid (p + 1);
203 SetComboBoxHeight (*this);
204 SetComboBoxWidth (*this);
206 // we don't modify the windowText value as it may be initialized
207 // before the dialog is shown