/* * ComboBoxEx control * * Copyright 1998, 1999 Eric Kohl * * NOTES * This is just a dummy control. An author is needed! Any volunteers? * I will only improve this control once in a while. * Eric * * TODO: * - All messages. * - All notifications. * * FIXME: * - should include "combo.h" */ #include "winbase.h" #include "commctrl.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(comboex); typedef struct { HIMAGELIST himl; HWND hwndCombo; DWORD dwExtStyle; } COMBOEX_INFO; #define ID_CB_EDIT 1001 #define COMBOEX_GetInfoPtr(wndPtr) ((COMBOEX_INFO *)GetWindowLongA (hwnd, 0)) /* << COMBOEX_DeleteItem >> */ inline static LRESULT COMBOEX_GetComboControl (HWND hwnd, WPARAM wParam, LPARAM lParam) { COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); TRACE("\n"); return (LRESULT)infoPtr->hwndCombo; } inline static LRESULT COMBOEX_GetEditControl (HWND hwnd, WPARAM wParam, LPARAM lParam) { COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); if ((GetWindowLongA (hwnd, GWL_STYLE) & CBS_DROPDOWNLIST) != CBS_DROPDOWN) return 0; TRACE("-- 0x%x\n", GetDlgItem (infoPtr->hwndCombo, ID_CB_EDIT)); return (LRESULT)GetDlgItem (infoPtr->hwndCombo, ID_CB_EDIT); } inline static LRESULT COMBOEX_GetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam) { COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); return (LRESULT)infoPtr->dwExtStyle; } inline static LRESULT COMBOEX_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam) { COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); TRACE("(0x%08x 0x%08lx)\n", wParam, lParam); return (LRESULT)infoPtr->himl; } static LRESULT COMBOEX_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam) { /* COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); */ FIXME("(0x%08x 0x%08lx)\n", wParam, lParam); return -1; } static LRESULT COMBOEX_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam) { COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); DWORD dwTemp; TRACE("(0x%08x 0x%08lx)\n", wParam, lParam); dwTemp = infoPtr->dwExtStyle; if ((DWORD)wParam) { infoPtr->dwExtStyle = (infoPtr->dwExtStyle & ~(DWORD)wParam) | (DWORD)lParam; } else infoPtr->dwExtStyle = (DWORD)lParam; /* FIXME: repaint?? */ return (LRESULT)dwTemp; } inline static LRESULT COMBOEX_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam) { COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); HIMAGELIST himlTemp; TRACE("(0x%08x 0x%08lx)\n", wParam, lParam); himlTemp = infoPtr->himl; infoPtr->himl = (HIMAGELIST)lParam; return (LRESULT)himlTemp; } static LRESULT COMBOEX_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam) { /* COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); */ FIXME("(%p): stub\n", (LPVOID)lParam); return TRUE; } /* << COMBOEX_SetItem32W >> */ inline static LRESULT COMBOEX_Forward (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); FIXME("(0x%x 0x%x 0x%lx): stub\n", uMsg, wParam, lParam); if (infoPtr->hwndCombo) return SendMessageA (infoPtr->hwndCombo, uMsg, wParam, lParam); return 0; } static LRESULT COMBOEX_Create (HWND hwnd, WPARAM wParam, LPARAM lParam) { COMBOEX_INFO *infoPtr; DWORD dwComboStyle; /* allocate memory for info structure */ infoPtr = (COMBOEX_INFO *)COMCTL32_Alloc (sizeof(COMBOEX_INFO)); if (infoPtr == NULL) { ERR("could not allocate info memory!\n"); return 0; } SetWindowLongA (hwnd, 0, (DWORD)infoPtr); /* initialize info structure */ /* create combo box */ dwComboStyle = GetWindowLongA (hwnd, GWL_STYLE) & (CBS_SIMPLE|CBS_DROPDOWN|CBS_DROPDOWNLIST|WS_CHILD); infoPtr->hwndCombo = CreateWindowA ("ComboBox", "", WS_CHILD | WS_VISIBLE | CBS_OWNERDRAWFIXED | dwComboStyle, 0, 0, 0, 0, hwnd, (HMENU)1, GetWindowLongA (hwnd, GWL_HINSTANCE), NULL); return 0; } static LRESULT COMBOEX_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam) { COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); if (infoPtr->hwndCombo) DestroyWindow (infoPtr->hwndCombo); /* free comboex info data */ COMCTL32_Free (infoPtr); SetWindowLongA (hwnd, 0, 0); return 0; } static LRESULT COMBOEX_Size (HWND hwnd, WPARAM wParam, LPARAM lParam) { COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); RECT rect; GetClientRect (hwnd, &rect); MoveWindow (infoPtr->hwndCombo, 0, 0, rect.right -rect.left, rect.bottom - rect.top, TRUE); return 0; } static LRESULT WINAPI COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx\n", hwnd, uMsg, wParam, lParam); if (!COMBOEX_GetInfoPtr (hwnd) && (uMsg != WM_CREATE)) return DefWindowProcA (hwnd, uMsg, wParam, lParam); switch (uMsg) { /* case CBEM_DELETEITEM: */ case CBEM_GETCOMBOCONTROL: return COMBOEX_GetComboControl (hwnd, wParam, lParam); case CBEM_GETEDITCONTROL: return COMBOEX_GetEditControl (hwnd, wParam, lParam); case CBEM_GETEXTENDEDSTYLE: return COMBOEX_GetExtendedStyle (hwnd, wParam, lParam); case CBEM_GETIMAGELIST: return COMBOEX_GetImageList (hwnd, wParam, lParam); /* case CBEM_GETITEM32A: case CBEM_GETITEM32W: case CBEM_GETUNICODEFORMAT: case CBEM_HASEDITCHANGED: */ case CBEM_INSERTITEMA: return COMBOEX_InsertItemA (hwnd, wParam, lParam); /* case CBEM_INSERTITEM32W: */ case CBEM_SETEXTENDEDSTYLE: return COMBOEX_SetExtendedStyle (hwnd, wParam, lParam); case CBEM_SETIMAGELIST: return COMBOEX_SetImageList (hwnd, wParam, lParam); case CBEM_SETITEMA: return COMBOEX_SetItemA (hwnd, wParam, lParam); /* case CBEM_SETITEM32W: case CBEM_SETUNICODEFORMAT: */ case CB_DELETESTRING: case CB_FINDSTRINGEXACT: case CB_GETCOUNT: case CB_GETCURSEL: case CB_GETDROPPEDCONTROLRECT: case CB_GETDROPPEDSTATE: case CB_GETITEMDATA: case CB_GETITEMHEIGHT: case CB_GETLBTEXT: case CB_GETLBTEXTLEN: case CB_GETEXTENDEDUI: case CB_LIMITTEXT: case CB_RESETCONTENT: case CB_SELECTSTRING: case CB_SETCURSEL: case CB_SETDROPPEDWIDTH: case CB_SETEXTENDEDUI: case CB_SETITEMDATA: case CB_SETITEMHEIGHT: case CB_SHOWDROPDOWN: return COMBOEX_Forward (hwnd, uMsg, wParam, lParam); case WM_CREATE: return COMBOEX_Create (hwnd, wParam, lParam); case WM_DESTROY: return COMBOEX_Destroy (hwnd, wParam, lParam); case WM_SIZE: return COMBOEX_Size (hwnd, wParam, lParam); default: if (uMsg >= WM_USER) ERR("unknown msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, lParam); return DefWindowProcA (hwnd, uMsg, wParam, lParam); } return 0; } VOID COMBOEX_Register (void) { WNDCLASSA wndClass; ZeroMemory (&wndClass, sizeof(WNDCLASSA)); wndClass.style = CS_GLOBALCLASS; wndClass.lpfnWndProc = (WNDPROC)COMBOEX_WindowProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = sizeof(COMBOEX_INFO *); wndClass.hCursor = LoadCursorA (0, IDC_ARROWA); wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wndClass.lpszClassName = WC_COMBOBOXEXA; RegisterClassA (&wndClass); } VOID COMBOEX_Unregister (void) { UnregisterClassA (WC_COMBOBOXEXA, (HINSTANCE)NULL); }