MultiColumnComboBox.cpp
上传用户:yangzi5763
上传日期:2007-01-02
资源大小:239k
文件大小:21k
源码类别:

ActiveX/DCOM/ATL

开发平台:

Visual C++

  1. /************************************
  2.   REVISION LOG ENTRY
  3.   Revision By: Mihai Filimon
  4.   Revised on 9/16/98 2:20:27 PM
  5.   Comments: MultiColumnComboBox.cpp : implementation file
  6.  ************************************/
  7. #include "stdafx.h"
  8. #include "MultiColumnComboBox.h"
  9. #include "XPropertiesWnd.h"
  10. #include <math.h>
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CMultiColumnComboBox
  18. CBrush CMultiColumnComboBox::m_brBkGnd(defaultRGBBkGnd);
  19. CFont CMultiColumnComboBox::m_font;
  20. static const LOGFONT logFontPages =
  21. {
  22. /*LONG lfHeight*/8,
  23. /*LONG lfWidth*/0,
  24. /*LONG lfEscapement*/0,
  25. /*LONG lfOrientation*/0,
  26. /*LONG lfWeight*/FW_NORMAL,
  27. /*BYTE lfItalic*/FALSE,
  28. /*BYTE lfUnderline*/FALSE,
  29. /*BYTE lfStrikeOut*/FALSE,
  30. /*BYTE lfCharSet*/ANSI_CHARSET,
  31. /*BYTE lfOutPrecision*/0,
  32. /*BYTE lfClipPrecision*/0,
  33. /*BYTE lfQuality*/DEFAULT_QUALITY,
  34. /*BYTE lfPitchAndFamily*/DEFAULT_PITCH,
  35. /*CHAR lfFaceName[LF_FACESIZE]*/_T("MS Sans Serif")
  36. };
  37. // Function name : CMultiColumnComboBox::CMultiColumnComboBox
  38. // Description     : default constuctor
  39. // Return type : 
  40. CMultiColumnComboBox::CMultiColumnComboBox(int nColumnKey)
  41. {
  42. RegClassMultiColumnComboBox();
  43. m_pListCtrl = NULL;
  44. m_pEdit = NULL;
  45. m_bCaptured = FALSE;
  46. m_nColumnKey = nColumnKey;
  47. SetRateWidth(0.0);
  48. SetMultipleHeight();
  49. m_bFirstShow = TRUE; 
  50. m_nCurrentItem = -1;
  51. }
  52. // Function name : CMultiColumnComboBox::~CMultiColumnComboBox
  53. // Description     : virtual destructor
  54. // Return type : 
  55. CMultiColumnComboBox::~CMultiColumnComboBox()
  56. {
  57. }
  58. BEGIN_MESSAGE_MAP(CMultiColumnComboBox, CWnd)
  59. //{{AFX_MSG_MAP(CMultiColumnComboBox)
  60. ON_WM_DESTROY()
  61. ON_WM_LBUTTONDOWN()
  62. ON_WM_WINDOWPOSCHANGED()
  63. ON_WM_PAINT()
  64. ON_WM_LBUTTONUP()
  65. ON_WM_MOUSEMOVE()
  66. ON_WM_SETFOCUS()
  67. ON_WM_CREATE()
  68. ON_WM_SIZE()
  69. ON_WM_KEYDOWN()
  70. //}}AFX_MSG_MAP
  71. END_MESSAGE_MAP()
  72. /////////////////////////////////////////////////////////////////////////////
  73. // CMultiColumnComboBox message handlers
  74. UINT CMultiColumnComboBox::m_nSelChange = NULL;
  75. // Function name : CMultiColumnComboBox::RegClassMultiColumnComboBox
  76. // Description     : Register this window class
  77. // Return type : BOOL 
  78. BOOL CMultiColumnComboBox::RegClassMultiColumnComboBox()
  79. {
  80. WNDCLASS wndClass;
  81. wndClass.style = CS_DBLCLKS;
  82. wndClass.lpfnWndProc = ::DefWindowProc;
  83. wndClass.cbClsExtra = NULL;
  84. wndClass.cbWndExtra = NULL;
  85. wndClass.hInstance = AfxGetInstanceHandle();
  86. wndClass.hIcon = NULL;
  87. wndClass.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
  88. wndClass.hbrBackground = (HBRUSH)m_brBkGnd;
  89. wndClass.lpszMenuName = NULL;
  90. wndClass.lpszClassName = wndClassName;
  91. BOOL bResult = AfxRegisterClass(&wndClass);
  92. if (bResult)
  93. {
  94. if (!m_nSelChange)
  95. m_nSelChange = RegisterWindowMessage(defaultSelChange);
  96. if (!m_font.GetSafeHandle())
  97. {
  98. //At the first call set the new font
  99. m_font.CreateFontIndirect(&logFontPages);
  100. }
  101. }
  102. return bResult;
  103. }
  104. CMultiColumnComboBox* CMultiColumnComboBox::m_pActiveMCBox = NULL;
  105. CMultiColumnComboBox::CWindowProcs CMultiColumnComboBox::m_wndProcs;
  106. // Function name : CMultiColumnComboBox::ListCtrlWindowProc
  107. // Description     : ListControl window procedure
  108. // Return type : LRESULT CALLBACK 
  109. // Argument         : HWND hWnd
  110. // Argument         : UINT nMsg
  111. // Argument         : WPARAM wParam
  112. // Argument         : LPARAM lParam
  113. LRESULT CALLBACK CMultiColumnComboBox::ListCtrlWindowProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
  114. {
  115. CMultiColumnComboBox* pOwner  = NULL;
  116. if (pOwner = CMultiColumnComboBox::m_pActiveMCBox)
  117. pOwner->ForwardMessage(nMsg, wParam, lParam);
  118. LRESULT lResult = CallWindowProc( CMultiColumnComboBox::m_wndProcs.GetOldListCtrlProcedure(hWnd), hWnd, nMsg, wParam, lParam );
  119. return lResult;
  120. }
  121. // Function name : CMultiColumnComboBox::ParentWindowProc
  122. // Description     : Parent window procedure.
  123. // Return type : LRESULT CALLBACK 
  124. // Argument         : HWND hWnd
  125. // Argument         : UINT nMsg
  126. // Argument         : WPARAM wParam
  127. // Argument         : LPARAM lParam
  128. LRESULT CALLBACK CMultiColumnComboBox::ParentWindowProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
  129. {
  130. if (CMultiColumnComboBox* pOwner = CMultiColumnComboBox::m_pActiveMCBox)
  131. {
  132. switch (nMsg)
  133. {
  134. case WM_COMMAND:
  135. case WM_CAPTURECHANGED:
  136. case WM_SYSCOMMAND:
  137. case WM_LBUTTONDOWN:
  138. case WM_NCLBUTTONDOWN:
  139. {
  140. BOOL bDropped = pOwner->IsDropedDown();
  141. pOwner->DropDown(FALSE);
  142. if (nMsg == WM_COMMAND)
  143. if (LOWORD(wParam) == IDOK)
  144. {
  145. pOwner->SelectCurrentItem();
  146. return FALSE;
  147. }
  148. else
  149. if (LOWORD(wParam) == IDCANCEL)
  150. if (bDropped)
  151. return FALSE;
  152. break;
  153. }
  154. }
  155. };
  156. WNDPROC wndProc = CMultiColumnComboBox::m_wndProcs.GetOldParentProcedure(hWnd);
  157. ASSERT (wndProc);
  158. return CallWindowProc( wndProc, hWnd, nMsg, wParam, lParam );
  159. }
  160. // Function name : CMultiColumnComboBox::EditWindowProc
  161. // Description     : Edit window procedure
  162. // Return type : LRESULT CALLBACK 
  163. // Argument         : HWND hWnd
  164. // Argument         : UINT nMsg
  165. // Argument         : WPARAM wParam
  166. // Argument         : LPARAM lParam
  167. LRESULT CALLBACK CMultiColumnComboBox::EditWindowProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
  168. {
  169. CMultiColumnComboBox* pOwner = CMultiColumnComboBox::m_pActiveMCBox;
  170. switch (nMsg)
  171. {
  172. case WM_SETFOCUS:
  173. {
  174. CMultiColumnComboBox::m_pActiveMCBox = (CMultiColumnComboBox*)CWnd::FromHandle(::GetParent(hWnd));
  175. break;
  176. }
  177. case WM_KILLFOCUS:
  178. {
  179. if (pOwner)
  180. {
  181. pOwner->DropDown(FALSE);
  182. CMultiColumnComboBox::m_pActiveMCBox = NULL;
  183. }
  184. break;
  185. }
  186. case WM_KEYDOWN:
  187. case WM_SYSKEYDOWN:
  188. {
  189. if (pOwner)
  190. switch ((int) wParam)
  191. {
  192. case VK_RETURN :
  193. case VK_ESCAPE :
  194. case VK_UP:
  195. case VK_DOWN:
  196. case VK_PRIOR:
  197. case VK_NEXT:
  198. {
  199. //dispatch enter,... keys to multi column...
  200. pOwner->SendMessage(nMsg, wParam, lParam);
  201. break;
  202. }
  203. case defaultDropDownKey:
  204. {
  205. pOwner->DropDown(!pOwner->IsDropedDown());
  206. pOwner->CaptureListCtrl();
  207. break;
  208. }
  209. }
  210. break;
  211. }
  212. }
  213. return CallWindowProc( CMultiColumnComboBox::m_wndProcs.GetOldEditProcedure(hWnd), hWnd, nMsg, wParam, lParam );
  214. }
  215. // Function name : CMultiColumnComboBox::OnInit
  216. // Description     : Init the control
  217. // Return type : BOOL 
  218. BOOL CMultiColumnComboBox::OnInit()
  219. {
  220. //Do not call twice
  221. ASSERT (m_pEdit == NULL && m_pListCtrl == NULL);
  222. ASSERT (m_font.GetSafeHandle());
  223. SetFont(&m_font);
  224. ModifyStyle(WS_OVERLAPPED , WS_TABSTOP);
  225. m_pEdit = new CEdit();
  226. m_pListCtrl = new CListCtrl();
  227. if (m_pEdit->Create(WS_CHILD | WS_VISIBLE | defaultEditStyle, CRect(0,0,0,0), this, IDEDIT ))
  228. {
  229. ModifyStyleEx(0, WS_EX_STATICEDGE);
  230. m_pEdit->SetFont(&m_font);
  231. if (m_pListCtrl->Create(WS_BORDER | WS_CHILD | defaultListCtrlStyle , CRect(0,0,0,0), GetDesktopWindow(), IDLISTCTRL))
  232. {
  233. //Set the reference to this object in user data dword
  234. ::SetWindowLong(m_pListCtrl->m_hWnd, GWL_USERDATA, (long)this);
  235. ::SetWindowLong(m_pListCtrl->m_hWnd, GWL_STYLE, GetWindowLong(m_pListCtrl->m_hWnd, GWL_STYLE) | WS_CLIPSIBLINGS | WS_OVERLAPPED);
  236. m_pListCtrl->ModifyStyleEx(0, WS_EX_TOOLWINDOW);
  237. m_pListCtrl->SetWindowPos(&CWnd::wndTopMost,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
  238. ListView_SetExtendedListViewStyle(m_pListCtrl->m_hWnd, LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);
  239. Resize();
  240. m_wndProcs.AddEdit(GetEdit(), EditWindowProc);
  241. m_wndProcs.AddListCtrl(GetListCtrl(), ListCtrlWindowProc);
  242. m_wndProcs.AddParent(GetParent(), ParentWindowProc);
  243. return TRUE;
  244. }
  245. }
  246. return FALSE;
  247. }
  248. // Function name : CMultiColumnComboBox::PreSubclassWindow
  249. // Description     : Call to subclass window
  250. // Return type : void 
  251. void CMultiColumnComboBox::PreSubclassWindow() 
  252. {
  253. CWnd::PreSubclassWindow();
  254. // If this is dynamical created then do not call OnInit
  255. if (AfxGetThreadState()->m_pWndInit == 0)
  256. OnInit();
  257. }
  258. // Function name : CMultiColumnComboBox::OnDestroy
  259. // Description     : Remove all dependent datas.
  260. // Return type : void 
  261. void CMultiColumnComboBox::OnDestroy() 
  262. {
  263. CWnd::OnDestroy();
  264. m_wndProcs.RemoveEdit(GetEdit());
  265. m_wndProcs.RemoveListCtrl(GetListCtrl());
  266. m_wndProcs.RemoveParent(GetParent());
  267. if (CListCtrl* pList = GetListCtrl())
  268. {
  269. pList->DeleteAllItems();
  270. delete pList;
  271. }
  272. if (CEdit* pEdit = GetEdit())
  273. delete pEdit;
  274. m_pListCtrl = NULL;
  275. m_pEdit = NULL;
  276. }
  277. // Function name : CMultiColumnComboBox::GetListCtrl
  278. // Description     : return the list control for 
  279. // Return type : CListCtrl* 
  280. CListCtrl* CMultiColumnComboBox::GetListCtrl()
  281. {
  282. return m_pListCtrl;
  283. }
  284. // Function name : CMultiColumnComboBox::GetEdit
  285. // Description     : retirn  pointer to edit control inside of thsi control
  286. // Return type : CEdit* 
  287. CEdit* CMultiColumnComboBox::GetEdit()
  288. {
  289. return m_pEdit;
  290. }
  291. // Function name : CMultiColumnComboBox::DrawButton
  292. // Description     : Draw down button
  293. // Return type : void 
  294. // Argument         : CDC * pDC
  295. // Argument         : CRect r
  296. // Argument         : BOOL bDown
  297. void CMultiColumnComboBox::DrawButton(CDC * pDC, CRect r, BOOL bDown)
  298. {
  299. r.InflateRect(-1,-1);
  300. pDC->FillRect(r,&CBrush(RGB(192,192,192)));
  301. pDC->DrawEdge(r, EDGE_RAISED, BF_RECT);
  302. pDC->DrawIcon(r.TopLeft() + CPoint(1,1),AfxGetApp()->LoadIcon(IDI_ICON_DOWN));
  303. }
  304. // Function name : CMultiColumnComboBox::OnPaint
  305. // Description     : On Draw function
  306. // Return type : void 
  307. void CMultiColumnComboBox::OnPaint() 
  308. {
  309. CPaintDC dc(this); // device context for painting
  310. CRect r; GetClientRect(r);
  311. r.left = r.right - (GetSystemMetrics(SM_CXHSCROLL) + 2);
  312. m_rectBtn = r;
  313. DrawButton(&dc, m_rectBtn);
  314. }
  315. // Function name : CMultiColumnComboBox::Resize
  316. // Description     : Call to remove the edit and list controls
  317. // Return type : void 
  318. void CMultiColumnComboBox::Resize()
  319. {
  320. ASSERT (GetListCtrl());
  321. CRect r;
  322. GetWindowRect(r);
  323. SetWindowPos(0, 0, 0, r.Width(), defaultSizeDY, SWP_NOMOVE | SWP_NOZORDER | SWP_NOMOVE);
  324. // Set the height and width of edit control
  325. GetClientRect(r);
  326. r.InflateRect(-1,-2); r.bottom++;
  327. r.right = r.right - (GetSystemMetrics(SM_CXHSCROLL) + 2);
  328. GetEdit()->MoveWindow(r.left, r.top, r.Width(), r.Height());
  329. // Set the height and width of list control
  330. GetWindowRect(r);
  331. int dy = r.Height();
  332. int dx = r.Width();
  333. r.top = r.bottom;
  334. r.left++;r.right--;
  335. r.bottom += m_nMultipleHeight * dy;
  336. r.right += int(m_dWidthList * r.Width());
  337. r.OffsetRect(-(r.Width() - dx),0);
  338. GetListCtrl()->MoveWindow(r.left, r.top, r.Width(), r.Height());
  339. }
  340. // Function name : CMultiColumnComboBox::DropDown
  341. // Description     : DropDown
  342. // Return type : void 
  343. // Argument         : BOOL bDown
  344. void CMultiColumnComboBox::DropDown(BOOL bDown)
  345. {
  346. if (IsWindowVisible())
  347. {
  348. if (IsDropedDown() != bDown)
  349. {
  350. Resize();
  351. GetListCtrl()->ShowWindow(bDown ? SW_SHOW : SW_HIDE);
  352. GetListCtrl()->SetCapture();
  353. if (bDown)
  354. {
  355. GetEdit()->SetFocus();
  356. SetCurrentItem(m_nSelectedItem);
  357. GetListCtrl()->EnsureVisible(m_nSelectedItem, FALSE);
  358. }
  359. else
  360. ReleaseCapture();
  361. }
  362. }
  363. }
  364. // Function name : CMultiColumnComboBox::IsDropedDown
  365. // Description     : If the list control is dropped downd, return TRUE
  366. // Return type : BOOL 
  367. BOOL CMultiColumnComboBox::IsDropedDown()
  368. {
  369. return GetListCtrl()->IsWindowVisible();
  370. }
  371. // Function name : CMultiColumnComboBox::OnWindowPosChanged
  372. // Description     : 
  373. // Return type : void 
  374. // Argument         : WINDOWPOS FAR* lpwndpos
  375. void CMultiColumnComboBox::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos) 
  376. {
  377. CWnd::OnWindowPosChanged(lpwndpos);
  378. Resize();
  379. }
  380. // Function name : CMultiColumnComboBox::OnLButtonDown
  381. // Description     : 
  382. // Return type : void 
  383. // Argument         : UINT nFlags
  384. // Argument         : CPoint point
  385. void CMultiColumnComboBox::OnLButtonDown(UINT nFlags, CPoint point) 
  386. {
  387. if (m_rectBtn.PtInRect(point))
  388. {
  389. SetButton();
  390. DropDown(!IsDropedDown());
  391. }
  392. CWnd::OnLButtonDown(nFlags, point);
  393. }
  394. // Function name : CMultiColumnComboBox::OnLButtonUp
  395. // Description     : 
  396. // Return type : void 
  397. // Argument         : UINT nFlags
  398. // Argument         : CPoint point
  399. void CMultiColumnComboBox::OnLButtonUp(UINT nFlags, CPoint point) 
  400. {
  401. ReleaseButton();
  402. CaptureListCtrl();
  403. CWnd::OnLButtonUp(nFlags, point);
  404. }
  405. // Function name : CMultiColumnComboBox::OnMouseMove
  406. // Description     : 
  407. // Return type : void 
  408. // Argument         : UINT nFlags
  409. // Argument         : CPoint point
  410. void CMultiColumnComboBox::OnMouseMove(UINT nFlags, CPoint point) 
  411. {
  412. if (m_bCaptured)
  413. {
  414. CPoint p; ::GetCursorPos(&p);
  415. ScreenToClient(&p);
  416. if (!m_rectBtn.PtInRect(p))
  417. ReleaseButton();
  418. }
  419. CWnd::OnMouseMove(nFlags, point);
  420. }
  421. // Function name : CMultiColumnComboBox::ReleaseButton
  422. // Description     : Call to release the capture and image of button. After SetButton()
  423. // Return type : void 
  424. void CMultiColumnComboBox::ReleaseButton()
  425. {
  426. if (m_bCaptured)
  427. {
  428. ReleaseCapture();
  429. CDC* pDC = GetDC();
  430. DrawButton(pDC, m_rectBtn);
  431. ReleaseDC(pDC);
  432. m_bCaptured = FALSE;
  433. GetListCtrl()->SetCapture();
  434. }
  435. }
  436. // Function name : CMultiColumnComboBox::SetButton
  437. // Description     : 
  438. // Return type : void 
  439. void CMultiColumnComboBox::SetButton()
  440. {
  441. if (!m_bCaptured)
  442. {
  443. SetCapture();
  444. CDC* pDC = GetDC();
  445. DrawButton(pDC, m_rectBtn, TRUE);
  446. ReleaseDC(pDC);
  447. m_bCaptured = TRUE;
  448. }
  449. }
  450. // Function name : CMultiColumnComboBox::ForwardMessage
  451. // Description     : This function is called by ListCtrlWindowProc
  452. // Return type : void 
  453. // Argument         : UINT nMsg
  454. // Argument         : WPARAM wParam
  455. // Argument         : LPARAM lParam
  456. void CMultiColumnComboBox::ForwardMessage(UINT nMsg, WPARAM wParam, LPARAM lParam)
  457. {
  458. CListCtrl* pListCtrl = GetListCtrl();
  459. switch (nMsg)
  460. {
  461. case WM_MOUSEMOVE:
  462. case WM_NCMOUSEMOVE:
  463. {
  464. ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
  465. pListCtrl->SetCapture();
  466. }
  467. case WM_LBUTTONDOWN:
  468. {
  469. CPoint point(LOWORD(lParam), HIWORD(lParam));
  470. CRect rectWindow; pListCtrl->GetWindowRect(rectWindow);
  471. CRect rectClient; pListCtrl->GetClientRect(rectClient);
  472. pListCtrl->ClientToScreen(rectClient);
  473. CPoint pointScreen(point);
  474. pListCtrl->ClientToScreen(&pointScreen);
  475. LPARAM lPoint = MAKELPARAM(pointScreen.x, pointScreen.y);
  476. BOOL bClient = rectClient.PtInRect(pointScreen);
  477. if ( bClient )
  478. {
  479. int nIndex = pListCtrl->HitTest(CPoint(LOWORD(lParam), HIWORD(lParam)));
  480. if (nIndex >= 0)
  481. if (GetCurrentItem() != nIndex)
  482. SetCurrentItem(nIndex);
  483. }
  484. else 
  485. if (rectWindow.PtInRect(pointScreen))
  486. if (nMsg == WM_LBUTTONDOWN)
  487. {
  488. ReleaseCapture();
  489. pListCtrl->SendMessage(WM_NCLBUTTONDOWN, pListCtrl->SendMessage(WM_NCHITTEST,0,lPoint), lPoint);
  490. pListCtrl->SetCapture();
  491. break;
  492. };
  493. if (nMsg == WM_LBUTTONDOWN)
  494. {
  495. DropDown(FALSE);
  496. if ( bClient )
  497. SelectCurrentItem();
  498. }
  499. break;
  500. }
  501. }
  502. }
  503. // Function name : CMultiColumnComboBox::OnSetFocus
  504. // Description     : When control have focus then edit will take the focus
  505. // Return type : void 
  506. // Argument         : CWnd* pOldWnd
  507. void CMultiColumnComboBox::OnSetFocus(CWnd* pOldWnd) 
  508. {
  509. CWnd::OnSetFocus(pOldWnd);
  510. GetEdit()->SetFocus();
  511. }
  512. // Function name : CMultiColumnComboBox::OnCommand
  513. // Description     : When something is happen in edit control, notify the list control
  514. // Return type : BOOL 
  515. // Argument         : WPARAM wParam
  516. // Argument         : LPARAM lParam
  517. BOOL CMultiColumnComboBox::OnCommand(WPARAM wParam, LPARAM lParam) 
  518. {
  519. if (LOWORD(wParam) == IDEDIT)
  520. if (HIWORD(wParam) == EN_CHANGE)
  521. {
  522. ASSERT( GetEdit() && GetEdit()->GetDlgCtrlID() == IDEDIT);
  523. CString text,t ;
  524. GetEdit()->GetWindowText(t);
  525. Search(t);
  526. }
  527. return CWnd::OnCommand(wParam, lParam);
  528. }
  529. // Function name : CMultiColumnComboBox::Search
  530. // Description     : Look for the lpszFindItem
  531. // Return type : void 
  532. // Argument         : LPCTSTR lpszFindItem
  533. void CMultiColumnComboBox::Search(LPCTSTR lpszFindItem)
  534. {
  535. if (CListCtrl* pListCtrl = GetListCtrl())
  536. {
  537. int nItem = 0, n = pListCtrl->GetItemCount(), l = CString(lpszFindItem).GetLength();
  538. while (nItem < n)
  539. {
  540. CString itemL = pListCtrl->GetItemText(nItem, m_nColumnKey).Mid(0,l);
  541. if (itemL.CompareNoCase(lpszFindItem) == 0)
  542. break;
  543. nItem++;
  544. }
  545. if (nItem < n)
  546. {
  547. SetCurrentItem(nItem);
  548. pListCtrl->EnsureVisible(nItem, FALSE); 
  549. }
  550. }
  551. }
  552. // Function name : CMultiColumnComboBox::SelectCurrentItem
  553. // Description     : Select the current item of list. Called if user click the mouse, oor press ENTER
  554. // Return type : void 
  555. BOOL CMultiColumnComboBox::SelectCurrentItem()
  556. {
  557. BOOL bResult = FALSE;
  558. m_nSelectedItem = GetCurrentItem();
  559. // Store in m_nSelectedItem lastselected item, to retrieve, when drop down occurs
  560. if (m_nSelectedItem >= 0)
  561. {
  562. GetEdit()->SetWindowText(GetListCtrl()->GetItemText(m_nSelectedItem, m_nColumnKey));
  563. //Notify the parent that one item was changed
  564. if (m_nSelectedItem >= 0)
  565. if (CWnd* pParent = GetParent())
  566. {
  567. pParent->SendMessage(m_nSelChange, (WPARAM)GetDlgCtrlID(), (LPARAM)m_hWnd);
  568. bResult = TRUE;
  569. }
  570. }
  571. return bResult;
  572. }
  573. // Function name : CMultiColumnComboBox::GetCurrentItem
  574. // Description     : Get current item from list control
  575. // Return type : int 
  576. int CMultiColumnComboBox::GetCurrentItem()
  577. {
  578. return m_nCurrentItem;
  579. //return GetListCtrl()->GetNextItem(-1, LVNI_SELECTED);
  580. }
  581. // Function name : CMultiColumnComboBox::SetCurrentItem
  582. // Description     : Set current item from list control to nIndex
  583. // Return type : void 
  584. // Argument         : int nIndex
  585. void CMultiColumnComboBox::SetCurrentItem(int nIndex)
  586. {
  587. if (nIndex >= 0)
  588. {
  589. GetListCtrl()->SetItemState(nIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  590. m_nCurrentItem = nIndex;
  591. }
  592. }
  593. // Function name : CMultiColumnComboBox::OnCreate
  594. // Description     : Call OnInit if control is created dynamically
  595. // Return type : int 
  596. // Argument         : LPCREATESTRUCT lpCreateStruct
  597. int CMultiColumnComboBox::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  598. {
  599. if (CWnd::OnCreate(lpCreateStruct) == -1)
  600. return -1;
  601. OnInit();
  602. return 0;
  603. }
  604. // Function name : CMultiColumnComboBox::SetRateWidth
  605. // Description     : This function will changes the width of inside listcontrol
  606. // Return type : double 
  607. // Argument         : double dWidthList
  608. double CMultiColumnComboBox::SetRateWidth(double dWidthList)
  609. {
  610. double dResult = m_dWidthList;
  611. m_dWidthList = fabs(dWidthList);
  612. return dResult;
  613. }
  614. // Function name : CMultiColumnComboBox::SetMultipleHeight
  615. // Description     : 
  616. // Return type : int 
  617. // Argument         : int nMHeight
  618. int CMultiColumnComboBox::SetMultipleHeight(int nMHeight)
  619. {
  620. int nResult = m_nMultipleHeight;
  621. m_nMultipleHeight = abs(nMHeight);
  622. return nResult;
  623. }
  624. // Function name : CMultiColumnComboBox::WindowProc
  625. // Description     : 
  626. // Return type : LRESULT 
  627. // Argument         : UINT message
  628. // Argument         : WPARAM wParam
  629. // Argument         : LPARAM lParam
  630. LRESULT CMultiColumnComboBox::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
  631. {
  632. if (GetEdit())
  633. switch ( message )
  634. {
  635. case WM_SETTEXT:
  636. case WM_GETTEXT:
  637. {
  638. GetEdit()->SendMessage( message, wParam, lParam );
  639. break;
  640. }
  641. }
  642. return CWnd::WindowProc(message, wParam, lParam);
  643. }
  644. // Function name : CMultiColumnComboBox::OnSize
  645. // Description     : resize combo if needs
  646. // Return type : void 
  647. // Argument         : UINT nType
  648. // Argument         : int cx
  649. // Argument         : int cy
  650. void CMultiColumnComboBox::OnSize(UINT nType, int cx, int cy) 
  651. {
  652. CWnd::OnSize(nType, cx, cy);
  653. Resize();
  654. }
  655. // Function name : CMultiColumnComboBox::CaptureListCtrl
  656. // Description     : Capture listcontrol to know when the drop will be up
  657. // Return type : void 
  658. void CMultiColumnComboBox::CaptureListCtrl()
  659. {
  660. if (IsDropedDown())
  661. GetListCtrl()->SetCapture();
  662. }
  663. // Function name : CMultiColumnComboBox::OnKeyDown
  664. // Description     : Treat here the VK_RETURN key
  665. // Return type : void 
  666. // Argument         : UINT nChar
  667. // Argument         : UINT nRepCnt
  668. // Argument         : UINT nFlags
  669. void CMultiColumnComboBox::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  670. {
  671. switch (nChar)
  672. {
  673. case VK_RETURN:
  674. case VK_SPACE:
  675. {
  676. DropDown(FALSE);
  677. SelectCurrentItem();
  678. }
  679. case VK_ESCAPE:
  680. {
  681. DropDown(FALSE);
  682. break;
  683. }
  684. case VK_UP:
  685. case VK_DOWN:
  686. case VK_PRIOR:
  687. case VK_NEXT:
  688. {
  689. //dispatch enter,... keys to multi column...
  690. GetListCtrl()->SendMessage(WM_KEYDOWN, nChar, 0);
  691. break;
  692. }
  693. }
  694. CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
  695. }