Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

342 lines
7.0 KiB

  1. // File: BitmapButton.cpp
  2. #include "precomp.h"
  3. #include "GenControls.h"
  4. #include <windowsx.h>
  5. CComboBox::CComboBox() :
  6. m_combo(NULL),
  7. m_hbrBack(NULL),
  8. m_hfText(NULL),
  9. m_pNotify(NULL)
  10. {
  11. }
  12. CComboBox::~CComboBox()
  13. {
  14. SetColors(NULL, 0, 0);
  15. SetFont(NULL);
  16. if (NULL != m_pNotify)
  17. {
  18. m_pNotify->Release();
  19. m_pNotify = NULL;
  20. }
  21. }
  22. BOOL CComboBox::Create(
  23. HWND hWndParent, // Parent of the edit control
  24. UINT height, // The height of the combo (with drop-down)
  25. DWORD dwStyle, // Edit control style
  26. LPCTSTR szTitle, // Initial text for the edit control
  27. IComboBoxChange *pNotify // Object to notify of changes
  28. )
  29. {
  30. if (!CFillWindow::Create(
  31. hWndParent, // Window parent
  32. 0, // ID of the child window
  33. TEXT("NMComboBox"), // Window name
  34. 0, // Window style; WS_CHILD|WS_VISIBLE will be added to this
  35. WS_EX_CONTROLPARENT // Extended window style
  36. ))
  37. {
  38. return(FALSE);
  39. }
  40. // Create the actual edit control and save it away
  41. m_combo = CreateWindowEx(0, TEXT("combobox"), szTitle,
  42. WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_VSCROLL|dwStyle,
  43. 0, 0, 10, height, GetWindow(), 0,
  44. reinterpret_cast<HINSTANCE>(GetWindowLongPtr(hWndParent, GWLP_HINSTANCE)),
  45. NULL);
  46. //
  47. // We don't have a font yet, we can't set it.
  48. //
  49. m_pNotify = pNotify;
  50. if (NULL != m_pNotify)
  51. {
  52. m_pNotify->AddRef();
  53. }
  54. return(TRUE);
  55. }
  56. // Not actually implemented yet; should use the font to determine a size
  57. void CComboBox::GetDesiredSize(SIZE *ppt)
  58. {
  59. CFillWindow::GetDesiredSize(ppt);
  60. HWND combo = GetComboBox();
  61. if (NULL == combo)
  62. {
  63. return;
  64. }
  65. // ComboBoxes always size themselves to their desired size
  66. RECT rc;
  67. GetClientRect(combo, &rc);
  68. // Just pick a number
  69. ppt->cx += 100;
  70. ppt->cy += rc.bottom;
  71. }
  72. // HACKHACK georgep: This object now owns the brush
  73. void CComboBox::SetColors(HBRUSH hbrBack, COLORREF back, COLORREF fore)
  74. {
  75. // Store off the colors and brush
  76. if (NULL != m_hbrBack)
  77. {
  78. DeleteObject(m_hbrBack);
  79. }
  80. m_hbrBack = hbrBack;
  81. m_crBack = back;
  82. m_crFore = fore;
  83. HWND edit = GetEdit();
  84. if (NULL != edit)
  85. {
  86. InvalidateRect(edit, NULL, TRUE);
  87. }
  88. }
  89. // HACKHACK georgep: This object now owns the font
  90. void CComboBox::SetFont(HFONT hf)
  91. {
  92. if (NULL != m_hfText)
  93. {
  94. DeleteObject(m_hfText);
  95. }
  96. m_hfText = hf;
  97. // Tell the edit control the font to use
  98. HWND edit = GetEdit();
  99. if (NULL != edit)
  100. {
  101. FORWARD_WM_SETFONT(edit, hf, TRUE, ::SendMessage);
  102. }
  103. }
  104. LRESULT CComboBox::ProcessMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  105. {
  106. switch (message)
  107. {
  108. HANDLE_MSG(GetWindow(), WM_CTLCOLOREDIT, OnCtlColor);
  109. HANDLE_MSG(GetWindow(), WM_COMMAND , OnCommand);
  110. HANDLE_MSG(GetWindow(), WM_NCDESTROY , OnNCDestroy);
  111. case WM_SETFOCUS:
  112. {
  113. HWND edit = GetEdit();
  114. if (NULL != edit)
  115. {
  116. ::SetFocus(edit);
  117. }
  118. break;
  119. }
  120. default:
  121. break;
  122. }
  123. return(CFillWindow::ProcessMessage(hwnd, message, wParam, lParam));
  124. }
  125. HBRUSH CComboBox::OnCtlColor(HWND hwnd, HDC hdc, HWND hwndChild, int type)
  126. {
  127. // Do default processing if there is no brush
  128. if (NULL == m_hbrBack)
  129. {
  130. return(FORWARD_WM_CTLCOLOREDIT(hwnd, hdc, hwndChild, CFillWindow::ProcessMessage));
  131. }
  132. // Set the colors in the DC, and return the brush
  133. SetBkColor(hdc, m_crBack);
  134. SetTextColor(hdc, m_crFore);
  135. return(m_hbrBack);
  136. }
  137. // Sets the text for the control
  138. void CComboBox::SetText(
  139. LPCTSTR szText // The text to set
  140. )
  141. {
  142. SetWindowText(GetEdit(), szText);
  143. }
  144. // Returns the number of items in the list
  145. int CComboBox::GetNumItems()
  146. {
  147. HWND combo = GetComboBox();
  148. int numItems;
  149. if (combo)
  150. {
  151. numItems = ComboBox_GetCount(combo);
  152. }
  153. else
  154. {
  155. numItems = 0;
  156. }
  157. return(numItems);
  158. }
  159. // Returns the index of the currently selected item
  160. int CComboBox::GetSelectedIndex()
  161. {
  162. return(ComboBox_GetCurSel(GetComboBox()));
  163. }
  164. // Sets the index of the currently selected item
  165. void CComboBox::SetSelectedIndex(int index)
  166. {
  167. ComboBox_SetCurSel(GetComboBox(), index);
  168. }
  169. // Gets the text for the control; returns the total text length
  170. int CComboBox::GetText(
  171. LPTSTR szText, // Where to put the text
  172. int nLen // The length of the buffer
  173. )
  174. {
  175. HWND edit = GetEdit();
  176. szText[0] = '\0';
  177. GetWindowText(edit, szText, nLen);
  178. return(GetWindowTextLength(edit));
  179. }
  180. int CComboBox::AddText(
  181. LPCTSTR pszText, // The string to add
  182. LPARAM lUserData // User data to associate with the string
  183. )
  184. {
  185. HWND combo = GetComboBox();
  186. int index = ComboBox_AddString(combo, pszText);
  187. if (0 != lUserData && 0 <= index)
  188. {
  189. ComboBox_SetItemData(combo, index, lUserData);
  190. }
  191. return(index);
  192. }
  193. int CComboBox::GetText(
  194. UINT index, // The index of the string to get
  195. LPTSTR pszText, // The string buffer to fill
  196. int nLen // User data to associate with the string
  197. )
  198. {
  199. HWND combo = GetComboBox();
  200. int nActualLen = ComboBox_GetLBTextLen(combo, index);
  201. if (nActualLen >= nLen)
  202. {
  203. pszText[0] = '\0';
  204. return(nActualLen);
  205. }
  206. ComboBox_GetLBText(combo, index, pszText);
  207. return(nActualLen);
  208. }
  209. LPARAM CComboBox::GetUserData(
  210. int index // The index of the user data to get
  211. )
  212. {
  213. return(ComboBox_GetItemData(GetComboBox(), index));
  214. }
  215. // Removes an item from the list
  216. void CComboBox::RemoveItem(
  217. UINT index // The index of the item to remove
  218. )
  219. {
  220. ComboBox_DeleteString(GetComboBox(), index);
  221. }
  222. void CComboBox::OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
  223. {
  224. switch (codeNotify)
  225. {
  226. case CBN_EDITUPDATE:
  227. if (NULL != m_pNotify)
  228. {
  229. m_pNotify->OnTextChange(this);
  230. }
  231. break;
  232. case CBN_SETFOCUS:
  233. SetHotControl(this);
  234. case CBN_KILLFOCUS:
  235. if (NULL != m_pNotify)
  236. {
  237. m_pNotify->OnFocusChange(this, CBN_SETFOCUS==codeNotify);
  238. }
  239. break;
  240. case CBN_SELCHANGE:
  241. if (NULL != m_pNotify)
  242. {
  243. m_pNotify->OnSelectionChange(this);
  244. }
  245. break;
  246. }
  247. FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, CFillWindow::ProcessMessage);
  248. }
  249. void CComboBox::OnNCDestroy(HWND hwnd)
  250. {
  251. if (NULL != m_pNotify)
  252. {
  253. m_pNotify->Release();
  254. m_pNotify = NULL;
  255. }
  256. m_combo = NULL;
  257. FORWARD_WM_NCDESTROY(hwnd, CFillWindow::ProcessMessage);
  258. }
  259. void CComboBox::Layout()
  260. {
  261. HWND child = GetComboBox();
  262. if (NULL != child)
  263. {
  264. RECT rcClient;
  265. GetClientRect(GetWindow(), &rcClient);
  266. RECT rcDropped;
  267. ComboBox_GetDroppedControlRect(GetComboBox(), &rcDropped);
  268. SetWindowPos(child, NULL, 0, 0, rcClient.right, rcDropped.bottom-rcDropped.top, SWP_NOZORDER);
  269. }
  270. }
  271. // Get the info necessary for displaying a tooltip
  272. void CComboBox::GetSharedTooltipInfo(TOOLINFO *pti)
  273. {
  274. CFillWindow::GetSharedTooltipInfo(pti);
  275. // Since the child covers this whole area, we need to change the HWND to
  276. // hook
  277. HWND hwnd = GetChild();
  278. // HACKHACK georgep: Setting the tooltip on the first child of the combo
  279. // box, which should be the edit control
  280. if (NULL != hwnd)
  281. {
  282. hwnd = GetFirstChild(hwnd);
  283. if (NULL != hwnd)
  284. {
  285. pti->hwnd = hwnd;
  286. }
  287. }
  288. }