ReactOS  0.4.15-dev-4873-gb671b1c
combo.c
Go to the documentation of this file.
1 /*
2  * Combo controls
3  *
4  * Copyright 1997 Alex Korobka
5  * Copyright (c) 2005 by Frank Richter
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  *
21  */
22 
23 #include <stdarg.h>
24 #include <string.h>
25 
26 #define OEMRESOURCE
27 
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wingdi.h"
31 #include "winuser.h"
32 #include "uxtheme.h"
33 #include "vssym32.h"
34 #include "commctrl.h"
35 #include "wine/unicode.h"
36 #include "wine/debug.h"
37 #include "wine/heap.h"
38 
39 #include "comctl32.h"
40 
42 
43  /* bits in the dwKeyData */
44 #define KEYDATA_ALT 0x2000
45 #define KEYDATA_PREVSTATE 0x4000
46 
47 /*
48  * Additional combo box definitions
49  */
50 
51 #define CB_NOTIFY( lphc, code ) \
52  (SendMessageW((lphc)->owner, WM_COMMAND, \
53  MAKEWPARAM(GetWindowLongPtrW((lphc)->self,GWLP_ID), (code)), (LPARAM)(lphc)->self))
54 
55 #define CB_DISABLED( lphc ) (!IsWindowEnabled((lphc)->self))
56 #define CB_OWNERDRAWN( lphc ) ((lphc)->dwStyle & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE))
57 #define CB_HASSTRINGS( lphc ) ((lphc)->dwStyle & CBS_HASSTRINGS)
58 #define CB_HWND( lphc ) ((lphc)->self)
59 #define CB_GETTYPE( lphc ) ((lphc)->dwStyle & (CBS_DROPDOWNLIST))
60 
61 #define ISWIN31 (LOWORD(GetVersion()) == 0x0a03)
62 
63 /*
64  * Drawing globals
65  */
66 static HBITMAP hComboBmp = 0;
68 
69 /*
70  * Look and feel dependent "constants"
71  */
72 
73 #define COMBO_YBORDERGAP 5
74 #define COMBO_XBORDERSIZE() 2
75 #define COMBO_YBORDERSIZE() 2
76 #define COMBO_EDITBUTTONSPACE() 0
77 #define EDIT_CONTROL_PADDING() 1
78 
79 #define ID_CB_LISTBOX 1000
80 #define ID_CB_EDIT 1001
81 
82 /***********************************************************************
83  * COMBO_Init
84  *
85  * Load combo button bitmap.
86  */
87 static BOOL COMBO_Init(void)
88 {
89  HDC hDC;
90 
91  if( hComboBmp ) return TRUE;
92  if( (hDC = CreateCompatibleDC(0)) )
93  {
94  BOOL bRet = FALSE;
96  {
97  BITMAP bm;
98  HBITMAP hPrevB;
99  RECT r;
100 
101  GetObjectW( hComboBmp, sizeof(bm), &bm );
102  CBitHeight = bm.bmHeight;
103  CBitWidth = bm.bmWidth;
104 
105  TRACE("combo bitmap [%i,%i]\n", CBitWidth, CBitHeight );
106 
107  hPrevB = SelectObject( hDC, hComboBmp);
108  SetRect( &r, 0, 0, CBitWidth, CBitHeight );
109  InvertRect( hDC, &r );
110  SelectObject( hDC, hPrevB );
111  bRet = TRUE;
112  }
113  DeleteDC( hDC );
114  return bRet;
115  }
116  return FALSE;
117 }
118 
119 /***********************************************************************
120  * COMBO_NCCreate
121  */
123 {
124  HEADCOMBO *lphc;
125 
126  if (COMBO_Init() && (lphc = heap_alloc_zero(sizeof(*lphc))))
127  {
128  lphc->self = hwnd;
129  SetWindowLongPtrW( hwnd, 0, (LONG_PTR)lphc );
130 
131  /* some braindead apps do try to use scrollbar/border flags */
132 
133  lphc->dwStyle = style & ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL);
135 
136  /*
137  * We also have to remove the client edge style to make sure
138  * we don't end-up with a non client area.
139  */
142 
144  lphc->dwStyle |= CBS_HASSTRINGS;
146  lphc->wState |= CBF_NOTIFY;
147 
148  TRACE("[%p], style = %08x\n", lphc, lphc->dwStyle );
149  return TRUE;
150  }
151  return FALSE;
152 }
153 
154 /***********************************************************************
155  * COMBO_NCDestroy
156  */
158 {
159  if (lphc)
160  {
161  TRACE("[%p]: freeing storage\n", lphc->self);
162 
163  if ( (CB_GETTYPE(lphc) != CBS_SIMPLE) && lphc->hWndLBox )
164  DestroyWindow( lphc->hWndLBox );
165 
166  SetWindowLongPtrW( lphc->self, 0, 0 );
167  heap_free( lphc );
168  }
169 
170  return 0;
171 }
172 
173 /***********************************************************************
174  * CBGetTextAreaHeight
175  *
176  * This method will calculate the height of the text area of the
177  * combobox.
178  * The height of the text area is set in two ways.
179  * It can be set explicitly through a combobox message or through a
180  * WM_MEASUREITEM callback.
181  * If this is not the case, the height is set to font height + 4px
182  * This height was determined through experimentation.
183  * CBCalcPlacement will add 2*COMBO_YBORDERSIZE pixels for the border
184  */
186  HWND hwnd,
187  LPHEADCOMBO lphc)
188 {
189  INT iTextItemHeight;
190 
191  if( lphc->editHeight ) /* explicitly set height */
192  {
193  iTextItemHeight = lphc->editHeight;
194  }
195  else
196  {
197  TEXTMETRICW tm;
198  HDC hDC = GetDC(hwnd);
199  HFONT hPrevFont = 0;
200  INT baseUnitY;
201 
202  if (lphc->hFont)
203  hPrevFont = SelectObject( hDC, lphc->hFont );
204 
206 
207  baseUnitY = tm.tmHeight;
208 
209  if( hPrevFont )
210  SelectObject( hDC, hPrevFont );
211 
212  ReleaseDC(hwnd, hDC);
213 
214  iTextItemHeight = baseUnitY + 4;
215  }
216 
217  /*
218  * Check the ownerdraw case if we haven't asked the parent the size
219  * of the item yet.
220  */
221  if ( CB_OWNERDRAWN(lphc) &&
222  (lphc->wState & CBF_MEASUREITEM) )
223  {
224  MEASUREITEMSTRUCT measureItem;
225  RECT clientRect;
226  INT originalItemHeight = iTextItemHeight;
227  UINT id = (UINT)GetWindowLongPtrW( lphc->self, GWLP_ID );
228 
229  /*
230  * We use the client rect for the width of the item.
231  */
232  GetClientRect(hwnd, &clientRect);
233 
234  lphc->wState &= ~CBF_MEASUREITEM;
235 
236  /*
237  * Send a first one to measure the size of the text area
238  */
239  measureItem.CtlType = ODT_COMBOBOX;
240  measureItem.CtlID = id;
241  measureItem.itemID = -1;
242  measureItem.itemWidth = clientRect.right;
243  measureItem.itemHeight = iTextItemHeight - 6; /* ownerdrawn cb is taller */
244  measureItem.itemData = 0;
245  SendMessageW(lphc->owner, WM_MEASUREITEM, id, (LPARAM)&measureItem);
246  iTextItemHeight = 6 + measureItem.itemHeight;
247 
248  /*
249  * Send a second one in the case of a fixed ownerdraw list to calculate the
250  * size of the list items. (we basically do this on behalf of the listbox)
251  */
252  if (lphc->dwStyle & CBS_OWNERDRAWFIXED)
253  {
254  measureItem.CtlType = ODT_COMBOBOX;
255  measureItem.CtlID = id;
256  measureItem.itemID = 0;
257  measureItem.itemWidth = clientRect.right;
258  measureItem.itemHeight = originalItemHeight;
259  measureItem.itemData = 0;
260  SendMessageW(lphc->owner, WM_MEASUREITEM, id, (LPARAM)&measureItem);
261  lphc->fixedOwnerDrawHeight = measureItem.itemHeight;
262  }
263 
264  /*
265  * Keep the size for the next time
266  */
267  lphc->editHeight = iTextItemHeight;
268  }
269 
270  return iTextItemHeight;
271 }
272 
273 /***********************************************************************
274  * CBForceDummyResize
275  *
276  * The dummy resize is used for listboxes that have a popup to trigger
277  * a re-arranging of the contents of the combobox and the recalculation
278  * of the size of the "real" control window.
279  */
280 static void CBForceDummyResize(
281  LPHEADCOMBO lphc)
282 {
283  RECT windowRect;
284  int newComboHeight;
285 
286  newComboHeight = CBGetTextAreaHeight(lphc->self,lphc) + 2*COMBO_YBORDERSIZE();
287 
288  GetWindowRect(lphc->self, &windowRect);
289 
290  /*
291  * We have to be careful, resizing a combobox also has the meaning that the
292  * dropped rect will be resized. In this case, we want to trigger a resize
293  * to recalculate layout but we don't want to change the dropped rectangle
294  * So, we pass the height of text area of control as the height.
295  * this will cancel-out in the processing of the WM_WINDOWPOSCHANGING
296  * message.
297  */
298  SetWindowPos( lphc->self,
299  NULL,
300  0, 0,
301  windowRect.right - windowRect.left,
302  newComboHeight,
304 }
305 
306 /***********************************************************************
307  * CBCalcPlacement
308  *
309  * Set up component coordinates given valid lphc->RectCombo.
310  */
311 static void CBCalcPlacement(
312  HWND hwnd,
313  LPHEADCOMBO lphc,
314  LPRECT lprEdit,
315  LPRECT lprButton,
316  LPRECT lprLB)
317 {
318  /*
319  * Again, start with the client rectangle.
320  */
321  GetClientRect(hwnd, lprEdit);
322 
323  /*
324  * Remove the borders
325  */
327 
328  /*
329  * Chop off the bottom part to fit with the height of the text area.
330  */
331  lprEdit->bottom = lprEdit->top + CBGetTextAreaHeight(hwnd, lphc);
332 
333  /*
334  * The button starts the same vertical position as the text area.
335  */
336  CopyRect(lprButton, lprEdit);
337 
338  /*
339  * If the combobox is "simple" there is no button.
340  */
341  if( CB_GETTYPE(lphc) == CBS_SIMPLE )
342  lprButton->left = lprButton->right = lprButton->bottom = 0;
343  else
344  {
345  /*
346  * Let's assume the combobox button is the same width as the
347  * scrollbar button.
348  * size the button horizontally and cut-off the text area.
349  */
350  lprButton->left = lprButton->right - GetSystemMetrics(SM_CXVSCROLL);
351  lprEdit->right = lprButton->left;
352  }
353 
354  /*
355  * In the case of a dropdown, there is an additional spacing between the
356  * text area and the button.
357  */
358  if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
359  {
360  lprEdit->right -= COMBO_EDITBUTTONSPACE();
361  }
362 
363  /*
364  * If we have an edit control, we space it away from the borders slightly.
365  */
366  if (CB_GETTYPE(lphc) != CBS_DROPDOWNLIST)
367  {
369  }
370 
371  /*
372  * Adjust the size of the listbox popup.
373  */
374  if( CB_GETTYPE(lphc) == CBS_SIMPLE )
375  {
376  /*
377  * Use the client rectangle to initialize the listbox rectangle
378  */
379  GetClientRect(hwnd, lprLB);
380 
381  /*
382  * Then, chop-off the top part.
383  */
384  lprLB->top = lprEdit->bottom + COMBO_YBORDERSIZE();
385  }
386  else
387  {
388  /*
389  * Make sure the dropped width is as large as the combobox itself.
390  */
391  if (lphc->droppedWidth < (lprButton->right + COMBO_XBORDERSIZE()))
392  {
393  lprLB->right = lprLB->left + (lprButton->right + COMBO_XBORDERSIZE());
394 
395  /*
396  * In the case of a dropdown, the popup listbox is offset to the right.
397  * so, we want to make sure it's flush with the right side of the
398  * combobox
399  */
400  if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
401  lprLB->right -= COMBO_EDITBUTTONSPACE();
402  }
403  else
404  lprLB->right = lprLB->left + lphc->droppedWidth;
405  }
406 
407  /* don't allow negative window width */
408  if (lprEdit->right < lprEdit->left)
409  lprEdit->right = lprEdit->left;
410 
411  TRACE("\ttext\t= (%s)\n", wine_dbgstr_rect(lprEdit));
412 
413  TRACE("\tbutton\t= (%s)\n", wine_dbgstr_rect(lprButton));
414 
415  TRACE("\tlbox\t= (%s)\n", wine_dbgstr_rect(lprLB));
416 }
417 
418 /***********************************************************************
419  * CBGetDroppedControlRect
420  */
421 static void CBGetDroppedControlRect( LPHEADCOMBO lphc, LPRECT lpRect)
422 {
423  /* In windows, CB_GETDROPPEDCONTROLRECT returns the upper left corner
424  of the combo box and the lower right corner of the listbox */
425 
426  GetWindowRect(lphc->self, lpRect);
427 
428  lpRect->right = lpRect->left + lphc->droppedRect.right - lphc->droppedRect.left;
429  lpRect->bottom = lpRect->top + lphc->droppedRect.bottom - lphc->droppedRect.top;
430 
431 }
432 
433 /***********************************************************************
434  * COMBO_Create
435  */
437 {
438  static const WCHAR clbName[] = {'C','o','m','b','o','L','B','o','x',0};
439  static const WCHAR editName[] = {'E','d','i','t',0};
440 
442  if( !CB_GETTYPE(lphc) ) lphc->dwStyle |= CBS_SIMPLE;
443  if( CB_GETTYPE(lphc) != CBS_DROPDOWNLIST ) lphc->wState |= CBF_EDIT;
444 
445  lphc->owner = hwndParent;
446 
447  /*
448  * The item height and dropped width are not set when the control
449  * is created.
450  */
451  lphc->droppedWidth = lphc->editHeight = 0;
452 
453  /*
454  * The first time we go through, we want to measure the ownerdraw item
455  */
456  lphc->wState |= CBF_MEASUREITEM;
457 
458  /*
459  * Per default the comctl32 version of combo shows up to 30 items
460  */
461  lphc->visibleItems = 30;
462 
463  /* M$ IE 3.01 actually creates (and rapidly destroys) an ownerless combobox */
464 
465  if( lphc->owner || !(style & WS_VISIBLE) )
466  {
467  UINT lbeStyle = 0;
468  UINT lbeExStyle = 0;
469 
470  /*
471  * Initialize the dropped rect to the size of the client area of the
472  * control and then, force all the areas of the combobox to be
473  * recalculated.
474  */
475  GetClientRect( hwnd, &lphc->droppedRect );
476  CBCalcPlacement(hwnd, lphc, &lphc->textRect, &lphc->buttonRect, &lphc->droppedRect );
477 
478  /*
479  * Adjust the position of the popup listbox if it's necessary
480  */
481  if ( CB_GETTYPE(lphc) != CBS_SIMPLE )
482  {
483  lphc->droppedRect.top = lphc->textRect.bottom + COMBO_YBORDERSIZE();
484 
485  /*
486  * If it's a dropdown, the listbox is offset
487  */
488  if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
490 
491  if (lphc->droppedRect.bottom < lphc->droppedRect.top)
492  lphc->droppedRect.bottom = lphc->droppedRect.top;
493  if (lphc->droppedRect.right < lphc->droppedRect.left)
494  lphc->droppedRect.right = lphc->droppedRect.left;
495  MapWindowPoints( hwnd, 0, (LPPOINT)&lphc->droppedRect, 2 );
496  }
497 
498  /* create listbox popup */
499 
502 
503  if( lphc->dwStyle & CBS_SORT )
504  lbeStyle |= LBS_SORT;
505  if( lphc->dwStyle & CBS_HASSTRINGS )
506  lbeStyle |= LBS_HASSTRINGS;
507  if( lphc->dwStyle & CBS_NOINTEGRALHEIGHT )
508  lbeStyle |= LBS_NOINTEGRALHEIGHT;
509  if( lphc->dwStyle & CBS_DISABLENOSCROLL )
510  lbeStyle |= LBS_DISABLENOSCROLL;
511 
512  if( CB_GETTYPE(lphc) == CBS_SIMPLE ) /* child listbox */
513  {
514  lbeStyle |= WS_VISIBLE;
515 
516  /*
517  * In win 95 look n feel, the listbox in the simple combobox has
518  * the WS_EXCLIENTEDGE style instead of the WS_BORDER style.
519  */
520  lbeStyle &= ~WS_BORDER;
521  lbeExStyle |= WS_EX_CLIENTEDGE;
522  }
523  else
524  {
525  lbeExStyle |= (WS_EX_TOPMOST | WS_EX_TOOLWINDOW);
526  }
527 
528  lphc->hWndLBox = CreateWindowExW(lbeExStyle, clbName, NULL, lbeStyle,
529  lphc->droppedRect.left, lphc->droppedRect.top, lphc->droppedRect.right - lphc->droppedRect.left,
532  if( lphc->hWndLBox )
533  {
534  BOOL bEdit = TRUE;
535  lbeStyle = WS_CHILD | WS_VISIBLE | ES_NOHIDESEL | ES_LEFT | ES_COMBO;
536 
537  if( lphc->wState & CBF_EDIT )
538  {
539  if( lphc->dwStyle & CBS_OEMCONVERT )
540  lbeStyle |= ES_OEMCONVERT;
541  if( lphc->dwStyle & CBS_AUTOHSCROLL )
542  lbeStyle |= ES_AUTOHSCROLL;
543  if( lphc->dwStyle & CBS_LOWERCASE )
544  lbeStyle |= ES_LOWERCASE;
545  else if( lphc->dwStyle & CBS_UPPERCASE )
546  lbeStyle |= ES_UPPERCASE;
547 
548  if (!IsWindowEnabled(hwnd)) lbeStyle |= WS_DISABLED;
549 
550  lphc->hWndEdit = CreateWindowExW(0, editName, NULL, lbeStyle,
551  lphc->textRect.left, lphc->textRect.top,
552  lphc->textRect.right - lphc->textRect.left,
553  lphc->textRect.bottom - lphc->textRect.top,
556  if( !lphc->hWndEdit )
557  bEdit = FALSE;
558  }
559 
560  if( bEdit )
561  {
562  if( CB_GETTYPE(lphc) != CBS_SIMPLE )
563  {
564  /* Now do the trick with parent */
566  /*
567  * If the combo is a dropdown, we must resize the control
568  * to fit only the text area and button. To do this,
569  * we send a dummy resize and the WM_WINDOWPOSCHANGING message
570  * will take care of setting the height for us.
571  */
572  CBForceDummyResize(lphc);
573  }
574 
575  TRACE("init done\n");
576  return 0;
577  }
578  ERR("edit control failure.\n");
579  } else ERR("listbox failure.\n");
580  } else ERR("no owner for visible combo.\n");
581 
582  /* CreateWindow() will send WM_NCDESTROY to cleanup */
583 
584  return -1;
585 }
586 
587 /***********************************************************************
588  * CBPaintButton
589  *
590  * Paint combo button (normal, pressed, and disabled states).
591  */
592 static void CBPaintButton( LPHEADCOMBO lphc, HDC hdc, RECT rectButton)
593 {
594  UINT buttonState = DFCS_SCROLLCOMBOBOX;
595 
596  if( lphc->wState & CBF_NOREDRAW )
597  return;
598 
599 
600  if (lphc->wState & CBF_BUTTONDOWN)
601  buttonState |= DFCS_PUSHED;
602 
603  if (CB_DISABLED(lphc))
604  buttonState |= DFCS_INACTIVE;
605 
606  DrawFrameControl(hdc, &rectButton, DFC_SCROLL, buttonState);
607 }
608 
609 /***********************************************************************
610  * COMBO_PrepareColors
611  *
612  * This method will sent the appropriate WM_CTLCOLOR message to
613  * prepare and setup the colors for the combo's DC.
614  *
615  * It also returns the brush to use for the background.
616  */
617 static HBRUSH COMBO_PrepareColors(
618  LPHEADCOMBO lphc,
619  HDC hDC)
620 {
621  HBRUSH hBkgBrush;
622 
623  /*
624  * Get the background brush for this control.
625  */
626  if (CB_DISABLED(lphc))
627  {
628  hBkgBrush = (HBRUSH)SendMessageW(lphc->owner, WM_CTLCOLORSTATIC,
629  (WPARAM)hDC, (LPARAM)lphc->self );
630 
631  /*
632  * We have to change the text color since WM_CTLCOLORSTATIC will
633  * set it to the "enabled" color. This is the same behavior as the
634  * edit control
635  */
637  }
638  else
639  {
640  /* FIXME: In which cases WM_CTLCOLORLISTBOX should be sent? */
641  hBkgBrush = (HBRUSH)SendMessageW(lphc->owner, WM_CTLCOLOREDIT,
642  (WPARAM)hDC, (LPARAM)lphc->self );
643  }
644 
645  /*
646  * Catch errors.
647  */
648  if( !hBkgBrush )
649  hBkgBrush = GetSysColorBrush(COLOR_WINDOW);
650 
651  return hBkgBrush;
652 }
653 
654 /***********************************************************************
655  * CBPaintText
656  *
657  * Paint CBS_DROPDOWNLIST text field / update edit control contents.
658  */
659 static void CBPaintText(HEADCOMBO *lphc, HDC hdc_paint)
660 {
661  RECT rectEdit = lphc->textRect;
662  INT id, size = 0;
663  LPWSTR pText = NULL;
664 
665  TRACE("\n");
666 
667  /* follow Windows combobox that sends a bunch of text
668  * inquiries to its listbox while processing WM_PAINT. */
669 
670  if( (id = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0) ) != LB_ERR )
671  {
672  size = SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, id, 0);
673  if (size == LB_ERR)
674  FIXME("LB_ERR probably not handled yet\n");
675  if ((pText = heap_alloc((size + 1) * sizeof(WCHAR))))
676  {
677  /* size from LB_GETTEXTLEN may be too large, from LB_GETTEXT is accurate */
679  pText[size] = '\0'; /* just in case */
680  } else return;
681  }
682 
683  if( lphc->wState & CBF_EDIT )
684  {
685  static const WCHAR empty_stringW[] = { 0 };
686  if( CB_HASSTRINGS(lphc) ) SetWindowTextW( lphc->hWndEdit, pText ? pText : empty_stringW );
687  if( lphc->wState & CBF_FOCUSED )
689  }
690  else if(!(lphc->wState & CBF_NOREDRAW) && IsWindowVisible( lphc->self ))
691  {
692  /* paint text field ourselves */
693  HDC hdc = hdc_paint ? hdc_paint : GetDC(lphc->self);
694  UINT itemState = ODS_COMBOBOXEDIT;
695  HFONT hPrevFont = (lphc->hFont) ? SelectObject(hdc, lphc->hFont) : 0;
696  HBRUSH hPrevBrush, hBkgBrush;
697 
698  /*
699  * Give ourselves some space.
700  */
701  InflateRect( &rectEdit, -1, -1 );
702 
703  hBkgBrush = COMBO_PrepareColors( lphc, hdc );
704  hPrevBrush = SelectObject( hdc, hBkgBrush );
705  FillRect( hdc, &rectEdit, hBkgBrush );
706 
707  if( CB_OWNERDRAWN(lphc) )
708  {
709  DRAWITEMSTRUCT dis;
710  HRGN clipRegion;
711  UINT ctlid = (UINT)GetWindowLongPtrW( lphc->self, GWLP_ID );
712 
713  /* setup state for DRAWITEM message. Owner will highlight */
714  if ( (lphc->wState & CBF_FOCUSED) &&
715  !(lphc->wState & CBF_DROPPED) )
716  itemState |= ODS_SELECTED | ODS_FOCUS;
717 
718  if (!IsWindowEnabled(lphc->self)) itemState |= ODS_DISABLED;
719 
720  dis.CtlType = ODT_COMBOBOX;
721  dis.CtlID = ctlid;
722  dis.hwndItem = lphc->self;
724  dis.itemID = id;
725  dis.itemState = itemState;
726  dis.hDC = hdc;
727  dis.rcItem = rectEdit;
728  dis.itemData = SendMessageW(lphc->hWndLBox, LB_GETITEMDATA, id, 0);
729 
730  /*
731  * Clip the DC and have the parent draw the item.
732  */
733  clipRegion = set_control_clipping( hdc, &rectEdit );
734 
735  SendMessageW(lphc->owner, WM_DRAWITEM, ctlid, (LPARAM)&dis );
736 
737  SelectClipRgn( hdc, clipRegion );
738  if (clipRegion) DeleteObject( clipRegion );
739  }
740  else
741  {
742  static const WCHAR empty_stringW[] = { 0 };
743 
744  if ( (lphc->wState & CBF_FOCUSED) &&
745  !(lphc->wState & CBF_DROPPED) ) {
746 
747  /* highlight */
751  }
752 
753  ExtTextOutW( hdc,
754  rectEdit.left + 1,
755  rectEdit.top + 1,
757  &rectEdit,
758  pText ? pText : empty_stringW , size, NULL );
759 
760  if(lphc->wState & CBF_FOCUSED && !(lphc->wState & CBF_DROPPED))
761  DrawFocusRect( hdc, &rectEdit );
762  }
763 
764  if( hPrevFont )
765  SelectObject(hdc, hPrevFont );
766 
767  if( hPrevBrush )
768  SelectObject( hdc, hPrevBrush );
769 
770  if( !hdc_paint )
771  ReleaseDC( lphc->self, hdc );
772  }
773 
774  heap_free(pText);
775 }
776 
777 /***********************************************************************
778  * CBPaintBorder
779  */
780 static void CBPaintBorder(
781  HWND hwnd,
782  const HEADCOMBO *lphc,
783  HDC hdc)
784 {
785  RECT clientRect;
786 
787  if (CB_GETTYPE(lphc) != CBS_SIMPLE)
788  {
789  GetClientRect(hwnd, &clientRect);
790  }
791  else
792  {
793  clientRect = lphc->textRect;
794 
797  }
798 
799  DrawEdge(hdc, &clientRect, EDGE_SUNKEN, BF_RECT);
800 }
801 
803 {
804  int button_state;
805  RECT frame;
806 
807  /* paint border */
808  if (CB_GETTYPE(lphc) != CBS_SIMPLE)
809  GetClientRect(lphc->self, &frame);
810  else
811  {
812  frame = lphc->textRect;
815  }
816 
817  DrawThemeBackground(theme, hdc, 0, IsWindowEnabled(lphc->self) ? CBXS_NORMAL : CBXS_DISABLED, &frame, NULL);
818 
819  /* Paint button */
820  if (!IsRectEmpty(&lphc->buttonRect))
821  {
822  if (!IsWindowEnabled(lphc->self))
823  button_state = CBXS_DISABLED;
824  else if (lphc->wState & CBF_BUTTONDOWN)
825  button_state = CBXS_PRESSED;
826  else if (lphc->wState & CBF_HOT)
827  button_state = CBXS_HOT;
828  else
829  button_state = CBXS_NORMAL;
830  DrawThemeBackground(theme, hdc, CP_DROPDOWNBUTTON, button_state, &lphc->buttonRect, NULL);
831  }
832 
833  if ((lphc->dwStyle & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST)
834  CBPaintText(lphc, hdc);
835 
836  return 0;
837 }
838 
839 /***********************************************************************
840  * COMBO_Paint
841  */
843 {
844  HBRUSH hPrevBrush, hBkgBrush;
845 
846  TRACE("hdc=%p\n", hdc);
847 
848  /*
849  * Retrieve the background brush and select it in the
850  * DC.
851  */
852  hBkgBrush = COMBO_PrepareColors(lphc, hdc);
853  hPrevBrush = SelectObject(hdc, hBkgBrush);
854  if (!(lphc->wState & CBF_EDIT))
855  FillRect(hdc, &lphc->textRect, hBkgBrush);
856 
857  /*
858  * In non 3.1 look, there is a sunken border on the combobox
859  */
860  CBPaintBorder(lphc->self, lphc, hdc);
861 
862  if (!IsRectEmpty(&lphc->buttonRect))
863  CBPaintButton(lphc, hdc, lphc->buttonRect);
864 
865  /* paint the edit control padding area */
866  if (CB_GETTYPE(lphc) != CBS_DROPDOWNLIST)
867  {
868  RECT rPadEdit = lphc->textRect;
869 
871 
873  }
874 
875  if (!(lphc->wState & CBF_EDIT))
876  CBPaintText( lphc, hdc );
877 
878  if (hPrevBrush)
879  SelectObject( hdc, hPrevBrush );
880 
881  return 0;
882 }
883 
884 /***********************************************************************
885  * CBUpdateLBox
886  *
887  * Select listbox entry according to the contents of the edit control.
888  */
889 static INT CBUpdateLBox( LPHEADCOMBO lphc, BOOL bSelect )
890 {
891  INT length, idx;
892  LPWSTR pText = NULL;
893 
894  idx = LB_ERR;
895  length = SendMessageW( lphc->hWndEdit, WM_GETTEXTLENGTH, 0, 0 );
896 
897  if (length > 0)
898  pText = heap_alloc((length + 1) * sizeof(WCHAR));
899 
900  TRACE("\t edit text length %i\n", length );
901 
902  if( pText )
903  {
904  GetWindowTextW( lphc->hWndEdit, pText, length + 1);
906  heap_free( pText );
907  }
908 
909  SendMessageW(lphc->hWndLBox, LB_SETCURSEL, bSelect ? idx : -1, 0);
910 
911  /* probably superfluous but Windows sends this too */
912  SendMessageW(lphc->hWndLBox, LB_SETCARETINDEX, idx < 0 ? 0 : idx, 0);
913  SendMessageW(lphc->hWndLBox, LB_SETTOPINDEX, idx < 0 ? 0 : idx, 0);
914 
915  return idx;
916 }
917 
918 /***********************************************************************
919  * CBUpdateEdit
920  *
921  * Copy a listbox entry to the edit control.
922  */
923 static void CBUpdateEdit( LPHEADCOMBO lphc , INT index )
924 {
925  INT length;
926  LPWSTR pText = NULL;
927  static const WCHAR empty_stringW[] = { 0 };
928 
929  TRACE("\t %i\n", index );
930 
931  if( index >= 0 ) /* got an entry */
932  {
934  if( length != LB_ERR)
935  {
936  if ((pText = heap_alloc((length + 1) * sizeof(WCHAR))))
938  }
939  }
940 
941  if( CB_HASSTRINGS(lphc) )
942  {
945  lphc->wState &= ~(CBF_NOEDITNOTIFY | CBF_NOLBSELECT);
946  }
947 
948  if( lphc->wState & CBF_FOCUSED )
949  SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, -1);
950 
951  heap_free( pText );
952 }
953 
954 /***********************************************************************
955  * CBDropDown
956  *
957  * Show listbox popup.
958  */
959 static void CBDropDown( LPHEADCOMBO lphc )
960 {
961  HMONITOR monitor;
962  MONITORINFO mon_info;
963  RECT rect,r;
964  int nItems;
965  int nDroppedHeight;
966 
967  TRACE("[%p]: drop down\n", lphc->self);
968 
969  CB_NOTIFY( lphc, CBN_DROPDOWN );
970 
971  /* set selection */
972 
973  lphc->wState |= CBF_DROPPED;
974  if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
975  {
976  lphc->droppedIndex = CBUpdateLBox( lphc, TRUE );
977 
978  /* Update edit only if item is in the list */
979  if( !(lphc->wState & CBF_CAPTURE) && lphc->droppedIndex >= 0)
980  CBUpdateEdit( lphc, lphc->droppedIndex );
981  }
982  else
983  {
984  lphc->droppedIndex = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
985 
987  lphc->droppedIndex == LB_ERR ? 0 : lphc->droppedIndex, 0);
988  SendMessageW(lphc->hWndLBox, LB_CARETON, 0, 0);
989  }
990 
991  /* now set popup position */
992  GetWindowRect( lphc->self, &rect );
993 
994  /*
995  * If it's a dropdown, the listbox is offset
996  */
997  if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
998  rect.left += COMBO_EDITBUTTONSPACE();
999 
1000  /* if the dropped height is greater than the total height of the dropped
1001  items list, then force the drop down list height to be the total height
1002  of the items in the dropped list */
1003 
1004  /* And Remove any extra space (Best Fit) */
1005  nDroppedHeight = lphc->droppedRect.bottom - lphc->droppedRect.top;
1006  /* if listbox length has been set directly by its handle */
1007  GetWindowRect(lphc->hWndLBox, &r);
1008  if (nDroppedHeight < r.bottom - r.top)
1009  nDroppedHeight = r.bottom - r.top;
1010  nItems = (int)SendMessageW(lphc->hWndLBox, LB_GETCOUNT, 0, 0);
1011 
1012  if (nItems > 0)
1013  {
1014  int nIHeight = (int)SendMessageW(lphc->hWndLBox, LB_GETITEMHEIGHT, 0, 0);
1015 
1016  if (lphc->dwStyle & CBS_NOINTEGRALHEIGHT)
1017  {
1018  nDroppedHeight -= 1;
1019  }
1020  else
1021  {
1022  if (nItems > lphc->visibleItems)
1023  nItems = lphc->visibleItems;
1024  nDroppedHeight = nItems * nIHeight + COMBO_YBORDERSIZE();
1025  }
1026  }
1027 
1028  r.left = rect.left;
1029  r.top = rect.bottom;
1030  r.right = r.left + lphc->droppedRect.right - lphc->droppedRect.left;
1031  r.bottom = r.top + nDroppedHeight;
1032 
1033  /*If height of dropped rectangle gets beyond a screen size it should go up, otherwise down.*/
1034  monitor = MonitorFromRect( &rect, MONITOR_DEFAULTTOPRIMARY );
1035  mon_info.cbSize = sizeof(mon_info);
1036  GetMonitorInfoW( monitor, &mon_info );
1037 
1038  if (r.bottom > mon_info.rcWork.bottom)
1039  {
1040  r.top = max( rect.top - nDroppedHeight, mon_info.rcWork.top );
1041  r.bottom = min( r.top + nDroppedHeight, mon_info.rcWork.bottom );
1042  }
1043 
1044  SetWindowPos( lphc->hWndLBox, HWND_TOPMOST, r.left, r.top, r.right - r.left, r.bottom - r.top,
1046 
1047 
1048  if( !(lphc->wState & CBF_NOREDRAW) )
1050 
1051  EnableWindow( lphc->hWndLBox, TRUE );
1052  if (GetCapture() != lphc->self)
1053  SetCapture(lphc->hWndLBox);
1054 }
1055 
1056 /***********************************************************************
1057  * CBRollUp
1058  *
1059  * Hide listbox popup.
1060  */
1061 static void CBRollUp( LPHEADCOMBO lphc, BOOL ok, BOOL bButton )
1062 {
1063  HWND hWnd = lphc->self;
1064 
1065  TRACE("[%p]: sel ok? [%i] dropped? [%i]\n",
1066  lphc->self, ok, (INT)(lphc->wState & CBF_DROPPED));
1067 
1068  CB_NOTIFY( lphc, (ok) ? CBN_SELENDOK : CBN_SELENDCANCEL );
1069 
1070  if( IsWindow( hWnd ) && CB_GETTYPE(lphc) != CBS_SIMPLE )
1071  {
1072 
1073  if( lphc->wState & CBF_DROPPED )
1074  {
1075  RECT rect;
1076 
1077  lphc->wState &= ~CBF_DROPPED;
1078  ShowWindow( lphc->hWndLBox, SW_HIDE );
1079 
1080  if(GetCapture() == lphc->hWndLBox)
1081  {
1082  ReleaseCapture();
1083  }
1084 
1085  if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
1086  {
1087  rect = lphc->buttonRect;
1088  }
1089  else
1090  {
1091  if( bButton )
1092  {
1093  UnionRect( &rect,
1094  &lphc->buttonRect,
1095  &lphc->textRect);
1096  }
1097  else
1098  rect = lphc->textRect;
1099 
1100  bButton = TRUE;
1101  }
1102 
1103  if( bButton && !(lphc->wState & CBF_NOREDRAW) )
1106  CB_NOTIFY( lphc, CBN_CLOSEUP );
1107  }
1108  }
1109 }
1110 
1111 /***********************************************************************
1112  * COMBO_FlipListbox
1113  *
1114  * Used by the ComboLBox to show/hide itself in response to VK_F4, etc...
1115  */
1117 {
1118  if( lphc->wState & CBF_DROPPED )
1119  {
1120  CBRollUp( lphc, ok, bRedrawButton );
1121  return FALSE;
1122  }
1123 
1124  CBDropDown( lphc );
1125  return TRUE;
1126 }
1127 
1128 /***********************************************************************
1129  * CBRepaintButton
1130  */
1131 static void CBRepaintButton( LPHEADCOMBO lphc )
1132  {
1133  InvalidateRect(lphc->self, &lphc->buttonRect, TRUE);
1134  UpdateWindow(lphc->self);
1135 }
1136 
1137 /***********************************************************************
1138  * COMBO_SetFocus
1139  */
1140 static void COMBO_SetFocus( LPHEADCOMBO lphc )
1141 {
1142  if( !(lphc->wState & CBF_FOCUSED) )
1143  {
1144  if( CB_GETTYPE(lphc) == CBS_DROPDOWNLIST )
1145  SendMessageW(lphc->hWndLBox, LB_CARETON, 0, 0);
1146 
1147  /* This is wrong. Message sequences seem to indicate that this
1148  is set *after* the notify. */
1149  /* lphc->wState |= CBF_FOCUSED; */
1150 
1151  if( !(lphc->wState & CBF_EDIT) )
1152  InvalidateRect(lphc->self, &lphc->textRect, TRUE);
1153 
1154  CB_NOTIFY( lphc, CBN_SETFOCUS );
1155  lphc->wState |= CBF_FOCUSED;
1156  }
1157 }
1158 
1159 /***********************************************************************
1160  * COMBO_KillFocus
1161  */
1162 static void COMBO_KillFocus( LPHEADCOMBO lphc )
1163 {
1164  HWND hWnd = lphc->self;
1165 
1166  if( lphc->wState & CBF_FOCUSED )
1167  {
1168  CBRollUp( lphc, FALSE, TRUE );
1169  if( IsWindow( hWnd ) )
1170  {
1171  if( CB_GETTYPE(lphc) == CBS_DROPDOWNLIST )
1172  SendMessageW(lphc->hWndLBox, LB_CARETOFF, 0, 0);
1173 
1174  lphc->wState &= ~CBF_FOCUSED;
1175 
1176  /* redraw text */
1177  if( !(lphc->wState & CBF_EDIT) )
1178  InvalidateRect(lphc->self, &lphc->textRect, TRUE);
1179 
1180  CB_NOTIFY( lphc, CBN_KILLFOCUS );
1181  }
1182  }
1183 }
1184 
1185 /***********************************************************************
1186  * COMBO_Command
1187  */
1189 {
1190  if ( lphc->wState & CBF_EDIT && lphc->hWndEdit == hWnd )
1191  {
1192  /* ">> 8" makes gcc generate jump-table instead of cmp ladder */
1193 
1194  switch( HIWORD(wParam) >> 8 )
1195  {
1196  case (EN_SETFOCUS >> 8):
1197 
1198  TRACE("[%p]: edit [%p] got focus\n", lphc->self, lphc->hWndEdit );
1199 
1200  COMBO_SetFocus( lphc );
1201  break;
1202 
1203  case (EN_KILLFOCUS >> 8):
1204 
1205  TRACE("[%p]: edit [%p] lost focus\n", lphc->self, lphc->hWndEdit );
1206 
1207  /* NOTE: it seems that Windows' edit control sends an
1208  * undocumented message WM_USER + 0x1B instead of this
1209  * notification (only when it happens to be a part of
1210  * the combo). ?? - AK.
1211  */
1212 
1213  COMBO_KillFocus( lphc );
1214  break;
1215 
1216 
1217  case (EN_CHANGE >> 8):
1218  /*
1219  * In some circumstances (when the selection of the combobox
1220  * is changed for example) we don't want the EN_CHANGE notification
1221  * to be forwarded to the parent of the combobox. This code
1222  * checks a flag that is set in these occasions and ignores the
1223  * notification.
1224  */
1225  if (lphc->wState & CBF_NOLBSELECT)
1226  {
1227  lphc->wState &= ~CBF_NOLBSELECT;
1228  }
1229  else
1230  {
1231  CBUpdateLBox( lphc, lphc->wState & CBF_DROPPED );
1232  }
1233 
1234  if (!(lphc->wState & CBF_NOEDITNOTIFY))
1235  CB_NOTIFY( lphc, CBN_EDITCHANGE );
1236  break;
1237 
1238  case (EN_UPDATE >> 8):
1239  if (!(lphc->wState & CBF_NOEDITNOTIFY))
1240  CB_NOTIFY( lphc, CBN_EDITUPDATE );
1241  break;
1242 
1243  case (EN_ERRSPACE >> 8):
1244  CB_NOTIFY( lphc, CBN_ERRSPACE );
1245  }
1246  }
1247  else if( lphc->hWndLBox == hWnd )
1248  {
1249  switch( (short)HIWORD(wParam) )
1250  {
1251  case LBN_ERRSPACE:
1252  CB_NOTIFY( lphc, CBN_ERRSPACE );
1253  break;
1254 
1255  case LBN_DBLCLK:
1256  CB_NOTIFY( lphc, CBN_DBLCLK );
1257  break;
1258 
1259  case LBN_SELCHANGE:
1260  case LBN_SELCANCEL:
1261 
1262  TRACE("[%p]: lbox selection change [%x]\n", lphc->self, lphc->wState );
1263 
1264  /* do not roll up if selection is being tracked
1265  * by arrow keys in the dropdown listbox */
1266  if (!(lphc->wState & CBF_NOROLLUP))
1267  {
1268  CBRollUp( lphc, (HIWORD(wParam) == LBN_SELCHANGE), TRUE );
1269  }
1270  else lphc->wState &= ~CBF_NOROLLUP;
1271 
1272  CB_NOTIFY( lphc, CBN_SELCHANGE );
1273 
1274  if( HIWORD(wParam) == LBN_SELCHANGE)
1275  {
1276  if( lphc->wState & CBF_EDIT )
1277  lphc->wState |= CBF_NOLBSELECT;
1278  CBPaintText( lphc, NULL );
1279  }
1280  break;
1281 
1282  case LBN_SETFOCUS:
1283  case LBN_KILLFOCUS:
1284  /* nothing to do here since ComboLBox always resets the focus to its
1285  * combo/edit counterpart */
1286  break;
1287  }
1288  }
1289  return 0;
1290 }
1291 
1292 /***********************************************************************
1293  * COMBO_ItemOp
1294  *
1295  * Fixup an ownerdrawn item operation and pass it up to the combobox owner.
1296  */
1298 {
1299  HWND hWnd = lphc->self;
1301 
1302  TRACE("[%p]: ownerdraw op %04x\n", lphc->self, msg );
1303 
1304  switch( msg )
1305  {
1306  case WM_DELETEITEM:
1307  {
1309  lpIS->CtlType = ODT_COMBOBOX;
1310  lpIS->CtlID = id;
1311  lpIS->hwndItem = hWnd;
1312  break;
1313  }
1314  case WM_DRAWITEM:
1315  {
1317  lpIS->CtlType = ODT_COMBOBOX;
1318  lpIS->CtlID = id;
1319  lpIS->hwndItem = hWnd;
1320  break;
1321  }
1322  case WM_COMPAREITEM:
1323  {
1325  lpIS->CtlType = ODT_COMBOBOX;
1326  lpIS->CtlID = id;
1327  lpIS->hwndItem = hWnd;
1328  break;
1329  }
1330  case WM_MEASUREITEM:
1331  {
1333  lpIS->CtlType = ODT_COMBOBOX;
1334  lpIS->CtlID = id;
1335  break;
1336  }
1337  }
1338  return SendMessageW(lphc->owner, msg, id, lParam);
1339 }
1340 
1341 
1342 /***********************************************************************
1343  * COMBO_GetTextW
1344  */
1346 {
1347  INT length;
1348 
1349  if( lphc->wState & CBF_EDIT )
1350  return SendMessageW( lphc->hWndEdit, WM_GETTEXT, count, (LPARAM)buf );
1351 
1352  /* get it from the listbox */
1353 
1354  if (!count || !buf) return 0;
1355  if( lphc->hWndLBox )
1356  {
1357  INT idx = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
1358  if (idx == LB_ERR) goto error;
1359  length = SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, idx, 0 );
1360  if (length == LB_ERR) goto error;
1361 
1362  /* 'length' is without the terminating character */
1363  if (length >= count)
1364  {
1365  WCHAR *lpBuffer = heap_alloc((length + 1) * sizeof(WCHAR));
1366  if (!lpBuffer) goto error;
1368 
1369  /* truncate if buffer is too short */
1370  if (length != LB_ERR)
1371  {
1372  lstrcpynW( buf, lpBuffer, count );
1373  length = count;
1374  }
1375  heap_free( lpBuffer );
1376  }
1377  else length = SendMessageW(lphc->hWndLBox, LB_GETTEXT, idx, (LPARAM)buf);
1378 
1379  if (length == LB_ERR) return 0;
1380  return length;
1381  }
1382 
1383  error: /* error - truncate string, return zero */
1384  buf[0] = 0;
1385  return 0;
1386 }
1387 
1388 /***********************************************************************
1389  * CBResetPos
1390  *
1391  * This function sets window positions according to the updated
1392  * component placement struct.
1393  */
1394 static void CBResetPos(
1395  LPHEADCOMBO lphc,
1396  const RECT *rectEdit,
1397  const RECT *rectLB,
1398  BOOL bRedraw)
1399 {
1400  BOOL bDrop = (CB_GETTYPE(lphc) != CBS_SIMPLE);
1401 
1402  /* NOTE: logs sometimes have WM_LBUTTONUP before a cascade of
1403  * sizing messages */
1404 
1405  if( lphc->wState & CBF_EDIT )
1406  SetWindowPos( lphc->hWndEdit, 0,
1407  rectEdit->left, rectEdit->top,
1408  rectEdit->right - rectEdit->left,
1409  rectEdit->bottom - rectEdit->top,
1410  SWP_NOZORDER | SWP_NOACTIVATE | ((bDrop) ? SWP_NOREDRAW : 0) );
1411 
1412  SetWindowPos( lphc->hWndLBox, 0,
1413  rectLB->left, rectLB->top,
1414  rectLB->right - rectLB->left,
1415  rectLB->bottom - rectLB->top,
1416  SWP_NOACTIVATE | SWP_NOZORDER | ((bDrop) ? SWP_NOREDRAW : 0) );
1417 
1418  if( bDrop )
1419  {
1420  if( lphc->wState & CBF_DROPPED )
1421  {
1422  lphc->wState &= ~CBF_DROPPED;
1423  ShowWindow( lphc->hWndLBox, SW_HIDE );
1424  }
1425 
1426  if( bRedraw && !(lphc->wState & CBF_NOREDRAW) )
1427  RedrawWindow( lphc->self, NULL, 0,
1429  }
1430 }
1431 
1432 
1433 /***********************************************************************
1434  * COMBO_Size
1435  */
1436 static void COMBO_Size( LPHEADCOMBO lphc )
1437 {
1438  /*
1439  * Those controls are always the same height. So we have to make sure
1440  * they are not resized to another value.
1441  */
1442  if( CB_GETTYPE(lphc) != CBS_SIMPLE )
1443  {
1444  int newComboHeight, curComboHeight, curComboWidth;
1445  RECT rc;
1446 
1447  GetWindowRect(lphc->self, &rc);
1448  curComboHeight = rc.bottom - rc.top;
1449  curComboWidth = rc.right - rc.left;
1450  newComboHeight = CBGetTextAreaHeight(lphc->self, lphc) + 2*COMBO_YBORDERSIZE();
1451 
1452  /*
1453  * Resizing a combobox has another side effect, it resizes the dropped
1454  * rectangle as well. However, it does it only if the new height for the
1455  * combobox is more than the height it should have. In other words,
1456  * if the application resizing the combobox only had the intention to resize
1457  * the actual control, for example, to do the layout of a dialog that is
1458  * resized, the height of the dropdown is not changed.
1459  */
1460  if( curComboHeight > newComboHeight )
1461  {
1462  TRACE("oldComboHeight=%d, newComboHeight=%d, oldDropBottom=%d, oldDropTop=%d\n",
1463  curComboHeight, newComboHeight, lphc->droppedRect.bottom,
1464  lphc->droppedRect.top);
1465  lphc->droppedRect.bottom = lphc->droppedRect.top + curComboHeight - newComboHeight;
1466  }
1467  /*
1468  * Restore original height
1469  */
1470  if( curComboHeight != newComboHeight )
1471  SetWindowPos(lphc->self, 0, 0, 0, curComboWidth, newComboHeight,
1473  }
1474 
1475  CBCalcPlacement(lphc->self,
1476  lphc,
1477  &lphc->textRect,
1478  &lphc->buttonRect,
1479  &lphc->droppedRect);
1480 
1481  CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
1482 }
1483 
1484 
1485 /***********************************************************************
1486  * COMBO_Font
1487  */
1488 static void COMBO_Font( LPHEADCOMBO lphc, HFONT hFont, BOOL bRedraw )
1489 {
1490  /*
1491  * Set the font
1492  */
1493  lphc->hFont = hFont;
1494 
1495  /*
1496  * Propagate to owned windows.
1497  */
1498  if( lphc->wState & CBF_EDIT )
1499  SendMessageW(lphc->hWndEdit, WM_SETFONT, (WPARAM)hFont, bRedraw);
1500  SendMessageW(lphc->hWndLBox, WM_SETFONT, (WPARAM)hFont, bRedraw);
1501 
1502  /*
1503  * Redo the layout of the control.
1504  */
1505  if ( CB_GETTYPE(lphc) == CBS_SIMPLE)
1506  {
1507  CBCalcPlacement(lphc->self,
1508  lphc,
1509  &lphc->textRect,
1510  &lphc->buttonRect,
1511  &lphc->droppedRect);
1512 
1513  CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
1514  }
1515  else
1516  {
1517  CBForceDummyResize(lphc);
1518  }
1519 }
1520 
1521 
1522 /***********************************************************************
1523  * COMBO_SetItemHeight
1524  */
1526 {
1527  LRESULT lRet = CB_ERR;
1528 
1529  if( index == -1 ) /* set text field height */
1530  {
1531  if( height < 32768 )
1532  {
1533  lphc->editHeight = height + 2; /* Is the 2 for 2*EDIT_CONTROL_PADDING? */
1534 
1535  /*
1536  * Redo the layout of the control.
1537  */
1538  if ( CB_GETTYPE(lphc) == CBS_SIMPLE)
1539  {
1540  CBCalcPlacement(lphc->self,
1541  lphc,
1542  &lphc->textRect,
1543  &lphc->buttonRect,
1544  &lphc->droppedRect);
1545 
1546  CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
1547  }
1548  else
1549  {
1550  CBForceDummyResize(lphc);
1551  }
1552 
1553  lRet = height;
1554  }
1555  }
1556  else if ( CB_OWNERDRAWN(lphc) ) /* set listbox item height */
1558  return lRet;
1559 }
1560 
1561 /***********************************************************************
1562  * COMBO_SelectString
1563  */
1565 {
1567  if( index >= 0 )
1568  {
1569  if( lphc->wState & CBF_EDIT )
1570  CBUpdateEdit( lphc, index );
1571  else
1572  {
1573  InvalidateRect(lphc->self, &lphc->textRect, TRUE);
1574  }
1575  }
1576  return (LRESULT)index;
1577 }
1578 
1579 /***********************************************************************
1580  * COMBO_LButtonDown
1581  */
1583 {
1584  POINT pt;
1585  BOOL bButton;
1586  HWND hWnd = lphc->self;
1587 
1588  pt.x = (short)LOWORD(lParam);
1589  pt.y = (short)HIWORD(lParam);
1590  bButton = PtInRect(&lphc->buttonRect, pt);
1591 
1592  if( (CB_GETTYPE(lphc) == CBS_DROPDOWNLIST) ||
1593  (bButton && (CB_GETTYPE(lphc) == CBS_DROPDOWN)) )
1594  {
1595  lphc->wState |= CBF_BUTTONDOWN;
1596  if( lphc->wState & CBF_DROPPED )
1597  {
1598  /* got a click to cancel selection */
1599 
1600  lphc->wState &= ~CBF_BUTTONDOWN;
1601  CBRollUp( lphc, TRUE, FALSE );
1602  if( !IsWindow( hWnd ) ) return;
1603 
1604  if( lphc->wState & CBF_CAPTURE )
1605  {
1606  lphc->wState &= ~CBF_CAPTURE;
1607  ReleaseCapture();
1608  }
1609  }
1610  else
1611  {
1612  /* drop down the listbox and start tracking */
1613 
1614  lphc->wState |= CBF_CAPTURE;
1615  SetCapture( hWnd );
1616  CBDropDown( lphc );
1617  }
1618  if( bButton ) CBRepaintButton( lphc );
1619  }
1620 }
1621 
1622 /***********************************************************************
1623  * COMBO_LButtonUp
1624  *
1625  * Release capture and stop tracking if needed.
1626  */
1627 static void COMBO_LButtonUp( LPHEADCOMBO lphc )
1628 {
1629  if( lphc->wState & CBF_CAPTURE )
1630  {
1631  lphc->wState &= ~CBF_CAPTURE;
1632  if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
1633  {
1634  INT index = CBUpdateLBox( lphc, TRUE );
1635  /* Update edit only if item is in the list */
1636  if(index >= 0)
1637  {
1638  lphc->wState |= CBF_NOLBSELECT;
1639  CBUpdateEdit( lphc, index );
1640  lphc->wState &= ~CBF_NOLBSELECT;
1641  }
1642  }
1643  ReleaseCapture();
1644  SetCapture(lphc->hWndLBox);
1645  }
1646 
1647  if( lphc->wState & CBF_BUTTONDOWN )
1648  {
1649  lphc->wState &= ~CBF_BUTTONDOWN;
1650  CBRepaintButton( lphc );
1651  }
1652 }
1653 
1654 /***********************************************************************
1655  * COMBO_MouseMove
1656  *
1657  * Two things to do - track combo button and release capture when
1658  * pointer goes into the listbox.
1659  */
1661 {
1662  POINT pt;
1663  RECT lbRect;
1664 
1665  pt.x = (short)LOWORD(lParam);
1666  pt.y = (short)HIWORD(lParam);
1667 
1668  if( lphc->wState & CBF_BUTTONDOWN )
1669  {
1670  BOOL bButton;
1671 
1672  bButton = PtInRect(&lphc->buttonRect, pt);
1673 
1674  if( !bButton )
1675  {
1676  lphc->wState &= ~CBF_BUTTONDOWN;
1677  CBRepaintButton( lphc );
1678  }
1679  }
1680 
1681  GetClientRect( lphc->hWndLBox, &lbRect );
1682  MapWindowPoints( lphc->self, lphc->hWndLBox, &pt, 1 );
1683  if( PtInRect(&lbRect, pt) )
1684  {
1685  lphc->wState &= ~CBF_CAPTURE;
1686  ReleaseCapture();
1687  if( CB_GETTYPE(lphc) == CBS_DROPDOWN ) CBUpdateLBox( lphc, TRUE );
1688 
1689  /* hand over pointer tracking */
1691  }
1692 }
1693 
1695 {
1696  if (!pcbi || (pcbi->cbSize < sizeof(COMBOBOXINFO)))
1697  return FALSE;
1698 
1699  pcbi->rcItem = lphc->textRect;
1700  pcbi->rcButton = lphc->buttonRect;
1701  pcbi->stateButton = 0;
1702  if (lphc->wState & CBF_BUTTONDOWN)
1704  if (IsRectEmpty(&lphc->buttonRect))
1706  pcbi->hwndCombo = lphc->self;
1707  pcbi->hwndItem = lphc->hWndEdit;
1708  pcbi->hwndList = lphc->hWndLBox;
1709  return TRUE;
1710 }
1711 
1713 {
1714  HEADCOMBO *lphc = (HEADCOMBO *)GetWindowLongPtrW( hwnd, 0 );
1715  HTHEME theme;
1716 
1717  TRACE("[%p]: msg %#x wp %08lx lp %08lx\n", hwnd, message, wParam, lParam );
1718 
1719  if (!IsWindow(hwnd)) return 0;
1720 
1721  if (lphc || message == WM_NCCREATE)
1722  switch(message)
1723  {
1724  case WM_NCCREATE:
1725  {
1726  LONG style = ((CREATESTRUCTW *)lParam)->style;
1727  return COMBO_NCCreate(hwnd, style);
1728  }
1729 
1730  case WM_NCDESTROY:
1731  COMBO_NCDestroy(lphc);
1732  break;/* -> DefWindowProc */
1733 
1734  case WM_CREATE:
1735  {
1736  HWND hwndParent;
1737  LONG style;
1738 
1739  hwndParent = ((CREATESTRUCTW *)lParam)->hwndParent;
1740  style = ((CREATESTRUCTW *)lParam)->style;
1741  return COMBO_Create(hwnd, lphc, hwndParent, style);
1742  }
1743 
1744  case WM_DESTROY:
1745  theme = GetWindowTheme( hwnd );
1746  CloseThemeData( theme );
1747  break;
1748 
1749  case WM_THEMECHANGED:
1750  theme = GetWindowTheme( hwnd );
1751  CloseThemeData( theme );
1753  break;
1754 
1755  case WM_PRINTCLIENT:
1756  case WM_PAINT:
1757  {
1758  LRESULT ret = 0;
1759  PAINTSTRUCT ps;
1760  HDC hdc;
1761 
1762  hdc = wParam ? (HDC)wParam : BeginPaint(hwnd, &ps);
1763 
1764  if (hdc && !(lphc->wState & CBF_NOREDRAW))
1765  {
1766  HTHEME theme = GetWindowTheme(hwnd);
1767 
1768  if (theme)
1769  ret = COMBO_ThemedPaint(theme, lphc, hdc);
1770  else
1771  ret = COMBO_Paint(lphc, hdc);
1772  }
1773 
1774  if (!wParam)
1775  EndPaint(hwnd, &ps);
1776 
1777  return ret;
1778  }
1779  case WM_ERASEBKGND:
1780  /* do all painting in WM_PAINT like Windows does */
1781  return 1;
1782 
1783  case WM_GETDLGCODE:
1784  {
1786  if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN))
1787  {
1788  int vk = (int)((LPMSG)lParam)->wParam;
1789 
1790  if ((vk == VK_RETURN || vk == VK_ESCAPE) && (lphc->wState & CBF_DROPPED))
1792  }
1793  return result;
1794  }
1795 
1796  case WM_SIZE:
1797  if (lphc->hWndLBox && !(lphc->wState & CBF_NORESIZE))
1798  COMBO_Size( lphc );
1799  return TRUE;
1800 
1801  case WM_SETFONT:
1802  COMBO_Font( lphc, (HFONT)wParam, (BOOL)lParam );
1803  return TRUE;
1804 
1805  case WM_GETFONT:
1806  return (LRESULT)lphc->hFont;
1807 
1808  case WM_SETFOCUS:
1809  if (lphc->wState & CBF_EDIT)
1810  {
1811  SetFocus( lphc->hWndEdit );
1812  /* The first time focus is received, select all the text */
1813  if (!(lphc->wState & CBF_BEENFOCUSED))
1814  {
1815  SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, -1);
1816  lphc->wState |= CBF_BEENFOCUSED;
1817  }
1818  }
1819  else
1820  COMBO_SetFocus( lphc );
1821  return TRUE;
1822 
1823  case WM_KILLFOCUS:
1824  {
1825  HWND hwndFocus = (HWND)wParam;
1826  if (!hwndFocus || (hwndFocus != lphc->hWndEdit && hwndFocus != lphc->hWndLBox))
1827  COMBO_KillFocus( lphc );
1828  return TRUE;
1829  }
1830 
1831  case WM_COMMAND:
1832  return COMBO_Command( lphc, wParam, (HWND)lParam );
1833 
1834  case WM_GETTEXT:
1835  return COMBO_GetText( lphc, wParam, (LPWSTR)lParam );
1836 
1837  case WM_SETTEXT:
1838  case WM_GETTEXTLENGTH:
1839  case WM_CLEAR:
1840  if ((message == WM_GETTEXTLENGTH) && !ISWIN31 && !(lphc->wState & CBF_EDIT))
1841  {
1842  int j = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
1843  if (j == -1) return 0;
1844  return SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, j, 0);
1845  }
1846  else if ( lphc->wState & CBF_EDIT )
1847  {
1848  LRESULT ret;
1849  lphc->wState |= CBF_NOEDITNOTIFY;
1851  lphc->wState &= ~CBF_NOEDITNOTIFY;
1852  return ret;
1853  }
1854  else
1855  return CB_ERR;
1856 
1857  case WM_CUT:
1858  case WM_PASTE:
1859  case WM_COPY:
1860  if (lphc->wState & CBF_EDIT)
1861  return SendMessageW(lphc->hWndEdit, message, wParam, lParam);
1862  else return CB_ERR;
1863 
1864  case WM_DRAWITEM:
1865  case WM_DELETEITEM:
1866  case WM_COMPAREITEM:
1867  case WM_MEASUREITEM:
1868  return COMBO_ItemOp(lphc, message, lParam);
1869 
1870  case WM_ENABLE:
1871  if (lphc->wState & CBF_EDIT)
1872  EnableWindow( lphc->hWndEdit, (BOOL)wParam );
1873  EnableWindow( lphc->hWndLBox, (BOOL)wParam );
1874 
1875  /* Force the control to repaint when the enabled state changes. */
1876  InvalidateRect(lphc->self, NULL, TRUE);
1877  return TRUE;
1878 
1879  case WM_SETREDRAW:
1880  if (wParam)
1881  lphc->wState &= ~CBF_NOREDRAW;
1882  else
1883  lphc->wState |= CBF_NOREDRAW;
1884 
1885  if ( lphc->wState & CBF_EDIT )
1888  return 0;
1889 
1890  case WM_SYSKEYDOWN:
1891  if ( KEYDATA_ALT & HIWORD(lParam) )
1892  if( wParam == VK_UP || wParam == VK_DOWN )
1893  COMBO_FlipListbox( lphc, FALSE, FALSE );
1894  return 0;
1895 
1896  case WM_KEYDOWN:
1897  if ((wParam == VK_RETURN || wParam == VK_ESCAPE) &&
1898  (lphc->wState & CBF_DROPPED))
1899  {
1900  CBRollUp( lphc, wParam == VK_RETURN, FALSE );
1901  return TRUE;
1902  }
1903  else if ((wParam == VK_F4) && !(lphc->wState & CBF_EUI))
1904  {
1905  COMBO_FlipListbox( lphc, FALSE, FALSE );
1906  return TRUE;
1907  }
1908  /* fall through */
1909  case WM_CHAR:
1910  case WM_IME_CHAR:
1911  {
1912  HWND hwndTarget;
1913 
1914  if ( lphc->wState & CBF_EDIT )
1915  hwndTarget = lphc->hWndEdit;
1916  else
1917  hwndTarget = lphc->hWndLBox;
1918 
1919  return SendMessageW(hwndTarget, message, wParam, lParam);
1920  }
1921 
1922  case WM_LBUTTONDOWN:
1923  if ( !(lphc->wState & CBF_FOCUSED) ) SetFocus( lphc->self );
1924  if ( lphc->wState & CBF_FOCUSED ) COMBO_LButtonDown( lphc, lParam );
1925  return TRUE;
1926 
1927  case WM_LBUTTONUP:
1928  COMBO_LButtonUp( lphc );
1929  return TRUE;
1930 
1931  case WM_MOUSEMOVE:
1932  if (!IsRectEmpty(&lphc->buttonRect))
1933  {
1934  POINT pt;
1935 
1936  pt.x = (short)LOWORD(lParam);
1937  pt.y = (short)HIWORD(lParam);
1938 
1939  if (PtInRect(&lphc->buttonRect, pt))
1940  {
1941  if (!(lphc->wState & CBF_HOT))
1942  {
1943  lphc->wState |= CBF_HOT;
1945  }
1946  }
1947  else if (lphc->wState & CBF_HOT)
1948  {
1949  lphc->wState &= ~CBF_HOT;
1951  }
1952  }
1953 
1954  if ( lphc->wState & CBF_CAPTURE )
1955  COMBO_MouseMove( lphc, wParam, lParam );
1956  return TRUE;
1957 
1958  case WM_MOUSEWHEEL:
1959  if (wParam & (MK_SHIFT | MK_CONTROL))
1961 
1962  if (GET_WHEEL_DELTA_WPARAM(wParam) > 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_UP, 0);
1963  if (GET_WHEEL_DELTA_WPARAM(wParam) < 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_DOWN, 0);
1964  return TRUE;
1965 
1966  case WM_CTLCOLOR:
1967  case WM_CTLCOLORMSGBOX:
1968  case WM_CTLCOLOREDIT:
1969  case WM_CTLCOLORLISTBOX:
1970  case WM_CTLCOLORBTN:
1971  case WM_CTLCOLORDLG:
1972  case WM_CTLCOLORSCROLLBAR:
1973  case WM_CTLCOLORSTATIC:
1974  return SendMessageW(lphc->owner, message, wParam, lParam);
1975 
1976  /* Combo messages */
1977  case CB_ADDSTRING:
1978  if (lphc->dwStyle & CBS_LOWERCASE)
1980  else if (lphc->dwStyle & CBS_UPPERCASE)
1982  return SendMessageW(lphc->hWndLBox, LB_ADDSTRING, 0, lParam);
1983 
1984  case CB_INSERTSTRING:
1985  if (lphc->dwStyle & CBS_LOWERCASE)
1987  else if (lphc->dwStyle & CBS_UPPERCASE)
1990 
1991  case CB_DELETESTRING:
1992  return SendMessageW(lphc->hWndLBox, LB_DELETESTRING, wParam, 0);
1993 
1994  case CB_SELECTSTRING:
1995  return COMBO_SelectString(lphc, (INT)wParam, lParam);
1996 
1997  case CB_FINDSTRING:
1998  return SendMessageW(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam);
1999 
2000  case CB_FINDSTRINGEXACT:
2002 
2003  case CB_SETITEMHEIGHT:
2004  return COMBO_SetItemHeight( lphc, (INT)wParam, (INT)lParam);
2005 
2006  case CB_GETITEMHEIGHT:
2007  if ((INT)wParam >= 0) /* listbox item */
2008  return SendMessageW(lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0);
2009  return CBGetTextAreaHeight(hwnd, lphc);
2010 
2011  case CB_RESETCONTENT:
2012  SendMessageW(lphc->hWndLBox, LB_RESETCONTENT, 0, 0);
2013 
2014  if ((lphc->wState & CBF_EDIT) && CB_HASSTRINGS(lphc))
2015  {
2016  static const WCHAR empty_stringW[] = { 0 };
2018  }
2019  else
2020  InvalidateRect(lphc->self, NULL, TRUE);
2021  return TRUE;
2022 
2023  case CB_INITSTORAGE:
2025 
2027  return SendMessageW(lphc->hWndLBox, LB_GETHORIZONTALEXTENT, 0, 0);
2028 
2031 
2032  case CB_GETTOPINDEX:
2033  return SendMessageW(lphc->hWndLBox, LB_GETTOPINDEX, 0, 0);
2034 
2035  case CB_GETLOCALE:
2036  return SendMessageW(lphc->hWndLBox, LB_GETLOCALE, 0, 0);
2037 
2038  case CB_SETLOCALE:
2039  return SendMessageW(lphc->hWndLBox, LB_SETLOCALE, wParam, 0);
2040 
2041  case CB_SETDROPPEDWIDTH:
2042  if ((CB_GETTYPE(lphc) == CBS_SIMPLE) || (INT)wParam >= 32768)
2043  return CB_ERR;
2044 
2045  /* new value must be higher than combobox width */
2046  if ((INT)wParam >= lphc->droppedRect.right - lphc->droppedRect.left)
2047  lphc->droppedWidth = wParam;
2048  else if (wParam)
2049  lphc->droppedWidth = 0;
2050 
2051  /* recalculate the combobox area */
2052  CBCalcPlacement(hwnd, lphc, &lphc->textRect, &lphc->buttonRect, &lphc->droppedRect );
2053 
2054  /* fall through */
2055  case CB_GETDROPPEDWIDTH:
2056  if (lphc->droppedWidth)
2057  return lphc->droppedWidth;
2058  return lphc->droppedRect.right - lphc->droppedRect.left;
2059 
2061  if (lParam)
2063  return CB_OKAY;
2064 
2065  case CB_GETDROPPEDSTATE:
2066  return (lphc->wState & CBF_DROPPED) != 0;
2067 
2068  case CB_DIR:
2069  return SendMessageW(lphc->hWndLBox, LB_DIR, wParam, lParam);
2070 
2071  case CB_SHOWDROPDOWN:
2072  if (CB_GETTYPE(lphc) != CBS_SIMPLE)
2073  {
2074  if (wParam)
2075  {
2076  if (!(lphc->wState & CBF_DROPPED))
2077  CBDropDown( lphc );
2078  }
2079  else if (lphc->wState & CBF_DROPPED)
2080  CBRollUp( lphc, FALSE, TRUE );
2081  }
2082  return TRUE;
2083 
2084  case CB_GETCOUNT:
2085  return SendMessageW(lphc->hWndLBox, LB_GETCOUNT, 0, 0);
2086 
2087  case CB_GETCURSEL:
2088  return SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
2089 
2090  case CB_SETCURSEL:
2092  if (lParam >= 0)
2094 
2095  /* no LBN_SELCHANGE in this case, update manually */
2096  CBPaintText(lphc, NULL);
2097  lphc->wState &= ~CBF_SELCHANGE;
2098  return lParam;
2099 
2100  case CB_GETLBTEXT:
2101  return SendMessageW(lphc->hWndLBox, LB_GETTEXT, wParam, lParam);
2102 
2103  case CB_GETLBTEXTLEN:
2104  return SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0);
2105 
2106  case CB_GETITEMDATA:
2107  return SendMessageW(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0);
2108 
2109  case CB_SETITEMDATA:
2111 
2112  case CB_GETEDITSEL:
2113  /* Edit checks passed parameters itself */
2114  if (lphc->wState & CBF_EDIT)
2115  return SendMessageW(lphc->hWndEdit, EM_GETSEL, wParam, lParam);
2116  return CB_ERR;
2117 
2118  case CB_SETEDITSEL:
2119  if (lphc->wState & CBF_EDIT)
2121  return CB_ERR;
2122 
2123  case CB_SETEXTENDEDUI:
2124  if (CB_GETTYPE(lphc) == CBS_SIMPLE )
2125  return CB_ERR;
2126  if (wParam)
2127  lphc->wState |= CBF_EUI;
2128  else
2129  lphc->wState &= ~CBF_EUI;
2130  return CB_OKAY;
2131 
2132  case CB_GETEXTENDEDUI:
2133  return (lphc->wState & CBF_EUI) != 0;
2134 
2135  case CB_GETCOMBOBOXINFO:
2136  return COMBO_GetComboBoxInfo(lphc, (COMBOBOXINFO *)lParam);
2137 
2138  case CB_LIMITTEXT:
2139  if (lphc->wState & CBF_EDIT)
2140  return SendMessageW(lphc->hWndEdit, EM_LIMITTEXT, wParam, lParam);
2141  return TRUE;
2142 
2143  case CB_GETMINVISIBLE:
2144  return lphc->visibleItems;
2145 
2146  case CB_SETMINVISIBLE:
2147  lphc->visibleItems = (INT)wParam;
2148  return TRUE;
2149 
2150  default:
2151  if (message >= WM_USER)
2152  WARN("unknown msg WM_USER+%04x wp=%04lx lp=%08lx\n", message - WM_USER, wParam, lParam );
2153  break;
2154  }
2155 
2157 }
2158 
2159 void COMBO_Register(void)
2160 {
2161  WNDCLASSW wndClass;
2162 
2163  memset(&wndClass, 0, sizeof(wndClass));
2165  wndClass.lpfnWndProc = COMBO_WindowProc;
2166  wndClass.cbClsExtra = 0;
2167  wndClass.cbWndExtra = sizeof(HEADCOMBO *);
2168  wndClass.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
2169  wndClass.hbrBackground = NULL;
2170  wndClass.lpszClassName = WC_COMBOBOXW;
2171  RegisterClassW(&wndClass);
2172 }
2173 
2174 #ifdef __REACTOS__
2175 void COMBO_Unregister(void)
2176 {
2178 }
2179 #endif
void COMBO_Register(void)
Definition: combo.c:2159
#define CBS_OWNERDRAWFIXED
Definition: winuser.h:289
#define ISWIN31
Definition: combo.c:61
#define EM_LIMITTEXT
Definition: winuser.h:1987
#define CB_GETTOPINDEX
Definition: winuser.h:1942
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define RDW_NOCHILDREN
Definition: winuser.h:1212
#define LB_SETCURSEL
Definition: winuser.h:2050
#define WM_GETTEXTLENGTH
Definition: winuser.h:1606
BOOL WINAPI ExtTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCWSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
#define WS_DISABLED
Definition: pedump.c:621
#define CBS_SORT
Definition: winuser.h:292
#define CBN_SETFOCUS
Definition: winuser.h:1969
#define CB_SETITEMDATA
Definition: winuser.h:1953
BOOL WINAPI RedrawWindow(_In_opt_ HWND, _In_opt_ LPCRECT, _In_opt_ HRGN, _In_ UINT)
#define LB_SETLOCALE
Definition: winuser.h:2054
#define max(a, b)
Definition: svc.c:63
BOOL WINAPI InflateRect(_Inout_ LPRECT, _In_ int, _In_ int)
Definition: tftpd.h:59
#define CB_GETLBTEXTLEN
Definition: winuser.h:1940
#define LB_CARETON
Definition: undocuser.h:50
static LRESULT COMBO_SetItemHeight(LPHEADCOMBO lphc, INT index, INT height)
Definition: combo.c:1525
#define DLGC_WANTCHARS
Definition: winuser.h:2598
#define COLOR_HIGHLIGHT
Definition: winuser.h:920
#define CB_DISABLED(lphc)
Definition: combo.c:55
#define LB_DIR
Definition: winuser.h:2020
static void CBGetDroppedControlRect(LPHEADCOMBO lphc, LPRECT lpRect)
Definition: combo.c:421
#define DLGC_WANTMESSAGE
Definition: winuser.h:2593
#define LB_SETCARETINDEX
Definition: winuser.h:2047
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
#define MK_SHIFT
Definition: winuser.h:2349
#define CB_GETDROPPEDSTATE
Definition: winuser.h:1932
LPCSTR pText
Definition: txtscale.cpp:79
#define LB_FINDSTRINGEXACT
Definition: winuser.h:2022
static LRESULT CALLBACK COMBO_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: combo.c:1712
int WINAPI SelectClipRgn(_In_ HDC, _In_opt_ HRGN)
static INT CBGetTextAreaHeight(HWND hwnd, LPHEADCOMBO lphc)
Definition: combo.c:185
UINT style
Definition: winuser.h:3156
#define WM_GETDLGCODE
Definition: winuser.h:1676
static void COMBO_Font(LPHEADCOMBO lphc, HFONT hFont, BOOL bRedraw)
Definition: combo.c:1488
#define ODT_COMBOBOX
Definition: winuser.h:2519
int WINAPI MapWindowPoints(_In_opt_ HWND hWndFrom, _In_opt_ HWND hWndTo, _Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
#define WM_CHAR
Definition: winuser.h:1704
#define WM_LBUTTONDOWN
Definition: winuser.h:1763
INT visibleItems
Definition: comctl32.h:158
#define LB_SETHORIZONTALEXTENT
Definition: winuser.h:2051
#define WM_CUT
Definition: winuser.h:1848
#define error(str)
Definition: mkdosfs.c:1605
GLuint64EXT * result
Definition: glext.h:11304
#define WM_IME_CHAR
Definition: winuser.h:1821
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
#define LB_ADDSTRING
Definition: winuser.h:2018
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define LB_GETHORIZONTALEXTENT
Definition: winuser.h:2027
#define MAXLONG
Definition: umtypes.h:116
static LRESULT COMBO_GetText(HEADCOMBO *lphc, INT count, LPWSTR buf)
Definition: combo.c:1345
static void CBDropDown(LPHEADCOMBO lphc)
Definition: combo.c:959
HDC WINAPI GetDC(_In_opt_ HWND)
#define CB_SETDROPPEDWIDTH
Definition: winuser.h:1949
INT editHeight
Definition: comctl32.h:157
#define CB_SETHORIZONTALEXTENT
Definition: winuser.h:1952
#define TRUE
Definition: types.h:120
static LRESULT COMBO_Paint(HEADCOMBO *lphc, HDC hdc)
Definition: combo.c:842
#define pt(x, y)
Definition: drawing.c:79
#define WM_CTLCOLORDLG
Definition: winuser.h:1757
#define CB_GETLBTEXT
Definition: winuser.h:1939
#define SW_HIDE
Definition: winuser.h:762
HWND WINAPI SetParent(_In_ HWND, _In_opt_ HWND)
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
static void COMBO_Size(LPHEADCOMBO lphc)
Definition: combo.c:1436
#define WM_MOUSEWHEEL
Definition: treelist.c:96
#define LB_GETITEMDATA
Definition: winuser.h:2028
#define CB_GETITEMDATA
Definition: winuser.h:1937
static void CBRollUp(LPHEADCOMBO lphc, BOOL ok, BOOL bButton)
Definition: combo.c:1061
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define LBS_HASSTRINGS
Definition: pedump.c:684
WORD vk
Definition: input.c:77
#define WM_CTLCOLORSTATIC
Definition: winuser.h:1759
UINT wState
Definition: comctl32.h:149
#define WM_GETTEXT
Definition: winuser.h:1605
#define WARN(fmt,...)
Definition: debug.h:112
LPWSTR WINAPI CharLowerW(_Inout_ LPWSTR)
BOOL WINAPI DrawFocusRect(_In_ HDC, _In_ LPCRECT)
#define INT
Definition: polytest.cpp:20
#define LBN_SETFOCUS
Definition: winuser.h:2063
static HDC
Definition: imagelist.c:92
#define DFCS_INACTIVE
Definition: winuser.h:502
#define CALLBACK
Definition: compat.h:35
#define WM_SETREDRAW
Definition: winuser.h:1603
BOOL WINAPI UpdateWindow(_In_ HWND)
HWND hWnd
Definition: settings.c:17
ULONG_PTR itemData
Definition: winuser.h:3073
LONG top
Definition: windef.h:307
static void COMBO_LButtonUp(LPHEADCOMBO lphc)
Definition: combo.c:1627
HANDLE HWND
Definition: compat.h:19
HWND hWndEdit
Definition: comctl32.h:147
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
#define ODS_FOCUS
Definition: winuser.h:2529
#define WM_PASTE
Definition: winuser.h:1850
#define ES_COMBO
Definition: edit.c:29
#define LBS_SORT
Definition: pedump.c:679
static HTHEME(WINAPI *pOpenThemeDataEx)(HWND
RECT droppedRect
Definition: comctl32.h:153
static void CBCalcPlacement(HWND hwnd, LPHEADCOMBO lphc, LPRECT lprEdit, LPRECT lprButton, LPRECT lprLB)
Definition: combo.c:311
#define CS_HREDRAW
Definition: winuser.h:648
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
static HBITMAP hComboBmp
Definition: combo.c:66
#define GWL_EXSTYLE
Definition: winuser.h:845
#define HWND_TOPMOST
Definition: winuser.h:1198
#define ID_CB_LISTBOX
Definition: combo.c:79
int cbClsExtra
Definition: winuser.h:3158
HWND WINAPI SetFocus(_In_opt_ HWND)
#define WM_CTLCOLOR
Definition: windowsx.h:4
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define LBS_COMBOBOX
Definition: winuser.h:324
#define CB_OWNERDRAWN(lphc)
Definition: combo.c:56
RECT buttonRect
Definition: comctl32.h:152
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
INT droppedIndex
Definition: comctl32.h:154
BOOL WINAPI DrawFrameControl(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
UINT_PTR WPARAM
Definition: windef.h:207
#define CBS_AUTOHSCROLL
Definition: winuser.h:281
#define VK_DOWN
Definition: winuser.h:2207
#define WS_CHILD
Definition: pedump.c:617
#define GetWindowLongPtrW
Definition: winuser.h:4809
static LRESULT COMBO_ItemOp(LPHEADCOMBO lphc, UINT msg, LPARAM lParam)
Definition: combo.c:1297
LONG left
Definition: windef.h:306
static HBRUSH COMBO_PrepareColors(LPHEADCOMBO lphc, HDC hDC)
Definition: combo.c:617
#define SWP_NOZORDER
Definition: winuser.h:1237
#define CB_SETLOCALE
Definition: winuser.h:1955
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define CBS_OEMCONVERT
Definition: winuser.h:288
#define VK_ESCAPE
Definition: winuser.h:2194
BOOL WINAPI InvertRect(_In_ HDC, _In_ LPCRECT)
#define WM_CLEAR
Definition: winuser.h:1851
LONG right
Definition: windef.h:308
static LRESULT COMBO_NCDestroy(HEADCOMBO *lphc)
Definition: combo.c:157
#define WM_CTLCOLORLISTBOX
Definition: winuser.h:1755
#define WM_NCCREATE
Definition: winuser.h:1670
BOOL WINAPI DestroyWindow(_In_ HWND)
#define LBN_SELCHANGE
Definition: winuser.h:2062
HRESULT WINAPI DrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect)
Definition: draw.c:128
#define WS_EX_TOOLWINDOW
Definition: winuser.h:404
#define COLOR_WINDOW
Definition: winuser.h:912
HRGN set_control_clipping(HDC hdc, const RECT *rect)
Definition: button.c:239
int32_t INT
Definition: typedefs.h:58
static UINT CBitWidth
Definition: combo.c:67
#define VK_RETURN
Definition: winuser.h:2181
#define CB_GETCURSEL
Definition: winuser.h:1930
DWORD WINAPI GetSysColor(_In_ int)
& rect
Definition: startmenu.cpp:1413
WPARAM wParam
Definition: combotst.c:138
#define LB_SELECTSTRING
Definition: winuser.h:2043
#define CBS_OWNERDRAWVARIABLE
Definition: winuser.h:290
HFONT hFont
Definition: main.c:53
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
static void CBUpdateEdit(LPHEADCOMBO lphc, INT index)
Definition: combo.c:923
#define WM_ENABLE
Definition: winuser.h:1602
LPWSTR WINAPI CharUpperW(_Inout_ LPWSTR)
#define WM_PRINTCLIENT
Definition: richedit.h:70
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define lstrcpynW
Definition: compat.h:597
#define CB_SETITEMHEIGHT
Definition: winuser.h:1954
#define LB_SETITEMHEIGHT
Definition: winuser.h:2053
#define EM_GETSEL
Definition: winuser.h:1984
#define CB_GETTYPE(lphc)
Definition: combo.c:59
#define CB_GETEDITSEL
Definition: winuser.h:1934
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:999
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
#define BF_RECT
Definition: winuser.h:462
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define CB_INITSTORAGE
Definition: winuser.h:1943
#define DFCS_PUSHED
Definition: winuser.h:503
static UINT CBitHeight
Definition: combo.c:67
#define LB_RESETCONTENT
Definition: winuser.h:2042
#define LBN_SELCANCEL
Definition: winuser.h:2061
#define EN_KILLFOCUS
Definition: winuser.h:2012
#define EDIT_CONTROL_PADDING()
Definition: combo.c:77
#define EN_SETFOCUS
Definition: winuser.h:2014
#define CB_GETDROPPEDWIDTH
Definition: winuser.h:1933
#define WM_CTLCOLORBTN
Definition: winuser.h:1756
#define VK_UP
Definition: winuser.h:2205
static void CBPaintBorder(HWND hwnd, const HEADCOMBO *lphc, HDC hdc)
Definition: combo.c:780
#define FALSE
Definition: types.h:117
#define ETO_OPAQUE
Definition: wingdi.h:647
static LRESULT COMBO_Command(LPHEADCOMBO lphc, WPARAM wParam, HWND hWnd)
Definition: combo.c:1188
#define LB_ERR
Definition: winuser.h:2412
#define WM_COPY
Definition: winuser.h:1849
#define CB_NOTIFY(lphc, code)
Definition: combo.c:51
static UINT msg
Definition: combo.c:716
INT fixedOwnerDrawHeight
Definition: comctl32.h:155
#define LBS_NOINTEGRALHEIGHT
Definition: pedump.c:686
unsigned int BOOL
Definition: ntddk_ex.h:94
#define CBN_SELENDOK
Definition: winuser.h:1968
long LONG
Definition: pedump.c:60
#define WM_DELETEITEM
Definition: winuser.h:1634
static void COMBO_KillFocus(LPHEADCOMBO lphc)
Definition: combo.c:1162
#define CB_SHOWDROPDOWN
Definition: winuser.h:1957
LONG WINAPI SetWindowLongW(_In_ HWND, _In_ int, _In_ LONG)
short SHORT
Definition: pedump.c:59
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
BOOL WINAPI DrawEdge(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
#define CBN_KILLFOCUS
Definition: winuser.h:1965
WNDPROC lpfnWndProc
Definition: winuser.h:3157
HWND WINAPI GetCapture(void)
Definition: message.c:2881
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define FIXME(fmt,...)
Definition: debug.h:111
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define CBS_SIMPLE
Definition: winuser.h:291
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
#define WM_CTLCOLORSCROLLBAR
Definition: winuser.h:1758
#define STATE_SYSTEM_PRESSED
Definition: winuser.h:2845
#define VK_F4
Definition: winuser.h:2238
unsigned int idx
Definition: utils.c:41
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
#define CB_HASSTRINGS(lphc)
Definition: combo.c:57
#define CB_ADDSTRING
Definition: winuser.h:1923
int nItems
Definition: appswitch.c:56
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define ES_UPPERCASE
Definition: pedump.c:668
#define CB_INSERTSTRING
Definition: winuser.h:1944
#define CBN_DBLCLK
Definition: winuser.h:1960
WINE_DEFAULT_DEBUG_CHANNEL(combo)
#define CB_GETCOMBOBOXINFO
Definition: winuser.h:1928
#define WM_GETFONT
Definition: winuser.h:1638
static LRESULT COMBO_Create(HWND hwnd, LPHEADCOMBO lphc, HWND hwndParent, LONG style)
Definition: combo.c:436
#define EN_ERRSPACE
Definition: winuser.h:2010
static HWND hwndParent
Definition: cryptui.c:300
#define WM_KEYDOWN
Definition: winuser.h:1702
LPCWSTR lpszClassName
Definition: winuser.h:3165
#define WM_CTLCOLORMSGBOX
Definition: winuser.h:1753
LONG_PTR LPARAM
Definition: windef.h:208
#define CBS_DROPDOWNLIST
Definition: winuser.h:284
BOOL WINAPI IsWindowEnabled(_In_ HWND)
#define CB_LIMITTEXT
Definition: winuser.h:1945
#define CB_SETMINVISIBLE
Definition: commctrl.h:4721
#define ETO_CLIPPED
Definition: wingdi.h:648
GLuint index
Definition: glext.h:6031
static void CBRepaintButton(LPHEADCOMBO lphc)
Definition: combo.c:1131
#define LB_GETTEXTLEN
Definition: winuser.h:2037
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:921
#define LB_GETCOUNT
Definition: winuser.h:2025
#define WM_SETTEXT
Definition: winuser.h:1604
#define CB_RESETCONTENT
Definition: winuser.h:1946
#define CBS_HASSTRINGS
Definition: winuser.h:285
RECT textRect
Definition: comctl32.h:151
#define CB_ERR
Definition: winuser.h:2415
#define LB_INITSTORAGE
Definition: winuser.h:2039
#define WM_DESTROY
Definition: winuser.h:1596
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
HWND hWndLBox
Definition: comctl32.h:148
#define CS_VREDRAW
Definition: winuser.h:653
#define ODA_DRAWENTIRE
Definition: winuser.h:2522
#define TRACE(s)
Definition: solgame.cpp:4
#define OBM_COMBO
Definition: winuser.h:1106
#define WM_KILLFOCUS
Definition: winuser.h:1601
GLsizeiptr size
Definition: glext.h:5919
#define CB_GETDROPPEDCONTROLRECT
Definition: winuser.h:1931
#define CBN_EDITCHANGE
Definition: winuser.h:1962
DWORD stateButton
Definition: winuser.h:3692
static void CBResetPos(LPHEADCOMBO lphc, const RECT *rectEdit, const RECT *rectLB, BOOL bRedraw)
Definition: combo.c:1394
#define LB_SETTOPINDEX
Definition: winuser.h:2057
int cbWndExtra
Definition: winuser.h:3159
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define WM_SIZE
Definition: winuser.h:1598
#define ODS_DISABLED
Definition: winuser.h:2527
BOOL WINAPI GetMonitorInfoW(_In_ HMONITOR, _Inout_ LPMONITORINFO)
static LRESULT COMBO_NCCreate(HWND hwnd, LONG style)
Definition: combo.c:122
#define SWP_NOACTIVATE
Definition: winuser.h:1232
#define RDW_ERASE
Definition: winuser.h:1201
#define CS_GLOBALCLASS
Definition: winuser.h:647
#define WM_NCDESTROY
Definition: winuser.h:1671
#define EM_SETSEL
Definition: winuser.h:2005
const char * wine_dbgstr_rect(const RECT *rect)
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
#define LBN_ERRSPACE
Definition: winuser.h:2059
int WINAPI GetSystemMetrics(_In_ int)
#define WM_MEASUREITEM
Definition: winuser.h:1633
#define LB_CARETOFF
Definition: undocuser.h:51
static BOOL COMBO_Init(void)
Definition: combo.c:87
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2074
BOOL WINAPI UnionRect(_Out_ LPRECT, _In_ LPCRECT, _In_ LPCRECT)
HFONT hFont
Definition: comctl32.h:150
#define LB_SETITEMDATA
Definition: winuser.h:2052
#define LBN_DBLCLK
Definition: winuser.h:2058
HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR classlist)
Definition: system.c:835
#define CBN_SELENDCANCEL
Definition: winuser.h:1967
#define ES_NOHIDESEL
Definition: pedump.c:673
#define WS_HSCROLL
Definition: pedump.c:628
#define WM_PAINT
Definition: winuser.h:1607
#define CB_GETHORIZONTALEXTENT
Definition: winuser.h:1936
HTHEME WINAPI GetWindowTheme(HWND hwnd)
Definition: system.c:851
#define COMBO_YBORDERSIZE()
Definition: combo.c:75
int ret
INT droppedWidth
Definition: comctl32.h:156
#define KEYDATA_ALT
Definition: combo.c:44
#define COLOR_GRAYTEXT
Definition: winuser.h:926
#define CB_GETMINVISIBLE
Definition: commctrl.h:4722
#define index(s, c)
Definition: various.h:29
#define LB_GETTEXT
Definition: winuser.h:2036
#define CBN_ERRSPACE
Definition: winuser.h:1964
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
HDC hdc
Definition: main.c:9
static void CBForceDummyResize(LPHEADCOMBO lphc)
Definition: combo.c:280
#define CB_SELECTSTRING
Definition: winuser.h:1947
static void CBPaintButton(LPHEADCOMBO lphc, HDC hdc, RECT rectButton)
Definition: combo.c:592
#define LB_GETLOCALE
Definition: winuser.h:2032
ULONG_PTR itemData
Definition: winuser.h:3626
#define WS_EX_TOPMOST
Definition: pedump.c:647
#define CB_SETCURSEL
Definition: winuser.h:1948
#define CS_DBLCLKS
Definition: winuser.h:646
Definition: time.h:68
#define WM_COMMAND
Definition: winuser.h:1727
#define COMBO_XBORDERSIZE()
Definition: combo.c:74
#define WM_USER
Definition: winuser.h:1882
#define LB_GETITEMHEIGHT
Definition: winuser.h:2029
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
#define CBS_UPPERCASE
Definition: winuser.h:293
BOOL WINAPI EnableWindow(_In_ HWND, _In_ BOOL)
HCURSOR hCursor
Definition: winuser.h:3162
#define ERR(fmt,...)
Definition: debug.h:110
#define ID_CB_EDIT
Definition: combo.c:80
#define GWL_STYLE
Definition: winuser.h:846
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:911
static HDC hDC
Definition: 3dtext.c:33
#define CB_OKAY
Definition: winuser.h:2414
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
static void COMBO_LButtonDown(LPHEADCOMBO lphc, LPARAM lParam)
Definition: combo.c:1582
#define CBN_DROPDOWN
Definition: winuser.h:1961
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
HWND WINAPI SetCapture(_In_ HWND hWnd)
#define WM_COMPAREITEM
Definition: winuser.h:1642
#define LB_FINDSTRING
Definition: winuser.h:2021
#define WS_BORDER
Definition: pedump.c:625
#define LBS_NOTIFY
Definition: pedump.c:678
#define WS_EX_NOPARENTNOTIFY
Definition: pedump.c:646
BOOL COMBO_FlipListbox(LPHEADCOMBO lphc, BOOL ok, BOOL bRedrawButton)
Definition: combo.c:1116
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1412
HWND self
Definition: comctl32.h:144
BOOL WINAPI DeleteDC(_In_ HDC)
#define CB_DIR
Definition: winuser.h:1925
#define CB_SETEDITSEL
Definition: winuser.h:1950
HBITMAP WINAPI LoadBitmapW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2132
#define CBS_LOWERCASE
Definition: winuser.h:286
#define LBS_DISABLENOSCROLL
Definition: pedump.c:690
GLuint start
Definition: gl.h:1545
static void COMBO_MouseMove(LPHEADCOMBO lphc, WPARAM wParam, LPARAM lParam)
Definition: combo.c:1660
DWORD cbSize
Definition: winuser.h:3764
#define WM_CTLCOLOREDIT
Definition: winuser.h:1754
HBRUSH hbrBackground
Definition: winuser.h:3163
#define CBS_DROPDOWN
Definition: winuser.h:283
#define LB_GETTOPINDEX
Definition: winuser.h:2038
static INT CBUpdateLBox(LPHEADCOMBO lphc, BOOL bSelect)
Definition: combo.c:889
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define ok(value,...)
Definition: atltest.h:57
#define WM_LBUTTONUP
Definition: winuser.h:1764
Definition: bl.h:1330
#define CB_SETEXTENDEDUI
Definition: winuser.h:1951
static void COMBO_SetFocus(LPHEADCOMBO lphc)
Definition: combo.c:1140
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define CB_GETLOCALE
Definition: winuser.h:1941
#define DFCS_SCROLLCOMBOBOX
Definition: winuser.h:493
#define HWND_DESKTOP
Definition: winuser.h:1199
#define min(a, b)
Definition: monoChain.cc:55
#define LB_GETCURSEL
Definition: winuser.h:2026
unsigned int UINT
Definition: ndis.h:50
#define WM_MOUSEMOVE
Definition: winuser.h:1762
#define NULL
Definition: types.h:112
#define WS_VSCROLL
Definition: pedump.c:627
static LRESULT COMBO_GetComboBoxInfo(const HEADCOMBO *lphc, COMBOBOXINFO *pcbi)
Definition: combo.c:1694
static LRESULT COMBO_ThemedPaint(HTHEME theme, HEADCOMBO *lphc, HDC hdc)
Definition: combo.c:802
#define SWP_SHOWWINDOW
Definition: winuser.h:1238
#define SWP_NOREDRAW
Definition: winuser.h:1236
#define SM_CXVSCROLL
Definition: winuser.h:955
#define CBN_SELCHANGE
Definition: winuser.h:1966
#define MK_CONTROL
Definition: winuser.h:2350
#define DFC_SCROLL
Definition: winuser.h:475
#define WM_SETFONT
Definition: winuser.h:1637
HWND owner
Definition: comctl32.h:145
#define WM_DRAWITEM
Definition: winuser.h:1632
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
#define RDW_UPDATENOW
Definition: winuser.h:1210
#define IDC_ARROW
Definition: winuser.h:682
#define GWLP_HINSTANCE
Definition: winuser.h:850
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2890
#define ES_OEMCONVERT
Definition: pedump.c:674
#define ODS_SELECTED
Definition: winuser.h:2525
#define WM_CREATE
Definition: winuser.h:1595
BOOL WINAPI CopyRect(_Out_ LPRECT, _In_ LPCRECT)
#define CB_GETITEMHEIGHT
Definition: winuser.h:1938
#define WM_SYSKEYDOWN
Definition: winuser.h:1706
#define CBN_EDITUPDATE
Definition: winuser.h:1963
#define HIWORD(l)
Definition: typedefs.h:247
GLenum GLuint id
Definition: glext.h:5579
BOOL WINAPI IsWindowVisible(_In_ HWND)
HMONITOR WINAPI MonitorFromRect(LPCRECT, DWORD)
LONG bottom
Definition: windef.h:309
#define EN_UPDATE
Definition: winuser.h:2015
#define SWP_NOMOVE
Definition: winuser.h:1234
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define EDGE_SUNKEN
Definition: winuser.h:451
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define CB_GETCOUNT
Definition: winuser.h:1929
#define SetWindowLongPtrW
Definition: winuser.h:5326
static HBITMAP
Definition: button.c:44
#define CB_GETEXTENDEDUI
Definition: winuser.h:1935
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define WM_ERASEBKGND
Definition: winuser.h:1612
#define WM_SETFOCUS
Definition: winuser.h:1600
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define CB_DELETESTRING
Definition: winuser.h:1924
#define COMBO_EDITBUTTONSPACE()
Definition: combo.c:76
LONG_PTR LRESULT
Definition: windef.h:209
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
Arabic default style
Definition: afstyles.h:93
#define LB_DELETESTRING
Definition: winuser.h:2019
#define ES_LEFT
Definition: pedump.c:664
#define WS_VISIBLE
Definition: pedump.c:620
HBRUSH WINAPI GetSysColorBrush(_In_ int)
#define memset(x, y, z)
Definition: compat.h:39
#define CBN_CLOSEUP
Definition: winuser.h:1959
#define CBS_NOINTEGRALHEIGHT
Definition: winuser.h:287
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define CB_FINDSTRING
Definition: winuser.h:1926
static const WCHAR empty_stringW[]
Definition: edit.c:171
#define LB_INSERTSTRING
Definition: winuser.h:2040
LPARAM lParam
Definition: combotst.c:139
#define ES_AUTOHSCROLL
Definition: pedump.c:672
#define LOWORD(l)
Definition: pedump.c:82
#define GWLP_ID
Definition: winuser.h:854
#define DLGC_WANTARROWS
Definition: winuser.h:2590
#define STATE_SYSTEM_INVISIBLE
Definition: winuser.h:2857
#define CS_PARENTDC
Definition: winuser.h:651
HRESULT WINAPI CloseThemeData(HTHEME hTheme)
Definition: system.c:950
UINT dwStyle
Definition: comctl32.h:146
#define RDW_INVALIDATE
Definition: winuser.h:1204
static LRESULT COMBO_SelectString(LPHEADCOMBO lphc, INT start, LPARAM pText)
Definition: combo.c:1564
int WINAPI FrameRect(_In_ HDC, _In_ LPCRECT, _In_ HBRUSH)
#define LBN_KILLFOCUS
Definition: winuser.h:2060
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
static void CBPaintText(HEADCOMBO *lphc, HDC hdc_paint)
Definition: combo.c:659
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define CBS_DISABLENOSCROLL
Definition: winuser.h:282
#define WC_COMBOBOXW
Definition: commctrl.h:4717
#define ES_LOWERCASE
Definition: pedump.c:669
#define EN_CHANGE
Definition: winuser.h:2009
#define CB_FINDSTRINGEXACT
Definition: winuser.h:1927