ReactOS  0.4.13-dev-249-gcba1a2f
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) )
1049  RedrawWindow( lphc->self, NULL, 0, RDW_INVALIDATE |
1051 
1052  EnableWindow( lphc->hWndLBox, TRUE );
1053  if (GetCapture() != lphc->self)
1054  SetCapture(lphc->hWndLBox);
1055 }
1056 
1057 /***********************************************************************
1058  * CBRollUp
1059  *
1060  * Hide listbox popup.
1061  */
1062 static void CBRollUp( LPHEADCOMBO lphc, BOOL ok, BOOL bButton )
1063 {
1064  HWND hWnd = lphc->self;
1065 
1066  TRACE("[%p]: sel ok? [%i] dropped? [%i]\n",
1067  lphc->self, ok, (INT)(lphc->wState & CBF_DROPPED));
1068 
1069  CB_NOTIFY( lphc, (ok) ? CBN_SELENDOK : CBN_SELENDCANCEL );
1070 
1071  if( IsWindow( hWnd ) && CB_GETTYPE(lphc) != CBS_SIMPLE )
1072  {
1073 
1074  if( lphc->wState & CBF_DROPPED )
1075  {
1076  RECT rect;
1077 
1078  lphc->wState &= ~CBF_DROPPED;
1079  ShowWindow( lphc->hWndLBox, SW_HIDE );
1080 
1081  if(GetCapture() == lphc->hWndLBox)
1082  {
1083  ReleaseCapture();
1084  }
1085 
1086  if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
1087  {
1088  rect = lphc->buttonRect;
1089  }
1090  else
1091  {
1092  if( bButton )
1093  {
1094  UnionRect( &rect,
1095  &lphc->buttonRect,
1096  &lphc->textRect);
1097  }
1098  else
1099  rect = lphc->textRect;
1100 
1101  bButton = TRUE;
1102  }
1103 
1104  if( bButton && !(lphc->wState & CBF_NOREDRAW) )
1107  CB_NOTIFY( lphc, CBN_CLOSEUP );
1108  }
1109  }
1110 }
1111 
1112 /***********************************************************************
1113  * COMBO_FlipListbox
1114  *
1115  * Used by the ComboLBox to show/hide itself in response to VK_F4, etc...
1116  */
1118 {
1119  if( lphc->wState & CBF_DROPPED )
1120  {
1121  CBRollUp( lphc, ok, bRedrawButton );
1122  return FALSE;
1123  }
1124 
1125  CBDropDown( lphc );
1126  return TRUE;
1127 }
1128 
1129 /***********************************************************************
1130  * CBRepaintButton
1131  */
1132 static void CBRepaintButton( LPHEADCOMBO lphc )
1133  {
1134  InvalidateRect(lphc->self, &lphc->buttonRect, TRUE);
1135  UpdateWindow(lphc->self);
1136 }
1137 
1138 /***********************************************************************
1139  * COMBO_SetFocus
1140  */
1141 static void COMBO_SetFocus( LPHEADCOMBO lphc )
1142 {
1143  if( !(lphc->wState & CBF_FOCUSED) )
1144  {
1145  if( CB_GETTYPE(lphc) == CBS_DROPDOWNLIST )
1146  SendMessageW(lphc->hWndLBox, LB_CARETON, 0, 0);
1147 
1148  /* This is wrong. Message sequences seem to indicate that this
1149  is set *after* the notify. */
1150  /* lphc->wState |= CBF_FOCUSED; */
1151 
1152  if( !(lphc->wState & CBF_EDIT) )
1153  InvalidateRect(lphc->self, &lphc->textRect, TRUE);
1154 
1155  CB_NOTIFY( lphc, CBN_SETFOCUS );
1156  lphc->wState |= CBF_FOCUSED;
1157  }
1158 }
1159 
1160 /***********************************************************************
1161  * COMBO_KillFocus
1162  */
1163 static void COMBO_KillFocus( LPHEADCOMBO lphc )
1164 {
1165  HWND hWnd = lphc->self;
1166 
1167  if( lphc->wState & CBF_FOCUSED )
1168  {
1169  CBRollUp( lphc, FALSE, TRUE );
1170  if( IsWindow( hWnd ) )
1171  {
1172  if( CB_GETTYPE(lphc) == CBS_DROPDOWNLIST )
1173  SendMessageW(lphc->hWndLBox, LB_CARETOFF, 0, 0);
1174 
1175  lphc->wState &= ~CBF_FOCUSED;
1176 
1177  /* redraw text */
1178  if( !(lphc->wState & CBF_EDIT) )
1179  InvalidateRect(lphc->self, &lphc->textRect, TRUE);
1180 
1181  CB_NOTIFY( lphc, CBN_KILLFOCUS );
1182  }
1183  }
1184 }
1185 
1186 /***********************************************************************
1187  * COMBO_Command
1188  */
1190 {
1191  if ( lphc->wState & CBF_EDIT && lphc->hWndEdit == hWnd )
1192  {
1193  /* ">> 8" makes gcc generate jump-table instead of cmp ladder */
1194 
1195  switch( HIWORD(wParam) >> 8 )
1196  {
1197  case (EN_SETFOCUS >> 8):
1198 
1199  TRACE("[%p]: edit [%p] got focus\n", lphc->self, lphc->hWndEdit );
1200 
1201  COMBO_SetFocus( lphc );
1202  break;
1203 
1204  case (EN_KILLFOCUS >> 8):
1205 
1206  TRACE("[%p]: edit [%p] lost focus\n", lphc->self, lphc->hWndEdit );
1207 
1208  /* NOTE: it seems that Windows' edit control sends an
1209  * undocumented message WM_USER + 0x1B instead of this
1210  * notification (only when it happens to be a part of
1211  * the combo). ?? - AK.
1212  */
1213 
1214  COMBO_KillFocus( lphc );
1215  break;
1216 
1217 
1218  case (EN_CHANGE >> 8):
1219  /*
1220  * In some circumstances (when the selection of the combobox
1221  * is changed for example) we don't want the EN_CHANGE notification
1222  * to be forwarded to the parent of the combobox. This code
1223  * checks a flag that is set in these occasions and ignores the
1224  * notification.
1225  */
1226  if (lphc->wState & CBF_NOLBSELECT)
1227  {
1228  lphc->wState &= ~CBF_NOLBSELECT;
1229  }
1230  else
1231  {
1232  CBUpdateLBox( lphc, lphc->wState & CBF_DROPPED );
1233  }
1234 
1235  if (!(lphc->wState & CBF_NOEDITNOTIFY))
1236  CB_NOTIFY( lphc, CBN_EDITCHANGE );
1237  break;
1238 
1239  case (EN_UPDATE >> 8):
1240  if (!(lphc->wState & CBF_NOEDITNOTIFY))
1241  CB_NOTIFY( lphc, CBN_EDITUPDATE );
1242  break;
1243 
1244  case (EN_ERRSPACE >> 8):
1245  CB_NOTIFY( lphc, CBN_ERRSPACE );
1246  }
1247  }
1248  else if( lphc->hWndLBox == hWnd )
1249  {
1250  switch( (short)HIWORD(wParam) )
1251  {
1252  case LBN_ERRSPACE:
1253  CB_NOTIFY( lphc, CBN_ERRSPACE );
1254  break;
1255 
1256  case LBN_DBLCLK:
1257  CB_NOTIFY( lphc, CBN_DBLCLK );
1258  break;
1259 
1260  case LBN_SELCHANGE:
1261  case LBN_SELCANCEL:
1262 
1263  TRACE("[%p]: lbox selection change [%x]\n", lphc->self, lphc->wState );
1264 
1265  /* do not roll up if selection is being tracked
1266  * by arrow keys in the dropdown listbox */
1267  if (!(lphc->wState & CBF_NOROLLUP))
1268  {
1269  CBRollUp( lphc, (HIWORD(wParam) == LBN_SELCHANGE), TRUE );
1270  }
1271  else lphc->wState &= ~CBF_NOROLLUP;
1272 
1273  CB_NOTIFY( lphc, CBN_SELCHANGE );
1274 
1275  if( HIWORD(wParam) == LBN_SELCHANGE)
1276  {
1277  if( lphc->wState & CBF_EDIT )
1278  lphc->wState |= CBF_NOLBSELECT;
1279  CBPaintText( lphc, NULL );
1280  }
1281  break;
1282 
1283  case LBN_SETFOCUS:
1284  case LBN_KILLFOCUS:
1285  /* nothing to do here since ComboLBox always resets the focus to its
1286  * combo/edit counterpart */
1287  break;
1288  }
1289  }
1290  return 0;
1291 }
1292 
1293 /***********************************************************************
1294  * COMBO_ItemOp
1295  *
1296  * Fixup an ownerdrawn item operation and pass it up to the combobox owner.
1297  */
1299 {
1300  HWND hWnd = lphc->self;
1302 
1303  TRACE("[%p]: ownerdraw op %04x\n", lphc->self, msg );
1304 
1305  switch( msg )
1306  {
1307  case WM_DELETEITEM:
1308  {
1310  lpIS->CtlType = ODT_COMBOBOX;
1311  lpIS->CtlID = id;
1312  lpIS->hwndItem = hWnd;
1313  break;
1314  }
1315  case WM_DRAWITEM:
1316  {
1318  lpIS->CtlType = ODT_COMBOBOX;
1319  lpIS->CtlID = id;
1320  lpIS->hwndItem = hWnd;
1321  break;
1322  }
1323  case WM_COMPAREITEM:
1324  {
1326  lpIS->CtlType = ODT_COMBOBOX;
1327  lpIS->CtlID = id;
1328  lpIS->hwndItem = hWnd;
1329  break;
1330  }
1331  case WM_MEASUREITEM:
1332  {
1334  lpIS->CtlType = ODT_COMBOBOX;
1335  lpIS->CtlID = id;
1336  break;
1337  }
1338  }
1339  return SendMessageW(lphc->owner, msg, id, lParam);
1340 }
1341 
1342 
1343 /***********************************************************************
1344  * COMBO_GetTextW
1345  */
1347 {
1348  INT length;
1349 
1350  if( lphc->wState & CBF_EDIT )
1351  return SendMessageW( lphc->hWndEdit, WM_GETTEXT, count, (LPARAM)buf );
1352 
1353  /* get it from the listbox */
1354 
1355  if (!count || !buf) return 0;
1356  if( lphc->hWndLBox )
1357  {
1358  INT idx = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
1359  if (idx == LB_ERR) goto error;
1360  length = SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, idx, 0 );
1361  if (length == LB_ERR) goto error;
1362 
1363  /* 'length' is without the terminating character */
1364  if (length >= count)
1365  {
1366  WCHAR *lpBuffer = heap_alloc((length + 1) * sizeof(WCHAR));
1367  if (!lpBuffer) goto error;
1369 
1370  /* truncate if buffer is too short */
1371  if (length != LB_ERR)
1372  {
1373  lstrcpynW( buf, lpBuffer, count );
1374  length = count;
1375  }
1376  heap_free( lpBuffer );
1377  }
1378  else length = SendMessageW(lphc->hWndLBox, LB_GETTEXT, idx, (LPARAM)buf);
1379 
1380  if (length == LB_ERR) return 0;
1381  return length;
1382  }
1383 
1384  error: /* error - truncate string, return zero */
1385  buf[0] = 0;
1386  return 0;
1387 }
1388 
1389 /***********************************************************************
1390  * CBResetPos
1391  *
1392  * This function sets window positions according to the updated
1393  * component placement struct.
1394  */
1395 static void CBResetPos(
1396  LPHEADCOMBO lphc,
1397  const RECT *rectEdit,
1398  const RECT *rectLB,
1399  BOOL bRedraw)
1400 {
1401  BOOL bDrop = (CB_GETTYPE(lphc) != CBS_SIMPLE);
1402 
1403  /* NOTE: logs sometimes have WM_LBUTTONUP before a cascade of
1404  * sizing messages */
1405 
1406  if( lphc->wState & CBF_EDIT )
1407  SetWindowPos( lphc->hWndEdit, 0,
1408  rectEdit->left, rectEdit->top,
1409  rectEdit->right - rectEdit->left,
1410  rectEdit->bottom - rectEdit->top,
1411  SWP_NOZORDER | SWP_NOACTIVATE | ((bDrop) ? SWP_NOREDRAW : 0) );
1412 
1413  SetWindowPos( lphc->hWndLBox, 0,
1414  rectLB->left, rectLB->top,
1415  rectLB->right - rectLB->left,
1416  rectLB->bottom - rectLB->top,
1417  SWP_NOACTIVATE | SWP_NOZORDER | ((bDrop) ? SWP_NOREDRAW : 0) );
1418 
1419  if( bDrop )
1420  {
1421  if( lphc->wState & CBF_DROPPED )
1422  {
1423  lphc->wState &= ~CBF_DROPPED;
1424  ShowWindow( lphc->hWndLBox, SW_HIDE );
1425  }
1426 
1427  if( bRedraw && !(lphc->wState & CBF_NOREDRAW) )
1428  RedrawWindow( lphc->self, NULL, 0,
1430  }
1431 }
1432 
1433 
1434 /***********************************************************************
1435  * COMBO_Size
1436  */
1437 static void COMBO_Size( LPHEADCOMBO lphc )
1438 {
1439  /*
1440  * Those controls are always the same height. So we have to make sure
1441  * they are not resized to another value.
1442  */
1443  if( CB_GETTYPE(lphc) != CBS_SIMPLE )
1444  {
1445  int newComboHeight, curComboHeight, curComboWidth;
1446  RECT rc;
1447 
1448  GetWindowRect(lphc->self, &rc);
1449  curComboHeight = rc.bottom - rc.top;
1450  curComboWidth = rc.right - rc.left;
1451  newComboHeight = CBGetTextAreaHeight(lphc->self, lphc) + 2*COMBO_YBORDERSIZE();
1452 
1453  /*
1454  * Resizing a combobox has another side effect, it resizes the dropped
1455  * rectangle as well. However, it does it only if the new height for the
1456  * combobox is more than the height it should have. In other words,
1457  * if the application resizing the combobox only had the intention to resize
1458  * the actual control, for example, to do the layout of a dialog that is
1459  * resized, the height of the dropdown is not changed.
1460  */
1461  if( curComboHeight > newComboHeight )
1462  {
1463  TRACE("oldComboHeight=%d, newComboHeight=%d, oldDropBottom=%d, oldDropTop=%d\n",
1464  curComboHeight, newComboHeight, lphc->droppedRect.bottom,
1465  lphc->droppedRect.top);
1466  lphc->droppedRect.bottom = lphc->droppedRect.top + curComboHeight - newComboHeight;
1467  }
1468  /*
1469  * Restore original height
1470  */
1471  if( curComboHeight != newComboHeight )
1472  SetWindowPos(lphc->self, 0, 0, 0, curComboWidth, newComboHeight,
1474  }
1475 
1476  CBCalcPlacement(lphc->self,
1477  lphc,
1478  &lphc->textRect,
1479  &lphc->buttonRect,
1480  &lphc->droppedRect);
1481 
1482  CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
1483 }
1484 
1485 
1486 /***********************************************************************
1487  * COMBO_Font
1488  */
1489 static void COMBO_Font( LPHEADCOMBO lphc, HFONT hFont, BOOL bRedraw )
1490 {
1491  /*
1492  * Set the font
1493  */
1494  lphc->hFont = hFont;
1495 
1496  /*
1497  * Propagate to owned windows.
1498  */
1499  if( lphc->wState & CBF_EDIT )
1500  SendMessageW(lphc->hWndEdit, WM_SETFONT, (WPARAM)hFont, bRedraw);
1501  SendMessageW(lphc->hWndLBox, WM_SETFONT, (WPARAM)hFont, bRedraw);
1502 
1503  /*
1504  * Redo the layout of the control.
1505  */
1506  if ( CB_GETTYPE(lphc) == CBS_SIMPLE)
1507  {
1508  CBCalcPlacement(lphc->self,
1509  lphc,
1510  &lphc->textRect,
1511  &lphc->buttonRect,
1512  &lphc->droppedRect);
1513 
1514  CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
1515  }
1516  else
1517  {
1518  CBForceDummyResize(lphc);
1519  }
1520 }
1521 
1522 
1523 /***********************************************************************
1524  * COMBO_SetItemHeight
1525  */
1527 {
1528  LRESULT lRet = CB_ERR;
1529 
1530  if( index == -1 ) /* set text field height */
1531  {
1532  if( height < 32768 )
1533  {
1534  lphc->editHeight = height + 2; /* Is the 2 for 2*EDIT_CONTROL_PADDING? */
1535 
1536  /*
1537  * Redo the layout of the control.
1538  */
1539  if ( CB_GETTYPE(lphc) == CBS_SIMPLE)
1540  {
1541  CBCalcPlacement(lphc->self,
1542  lphc,
1543  &lphc->textRect,
1544  &lphc->buttonRect,
1545  &lphc->droppedRect);
1546 
1547  CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
1548  }
1549  else
1550  {
1551  CBForceDummyResize(lphc);
1552  }
1553 
1554  lRet = height;
1555  }
1556  }
1557  else if ( CB_OWNERDRAWN(lphc) ) /* set listbox item height */
1559  return lRet;
1560 }
1561 
1562 /***********************************************************************
1563  * COMBO_SelectString
1564  */
1566 {
1568  if( index >= 0 )
1569  {
1570  if( lphc->wState & CBF_EDIT )
1571  CBUpdateEdit( lphc, index );
1572  else
1573  {
1574  InvalidateRect(lphc->self, &lphc->textRect, TRUE);
1575  }
1576  }
1577  return (LRESULT)index;
1578 }
1579 
1580 /***********************************************************************
1581  * COMBO_LButtonDown
1582  */
1584 {
1585  POINT pt;
1586  BOOL bButton;
1587  HWND hWnd = lphc->self;
1588 
1589  pt.x = (short)LOWORD(lParam);
1590  pt.y = (short)HIWORD(lParam);
1591  bButton = PtInRect(&lphc->buttonRect, pt);
1592 
1593  if( (CB_GETTYPE(lphc) == CBS_DROPDOWNLIST) ||
1594  (bButton && (CB_GETTYPE(lphc) == CBS_DROPDOWN)) )
1595  {
1596  lphc->wState |= CBF_BUTTONDOWN;
1597  if( lphc->wState & CBF_DROPPED )
1598  {
1599  /* got a click to cancel selection */
1600 
1601  lphc->wState &= ~CBF_BUTTONDOWN;
1602  CBRollUp( lphc, TRUE, FALSE );
1603  if( !IsWindow( hWnd ) ) return;
1604 
1605  if( lphc->wState & CBF_CAPTURE )
1606  {
1607  lphc->wState &= ~CBF_CAPTURE;
1608  ReleaseCapture();
1609  }
1610  }
1611  else
1612  {
1613  /* drop down the listbox and start tracking */
1614 
1615  lphc->wState |= CBF_CAPTURE;
1616  SetCapture( hWnd );
1617  CBDropDown( lphc );
1618  }
1619  if( bButton ) CBRepaintButton( lphc );
1620  }
1621 }
1622 
1623 /***********************************************************************
1624  * COMBO_LButtonUp
1625  *
1626  * Release capture and stop tracking if needed.
1627  */
1628 static void COMBO_LButtonUp( LPHEADCOMBO lphc )
1629 {
1630  if( lphc->wState & CBF_CAPTURE )
1631  {
1632  lphc->wState &= ~CBF_CAPTURE;
1633  if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
1634  {
1635  INT index = CBUpdateLBox( lphc, TRUE );
1636  /* Update edit only if item is in the list */
1637  if(index >= 0)
1638  {
1639  lphc->wState |= CBF_NOLBSELECT;
1640  CBUpdateEdit( lphc, index );
1641  lphc->wState &= ~CBF_NOLBSELECT;
1642  }
1643  }
1644  ReleaseCapture();
1645  SetCapture(lphc->hWndLBox);
1646  }
1647 
1648  if( lphc->wState & CBF_BUTTONDOWN )
1649  {
1650  lphc->wState &= ~CBF_BUTTONDOWN;
1651  CBRepaintButton( lphc );
1652  }
1653 }
1654 
1655 /***********************************************************************
1656  * COMBO_MouseMove
1657  *
1658  * Two things to do - track combo button and release capture when
1659  * pointer goes into the listbox.
1660  */
1662 {
1663  POINT pt;
1664  RECT lbRect;
1665 
1666  pt.x = (short)LOWORD(lParam);
1667  pt.y = (short)HIWORD(lParam);
1668 
1669  if( lphc->wState & CBF_BUTTONDOWN )
1670  {
1671  BOOL bButton;
1672 
1673  bButton = PtInRect(&lphc->buttonRect, pt);
1674 
1675  if( !bButton )
1676  {
1677  lphc->wState &= ~CBF_BUTTONDOWN;
1678  CBRepaintButton( lphc );
1679  }
1680  }
1681 
1682  GetClientRect( lphc->hWndLBox, &lbRect );
1683  MapWindowPoints( lphc->self, lphc->hWndLBox, &pt, 1 );
1684  if( PtInRect(&lbRect, pt) )
1685  {
1686  lphc->wState &= ~CBF_CAPTURE;
1687  ReleaseCapture();
1688  if( CB_GETTYPE(lphc) == CBS_DROPDOWN ) CBUpdateLBox( lphc, TRUE );
1689 
1690  /* hand over pointer tracking */
1692  }
1693 }
1694 
1696 {
1697  if (!pcbi || (pcbi->cbSize < sizeof(COMBOBOXINFO)))
1698  return FALSE;
1699 
1700  pcbi->rcItem = lphc->textRect;
1701  pcbi->rcButton = lphc->buttonRect;
1702  pcbi->stateButton = 0;
1703  if (lphc->wState & CBF_BUTTONDOWN)
1705  if (IsRectEmpty(&lphc->buttonRect))
1707  pcbi->hwndCombo = lphc->self;
1708  pcbi->hwndItem = lphc->hWndEdit;
1709  pcbi->hwndList = lphc->hWndLBox;
1710  return TRUE;
1711 }
1712 
1714 {
1715  HEADCOMBO *lphc = (HEADCOMBO *)GetWindowLongPtrW( hwnd, 0 );
1716  HTHEME theme;
1717 
1718  TRACE("[%p]: msg %#x wp %08lx lp %08lx\n", hwnd, message, wParam, lParam );
1719 
1720  if (!IsWindow(hwnd)) return 0;
1721 
1722  if (lphc || message == WM_NCCREATE)
1723  switch(message)
1724  {
1725  case WM_NCCREATE:
1726  {
1727  LONG style = ((CREATESTRUCTW *)lParam)->style;
1728  return COMBO_NCCreate(hwnd, style);
1729  }
1730 
1731  case WM_NCDESTROY:
1732  COMBO_NCDestroy(lphc);
1733  break;/* -> DefWindowProc */
1734 
1735  case WM_CREATE:
1736  {
1737  HWND hwndParent;
1738  LONG style;
1739 
1740  hwndParent = ((CREATESTRUCTW *)lParam)->hwndParent;
1741  style = ((CREATESTRUCTW *)lParam)->style;
1742  return COMBO_Create(hwnd, lphc, hwndParent, style);
1743  }
1744 
1745  case WM_DESTROY:
1746  theme = GetWindowTheme( hwnd );
1747  CloseThemeData( theme );
1748  break;
1749 
1750  case WM_THEMECHANGED:
1751  theme = GetWindowTheme( hwnd );
1752  CloseThemeData( theme );
1754  break;
1755 
1756  case WM_PRINTCLIENT:
1757  case WM_PAINT:
1758  {
1759  LRESULT ret = 0;
1760  PAINTSTRUCT ps;
1761  HDC hdc;
1762 
1763  hdc = wParam ? (HDC)wParam : BeginPaint(hwnd, &ps);
1764 
1765  if (hdc && !(lphc->wState & CBF_NOREDRAW))
1766  {
1767  HTHEME theme = GetWindowTheme(hwnd);
1768 
1769  if (theme)
1770  ret = COMBO_ThemedPaint(theme, lphc, hdc);
1771  else
1772  ret = COMBO_Paint(lphc, hdc);
1773  }
1774 
1775  if (!wParam)
1776  EndPaint(hwnd, &ps);
1777 
1778  return ret;
1779  }
1780  case WM_ERASEBKGND:
1781  /* do all painting in WM_PAINT like Windows does */
1782  return 1;
1783 
1784  case WM_GETDLGCODE:
1785  {
1787  if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN))
1788  {
1789  int vk = (int)((LPMSG)lParam)->wParam;
1790 
1791  if ((vk == VK_RETURN || vk == VK_ESCAPE) && (lphc->wState & CBF_DROPPED))
1793  }
1794  return result;
1795  }
1796 
1797  case WM_SIZE:
1798  if (lphc->hWndLBox && !(lphc->wState & CBF_NORESIZE))
1799  COMBO_Size( lphc );
1800  return TRUE;
1801 
1802  case WM_SETFONT:
1803  COMBO_Font( lphc, (HFONT)wParam, (BOOL)lParam );
1804  return TRUE;
1805 
1806  case WM_GETFONT:
1807  return (LRESULT)lphc->hFont;
1808 
1809  case WM_SETFOCUS:
1810  if (lphc->wState & CBF_EDIT)
1811  {
1812  SetFocus( lphc->hWndEdit );
1813  /* The first time focus is received, select all the text */
1814  if (!(lphc->wState & CBF_BEENFOCUSED))
1815  {
1816  SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, -1);
1817  lphc->wState |= CBF_BEENFOCUSED;
1818  }
1819  }
1820  else
1821  COMBO_SetFocus( lphc );
1822  return TRUE;
1823 
1824  case WM_KILLFOCUS:
1825  {
1826  HWND hwndFocus = (HWND)wParam;
1827  if (!hwndFocus || (hwndFocus != lphc->hWndEdit && hwndFocus != lphc->hWndLBox))
1828  COMBO_KillFocus( lphc );
1829  return TRUE;
1830  }
1831 
1832  case WM_COMMAND:
1833  return COMBO_Command( lphc, wParam, (HWND)lParam );
1834 
1835  case WM_GETTEXT:
1836  return COMBO_GetText( lphc, wParam, (LPWSTR)lParam );
1837 
1838  case WM_SETTEXT:
1839  case WM_GETTEXTLENGTH:
1840  case WM_CLEAR:
1841  if ((message == WM_GETTEXTLENGTH) && !ISWIN31 && !(lphc->wState & CBF_EDIT))
1842  {
1843  int j = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
1844  if (j == -1) return 0;
1845  return SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, j, 0);
1846  }
1847  else if ( lphc->wState & CBF_EDIT )
1848  {
1849  LRESULT ret;
1850  lphc->wState |= CBF_NOEDITNOTIFY;
1852  lphc->wState &= ~CBF_NOEDITNOTIFY;
1853  return ret;
1854  }
1855  else
1856  return CB_ERR;
1857 
1858  case WM_CUT:
1859  case WM_PASTE:
1860  case WM_COPY:
1861  if (lphc->wState & CBF_EDIT)
1862  return SendMessageW(lphc->hWndEdit, message, wParam, lParam);
1863  else return CB_ERR;
1864 
1865  case WM_DRAWITEM:
1866  case WM_DELETEITEM:
1867  case WM_COMPAREITEM:
1868  case WM_MEASUREITEM:
1869  return COMBO_ItemOp(lphc, message, lParam);
1870 
1871  case WM_ENABLE:
1872  if (lphc->wState & CBF_EDIT)
1873  EnableWindow( lphc->hWndEdit, (BOOL)wParam );
1874  EnableWindow( lphc->hWndLBox, (BOOL)wParam );
1875 
1876  /* Force the control to repaint when the enabled state changes. */
1877  InvalidateRect(lphc->self, NULL, TRUE);
1878  return TRUE;
1879 
1880  case WM_SETREDRAW:
1881  if (wParam)
1882  lphc->wState &= ~CBF_NOREDRAW;
1883  else
1884  lphc->wState |= CBF_NOREDRAW;
1885 
1886  if ( lphc->wState & CBF_EDIT )
1889  return 0;
1890 
1891  case WM_SYSKEYDOWN:
1892  if ( KEYDATA_ALT & HIWORD(lParam) )
1893  if( wParam == VK_UP || wParam == VK_DOWN )
1894  COMBO_FlipListbox( lphc, FALSE, FALSE );
1895  return 0;
1896 
1897  case WM_KEYDOWN:
1898  if ((wParam == VK_RETURN || wParam == VK_ESCAPE) &&
1899  (lphc->wState & CBF_DROPPED))
1900  {
1901  CBRollUp( lphc, wParam == VK_RETURN, FALSE );
1902  return TRUE;
1903  }
1904  else if ((wParam == VK_F4) && !(lphc->wState & CBF_EUI))
1905  {
1906  COMBO_FlipListbox( lphc, FALSE, FALSE );
1907  return TRUE;
1908  }
1909  /* fall through */
1910  case WM_CHAR:
1911  case WM_IME_CHAR:
1912  {
1913  HWND hwndTarget;
1914 
1915  if ( lphc->wState & CBF_EDIT )
1916  hwndTarget = lphc->hWndEdit;
1917  else
1918  hwndTarget = lphc->hWndLBox;
1919 
1920  return SendMessageW(hwndTarget, message, wParam, lParam);
1921  }
1922 
1923  case WM_LBUTTONDOWN:
1924  if ( !(lphc->wState & CBF_FOCUSED) ) SetFocus( lphc->self );
1925  if ( lphc->wState & CBF_FOCUSED ) COMBO_LButtonDown( lphc, lParam );
1926  return TRUE;
1927 
1928  case WM_LBUTTONUP:
1929  COMBO_LButtonUp( lphc );
1930  return TRUE;
1931 
1932  case WM_MOUSEMOVE:
1933  if (!IsRectEmpty(&lphc->buttonRect))
1934  {
1935  POINT pt;
1936 
1937  pt.x = (short)LOWORD(lParam);
1938  pt.y = (short)HIWORD(lParam);
1939 
1940  if (PtInRect(&lphc->buttonRect, pt))
1941  {
1942  if (!(lphc->wState & CBF_HOT))
1943  {
1944  lphc->wState |= CBF_HOT;
1946  }
1947  }
1948  else if (lphc->wState & CBF_HOT)
1949  {
1950  lphc->wState &= ~CBF_HOT;
1952  }
1953  }
1954 
1955  if ( lphc->wState & CBF_CAPTURE )
1956  COMBO_MouseMove( lphc, wParam, lParam );
1957  return TRUE;
1958 
1959  case WM_MOUSEWHEEL:
1960  if (wParam & (MK_SHIFT | MK_CONTROL))
1962 
1963  if (GET_WHEEL_DELTA_WPARAM(wParam) > 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_UP, 0);
1964  if (GET_WHEEL_DELTA_WPARAM(wParam) < 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_DOWN, 0);
1965  return TRUE;
1966 
1967  /* Combo messages */
1968  case CB_ADDSTRING:
1969  if (lphc->dwStyle & CBS_LOWERCASE)
1971  else if (lphc->dwStyle & CBS_UPPERCASE)
1973  return SendMessageW(lphc->hWndLBox, LB_ADDSTRING, 0, lParam);
1974 
1975  case CB_INSERTSTRING:
1976  if (lphc->dwStyle & CBS_LOWERCASE)
1978  else if (lphc->dwStyle & CBS_UPPERCASE)
1981 
1982  case CB_DELETESTRING:
1983  return SendMessageW(lphc->hWndLBox, LB_DELETESTRING, wParam, 0);
1984 
1985  case CB_SELECTSTRING:
1986  return COMBO_SelectString(lphc, (INT)wParam, lParam);
1987 
1988  case CB_FINDSTRING:
1989  return SendMessageW(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam);
1990 
1991  case CB_FINDSTRINGEXACT:
1993 
1994  case CB_SETITEMHEIGHT:
1995  return COMBO_SetItemHeight( lphc, (INT)wParam, (INT)lParam);
1996 
1997  case CB_GETITEMHEIGHT:
1998  if ((INT)wParam >= 0) /* listbox item */
1999  return SendMessageW(lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0);
2000  return CBGetTextAreaHeight(hwnd, lphc);
2001 
2002  case CB_RESETCONTENT:
2003  SendMessageW(lphc->hWndLBox, LB_RESETCONTENT, 0, 0);
2004 
2005  if ((lphc->wState & CBF_EDIT) && CB_HASSTRINGS(lphc))
2006  {
2007  static const WCHAR empty_stringW[] = { 0 };
2009  }
2010  else
2011  InvalidateRect(lphc->self, NULL, TRUE);
2012  return TRUE;
2013 
2014  case CB_INITSTORAGE:
2016 
2018  return SendMessageW(lphc->hWndLBox, LB_GETHORIZONTALEXTENT, 0, 0);
2019 
2022 
2023  case CB_GETTOPINDEX:
2024  return SendMessageW(lphc->hWndLBox, LB_GETTOPINDEX, 0, 0);
2025 
2026  case CB_GETLOCALE:
2027  return SendMessageW(lphc->hWndLBox, LB_GETLOCALE, 0, 0);
2028 
2029  case CB_SETLOCALE:
2030  return SendMessageW(lphc->hWndLBox, LB_SETLOCALE, wParam, 0);
2031 
2032  case CB_SETDROPPEDWIDTH:
2033  if ((CB_GETTYPE(lphc) == CBS_SIMPLE) || (INT)wParam >= 32768)
2034  return CB_ERR;
2035 
2036  /* new value must be higher than combobox width */
2037  if ((INT)wParam >= lphc->droppedRect.right - lphc->droppedRect.left)
2038  lphc->droppedWidth = wParam;
2039  else if (wParam)
2040  lphc->droppedWidth = 0;
2041 
2042  /* recalculate the combobox area */
2043  CBCalcPlacement(hwnd, lphc, &lphc->textRect, &lphc->buttonRect, &lphc->droppedRect );
2044 
2045  /* fall through */
2046  case CB_GETDROPPEDWIDTH:
2047  if (lphc->droppedWidth)
2048  return lphc->droppedWidth;
2049  return lphc->droppedRect.right - lphc->droppedRect.left;
2050 
2052  if (lParam)
2054  return CB_OKAY;
2055 
2056  case CB_GETDROPPEDSTATE:
2057  return (lphc->wState & CBF_DROPPED) != 0;
2058 
2059  case CB_DIR:
2060  return SendMessageW(lphc->hWndLBox, LB_DIR, wParam, lParam);
2061 
2062  case CB_SHOWDROPDOWN:
2063  if (CB_GETTYPE(lphc) != CBS_SIMPLE)
2064  {
2065  if (wParam)
2066  {
2067  if (!(lphc->wState & CBF_DROPPED))
2068  CBDropDown( lphc );
2069  }
2070  else if (lphc->wState & CBF_DROPPED)
2071  CBRollUp( lphc, FALSE, TRUE );
2072  }
2073  return TRUE;
2074 
2075  case CB_GETCOUNT:
2076  return SendMessageW(lphc->hWndLBox, LB_GETCOUNT, 0, 0);
2077 
2078  case CB_GETCURSEL:
2079  return SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
2080 
2081  case CB_SETCURSEL:
2083  if (lParam >= 0)
2085 
2086  /* no LBN_SELCHANGE in this case, update manually */
2087  CBPaintText(lphc, NULL);
2088  lphc->wState &= ~CBF_SELCHANGE;
2089  return lParam;
2090 
2091  case CB_GETLBTEXT:
2092  return SendMessageW(lphc->hWndLBox, LB_GETTEXT, wParam, lParam);
2093 
2094  case CB_GETLBTEXTLEN:
2095  return SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0);
2096 
2097  case CB_GETITEMDATA:
2098  return SendMessageW(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0);
2099 
2100  case CB_SETITEMDATA:
2102 
2103  case CB_GETEDITSEL:
2104  /* Edit checks passed parameters itself */
2105  if (lphc->wState & CBF_EDIT)
2106  return SendMessageW(lphc->hWndEdit, EM_GETSEL, wParam, lParam);
2107  return CB_ERR;
2108 
2109  case CB_SETEDITSEL:
2110  if (lphc->wState & CBF_EDIT)
2112  return CB_ERR;
2113 
2114  case CB_SETEXTENDEDUI:
2115  if (CB_GETTYPE(lphc) == CBS_SIMPLE )
2116  return CB_ERR;
2117  if (wParam)
2118  lphc->wState |= CBF_EUI;
2119  else
2120  lphc->wState &= ~CBF_EUI;
2121  return CB_OKAY;
2122 
2123  case CB_GETEXTENDEDUI:
2124  return (lphc->wState & CBF_EUI) != 0;
2125 
2126  case CB_GETCOMBOBOXINFO:
2127  return COMBO_GetComboBoxInfo(lphc, (COMBOBOXINFO *)lParam);
2128 
2129  case CB_LIMITTEXT:
2130  if (lphc->wState & CBF_EDIT)
2131  return SendMessageW(lphc->hWndEdit, EM_LIMITTEXT, wParam, lParam);
2132  return TRUE;
2133 
2134  case CB_GETMINVISIBLE:
2135  return lphc->visibleItems;
2136 
2137  case CB_SETMINVISIBLE:
2138  lphc->visibleItems = (INT)wParam;
2139  return TRUE;
2140 
2141  default:
2142  if (message >= WM_USER)
2143  WARN("unknown msg WM_USER+%04x wp=%04lx lp=%08lx\n", message - WM_USER, wParam, lParam );
2144  break;
2145  }
2146 
2148 }
2149 
2150 void COMBO_Register(void)
2151 {
2152  WNDCLASSW wndClass;
2153 
2154  memset(&wndClass, 0, sizeof(wndClass));
2156  wndClass.lpfnWndProc = COMBO_WindowProc;
2157  wndClass.cbClsExtra = 0;
2158  wndClass.cbWndExtra = sizeof(HEADCOMBO *);
2159  wndClass.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
2160  wndClass.hbrBackground = NULL;
2161  wndClass.lpszClassName = WC_COMBOBOXW;
2162  RegisterClassW(&wndClass);
2163 }
2164 
2165 #ifdef __REACTOS__
2166 void COMBO_Unregister(void)
2167 {
2169 }
2170 #endif
void COMBO_Register(void)
Definition: combo.c:2150
#define CBS_OWNERDRAWFIXED
Definition: winuser.h:289
#define ISWIN31
Definition: combo.c:61
#define EM_LIMITTEXT
Definition: winuser.h:1961
#define CB_GETTOPINDEX
Definition: winuser.h:1916
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define RDW_NOCHILDREN
Definition: winuser.h:1208
#define LB_SETCURSEL
Definition: winuser.h:2024
#define WM_GETTEXTLENGTH
Definition: winuser.h:1601
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:1943
#define CB_SETITEMDATA
Definition: winuser.h:1927
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
BOOL WINAPI RedrawWindow(_In_opt_ HWND, _In_opt_ LPCRECT, _In_opt_ HRGN, _In_ UINT)
#define LB_SETLOCALE
Definition: winuser.h:2028
#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:1914
#define LB_CARETON
Definition: undocuser.h:50
#define TRUE
Definition: types.h:120
static LRESULT COMBO_SetItemHeight(LPHEADCOMBO lphc, INT index, INT height)
Definition: combo.c:1526
#define DLGC_WANTCHARS
Definition: winuser.h:2572
#define COLOR_HIGHLIGHT
Definition: winuser.h:916
#define CB_DISABLED(lphc)
Definition: combo.c:55
#define LB_DIR
Definition: winuser.h:1994
static void CBGetDroppedControlRect(LPHEADCOMBO lphc, LPRECT lpRect)
Definition: combo.c:421
#define DLGC_WANTMESSAGE
Definition: winuser.h:2567
#define LB_SETCARETINDEX
Definition: winuser.h:2021
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
#define MK_SHIFT
Definition: winuser.h:2323
#define CB_GETDROPPEDSTATE
Definition: winuser.h:1906
LPCSTR pText
Definition: txtscale.cpp:79
#define LB_FINDSTRINGEXACT
Definition: winuser.h:1996
static LRESULT CALLBACK COMBO_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: combo.c:1713
int WINAPI SelectClipRgn(_In_ HDC, _In_opt_ HRGN)
static INT CBGetTextAreaHeight(HWND hwnd, LPHEADCOMBO lphc)
Definition: combo.c:185
UINT style
Definition: winuser.h:3129
#define WM_GETDLGCODE
Definition: winuser.h:1671
static void COMBO_Font(LPHEADCOMBO lphc, HFONT hFont, BOOL bRedraw)
Definition: combo.c:1489
#define ODT_COMBOBOX
Definition: winuser.h:2493
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:1693
#define WM_LBUTTONDOWN
Definition: winuser.h:1752
INT visibleItems
Definition: comctl32.h:150
#define LB_SETHORIZONTALEXTENT
Definition: winuser.h:2025
#define WM_CUT
Definition: winuser.h:1822
#define error(str)
Definition: mkdosfs.c:1605
#define WM_IME_CHAR
Definition: winuser.h:1810
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
#define LB_ADDSTRING
Definition: winuser.h:1992
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define LB_GETHORIZONTALEXTENT
Definition: winuser.h:2001
#define MAXLONG
Definition: umtypes.h:116
static LRESULT COMBO_GetText(HEADCOMBO *lphc, INT count, LPWSTR buf)
Definition: combo.c:1346
static void CBDropDown(LPHEADCOMBO lphc)
Definition: combo.c:959
HDC WINAPI GetDC(_In_opt_ HWND)
#define CB_SETDROPPEDWIDTH
Definition: winuser.h:1923
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
INT editHeight
Definition: comctl32.h:149
#define CB_SETHORIZONTALEXTENT
Definition: winuser.h:1926
static LRESULT COMBO_Paint(HEADCOMBO *lphc, HDC hdc)
Definition: combo.c:842
#define pt(x, y)
Definition: drawing.c:79
#define CB_GETLBTEXT
Definition: winuser.h:1913
#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:1437
#define WM_MOUSEWHEEL
Definition: treelist.c:96
#define LB_GETITEMDATA
Definition: winuser.h:2002
#define CB_GETITEMDATA
Definition: winuser.h:1911
GLuint GLuint GLsizei count
Definition: gl.h:1545
static void CBRollUp(LPHEADCOMBO lphc, BOOL ok, BOOL bButton)
Definition: combo.c:1062
#define LBS_HASSTRINGS
Definition: pedump.c:684
#define WM_CTLCOLORSTATIC
Definition: winuser.h:1748
UINT wState
Definition: comctl32.h:141
#define WM_GETTEXT
Definition: winuser.h:1600
#define WARN(fmt,...)
Definition: debug.h:111
LPWSTR WINAPI CharLowerW(_Inout_ LPWSTR)
BOOL WINAPI DrawFocusRect(_In_ HDC, _In_ LPCRECT)
#define INT
Definition: polytest.cpp:20
#define LBN_SETFOCUS
Definition: winuser.h:2037
static HDC
Definition: imagelist.c:92
#define DFCS_INACTIVE
Definition: winuser.h:502
#define CALLBACK
Definition: compat.h:27
#define WM_SETREDRAW
Definition: winuser.h:1598
BOOL WINAPI UpdateWindow(_In_ HWND)
HWND hWnd
Definition: settings.c:17
ULONG_PTR itemData
Definition: winuser.h:3046
LONG top
Definition: windef.h:292
static void COMBO_LButtonUp(LPHEADCOMBO lphc)
Definition: combo.c:1628
HANDLE HWND
Definition: compat.h:13
HWND hWndEdit
Definition: comctl32.h:139
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
#define ODS_FOCUS
Definition: winuser.h:2503
#define WM_PASTE
Definition: winuser.h:1824
#define ES_COMBO
Definition: edit.c:29
#define LBS_SORT
Definition: pedump.c:679
static HTHEME(WINAPI *pOpenThemeDataEx)(HWND
RECT droppedRect
Definition: comctl32.h:145
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:1194
#define ID_CB_LISTBOX
Definition: combo.c:79
int cbClsExtra
Definition: winuser.h:3131
HWND WINAPI SetFocus(_In_opt_ HWND)
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:144
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
INT droppedIndex
Definition: comctl32.h:146
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:2181
#define WS_CHILD
Definition: pedump.c:617
#define GetWindowLongPtrW
Definition: winuser.h:4698
static LRESULT COMBO_ItemOp(LPHEADCOMBO lphc, UINT msg, LPARAM lParam)
Definition: combo.c:1298
LONG left
Definition: windef.h:291
static HBRUSH COMBO_PrepareColors(LPHEADCOMBO lphc, HDC hDC)
Definition: combo.c:617
#define SWP_NOZORDER
Definition: winuser.h:1232
#define CB_SETLOCALE
Definition: winuser.h:1929
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:2168
BOOL WINAPI InvertRect(_In_ HDC, _In_ LPCRECT)
#define WM_CLEAR
Definition: winuser.h:1825
LONG right
Definition: windef.h:293
static LRESULT COMBO_NCDestroy(HEADCOMBO *lphc)
Definition: combo.c:157
#define WM_NCCREATE
Definition: winuser.h:1665
BOOL WINAPI DestroyWindow(_In_ HWND)
#define LBN_SELCHANGE
Definition: winuser.h:2036
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:908
HRGN set_control_clipping(HDC hdc, const RECT *rect)
Definition: button.c:239
int32_t INT
Definition: typedefs.h:56
static UINT CBitWidth
Definition: combo.c:67
#define VK_RETURN
Definition: winuser.h:2155
#define CB_GETCURSEL
Definition: winuser.h:1904
DWORD WINAPI GetSysColor(_In_ int)
& rect
Definition: startmenu.cpp:1413
WPARAM wParam
Definition: combotst.c:138
#define LB_SELECTSTRING
Definition: winuser.h:2017
#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:1597
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:397
#define CB_SETITEMHEIGHT
Definition: winuser.h:1928
#define LB_SETITEMHEIGHT
Definition: winuser.h:2027
#define EM_GETSEL
Definition: winuser.h:1958
#define CB_GETTYPE(lphc)
Definition: combo.c:59
#define CB_GETEDITSEL
Definition: winuser.h:1908
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:975
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
#define BF_RECT
Definition: winuser.h:462
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:93
#define CB_INITSTORAGE
Definition: winuser.h:1917
#define DFCS_PUSHED
Definition: winuser.h:503
static UINT CBitHeight
Definition: combo.c:67
#define LB_RESETCONTENT
Definition: winuser.h:2016
#define LBN_SELCANCEL
Definition: winuser.h:2035
#define EN_KILLFOCUS
Definition: winuser.h:1986
#define EDIT_CONTROL_PADDING()
Definition: combo.c:77
#define EN_SETFOCUS
Definition: winuser.h:1988
#define CB_GETDROPPEDWIDTH
Definition: winuser.h:1907
#define VK_UP
Definition: winuser.h:2179
static void CBPaintBorder(HWND hwnd, const HEADCOMBO *lphc, HDC hdc)
Definition: combo.c:780
#define ETO_OPAQUE
Definition: wingdi.h:646
static LRESULT COMBO_Command(LPHEADCOMBO lphc, WPARAM wParam, HWND hWnd)
Definition: combo.c:1189
#define LB_ERR
Definition: winuser.h:2386
#define WM_COPY
Definition: winuser.h:1823
#define CB_NOTIFY(lphc, code)
Definition: combo.c:51
static UINT msg
Definition: combo.c:716
INT fixedOwnerDrawHeight
Definition: comctl32.h:147
#define LBS_NOINTEGRALHEIGHT
Definition: pedump.c:686
unsigned int BOOL
Definition: ntddk_ex.h:94
#define CBN_SELENDOK
Definition: winuser.h:1942
long LONG
Definition: pedump.c:60
#define WM_DELETEITEM
Definition: winuser.h:1629
static void COMBO_KillFocus(LPHEADCOMBO lphc)
Definition: combo.c:1163
#define CB_SHOWDROPDOWN
Definition: winuser.h:1931
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:1939
WNDPROC lpfnWndProc
Definition: winuser.h:3130
HWND WINAPI GetCapture(void)
Definition: message.c:2879
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define FIXME(fmt,...)
Definition: debug.h:110
#define CBS_SIMPLE
Definition: winuser.h:291
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
#define ok(value,...)
#define STATE_SYSTEM_PRESSED
Definition: winuser.h:2818
#define VK_F4
Definition: winuser.h:2212
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:1897
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:1918
#define CBN_DBLCLK
Definition: winuser.h:1934
WINE_DEFAULT_DEBUG_CHANNEL(combo)
#define CB_GETCOMBOBOXINFO
Definition: winuser.h:1902
smooth NULL
Definition: ftsmooth.c:416
#define WM_GETFONT
Definition: winuser.h:1633
static LRESULT COMBO_Create(HWND hwnd, LPHEADCOMBO lphc, HWND hwndParent, LONG style)
Definition: combo.c:436
#define EN_ERRSPACE
Definition: winuser.h:1984
static HWND hwndParent
Definition: cryptui.c:300
#define WM_KEYDOWN
Definition: winuser.h:1691
LPCWSTR lpszClassName
Definition: winuser.h:3138
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:1919
#define CB_SETMINVISIBLE
Definition: commctrl.h:4692
#define ETO_CLIPPED
Definition: wingdi.h:647
GLuint index
Definition: glext.h:6031
static void CBRepaintButton(LPHEADCOMBO lphc)
Definition: combo.c:1132
#define LB_GETTEXTLEN
Definition: winuser.h:2011
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:917
#define LB_GETCOUNT
Definition: winuser.h:1999
#define WM_SETTEXT
Definition: winuser.h:1599
#define CB_RESETCONTENT
Definition: winuser.h:1920
#define CBS_HASSTRINGS
Definition: winuser.h:285
RECT textRect
Definition: comctl32.h:143
#define CB_ERR
Definition: winuser.h:2389
#define LB_INITSTORAGE
Definition: winuser.h:2013
#define WM_DESTROY
Definition: winuser.h:1591
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:140
#define CS_VREDRAW
Definition: winuser.h:653
#define ODA_DRAWENTIRE
Definition: winuser.h:2496
#define TRACE(s)
Definition: solgame.cpp:4
#define OBM_COMBO
Definition: winuser.h:1102
#define WM_KILLFOCUS
Definition: winuser.h:1596
GLsizeiptr size
Definition: glext.h:5919
#define CB_GETDROPPEDCONTROLRECT
Definition: winuser.h:1905
#define CBN_EDITCHANGE
Definition: winuser.h:1936
DWORD stateButton
Definition: winuser.h:3654
static void CBResetPos(LPHEADCOMBO lphc, const RECT *rectEdit, const RECT *rectLB, BOOL bRedraw)
Definition: combo.c:1395
#define LB_SETTOPINDEX
Definition: winuser.h:2031
int cbWndExtra
Definition: winuser.h:3132
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define WM_SIZE
Definition: winuser.h:1593
#define ODS_DISABLED
Definition: winuser.h:2501
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
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:1227
#define RDW_ERASE
Definition: winuser.h:1197
#define CS_GLOBALCLASS
Definition: winuser.h:647
#define WM_NCDESTROY
Definition: winuser.h:1666
#define EM_SETSEL
Definition: winuser.h:1979
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:2033
int WINAPI GetSystemMetrics(_In_ int)
#define WM_MEASUREITEM
Definition: winuser.h:1628
#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:142
#define LB_SETITEMDATA
Definition: winuser.h:2026
#define LBN_DBLCLK
Definition: winuser.h:2032
HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR classlist)
Definition: system.c:835
#define CBN_SELENDCANCEL
Definition: winuser.h:1941
#define ES_NOHIDESEL
Definition: pedump.c:673
#define WS_HSCROLL
Definition: pedump.c:628
#define WM_PAINT
Definition: winuser.h:1602
#define CB_GETHORIZONTALEXTENT
Definition: winuser.h:1910
HTHEME WINAPI GetWindowTheme(HWND hwnd)
Definition: system.c:851
#define COMBO_YBORDERSIZE()
Definition: combo.c:75
int ret
INT droppedWidth
Definition: comctl32.h:148
#define KEYDATA_ALT
Definition: combo.c:44
#define COLOR_GRAYTEXT
Definition: winuser.h:922
#define CB_GETMINVISIBLE
Definition: commctrl.h:4693
#define index(s, c)
Definition: various.h:29
#define LB_GETTEXT
Definition: winuser.h:2010
#define CBN_ERRSPACE
Definition: winuser.h:1938
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:1921
static void CBPaintButton(LPHEADCOMBO lphc, HDC hdc, RECT rectButton)
Definition: combo.c:592
#define LB_GETLOCALE
Definition: winuser.h:2006
ULONG_PTR itemData
Definition: winuser.h:3588
#define WS_EX_TOPMOST
Definition: pedump.c:647
#define CB_SETCURSEL
Definition: winuser.h:1922
#define CS_DBLCLKS
Definition: winuser.h:646
Definition: time.h:76
#define WM_COMMAND
Definition: winuser.h:1716
#define COMBO_XBORDERSIZE()
Definition: combo.c:74
#define WM_USER
Definition: winuser.h:1856
#define LB_GETITEMHEIGHT
Definition: winuser.h:2003
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:3135
#define ERR(fmt,...)
Definition: debug.h:109
#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:886
static HDC hDC
Definition: 3dtext.c:33
#define CB_OKAY
Definition: winuser.h:2388
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:1583
#define CBN_DROPDOWN
Definition: winuser.h:1935
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:1637
#define LB_FINDSTRING
Definition: winuser.h:1995
#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:1117
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1378
HWND self
Definition: comctl32.h:136
BOOL WINAPI DeleteDC(_In_ HDC)
#define CB_DIR
Definition: winuser.h:1899
#define CB_SETEDITSEL
Definition: winuser.h:1924
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:1661
DWORD cbSize
Definition: winuser.h:3726
#define WM_CTLCOLOREDIT
Definition: winuser.h:1743
HBRUSH hbrBackground
Definition: winuser.h:3136
#define CBS_DROPDOWN
Definition: winuser.h:283
#define LB_GETTOPINDEX
Definition: winuser.h:2012
static INT CBUpdateLBox(LPHEADCOMBO lphc, BOOL bSelect)
Definition: combo.c:889
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_LBUTTONUP
Definition: winuser.h:1753
Definition: bl.h:1331
#define CB_SETEXTENDEDUI
Definition: winuser.h:1925
static void COMBO_SetFocus(LPHEADCOMBO lphc)
Definition: combo.c:1141
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define CB_GETLOCALE
Definition: winuser.h:1915
#define DFCS_SCROLLCOMBOBOX
Definition: winuser.h:493
#define HWND_DESKTOP
Definition: winuser.h:1195
#define min(a, b)
Definition: monoChain.cc:55
#define LB_GETCURSEL
Definition: winuser.h:2000
unsigned int UINT
Definition: ndis.h:50
#define WM_MOUSEMOVE
Definition: winuser.h:1751
#define WS_VSCROLL
Definition: pedump.c:627
static LRESULT COMBO_GetComboBoxInfo(const HEADCOMBO *lphc, COMBOBOXINFO *pcbi)
Definition: combo.c:1695
static LRESULT COMBO_ThemedPaint(HTHEME theme, HEADCOMBO *lphc, HDC hdc)
Definition: combo.c:802
#define SWP_SHOWWINDOW
Definition: winuser.h:1233
#define SWP_NOREDRAW
Definition: winuser.h:1231
#define SM_CXVSCROLL
Definition: winuser.h:951
#define CBN_SELCHANGE
Definition: winuser.h:1940
#define MK_CONTROL
Definition: winuser.h:2324
#define DFC_SCROLL
Definition: winuser.h:475
#define WM_SETFONT
Definition: winuser.h:1632
HWND owner
Definition: comctl32.h:137
#define WM_DRAWITEM
Definition: winuser.h:1627
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
#define RDW_UPDATENOW
Definition: winuser.h:1206
#define IDC_ARROW
Definition: winuser.h:682
#define GWLP_HINSTANCE
Definition: winuser.h:850
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2888
#define ES_OEMCONVERT
Definition: pedump.c:674
#define ODS_SELECTED
Definition: winuser.h:2499
#define WM_CREATE
Definition: winuser.h:1590
BOOL WINAPI CopyRect(_Out_ LPRECT, _In_ LPCRECT)
#define CB_GETITEMHEIGHT
Definition: winuser.h:1912
#define WM_SYSKEYDOWN
Definition: winuser.h:1695
#define CBN_EDITUPDATE
Definition: winuser.h:1937
#define HIWORD(l)
Definition: typedefs.h:246
GLenum GLuint id
Definition: glext.h:5579
BOOL WINAPI IsWindowVisible(_In_ HWND)
HMONITOR WINAPI MonitorFromRect(LPCRECT, DWORD)
LONG bottom
Definition: windef.h:294
#define EN_UPDATE
Definition: winuser.h:1989
#define SWP_NOMOVE
Definition: winuser.h:1229
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:1903
#define SetWindowLongPtrW
Definition: winuser.h:5215
static HBITMAP
Definition: button.c:44
#define CB_GETEXTENDEDUI
Definition: winuser.h:1909
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define WM_ERASEBKGND
Definition: winuser.h:1607
#define WM_SETFOCUS
Definition: winuser.h:1595
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define CB_DELETESTRING
Definition: winuser.h:1898
#define COMBO_EDITBUTTONSPACE()
Definition: combo.c:76
LONG_PTR LRESULT
Definition: windef.h:209
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
Arabic default style
Definition: afstyles.h:93
#define LB_DELETESTRING
Definition: winuser.h:1993
#define ES_LEFT
Definition: pedump.c:664
#define WS_VISIBLE
Definition: pedump.c:620
HBRUSH WINAPI GetSysColorBrush(_In_ int)
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
#define CBN_CLOSEUP
Definition: winuser.h:1933
#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:1900
static const WCHAR empty_stringW[]
Definition: edit.c:166
#define LB_INSERTSTRING
Definition: winuser.h:2014
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:2564
#define STATE_SYSTEM_INVISIBLE
Definition: winuser.h:2830
#define CS_PARENTDC
Definition: winuser.h:651
HRESULT WINAPI CloseThemeData(HTHEME hTheme)
Definition: system.c:950
UINT dwStyle
Definition: comctl32.h:138
#define RDW_INVALIDATE
Definition: winuser.h:1200
static LRESULT COMBO_SelectString(LPHEADCOMBO lphc, INT start, LPARAM pText)
Definition: combo.c:1565
int WINAPI FrameRect(_In_ HDC, _In_ LPCRECT, _In_ HBRUSH)
#define LBN_KILLFOCUS
Definition: winuser.h:2034
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:4688
#define ES_LOWERCASE
Definition: pedump.c:669
#define EN_CHANGE
Definition: winuser.h:1983
#define CB_FINDSTRINGEXACT
Definition: winuser.h:1901