ReactOS 0.4.17-dev-1321-g5c122a9
listbox.c
Go to the documentation of this file.
1/*
2 * Listbox controls
3 *
4 * Copyright 1996 Alexandre Julliard
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 * NOTES
21 *
22 * This code was audited for completeness against the documented features
23 * of Comctl32.dll version 6.0 on Oct. 9, 2004, by Dimitrie O. Paun.
24 *
25 * Unless otherwise noted, we believe this code to be complete, as per
26 * the specification mentioned above.
27 * If you discover missing features, or bugs, please note them below.
28 *
29 * TODO:
30 * - LBS_NODATA ReactOS
31 */
32
33#include <user32.h>
34
36
37/* Items array granularity (must be power of 2) */
38#define LB_ARRAY_GRANULARITY 16
39
40/* Scrolling timeout in ms */
41#define LB_SCROLL_TIMEOUT 50
42
43/* Listbox system timer id */
44#define LB_TIMER_ID 2
45
46/* flag listbox changed while setredraw false - internal style */
47#define LBS_DISPLAYCHANGED 0x80000000
48
49/* Item structure */
50typedef struct
51{
52 LPWSTR str; /* Item text */
53 BOOL selected; /* Is item selected? */
54 UINT height; /* Item height (only for OWNERDRAWVARIABLE) */
55 ULONG_PTR data; /* User data */
57
58/* Listbox structure */
59typedef struct
60{
61 HWND self; /* Our own window handle */
62 HWND owner; /* Owner window to send notifications to */
63 UINT style; /* Window style */
64 INT width; /* Window width */
65 INT height; /* Window height */
66 union
67 {
68 LB_ITEMDATA *items; /* Array of items */
69 BYTE *nodata_items; /* For multi-selection LBS_NODATA */
70 } u;
71 INT nb_items; /* Number of items */
72 UINT items_size; /* Total number of allocated items in the array */
73 INT top_item; /* Top visible item */
74 INT selected_item; /* Selected item */
75 INT focus_item; /* Item that has the focus */
76 INT anchor_item; /* Anchor item for extended selection */
77 INT item_height; /* Default item height */
78 INT page_size; /* Items per listbox page */
79 INT column_width; /* Column width for multi-column listboxes */
80 INT horz_extent; /* Horizontal extent */
81 INT horz_pos; /* Horizontal position */
82 INT nb_tabs; /* Number of tabs in array */
83 INT *tabs; /* Array of tabs */
84 INT avg_char_width; /* Average width of characters */
85 INT wheel_remain; /* Left over scroll amount */
86 BOOL caret_on; /* Is caret on? */
87 BOOL captured; /* Is mouse captured? */
88 BOOL in_focus;
89 HFONT font; /* Current font */
90 LCID locale; /* Current locale for string comparisons */
91 HEADCOMBO *lphc; /* ComboLBox */
92#ifdef __REACTOS__
93 LONG UIState; /* UISF_ACTIVE, UISF_HIDEACCEL, UISF_HIDEFOCUS */
94#endif
95} LB_DESCR;
96
97
98#define IS_OWNERDRAW(descr) \
99 ((descr)->style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE))
100
101#define HAS_STRINGS(descr) \
102 (!IS_OWNERDRAW(descr) || ((descr)->style & LBS_HASSTRINGS))
103
104
105#define IS_MULTISELECT(descr) \
106 ((descr)->style & (LBS_MULTIPLESEL|LBS_EXTENDEDSEL) && \
107 !((descr)->style & LBS_NOSEL))
108
109#define SEND_NOTIFICATION(descr,code) \
110 (SendMessageW( (descr)->owner, WM_COMMAND, \
111 MAKEWPARAM( GetWindowLongPtrW((descr->self),GWLP_ID), (code)), (LPARAM)(descr->self) ))
112
113#define ISWIN31 (LOWORD(GetVersion()) == 0x0a03)
114
115/* Current timer status */
116typedef enum
117{
124
126
128
129#ifdef __REACTOS__
130/*********************************************************************
131 * listbox class descriptor
132 */
133static const WCHAR listboxW[] = {'L','i','s','t','B','o','x',0};
135{
136 listboxW, /* name */
137 CS_DBLCLKS /*| CS_PARENTDC*/, /* style */
138 &pfnClientA.pfnListBoxWndProc, /* procA */
139 &pfnClientW.pfnListBoxWndProc, /* procW */
140 sizeof(LB_DESCR *), /* extra */
141 IDC_ARROW, /* cursor */
142 0 /* brush */
143};
144
145
146/*********************************************************************
147 * combolbox class descriptor
148 */
149static const WCHAR combolboxW[] = {'C','o','m','b','o','L','B','o','x',0};
151{
152 combolboxW, /* name */
153 CS_DBLCLKS | CS_SAVEBITS, /* style */
154 &pfnClientA.pfnComboListBoxProc, /* procA */
155 &pfnClientW.pfnComboListBoxProc, /* procW */
156 sizeof(LB_DESCR *), /* extra */
157 IDC_ARROW, /* cursor */
158 0 /* brush */
159};
160#endif
161
163{
164 return (LB_DESCR *)NtUserGetPrivateData( hwnd, 0, sizeof(LB_DESCR *) );
165}
166
168{
169 return (LB_DESCR *)NtUserSetPrivateData( hwnd, 0, sizeof(LB_DESCR *), (LONG_PTR)state );
170}
171
172/*
173 For listboxes without LBS_NODATA, an array of LB_ITEMDATA is allocated
174 to store the states of each item into descr->u.items.
175
176 For single-selection LBS_NODATA listboxes, no storage is allocated,
177 and thus descr->u.nodata_items will always be NULL.
178
179 For multi-selection LBS_NODATA listboxes, one byte per item is stored
180 for the item's selection state into descr->u.nodata_items.
181*/
182static size_t get_sizeof_item( const LB_DESCR *descr )
183{
184 return (descr->style & LBS_NODATA) ? sizeof(BYTE) : sizeof(LB_ITEMDATA);
185}
186
188{
190
191 if (items_size > descr->items_size ||
192 items_size + LB_ARRAY_GRANULARITY * 2 < descr->items_size)
193 {
194 items_size = (items_size + LB_ARRAY_GRANULARITY - 1) & ~(LB_ARRAY_GRANULARITY - 1);
196 {
197 items = realloc(descr->u.items, items_size * get_sizeof_item(descr));
198 if (!items)
199 {
201 return FALSE;
202 }
203 descr->u.items = items;
204 }
205 descr->items_size = items_size;
206 }
207
208 if ((descr->style & LBS_NODATA) && descr->u.nodata_items && items_size > descr->nb_items)
209 {
210 memset(descr->u.nodata_items + descr->nb_items, 0,
211 (items_size - descr->nb_items) * get_sizeof_item(descr));
212 }
213 return TRUE;
214}
215
217{
218 return (descr->style & LBS_NODATA) ? 0 : descr->u.items[index].data;
219}
220
222{
223 if (!(descr->style & LBS_NODATA)) descr->u.items[index].data = data;
224}
225
227{
228 return HAS_STRINGS(descr) ? descr->u.items[index].str : NULL;
229}
230
231static void set_item_string( const LB_DESCR *descr, UINT index, WCHAR *string )
232{
233 if (!(descr->style & LBS_NODATA)) descr->u.items[index].str = string;
234}
235
237{
238 return (descr->style & LBS_NODATA) ? 0 : descr->u.items[index].height;
239}
240
242{
243 if (!(descr->style & LBS_NODATA)) descr->u.items[index].height = height;
244}
245
247{
248 if (!(descr->style & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)))
249 return index == descr->selected_item;
250 if (descr->style & LBS_NODATA)
251 return descr->u.nodata_items[index];
252 else
253 return descr->u.items[index].selected;
254}
255
257{
258 if (descr->style & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL))
259 {
260 if (descr->style & LBS_NODATA)
261 descr->u.nodata_items[index] = state;
262 else
263 descr->u.items[index].selected = state;
264 }
265}
266
268{
269 size_t size = get_sizeof_item(descr);
270 BYTE *p = descr->u.nodata_items + index * size;
271
272 if (!descr->u.items) return;
273
274 if (index < descr->nb_items)
275 memmove(p + size, p, (descr->nb_items - index) * size);
276}
277
279{
280 size_t size = get_sizeof_item(descr);
281 BYTE *p = descr->u.nodata_items + index * size;
282
283 if (!descr->u.items) return;
284
285 if (index < descr->nb_items)
286 memmove(p, p + size, (descr->nb_items - index) * size);
287}
288
289
290/***********************************************************************
291 * LISTBOX_GetCurrentPageSize
292 *
293 * Return the current page size
294 */
296{
297 INT i, height;
298 if (!(descr->style & LBS_OWNERDRAWVARIABLE)) return descr->page_size;
299 for (i = descr->top_item, height = 0; i < descr->nb_items; i++)
300 {
301 if ((height += get_item_height(descr, i)) > descr->height) break;
302 }
303 if (i == descr->top_item) return 1;
304 else return i - descr->top_item;
305}
306
307
308/***********************************************************************
309 * LISTBOX_GetMaxTopIndex
310 *
311 * Return the maximum possible index for the top of the listbox.
312 */
314{
315 INT max, page;
316
317 if (descr->style & LBS_OWNERDRAWVARIABLE)
318 {
319 page = descr->height;
320 for (max = descr->nb_items - 1; max >= 0; max--)
321 if ((page -= get_item_height(descr, max)) < 0) break;
322 if (max < descr->nb_items - 1) max++;
323 }
324 else if (descr->style & LBS_MULTICOLUMN)
325 {
326 if ((page = descr->width / descr->column_width) < 1) page = 1;
327 max = (descr->nb_items + descr->page_size - 1) / descr->page_size;
328 max = (max - page) * descr->page_size;
329 }
330 else
331 {
332 max = descr->nb_items - descr->page_size;
333 }
334 if (max < 0) max = 0;
335 return max;
336}
337
338
339/***********************************************************************
340 * LISTBOX_UpdateScroll
341 *
342 * Update the scrollbars. Should be called whenever the content
343 * of the listbox changes.
344 */
346{
348
349 /* Check the listbox scroll bar flags individually before we call
350 NtUserSetScrollInfo otherwise when the listbox style is WS_HSCROLL and
351 no WS_VSCROLL, we end up with an uninitialized, visible horizontal
352 scroll bar when we do not need one.
353 if (!(descr->style & WS_VSCROLL)) return;
354 */
355
356 /* It is important that we check descr->style, and not wnd->dwStyle,
357 for WS_VSCROLL, as the former is exactly the one passed in
358 argument to CreateWindow.
359 In Windows (and from now on in Wine :) a listbox created
360 with such a style (no WS_SCROLL) does not update
361 the scrollbar with listbox-related data, thus letting
362 the programmer use it for his/her own purposes. */
363
364 if (descr->style & LBS_NOREDRAW) return;
365 info.cbSize = sizeof(info);
366
367 if (descr->style & LBS_MULTICOLUMN)
368 {
369 info.nMin = 0;
370 info.nMax = (descr->nb_items - 1) / descr->page_size;
371 info.nPos = descr->top_item / descr->page_size;
372 info.nPage = descr->width / descr->column_width;
373 if (info.nPage < 1) info.nPage = 1;
374 info.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
375 if (descr->style & LBS_DISABLENOSCROLL)
376 info.fMask |= SIF_DISABLENOSCROLL;
377 if (descr->style & WS_HSCROLL)
378#ifdef __REACTOS__
379 /* Unlike WINE, SetScrollInfo is more than just a NtUserSetScrollInfo wrapper on ReactOS. */
380 SetScrollInfo( descr->self, SB_HORZ, &info, TRUE );
381#else
383#endif
384 info.nMax = 0;
385 info.fMask = SIF_RANGE;
386 if (descr->style & WS_VSCROLL)
387#ifdef __REACTOS__
388 SetScrollInfo( descr->self, SB_VERT, &info, TRUE );
389#else
391#endif
392 }
393 else
394 {
395 info.nMin = 0;
396 info.nMax = descr->nb_items - 1;
397 info.nPos = descr->top_item;
399 info.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
400 if (descr->style & LBS_DISABLENOSCROLL)
401 info.fMask |= SIF_DISABLENOSCROLL;
402 if (descr->style & WS_VSCROLL)
403#ifdef __REACTOS__
404 SetScrollInfo( descr->self, SB_VERT, &info, TRUE );
405#else
407#endif
408
409 if ((descr->style & WS_HSCROLL) && descr->horz_extent)
410 {
411 info.nPos = descr->horz_pos;
412 info.nPage = descr->width;
413 info.fMask = SIF_POS | SIF_PAGE;
414 if (descr->style & LBS_DISABLENOSCROLL)
415 info.fMask |= SIF_DISABLENOSCROLL;
416#ifdef __REACTOS__
417 SetScrollInfo( descr->self, SB_HORZ, &info, TRUE );
418#else
420#endif
421 }
422 else
423 {
424 if (descr->style & LBS_DISABLENOSCROLL)
425 {
426 info.nMin = 0;
427 info.nMax = 0;
429#ifdef __REACTOS__
430 SetScrollInfo( descr->self, SB_HORZ, &info, TRUE );
431#else
433#endif
434 }
435 else
436 {
438 }
439 }
440 }
441}
442
443
444/***********************************************************************
445 * LISTBOX_SetTopItem
446 *
447 * Set the top item of the listbox, scrolling up or down if necessary.
448 */
450{
452
453 TRACE("setting top item %d, scroll %d\n", index, scroll);
454
455 if (index > max) index = max;
456 if (index < 0) index = 0;
457 if (descr->style & LBS_MULTICOLUMN) index -= index % descr->page_size;
458 if (descr->top_item == index) return LB_OKAY;
459 if (scroll)
460 {
461 INT dx = 0, dy = 0;
462 if (descr->style & LBS_MULTICOLUMN)
463 dx = (descr->top_item - index) / descr->page_size * descr->column_width;
464 else if (descr->style & LBS_OWNERDRAWVARIABLE)
465 {
466 INT i;
467 if (index > descr->top_item)
468 {
469 for (i = index - 1; i >= descr->top_item; i--)
471 }
472 else
473 {
474 for (i = index; i < descr->top_item; i++)
476 }
477 }
478 else
479 dy = (descr->top_item - index) * descr->item_height;
480
483 }
484 else
486 descr->top_item = index;
488 return LB_OKAY;
489}
490
491
492/***********************************************************************
493 * LISTBOX_UpdatePage
494 *
495 * Update the page size. Should be called when the size of
496 * the client area or the item height changes.
497 */
499{
501
502 if ((descr->item_height == 0) || (page_size = descr->height / descr->item_height) < 1)
503 page_size = 1;
504 if (page_size == descr->page_size) return;
505 descr->page_size = page_size;
506 if (descr->style & LBS_MULTICOLUMN)
508 LISTBOX_SetTopItem( descr, descr->top_item, FALSE );
509}
510
511
512/***********************************************************************
513 * LISTBOX_UpdateSize
514 *
515 * Update the size of the listbox. Should be called when the size of
516 * the client area changes.
517 */
519{
520 RECT rect;
522
523 GetClientRect( descr->self, &rect );
524 if (style & WS_HSCROLL)
526 descr->width = rect.right - rect.left;
527 descr->height = rect.bottom - rect.top;
528 if (!(descr->style & LBS_NOINTEGRALHEIGHT) && !(descr->style & LBS_OWNERDRAWVARIABLE))
529 {
530 int height = descr->height;
531 INT remaining;
532 RECT rect;
533
534 /* The whole point of integral height is to ensure that partial items
535 * aren't displayed. Native seems to fail to take the horizontal
536 * scrollbar into account (while successfully taking into account e.g.
537 * WS_EX_CLIENTEDGE), so it ends up obscuring partial items anyway.
538 *
539 * It's not clear if native is trying to work from
540 * the window rect as opposed to the client rect [and badly
541 * reimplementing AdjustWindowRect()] or poorly working around the case
542 * where the horizontal scrollbar is repeatedly toggled (which could
543 * unnecessarily shrink the scrollbar every time it happens). */
546
547 GetWindowRect( descr->self, &rect );
548 if(descr->item_height != 0)
549 remaining = height % descr->item_height;
550 else
551 remaining = 0;
552 if ((height > descr->item_height) && remaining)
553 {
554 TRACE( "[%p]: changing height %d -> %d\n", descr->self, height, height - remaining );
555 NtUserSetWindowPos( descr->self, 0, 0, 0, rect.right - rect.left,
556 rect.bottom - rect.top - remaining,
558 return;
559 }
560 }
561 TRACE("[%p]: new size = %d,%d\n", descr->self, descr->width, descr->height );
564
565 /* Invalidate the focused item so it will be repainted correctly */
566 if (LISTBOX_GetItemRect( descr, descr->focus_item, &rect ) == 1)
567 {
569 }
570}
571
572
573/***********************************************************************
574 * LISTBOX_GetItemRect
575 *
576 * Get the rectangle enclosing an item, in listbox client coordinates.
577 * Return 1 if the rectangle is (partially) visible, 0 if hidden, -1 on error.
578 */
580{
581 /* Index <= 0 is legal even on empty listboxes */
582 if (index && (index >= descr->nb_items))
583 {
586 return LB_ERR;
587 }
588 SetRect( rect, 0, 0, descr->width, descr->height );
589 if (descr->style & LBS_MULTICOLUMN)
590 {
591 INT col = (index / descr->page_size) -
592 (descr->top_item / descr->page_size);
593 rect->left += col * descr->column_width;
594 rect->right = rect->left + descr->column_width;
595 rect->top += (index % descr->page_size) * descr->item_height;
596 rect->bottom = rect->top + descr->item_height;
597 }
598 else if (descr->style & LBS_OWNERDRAWVARIABLE)
599 {
600 INT i;
601 rect->right += descr->horz_pos;
602 if ((index >= 0) && (index < descr->nb_items))
603 {
604 if (index < descr->top_item)
605 {
606 for (i = descr->top_item-1; i >= index; i--)
608 }
609 else
610 {
611 for (i = descr->top_item; i < index; i++)
613 }
615
616 }
617 }
618 else
619 {
620 rect->top += (index - descr->top_item) * descr->item_height;
621 rect->bottom = rect->top + descr->item_height;
622 rect->right += descr->horz_pos;
623 }
624
625 TRACE("item %d, rect %s\n", index, wine_dbgstr_rect(rect));
626
627 return ((rect->left < descr->width) && (rect->right > 0) &&
628 (rect->top < descr->height) && (rect->bottom > 0));
629}
630
631
632/***********************************************************************
633 * LISTBOX_GetItemFromPoint
634 *
635 * Return the item nearest from point (x,y) (in client coordinates).
636 */
638{
639 INT index = descr->top_item;
640
641 if (!descr->nb_items) return -1; /* No items */
642 if (descr->style & LBS_OWNERDRAWVARIABLE)
643 {
644 INT pos = 0;
645 if (y >= 0)
646 {
647 while (index < descr->nb_items)
648 {
649 if ((pos += get_item_height(descr, index)) > y) break;
650 index++;
651 }
652 }
653 else
654 {
655 while (index > 0)
656 {
657 index--;
658 if ((pos -= get_item_height(descr, index)) <= y) break;
659 }
660 }
661 }
662 else if (descr->style & LBS_MULTICOLUMN)
663 {
664 if (y >= descr->item_height * descr->page_size) return -1;
665 if (y >= 0) index += y / descr->item_height;
666 if (x >= 0) index += (x / descr->column_width) * descr->page_size;
667 else index -= (((x + 1) / descr->column_width) - 1) * descr->page_size;
668 }
669 else
670 {
671 index += (y / descr->item_height);
672 }
673 if (index < 0) return 0;
674 if (index >= descr->nb_items) return -1;
675 return index;
676}
677
678
679/***********************************************************************
680 * LISTBOX_PaintItem
681 *
682 * Paint an item.
683 */
685 INT index, UINT action, BOOL ignoreFocus )
686{
687 BOOL selected = FALSE, focused;
688 WCHAR *item_str = NULL;
689
690 if (index < descr->nb_items)
691 {
692 item_str = get_item_string(descr, index);
694 }
695
696#ifdef __REACTOS__
697 focused = !ignoreFocus && descr->focus_item == index && descr->caret_on && descr->in_focus
698 && !(descr->UIState & UISF_HIDEFOCUS);
699#else
700 focused = !ignoreFocus && descr->focus_item == index && descr->caret_on && descr->in_focus;
701#endif
702
703 if (IS_OWNERDRAW(descr))
704 {
705 DRAWITEMSTRUCT dis;
706 RECT r;
707 HRGN hrgn;
708
709 if (index >= descr->nb_items)
710 {
711 if (action == ODA_FOCUS)
712 { // REACTOS
713 if (!(descr->UIState & UISF_HIDEFOCUS))
715 } //
716 else
717 ERR("called with an out of bounds index %d(%d) in owner draw, Not good.\n",index,descr->nb_items);
718 return;
719 }
720
721 /* some programs mess with the clipping region when
722 drawing the item, *and* restore the previous region
723 after they are done, so a region has better to exist
724 else everything ends clipped */
725 GetClientRect(descr->self, &r);
727
728 dis.CtlType = ODT_LISTBOX;
729 dis.CtlID = GetWindowLongPtrW( descr->self, GWLP_ID );
730 dis.hwndItem = descr->self;
731 dis.itemAction = action;
732 dis.hDC = hdc;
733 dis.itemID = index;
734 dis.itemState = 0;
735 if (selected)
736 dis.itemState |= ODS_SELECTED;
737 if (focused)
738 dis.itemState |= ODS_FOCUS;
739 if (!IsWindowEnabled(descr->self)) dis.itemState |= ODS_DISABLED;
741 dis.rcItem = *rect;
742 TRACE("[%p]: drawitem %d (%s) action=%02x state=%02x rect=%s\n",
743 descr->self, index, debugstr_w(item_str), action,
745 SendMessageW(descr->owner, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
747 if (hrgn) DeleteObject( hrgn );
748 }
749 else
750 {
751 COLORREF oldText = 0, oldBk = 0;
752
753 if (action == ODA_FOCUS)
754 {
755 if (!(descr->UIState & UISF_HIDEFOCUS)) // REACTOS
757 return;
758 }
759 if (selected)
760 {
763 }
764#ifdef __REACTOS__
765 else
766 {
767 HBRUSH br = GetCurrentObject(hdc, OBJ_BRUSH);
768 FillRect(hdc, rect, br);
769 }
770#endif
771
772 TRACE("[%p]: painting %d (%s) action=%02x rect=%s\n",
773 descr->self, index, debugstr_w(item_str), action,
775 if (!item_str)
776 ExtTextOutW( hdc, rect->left + 1, rect->top,
778 else if (!(descr->style & LBS_USETABSTOPS))
779#ifdef __REACTOS__
780 {
781 RECT rc = *rect;
782 if (!selected)
783 {
784 SIZE sz;
785 GetTextExtentPoint32(hdc, item_str, strlenW(item_str), &sz);
786 rc.right = min(sz.cx, rc.right);
787 }
788 ExtTextOutW( hdc, rect->left + 1, rect->top,
789 ETO_OPAQUE | ETO_CLIPPED, &rc, item_str,
790 strlenW(item_str), NULL);
791 }
792#else
793 ExtTextOutW( hdc, rect->left + 1, rect->top,
794 ETO_OPAQUE | ETO_CLIPPED, rect, item_str,
795 lstrlenW(item_str), NULL );
796#endif
797 else
798 {
799 /* Output empty string to paint background in the full width. */
800 ExtTextOutW( hdc, rect->left + 1, rect->top,
803 item_str, lstrlenW(item_str),
804 descr->nb_tabs, descr->tabs, 0);
805 }
806 if (selected)
807 {
808 SetBkColor( hdc, oldBk );
809 SetTextColor( hdc, oldText );
810 }
811 if (focused)
813 }
814}
815
816
817/***********************************************************************
818 * LISTBOX_SetRedraw
819 *
820 * Change the redraw flag.
821 */
823{
824 if (on)
825 {
826 if (!(descr->style & LBS_NOREDRAW)) return;
827 descr->style &= ~LBS_NOREDRAW;
828 if (descr->style & LBS_DISPLAYCHANGED)
829 { /* page was changed while setredraw false, refresh automatically */
831 if ((descr->top_item + descr->page_size) > descr->nb_items)
832 { /* reset top of page if less than number of items/page */
833 descr->top_item = descr->nb_items - descr->page_size;
834 if (descr->top_item < 0) descr->top_item = 0;
835 }
836 descr->style &= ~LBS_DISPLAYCHANGED;
837 }
839 }
840 else descr->style |= LBS_NOREDRAW;
841}
842
843
844/***********************************************************************
845 * LISTBOX_RepaintItem
846 *
847 * Repaint a single item synchronously.
848 */
850{
851 HDC hdc;
852 RECT rect;
853 HFONT oldFont = 0;
854 HBRUSH hbrush, oldBrush = 0;
855
856 /* Do not repaint the item if the item is not visible */
857 if (!IsWindowVisible(descr->self)) return;
858 if (descr->style & LBS_NOREDRAW)
859 {
860 descr->style |= LBS_DISPLAYCHANGED;
861 return;
862 }
863 if (LISTBOX_GetItemRect( descr, index, &rect ) != 1) return;
864 if (!(hdc = NtUserGetDCEx( descr->self, 0, DCX_CACHE ))) return;
865 if (descr->font) oldFont = SelectObject( hdc, descr->font );
866#ifdef __REACTOS__
868#else
869 hbrush = (HBRUSH)SendMessageW( descr->owner, WM_CTLCOLORLISTBOX,
870 (WPARAM)hdc, (LPARAM)descr->self );
871#endif
872 if (hbrush) oldBrush = SelectObject( hdc, hbrush );
873 if (!IsWindowEnabled(descr->self))
875 SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
877 if (oldFont) SelectObject( hdc, oldFont );
878 if (oldBrush) SelectObject( hdc, oldBrush );
879 NtUserReleaseDC( descr->self, hdc );
880}
881
882
883/***********************************************************************
884 * LISTBOX_DrawFocusRect
885 */
887{
888 HDC hdc;
889 RECT rect;
890 HFONT oldFont = 0;
891
892 /* Do not repaint the item if the item is not visible */
893 if (!IsWindowVisible(descr->self)) return;
894
895 if (descr->focus_item == -1) return;
896 if (!descr->caret_on || !descr->in_focus) return;
897
898 if (LISTBOX_GetItemRect( descr, descr->focus_item, &rect ) != 1) return;
899 if (!(hdc = NtUserGetDCEx( descr->self, 0, DCX_CACHE ))) return;
900 if (descr->font) oldFont = SelectObject( hdc, descr->font );
901 if (!IsWindowEnabled(descr->self))
903 SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
904 LISTBOX_PaintItem( descr, hdc, &rect, descr->focus_item, ODA_FOCUS, !on );
905 if (oldFont) SelectObject( hdc, oldFont );
906 NtUserReleaseDC( descr->self, hdc );
907}
908
909
910/***********************************************************************
911 * LISTBOX_InitStorage
912 */
914{
915 UINT new_size = descr->nb_items + nb_items;
916
917 if (new_size > descr->items_size && !resize_storage(descr, new_size))
918 return LB_ERRSPACE;
919 return descr->items_size;
920}
921
922
923/***********************************************************************
924 * LISTBOX_SetTabStops
925 */
927{
928 INT i;
929
930 if (!(descr->style & LBS_USETABSTOPS))
931 {
933 return FALSE;
934 }
935
936 HeapFree( GetProcessHeap(), 0, descr->tabs );
937 if (!(descr->nb_tabs = count))
938 {
939 descr->tabs = NULL;
940 return TRUE;
941 }
942 if (!(descr->tabs = HeapAlloc( GetProcessHeap(), 0,
943 descr->nb_tabs * sizeof(INT) )))
944 return FALSE;
945 memcpy( descr->tabs, tabs, descr->nb_tabs * sizeof(INT) );
946
947 /* convert into "dialog units"*/
948 for (i = 0; i < descr->nb_tabs; i++)
949 descr->tabs[i] = MulDiv(descr->tabs[i], descr->avg_char_width, 4);
950
951 return TRUE;
952}
953
954
955/***********************************************************************
956 * LISTBOX_GetText
957 */
959{
960 DWORD len;
961
962 if ((index < 0) || (index >= descr->nb_items))
963 {
965 return LB_ERR;
966 }
967
968 if (HAS_STRINGS(descr))
969 {
971
972 if (!buffer)
973 {
974 len = lstrlenW(str);
975 if( unicode )
976 return len;
977 return WideCharToMultiByte( CP_ACP, 0, str, len, NULL, 0, NULL, NULL );
978 }
979
980 TRACE("index %d (0x%04x) %s\n", index, index, debugstr_w(str));
981
982 _SEH2_TRY /* hide a Delphi bug that passes a read-only buffer */
983 {
984 if(unicode)
985 {
988 }
989 else
990 {
992 0x7FFFFFFF, NULL, NULL) - 1;
993 }
994 }
996 {
997 ERR( "got an invalid buffer (Delphi bug?)\n" );
999 len = LB_ERR;
1000 }
1001 _SEH2_END
1002 } else
1003 {
1004 if (buffer)
1006 len = sizeof(ULONG_PTR);
1007 }
1008 return len;
1009}
1010
1012{
1014 if (ret == CSTR_LESS_THAN)
1015 return -1;
1016 if (ret == CSTR_EQUAL)
1017 return 0;
1018 if (ret == CSTR_GREATER_THAN)
1019 return 1;
1020 return -1;
1021}
1022
1023/***********************************************************************
1024 * LISTBOX_FindStringPos
1025 *
1026 * Find the nearest string located before a given string in sort order.
1027 * If 'exact' is TRUE, return an error if we don't get an exact match.
1028 */
1030{
1031 INT index, min, max, res;
1032
1033 if (!descr->nb_items || !(descr->style & LBS_SORT)) return -1; /* Add it at the end */
1034
1035 min = 0;
1036 max = descr->nb_items - 1;
1037 while (min <= max)
1038 {
1039 index = (min + max) / 2;
1040 if (HAS_STRINGS(descr))
1042 else
1043 {
1045 UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID );
1046
1047 cis.CtlType = ODT_LISTBOX;
1048 cis.CtlID = id;
1049 cis.hwndItem = descr->self;
1050 /* note that some application (MetaStock) expects the second item
1051 * to be in the listbox */
1052 cis.itemID1 = index;
1054 cis.itemID2 = -1;
1055 cis.itemData2 = (ULONG_PTR)str;
1056 cis.dwLocaleId = descr->locale;
1057 res = SendMessageW( descr->owner, WM_COMPAREITEM, id, (LPARAM)&cis );
1058 }
1059 if (!res) return index;
1060 if (res > 0) max = index - 1;
1061 else min = index + 1;
1062 }
1063 return exact ? -1 : min;
1064}
1065
1066
1067/***********************************************************************
1068 * LISTBOX_FindFileStrPos
1069 *
1070 * Find the nearest string located before a given string in directory
1071 * sort order (i.e. first files, then directories, then drives).
1072 */
1074{
1075 INT min, max, res;
1076
1077 if (!HAS_STRINGS(descr))
1079 min = 0;
1080 max = descr->nb_items;
1081 while (min != max)
1082 {
1083 INT index = (min + max) / 2;
1085 if (*p == '[') /* drive or directory */
1086 {
1087 if (*str != '[') res = -1;
1088 else if (p[1] == '-') /* drive */
1089 {
1090 if (str[1] == '-') res = str[2] - p[2];
1091 else res = -1;
1092 }
1093 else /* directory */
1094 {
1095 if (str[1] == '-') res = 1;
1096 else res = LISTBOX_lstrcmpiW( descr->locale, str, p, -1 );
1097 }
1098 }
1099 else /* filename */
1100 {
1101 if (*str == '[') res = 1;
1102 else res = LISTBOX_lstrcmpiW( descr->locale, str, p, -1 );
1103 }
1104 if (!res) return index;
1105 if (res < 0) max = index;
1106 else min = index + 1;
1107 }
1108 return max;
1109}
1110
1111
1112/***********************************************************************
1113 * LISTBOX_FindString
1114 *
1115 * Find the item beginning with a given string.
1116 */
1118{
1119 INT i, index;
1120
1121 if (descr->style & LBS_NODATA)
1122 {
1124 return LB_ERR;
1125 }
1126
1127 start++;
1128 if (start >= descr->nb_items) start = 0;
1129 if (HAS_STRINGS(descr))
1130 {
1131 if (!str || ! str[0] ) return LB_ERR;
1132 if (exact)
1133 {
1134 for (i = 0, index = start; i < descr->nb_items; i++, index++)
1135 {
1136 if (index == descr->nb_items) index = 0;
1137 if (!LISTBOX_lstrcmpiW(descr->locale, str, get_item_string(descr, index), -1))
1138 return index;
1139 }
1140 }
1141 else
1142 {
1143 /* Special case for drives and directories: ignore prefix */
1144 INT len = lstrlenW(str);
1145 WCHAR *item_str;
1146
1147 for (i = 0, index = start; i < descr->nb_items; i++, index++)
1148 {
1149 if (index == descr->nb_items) index = 0;
1150 item_str = get_item_string(descr, index);
1151
1152 if (!LISTBOX_lstrcmpiW(descr->locale, str, item_str, len)) return index;
1153 if (item_str[0] == '[')
1154 {
1155 if (!LISTBOX_lstrcmpiW(descr->locale, str, item_str + 1, len)) return index;
1156 if (item_str[1] == '-' && !LISTBOX_lstrcmpiW(descr->locale, str, item_str + 2, len)) return index;
1157 }
1158 }
1159 }
1160 }
1161 else
1162 {
1163 if (exact && (descr->style & LBS_SORT))
1164 /* If sorted, use a WM_COMPAREITEM binary search */
1165 return LISTBOX_FindStringPos( descr, str, TRUE );
1166
1167 /* Otherwise use a linear search */
1168 for (i = 0, index = start; i < descr->nb_items; i++, index++)
1169 {
1170 if (index == descr->nb_items) index = 0;
1171 if (get_item_data(descr, index) == (ULONG_PTR)str) return index;
1172 }
1173 }
1174 return LB_ERR;
1175}
1176
1177
1178/***********************************************************************
1179 * LISTBOX_GetSelCount
1180 */
1182{
1183 INT i, count;
1184
1185 if (!(descr->style & LBS_MULTIPLESEL) ||
1186 (descr->style & LBS_NOSEL))
1187 return LB_ERR;
1188 for (i = count = 0; i < descr->nb_items; i++)
1189 if (is_item_selected(descr, i)) count++;
1190 return count;
1191}
1192
1193
1194/***********************************************************************
1195 * LISTBOX_GetSelItems
1196 */
1198{
1199 INT i, count;
1200
1201 if (!(descr->style & LBS_MULTIPLESEL)) return LB_ERR;
1202 for (i = count = 0; (i < descr->nb_items) && (count < max); i++)
1203 if (is_item_selected(descr, i)) array[count++] = i;
1204 return count;
1205}
1206
1207
1208/***********************************************************************
1209 * LISTBOX_Paint
1210 */
1212{
1213 INT i, col_pos = descr->page_size - 1;
1214 RECT rect;
1215 RECT focusRect = {-1, -1, -1, -1};
1216 HFONT oldFont = 0;
1217 HBRUSH hbrush, oldBrush = 0;
1218
1219 if (descr->style & LBS_NOREDRAW) return 0;
1220
1221 SetRect( &rect, 0, 0, descr->width, descr->height );
1222 if (descr->style & LBS_MULTICOLUMN)
1223 rect.right = rect.left + descr->column_width;
1224 else if (descr->horz_pos)
1225 {
1226 SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
1227 rect.right += descr->horz_pos;
1228 }
1229
1230 if (descr->font) oldFont = SelectObject( hdc, descr->font );
1231#ifdef __REACTOS__
1233#else
1234 hbrush = (HBRUSH)SendMessageW( descr->owner, WM_CTLCOLORLISTBOX,
1235 (WPARAM)hdc, (LPARAM)descr->self );
1236#endif
1237 if (hbrush) oldBrush = SelectObject( hdc, hbrush );
1239
1240 if (!descr->nb_items && (descr->focus_item != -1) && descr->caret_on &&
1241 (descr->in_focus))
1242 {
1243 /* Special case for empty listbox: paint focus rect */
1244 rect.bottom = rect.top + descr->item_height;
1246 &rect, NULL, 0, NULL );
1247 LISTBOX_PaintItem( descr, hdc, &rect, descr->focus_item, ODA_FOCUS, FALSE );
1248 rect.top = rect.bottom;
1249 }
1250
1251 /* Paint all the item, regarding the selection
1252 Focus state will be painted after */
1253
1254 for (i = descr->top_item; i < descr->nb_items; i++)
1255 {
1256 if (!(descr->style & LBS_OWNERDRAWVARIABLE))
1257 rect.bottom = rect.top + descr->item_height;
1258 else
1260
1261 /* keep the focus rect, to paint the focus item after */
1262 if (i == descr->focus_item)
1263 focusRect = rect;
1264#ifdef __REACTOS__
1265 rect.bottom = min(rect.bottom, descr->height);
1266#endif
1268 rect.top = rect.bottom;
1269
1270 if ((descr->style & LBS_MULTICOLUMN) && !col_pos)
1271 {
1272 if (!IS_OWNERDRAW(descr))
1273 {
1274 /* Clear the bottom of the column */
1275 if (rect.top < descr->height)
1276 {
1277 rect.bottom = descr->height;
1279 &rect, NULL, 0, NULL );
1280 }
1281 }
1282
1283 /* Go to the next column */
1284 rect.left += descr->column_width;
1285 rect.right += descr->column_width;
1286 rect.top = 0;
1287 col_pos = descr->page_size - 1;
1288 if (rect.left >= descr->width) break;
1289 }
1290 else
1291 {
1292 col_pos--;
1293 if (rect.top >= descr->height) break;
1294 }
1295 }
1296
1297 /* Paint the focus item now */
1298 if (focusRect.top != focusRect.bottom &&
1299 descr->caret_on && descr->in_focus)
1300 LISTBOX_PaintItem( descr, hdc, &focusRect, descr->focus_item, ODA_FOCUS, FALSE );
1301
1302 if (!IS_OWNERDRAW(descr))
1303 {
1304 /* Clear the remainder of the client area */
1305 if (rect.top < descr->height)
1306 {
1307 rect.bottom = descr->height;
1308#ifdef __REACTOS__
1309 HBRUSH br = GetCurrentObject(hdc, OBJ_BRUSH);
1310 FillRect(hdc, &rect, br);
1311#else
1313 &rect, NULL, 0, NULL );
1314#endif
1315 }
1316 if (rect.right < descr->width)
1317 {
1318 rect.left = rect.right;
1319 rect.right = descr->width;
1320 rect.top = 0;
1321 rect.bottom = descr->height;
1322#ifdef __REACTOS__
1323 HBRUSH br = GetCurrentObject(hdc, OBJ_BRUSH);
1324 FillRect(hdc, &rect, br);
1325#else
1327 &rect, NULL, 0, NULL );
1328#endif
1329 }
1330 }
1331 if (oldFont) SelectObject( hdc, oldFont );
1332 if (oldBrush) SelectObject( hdc, oldBrush );
1333 return 0;
1334}
1335
1336
1337/***********************************************************************
1338 * LISTBOX_InvalidateItems
1339 *
1340 * Invalidate all items from a given item. If the specified item is not
1341 * visible, nothing happens.
1342 */
1344{
1345 RECT rect;
1346
1347 if (LISTBOX_GetItemRect( descr, index, &rect ) == 1)
1348 {
1349 if (descr->style & LBS_NOREDRAW)
1350 {
1351 descr->style |= LBS_DISPLAYCHANGED;
1352 return;
1353 }
1354 rect.bottom = descr->height;
1355 NtUserInvalidateRect( descr->self, &rect, TRUE );
1356 if (descr->style & LBS_MULTICOLUMN)
1357 {
1358 /* Repaint the other columns */
1359 rect.left = rect.right;
1360 rect.right = descr->width;
1361 rect.top = 0;
1362 NtUserInvalidateRect( descr->self, &rect, TRUE );
1363 }
1364 }
1365}
1366
1368{
1369 RECT rect;
1370
1371 if (LISTBOX_GetItemRect( descr, index, &rect ) == 1)
1372 NtUserInvalidateRect( descr->self, &rect, TRUE );
1373}
1374
1375/***********************************************************************
1376 * LISTBOX_GetItemHeight
1377 */
1379{
1380 if (descr->style & LBS_OWNERDRAWVARIABLE && descr->nb_items > 0)
1381 {
1382 if ((index < 0) || (index >= descr->nb_items))
1383 {
1385 return LB_ERR;
1386 }
1387 return get_item_height(descr, index);
1388 }
1389 else return descr->item_height;
1390}
1391
1392
1393/***********************************************************************
1394 * LISTBOX_SetItemHeight
1395 */
1397{
1398 if (height > MAXBYTE)
1399 return -1;
1400
1401 if (!height) height = 1;
1402
1403 if (descr->style & LBS_OWNERDRAWVARIABLE)
1404 {
1405 if ((index < 0) || (index >= descr->nb_items))
1406 {
1408 return LB_ERR;
1409 }
1410 TRACE("[%p]: item %d height = %d\n", descr->self, index, height );
1413 if (repaint)
1415 }
1416 else if (height != descr->item_height)
1417 {
1418 TRACE("[%p]: new height = %d\n", descr->self, height );
1419 descr->item_height = height;
1422 if (repaint)
1423 NtUserInvalidateRect( descr->self, 0, TRUE );
1424 }
1425 return LB_OKAY;
1426}
1427
1428
1429/***********************************************************************
1430 * LISTBOX_SetHorizontalPos
1431 */
1433{
1434 INT diff;
1435
1436 if (pos > descr->horz_extent - descr->width)
1437 pos = descr->horz_extent - descr->width;
1438 if (pos < 0) pos = 0;
1439 if (!(diff = descr->horz_pos - pos)) return;
1440 TRACE("[%p]: new horz pos = %d\n", descr->self, pos );
1441 descr->horz_pos = pos;
1443 if (abs(diff) < descr->width)
1444 {
1445 RECT rect;
1446 /* Invalidate the focused item so it will be repainted correctly */
1447 if (LISTBOX_GetItemRect( descr, descr->focus_item, &rect ) == 1)
1448 NtUserInvalidateRect( descr->self, &rect, TRUE );
1449 NtUserScrollWindowEx( descr->self, diff, 0, NULL, NULL, 0, NULL,
1451 }
1452 else
1454}
1455
1456
1457/***********************************************************************
1458 * LISTBOX_SetHorizontalExtent
1459 */
1461{
1462 if (descr->style & LBS_MULTICOLUMN)
1463 return LB_OKAY;
1464 if (extent == descr->horz_extent) return LB_OKAY;
1465 TRACE("[%p]: new horz extent = %d\n", descr->self, extent );
1466 descr->horz_extent = extent;
1467 if (descr->style & WS_HSCROLL) {
1469 info.cbSize = sizeof(info);
1470 info.nMin = 0;
1471 info.nMax = descr->horz_extent ? descr->horz_extent - 1 : 0;
1472 info.fMask = SIF_RANGE;
1473 if (descr->style & LBS_DISABLENOSCROLL)
1474 info.fMask |= SIF_DISABLENOSCROLL;
1475#ifdef __REACTOS__
1476 SetScrollInfo(descr->self, SB_HORZ, &info, TRUE);
1477#else
1479#endif
1480 }
1481 if (descr->horz_pos > extent - descr->width)
1483 return LB_OKAY;
1484}
1485
1486
1487/***********************************************************************
1488 * LISTBOX_SetColumnWidth
1489 */
1491{
1492 RECT rect;
1493
1494 TRACE("[%p]: new column width = %d\n", descr->self, column_width);
1495
1496 GetClientRect(descr->self, &rect);
1497 descr->width = rect.right - rect.left;
1498 descr->height = rect.bottom - rect.top;
1499 descr->column_width = column_width;
1500
1503 return LB_OKAY;
1504}
1505
1506
1507/***********************************************************************
1508 * LISTBOX_SetFont
1509 *
1510 * Returns the item height.
1511 */
1513{
1514 HDC hdc;
1515 HFONT oldFont = 0;
1516 const char *alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
1517 SIZE sz;
1518
1519 descr->font = font;
1520
1521 if (!(hdc = NtUserGetDCEx( descr->self, 0, DCX_CACHE )))
1522 {
1523 ERR("unable to get DC.\n" );
1524 return 16;
1525 }
1526 if (font) oldFont = SelectObject( hdc, font );
1527 GetTextExtentPointA( hdc, alphabet, 52, &sz);
1528 if (oldFont) SelectObject( hdc, oldFont );
1529 NtUserReleaseDC( descr->self, hdc );
1530
1531 descr->avg_char_width = (sz.cx / 26 + 1) / 2;
1532 if (!IS_OWNERDRAW(descr))
1534 return sz.cy;
1535}
1536
1537
1538/***********************************************************************
1539 * LISTBOX_MakeItemVisible
1540 *
1541 * Make sure that a given item is partially or fully visible.
1542 */
1544{
1545 INT top;
1546
1547 TRACE("current top item %d, index %d, fully %d\n", descr->top_item, index, fully);
1548
1549 if (index <= descr->top_item) top = index;
1550 else if (descr->style & LBS_MULTICOLUMN)
1551 {
1552 INT cols = descr->width;
1553 if (!fully) cols += descr->column_width - 1;
1554 if (cols >= descr->column_width) cols /= descr->column_width;
1555 else cols = 1;
1556 if (index < descr->top_item + (descr->page_size * cols)) return;
1557 top = index - descr->page_size * (cols - 1);
1558 }
1559 else if (descr->style & LBS_OWNERDRAWVARIABLE)
1560 {
1561 INT height = fully ? get_item_height(descr, index) : 1;
1562 for (top = index; top > descr->top_item; top--)
1563 if ((height += get_item_height(descr, top - 1)) > descr->height) break;
1564 }
1565 else
1566 {
1567 if (index < descr->top_item + descr->page_size) return;
1568 if (!fully && (index == descr->top_item + descr->page_size) &&
1569 (descr->height > (descr->page_size * descr->item_height))) return;
1570 top = index - descr->page_size + 1;
1571 }
1573}
1574
1575/***********************************************************************
1576 * LISTBOX_SetCaretIndex
1577 *
1578 * NOTES
1579 * index must be between 0 and descr->nb_items-1, or LB_ERR is returned.
1580 *
1581 */
1583{
1584 BOOL focus_changed = descr->focus_item != index;
1585
1586 TRACE("old focus %d, index %d\n", descr->focus_item, index);
1587
1588 if (descr->style & LBS_NOSEL) return LB_ERR;
1589 if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
1590
1591 if (focus_changed)
1592 {
1594 descr->focus_item = index;
1595 }
1596
1597 LISTBOX_MakeItemVisible( descr, index, fully_visible );
1598
1599 if (focus_changed)
1601
1602 return LB_OKAY;
1603}
1604
1605
1606/***********************************************************************
1607 * LISTBOX_SelectItemRange
1608 *
1609 * Select a range of items. Should only be used on a MULTIPLESEL listbox.
1610 */
1612 INT last, BOOL on )
1613{
1614 INT i;
1615
1616 /* A few sanity checks */
1617
1618 if (descr->style & LBS_NOSEL) return LB_ERR;
1619 if (!(descr->style & LBS_MULTIPLESEL)) return LB_ERR;
1620
1621 if (!descr->nb_items) return LB_OKAY;
1622
1623 if (last == -1 || last >= descr->nb_items) last = descr->nb_items - 1;
1624 if (first < 0) first = 0;
1625 if (last < first) return LB_OKAY;
1626
1627 if (on) /* Turn selection on */
1628 {
1629 for (i = first; i <= last; i++)
1630 {
1631 if (is_item_selected(descr, i)) continue;
1634 }
1635 }
1636 else /* Turn selection off */
1637 {
1638 for (i = first; i <= last; i++)
1639 {
1640 if (!is_item_selected(descr, i)) continue;
1643 }
1644 }
1645 return LB_OKAY;
1646}
1647
1648/***********************************************************************
1649 * LISTBOX_SetSelection
1650 */
1652 BOOL on, BOOL send_notify )
1653{
1654 TRACE( "cur_sel=%d index=%d notify=%s\n",
1655 descr->selected_item, index, send_notify ? "YES" : "NO" );
1656
1657 if (descr->style & LBS_NOSEL)
1658 {
1659 descr->selected_item = index;
1660 return LB_ERR;
1661 }
1662 if ((index < -1) || (index >= descr->nb_items)) return LB_ERR;
1663 if (descr->style & LBS_MULTIPLESEL)
1664 {
1665 if (index == -1) /* Select all items */
1666 return LISTBOX_SelectItemRange( descr, 0, descr->nb_items, on );
1667 else /* Only one item */
1668 return LISTBOX_SelectItemRange( descr, index, index, on );
1669 }
1670 else
1671 {
1672 INT oldsel = descr->selected_item;
1673 if (index == oldsel) return LB_OKAY;
1674 if (oldsel != -1) set_item_selected_state(descr, oldsel, FALSE);
1676 descr->selected_item = index;
1677 if (oldsel != -1) LISTBOX_RepaintItem( descr, oldsel, ODA_SELECT );
1679 if (send_notify && descr->nb_items) SEND_NOTIFICATION( descr,
1680 (index != -1) ? LBN_SELCHANGE : LBN_SELCANCEL );
1681 else
1682 if( descr->lphc ) /* set selection change flag for parent combo */
1683 descr->lphc->wState |= CBF_SELCHANGE;
1684 }
1685 return LB_OKAY;
1686}
1687
1688
1689/***********************************************************************
1690 * LISTBOX_MoveCaret
1691 *
1692 * Change the caret position and extend the selection to the new caret.
1693 */
1694static void LISTBOX_MoveCaret( LB_DESCR *descr, INT index, BOOL fully_visible )
1695{
1696 TRACE("old focus %d, index %d\n", descr->focus_item, index);
1697
1698 if ((index < 0) || (index >= descr->nb_items))
1699 return;
1700
1701 /* Important, repaint needs to be done in this order if
1702 you want to mimic Windows behavior:
1703 1. Remove the focus and paint the item
1704 2. Remove the selection and paint the item(s)
1705 3. Set the selection and repaint the item(s)
1706 4. Set the focus to 'index' and repaint the item */
1707
1708 /* 1. remove the focus and repaint the item */
1710
1711 /* 2. then turn off the previous selection */
1712 /* 3. repaint the new selected item */
1713 if (descr->style & LBS_EXTENDEDSEL)
1714 {
1715 if (descr->anchor_item != -1)
1716 {
1717 INT first = min( index, descr->anchor_item );
1718 INT last = max( index, descr->anchor_item );
1719 if (first > 0)
1723 }
1724 }
1725 else if (!(descr->style & LBS_MULTIPLESEL))
1726 {
1727 /* Set selection to new caret item */
1729 }
1730
1731 /* 4. repaint the new item with the focus */
1732 descr->focus_item = index;
1733 LISTBOX_MakeItemVisible( descr, index, fully_visible );
1735}
1736
1737
1738/***********************************************************************
1739 * LISTBOX_InsertItem
1740 */
1743{
1744 INT oldfocus = descr->focus_item;
1745
1746 if (index == -1) index = descr->nb_items;
1747 else if ((index < 0) || (index > descr->nb_items)) return LB_ERR;
1748 if (!resize_storage(descr, descr->nb_items + 1)) return LB_ERR;
1749
1751 descr->nb_items++;
1756
1757 /* Get item height */
1758
1759 if (descr->style & LBS_OWNERDRAWVARIABLE)
1760 {
1762 UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID );
1763
1764 mis.CtlType = ODT_LISTBOX;
1765 mis.CtlID = id;
1766 mis.itemID = index;
1767 mis.itemData = str ? (ULONG_PTR)str : data;
1768 mis.itemHeight = descr->item_height;
1769 SendMessageW( descr->owner, WM_MEASUREITEM, id, (LPARAM)&mis );
1771 TRACE("[%p]: measure item %d (%s) = %d\n",
1772 descr->self, index, str ? debugstr_w(str) : "", get_item_height(descr, index));
1773 }
1774
1775 NtUserNotifyWinEvent( EVENT_OBJECT_CREATE, descr->self, OBJID_CLIENT, index + 1 );
1776
1777 /* Repaint the items */
1778
1781
1782 /* Move selection and focused item */
1783 /* If listbox was empty, set focus to the first item */
1784 if (descr->nb_items == 1)
1786 /* single select don't change selection index in win31 */
1787 else if ((ISWIN31) && !(IS_MULTISELECT(descr)))
1788 {
1789 descr->selected_item++;
1790 LISTBOX_SetSelection( descr, descr->selected_item-1, TRUE, FALSE );
1791 }
1792 else
1793 {
1794 if (index <= descr->selected_item)
1795 {
1796 descr->selected_item++;
1797 descr->focus_item = oldfocus; /* focus not changed */
1798 }
1799 }
1800 return LB_OKAY;
1801}
1802
1803
1804/***********************************************************************
1805 * LISTBOX_InsertString
1806 */
1808{
1809 LPWSTR new_str = NULL;
1810 LRESULT ret;
1811
1812 if (HAS_STRINGS(descr))
1813 {
1814 if (!str) str = L"";
1815 if (!(new_str = HeapAlloc( GetProcessHeap(), 0, (lstrlenW(str) + 1) * sizeof(WCHAR) )))
1816 {
1818 return LB_ERRSPACE;
1819 }
1820 lstrcpyW(new_str, str);
1821 }
1822
1823 if (index == -1) index = descr->nb_items;
1824 if ((ret = LISTBOX_InsertItem( descr, index, new_str, (ULONG_PTR)str )) != 0)
1825 {
1826 HeapFree( GetProcessHeap(), 0, new_str );
1827 return ret;
1828 }
1829
1830 TRACE("[%p]: added item %d %s\n",
1831 descr->self, index, HAS_STRINGS(descr) ? debugstr_w(new_str) : "" );
1832 return index;
1833}
1834
1835
1836/***********************************************************************
1837 * LISTBOX_DeleteItem
1838 *
1839 * Delete the content of an item. 'index' must be a valid index.
1840 */
1842{
1843 /* Note: Win 3.1 only sends DELETEITEM on owner-draw items,
1844 * while Win95 sends it for all items with user data.
1845 * It's probably better to send it too often than not
1846 * often enough, so this is what we do here.
1847 */
1849 {
1850 DELETEITEMSTRUCT dis;
1851 UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID );
1852
1853 dis.CtlType = ODT_LISTBOX;
1854 dis.CtlID = id;
1855 dis.itemID = index;
1856 dis.hwndItem = descr->self;
1858 SendMessageW( descr->owner, WM_DELETEITEM, id, (LPARAM)&dis );
1859 }
1861}
1862
1863
1864/***********************************************************************
1865 * LISTBOX_RemoveItem
1866 *
1867 * Remove an item from the listbox and delete its content.
1868 */
1870{
1871 if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
1872
1873 /* We need to invalidate the original rect instead of the updated one. */
1875
1876 NtUserNotifyWinEvent( EVENT_OBJECT_DESTROY, descr->self, OBJID_CLIENT, index + 1 );
1877
1878 if (descr->nb_items == 1)
1879 {
1880 SendMessageW(descr->self, LB_RESETCONTENT, 0, 0);
1881 return LB_OKAY;
1882 }
1883 descr->nb_items--;
1886
1887 if (descr->anchor_item == descr->nb_items) descr->anchor_item--;
1888 resize_storage(descr, descr->nb_items);
1889 /* Repaint the items */
1890
1892 /* if we removed the scrollbar, reset the top of the list
1893 (correct for owner-drawn ???) */
1894 if (descr->nb_items == descr->page_size)
1896
1897 /* Move selection and focused item */
1898 if (!IS_MULTISELECT(descr))
1899 {
1900 if (index == descr->selected_item)
1901 descr->selected_item = -1;
1902 else if (index < descr->selected_item)
1903 {
1904 descr->selected_item--;
1905 if (ISWIN31) /* win 31 do not change the selected item number */
1906 LISTBOX_SetSelection( descr, descr->selected_item + 1, TRUE, FALSE);
1907 }
1908 }
1909
1910 if (descr->focus_item >= descr->nb_items)
1911 {
1912 descr->focus_item = descr->nb_items - 1;
1913 if (descr->focus_item < 0) descr->focus_item = 0;
1914 }
1915 return LB_OKAY;
1916}
1917
1918
1919/***********************************************************************
1920 * LISTBOX_ResetContent
1921 */
1923{
1924 INT i;
1925
1926 if (!(descr->style & LBS_NODATA))
1927 for (i = descr->nb_items - 1; i >= 0; i--) LISTBOX_DeleteItem(descr, i);
1928 free( descr->u.items );
1929 descr->nb_items = 0;
1930 descr->top_item = 0;
1931 descr->selected_item = -1;
1932 descr->focus_item = 0;
1933 descr->anchor_item = -1;
1934 descr->items_size = 0;
1935 descr->u.items = NULL;
1936}
1937
1938
1939/***********************************************************************
1940 * LISTBOX_SetCount
1941 */
1943{
1944 UINT orig_num = descr->nb_items;
1945
1946 if (!(descr->style & LBS_NODATA))
1947 {
1949 return LB_ERR;
1950 }
1951
1952 if (!resize_storage(descr, count))
1953 return LB_ERRSPACE;
1954 descr->nb_items = count;
1955 if (descr->style & LBS_NOREDRAW)
1956 descr->style |= LBS_DISPLAYCHANGED;
1957
1958 if (count)
1959 {
1961 if (count < orig_num)
1962 {
1963 descr->anchor_item = min(descr->anchor_item, count - 1);
1964 if (descr->selected_item >= count)
1965 descr->selected_item = -1;
1966
1967 /* If we removed the scrollbar, reset the top of the list */
1968 if (count <= descr->page_size && orig_num > descr->page_size)
1970
1971 descr->focus_item = min(descr->focus_item, count - 1);
1972 }
1973
1974 /* If it was empty before growing, set focus to the first item */
1975 else if (orig_num == 0) LISTBOX_SetCaretIndex(descr, 0, FALSE);
1976 }
1977 else SendMessageW(descr->self, LB_RESETCONTENT, 0, 0);
1978
1980 return LB_OKAY;
1981}
1982
1983
1984/***********************************************************************
1985 * LISTBOX_Directory
1986 */
1988 LPCWSTR filespec, BOOL long_names )
1989{
1990 HANDLE handle;
1993 int pos;
1994 LRESULT maxinsert = LB_ERR;
1995
1996 /* don't scan directory if we just want drives exclusively */
1997 if (attrib != (DDL_DRIVES | DDL_EXCLUSIVE)) {
1998 /* scan directory */
1999 if ((handle = FindFirstFileW(filespec, &entry)) == INVALID_HANDLE_VALUE)
2000 {
2001 int le = GetLastError();
2002 if ((le != ERROR_NO_MORE_FILES) && (le != ERROR_FILE_NOT_FOUND)) return LB_ERR;
2003 }
2004 else
2005 {
2006 do
2007 {
2008 WCHAR buffer[270];
2009 if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
2010 {
2011 if (!(attrib & DDL_DIRECTORY) ||
2012 !wcscmp( entry.cFileName, L"." )) continue;
2013 buffer[0] = '[';
2014 if (!long_names && entry.cAlternateFileName[0])
2015 lstrcpyW( buffer + 1, entry.cAlternateFileName );
2016 else
2017 lstrcpyW( buffer + 1, entry.cFileName );
2018 lstrcatW(buffer, L"]");
2019 }
2020 else /* not a directory */
2021 {
2022#define ATTRIBS (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | \
2023 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE)
2024
2025 if ((attrib & DDL_EXCLUSIVE) &&
2026 ((attrib & ATTRIBS) != (entry.dwFileAttributes & ATTRIBS)))
2027 continue;
2028#undef ATTRIBS
2029 if (!long_names && entry.cAlternateFileName[0])
2030 lstrcpyW( buffer, entry.cAlternateFileName );
2031 else
2032 lstrcpyW( buffer, entry.cFileName );
2033 }
2034 if (!long_names) CharLowerW( buffer );
2036 if ((ret = LISTBOX_InsertString( descr, pos, buffer )) < 0)
2037 break;
2038 if (ret <= maxinsert) maxinsert++; else maxinsert = ret;
2039 } while (FindNextFileW( handle, &entry ));
2040 FindClose( handle );
2041 }
2042 }
2043 if (ret >= 0)
2044 {
2045 ret = maxinsert;
2046
2047 /* scan drives */
2048 if (attrib & DDL_DRIVES)
2049 {
2050 WCHAR buffer[] = L"[-a-]";
2051 WCHAR root[] = L"A:\\";
2052 int drive;
2053 for (drive = 0; drive < 26; drive++, buffer[2]++, root[0]++)
2054 {
2055 if (GetDriveTypeW(root) <= DRIVE_NO_ROOT_DIR) continue;
2056 if ((ret = LISTBOX_InsertString( descr, -1, buffer )) < 0)
2057 break;
2058 }
2059 }
2060 }
2061 return ret;
2062}
2063
2064
2065/***********************************************************************
2066 * LISTBOX_HandleVScroll
2067 */
2069{
2071
2072 if (descr->style & LBS_MULTICOLUMN) return 0;
2073 switch(scrollReq)
2074 {
2075 case SB_LINEUP:
2076 LISTBOX_SetTopItem( descr, descr->top_item - 1, TRUE );
2077 break;
2078 case SB_LINEDOWN:
2079 LISTBOX_SetTopItem( descr, descr->top_item + 1, TRUE );
2080 break;
2081 case SB_PAGEUP:
2082 LISTBOX_SetTopItem( descr, descr->top_item -
2084 break;
2085 case SB_PAGEDOWN:
2086 LISTBOX_SetTopItem( descr, descr->top_item +
2088 break;
2089 case SB_THUMBPOSITION:
2091 break;
2092 case SB_THUMBTRACK:
2093 info.cbSize = sizeof(info);
2094 info.fMask = SIF_TRACKPOS;
2095 GetScrollInfo( descr->self, SB_VERT, &info );
2096 LISTBOX_SetTopItem( descr, info.nTrackPos, TRUE );
2097 break;
2098 case SB_TOP:
2100 break;
2101 case SB_BOTTOM:
2102 LISTBOX_SetTopItem( descr, descr->nb_items, TRUE );
2103 break;
2104 }
2105 return 0;
2106}
2107
2108
2109/***********************************************************************
2110 * LISTBOX_HandleHScroll
2111 */
2113{
2115 INT page;
2116
2117 if (descr->style & LBS_MULTICOLUMN)
2118 {
2119 switch(scrollReq)
2120 {
2121 case SB_LINELEFT:
2122 LISTBOX_SetTopItem( descr, descr->top_item-descr->page_size,
2123 TRUE );
2124 break;
2125 case SB_LINERIGHT:
2126 LISTBOX_SetTopItem( descr, descr->top_item+descr->page_size,
2127 TRUE );
2128 break;
2129 case SB_PAGELEFT:
2130 page = descr->width / descr->column_width;
2131 if (page < 1) page = 1;
2133 descr->top_item - page * descr->page_size, TRUE );
2134 break;
2135 case SB_PAGERIGHT:
2136 page = descr->width / descr->column_width;
2137 if (page < 1) page = 1;
2139 descr->top_item + page * descr->page_size, TRUE );
2140 break;
2141 case SB_THUMBPOSITION:
2142 LISTBOX_SetTopItem( descr, pos*descr->page_size, TRUE );
2143 break;
2144 case SB_THUMBTRACK:
2145 info.cbSize = sizeof(info);
2146 info.fMask = SIF_TRACKPOS;
2147#ifdef __REACTOS__
2148 GetScrollInfo( descr->self, SB_HORZ, &info );
2149#else
2150 GetScrollInfo( descr->self, SB_VERT, &info );
2151#endif
2152 LISTBOX_SetTopItem( descr, info.nTrackPos*descr->page_size,
2153 TRUE );
2154 break;
2155 case SB_LEFT:
2157 break;
2158 case SB_RIGHT:
2159 LISTBOX_SetTopItem( descr, descr->nb_items, TRUE );
2160 break;
2161 }
2162 }
2163 else if (descr->horz_extent)
2164 {
2165 switch(scrollReq)
2166 {
2167 case SB_LINELEFT:
2168 LISTBOX_SetHorizontalPos( descr, descr->horz_pos - 1 );
2169 break;
2170 case SB_LINERIGHT:
2171 LISTBOX_SetHorizontalPos( descr, descr->horz_pos + 1 );
2172 break;
2173 case SB_PAGELEFT:
2175 descr->horz_pos - descr->width );
2176 break;
2177 case SB_PAGERIGHT:
2179 descr->horz_pos + descr->width );
2180 break;
2181 case SB_THUMBPOSITION:
2183 break;
2184 case SB_THUMBTRACK:
2185 info.cbSize = sizeof(info);
2186 info.fMask = SIF_TRACKPOS;
2187 GetScrollInfo( descr->self, SB_HORZ, &info );
2188 LISTBOX_SetHorizontalPos( descr, info.nTrackPos );
2189 break;
2190 case SB_LEFT:
2192 break;
2193 case SB_RIGHT:
2195 descr->horz_extent - descr->width );
2196 break;
2197 }
2198 }
2199 return 0;
2200}
2201
2203{
2204 INT pulScrollLines = 3;
2205
2206 SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0);
2207
2208 /* if scrolling changes direction, ignore left overs */
2209 if ((delta < 0 && descr->wheel_remain < 0) ||
2210 (delta > 0 && descr->wheel_remain > 0))
2211 descr->wheel_remain += delta;
2212 else
2213 descr->wheel_remain = delta;
2214
2215 if (descr->wheel_remain && pulScrollLines)
2216 {
2217 int cLineScroll;
2218 if (descr->style & LBS_MULTICOLUMN)
2219 {
2220 pulScrollLines = min(descr->width / descr->column_width, pulScrollLines);
2221 pulScrollLines = max(1, pulScrollLines);
2222 cLineScroll = pulScrollLines * descr->wheel_remain / WHEEL_DELTA;
2223 descr->wheel_remain -= WHEEL_DELTA * cLineScroll / pulScrollLines;
2224 cLineScroll *= descr->page_size;
2225 }
2226 else
2227 {
2228 pulScrollLines = min(descr->page_size, pulScrollLines);
2229 cLineScroll = pulScrollLines * descr->wheel_remain / WHEEL_DELTA;
2230 descr->wheel_remain -= WHEEL_DELTA * cLineScroll / pulScrollLines;
2231#ifdef __REACTOS__
2232 if (cLineScroll < 0)
2233 cLineScroll -= descr->page_size;
2234#endif
2235 }
2236 LISTBOX_SetTopItem( descr, descr->top_item - cLineScroll, TRUE );
2237 }
2238 return 0;
2239}
2240
2241/***********************************************************************
2242 * LISTBOX_HandleLButtonDown
2243 */
2245{
2247
2248 TRACE("[%p]: lbuttondown %d,%d item %d, focus item %d\n",
2249 descr->self, x, y, index, descr->focus_item);
2250
2251 if (!descr->caret_on && (descr->in_focus)) return 0;
2252
2253 if (!descr->in_focus)
2254 {
2255 if( !descr->lphc ) NtUserSetFocus( descr->self );
2256 else NtUserSetFocus( (descr->lphc->hWndEdit) ? descr->lphc->hWndEdit : descr->lphc->self );
2257 }
2258
2259 if (index == -1) return 0;
2260
2261 if (!descr->lphc)
2262 {
2263 if (descr->style & LBS_NOTIFY )
2265 MAKELPARAM( x, y ) );
2266 }
2267
2268 descr->captured = TRUE;
2269 NtUserSetCapture( descr->self );
2270
2271 if (descr->style & (LBS_EXTENDEDSEL | LBS_MULTIPLESEL))
2272 {
2273 /* we should perhaps make sure that all items are deselected
2274 FIXME: needed for !LBS_EXTENDEDSEL, too ?
2275 if (!(keys & (MK_SHIFT|MK_CONTROL)))
2276 LISTBOX_SetSelection( descr, -1, FALSE, FALSE);
2277 */
2278
2279 if (!(keys & MK_SHIFT)) descr->anchor_item = index;
2280 if (keys & MK_CONTROL)
2281 {
2285 (descr->style & LBS_NOTIFY) != 0);
2286 }
2287 else
2288 {
2290
2291 if (descr->style & LBS_EXTENDEDSEL)
2292 {
2295 (descr->style & LBS_NOTIFY) != 0 );
2296 }
2297 else
2298 {
2301 (descr->style & LBS_NOTIFY) != 0 );
2302 }
2303 }
2304 }
2305 else
2306 {
2307 descr->anchor_item = index;
2310 TRUE, (descr->style & LBS_NOTIFY) != 0 );
2311 NtUserNotifyWinEvent( EVENT_OBJECT_FOCUS, descr->self, OBJID_CLIENT, index + 1 );
2312 NtUserNotifyWinEvent( EVENT_OBJECT_SELECTION, descr->self, OBJID_CLIENT, index + 1 );
2313 }
2314
2315 if (!descr->lphc)
2316 { // See rev 40864 use Ptr for 64 bit.
2318 {
2319 POINT pt;
2320
2321 pt.x = x;
2322 pt.y = y;
2323
2324 if (DragDetect( descr->self, pt ))
2325 SendMessageW( descr->owner, WM_BEGINDRAG, 0, 0 );
2326 }
2327 }
2328 return 0;
2329}
2330
2331
2332/*************************************************************************
2333 * LISTBOX_HandleLButtonDownCombo [Internal]
2334 *
2335 * Process LButtonDown message for the ComboListBox
2336 *
2337 * PARAMS
2338 * pWnd [I] The windows internal structure
2339 * pDescr [I] The ListBox internal structure
2340 * keys [I] Key Flag (WM_LBUTTONDOWN doc for more info)
2341 * x [I] X Mouse Coordinate
2342 * y [I] Y Mouse Coordinate
2343 *
2344 * RETURNS
2345 * 0 since we are processing the WM_LBUTTONDOWN Message
2346 *
2347 * NOTES
2348 * This function is only to be used when a ListBox is a ComboListBox
2349 */
2350
2352{
2353 RECT clientRect, screenRect;
2354 POINT mousePos;
2355
2356 mousePos.x = x;
2357 mousePos.y = y;
2358
2359 GetClientRect(descr->self, &clientRect);
2360
2361 if(PtInRect(&clientRect, mousePos))
2362 {
2363 /* MousePos is in client, resume normal processing */
2364 if (msg == WM_LBUTTONDOWN)
2365 {
2366 descr->lphc->droppedIndex = descr->nb_items ? descr->selected_item : -1;
2368 }
2369 else if (descr->style & LBS_NOTIFY)
2371 }
2372 else
2373 {
2374 POINT screenMousePos;
2375 HWND hWndOldCapture;
2376
2377 /* Check the Non-Client Area */
2378 screenMousePos = mousePos;
2379 hWndOldCapture = GetCapture();
2381 GetWindowRect(descr->self, &screenRect);
2382 ClientToScreen(descr->self, &screenMousePos);
2383
2384 if(!PtInRect(&screenRect, screenMousePos))
2385 {
2386 LISTBOX_SetCaretIndex( descr, descr->lphc->droppedIndex, FALSE );
2387 LISTBOX_SetSelection( descr, descr->lphc->droppedIndex, FALSE, FALSE );
2389 }
2390 else
2391 {
2392 /* Check to see the NC is a scrollbar */
2393 INT nHitTestType=0;
2395 /* Check Vertical scroll bar */
2396 if (style & WS_VSCROLL)
2397 {
2398 clientRect.right += GetSystemMetrics(SM_CXVSCROLL);
2399 if (PtInRect( &clientRect, mousePos ))
2400 nHitTestType = HTVSCROLL;
2401 }
2402 /* Check horizontal scroll bar */
2403 if (style & WS_HSCROLL)
2404 {
2405 clientRect.bottom += GetSystemMetrics(SM_CYHSCROLL);
2406 if (PtInRect( &clientRect, mousePos ))
2407 nHitTestType = HTHSCROLL;
2408 }
2409 /* Windows sends this message when a scrollbar is clicked
2410 */
2411
2412 if(nHitTestType != 0)
2413 {
2414 SendMessageW(descr->self, WM_NCLBUTTONDOWN, nHitTestType,
2415 MAKELONG(screenMousePos.x, screenMousePos.y));
2416 }
2417 /* Resume the Capture after scrolling is complete
2418 */
2419 if(hWndOldCapture != 0)
2420 NtUserSetCapture(hWndOldCapture);
2421 }
2422 }
2423 return 0;
2424}
2425
2426/***********************************************************************
2427 * LISTBOX_HandleLButtonUp
2428 */
2430{
2434 if (descr->captured)
2435 {
2436 descr->captured = FALSE;
2437 if (GetCapture() == descr->self) NtUserReleaseCapture();
2438 if ((descr->style & LBS_NOTIFY) && descr->nb_items)
2440 }
2441 return 0;
2442}
2443
2444
2445/***********************************************************************
2446 * LISTBOX_HandleTimer
2447 *
2448 * Handle scrolling upon a timer event.
2449 * Return TRUE if scrolling should continue.
2450 */
2452{
2453 switch(dir)
2454 {
2455 case LB_TIMER_UP:
2456 if (descr->top_item) index = descr->top_item - 1;
2457 else index = 0;
2458 break;
2459 case LB_TIMER_LEFT:
2460 if (descr->top_item) index -= descr->page_size;
2461 break;
2462 case LB_TIMER_DOWN:
2464 if (index == descr->focus_item) index++;
2465 if (index >= descr->nb_items) index = descr->nb_items - 1;
2466 break;
2467 case LB_TIMER_RIGHT:
2468 if (index + descr->page_size < descr->nb_items)
2469 index += descr->page_size;
2470 break;
2471 case LB_TIMER_NONE:
2472 break;
2473 }
2474 if (index == descr->focus_item) return FALSE;
2476 return TRUE;
2477}
2478
2479
2480/***********************************************************************
2481 * LISTBOX_HandleSystemTimer
2482 *
2483 * WM_SYSTIMER handler.
2484 */
2486{
2487 if (!LISTBOX_HandleTimer( descr, descr->focus_item, LISTBOX_Timer ))
2488 {
2491 }
2492 return 0;
2493}
2494
2495
2496/***********************************************************************
2497 * LISTBOX_HandleMouseMove
2498 *
2499 * WM_MOUSEMOVE handler.
2500 */
2502 INT x, INT y )
2503{
2504 INT index;
2506
2507 if (!descr->captured) return;
2508
2509 if (descr->style & LBS_MULTICOLUMN)
2510 {
2511 if (y < 0) y = 0;
2512 else if (y >= descr->item_height * descr->page_size)
2513 y = descr->item_height * descr->page_size - 1;
2514
2515 if (x < 0)
2516 {
2518 x = 0;
2519 }
2520 else if (x >= descr->width)
2521 {
2523 x = descr->width - 1;
2524 }
2525 }
2526 else
2527 {
2528 if (y < 0) dir = LB_TIMER_UP; /* above */
2529 else if (y >= descr->height) dir = LB_TIMER_DOWN; /* below */
2530 }
2531
2533 if (index == -1) index = descr->focus_item;
2535
2536 /* Start/stop the system timer */
2537
2538 if (dir != LB_TIMER_NONE)
2540 else if (LISTBOX_Timer != LB_TIMER_NONE)
2543}
2544
2545
2546/***********************************************************************
2547 * LISTBOX_HandleKeyDown
2548 */
2550{
2551 INT caret = -1;
2552 BOOL bForceSelection = TRUE; /* select item pointed to by focus_item */
2553 if ((IS_MULTISELECT(descr)) || (descr->selected_item == descr->focus_item))
2554 bForceSelection = FALSE; /* only for single select list */
2555
2556 if (descr->style & LBS_WANTKEYBOARDINPUT)
2557 {
2558 caret = SendMessageW( descr->owner, WM_VKEYTOITEM,
2559 MAKEWPARAM(LOWORD(key), descr->focus_item),
2560 (LPARAM)descr->self );
2561 if (caret == -2) return 0;
2562 }
2563 if (caret == -1) switch(key)
2564 {
2565 case VK_LEFT:
2566 if (descr->style & LBS_MULTICOLUMN)
2567 {
2568 bForceSelection = FALSE;
2569 if (descr->focus_item >= descr->page_size)
2570 caret = descr->focus_item - descr->page_size;
2571 break;
2572 }
2573 /* fall through */
2574 case VK_UP:
2575 caret = descr->focus_item - 1;
2576 if (caret < 0) caret = 0;
2577 break;
2578 case VK_RIGHT:
2579 if (descr->style & LBS_MULTICOLUMN)
2580 {
2581 bForceSelection = FALSE;
2582 caret = min(descr->focus_item + descr->page_size, descr->nb_items - 1);
2583 break;
2584 }
2585 /* fall through */
2586 case VK_DOWN:
2587 caret = descr->focus_item + 1;
2588 if (caret >= descr->nb_items) caret = descr->nb_items - 1;
2589 break;
2590
2591 case VK_PRIOR:
2592 if (descr->style & LBS_MULTICOLUMN)
2593 {
2594 INT page = descr->width / descr->column_width;
2595 if (page < 1) page = 1;
2596 caret = descr->focus_item - (page * descr->page_size) + 1;
2597 }
2598 else caret = descr->focus_item-LISTBOX_GetCurrentPageSize(descr) + 1;
2599 if (caret < 0) caret = 0;
2600 break;
2601 case VK_NEXT:
2602 if (descr->style & LBS_MULTICOLUMN)
2603 {
2604 INT page = descr->width / descr->column_width;
2605 if (page < 1) page = 1;
2606 caret = descr->focus_item + (page * descr->page_size) - 1;
2607 }
2608 else caret = descr->focus_item + LISTBOX_GetCurrentPageSize(descr) - 1;
2609 if (caret >= descr->nb_items) caret = descr->nb_items - 1;
2610 break;
2611 case VK_HOME:
2612 caret = 0;
2613 break;
2614 case VK_END:
2615 caret = descr->nb_items - 1;
2616 break;
2617 case VK_SPACE:
2618 if (descr->style & LBS_EXTENDEDSEL) caret = descr->focus_item;
2619 else if (descr->style & LBS_MULTIPLESEL)
2620 {
2621 LISTBOX_SetSelection( descr, descr->focus_item,
2622 !is_item_selected(descr, descr->focus_item),
2623 (descr->style & LBS_NOTIFY) != 0 );
2624 }
2625 break;
2626 default:
2627 bForceSelection = FALSE;
2628 }
2629 if (bForceSelection) /* focused item is used instead of key */
2630 caret = descr->focus_item;
2631 if (caret >= 0)
2632 {
2633 if (((descr->style & LBS_EXTENDEDSEL) &&
2634 !(NtUserGetKeyState( VK_SHIFT ) & 0x8000)) ||
2636 descr->anchor_item = caret;
2637 LISTBOX_MoveCaret( descr, caret, TRUE );
2638
2639 if (descr->style & LBS_MULTIPLESEL)
2640 descr->selected_item = caret;
2641 else
2643 if (descr->style & LBS_NOTIFY)
2644 {
2645 if (descr->lphc && IsWindowVisible( descr->self ))
2646 {
2647 /* make sure that combo parent doesn't hide us */
2648 descr->lphc->wState |= CBF_NOROLLUP;
2649 }
2650 if (descr->nb_items) SEND_NOTIFICATION( descr, LBN_SELCHANGE );
2651 }
2652 }
2653 return 0;
2654}
2655
2656
2657/***********************************************************************
2658 * LISTBOX_HandleChar
2659 */
2661{
2662 INT caret = -1;
2663 WCHAR str[2];
2664
2665 str[0] = charW;
2666 str[1] = '\0';
2667
2668 if (descr->style & LBS_WANTKEYBOARDINPUT)
2669 {
2670 caret = SendMessageW( descr->owner, WM_CHARTOITEM,
2671 MAKEWPARAM(charW, descr->focus_item),
2672 (LPARAM)descr->self );
2673 if (caret == -2) return 0;
2674 }
2675 if (caret == -1 && !(descr->style & LBS_NODATA))
2676 caret = LISTBOX_FindString( descr, descr->focus_item, str, FALSE);
2677 if (caret != -1)
2678 {
2679 if ((!IS_MULTISELECT(descr)) && descr->selected_item == -1)
2681 LISTBOX_MoveCaret( descr, caret, TRUE );
2682 if ((descr->style & LBS_NOTIFY) && descr->nb_items)
2684 }
2685 return 0;
2686}
2687
2688/* ReactOS Retrieve the UI state for the control */
2690{
2691 LONG prev_flags;
2692
2693 prev_flags = descr->UIState;
2694 descr->UIState = DefWindowProcW(descr->self, WM_QUERYUISTATE, 0, 0);
2695 return prev_flags != descr->UIState;
2696}
2697
2698
2699/***********************************************************************
2700 * LISTBOX_Create
2701 */
2703{
2704 LB_DESCR *descr;
2706 RECT rect;
2707
2708 if (!(descr = HeapAlloc( GetProcessHeap(), 0, sizeof(*descr) )))
2709 return FALSE;
2710
2711 GetClientRect( hwnd, &rect );
2712 descr->self = hwnd;
2713 descr->owner = GetParent( descr->self );
2714 descr->style = GetWindowLongPtrW( descr->self, GWL_STYLE );
2715 descr->width = rect.right - rect.left;
2716 descr->height = rect.bottom - rect.top;
2717 descr->u.items = NULL;
2718 descr->items_size = 0;
2719 descr->nb_items = 0;
2720 descr->top_item = 0;
2721 descr->selected_item = -1;
2722 descr->focus_item = 0;
2723 descr->anchor_item = -1;
2724 descr->item_height = 1;
2725 descr->page_size = 1;
2726 descr->column_width = 150;
2727 descr->horz_extent = 0;
2728 descr->horz_pos = 0;
2729 descr->nb_tabs = 0;
2730 descr->tabs = NULL;
2731 descr->wheel_remain = 0;
2732 descr->caret_on = !lphc;
2733 if (descr->style & LBS_NOSEL) descr->caret_on = FALSE;
2734 descr->in_focus = FALSE;
2735 descr->captured = FALSE;
2736 descr->font = 0;
2737 descr->locale = GetUserDefaultLCID();
2738 descr->lphc = lphc;
2739
2740 if( lphc )
2741 {
2742 TRACE("[%p]: resetting owner %p -> %p\n", descr->self, descr->owner, lphc->self );
2743 descr->owner = lphc->self;
2744 }
2745
2746 set_control_state( descr->self, descr );
2747
2748 LISTBOX_update_uistate(descr); // ReactOS
2749
2750/* if (wnd->dwExStyle & WS_EX_NOPARENTNOTIFY) descr->style &= ~LBS_NOTIFY;
2751 */
2752 if (descr->style & LBS_EXTENDEDSEL) descr->style |= LBS_MULTIPLESEL;
2753 if (descr->style & LBS_MULTICOLUMN) descr->style &= ~LBS_OWNERDRAWVARIABLE;
2754 if (descr->style & LBS_OWNERDRAWVARIABLE) descr->style |= LBS_NOINTEGRALHEIGHT;
2755
2757 /* A no-data list box must also have the LBS_OWNERDRAWFIXED style, but must
2758 not have the LBS_SORT or LBS_HASSTRINGS style. */
2759 if ( descr->style & LBS_NODATA &&
2760 (!(descr->style & LBS_OWNERDRAWFIXED) || descr->style & (LBS_HASSTRINGS|LBS_SORT) ) )
2761 descr->style &= ~LBS_NODATA;
2764 descr->style &= ~LBS_NODATA;
2765 descr->item_height = LISTBOX_SetFont( descr, 0 );
2766
2767 if (descr->style & LBS_OWNERDRAWFIXED)
2768 {
2769 descr->style &= ~LBS_OWNERDRAWVARIABLE;
2770
2771 if( descr->lphc && (descr->lphc->dwStyle & CBS_DROPDOWN))
2772 {
2773 /* WinWord gets VERY unhappy if we send WM_MEASUREITEM from here */
2774 descr->item_height = lphc->fixedOwnerDrawHeight;
2775 }
2776 else
2777 {
2778 UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID );
2779 mis.CtlType = ODT_LISTBOX;
2780 mis.CtlID = id;
2781 mis.itemID = -1;
2782 mis.itemWidth = 0;
2783 mis.itemData = 0;
2784 mis.itemHeight = descr->item_height;
2785 SendMessageW( descr->owner, WM_MEASUREITEM, id, (LPARAM)&mis );
2786 descr->item_height = mis.itemHeight ? mis.itemHeight : 1;
2787 }
2788 }
2789
2790 TRACE("owner: %p, style: %08x, width: %d, height: %d\n", descr->owner, descr->style, descr->width, descr->height);
2791 return TRUE;
2792}
2793
2794
2795/***********************************************************************
2796 * LISTBOX_Destroy
2797 */
2799{
2801 set_control_state( descr->self, NULL );
2802 HeapFree( GetProcessHeap(), 0, descr );
2803 return TRUE;
2804}
2805
2806
2807/***********************************************************************
2808 * ListBoxWndProc_common
2809 */
2811 WPARAM wParam, LPARAM lParam, BOOL unicode )
2812{
2814 HEADCOMBO *lphc = NULL;
2815 LRESULT ret;
2817
2818 if (!descr)
2819 {
2820 if (!IsWindow(hwnd)) return 0;
2821
2822 if (msg == WM_CREATE)
2823 {
2825 if (lpcs->style & LBS_COMBOBOX) lphc = lpcs->lpCreateParams;
2826 if (!LISTBOX_Create( hwnd, lphc )) return -1;
2827 TRACE("creating hwnd %p descr %p\n", hwnd, get_control_state( hwnd ) );
2828 return 0;
2829 }
2830 /* Ignore all other messages before we get a WM_CREATE */
2831 return unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) :
2833 }
2834 if (descr->style & LBS_COMBOBOX) lphc = descr->lphc;
2835
2836 TRACE("[%p]: msg %s wp %08Ix lp %08Ix\n",
2837 descr->self, SPY_GetMsgName(msg, descr->self), wParam, lParam );
2838
2839 switch(msg)
2840 {
2841 case LB_RESETCONTENT:
2845 return 0;
2846
2847 case LB_ADDSTRING:
2848#ifdef __REACTOS__
2849 case LB_ADDSTRING_LOWER:
2850 case LB_ADDSTRING_UPPER:
2851#endif
2852 {
2853 INT ret;
2854 LPWSTR textW;
2855 if(unicode || !HAS_STRINGS(descr))
2856 textW = (LPWSTR)lParam;
2857 else
2858 {
2860 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
2861 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
2862 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
2863 else
2864 return LB_ERRSPACE;
2865 }
2866#ifdef __REACTOS__
2867 /* in the unicode the version, the string is really overwritten
2868 during the converting case */
2869 if (msg == LB_ADDSTRING_LOWER)
2870 strlwrW(textW);
2871 else if (msg == LB_ADDSTRING_UPPER)
2872 struprW(textW);
2873#endif
2876 if (!unicode && HAS_STRINGS(descr))
2878 return ret;
2879 }
2880
2881 case LB_INSERTSTRING:
2882#ifdef __REACTOS__
2885#endif
2886 {
2887 INT ret;
2888 LPWSTR textW;
2889 if(unicode || !HAS_STRINGS(descr))
2890 textW = (LPWSTR)lParam;
2891 else
2892 {
2894 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
2895 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
2896 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
2897 else
2898 return LB_ERRSPACE;
2899 }
2900#ifdef __REACTOS__
2901 /* in the unicode the version, the string is really overwritten
2902 during the converting case */
2904 strlwrW(textW);
2905 else if (msg == LB_INSERTSTRING_UPPER)
2906 struprW(textW);
2907#endif
2909 if(!unicode && HAS_STRINGS(descr))
2911 return ret;
2912 }
2913
2914 case LB_ADDFILE:
2915 {
2916 INT ret;
2917 LPWSTR textW;
2918 if(unicode || !HAS_STRINGS(descr))
2919 textW = (LPWSTR)lParam;
2920 else
2921 {
2923 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
2924 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
2925 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
2926 else
2927 return LB_ERRSPACE;
2928 }
2931 if(!unicode && HAS_STRINGS(descr))
2933 return ret;
2934 }
2935
2936 case LB_DELETESTRING:
2938 return descr->nb_items;
2939 else
2940 {
2942 return LB_ERR;
2943 }
2944
2945 case LB_GETITEMDATA:
2946 if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
2947 {
2949 return LB_ERR;
2950 }
2951 return get_item_data(descr, wParam);
2952
2953 case LB_SETITEMDATA:
2954 if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
2955 {
2957 return LB_ERR;
2958 }
2960 /* undocumented: returns TRUE, not LB_OKAY (0) */
2961 return TRUE;
2962
2963 case LB_GETCOUNT:
2964 return descr->nb_items;
2965
2966 case LB_GETTEXT:
2967 return LISTBOX_GetText( descr, wParam, (LPWSTR)lParam, unicode );
2968
2969 case LB_GETTEXTLEN:
2970 if ((INT)wParam >= descr->nb_items || (INT)wParam < 0)
2971 {
2973 return LB_ERR;
2974 }
2975 if (!HAS_STRINGS(descr)) return sizeof(ULONG_PTR);
2976 if (unicode) return lstrlenW(get_item_string(descr, wParam));
2979
2980 case LB_GETCURSEL:
2981 if (descr->nb_items == 0)
2982 return LB_ERR;
2983 if (!IS_MULTISELECT(descr))
2984 return descr->selected_item;
2985 if (descr->selected_item != -1)
2986 return descr->selected_item;
2987 return descr->focus_item;
2988 /* otherwise, if the user tries to move the selection with the */
2989 /* arrow keys, we will give the application something to choke on */
2990 case LB_GETTOPINDEX:
2991 return descr->top_item;
2992
2993 case LB_GETITEMHEIGHT:
2995
2996 case LB_SETITEMHEIGHT:
2998
2999 case LB_ITEMFROMPOINT:
3000 {
3001 POINT pt;
3002 RECT rect;
3003 int index;
3004 BOOL hit = TRUE;
3005
3006 /* The hiword of the return value is not a client area
3007 hittest as suggested by MSDN, but rather a hittest on
3008 the returned listbox item. */
3009
3010 if(descr->nb_items == 0)
3011 return 0x1ffff; /* win9x returns 0x10000, we copy winnt */
3012
3013 pt.x = (short)LOWORD(lParam);
3014 pt.y = (short)HIWORD(lParam);
3015
3016 SetRect(&rect, 0, 0, descr->width, descr->height);
3017
3018 if(!PtInRect(&rect, pt))
3019 {
3020 pt.x = min(pt.x, rect.right - 1);
3021 pt.x = max(pt.x, 0);
3022 pt.y = min(pt.y, rect.bottom - 1);
3023 pt.y = max(pt.y, 0);
3024 hit = FALSE;
3025 }
3026
3028
3029 if(index == -1)
3030 {
3031 index = descr->nb_items - 1;
3032 hit = FALSE;
3033 }
3034 return MAKELONG(index, hit ? 0 : 1);
3035 }
3036
3037 case LB_SETCARETINDEX:
3038 if ((!IS_MULTISELECT(descr)) && (descr->selected_item != -1)) return LB_ERR;
3040 return LB_ERR;
3041 else if (ISWIN31)
3042 return wParam;
3043 else
3044 return LB_OKAY;
3045
3046 case LB_GETCARETINDEX:
3047 return descr->focus_item;
3048
3049 case LB_SETTOPINDEX:
3050 return LISTBOX_SetTopItem( descr, wParam, TRUE );
3051
3052 case LB_SETCOLUMNWIDTH:
3054
3055 case LB_GETITEMRECT:
3057
3058 case LB_FINDSTRING:
3059 {
3060 INT ret;
3061 LPWSTR textW;
3062 if(unicode || !HAS_STRINGS(descr))
3063 textW = (LPWSTR)lParam;
3064 else
3065 {
3067 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
3068 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
3069 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
3070 }
3072 if(!unicode && HAS_STRINGS(descr))
3074 return ret;
3075 }
3076
3077 case LB_FINDSTRINGEXACT:
3078 {
3079 INT ret;
3080 LPWSTR textW;
3081 if(unicode || !HAS_STRINGS(descr))
3082 textW = (LPWSTR)lParam;
3083 else
3084 {
3086 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
3087 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
3088 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
3089 }
3091 if(!unicode && HAS_STRINGS(descr))
3093 return ret;
3094 }
3095
3096 case LB_SELECTSTRING:
3097 {
3098 INT index;
3099 LPWSTR textW;
3100
3101 if(HAS_STRINGS(descr))
3102 TRACE("LB_SELECTSTRING: %s\n", unicode ? debugstr_w((LPWSTR)lParam) :
3104 if(unicode || !HAS_STRINGS(descr))
3105 textW = (LPWSTR)lParam;
3106 else
3107 {
3109 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
3110 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
3111 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
3112 }
3114 if(!unicode && HAS_STRINGS(descr))
3116 if (index != LB_ERR)
3117 {
3120 }
3121 return index;
3122 }
3123
3124 case LB_GETSEL:
3125 if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
3126 return LB_ERR;
3127 return is_item_selected(descr, wParam);
3128
3129 case LB_SETSEL:
3131 if (ret != LB_ERR && wParam)
3132 {
3133 descr->anchor_item = lParam;
3134 if (lParam != -1)
3136 }
3137 return ret;
3138
3139 case LB_SETCURSEL:
3140 if (IS_MULTISELECT(descr)) return LB_ERR;
3143 if (ret != LB_ERR)
3144 {
3145 ret = descr->selected_item;
3146 NtUserNotifyWinEvent( EVENT_OBJECT_FOCUS, descr->self, OBJID_CLIENT, ret + 1 );
3147 NtUserNotifyWinEvent( EVENT_OBJECT_SELECTION, descr->self, OBJID_CLIENT, ret + 1 );
3148 }
3149 return ret;
3150
3151 case LB_GETSELCOUNT:
3152 return LISTBOX_GetSelCount( descr );
3153
3154 case LB_GETSELITEMS:
3156
3157 case LB_SELITEMRANGE:
3158 if (LOWORD(lParam) <= HIWORD(lParam))
3160 HIWORD(lParam), wParam );
3161 else
3163 LOWORD(lParam), wParam );
3164
3165 case LB_SELITEMRANGEEX:
3166 if ((INT)lParam >= (INT)wParam)
3168 else
3170
3172 return descr->horz_extent;
3173
3176
3177 case LB_GETANCHORINDEX:
3178 return descr->anchor_item;
3179
3180 case LB_SETANCHORINDEX:
3181 if (((INT)wParam < -1) || ((INT)wParam >= descr->nb_items))
3182 {
3184 return LB_ERR;
3185 }
3186 descr->anchor_item = (INT)wParam;
3187 return LB_OKAY;
3188
3189 case LB_DIR:
3190 {
3191 INT ret;
3192 LPWSTR textW;
3193 if(unicode)
3194 textW = (LPWSTR)lParam;
3195 else
3196 {
3198 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
3199 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
3200 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
3201 }
3203 if(!unicode)
3205 return ret;
3206 }
3207
3208 case LB_GETLOCALE:
3209 return descr->locale;
3210
3211 case LB_SETLOCALE:
3212 {
3213 LCID ret;
3215 return LB_ERR;
3216 ret = descr->locale;
3217 descr->locale = (LCID)wParam;
3218 return ret;
3219 }
3220
3221 case LB_INITSTORAGE:
3222 return LISTBOX_InitStorage( descr, wParam );
3223
3224 case LB_SETCOUNT:
3225 return LISTBOX_SetCount( descr, (INT)wParam );
3226
3227 case LB_SETTABSTOPS:
3229
3230 case LB_CARETON:
3231 if (descr->caret_on)
3232 return LB_OKAY;
3233 descr->caret_on = TRUE;
3234 if ((descr->focus_item != -1) && (descr->in_focus))
3235 LISTBOX_RepaintItem( descr, descr->focus_item, ODA_FOCUS );
3236 return LB_OKAY;
3237
3238 case LB_CARETOFF:
3239 if (!descr->caret_on)
3240 return LB_OKAY;
3241 descr->caret_on = FALSE;
3242 if ((descr->focus_item != -1) && (descr->in_focus))
3243 LISTBOX_RepaintItem( descr, descr->focus_item, ODA_FOCUS );
3244 return LB_OKAY;
3245
3246 case LB_GETLISTBOXINFO:
3247 return descr->page_size;
3248
3249 case WM_DESTROY:
3250 return LISTBOX_Destroy( descr );
3251
3252 case WM_ENABLE:
3254 return 0;
3255
3256 case WM_SETREDRAW:
3258 return 0;
3259
3260 case WM_GETDLGCODE:
3262
3263 case WM_PRINTCLIENT:
3264 case WM_PAINT:
3265 {
3266 PAINTSTRUCT ps;
3267 HDC hdc = ( wParam ) ? ((HDC)wParam) : NtUserBeginPaint( descr->self, &ps );
3268 ret = LISTBOX_Paint( descr, hdc );
3269 if (!wParam) NtUserEndPaint( descr->self, &ps );
3270 }
3271 return ret;
3272 case WM_SIZE:
3274 return 0;
3275 case WM_GETFONT:
3276 return (LRESULT)descr->font;
3277 case WM_SETFONT:
3278 LISTBOX_SetFont( descr, (HFONT)wParam );
3279 if (lParam) NtUserInvalidateRect( descr->self, 0, TRUE );
3280 return 0;
3281 case WM_SETFOCUS:
3282 descr->in_focus = TRUE;
3283 descr->caret_on = TRUE;
3284 if (descr->focus_item != -1)
3287 NtUserNotifyWinEvent( EVENT_OBJECT_FOCUS, descr->self, OBJID_CLIENT, descr->focus_item + 1 );
3288 return 0;
3289 case WM_KILLFOCUS:
3290 LISTBOX_HandleLButtonUp( descr ); /* Release capture if we have it */
3291 descr->in_focus = FALSE;
3292 descr->wheel_remain = 0;
3293 if ((descr->focus_item != -1) && descr->caret_on)
3294 LISTBOX_RepaintItem( descr, descr->focus_item, ODA_FOCUS );
3296 return 0;
3297 case WM_HSCROLL:
3299 case WM_VSCROLL:
3301 case WM_MOUSEWHEEL:
3302 if (wParam & (MK_SHIFT | MK_CONTROL))
3303 return DefWindowProcW( descr->self, msg, wParam, lParam );
3305 case WM_LBUTTONDOWN:
3306 if (lphc)
3309 (INT16)HIWORD(lParam) );
3312 (INT16)HIWORD(lParam) );
3313 case WM_LBUTTONDBLCLK:
3314 if (lphc)
3317 (INT16)HIWORD(lParam) );
3318 if ((descr->style & LBS_NOTIFY) && descr->nb_items)
3320 return 0;
3321 case WM_MOUSEMOVE:
3322 if ( lphc && ((lphc->dwStyle & CBS_DROPDOWNLIST) != CBS_SIMPLE) )
3323 {
3324 BOOL captured = descr->captured;
3325 POINT mousePos;
3326 RECT clientRect;
3327
3328 mousePos.x = (INT16)LOWORD(lParam);
3329 mousePos.y = (INT16)HIWORD(lParam);
3330
3331 /*
3332 * If we are in a dropdown combobox, we simulate that
3333 * the mouse is captured to show the tracking of the item.
3334 */
3335 if (GetClientRect(descr->self, &clientRect) && PtInRect( &clientRect, mousePos ))
3336 descr->captured = TRUE;
3337
3338 LISTBOX_HandleMouseMove( descr, mousePos.x, mousePos.y);
3339
3340 descr->captured = captured;
3341 }
3342 else if (GetCapture() == descr->self)
3343 {
3345 (INT16)HIWORD(lParam) );
3346 }
3347 return 0;
3348 case WM_LBUTTONUP:
3349 if (lphc)
3350 {
3351 POINT mousePos;
3352 RECT clientRect;
3353
3354 /*
3355 * If the mouse button "up" is not in the listbox,
3356 * we make sure there is no selection by re-selecting the
3357 * item that was selected when the listbox was made visible.
3358 */
3359 mousePos.x = (INT16)LOWORD(lParam);
3360 mousePos.y = (INT16)HIWORD(lParam);
3361
3362 GetClientRect(descr->self, &clientRect);
3363
3364 /*
3365 * When the user clicks outside the combobox and the focus
3366 * is lost, the owning combobox will send a fake buttonup with
3367 * 0xFFFFFFF as the mouse location, we must also revert the
3368 * selection to the original selection.
3369 */
3370 if ( (lParam == (LPARAM)-1) || (!PtInRect( &clientRect, mousePos )) )
3372 }
3374 case WM_KEYDOWN:
3375 if( lphc && (lphc->dwStyle & CBS_DROPDOWNLIST) != CBS_SIMPLE )
3376 {
3377 /* for some reason Windows makes it possible to
3378 * show/hide ComboLBox by sending it WM_KEYDOWNs */
3379
3380 if( (!(lphc->wState & CBF_EUI) && wParam == VK_F4) ||
3381 ( (lphc->wState & CBF_EUI) && !(lphc->wState & CBF_DROPPED)
3382 && (wParam == VK_DOWN || wParam == VK_UP)) )
3383 {
3384 COMBO_FlipListbox( lphc, FALSE, FALSE );
3385 return 0;
3386 }
3387 }
3389 case WM_CHAR:
3390 {
3391 WCHAR charW;
3392 if(unicode)
3393 charW = (WCHAR)wParam;
3394 else
3395 {
3396 CHAR charA = (CHAR)wParam;
3397 MultiByteToWideChar(CP_ACP, 0, &charA, 1, &charW, 1);
3398 }
3399 return LISTBOX_HandleChar( descr, charW );
3400 }
3401 case WM_SYSTIMER:
3403 case WM_ERASEBKGND:
3404 if ((IS_OWNERDRAW(descr)) && !(descr->style & LBS_DISPLAYCHANGED))
3405 {
3406 RECT rect;
3407#ifdef __REACTOS__
3408 HBRUSH hbrush = GetControlColor( descr->owner, descr->self, (HDC)wParam, WM_CTLCOLORLISTBOX);
3409#else
3410 HBRUSH hbrush = (HBRUSH)SendMessageW( descr->owner, WM_CTLCOLORLISTBOX,
3411 wParam, (LPARAM)descr->self );
3412#endif
3413 TRACE("hbrush = %p\n", hbrush);
3414 if(!hbrush)
3416 if(hbrush)
3417 {
3418 GetClientRect(descr->self, &rect);
3420 }
3421 }
3422 return 1;
3423 case WM_DROPFILES:
3424 if( lphc ) return 0;
3425 return unicode ? SendMessageW( descr->owner, msg, wParam, lParam ) :
3426 SendMessageA( descr->owner, msg, wParam, lParam );
3427
3428 case WM_NCDESTROY:
3429 if( lphc && (lphc->dwStyle & CBS_DROPDOWNLIST) != CBS_SIMPLE )
3430 lphc->hWndLBox = 0;
3431#ifdef __REACTOS__
3433#endif
3434 break;
3435
3436 case WM_NCACTIVATE:
3437 if (lphc) return 0;
3438 break;
3439#ifdef __REACTOS__
3440 case WM_UPDATEUISTATE:
3441 if (unicode)
3443 else
3445
3447 {
3448 /* redraw text */
3449 if (descr->focus_item != -1)
3450 LISTBOX_DrawFocusRect( descr, descr->in_focus );
3451 }
3452 break;
3453#endif
3454 default:
3455 if ((msg >= WM_USER) && (msg < 0xc000))
3456 WARN("[%p]: unknown msg %04x wp %08Ix lp %08Ix\n",
3457 hwnd, msg, wParam, lParam );
3458 }
3459
3460 return unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) :
3462}
3463
3464#ifdef __REACTOS__
3465/***********************************************************************
3466 * ListBoxWndProcA
3467 */
3469{
3471}
3472
3473/***********************************************************************
3474 * ListBoxWndProcW
3475 */
3477{
3479}
3480#endif
static HRGN hrgn
static HBRUSH hbrush
short INT16
Definition: actypes.h:130
static int state
Definition: maze.c:121
unsigned int dir
Definition: maze.c:112
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
#define CHAR(Char)
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
Definition: _locale.h:75
RECT rect
Definition: combotst.c:67
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define WM_SYSTIMER
Definition: comctl32.h:125
#define LB_INSERTSTRING_LOWER
Definition: controls.h:87
#define CBF_SELCHANGE
Definition: controls.h:55
LRESULT WINAPI ListBoxWndProcW(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
#define CBF_DROPPED
Definition: controls.h:45
#define LB_INSERTSTRING_UPPER
Definition: controls.h:86
#define LB_ADDSTRING_LOWER
Definition: controls.h:89
#define CBF_EUI
Definition: controls.h:59
LRESULT WINAPI ListBoxWndProcA(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
#define CBF_NOROLLUP
Definition: controls.h:47
#define LB_ADDSTRING_UPPER
Definition: controls.h:88
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
static char selected[MAX_PATH+1]
Definition: dirdlg.c:7
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRGN set_control_clipping(HDC hdc, const RECT *rect)
Definition: button.c:242
BOOL COMBO_FlipListbox(LPHEADCOMBO lphc, BOOL ok, BOOL bRedrawButton)
Definition: combo.c:1086
static LRESULT LISTBOX_RemoveItem(LB_DESCR *descr, INT index)
Definition: listbox.c:1796
#define SEND_NOTIFICATION(descr, code)
Definition: listbox.c:111
static LRESULT LISTBOX_InsertString(LB_DESCR *descr, INT index, LPCWSTR str)
Definition: listbox.c:1733
static void LISTBOX_DrawFocusRect(LB_DESCR *descr, BOOL on)
Definition: listbox.c:797
static void LISTBOX_SetHorizontalPos(LB_DESCR *descr, INT pos)
Definition: listbox.c:1364
static LRESULT LISTBOX_HandleKeyDown(LB_DESCR *descr, DWORD key)
Definition: listbox.c:2461
static LRESULT LISTBOX_SetCaretIndex(LB_DESCR *descr, INT index, BOOL fully_visible)
Definition: listbox.c:1510
static BOOL LISTBOX_SetTabStops(LB_DESCR *descr, INT count, LPINT tabs)
Definition: listbox.c:837
static LRESULT LISTBOX_HandleLButtonUp(LB_DESCR *descr)
Definition: listbox.c:2341
#define ATTRIBS
static void remove_item_data(LB_DESCR *descr, UINT index)
Definition: listbox.c:237
static void LISTBOX_DeleteItem(LB_DESCR *descr, INT index)
Definition: listbox.c:1768
static void LISTBOX_InvalidateItems(LB_DESCR *descr, INT index)
Definition: listbox.c:1275
static LRESULT LISTBOX_GetSelCount(const LB_DESCR *descr)
Definition: listbox.c:1075
static void LISTBOX_SetRedraw(LB_DESCR *descr, BOOL on)
Definition: listbox.c:737
static void LISTBOX_InvalidateItemRect(LB_DESCR *descr, INT index)
Definition: listbox.c:1299
static LRESULT LISTBOX_GetText(LB_DESCR *descr, INT index, LPWSTR buffer, BOOL unicode)
Definition: listbox.c:869
#define ISWIN31
Definition: listbox.c:115
static LRESULT LISTBOX_InitStorage(LB_DESCR *descr, INT nb_items)
Definition: listbox.c:824
static void LISTBOX_MakeItemVisible(LB_DESCR *descr, INT index, BOOL fully)
Definition: listbox.c:1471
static INT LISTBOX_FindFileStrPos(LB_DESCR *descr, LPCWSTR str)
Definition: listbox.c:971
static LRESULT LISTBOX_SetSelection(LB_DESCR *descr, INT index, BOOL on, BOOL send_notify)
Definition: listbox.c:1579
static LRESULT LISTBOX_HandleLButtonDownCombo(LB_DESCR *descr, UINT msg, DWORD keys, INT x, INT y)
Definition: listbox.c:2263
static LRESULT LISTBOX_HandleVScroll(LB_DESCR *descr, WORD scrollReq, WORD pos)
Definition: listbox.c:1990
#define IS_MULTISELECT(descr)
Definition: listbox.c:107
static void LISTBOX_ResetContent(LB_DESCR *descr)
Definition: listbox.c:1848
static LRESULT LISTBOX_HandleTimer(LB_DESCR *descr, INT index, TIMER_DIRECTION dir)
Definition: listbox.c:2363
#define HAS_STRINGS(descr)
Definition: listbox.c:103
static LRESULT LISTBOX_HandleMouseWheel(LB_DESCR *descr, SHORT delta)
Definition: listbox.c:2120
TIMER_DIRECTION
Definition: listbox.c:119
@ LB_TIMER_NONE
Definition: listbox.c:120
@ LB_TIMER_UP
Definition: listbox.c:121
@ LB_TIMER_RIGHT
Definition: listbox.c:124
@ LB_TIMER_DOWN
Definition: listbox.c:123
@ LB_TIMER_LEFT
Definition: listbox.c:122
static UINT get_item_height(const LB_DESCR *descr, UINT index)
Definition: listbox.c:195
static LRESULT LISTBOX_SetHorizontalExtent(LB_DESCR *descr, INT extent)
Definition: listbox.c:1392
static void set_item_height(LB_DESCR *descr, UINT index, UINT height)
Definition: listbox.c:200
static void set_item_selected_state(LB_DESCR *descr, UINT index, BOOL state)
Definition: listbox.c:215
static LRESULT LISTBOX_InsertItem(LB_DESCR *descr, INT index, LPWSTR str, ULONG_PTR data)
Definition: listbox.c:1669
static void LISTBOX_MoveCaret(LB_DESCR *descr, INT index, BOOL fully_visible)
Definition: listbox.c:1622
static LRESULT LISTBOX_GetSelItems(const LB_DESCR *descr, INT max, LPINT array)
Definition: listbox.c:1091
static BOOL is_item_selected(const LB_DESCR *descr, UINT index)
Definition: listbox.c:205
static LRESULT LISTBOX_Paint(LB_DESCR *descr, HDC hdc)
Definition: listbox.c:1105
static void LISTBOX_UpdateScroll(LB_DESCR *descr)
Definition: listbox.c:303
static TIMER_DIRECTION LISTBOX_Timer
Definition: listbox.c:127
static LRESULT LISTBOX_SetTopItem(LB_DESCR *descr, INT index, BOOL scroll)
Definition: listbox.c:386
static INT LISTBOX_SetFont(LB_DESCR *descr, HFONT font)
Definition: listbox.c:1440
static LRESULT LISTBOX_SetColumnWidth(LB_DESCR *descr, INT column_width)
Definition: listbox.c:1418
static LRESULT LISTBOX_HandleHScroll(LB_DESCR *descr, WORD scrollReq, WORD pos)
Definition: listbox.c:2034
static ULONG_PTR get_item_data(const LB_DESCR *descr, UINT index)
Definition: listbox.c:175
static LRESULT LISTBOX_SelectItemRange(LB_DESCR *descr, INT first, INT last, BOOL on)
Definition: listbox.c:1539
static void set_item_data(LB_DESCR *descr, UINT index, ULONG_PTR data)
Definition: listbox.c:180
static void LISTBOX_RepaintItem(LB_DESCR *descr, INT index, UINT action)
Definition: listbox.c:764
static LRESULT LISTBOX_GetItemRect(const LB_DESCR *descr, INT index, RECT *rect)
Definition: listbox.c:500
static void set_item_string(const LB_DESCR *descr, UINT index, WCHAR *string)
Definition: listbox.c:190
static INT LISTBOX_FindString(LB_DESCR *descr, INT start, LPCWSTR str, BOOL exact)
Definition: listbox.c:1015
static void insert_item_data(LB_DESCR *descr, UINT index)
Definition: listbox.c:226
static BOOL LISTBOX_Destroy(LB_DESCR *descr)
Definition: listbox.c:2692
#define LB_ARRAY_GRANULARITY
Definition: listbox.c:43
static LRESULT LISTBOX_HandleSystemTimer(LB_DESCR *descr)
Definition: listbox.c:2397
#define LB_TIMER_ID
Definition: listbox.c:49
static BOOL resize_storage(LB_DESCR *descr, UINT items_size)
Definition: listbox.c:146
static LRESULT LISTBOX_Directory(LB_DESCR *descr, UINT attrib, LPCWSTR filespec, BOOL long_names)
Definition: listbox.c:1907
static void LISTBOX_HandleMouseMove(LB_DESCR *descr, INT x, INT y)
Definition: listbox.c:2413
static LRESULT LISTBOX_GetItemHeight(const LB_DESCR *descr, INT index)
Definition: listbox.c:1310
#define LB_SCROLL_TIMEOUT
Definition: listbox.c:46
static INT LISTBOX_FindStringPos(LB_DESCR *descr, LPCWSTR str, BOOL exact)
Definition: listbox.c:927
static void LISTBOX_PaintItem(LB_DESCR *descr, HDC hdc, const RECT *rect, INT index, UINT action, BOOL ignoreFocus)
Definition: listbox.c:605
#define IS_OWNERDRAW(descr)
Definition: listbox.c:100
static INT LISTBOX_GetItemFromPoint(const LB_DESCR *descr, INT x, INT y)
Definition: listbox.c:558
static INT LISTBOX_lstrcmpiW(LCID lcid, LPCWSTR str1, LPCWSTR str2)
Definition: listbox.c:909
#define LBS_DISPLAYCHANGED
Definition: listbox.c:52
static size_t get_sizeof_item(const LB_DESCR *descr)
Definition: listbox.c:141
static LRESULT LISTBOX_HandleChar(LB_DESCR *descr, WCHAR charW)
Definition: listbox.c:2572
static void LISTBOX_UpdatePage(LB_DESCR *descr)
Definition: listbox.c:435
static LRESULT LISTBOX_SetItemHeight(LB_DESCR *descr, INT index, INT height, BOOL repaint)
Definition: listbox.c:1328
static void LISTBOX_UpdateSize(LB_DESCR *descr)
Definition: listbox.c:455
static WCHAR * get_item_string(const LB_DESCR *descr, UINT index)
Definition: listbox.c:185
static INT LISTBOX_GetCurrentPageSize(const LB_DESCR *descr)
Definition: listbox.c:253
static LRESULT LISTBOX_SetCount(LB_DESCR *descr, UINT count)
Definition: listbox.c:1868
static INT LISTBOX_GetMaxTopIndex(const LB_DESCR *descr)
Definition: listbox.c:271
static BOOL LISTBOX_Create(HWND hwnd, LPHEADCOMBO lphc)
Definition: listbox.c:2604
static LRESULT LISTBOX_HandleLButtonDown(LB_DESCR *descr, DWORD keys, INT x, INT y)
Definition: listbox.c:2158
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrlenW
Definition: compat.h:750
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: locale.c:3946
BOOL WINAPI IsValidLocale(LCID lcid, DWORD flags)
Definition: locale.c:2925
LCID WINAPI GetUserDefaultLCID(void)
Definition: locale.c:1216
LCID lcid
Definition: locale.c:5660
const UINT * keys
Definition: locale.c:418
LPWSTR WINAPI CharLowerW(WCHAR *str)
Definition: string.c:1136
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define pt(x, y)
Definition: drawing.c:79
return ret
Definition: mutex.c:147
action
Definition: namespace.c:714
#define L(x)
Definition: resources.c:13
#define ULONG_PTR
Definition: config.h:101
size_t const new_size
Definition: expand.cpp:66
#define abs(i)
Definition: fconv.c:206
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
pKey DeleteObject()
GLuint start
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint buffer
Definition: glext.h:5915
GLuint res
Definition: glext.h:9613
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
const GLint * first
Definition: glext.h:5794
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
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 i
Definition: glfuncs.h:248
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 * u
Definition: glfuncs.h:240
unsigned int UINT
Definition: sysinfo.c:13
VOID NTAPI NtUserNotifyWinEvent(DWORD Event, HWND hWnd, LONG idObject, LONG idChild)
Definition: event.c:254
BOOL NTAPI NtUserSetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags)
Definition: winpos.c:3573
DWORD NTAPI NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *rect, const RECT *clipRect, HRGN hrgnUpdate, LPRECT rcUpdate, UINT flags)
Definition: scrollex.c:571
#define FNID_DESTROY
Definition: ntuser.h:905
HWND NTAPI NtUserSetFocus(HWND hWnd)
Definition: focus.c:1717
DWORD NTAPI NtUserSetScrollInfo(HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
Definition: scrollbar.c:1344
BOOL NTAPI NtUserInvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase)
Definition: painting.c:2541
HDC NTAPI NtUserGetDCEx(HWND hWnd, HANDLE hRegion, ULONG Flags)
Definition: windc.c:974
BOOL NTAPI NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT *lPs)
Definition: painting.c:1660
HDC NTAPI NtUserBeginPaint(HWND hWnd, PAINTSTRUCT *lPs)
Definition: painting.c:1614
HWND NTAPI NtUserSetCapture(HWND Wnd)
Definition: focus.c:1699
SHORT NTAPI NtUserGetKeyState(INT VirtKey)
Definition: msgqueue.c:2573
DWORD NTAPI NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow)
Definition: scrollbar.c:1383
BOOL NTAPI NtUserSetWindowFNID(HWND hWnd, WORD fnID)
Definition: window.c:4335
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
GLint dy
Definition: linetemp.h:97
if(dx< 0)
Definition: linetemp.h:194
GLint dx
Definition: linetemp.h:97
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
int * LPINT
Definition: minwindef.h:151
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
char string[160]
Definition: util.h:11
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
HDC hdc
Definition: main.c:9
static const char textA[]
Definition: registrar.c:40
static HDC
Definition: imagelist.c:88
static void send_notify(HWND pager, UINT unicode, UINT ansi, LPARAM lParam, BOOL code_change)
Definition: pager.c:918
static const WCHAR textW[]
Definition: itemdlg.c:1621
static DWORD page_size
Definition: loader.c:54
static const LARGE_INTEGER *static const HANDLE const LARGE_INTEGER *static PSLIST_ENTRY PSLIST_ENTRY last
Definition: sync.c:64
#define WM_LBTRACKPOINT
Definition: msg.c:61
#define min(a, b)
Definition: monoChain.cc:55
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
Definition: mk_font.cpp:20
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define MAXBYTE
#define OBJ_BRUSH
Definition: objidl.idl:1015
static TCHAR * items[]
Definition: page1.c:45
#define LOWORD(l)
Definition: pedump.c:82
#define LBS_DISABLENOSCROLL
Definition: pedump.c:690
#define LBS_SORT
Definition: pedump.c:679
short WCHAR
Definition: pedump.c:58
#define LBS_OWNERDRAWFIXED
Definition: pedump.c:682
#define LBS_HASSTRINGS
Definition: pedump.c:684
#define LBS_MULTICOLUMN
Definition: pedump.c:687
#define WS_VSCROLL
Definition: pedump.c:627
#define LBS_OWNERDRAWVARIABLE
Definition: pedump.c:683
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
#define LBS_MULTIPLESEL
Definition: pedump.c:681
#define LBS_USETABSTOPS
Definition: pedump.c:685
#define WS_HSCROLL
Definition: pedump.c:628
#define LBS_NOINTEGRALHEIGHT
Definition: pedump.c:686
#define LBS_NOTIFY
Definition: pedump.c:678
#define LBS_EXTENDEDSEL
Definition: pedump.c:689
char CHAR
Definition: pedump.c:57
#define LBS_WANTKEYBOARDINPUT
Definition: pedump.c:688
#define LBS_NOREDRAW
Definition: pedump.c:680
#define INT
Definition: polytest.cpp:20
#define WM_PAINT
Definition: winuser.h:1648
#define ODS_DISABLED
Definition: winuser.h:2583
#define LB_ERR
Definition: winuser.h:2468
#define LB_ADDFILE
Definition: winuser.h:2059
#define WM_ERASEBKGND
Definition: winuser.h:1653
DWORD WINAPI GetSysColor(_In_ int)
#define LBN_ERRSPACE
Definition: winuser.h:2108
#define MAKEWPARAM(l, h)
Definition: winuser.h:4117
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define MK_SHIFT
Definition: winuser.h:2405
#define LB_GETCOUNT
Definition: winuser.h:2067
#define ODS_SELECTED
Definition: winuser.h:2581
#define LB_FINDSTRINGEXACT
Definition: winuser.h:2064
#define SWP_NOACTIVATE
Definition: winuser.h:1253
#define LB_GETITEMDATA
Definition: winuser.h:2070
#define SB_THUMBTRACK
Definition: winuser.h:573
#define GetWindowLongPtrW
Definition: winuser.h:4983
#define WM_ENABLE
Definition: winuser.h:1643
#define SB_LINEUP
Definition: winuser.h:564
#define WM_HSCROLL
Definition: winuser.h:1771
#define MAKELPARAM(l, h)
Definition: winuser.h:4116
#define LB_SETHORIZONTALEXTENT
Definition: winuser.h:2100
#define COLOR_GRAYTEXT
Definition: winuser.h:943
#define COLOR_WINDOW
Definition: winuser.h:929
#define DCX_CACHE
Definition: winuser.h:2150
#define WM_CHARTOITEM
Definition: winuser.h:1677
#define ODA_DRAWENTIRE
Definition: winuser.h:2578
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define LBN_SELCANCEL
Definition: winuser.h:2110
#define CBS_DROPDOWNLIST
Definition: winuser.h:284
#define LB_SETCOUNT
Definition: winuser.h:2098
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define LB_OKAY
Definition: winuser.h:2467
#define LB_GETTEXT
Definition: winuser.h:2085
#define LB_SETTOPINDEX
Definition: winuser.h:2106
#define WM_VSCROLL
Definition: winuser.h:1772
#define SW_SCROLLCHILDREN
Definition: winuser.h:2614
#define LBN_DBLCLK
Definition: winuser.h:2107
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define SIF_RANGE
Definition: winuser.h:1246
#define WM_CREATE
Definition: winuser.h:1636
#define DLGC_WANTCHARS
Definition: winuser.h:2660
#define SB_PAGERIGHT
Definition: winuser.h:571
#define SM_CXVSCROLL
Definition: winuser.h:972
#define VK_SPACE
Definition: winuser.h:2255
#define LB_DIR
Definition: winuser.h:2062
#define WM_SIZE
Definition: winuser.h:1639
#define COLOR_HIGHLIGHT
Definition: winuser.h:937
HBRUSH WINAPI GetSysColorBrush(_In_ int)
#define SB_VERT
Definition: winuser.h:553
#define SB_LEFT
Definition: winuser.h:575
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define WM_DROPFILES
Definition: winuser.h:1853
#define SB_BOTTOM
Definition: winuser.h:577
#define LB_GETSELCOUNT
Definition: winuser.h:2083
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1806
#define SWP_NOMOVE
Definition: winuser.h:1255
#define SW_INVALIDATE
Definition: winuser.h:2615
#define LB_GETITEMRECT
Definition: winuser.h:2072
#define ODA_FOCUS
Definition: winuser.h:2580
#define HTVSCROLL
Definition: winuser.h:2518
#define HTHSCROLL
Definition: winuser.h:2517
#define IDC_ARROW
Definition: winuser.h:695
#define LBN_SETFOCUS
Definition: winuser.h:2112
#define LB_GETTOPINDEX
Definition: winuser.h:2087
#define LB_GETANCHORINDEX
Definition: winuser.h:2065
#define LB_ERRSPACE
Definition: winuser.h:2469
#define VK_UP
Definition: winuser.h:2261
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define DDL_DRIVES
Definition: winuser.h:425
#define WM_SETFOCUS
Definition: winuser.h:1641
#define SIF_PAGE
Definition: winuser.h:1244
#define WM_MOUSEMOVE
Definition: winuser.h:1803
#define LB_GETLOCALE
Definition: winuser.h:2081
HWND WINAPI GetCapture(void)
Definition: message.c:2881
#define LB_SETLOCALE
Definition: winuser.h:2103
#define SB_LINERIGHT
Definition: winuser.h:567
#define CS_DBLCLKS
Definition: winuser.h:659
#define WM_LBUTTONDOWN
Definition: winuser.h:1804
#define LB_GETSEL
Definition: winuser.h:2082
#define LB_ADDSTRING
Definition: winuser.h:2060
#define LB_SETCOLUMNWIDTH
Definition: winuser.h:2097
#define SIF_TRACKPOS
Definition: winuser.h:1248
#define WM_GETFONT
Definition: winuser.h:1679
#define WM_DELETEITEM
Definition: winuser.h:1675
BOOL WINAPI ClientToScreen(_In_ HWND, _Inout_ LPPOINT)
#define LB_SELITEMRANGEEX
Definition: winuser.h:2094
#define SM_CYHSCROLL
Definition: winuser.h:973
#define WM_DRAWITEM
Definition: winuser.h:1673
#define VK_NEXT
Definition: winuser.h:2257
#define LB_SELITEMRANGE
Definition: winuser.h:2093
#define WM_NCCREATE
Definition: winuser.h:1711
#define LB_SETANCHORINDEX
Definition: winuser.h:2095
#define LB_SETITEMHEIGHT
Definition: winuser.h:2102
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
#define DDL_EXCLUSIVE
Definition: winuser.h:426
#define CBS_SIMPLE
Definition: winuser.h:291
#define LB_SELECTSTRING
Definition: winuser.h:2092
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define WM_NCACTIVATE
Definition: winuser.h:1716
#define LBS_COMBOBOX
Definition: winuser.h:324
#define LB_RESETCONTENT
Definition: winuser.h:2091
#define LB_DELETESTRING
Definition: winuser.h:2061
#define SB_LINELEFT
Definition: winuser.h:566
#define LB_FINDSTRING
Definition: winuser.h:2063
#define MK_CONTROL
Definition: winuser.h:2406
#define DDL_DIRECTORY
Definition: winuser.h:422
#define LB_GETITEMHEIGHT
Definition: winuser.h:2071
#define WM_SETFONT
Definition: winuser.h:1678
#define VK_END
Definition: winuser.h:2258
#define VK_HOME
Definition: winuser.h:2259
#define LB_GETHORIZONTALEXTENT
Definition: winuser.h:2069
#define DLGC_WANTARROWS
Definition: winuser.h:2652
#define SIF_DISABLENOSCROLL
Definition: winuser.h:1247
#define LB_INSERTSTRING
Definition: winuser.h:2089
#define LBS_NODATA
Definition: winuser.h:313
#define SB_PAGEDOWN
Definition: winuser.h:569
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:938
BOOL WINAPI DragDetect(_In_ HWND, _In_ POINT)
#define LB_ITEMFROMPOINT
Definition: winuser.h:2090
#define SB_LINEDOWN
Definition: winuser.h:565
#define CBS_DROPDOWN
Definition: winuser.h:283
#define WM_MEASUREITEM
Definition: winuser.h:1674
#define VK_F4
Definition: winuser.h:2294
#define WM_LBUTTONUP
Definition: winuser.h:1805
BOOL WINAPI SystemParametersInfoW(_In_ UINT uiAction, _In_ UINT uiParam, _Inout_opt_ PVOID pvParam, _In_ UINT fWinIni)
#define WM_CHAR
Definition: winuser.h:1745
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
BOOL WINAPI IsWindowEnabled(_In_ HWND)
#define LB_GETTEXTLEN
Definition: winuser.h:2086
HWND WINAPI GetParent(_In_ HWND)
#define LB_SETITEMDATA
Definition: winuser.h:2101
#define VK_LEFT
Definition: winuser.h:2260
#define LBN_SELCHANGE
Definition: winuser.h:2111
#define WM_NCDESTROY
Definition: winuser.h:1712
#define VK_RIGHT
Definition: winuser.h:2262
#define ODA_SELECT
Definition: winuser.h:2579
#define SB_TOP
Definition: winuser.h:578
#define CS_SAVEBITS
Definition: winuser.h:665
#define SIF_POS
Definition: winuser.h:1245
#define VK_DOWN
Definition: winuser.h:2263
#define LB_GETCARETINDEX
Definition: winuser.h:2066
#define GWLP_ID
Definition: winuser.h:871
#define SW_ERASE
Definition: winuser.h:2616
#define WM_USER
Definition: winuser.h:1923
#define LBN_KILLFOCUS
Definition: winuser.h:2109
#define WM_CTLCOLORLISTBOX
Definition: winuser.h:1796
#define LB_SETTABSTOPS
Definition: winuser.h:2105
#define VK_SHIFT
Definition: winuser.h:2238
#define LB_SETSEL
Definition: winuser.h:2104
#define VK_PRIOR
Definition: winuser.h:2256
int WINAPI SetScrollInfo(_In_ HWND, _In_ int, _In_ LPCSCROLLINFO, _In_ BOOL)
#define WM_DESTROY
Definition: winuser.h:1637
#define LBS_NOSEL
Definition: winuser.h:316
#define LB_SETCURSEL
Definition: winuser.h:2099
#define WM_KEYDOWN
Definition: winuser.h:1743
BOOL WINAPI DrawFocusRect(_In_ HDC, _In_ LPCRECT)
#define SB_RIGHT
Definition: winuser.h:576
#define WM_COMPAREITEM
Definition: winuser.h:1683
#define SWP_NOZORDER
Definition: winuser.h:1258
#define LB_GETCURSEL
Definition: winuser.h:2068
#define GWL_STYLE
Definition: winuser.h:863
#define LB_GETSELITEMS
Definition: winuser.h:2084
BOOL WINAPI GetScrollInfo(_In_ HWND, _In_ int, _Inout_ LPSCROLLINFO)
#define LB_INITSTORAGE
Definition: winuser.h:2088
BOOL WINAPI IsWindowVisible(_In_ HWND)
#define ODT_LISTBOX
Definition: winuser.h:2574
#define WM_KILLFOCUS
Definition: winuser.h:1642
#define ODS_FOCUS
Definition: winuser.h:2585
int WINAPI GetSystemMetrics(_In_ int)
#define SB_PAGEUP
Definition: winuser.h:568
#define WM_NCLBUTTONDOWN
Definition: winuser.h:1720
#define LB_SETCARETINDEX
Definition: winuser.h:2096
#define WM_GETDLGCODE
Definition: winuser.h:1717
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SB_HORZ
Definition: winuser.h:552
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define WM_VKEYTOITEM
Definition: winuser.h:1676
#define SB_PAGELEFT
Definition: winuser.h:570
#define GWL_EXSTYLE
Definition: winuser.h:862
#define WM_SETREDRAW
Definition: winuser.h:1644
#define SB_THUMBPOSITION
Definition: winuser.h:572
LONG WINAPI TabbedTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_reads_(chCount) LPCWSTR lpString, _In_ int chCount, _In_ int nTabPositions, _In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions, _In_ int nTabOrigin)
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
PFNCLIENT pfnClientA
Definition: regcontrol.c:15
PFNCLIENT pfnClientW
Definition: regcontrol.c:16
const struct builtin_class_descr LISTBOX_builtin_class
const struct builtin_class_descr COMBOLBOX_builtin_class
#define WM_PRINTCLIENT
Definition: richedit.h:70
const WCHAR * str
DWORD LCID
Definition: nls.h:13
XML_HIDDEN void xmlParserErrors const char const xmlChar const xmlChar * str2
Definition: parser.h:35
XML_HIDDEN void xmlParserErrors const char const xmlChar * str1
Definition: parser.h:35
const char * descr
Definition: boot.c:45
#define memset(x, y, z)
Definition: compat.h:39
#define UINT
Definition: utils.c:29
#define TRACE(s)
Definition: solgame.cpp:4
INT fixedOwnerDrawHeight
Definition: comctl32.h:161
UINT wState
Definition: comctl32.h:155
HWND hWndLBox
Definition: comctl32.h:154
INT droppedIndex
Definition: comctl32.h:160
HWND self
Definition: comctl32.h:150
UINT dwStyle
Definition: comctl32.h:152
long y
Definition: dcommon.idl:24
long x
Definition: dcommon.idl:24
Definition: dcommon.idl:28
long bottom
Definition: dcommon.idl:29
long right
Definition: dcommon.idl:29
long left
Definition: dcommon.idl:29
long top
Definition: dcommon.idl:29
WNDPROC pfnComboListBoxProc
Definition: ntuser.h:809
WNDPROC pfnListBoxWndProc
Definition: ntuser.h:812
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
Definition: undname.c:54
Definition: copy.c:22
Definition: module.h:576
Definition: style.c:91
ULONG_PTR itemData1
Definition: winuser.h:3102
ULONG_PTR itemData2
Definition: winuser.h:3104
LPVOID lpCreateParams
Definition: winuser.h:3063
ULONG_PTR itemData
Definition: winuser.h:3152
ULONG_PTR itemData
Definition: winuser.h:3201
ULONG_PTR itemData
Definition: winuser.h:3754
#define max(a, b)
Definition: svc.c:63
#define WHEEL_DELTA
Definition: treelist.c:99
#define WM_MOUSEWHEEL
Definition: treelist.c:96
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
#define WS_EX_DRAGDETECT
Definition: undocuser.h:23
#define LB_CARETON
Definition: undocuser.h:53
#define LB_CARETOFF
Definition: undocuser.h:54
#define WM_BEGINDRAG
Definition: undocuser.h:58
const char * SPY_GetMsgName(UINT msg, HWND hWnd)
Definition: spy.c:2232
#define NtUserSetPrivateData(HWND, OFFSET, SIZE, VALUE)
Definition: user_x.h:132
#define NTUSER_WNDPROC_LISTBOX
Definition: user_x.h:138
#define NtUserSetSystemTimer(HWND, ID, TIMEOUT)
Definition: user_x.h:123
#define NtUserReleaseDC(HWND, HDC)
Definition: user_x.h:120
#define MAKE_FNID(index)
Definition: user_x.h:143
#define NtUserGetPrivateData(HWND, OFFSET, SIZE)
Definition: user_x.h:131
#define NtUserKillSystemTimer(HWND, ID)
Definition: user_x.h:122
#define NtUserReleaseCapture()
Definition: user_x.h:121
HBRUSH FASTCALL GetControlColor(PWND pwndParent, PWND pwnd, HDC hdc, UINT CtlMsg)
Definition: misc.c:153
static LB_DESCR * get_control_state(HWND hwnd)
Definition: listbox.c:162
static BOOL LISTBOX_update_uistate(LB_DESCR *descr)
Definition: listbox.c:2689
LRESULT WINAPI ListBoxWndProc_common(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode)
Definition: listbox.c:2810
static LB_DESCR * set_control_state(HWND hwnd, LB_DESCR *state)
Definition: listbox.c:167
#define OBJID_CLIENT
Definition: winable.h:19
#define DRIVE_NO_ROOT_DIR
Definition: winbase.h:282
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
DWORD COLORREF
Definition: windef.h:100
#define WINAPI
Definition: msvc.h:6
#define struprW(s)
Definition: unicode.h:57
#define strlenW(s)
Definition: unicode.h:28
#define strlwrW(s)
Definition: unicode.h:56
#define ERROR_INVALID_INDEX
Definition: winerror.h:1239
#define ERROR_SETCOUNT_ON_BAD_LB
Definition: winerror.h:1259
#define ERROR_LB_WITHOUT_TABSTOPS
Definition: winerror.h:1260
#define ERROR_NO_MORE_FILES
Definition: winerror.h:243
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:999
BOOL WINAPI SetWindowOrgEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
Definition: coord.c:532
#define GetTextExtentPoint32
Definition: wingdi.h:4918
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:428
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
#define ETO_CLIPPED
Definition: wingdi.h:648
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 ETO_OPAQUE
Definition: wingdi.h:647
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:917
int WINAPI SelectClipRgn(_In_ HDC, _In_opt_ HRGN)
BOOL WINAPI GetTextExtentPointA(_In_ HDC hdc, _In_reads_(c) LPCSTR lpString, _In_ int c, _Out_ LPSIZE lpsz)
#define NORM_IGNORECASE
Definition: winnls.h:191
#define LCID_INSTALLED
Definition: winnls.h:224
#define CSTR_EQUAL
Definition: winnls.h:508
#define CSTR_LESS_THAN
Definition: winnls.h:507
#define CSTR_GREATER_THAN
Definition: winnls.h:509
unsigned char BYTE
Definition: xxhash.c:193