// File: BitmapButton.cpp #include "precomp.h" #include "GenControls.h" #include CComboBox::CComboBox() : m_combo(NULL), m_hbrBack(NULL), m_hfText(NULL), m_pNotify(NULL) { } CComboBox::~CComboBox() { SetColors(NULL, 0, 0); SetFont(NULL); if (NULL != m_pNotify) { m_pNotify->Release(); m_pNotify = NULL; } } BOOL CComboBox::Create( HWND hWndParent, // Parent of the edit control UINT height, // The height of the combo (with drop-down) DWORD dwStyle, // Edit control style LPCTSTR szTitle, // Initial text for the edit control IComboBoxChange *pNotify // Object to notify of changes ) { if (!CFillWindow::Create( hWndParent, // Window parent 0, // ID of the child window TEXT("NMComboBox"), // Window name 0, // Window style; WS_CHILD|WS_VISIBLE will be added to this WS_EX_CONTROLPARENT // Extended window style )) { return(FALSE); } // Create the actual edit control and save it away m_combo = CreateWindowEx(0, TEXT("combobox"), szTitle, WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_VSCROLL|dwStyle, 0, 0, 10, height, GetWindow(), 0, reinterpret_cast(GetWindowLongPtr(hWndParent, GWLP_HINSTANCE)), NULL); // // We don't have a font yet, we can't set it. // m_pNotify = pNotify; if (NULL != m_pNotify) { m_pNotify->AddRef(); } return(TRUE); } // Not actually implemented yet; should use the font to determine a size void CComboBox::GetDesiredSize(SIZE *ppt) { CFillWindow::GetDesiredSize(ppt); HWND combo = GetComboBox(); if (NULL == combo) { return; } // ComboBoxes always size themselves to their desired size RECT rc; GetClientRect(combo, &rc); // Just pick a number ppt->cx += 100; ppt->cy += rc.bottom; } // HACKHACK georgep: This object now owns the brush void CComboBox::SetColors(HBRUSH hbrBack, COLORREF back, COLORREF fore) { // Store off the colors and brush if (NULL != m_hbrBack) { DeleteObject(m_hbrBack); } m_hbrBack = hbrBack; m_crBack = back; m_crFore = fore; HWND edit = GetEdit(); if (NULL != edit) { InvalidateRect(edit, NULL, TRUE); } } // HACKHACK georgep: This object now owns the font void CComboBox::SetFont(HFONT hf) { if (NULL != m_hfText) { DeleteObject(m_hfText); } m_hfText = hf; // Tell the edit control the font to use HWND edit = GetEdit(); if (NULL != edit) { FORWARD_WM_SETFONT(edit, hf, TRUE, ::SendMessage); } } LRESULT CComboBox::ProcessMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { HANDLE_MSG(GetWindow(), WM_CTLCOLOREDIT, OnCtlColor); HANDLE_MSG(GetWindow(), WM_COMMAND , OnCommand); HANDLE_MSG(GetWindow(), WM_NCDESTROY , OnNCDestroy); case WM_SETFOCUS: { HWND edit = GetEdit(); if (NULL != edit) { ::SetFocus(edit); } break; } default: break; } return(CFillWindow::ProcessMessage(hwnd, message, wParam, lParam)); } HBRUSH CComboBox::OnCtlColor(HWND hwnd, HDC hdc, HWND hwndChild, int type) { // Do default processing if there is no brush if (NULL == m_hbrBack) { return(FORWARD_WM_CTLCOLOREDIT(hwnd, hdc, hwndChild, CFillWindow::ProcessMessage)); } // Set the colors in the DC, and return the brush SetBkColor(hdc, m_crBack); SetTextColor(hdc, m_crFore); return(m_hbrBack); } // Sets the text for the control void CComboBox::SetText( LPCTSTR szText // The text to set ) { SetWindowText(GetEdit(), szText); } // Returns the number of items in the list int CComboBox::GetNumItems() { HWND combo = GetComboBox(); int numItems; if (combo) { numItems = ComboBox_GetCount(combo); } else { numItems = 0; } return(numItems); } // Returns the index of the currently selected item int CComboBox::GetSelectedIndex() { return(ComboBox_GetCurSel(GetComboBox())); } // Sets the index of the currently selected item void CComboBox::SetSelectedIndex(int index) { ComboBox_SetCurSel(GetComboBox(), index); } // Gets the text for the control; returns the total text length int CComboBox::GetText( LPTSTR szText, // Where to put the text int nLen // The length of the buffer ) { HWND edit = GetEdit(); szText[0] = '\0'; GetWindowText(edit, szText, nLen); return(GetWindowTextLength(edit)); } int CComboBox::AddText( LPCTSTR pszText, // The string to add LPARAM lUserData // User data to associate with the string ) { HWND combo = GetComboBox(); int index = ComboBox_AddString(combo, pszText); if (0 != lUserData && 0 <= index) { ComboBox_SetItemData(combo, index, lUserData); } return(index); } int CComboBox::GetText( UINT index, // The index of the string to get LPTSTR pszText, // The string buffer to fill int nLen // User data to associate with the string ) { HWND combo = GetComboBox(); int nActualLen = ComboBox_GetLBTextLen(combo, index); if (nActualLen >= nLen) { pszText[0] = '\0'; return(nActualLen); } ComboBox_GetLBText(combo, index, pszText); return(nActualLen); } LPARAM CComboBox::GetUserData( int index // The index of the user data to get ) { return(ComboBox_GetItemData(GetComboBox(), index)); } // Removes an item from the list void CComboBox::RemoveItem( UINT index // The index of the item to remove ) { ComboBox_DeleteString(GetComboBox(), index); } void CComboBox::OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { switch (codeNotify) { case CBN_EDITUPDATE: if (NULL != m_pNotify) { m_pNotify->OnTextChange(this); } break; case CBN_SETFOCUS: SetHotControl(this); case CBN_KILLFOCUS: if (NULL != m_pNotify) { m_pNotify->OnFocusChange(this, CBN_SETFOCUS==codeNotify); } break; case CBN_SELCHANGE: if (NULL != m_pNotify) { m_pNotify->OnSelectionChange(this); } break; } FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, CFillWindow::ProcessMessage); } void CComboBox::OnNCDestroy(HWND hwnd) { if (NULL != m_pNotify) { m_pNotify->Release(); m_pNotify = NULL; } m_combo = NULL; FORWARD_WM_NCDESTROY(hwnd, CFillWindow::ProcessMessage); } void CComboBox::Layout() { HWND child = GetComboBox(); if (NULL != child) { RECT rcClient; GetClientRect(GetWindow(), &rcClient); RECT rcDropped; ComboBox_GetDroppedControlRect(GetComboBox(), &rcDropped); SetWindowPos(child, NULL, 0, 0, rcClient.right, rcDropped.bottom-rcDropped.top, SWP_NOZORDER); } } // Get the info necessary for displaying a tooltip void CComboBox::GetSharedTooltipInfo(TOOLINFO *pti) { CFillWindow::GetSharedTooltipInfo(pti); // Since the child covers this whole area, we need to change the HWND to // hook HWND hwnd = GetChild(); // HACKHACK georgep: Setting the tooltip on the first child of the combo // box, which should be the edit control if (NULL != hwnd) { hwnd = GetFirstChild(hwnd); if (NULL != hwnd) { pti->hwnd = hwnd; } } }