// The callback function that hooks up and processes messages // send to the list-box within the combobox LRESULT CALLBACK CTTComboBox::HookListboxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { CListBox* pList = (CListBox*)CWnd::FromHandle(hWnd); CTTComboBox* pThisCombo = NULL; m_mapCombo.Lookup(hWnd, pThisCombo); if (message == WM_MOUSEMOVE) { WORD xPos, yPos; xPos = LOWORD(lParam); yPos = HIWORD(lParam); CPoint point(xPos, yPos); CRect rcClient; ::GetClientRect(hWnd, &rcClient); if (rcClient.PtInRect(point)) {// Handle mouse move event that may show a tool-tip window... CTTComboBox::HandleListboxMouseMove(pList, wParam, point); } else {// However, the list-box may be captured thus we must know when the mouse cursor // out of the area of the list-box, and send 'WM_MOUSELEAVE' notification. ::SendMessage(hWnd, WM_MOUSELEAVE, wParam, lParam); } if (!m_isEnter) {// Tracking the mouse event which are hovering and leaving. OnTrackMouseEvent(hWnd, TME_HOVER|TME_LEAVE); m_isEnter = TRUE; } } else if (message == WM_MOUSELEAVE) { // When the mouse cursor has been left current window, the original select of the list-box // to reset LB_ERR. m_OriginalSel = LB_ERR; m_isEnter = FALSE; // The tool-tip window is hidden m_tipWnd.ShowWindow(SW_HIDE); } else if (message == WM_CAPTURECHANGED) { // Ignore the mouse capture changed... return 1; } else if (message == WM_LBUTTONDOWN || message == WM_LBUTTONDBLCLK) { WORD xPos, yPos; xPos = LOWORD(lParam); yPos = HIWORD(lParam); CPoint point(xPos, yPos); CRect rcClient; ::GetClientRect(hWnd, &rcClient); if (rcClient.PtInRect(point)) { BOOL bOutside; int curSel = pList->ItemFromPoint(point, bOutside); if (!bOutside && curSel != LB_ERR) { for (int i = 0; i < pThisCombo->m_arrDisabledItems.GetSize(); i++) { if ((UINT)curSel == pThisCombo->m_arrDisabledItems.GetAt(i)) { return TRUE; // Don't process the message } } } } } else if (message == WM_SHOWWINDOW) { if (wParam == TRUE) // Show up! { pThisCombo->AlignListBoxWithCombo(); } } // Get previous window procedure WNDPROC oldListWndProc; m_mapWndProc.Lookup(hWnd, oldListWndProc); // Call previous window procedure return ::CallWindowProc(oldListWndProc, hWnd, message, wParam, lParam); }