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