4 * Copyright 1998, 1999 Eric Kohl
7 * This is just a dummy control. An author is needed! Any volunteers?
8 * I will only improve this control once in a while.
9 * Eric <ekohl@abo.rhein-zeitung.de>
13 * - All notifications.
16 * - should include "combo.h"
18 * Changes Guy Albertelli <galberte@neo.lrun.com>
19 * 1. Implemented message CB_SETITEMHEIGHT
20 * 2. Implemented message WM_WINDOWPOSCHANGING
21 * 3. Implemented message WM_MEASUREITEM
22 * 4. Add code to WM_CREATE processing to set font of COMBOBOX and
23 * issue the CB_SETITEMHEIGHT to start the correct sizing process.
24 * The above 4 changes allow the window rect for the comboboxex
25 * to be set properly, which in turn allows the height of the
26 * rebar control it *may* be imbeded in to be correct.
27 * 5. Rewrite CBEM_INSERTITEMA to save the information.
28 * 6. Implemented message WM_DRAWITEM. The code will handle images
29 * but not "overlays" yet.
30 * 7. Fixed code in CBEM_SETIMAGELIST to resize control.
31 * 8. Add debugging code.
33 * Test vehicals were the ControlSpy modules (rebar.exe and comboboxex.exe)
38 #include "wine/winestring.h"
40 #include "debugtools.h"
41 #include "wine/unicode.h"
43 DEFAULT_DEBUG_CHANNEL(comboex
);
44 DECLARE_DEBUG_CHANNEL(message
);
60 /* ComboBoxEx structure */
67 INT nb_items
; /* Number of items */
68 CBE_ITEMDATA
*items
; /* Array of items */
71 #define ID_CB_EDIT 1001
73 /* Height in pixels of control over the amount of the selected font */
76 /* Indent amount per MS documentation */
79 /* Offset in pixels from left side for start of image or text */
80 #define CBE_STARTOFFSET 6
82 /* Offset between image and text */
85 #define COMBOEX_GetInfoPtr(wndPtr) ((COMBOEX_INFO *)GetWindowLongA (hwnd, 0))
89 COMBOEX_DumpItem (CBE_ITEMDATA
*item
)
91 if (TRACE_ON(comboex
)){
92 TRACE("item %p - mask=%08x, pszText=%p, cchTM=%d, iImage=%d\n",
93 item
, item
->mask
, item
->pszText
, item
->cchTextMax
,
95 TRACE("item %p - iSelectedImage=%d, iOverlay=%d, iIndent=%d, lParam=%08lx\n",
96 item
, item
->iSelectedImage
, item
->iOverlay
, item
->iIndent
, item
->lParam
);
101 inline static LRESULT
102 COMBOEX_Forward (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
104 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
106 FIXME("(0x%x 0x%x 0x%lx): stub\n", uMsg
, wParam
, lParam
);
108 if (infoPtr
->hwndCombo
)
109 return SendMessageA (infoPtr
->hwndCombo
, uMsg
, wParam
, lParam
);
116 COMBOEX_ReSize (HWND hwnd
, COMBOEX_INFO
*infoPtr
)
124 mydc
= GetDC (0); /* why the entire screen???? */
125 nfont
= SendMessageA (infoPtr
->hwndCombo
, WM_GETFONT
, 0, 0);
126 ofont
= (HFONT
) SelectObject (mydc
, nfont
);
127 GetTextExtentPointA (mydc
, "A", 1, &mysize
);
128 SelectObject (mydc
, ofont
);
130 cy
= mysize
.cy
+ CBE_EXTRA
;
132 ImageList_GetImageInfo(infoPtr
->himl
, 0, &iinfo
);
133 cy
= max (iinfo
.rcImage
.bottom
- iinfo
.rcImage
.top
, cy
);
135 TRACE("selected font hwnd=%08x, height=%d\n", nfont
, cy
);
136 SendMessageA (hwnd
, CB_SETITEMHEIGHT
, (WPARAM
) -1, (LPARAM
) cy
);
137 if (infoPtr
->hwndCombo
)
138 SendMessageA (infoPtr
->hwndCombo
, CB_SETITEMHEIGHT
,
139 (WPARAM
) 0, (LPARAM
) cy
);
143 /* *** CBEM_xxx message support *** */
146 /* << COMBOEX_DeleteItem >> */
149 inline static LRESULT
150 COMBOEX_GetComboControl (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
152 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
156 return (LRESULT
)infoPtr
->hwndCombo
;
160 inline static LRESULT
161 COMBOEX_GetEditControl (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
163 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
165 if ((GetWindowLongA (hwnd
, GWL_STYLE
) & CBS_DROPDOWNLIST
) != CBS_DROPDOWN
)
168 TRACE("-- 0x%x\n", GetDlgItem (infoPtr
->hwndCombo
, ID_CB_EDIT
));
170 return (LRESULT
)GetDlgItem (infoPtr
->hwndCombo
, ID_CB_EDIT
);
174 inline static LRESULT
175 COMBOEX_GetExtendedStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
177 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
179 return (LRESULT
)infoPtr
->dwExtStyle
;
183 inline static LRESULT
184 COMBOEX_GetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
186 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
188 TRACE("(0x%08x 0x%08lx)\n", wParam
, lParam
);
190 return (LRESULT
)infoPtr
->himl
;
194 /* << COMBOEX_GetItemA >> */
196 /* << COMBOEX_GetItemW >> */
198 /* << COMBOEX_GetUniCodeFormat >> */
200 /* << COMBOEX_HasEditChanged >> */
204 COMBOEX_InsertItemA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
206 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
207 COMBOBOXEXITEMA
*cit
= (COMBOBOXEXITEMA
*) lParam
;
212 /* get real index of item to insert */
214 if (index
== -1) index
= infoPtr
->nb_items
;
215 if (index
> infoPtr
->nb_items
) index
= infoPtr
->nb_items
;
217 /* get space and chain it in */
218 item
= (CBE_ITEMDATA
*)COMCTL32_Alloc (sizeof (CBE_ITEMDATA
));
220 item
->pszText
= NULL
;
222 /* locate position to insert new item in */
223 if (index
== infoPtr
->nb_items
) {
224 /* fast path for iItem = -1 */
225 item
->next
= infoPtr
->items
;
226 infoPtr
->items
= item
;
229 int i
= infoPtr
->nb_items
-1;
230 CBE_ITEMDATA
*moving
= infoPtr
->items
;
232 while (i
> index
&& moving
) {
233 moving
= (CBE_ITEMDATA
*)moving
->next
;
236 FIXME("COMBOBOXEX item structures broken. Please report!\n");
240 item
->next
= moving
->next
;
244 /* fill in our hidden item structure */
245 item
->mask
= cit
->mask
;
246 if (item
->mask
& CBEIF_TEXT
) {
252 len
= MultiByteToWideChar (CP_ACP
, 0, str
, -1, NULL
, 0);
254 item
->pszText
= (LPWSTR
)COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
255 MultiByteToWideChar (CP_ACP
, 0, str
, -1, item
->pszText
, len
);
257 item
->cchTextMax
= cit
->cchTextMax
;
259 if (item
->mask
& CBEIF_IMAGE
)
260 item
->iImage
= cit
->iImage
;
261 if (item
->mask
& CBEIF_SELECTEDIMAGE
)
262 item
->iSelectedImage
= cit
->iSelectedImage
;
263 if (item
->mask
& CBEIF_OVERLAY
)
264 item
->iOverlay
= cit
->iOverlay
;
265 if (item
->mask
& CBEIF_INDENT
)
266 item
->iIndent
= cit
->iIndent
;
267 if (item
->mask
& CBEIF_LPARAM
)
268 item
->lParam
= cit
->lParam
;
271 COMBOEX_DumpItem (item
);
273 SendMessageA (infoPtr
->hwndCombo
, CB_INSERTSTRING
,
274 (WPARAM
)cit
->iItem
, (LPARAM
)item
);
282 COMBOEX_InsertItemW (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
284 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
285 COMBOBOXEXITEMW
*cit
= (COMBOBOXEXITEMW
*) lParam
;
289 /* get real index of item to insert */
291 if (index
== -1) index
= infoPtr
->nb_items
;
292 if (index
> infoPtr
->nb_items
) index
= infoPtr
->nb_items
;
294 /* get space and chain it in */
295 item
= (CBE_ITEMDATA
*)COMCTL32_Alloc (sizeof (CBE_ITEMDATA
));
297 item
->pszText
= NULL
;
299 /* locate position to insert new item in */
300 if (index
== infoPtr
->nb_items
) {
301 /* fast path for iItem = -1 */
302 item
->next
= infoPtr
->items
;
303 infoPtr
->items
= item
;
306 INT i
= infoPtr
->nb_items
-1;
307 CBE_ITEMDATA
*moving
= infoPtr
->items
;
309 while ((i
> index
) && moving
) {
310 moving
= (CBE_ITEMDATA
*)moving
->next
;
314 FIXME("COMBOBOXEX item structures broken. Please report!\n");
318 item
->next
= moving
->next
;
322 /* fill in our hidden item structure */
323 item
->mask
= cit
->mask
;
324 if (item
->mask
& CBEIF_TEXT
) {
329 if (!str
) str
= (LPWSTR
) L
"";
332 item
->pszText
= (LPWSTR
)COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
333 strcpyW (item
->pszText
, str
);
335 item
->cchTextMax
= cit
->cchTextMax
;
337 if (item
->mask
& CBEIF_IMAGE
)
338 item
->iImage
= cit
->iImage
;
339 if (item
->mask
& CBEIF_SELECTEDIMAGE
)
340 item
->iSelectedImage
= cit
->iSelectedImage
;
341 if (item
->mask
& CBEIF_OVERLAY
)
342 item
->iOverlay
= cit
->iOverlay
;
343 if (item
->mask
& CBEIF_INDENT
)
344 item
->iIndent
= cit
->iIndent
;
345 if (item
->mask
& CBEIF_LPARAM
)
346 item
->lParam
= cit
->lParam
;
349 COMBOEX_DumpItem (item
);
351 SendMessageA (infoPtr
->hwndCombo
, CB_INSERTSTRING
,
352 (WPARAM
)cit
->iItem
, (LPARAM
)item
);
360 COMBOEX_SetExtendedStyle (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
362 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
365 TRACE("(0x%08x 0x%08lx)\n", wParam
, lParam
);
367 dwTemp
= infoPtr
->dwExtStyle
;
370 infoPtr
->dwExtStyle
= (infoPtr
->dwExtStyle
& ~(DWORD
)wParam
) | (DWORD
)lParam
;
373 infoPtr
->dwExtStyle
= (DWORD
)lParam
;
375 /* FIXME: repaint?? */
377 return (LRESULT
)dwTemp
;
381 inline static LRESULT
382 COMBOEX_SetImageList (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
384 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
387 TRACE("(0x%08x 0x%08lx)\n", wParam
, lParam
);
389 himlTemp
= infoPtr
->himl
;
390 infoPtr
->himl
= (HIMAGELIST
)lParam
;
392 COMBOEX_ReSize (hwnd
, infoPtr
);
393 InvalidateRect (hwnd
, NULL
, TRUE
);
395 return (LRESULT
)himlTemp
;
400 COMBOEX_SetItemA (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
402 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
403 COMBOBOXEXITEMA
*cit
= (COMBOBOXEXITEMA
*) lParam
;
408 /* get real index of item to insert */
411 FIXME("NYI setting data for item in edit control\n");
415 /* if item number requested does not exist then return failure */
416 if ((index
> infoPtr
->nb_items
) || (index
< 0)) return 0;
418 /* find the item in the list */
419 item
= infoPtr
->items
;
420 i
= infoPtr
->nb_items
- 1;
421 while (item
&& (i
> index
)) {
422 item
= (CBE_ITEMDATA
*)item
->next
;
425 if (!item
|| (i
!= index
)) {
426 FIXME("COMBOBOXEX item structures broken. Please report!\n");
430 /* add/change stuff to the internal item structure */
431 item
->mask
|= cit
->mask
;
432 if (cit
->mask
& CBEIF_TEXT
) {
438 len
= MultiByteToWideChar (CP_ACP
, 0, str
, -1, NULL
, 0);
440 item
->pszText
= (LPWSTR
)COMCTL32_Alloc ((len
+ 1)*sizeof(WCHAR
));
441 MultiByteToWideChar (CP_ACP
, 0, str
, -1, item
->pszText
, len
);
443 item
->cchTextMax
= cit
->cchTextMax
;
445 if (cit
->mask
& CBEIF_IMAGE
)
446 item
->iImage
= cit
->iImage
;
447 if (cit
->mask
& CBEIF_SELECTEDIMAGE
)
448 item
->iSelectedImage
= cit
->iSelectedImage
;
449 if (cit
->mask
& CBEIF_OVERLAY
)
450 item
->iOverlay
= cit
->iOverlay
;
451 if (cit
->mask
& CBEIF_INDENT
)
452 item
->iIndent
= cit
->iIndent
;
453 if (cit
->mask
& CBEIF_LPARAM
)
454 cit
->lParam
= cit
->lParam
;
456 COMBOEX_DumpItem (item
);
462 /* << COMBOEX_SetItemW >> */
464 /* << COMBOEX_SetUniCodeFormat >> */
467 /* *** CB_xxx message support *** */
471 COMBOEX_SetItemHeight (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
473 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
474 RECT cb_wrect
, cbx_wrect
, cbx_crect
;
478 /* First, lets forward the message to the normal combo control
479 just like Windows. */
480 if (infoPtr
->hwndCombo
)
481 SendMessageA (infoPtr
->hwndCombo
, CB_SETITEMHEIGHT
, wParam
, lParam
);
484 GetWindowRect (infoPtr
->hwndCombo
, &cb_wrect
);
485 GetWindowRect (hwnd
, &cbx_wrect
);
486 GetClientRect (hwnd
, &cbx_crect
);
487 /* the height of comboex as height of the combo + comboex border */
488 height
= cb_wrect
.bottom
-cb_wrect
.top
489 + cbx_wrect
.bottom
-cbx_wrect
.top
490 - (cbx_crect
.bottom
-cbx_crect
.top
);
491 TRACE("EX window=(%d,%d)-(%d,%d), client=(%d,%d)-(%d,%d)\n",
492 cbx_wrect
.left
, cbx_wrect
.top
, cbx_wrect
.right
, cbx_wrect
.bottom
,
493 cbx_crect
.left
, cbx_crect
.top
, cbx_crect
.right
, cbx_crect
.bottom
);
494 TRACE("CB window=(%d,%d)-(%d,%d), EX setting=(0,0)-(%d,%d)\n",
495 cb_wrect
.left
, cb_wrect
.top
, cb_wrect
.right
, cb_wrect
.bottom
,
496 cbx_wrect
.right
-cbx_wrect
.left
, height
);
497 SetWindowPos (hwnd
, HWND_TOP
, 0, 0,
498 cbx_wrect
.right
-cbx_wrect
.left
,
500 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_NOMOVE
);
501 /* *** end new *** */
507 /* *** WM_xxx message support *** */
511 COMBOEX_Create (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
513 LPCREATESTRUCTA cs
= (LPCREATESTRUCTA
) lParam
;
514 COMBOEX_INFO
*infoPtr
;
518 /* allocate memory for info structure */
519 infoPtr
= (COMBOEX_INFO
*)COMCTL32_Alloc (sizeof(COMBOEX_INFO
));
520 if (infoPtr
== NULL
) {
521 ERR("could not allocate info memory!\n");
524 infoPtr
->items
= NULL
;
525 infoPtr
->nb_items
= 0;
527 SetWindowLongA (hwnd
, 0, (DWORD
)infoPtr
);
530 /* initialize info structure */
533 /* create combo box */
534 dwComboStyle
= GetWindowLongA (hwnd
, GWL_STYLE
) &
535 (CBS_SIMPLE
|CBS_DROPDOWN
|CBS_DROPDOWNLIST
|WS_CHILD
);
537 infoPtr
->hwndCombo
= CreateWindowA ("ComboBox", "",
538 /* following line added to match native */
539 WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_VSCROLL
| CBS_NOINTEGRALHEIGHT
|
540 /* was base and is necessary */
541 WS_CHILD
| WS_VISIBLE
| CBS_OWNERDRAWFIXED
| dwComboStyle
,
542 cs
->y
, cs
->x
, cs
->cx
, cs
->cy
, hwnd
, (HMENU
)0,
543 GetWindowLongA (hwnd
, GWL_HINSTANCE
), NULL
);
546 SystemParametersInfoA (SPI_GETICONTITLELOGFONT
, sizeof(mylogfont
), &mylogfont
, 0);
547 infoPtr
->font
= CreateFontIndirectA (&mylogfont
);
548 SendMessageA (infoPtr
->hwndCombo
, WM_SETFONT
, (WPARAM
)infoPtr
->font
, 0);
549 COMBOEX_ReSize (hwnd
, infoPtr
);
550 /* *** end new *** */
556 inline static LRESULT
557 COMBOEX_DrawItem (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
559 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
560 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)lParam
;
567 UINT xioff
= 0; /* size and spacer of image if any */
571 if (!IsWindowEnabled(infoPtr
->hwndCombo
)) return 0;
573 item
= (CBE_ITEMDATA
*)SendMessageA (infoPtr
->hwndCombo
, CB_GETITEMDATA
,
574 (WPARAM
)dis
->itemID
, 0);
575 if (!TRACE_ON(message
)) {
576 TRACE("DRAWITEMSTRUCT: CtlType=0x%08x CtlID=0x%08x\n",
577 dis
->CtlType
, dis
->CtlID
);
578 TRACE("itemID=0x%08x itemAction=0x%08x itemState=0x%08x\n",
579 dis
->itemID
, dis
->itemAction
, dis
->itemState
);
580 TRACE("hWnd=0x%04x hDC=0x%04x (%d,%d)-(%d,%d) itemData=0x%08lx\n",
581 dis
->hwndItem
, dis
->hDC
, dis
->rcItem
.left
,
582 dis
->rcItem
.top
, dis
->rcItem
.right
, dis
->rcItem
.bottom
,
585 COMBOEX_DumpItem (item
);
587 xbase
= CBE_STARTOFFSET
;
588 if (item
->mask
& CBEIF_INDENT
)
589 xbase
+= (item
->iIndent
* CBE_INDENT
);
590 if (item
->mask
& CBEIF_IMAGE
) {
591 ImageList_GetImageInfo(infoPtr
->himl
, item
->iImage
, &iinfo
);
592 xioff
= (iinfo
.rcImage
.right
- iinfo
.rcImage
.left
+ CBE_SEP
);
595 switch (dis
->itemAction
) {
597 if (dis
->itemState
& ODS_SELECTED
/*1*/) {
598 if ((item
->mask
& CBEIF_TEXT
) && item
->pszText
) {
599 len
= strlenW (item
->pszText
);
600 GetTextExtentPointW (dis
->hDC
, item
->pszText
, len
, &txtsize
);
601 rect
.left
= xbase
+ xioff
- 1;
602 rect
.top
= dis
->rcItem
.top
- 1 +
603 (dis
->rcItem
.bottom
- dis
->rcItem
.top
- txtsize
.cy
) / 2;
604 rect
.right
= rect
.left
+ txtsize
.cx
+ 2;
605 rect
.bottom
= rect
.top
+ txtsize
.cy
+ 2;
606 TRACE("drawing item %d focus, rect=(%d,%d)-(%d,%d)\n",
607 dis
->itemID
, rect
.left
, rect
.top
,
608 rect
.right
, rect
.bottom
);
609 DrawFocusRect(dis
->hDC
, &rect
);
616 if (item
->mask
& CBEIF_IMAGE
) drawimage
= item
->iImage
;
617 if ((dis
->itemState
& ODS_SELECTED
) &&
618 (item
->mask
& CBEIF_SELECTEDIMAGE
))
619 drawimage
= item
->iSelectedImage
;
620 if (drawimage
!= -1) {
621 ImageList_Draw (infoPtr
->himl
, drawimage
, dis
->hDC
,
622 xbase
, dis
->rcItem
.top
,
623 (dis
->itemState
& ODS_SELECTED
) ?
624 ILD_SELECTED
: ILD_NORMAL
);
626 if ((item
->mask
& CBEIF_TEXT
) && item
->pszText
) {
627 len
= strlenW (item
->pszText
);
628 GetTextExtentPointW (dis
->hDC
, item
->pszText
, len
, &txtsize
);
629 nbkc
= GetSysColor ((dis
->itemState
& ODS_SELECTED
) ?
630 COLOR_HIGHLIGHT
: COLOR_WINDOW
);
631 SetBkColor (dis
->hDC
, nbkc
);
632 ntxc
= GetSysColor ((dis
->itemState
& ODS_SELECTED
) ?
633 COLOR_HIGHLIGHTTEXT
: COLOR_WINDOWTEXT
);
634 SetTextColor (dis
->hDC
, ntxc
);
636 y
= dis
->rcItem
.top
+
637 (dis
->rcItem
.bottom
- dis
->rcItem
.top
- txtsize
.cy
) / 2;
639 rect
.right
= x
+ txtsize
.cx
;
641 rect
.bottom
= y
+ txtsize
.cy
;
642 TRACE("drawing item %d text, rect=(%d,%d)-(%d,%d)\n",
643 dis
->itemID
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
644 ExtTextOutW (dis
->hDC
, x
, y
, ETO_OPAQUE
| ETO_CLIPPED
,
645 &rect
, item
->pszText
, len
, 0);
646 if (dis
->itemState
& ODS_FOCUS
) {
651 TRACE("drawing item %d focus, rect=(%d,%d)-(%d,%d)\n",
652 dis
->itemID
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
653 DrawFocusRect (dis
->hDC
, &rect
);
658 FIXME("unknown action hwnd=%08x, wparam=%08x, lparam=%08lx, action=%d\n",
659 hwnd
, wParam
, lParam
, dis
->itemAction
);
667 COMBOEX_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
669 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
671 if (infoPtr
->hwndCombo
)
672 DestroyWindow (infoPtr
->hwndCombo
);
674 if (infoPtr
->items
) {
675 CBE_ITEMDATA
*this, *next
;
677 this = infoPtr
->items
;
679 next
= (CBE_ITEMDATA
*)this->next
;
680 if ((this->mask
& CBEIF_TEXT
) && this->pszText
)
681 COMCTL32_Free (this->pszText
);
682 COMCTL32_Free (this);
687 DeleteObject (infoPtr
->font
);
689 /* free comboex info data */
690 COMCTL32_Free (infoPtr
);
691 SetWindowLongA (hwnd
, 0, 0);
697 COMBOEX_MeasureItem (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
699 /*COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);*/
700 MEASUREITEMSTRUCT
*mis
= (MEASUREITEMSTRUCT
*) lParam
;
705 GetTextExtentPointA (hdc
, "W", 1, &mysize
);
707 mis
->itemHeight
= mysize
.cy
+ CBE_EXTRA
;
709 TRACE("adjusted height hwnd=%08x, height=%d\n",
710 hwnd
, mis
->itemHeight
);
717 COMBOEX_Size (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
719 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
722 GetClientRect (hwnd
, &rect
);
724 MoveWindow (infoPtr
->hwndCombo
, 0, 0, rect
.right
-rect
.left
,
725 rect
.bottom
- rect
.top
, TRUE
);
732 COMBOEX_WindowPosChanging (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
734 COMBOEX_INFO
*infoPtr
= COMBOEX_GetInfoPtr (hwnd
);
736 RECT cbx_wrect
, cbx_crect
, cb_wrect
;
738 WINDOWPOS
*wp
= (WINDOWPOS
*)lParam
;
740 ret
= DefWindowProcA (hwnd
, WM_WINDOWPOSCHANGING
, wParam
, lParam
);
741 GetWindowRect (hwnd
, &cbx_wrect
);
742 GetClientRect (hwnd
, &cbx_crect
);
743 GetWindowRect (infoPtr
->hwndCombo
, &cb_wrect
);
745 /* width is winpos value + border width of comboex */
747 + cbx_wrect
.right
-cbx_wrect
.left
748 - (cbx_crect
.right
- cbx_crect
.left
);
750 TRACE("EX window=(%d,%d)-(%d,%d), client=(%d,%d)-(%d,%d)\n",
751 cbx_wrect
.left
, cbx_wrect
.top
, cbx_wrect
.right
, cbx_wrect
.bottom
,
752 cbx_crect
.left
, cbx_crect
.top
, cbx_crect
.right
, cbx_crect
.bottom
);
753 TRACE("CB window=(%d,%d)-(%d,%d), EX setting=(0,0)-(%d,%d)\n",
754 cb_wrect
.left
, cb_wrect
.top
, cb_wrect
.right
, cb_wrect
.bottom
,
755 width
, cb_wrect
.bottom
-cb_wrect
.top
);
757 SetWindowPos (infoPtr
->hwndCombo
, HWND_TOP
, 0, 0,
759 cb_wrect
.bottom
-cb_wrect
.top
,
766 static LRESULT WINAPI
767 COMBOEX_WindowProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
769 TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx\n", hwnd
, uMsg
, wParam
, lParam
);
770 if (!COMBOEX_GetInfoPtr (hwnd
) && (uMsg
!= WM_CREATE
))
771 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
775 /* case CBEM_DELETEITEM: */
777 case CBEM_GETCOMBOCONTROL
:
778 return COMBOEX_GetComboControl (hwnd
, wParam
, lParam
);
780 case CBEM_GETEDITCONTROL
:
781 return COMBOEX_GetEditControl (hwnd
, wParam
, lParam
);
783 case CBEM_GETEXTENDEDSTYLE
:
784 return COMBOEX_GetExtendedStyle (hwnd
, wParam
, lParam
);
786 case CBEM_GETIMAGELIST
:
787 return COMBOEX_GetImageList (hwnd
, wParam
, lParam
);
789 /* case CBEM_GETITEMA:
791 case CBEM_GETUNICODEFORMAT:
792 case CBEM_HASEDITCHANGED:
795 case CBEM_INSERTITEMA
:
796 return COMBOEX_InsertItemA (hwnd
, wParam
, lParam
);
798 case CBEM_INSERTITEMW
:
799 return COMBOEX_InsertItemW (hwnd
, wParam
, lParam
);
801 case CBEM_SETEXTENDEDSTYLE
:
802 return COMBOEX_SetExtendedStyle (hwnd
, wParam
, lParam
);
804 case CBEM_SETIMAGELIST
:
805 return COMBOEX_SetImageList (hwnd
, wParam
, lParam
);
808 return COMBOEX_SetItemA (hwnd
, wParam
, lParam
);
810 /* case CBEM_SETITEMW:
811 case CBEM_SETUNICODEFORMAT:
814 case CB_DELETESTRING
:
815 case CB_FINDSTRINGEXACT
:
818 case CB_GETDROPPEDCONTROLRECT
:
819 case CB_GETDROPPEDSTATE
:
821 case CB_GETITEMHEIGHT
:
823 case CB_GETLBTEXTLEN
:
824 case CB_GETEXTENDEDUI
:
826 case CB_RESETCONTENT
:
827 case CB_SELECTSTRING
:
829 case CB_SETDROPPEDWIDTH
:
830 case CB_SETEXTENDEDUI
:
832 case CB_SHOWDROPDOWN
:
833 return COMBOEX_Forward (hwnd
, uMsg
, wParam
, lParam
);
835 case CB_SETITEMHEIGHT
:
836 return COMBOEX_SetItemHeight (hwnd
, wParam
, lParam
);
840 return COMBOEX_Create (hwnd
, wParam
, lParam
);
843 return COMBOEX_DrawItem (hwnd
, wParam
, lParam
);
846 return COMBOEX_Destroy (hwnd
, wParam
, lParam
);
849 return COMBOEX_MeasureItem (hwnd
, wParam
, lParam
);
852 return COMBOEX_Size (hwnd
, wParam
, lParam
);
854 case WM_WINDOWPOSCHANGING
:
855 return COMBOEX_WindowPosChanging (hwnd
, wParam
, lParam
);
859 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
860 uMsg
, wParam
, lParam
);
861 return DefWindowProcA (hwnd
, uMsg
, wParam
, lParam
);
868 COMBOEX_Register (void)
872 ZeroMemory (&wndClass
, sizeof(WNDCLASSA
));
873 wndClass
.style
= CS_GLOBALCLASS
;
874 wndClass
.lpfnWndProc
= (WNDPROC
)COMBOEX_WindowProc
;
875 wndClass
.cbClsExtra
= 0;
876 wndClass
.cbWndExtra
= sizeof(COMBOEX_INFO
*);
877 wndClass
.hCursor
= LoadCursorA (0, IDC_ARROWA
);
878 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
879 wndClass
.lpszClassName
= WC_COMBOBOXEXA
;
881 RegisterClassA (&wndClass
);
886 COMBOEX_Unregister (void)
888 UnregisterClassA (WC_COMBOBOXEXA
, (HINSTANCE
)NULL
);