ReactOS 0.4.16-dev-117-g38f21f9
listbox.c File Reference
#include <user32.h>
Include dependency graph for listbox.c:

Go to the source code of this file.

Classes

struct  LB_ITEMDATA
 
struct  LB_DESCR
 

Macros

#define LB_ARRAY_GRANULARITY   16
 
#define LB_SCROLL_TIMEOUT   50
 
#define LB_TIMER_ID   2
 
#define LBS_DISPLAYCHANGED   0x80000000
 
#define IS_OWNERDRAW(descr)    ((descr)->style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE))
 
#define HAS_STRINGS(descr)    (!IS_OWNERDRAW(descr) || ((descr)->style & LBS_HASSTRINGS))
 
#define IS_MULTISELECT(descr)
 
#define SEND_NOTIFICATION(descr, code)
 
#define ISWIN31   (LOWORD(GetVersion()) == 0x0a03)
 
#define CHECK_DRIVE(item)
 
#define ATTRIBS
 

Enumerations

enum  TIMER_DIRECTION {
  LB_TIMER_NONE , LB_TIMER_UP , LB_TIMER_LEFT , LB_TIMER_DOWN ,
  LB_TIMER_RIGHT , LB_TIMER_NONE , LB_TIMER_UP , LB_TIMER_LEFT ,
  LB_TIMER_DOWN , LB_TIMER_RIGHT
}
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (listbox)
 
static LRESULT LISTBOX_GetItemRect (const LB_DESCR *descr, INT index, RECT *rect)
 
static INT LISTBOX_GetCurrentPageSize (const LB_DESCR *descr)
 
static INT LISTBOX_GetMaxTopIndex (const LB_DESCR *descr)
 
static void LISTBOX_UpdateScroll (LB_DESCR *descr)
 
static LRESULT LISTBOX_SetTopItem (LB_DESCR *descr, INT index, BOOL scroll)
 
static void LISTBOX_UpdatePage (LB_DESCR *descr)
 
static void LISTBOX_UpdateSize (LB_DESCR *descr)
 
static INT LISTBOX_GetItemFromPoint (const LB_DESCR *descr, INT x, INT y)
 
static void LISTBOX_PaintItem (LB_DESCR *descr, HDC hdc, const RECT *rect, INT index, UINT action, BOOL ignoreFocus)
 
static void LISTBOX_SetRedraw (LB_DESCR *descr, BOOL on)
 
static void LISTBOX_RepaintItem (LB_DESCR *descr, INT index, UINT action)
 
static void LISTBOX_DrawFocusRect (LB_DESCR *descr, BOOL on)
 
static LRESULT LISTBOX_InitStorage (LB_DESCR *descr, INT nb_items)
 
static BOOL LISTBOX_SetTabStops (LB_DESCR *descr, INT count, LPINT tabs)
 
static LRESULT LISTBOX_GetText (LB_DESCR *descr, INT index, LPWSTR buffer, BOOL unicode)
 
static INT LISTBOX_lstrcmpiW (LCID lcid, LPCWSTR str1, LPCWSTR str2)
 
static INT LISTBOX_FindStringPos (LB_DESCR *descr, LPCWSTR str, BOOL exact)
 
static INT LISTBOX_FindFileStrPos (LB_DESCR *descr, LPCWSTR str)
 
static INT LISTBOX_FindString (LB_DESCR *descr, INT start, LPCWSTR str, BOOL exact)
 
static LRESULT LISTBOX_GetSelCount (const LB_DESCR *descr)
 
static LRESULT LISTBOX_GetSelItems (const LB_DESCR *descr, INT max, LPINT array)
 
static LRESULT LISTBOX_Paint (LB_DESCR *descr, HDC hdc)
 
static void LISTBOX_InvalidateItems (LB_DESCR *descr, INT index)
 
static void LISTBOX_InvalidateItemRect (LB_DESCR *descr, INT index)
 
static LRESULT LISTBOX_GetItemHeight (const LB_DESCR *descr, INT index)
 
static LRESULT LISTBOX_SetItemHeight (LB_DESCR *descr, INT index, INT height, BOOL repaint)
 
static void LISTBOX_SetHorizontalPos (LB_DESCR *descr, INT pos)
 
static LRESULT LISTBOX_SetHorizontalExtent (LB_DESCR *descr, INT extent)
 
static LRESULT LISTBOX_SetColumnWidth (LB_DESCR *descr, INT width)
 
static INT LISTBOX_SetFont (LB_DESCR *descr, HFONT font)
 
static void LISTBOX_MakeItemVisible (LB_DESCR *descr, INT index, BOOL fully)
 
static LRESULT LISTBOX_SetCaretIndex (LB_DESCR *descr, INT index, BOOL fully_visible)
 
static LRESULT LISTBOX_SelectItemRange (LB_DESCR *descr, INT first, INT last, BOOL on)
 
static LRESULT LISTBOX_SetSelection (LB_DESCR *descr, INT index, BOOL on, BOOL send_notify)
 
static void LISTBOX_MoveCaret (LB_DESCR *descr, INT index, BOOL fully_visible)
 
static LRESULT LISTBOX_InsertItem (LB_DESCR *descr, INT index, LPWSTR str, ULONG_PTR data)
 
static LRESULT LISTBOX_InsertString (LB_DESCR *descr, INT index, LPCWSTR str)
 
static void LISTBOX_DeleteItem (LB_DESCR *descr, INT index)
 
static LRESULT LISTBOX_RemoveItem (LB_DESCR *descr, INT index)
 
static void LISTBOX_ResetContent (LB_DESCR *descr)
 
static LRESULT LISTBOX_SetCount (LB_DESCR *descr, INT count)
 
static LRESULT LISTBOX_Directory (LB_DESCR *descr, UINT attrib, LPCWSTR filespec, BOOL long_names)
 
static LRESULT LISTBOX_HandleVScroll (LB_DESCR *descr, WORD scrollReq, WORD pos)
 
static LRESULT LISTBOX_HandleHScroll (LB_DESCR *descr, WORD scrollReq, WORD pos)
 
static LRESULT LISTBOX_HandleMouseWheel (LB_DESCR *descr, SHORT delta)
 
static LRESULT LISTBOX_HandleLButtonDown (LB_DESCR *descr, DWORD keys, INT x, INT y)
 
static LRESULT LISTBOX_HandleLButtonDownCombo (LB_DESCR *descr, UINT msg, DWORD keys, INT x, INT y)
 
static LRESULT LISTBOX_HandleLButtonUp (LB_DESCR *descr)
 
static LRESULT LISTBOX_HandleTimer (LB_DESCR *descr, INT index, TIMER_DIRECTION dir)
 
static LRESULT LISTBOX_HandleSystemTimer (LB_DESCR *descr)
 
static void LISTBOX_HandleMouseMove (LB_DESCR *descr, INT x, INT y)
 
static LRESULT LISTBOX_HandleKeyDown (LB_DESCR *descr, DWORD key)
 
static LRESULT LISTBOX_HandleChar (LB_DESCR *descr, WCHAR charW)
 
static BOOL LISTBOX_update_uistate (LB_DESCR *descr)
 
static BOOL LISTBOX_Create (HWND hwnd, LPHEADCOMBO lphc)
 
static BOOL LISTBOX_Destroy (LB_DESCR *descr)
 
LRESULT WINAPI ListBoxWndProc_common (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode)
 
LRESULT WINAPI ListBoxWndProcA (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
LRESULT WINAPI ListBoxWndProcW (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 

Variables

static TIMER_DIRECTION LISTBOX_Timer = LB_TIMER_NONE
 
static const WCHAR listboxW [] = {'L','i','s','t','B','o','x',0}
 
const struct builtin_class_descr LISTBOX_builtin_class
 
static const WCHAR combolboxW [] = {'C','o','m','b','o','L','B','o','x',0}
 
const struct builtin_class_descr COMBOLBOX_builtin_class
 

Macro Definition Documentation

◆ ATTRIBS

#define ATTRIBS
Value:
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706

◆ CHECK_DRIVE

#define CHECK_DRIVE (   item)
Value:
if ((item)->str[0] == '[') \
{ \
if (!strncmpiW( str, (item)->str+1, len )) return i; \
if (((item)->str[1] == '-') && !strncmpiW(str, (item)->str+2, len)) \
return i; \
}
GLenum GLsizei len
Definition: glext.h:6722
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
static ATOM item
Definition: dde.c:856
#define strncmpiW(s1, s2, n)
Definition: unicode.h:46
const WCHAR * str

◆ HAS_STRINGS

#define HAS_STRINGS (   descr)     (!IS_OWNERDRAW(descr) || ((descr)->style & LBS_HASSTRINGS))

Definition at line 94 of file listbox.c.

◆ IS_MULTISELECT

#define IS_MULTISELECT (   descr)
Value:
Arabic default style
Definition: afstyles.h:94
#define LBS_MULTIPLESEL
Definition: pedump.c:681
#define LBS_EXTENDEDSEL
Definition: pedump.c:689
const char * descr
Definition: boot.c:45
#define LBS_NOSEL
Definition: winuser.h:316

Definition at line 98 of file listbox.c.

◆ IS_OWNERDRAW

#define IS_OWNERDRAW (   descr)     ((descr)->style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE))

Definition at line 91 of file listbox.c.

◆ ISWIN31

#define ISWIN31   (LOWORD(GetVersion()) == 0x0a03)

Definition at line 106 of file listbox.c.

◆ LB_ARRAY_GRANULARITY

#define LB_ARRAY_GRANULARITY   16

Definition at line 38 of file listbox.c.

◆ LB_SCROLL_TIMEOUT

#define LB_SCROLL_TIMEOUT   50

Definition at line 41 of file listbox.c.

◆ LB_TIMER_ID

#define LB_TIMER_ID   2

Definition at line 44 of file listbox.c.

◆ LBS_DISPLAYCHANGED

#define LBS_DISPLAYCHANGED   0x80000000

Definition at line 47 of file listbox.c.

◆ SEND_NOTIFICATION

#define SEND_NOTIFICATION (   descr,
  code 
)
Value:
(SendMessageW( (descr)->owner, WM_COMMAND, \
Definition: inflate.c:139
LONG_PTR LPARAM
Definition: windef.h:208
#define MAKEWPARAM(l, h)
Definition: winuser.h:4012
#define GetWindowLongPtrW
Definition: winuser.h:4832
#define WM_COMMAND
Definition: winuser.h:1743
#define GWLP_ID
Definition: winuser.h:863
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)

Definition at line 102 of file listbox.c.

Enumeration Type Documentation

◆ TIMER_DIRECTION

Enumerator
LB_TIMER_NONE 
LB_TIMER_UP 
LB_TIMER_LEFT 
LB_TIMER_DOWN 
LB_TIMER_RIGHT 
LB_TIMER_NONE 
LB_TIMER_UP 
LB_TIMER_LEFT 
LB_TIMER_DOWN 
LB_TIMER_RIGHT 

Definition at line 109 of file listbox.c.

110{
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

Function Documentation

◆ LISTBOX_Create()

static BOOL LISTBOX_Create ( HWND  hwnd,
LPHEADCOMBO  lphc 
)
static

Definition at line 2511 of file listbox.c.

2512{
2513 LB_DESCR *descr;
2515 RECT rect;
2516
2517 if (!(descr = HeapAlloc( GetProcessHeap(), 0, sizeof(*descr) )))
2518 return FALSE;
2519
2520 GetClientRect( hwnd, &rect );
2521 descr->self = hwnd;
2522 descr->owner = GetParent( descr->self );
2523 descr->style = GetWindowLongPtrW( descr->self, GWL_STYLE );
2524 descr->width = rect.right - rect.left;
2525 descr->height = rect.bottom - rect.top;
2526 descr->items = NULL;
2527 descr->nb_items = 0;
2528 descr->top_item = 0;
2529 descr->selected_item = -1;
2530 descr->focus_item = 0;
2531 descr->anchor_item = -1;
2532 descr->item_height = 1;
2533 descr->page_size = 1;
2534 descr->column_width = 150;
2535 descr->horz_extent = 0;
2536 descr->horz_pos = 0;
2537 descr->nb_tabs = 0;
2538 descr->tabs = NULL;
2539 descr->wheel_remain = 0;
2540 descr->caret_on = !lphc;
2541 if (descr->style & LBS_NOSEL) descr->caret_on = FALSE;
2542 descr->in_focus = FALSE;
2543 descr->captured = FALSE;
2544 descr->font = 0;
2545 descr->locale = GetUserDefaultLCID();
2546 descr->lphc = lphc;
2547
2548 if( lphc )
2549 {
2550 TRACE("[%p]: resetting owner %p -> %p\n", descr->self, descr->owner, lphc->self );
2551 descr->owner = lphc->self;
2552 }
2553
2554 SetWindowLongPtrW( descr->self, 0, (LONG_PTR)descr );
2555
2556 LISTBOX_update_uistate(descr); // ReactOS
2557
2558/* if (wnd->dwExStyle & WS_EX_NOPARENTNOTIFY) descr->style &= ~LBS_NOTIFY;
2559 */
2560 if (descr->style & LBS_EXTENDEDSEL) descr->style |= LBS_MULTIPLESEL;
2561 if (descr->style & LBS_MULTICOLUMN) descr->style &= ~LBS_OWNERDRAWVARIABLE;
2562 if (descr->style & LBS_OWNERDRAWVARIABLE) descr->style |= LBS_NOINTEGRALHEIGHT;
2563
2565 /* A no-data list box must also have the LBS_OWNERDRAWFIXED style, but must
2566 not have the LBS_SORT or LBS_HASSTRINGS style. */
2567 if ( descr->style & LBS_NODATA &&
2568 (!(descr->style & LBS_OWNERDRAWFIXED) || descr->style & (LBS_HASSTRINGS|LBS_SORT) ) )
2569 descr->style &= ~LBS_NODATA;
2571 descr->item_height = LISTBOX_SetFont( descr, 0 );
2572
2573 if (descr->style & LBS_OWNERDRAWFIXED)
2574 {
2575 if( descr->lphc && (descr->lphc->dwStyle & CBS_DROPDOWN))
2576 {
2577 /* WinWord gets VERY unhappy if we send WM_MEASUREITEM from here */
2578 descr->item_height = lphc->fixedOwnerDrawHeight;
2579 }
2580 else
2581 {
2582 UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID );
2583 mis.CtlType = ODT_LISTBOX;
2584 mis.CtlID = id;
2585 mis.itemID = -1;
2586 mis.itemWidth = 0;
2587 mis.itemData = 0;
2588 mis.itemHeight = descr->item_height;
2589 SendMessageW( descr->owner, WM_MEASUREITEM, id, (LPARAM)&mis );
2590 descr->item_height = mis.itemHeight ? mis.itemHeight : 1;
2591 }
2592 }
2593
2594 TRACE("owner: %p, style: %08x, width: %d, height: %d\n", descr->owner, descr->style, descr->width, descr->height);
2595 return TRUE;
2596}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static INT LISTBOX_SetFont(LB_DESCR *descr, HFONT font)
Definition: listbox.c:1403
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
LCID WINAPI GetUserDefaultLCID(void)
Definition: locale.c:1210
GLuint id
Definition: glext.h:5910
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define LBS_SORT
Definition: pedump.c:679
#define LBS_OWNERDRAWFIXED
Definition: pedump.c:682
#define LBS_HASSTRINGS
Definition: pedump.c:684
#define LBS_MULTICOLUMN
Definition: pedump.c:687
#define LBS_OWNERDRAWVARIABLE
Definition: pedump.c:683
#define LBS_NOINTEGRALHEIGHT
Definition: pedump.c:686
#define TRACE(s)
Definition: solgame.cpp:4
& rect
Definition: startmenu.cpp:1413
INT fixedOwnerDrawHeight
Definition: comctl32.h:161
HWND self
Definition: comctl32.h:150
ULONG_PTR itemData
Definition: winuser.h:3649
static BOOL LISTBOX_update_uistate(LB_DESCR *descr)
Definition: listbox.c:2498
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define LBS_NODATA
Definition: winuser.h:313
#define CBS_DROPDOWN
Definition: winuser.h:283
#define WM_MEASUREITEM
Definition: winuser.h:1649
HWND WINAPI GetParent(_In_ HWND)
#define SetWindowLongPtrW
Definition: winuser.h:5358
#define GWL_STYLE
Definition: winuser.h:855
#define ODT_LISTBOX
Definition: winuser.h:2541

◆ LISTBOX_DeleteItem()

static void LISTBOX_DeleteItem ( LB_DESCR descr,
INT  index 
)
static

Definition at line 1654 of file listbox.c.

1655{
1656 /* save the item data before it gets freed by LB_RESETCONTENT */
1657 ULONG_PTR item_data = descr->items[index].data;
1658 LPWSTR item_str = descr->items[index].str;
1659
1660 if (!descr->nb_items)
1661 SendMessageW( descr->self, LB_RESETCONTENT, 0, 0 );
1662
1663 /* Note: Win 3.1 only sends DELETEITEM on owner-draw items,
1664 * while Win95 sends it for all items with user data.
1665 * It's probably better to send it too often than not
1666 * often enough, so this is what we do here.
1667 */
1668 if (IS_OWNERDRAW(descr) || item_data)
1669 {
1670 DELETEITEMSTRUCT dis;
1671 UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID );
1672
1673 dis.CtlType = ODT_LISTBOX;
1674 dis.CtlID = id;
1675 dis.itemID = index;
1676 dis.hwndItem = descr->self;
1677 dis.itemData = item_data;
1678 SendMessageW( descr->owner, WM_DELETEITEM, id, (LPARAM)&dis );
1679 }
1680 if (HAS_STRINGS(descr))
1681 HeapFree( GetProcessHeap(), 0, item_str );
1682}
#define index(s, c)
Definition: various.h:29
#define HAS_STRINGS(descr)
Definition: listbox.c:103
#define IS_OWNERDRAW(descr)
Definition: listbox.c:100
#define HeapFree(x, y, z)
Definition: compat.h:735
ULONG_PTR itemData
Definition: winuser.h:3047
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define WM_DELETEITEM
Definition: winuser.h:1650
#define LB_RESETCONTENT
Definition: winuser.h:2058
WCHAR * LPWSTR
Definition: xmlstorage.h:184

◆ LISTBOX_Destroy()

static BOOL LISTBOX_Destroy ( LB_DESCR descr)
static

Definition at line 2602 of file listbox.c.

2603{
2605 SetWindowLongPtrW( descr->self, 0, 0 );
2606 HeapFree( GetProcessHeap(), 0, descr );
2607 return TRUE;
2608}
static void LISTBOX_ResetContent(LB_DESCR *descr)
Definition: listbox.c:1811

◆ LISTBOX_Directory()

static LRESULT LISTBOX_Directory ( LB_DESCR descr,
UINT  attrib,
LPCWSTR  filespec,
BOOL  long_names 
)
static

Definition at line 1806 of file listbox.c.

1808{
1809 HANDLE handle;
1812 int pos;
1813 LRESULT maxinsert = LB_ERR;
1814
1815 /* don't scan directory if we just want drives exclusively */
1816 if (attrib != (DDL_DRIVES | DDL_EXCLUSIVE)) {
1817 /* scan directory */
1818 if ((handle = FindFirstFileW(filespec, &entry)) == INVALID_HANDLE_VALUE)
1819 {
1820 int le = GetLastError();
1821 if ((le != ERROR_NO_MORE_FILES) && (le != ERROR_FILE_NOT_FOUND)) return LB_ERR;
1822 }
1823 else
1824 {
1825 do
1826 {
1827 WCHAR buffer[270];
1828 if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1829 {
1830 static const WCHAR bracketW[] = { ']',0 };
1831 static const WCHAR dotW[] = { '.',0 };
1832 if (!(attrib & DDL_DIRECTORY) ||
1833 !strcmpW( entry.cFileName, dotW )) continue;
1834 buffer[0] = '[';
1835 if (!long_names && entry.cAlternateFileName[0])
1836 strcpyW( buffer + 1, entry.cAlternateFileName );
1837 else
1838 strcpyW( buffer + 1, entry.cFileName );
1839 strcatW(buffer, bracketW);
1840 }
1841 else /* not a directory */
1842 {
1843#define ATTRIBS (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | \
1844 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE)
1845
1846 if ((attrib & DDL_EXCLUSIVE) &&
1847 ((attrib & ATTRIBS) != (entry.dwFileAttributes & ATTRIBS)))
1848 continue;
1849#undef ATTRIBS
1850 if (!long_names && entry.cAlternateFileName[0])
1851 strcpyW( buffer, entry.cAlternateFileName );
1852 else
1853 strcpyW( buffer, entry.cFileName );
1854 }
1855 if (!long_names) CharLowerW( buffer );
1857 if ((ret = LISTBOX_InsertString( descr, pos, buffer )) < 0)
1858 break;
1859 if (ret <= maxinsert) maxinsert++; else maxinsert = ret;
1860 } while (FindNextFileW( handle, &entry ));
1861 FindClose( handle );
1862 }
1863 }
1864 if (ret >= 0)
1865 {
1866 ret = maxinsert;
1867
1868 /* scan drives */
1869 if (attrib & DDL_DRIVES)
1870 {
1871 WCHAR buffer[] = {'[','-','a','-',']',0};
1872 WCHAR root[] = {'A',':','\\',0};
1873 int drive;
1874 for (drive = 0; drive < 26; drive++, buffer[2]++, root[0]++)
1875 {
1876 if (GetDriveTypeW(root) <= DRIVE_NO_ROOT_DIR) continue;
1877 if ((ret = LISTBOX_InsertString( descr, -1, buffer )) < 0)
1878 break;
1879 }
1880 }
1881 }
1882 return ret;
1883}
static LRESULT LISTBOX_InsertString(LB_DESCR *descr, INT index, LPCWSTR str)
Definition: listbox.c:1696
#define ATTRIBS
static INT LISTBOX_FindFileStrPos(LB_DESCR *descr, LPCWSTR str)
Definition: listbox.c:946
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
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
GLuint buffer
Definition: glext.h:5915
uint32_t entry
Definition: isohybrid.c:63
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static const WCHAR dotW[]
Definition: directory.c:80
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define strcmpW(s1, s2)
Definition: unicode.h:44
#define strcatW(d, s)
Definition: unicode.h:36
#define strcpyW(d, s)
Definition: unicode.h:35
int ret
#define DRIVE_NO_ROOT_DIR
Definition: winbase.h:257
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
LONG_PTR LRESULT
Definition: windef.h:209
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121
#define LB_ERR
Definition: winuser.h:2435
#define LB_OKAY
Definition: winuser.h:2434
LPWSTR WINAPI CharLowerW(_Inout_ LPWSTR)
#define DDL_DRIVES
Definition: winuser.h:425
#define DDL_EXCLUSIVE
Definition: winuser.h:426
#define DDL_DIRECTORY
Definition: winuser.h:422
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ LISTBOX_DrawFocusRect()

static void LISTBOX_DrawFocusRect ( LB_DESCR descr,
BOOL  on 
)
static

Definition at line 690 of file listbox.c.

691{
692 HDC hdc;
693 RECT rect;
694 HFONT oldFont = 0;
695
696 /* Do not repaint the item if the item is not visible */
697 if (!IsWindowVisible(descr->self)) return;
698
699 if (descr->focus_item == -1) return;
700 if (!descr->caret_on || !descr->in_focus) return;
701
702 if (LISTBOX_GetItemRect( descr, descr->focus_item, &rect ) != 1) return;
703 if (!(hdc = GetDCEx( descr->self, 0, DCX_CACHE ))) return;
704 if (descr->font) oldFont = SelectObject( hdc, descr->font );
705 if (!IsWindowEnabled(descr->self))
707 SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
708 LISTBOX_PaintItem( descr, hdc, &rect, descr->focus_item, ODA_FOCUS, !on );
709 if (oldFont) SelectObject( hdc, oldFont );
710 ReleaseDC( descr->self, hdc );
711}
static LRESULT LISTBOX_GetItemRect(const LB_DESCR *descr, INT index, RECT *rect)
Definition: listbox.c:500
static void LISTBOX_PaintItem(LB_DESCR *descr, HDC hdc, const RECT *rect, INT index, UINT action, BOOL ignoreFocus)
Definition: listbox.c:605
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
BOOL WINAPI SetWindowOrgEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
Definition: coord.c:532
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:918
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
DWORD WINAPI GetSysColor(_In_ int)
#define COLOR_GRAYTEXT
Definition: winuser.h:935
#define DCX_CACHE
Definition: winuser.h:2117
#define ODA_FOCUS
Definition: winuser.h:2547
HDC WINAPI GetDCEx(_In_opt_ HWND, _In_opt_ HRGN, _In_ DWORD)
BOOL WINAPI IsWindowEnabled(_In_ HWND)
BOOL WINAPI IsWindowVisible(_In_ HWND)

◆ LISTBOX_FindFileStrPos()

static INT LISTBOX_FindFileStrPos ( LB_DESCR descr,
LPCWSTR  str 
)
static

Definition at line 889 of file listbox.c.

890{
891 INT min, max, res;
892
893 if (!HAS_STRINGS(descr))
895 min = 0;
896 max = descr->nb_items;
897 while (min != max)
898 {
899 INT index = (min + max) / 2;
900 LPCWSTR p = descr->items[index].str;
901 if (*p == '[') /* drive or directory */
902 {
903 if (*str != '[') res = -1;
904 else if (p[1] == '-') /* drive */
905 {
906 if (str[1] == '-') res = str[2] - p[2];
907 else res = -1;
908 }
909 else /* directory */
910 {
911 if (str[1] == '-') res = 1;
912 else res = LISTBOX_lstrcmpiW( descr->locale, str, p );
913 }
914 }
915 else /* filename */
916 {
917 if (*str == '[') res = 1;
918 else res = LISTBOX_lstrcmpiW( descr->locale, str, p );
919 }
920 if (!res) return index;
921 if (res < 0) max = index;
922 else min = index + 1;
923 }
924 return max;
925}
static INT LISTBOX_FindStringPos(LB_DESCR *descr, LPCWSTR str, BOOL exact)
Definition: listbox.c:902
static INT LISTBOX_lstrcmpiW(LCID lcid, LPCWSTR str1, LPCWSTR str2)
Definition: listbox.c:884
GLuint res
Definition: glext.h:9613
GLuint index
Definition: glext.h:6031
GLfloat GLfloat p
Definition: glext.h:8902
#define min(a, b)
Definition: monoChain.cc:55
#define max(a, b)
Definition: svc.c:63
int32_t INT
Definition: typedefs.h:58
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

◆ LISTBOX_FindString()

static INT LISTBOX_FindString ( LB_DESCR descr,
INT  start,
LPCWSTR  str,
BOOL  exact 
)
static

Definition at line 933 of file listbox.c.

934{
935 INT i;
937
938 if (start >= descr->nb_items) start = -1;
939 item = descr->items + start + 1;
940 if (HAS_STRINGS(descr))
941 {
942 if (!str || ! str[0] ) return LB_ERR;
943 if (exact)
944 {
945 for (i = start + 1; i < descr->nb_items; i++, item++)
946 if (!LISTBOX_lstrcmpiW( descr->locale, str, item->str )) return i;
947 for (i = 0, item = descr->items; i <= start; i++, item++)
948 if (!LISTBOX_lstrcmpiW( descr->locale, str, item->str )) return i;
949 }
950 else
951 {
952 /* Special case for drives and directories: ignore prefix */
953#define CHECK_DRIVE(item) \
954 if ((item)->str[0] == '[') \
955 { \
956 if (!strncmpiW( str, (item)->str+1, len )) return i; \
957 if (((item)->str[1] == '-') && !strncmpiW(str, (item)->str+2, len)) \
958 return i; \
959 }
960
961 INT len = strlenW(str);
962 for (i = start + 1; i < descr->nb_items; i++, item++)
963 {
964 if (!strncmpiW( str, item->str, len )) return i;
966 }
967 for (i = 0, item = descr->items; i <= start; i++, item++)
968 {
969 if (!strncmpiW( str, item->str, len )) return i;
971 }
972#undef CHECK_DRIVE
973 }
974 }
975 else
976 {
977 if (exact && (descr->style & LBS_SORT))
978 /* If sorted, use a WM_COMPAREITEM binary search */
980
981 /* Otherwise use a linear search */
982 for (i = start + 1; i < descr->nb_items; i++, item++)
983 if (item->data == (ULONG_PTR)str) return i;
984 for (i = 0, item = descr->items; i <= start; i++, item++)
985 if (item->data == (ULONG_PTR)str) return i;
986 }
987 return LB_ERR;
988}
GLuint start
Definition: gl.h:1545
#define strlenW(s)
Definition: unicode.h:34
#define CHECK_DRIVE(item)

◆ LISTBOX_FindStringPos()

static INT LISTBOX_FindStringPos ( LB_DESCR descr,
LPCWSTR  str,
BOOL  exact 
)
static

Definition at line 846 of file listbox.c.

847{
848 INT index, min, max, res;
849
850 if (!(descr->style & LBS_SORT)) return -1; /* Add it at the end */
851 min = 0;
852 max = descr->nb_items;
853 while (min != max)
854 {
855 index = (min + max) / 2;
856 if (HAS_STRINGS(descr))
857 res = LISTBOX_lstrcmpiW( descr->locale, str, descr->items[index].str);
858 else
859 {
861 UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID );
862
863 cis.CtlType = ODT_LISTBOX;
864 cis.CtlID = id;
865 cis.hwndItem = descr->self;
866 /* note that some application (MetaStock) expects the second item
867 * to be in the listbox */
868 cis.itemID1 = -1;
869 cis.itemData1 = (ULONG_PTR)str;
870 cis.itemID2 = index;
871 cis.itemData2 = descr->items[index].data;
872 cis.dwLocaleId = descr->locale;
873 res = SendMessageW( descr->owner, WM_COMPAREITEM, id, (LPARAM)&cis );
874 }
875 if (!res) return index;
876 if (res < 0) max = index;
877 else min = index + 1;
878 }
879 return exact ? -1 : max;
880}
#define ULONG_PTR
Definition: config.h:101
ULONG_PTR itemData1
Definition: winuser.h:2997
ULONG_PTR itemData2
Definition: winuser.h:2999
#define WM_COMPAREITEM
Definition: winuser.h:1658

◆ LISTBOX_GetCurrentPageSize()

static INT LISTBOX_GetCurrentPageSize ( const LB_DESCR descr)
static

Definition at line 159 of file listbox.c.

160{
161 INT i, height;
162 if (!(descr->style & LBS_OWNERDRAWVARIABLE)) return descr->page_size;
163 for (i = descr->top_item, height = 0; i < descr->nb_items; i++)
164 {
165 if ((height += descr->items[i].height) > descr->height) break;
166 }
167 if (i == descr->top_item) return 1;
168 else return i - descr->top_item;
169}
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546

◆ LISTBOX_GetItemFromPoint()

static INT LISTBOX_GetItemFromPoint ( const LB_DESCR descr,
INT  x,
INT  y 
)
static

Definition at line 474 of file listbox.c.

475{
476 INT index = descr->top_item;
477
478 if (!descr->nb_items) return -1; /* No items */
479 if (descr->style & LBS_OWNERDRAWVARIABLE)
480 {
481 INT pos = 0;
482 if (y >= 0)
483 {
484 while (index < descr->nb_items)
485 {
486 if ((pos += descr->items[index].height) > y) break;
487 index++;
488 }
489 }
490 else
491 {
492 while (index > 0)
493 {
494 index--;
495 if ((pos -= descr->items[index].height) <= y) break;
496 }
497 }
498 }
499 else if (descr->style & LBS_MULTICOLUMN)
500 {
501 if (y >= descr->item_height * descr->page_size) return -1;
502 if (y >= 0) index += y / descr->item_height;
503 if (x >= 0) index += (x / descr->column_width) * descr->page_size;
504 else index -= (((x + 1) / descr->column_width) - 1) * descr->page_size;
505 }
506 else
507 {
508 index += (y / descr->item_height);
509 }
510 if (index < 0) return 0;
511 if (index >= descr->nb_items) return -1;
512 return index;
513}
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548

◆ LISTBOX_GetItemHeight()

static LRESULT LISTBOX_GetItemHeight ( const LB_DESCR descr,
INT  index 
)
static

Definition at line 1180 of file listbox.c.

1181{
1182 if (descr->style & LBS_OWNERDRAWVARIABLE && descr->nb_items > 0)
1183 {
1184 if ((index < 0) || (index >= descr->nb_items))
1185 {
1187 return LB_ERR;
1188 }
1189 return descr->items[index].height;
1190 }
1191 else return descr->item_height;
1192}
#define SetLastError(x)
Definition: compat.h:752
#define ERROR_INVALID_INDEX
Definition: winerror.h:894

◆ LISTBOX_GetItemRect()

static LRESULT LISTBOX_GetItemRect ( const LB_DESCR descr,
INT  index,
RECT rect 
)
static

Definition at line 416 of file listbox.c.

417{
418 /* Index <= 0 is legal even on empty listboxes */
419 if (index && (index >= descr->nb_items))
420 {
421 memset(rect, 0, sizeof(*rect));
423 return LB_ERR;
424 }
425 SetRect( rect, 0, 0, descr->width, descr->height );
426 if (descr->style & LBS_MULTICOLUMN)
427 {
428 INT col = (index / descr->page_size) -
429 (descr->top_item / descr->page_size);
430 rect->left += col * descr->column_width;
431 rect->right = rect->left + descr->column_width;
432 rect->top += (index % descr->page_size) * descr->item_height;
433 rect->bottom = rect->top + descr->item_height;
434 }
435 else if (descr->style & LBS_OWNERDRAWVARIABLE)
436 {
437 INT i;
438 rect->right += descr->horz_pos;
439 if ((index >= 0) && (index < descr->nb_items))
440 {
441 if (index < descr->top_item)
442 {
443 for (i = descr->top_item-1; i >= index; i--)
444 rect->top -= descr->items[i].height;
445 }
446 else
447 {
448 for (i = descr->top_item; i < index; i++)
449 rect->top += descr->items[i].height;
450 }
451 rect->bottom = rect->top + descr->items[index].height;
452
453 }
454 }
455 else
456 {
457 rect->top += (index - descr->top_item) * descr->item_height;
458 rect->bottom = rect->top + descr->item_height;
459 rect->right += descr->horz_pos;
460 }
461
462 TRACE("item %d, rect %s\n", index, wine_dbgstr_rect(rect));
463
464 return ((rect->left < descr->width) && (rect->right > 0) &&
465 (rect->top < descr->height) && (rect->bottom > 0));
466}
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
#define memset(x, y, z)
Definition: compat.h:39
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)

◆ LISTBOX_GetMaxTopIndex()

static INT LISTBOX_GetMaxTopIndex ( const LB_DESCR descr)
static

Definition at line 177 of file listbox.c.

178{
179 INT max, page;
180
181 if (descr->style & LBS_OWNERDRAWVARIABLE)
182 {
183 page = descr->height;
184 for (max = descr->nb_items - 1; max >= 0; max--)
185 if ((page -= descr->items[max].height) < 0) break;
186 if (max < descr->nb_items - 1) max++;
187 }
188 else if (descr->style & LBS_MULTICOLUMN)
189 {
190 if ((page = descr->width / descr->column_width) < 1) page = 1;
191 max = (descr->nb_items + descr->page_size - 1) / descr->page_size;
192 max = (max - page) * descr->page_size;
193 }
194 else
195 {
196 max = descr->nb_items - descr->page_size;
197 }
198 if (max < 0) max = 0;
199 return max;
200}
Definition: module.h:576

◆ LISTBOX_GetSelCount()

static LRESULT LISTBOX_GetSelCount ( const LB_DESCR descr)
static

Definition at line 994 of file listbox.c.

995{
996 INT i, count;
997 const LB_ITEMDATA *item = descr->items;
998
999 if (!(descr->style & LBS_MULTIPLESEL) ||
1000 (descr->style & LBS_NOSEL))
1001 return LB_ERR;
1002 for (i = count = 0; i < descr->nb_items; i++, item++)
1003 if (item->selected) count++;
1004 return count;
1005}
GLuint GLuint GLsizei count
Definition: gl.h:1545

◆ LISTBOX_GetSelItems()

static LRESULT LISTBOX_GetSelItems ( const LB_DESCR descr,
INT  max,
LPINT  array 
)
static

Definition at line 1011 of file listbox.c.

1012{
1013 INT i, count;
1014 const LB_ITEMDATA *item = descr->items;
1015
1016 if (!(descr->style & LBS_MULTIPLESEL)) return LB_ERR;
1017 for (i = count = 0; (i < descr->nb_items) && (count < max); i++, item++)
1018 if (item->selected) array[count++] = i;
1019 return count;
1020}

◆ LISTBOX_GetText()

static LRESULT LISTBOX_GetText ( LB_DESCR descr,
INT  index,
LPWSTR  buffer,
BOOL  unicode 
)
static

Definition at line 778 of file listbox.c.

779{
780 DWORD len;
781
782 if ((index < 0) || (index >= descr->nb_items))
783 {
785 return LB_ERR;
786 }
787 if (HAS_STRINGS(descr))
788 {
789 if (!buffer)
790 {
791 len = strlenW(descr->items[index].str);
792 if( unicode )
793 return len;
794 return WideCharToMultiByte( CP_ACP, 0, descr->items[index].str, len,
795 NULL, 0, NULL, NULL );
796 }
797
798 TRACE("index %d (0x%04x) %s\n", index, index, debugstr_w(descr->items[index].str));
799
800 _SEH2_TRY /* hide a Delphi bug that passes a read-only buffer */
801 {
802 if(unicode)
803 {
804 strcpyW( buffer, descr->items[index].str );
805 len = strlenW(buffer);
806 }
807 else
808 {
809 len = WideCharToMultiByte(CP_ACP, 0, descr->items[index].str, -1,
810 (LPSTR)buffer, 0x7FFFFFFF, NULL, NULL) - 1;
811 }
812 }
814 {
815 ERR( "got an invalid buffer (Delphi bug?)\n" );
817 len = LB_ERR;
818 }
820 } else {
821 if (buffer)
822 *((LPDWORD)buffer)=*(LPDWORD)(&descr->items[index].data);
823 len = sizeof(DWORD);
824 }
825 return len;
826}
#define ERR(fmt,...)
Definition: precomp.h:57
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define WideCharToMultiByte
Definition: compat.h:111
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned long DWORD
Definition: ntddk_ex.h:95
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define debugstr_w
Definition: kernel32.h:32
#define LPDWORD
Definition: nt_native.h:46
#define DWORD
Definition: nt_native.h:44
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
char * LPSTR
Definition: xmlstorage.h:182

◆ LISTBOX_HandleChar()

static LRESULT LISTBOX_HandleChar ( LB_DESCR descr,
WCHAR  charW 
)
static

Definition at line 2469 of file listbox.c.

2470{
2471 INT caret = -1;
2472 WCHAR str[2];
2473
2474 str[0] = charW;
2475 str[1] = '\0';
2476
2477 if (descr->style & LBS_WANTKEYBOARDINPUT)
2478 {
2479 caret = SendMessageW( descr->owner, WM_CHARTOITEM,
2480 MAKEWPARAM(charW, descr->focus_item),
2481 (LPARAM)descr->self );
2482 if (caret == -2) return 0;
2483 }
2484 if (caret == -1)
2485 caret = LISTBOX_FindString( descr, descr->focus_item, str, FALSE);
2486 if (caret != -1)
2487 {
2488 if ((!IS_MULTISELECT(descr)) && descr->selected_item == -1)
2490 LISTBOX_MoveCaret( descr, caret, TRUE );
2491 if ((descr->style & LBS_NOTIFY) && descr->nb_items)
2493 }
2494 return 0;
2495}
#define SEND_NOTIFICATION(descr, code)
Definition: listbox.c:111
static LRESULT LISTBOX_SetSelection(LB_DESCR *descr, INT index, BOOL on, BOOL send_notify)
Definition: listbox.c:1542
#define IS_MULTISELECT(descr)
Definition: listbox.c:107
static void LISTBOX_MoveCaret(LB_DESCR *descr, INT index, BOOL fully_visible)
Definition: listbox.c:1585
static INT LISTBOX_FindString(LB_DESCR *descr, INT start, LPCWSTR str, BOOL exact)
Definition: listbox.c:990
#define LBS_NOTIFY
Definition: pedump.c:678
#define LBS_WANTKEYBOARDINPUT
Definition: pedump.c:688
#define WM_CHARTOITEM
Definition: winuser.h:1652
#define LBN_SELCHANGE
Definition: winuser.h:2078

◆ LISTBOX_HandleHScroll()

static LRESULT LISTBOX_HandleHScroll ( LB_DESCR descr,
WORD  scrollReq,
WORD  pos 
)
static

Definition at line 1933 of file listbox.c.

1934{
1936 INT page;
1937
1938 if (descr->style & LBS_MULTICOLUMN)
1939 {
1940 switch(scrollReq)
1941 {
1942 case SB_LINELEFT:
1943 LISTBOX_SetTopItem( descr, descr->top_item-descr->page_size,
1944 TRUE );
1945 break;
1946 case SB_LINERIGHT:
1947 LISTBOX_SetTopItem( descr, descr->top_item+descr->page_size,
1948 TRUE );
1949 break;
1950 case SB_PAGELEFT:
1951 page = descr->width / descr->column_width;
1952 if (page < 1) page = 1;
1954 descr->top_item - page * descr->page_size, TRUE );
1955 break;
1956 case SB_PAGERIGHT:
1957 page = descr->width / descr->column_width;
1958 if (page < 1) page = 1;
1960 descr->top_item + page * descr->page_size, TRUE );
1961 break;
1962 case SB_THUMBPOSITION:
1963 LISTBOX_SetTopItem( descr, pos*descr->page_size, TRUE );
1964 break;
1965 case SB_THUMBTRACK:
1966 info.cbSize = sizeof(info);
1967 info.fMask = SIF_TRACKPOS;
1968#ifdef __REACTOS__
1969 GetScrollInfo( descr->self, SB_HORZ, &info );
1970#else
1971 GetScrollInfo( descr->self, SB_VERT, &info );
1972#endif
1973 LISTBOX_SetTopItem( descr, info.nTrackPos*descr->page_size,
1974 TRUE );
1975 break;
1976 case SB_LEFT:
1978 break;
1979 case SB_RIGHT:
1980 LISTBOX_SetTopItem( descr, descr->nb_items, TRUE );
1981 break;
1982 }
1983 }
1984 else if (descr->horz_extent)
1985 {
1986 switch(scrollReq)
1987 {
1988 case SB_LINELEFT:
1989 LISTBOX_SetHorizontalPos( descr, descr->horz_pos - 1 );
1990 break;
1991 case SB_LINERIGHT:
1992 LISTBOX_SetHorizontalPos( descr, descr->horz_pos + 1 );
1993 break;
1994 case SB_PAGELEFT:
1996 descr->horz_pos - descr->width );
1997 break;
1998 case SB_PAGERIGHT:
2000 descr->horz_pos + descr->width );
2001 break;
2002 case SB_THUMBPOSITION:
2004 break;
2005 case SB_THUMBTRACK:
2006 info.cbSize = sizeof(info);
2007 info.fMask = SIF_TRACKPOS;
2008 GetScrollInfo( descr->self, SB_HORZ, &info );
2009 LISTBOX_SetHorizontalPos( descr, info.nTrackPos );
2010 break;
2011 case SB_LEFT:
2013 break;
2014 case SB_RIGHT:
2016 descr->horz_extent - descr->width );
2017 break;
2018 }
2019 }
2020 return 0;
2021}
static void LISTBOX_SetHorizontalPos(LB_DESCR *descr, INT pos)
Definition: listbox.c:1327
static LRESULT LISTBOX_SetTopItem(LB_DESCR *descr, INT index, BOOL scroll)
Definition: listbox.c:386
#define SB_THUMBTRACK
Definition: winuser.h:573
#define SB_PAGERIGHT
Definition: winuser.h:571
#define SB_VERT
Definition: winuser.h:553
#define SB_LEFT
Definition: winuser.h:575
#define SB_LINERIGHT
Definition: winuser.h:567
#define SIF_TRACKPOS
Definition: winuser.h:1240
#define SB_LINELEFT
Definition: winuser.h:566
#define SB_RIGHT
Definition: winuser.h:576
BOOL WINAPI GetScrollInfo(_In_ HWND, _In_ int, _Inout_ LPSCROLLINFO)
#define SB_HORZ
Definition: winuser.h:552
#define SB_PAGELEFT
Definition: winuser.h:570
#define SB_THUMBPOSITION
Definition: winuser.h:572

◆ LISTBOX_HandleKeyDown()

static LRESULT LISTBOX_HandleKeyDown ( LB_DESCR descr,
DWORD  key 
)
static

Definition at line 2357 of file listbox.c.

2358{
2359 INT caret = -1;
2360 BOOL bForceSelection = TRUE; /* select item pointed to by focus_item */
2361 if ((IS_MULTISELECT(descr)) || (descr->selected_item == descr->focus_item))
2362 bForceSelection = FALSE; /* only for single select list */
2363
2364 if (descr->style & LBS_WANTKEYBOARDINPUT)
2365 {
2366 caret = SendMessageW( descr->owner, WM_VKEYTOITEM,
2367 MAKEWPARAM(LOWORD(key), descr->focus_item),
2368 (LPARAM)descr->self );
2369 if (caret == -2) return 0;
2370 }
2371 if (caret == -1) switch(key)
2372 {
2373 case VK_LEFT:
2374 if (descr->style & LBS_MULTICOLUMN)
2375 {
2376 bForceSelection = FALSE;
2377 if (descr->focus_item >= descr->page_size)
2378 caret = descr->focus_item - descr->page_size;
2379 break;
2380 }
2381 /* fall through */
2382 case VK_UP:
2383 caret = descr->focus_item - 1;
2384 if (caret < 0) caret = 0;
2385 break;
2386 case VK_RIGHT:
2387 if (descr->style & LBS_MULTICOLUMN)
2388 {
2389 bForceSelection = FALSE;
2390 if (descr->focus_item + descr->page_size < descr->nb_items)
2391 caret = descr->focus_item + descr->page_size;
2392 break;
2393 }
2394 /* fall through */
2395 case VK_DOWN:
2396 caret = descr->focus_item + 1;
2397 if (caret >= descr->nb_items) caret = descr->nb_items - 1;
2398 break;
2399
2400 case VK_PRIOR:
2401 if (descr->style & LBS_MULTICOLUMN)
2402 {
2403 INT page = descr->width / descr->column_width;
2404 if (page < 1) page = 1;
2405 caret = descr->focus_item - (page * descr->page_size) + 1;
2406 }
2407 else caret = descr->focus_item-LISTBOX_GetCurrentPageSize(descr) + 1;
2408 if (caret < 0) caret = 0;
2409 break;
2410 case VK_NEXT:
2411 if (descr->style & LBS_MULTICOLUMN)
2412 {
2413 INT page = descr->width / descr->column_width;
2414 if (page < 1) page = 1;
2415 caret = descr->focus_item + (page * descr->page_size) - 1;
2416 }
2417 else caret = descr->focus_item + LISTBOX_GetCurrentPageSize(descr) - 1;
2418 if (caret >= descr->nb_items) caret = descr->nb_items - 1;
2419 break;
2420 case VK_HOME:
2421 caret = 0;
2422 break;
2423 case VK_END:
2424 caret = descr->nb_items - 1;
2425 break;
2426 case VK_SPACE:
2427 if (descr->style & LBS_EXTENDEDSEL) caret = descr->focus_item;
2428 else if (descr->style & LBS_MULTIPLESEL)
2429 {
2430 LISTBOX_SetSelection( descr, descr->focus_item,
2431 !descr->items[descr->focus_item].selected,
2432 (descr->style & LBS_NOTIFY) != 0 );
2433 }
2434 break;
2435 default:
2436 bForceSelection = FALSE;
2437 }
2438 if (bForceSelection) /* focused item is used instead of key */
2439 caret = descr->focus_item;
2440 if (caret >= 0)
2441 {
2442 if (((descr->style & LBS_EXTENDEDSEL) &&
2443 !(GetKeyState( VK_SHIFT ) & 0x8000)) ||
2445 descr->anchor_item = caret;
2446 LISTBOX_MoveCaret( descr, caret, TRUE );
2447
2448 if (descr->style & LBS_MULTIPLESEL)
2449 descr->selected_item = caret;
2450 else
2452 if (descr->style & LBS_NOTIFY)
2453 {
2454 if (descr->lphc && IsWindowVisible( descr->self ))
2455 {
2456 /* make sure that combo parent doesn't hide us */
2457 descr->lphc->wState |= CBF_NOROLLUP;
2458 }
2459 if (descr->nb_items) SEND_NOTIFICATION( descr, LBN_SELCHANGE );
2460 }
2461 }
2462 return 0;
2463}
#define CBF_NOROLLUP
Definition: controls.h:47
static INT LISTBOX_GetCurrentPageSize(const LB_DESCR *descr)
Definition: listbox.c:253
unsigned int BOOL
Definition: ntddk_ex.h:94
#define LOWORD(l)
Definition: pedump.c:82
Definition: copy.c:22
#define VK_SPACE
Definition: winuser.h:2222
#define VK_UP
Definition: winuser.h:2228
#define VK_NEXT
Definition: winuser.h:2224
#define VK_END
Definition: winuser.h:2225
#define VK_HOME
Definition: winuser.h:2226
#define VK_LEFT
Definition: winuser.h:2227
#define VK_RIGHT
Definition: winuser.h:2229
#define VK_DOWN
Definition: winuser.h:2230
#define VK_SHIFT
Definition: winuser.h:2205
#define VK_PRIOR
Definition: winuser.h:2223
SHORT WINAPI GetKeyState(_In_ int)
#define WM_VKEYTOITEM
Definition: winuser.h:1651

◆ LISTBOX_HandleLButtonDown()

static LRESULT LISTBOX_HandleLButtonDown ( LB_DESCR descr,
DWORD  keys,
INT  x,
INT  y 
)
static

Definition at line 2054 of file listbox.c.

2055{
2057
2058 TRACE("[%p]: lbuttondown %d,%d item %d, focus item %d\n",
2059 descr->self, x, y, index, descr->focus_item);
2060
2061 if (!descr->caret_on && (descr->in_focus)) return 0;
2062
2063 if (!descr->in_focus)
2064 {
2065 if( !descr->lphc ) SetFocus( descr->self );
2066 else SetFocus( (descr->lphc->hWndEdit) ? descr->lphc->hWndEdit : descr->lphc->self );
2067 }
2068
2069 if (index == -1) return 0;
2070
2071 if (!descr->lphc)
2072 {
2073 if (descr->style & LBS_NOTIFY )
2075 MAKELPARAM( x, y ) );
2076 }
2077
2078 descr->captured = TRUE;
2079 SetCapture( descr->self );
2080
2081 if (descr->style & (LBS_EXTENDEDSEL | LBS_MULTIPLESEL))
2082 {
2083 /* we should perhaps make sure that all items are deselected
2084 FIXME: needed for !LBS_EXTENDEDSEL, too ?
2085 if (!(keys & (MK_SHIFT|MK_CONTROL)))
2086 LISTBOX_SetSelection( descr, -1, FALSE, FALSE);
2087 */
2088
2089 if (!(keys & MK_SHIFT)) descr->anchor_item = index;
2090 if (keys & MK_CONTROL)
2091 {
2094 !descr->items[index].selected,
2095 (descr->style & LBS_NOTIFY) != 0);
2096 }
2097 else
2098 {
2100
2101 if (descr->style & LBS_EXTENDEDSEL)
2102 {
2104 descr->items[index].selected,
2105 (descr->style & LBS_NOTIFY) != 0 );
2106 }
2107 else
2108 {
2110 !descr->items[index].selected,
2111 (descr->style & LBS_NOTIFY) != 0 );
2112 }
2113 }
2114 }
2115 else
2116 {
2117 descr->anchor_item = index;
2120 TRUE, (descr->style & LBS_NOTIFY) != 0 );
2121 }
2122
2123 if (!descr->lphc)
2124 { // See rev 40864 use Ptr for 64 bit.
2126 {
2127 POINT pt;
2128
2129 pt.x = x;
2130 pt.y = y;
2131
2132 if (DragDetect( descr->self, pt ))
2133 SendMessageW( descr->owner, WM_BEGINDRAG, 0, 0 );
2134 }
2135 }
2136 return 0;
2137}
static LRESULT LISTBOX_SetCaretIndex(LB_DESCR *descr, INT index, BOOL fully_visible)
Definition: listbox.c:1473
static INT LISTBOX_GetItemFromPoint(const LB_DESCR *descr, INT x, INT y)
Definition: listbox.c:558
#define pt(x, y)
Definition: drawing.c:79
#define WM_LBTRACKPOINT
Definition: msg.c:59
#define WS_EX_DRAGDETECT
Definition: undocuser.h:21
#define WM_BEGINDRAG
Definition: undocuser.h:56
HWND WINAPI SetCapture(_In_ HWND hWnd)
#define MK_SHIFT
Definition: winuser.h:2372
#define MAKELPARAM(l, h)
Definition: winuser.h:4011
HWND WINAPI SetFocus(_In_opt_ HWND)
#define MK_CONTROL
Definition: winuser.h:2373
BOOL WINAPI DragDetect(_In_ HWND, _In_ POINT)
#define GWL_EXSTYLE
Definition: winuser.h:854

◆ LISTBOX_HandleLButtonDownCombo()

static LRESULT LISTBOX_HandleLButtonDownCombo ( LB_DESCR descr,
UINT  msg,
DWORD  keys,
INT  x,
INT  y 
)
static

Definition at line 2159 of file listbox.c.

2160{
2161 RECT clientRect, screenRect;
2162 POINT mousePos;
2163
2164 mousePos.x = x;
2165 mousePos.y = y;
2166
2167 GetClientRect(descr->self, &clientRect);
2168
2169 if(PtInRect(&clientRect, mousePos))
2170 {
2171 /* MousePos is in client, resume normal processing */
2172 if (msg == WM_LBUTTONDOWN)
2173 {
2174 descr->lphc->droppedIndex = descr->nb_items ? descr->selected_item : -1;
2175 return LISTBOX_HandleLButtonDown( descr, keys, x, y);
2176 }
2177 else if (descr->style & LBS_NOTIFY)
2179 }
2180 else
2181 {
2182 POINT screenMousePos;
2183 HWND hWndOldCapture;
2184
2185 /* Check the Non-Client Area */
2186 screenMousePos = mousePos;
2187 hWndOldCapture = GetCapture();
2189 GetWindowRect(descr->self, &screenRect);
2190 ClientToScreen(descr->self, &screenMousePos);
2191
2192 if(!PtInRect(&screenRect, screenMousePos))
2193 {
2194 LISTBOX_SetCaretIndex( descr, descr->lphc->droppedIndex, FALSE );
2195 LISTBOX_SetSelection( descr, descr->lphc->droppedIndex, FALSE, FALSE );
2197 }
2198 else
2199 {
2200 /* Check to see the NC is a scrollbar */
2201 INT nHitTestType=0;
2203 /* Check Vertical scroll bar */
2204 if (style & WS_VSCROLL)
2205 {
2206 clientRect.right += GetSystemMetrics(SM_CXVSCROLL);
2207 if (PtInRect( &clientRect, mousePos ))
2208 nHitTestType = HTVSCROLL;
2209 }
2210 /* Check horizontal scroll bar */
2211 if (style & WS_HSCROLL)
2212 {
2213 clientRect.bottom += GetSystemMetrics(SM_CYHSCROLL);
2214 if (PtInRect( &clientRect, mousePos ))
2215 nHitTestType = HTHSCROLL;
2216 }
2217 /* Windows sends this message when a scrollbar is clicked
2218 */
2219
2220 if(nHitTestType != 0)
2221 {
2222 SendMessageW(descr->self, WM_NCLBUTTONDOWN, nHitTestType,
2223 MAKELONG(screenMousePos.x, screenMousePos.y));
2224 }
2225 /* Resume the Capture after scrolling is complete
2226 */
2227 if(hWndOldCapture != 0)
2228 SetCapture(hWndOldCapture);
2229 }
2230 }
2231 return 0;
2232}
#define msg(x)
Definition: auth_time.c:54
BOOL COMBO_FlipListbox(LPHEADCOMBO lphc, BOOL ok, BOOL bRedrawButton)
Definition: combo.c:1078
static LRESULT LISTBOX_HandleLButtonDown(LB_DESCR *descr, DWORD keys, INT x, INT y)
Definition: listbox.c:2121
#define WS_VSCROLL
Definition: pedump.c:627
long LONG
Definition: pedump.c:60
#define WS_HSCROLL
Definition: pedump.c:628
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
#define MAKELONG(a, b)
Definition: typedefs.h:249
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2890
#define LBN_DBLCLK
Definition: winuser.h:2074
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define SM_CXVSCROLL
Definition: winuser.h:964
#define HTVSCROLL
Definition: winuser.h:2485
#define HTHSCROLL
Definition: winuser.h:2484
HWND WINAPI GetCapture(void)
Definition: message.c:2881
#define WM_LBUTTONDOWN
Definition: winuser.h:1779
BOOL WINAPI ClientToScreen(_In_ HWND, _Inout_ LPPOINT)
#define SM_CYHSCROLL
Definition: winuser.h:965
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
int WINAPI GetSystemMetrics(_In_ int)
#define WM_NCLBUTTONDOWN
Definition: winuser.h:1695

◆ LISTBOX_HandleLButtonUp()

static LRESULT LISTBOX_HandleLButtonUp ( LB_DESCR descr)
static

Definition at line 2237 of file listbox.c.

2238{
2242 if (descr->captured)
2243 {
2244 descr->captured = FALSE;
2245 if (GetCapture() == descr->self) ReleaseCapture();
2246 if ((descr->style & LBS_NOTIFY) && descr->nb_items)
2248 }
2249 return 0;
2250}
static TIMER_DIRECTION LISTBOX_Timer
Definition: listbox.c:127
#define LB_TIMER_ID
Definition: listbox.c:49
BOOL WINAPI KillSystemTimer(HWND, UINT_PTR)
Definition: timer.c:35

◆ LISTBOX_HandleMouseMove()

static void LISTBOX_HandleMouseMove ( LB_DESCR descr,
INT  x,
INT  y 
)
static

Definition at line 2309 of file listbox.c.

2311{
2312 INT index;
2314
2315 if (!descr->captured) return;
2316
2317 if (descr->style & LBS_MULTICOLUMN)
2318 {
2319 if (y < 0) y = 0;
2320 else if (y >= descr->item_height * descr->page_size)
2321 y = descr->item_height * descr->page_size - 1;
2322
2323 if (x < 0)
2324 {
2326 x = 0;
2327 }
2328 else if (x >= descr->width)
2329 {
2331 x = descr->width - 1;
2332 }
2333 }
2334 else
2335 {
2336 if (y < 0) dir = LB_TIMER_UP; /* above */
2337 else if (y >= descr->height) dir = LB_TIMER_DOWN; /* below */
2338 }
2339
2341 if (index == -1) index = descr->focus_item;
2343
2344 /* Start/stop the system timer */
2345
2346 if (dir != LB_TIMER_NONE)
2348 else if (LISTBOX_Timer != LB_TIMER_NONE)
2351}
unsigned int dir
Definition: maze.c:112
static LRESULT LISTBOX_HandleTimer(LB_DESCR *descr, INT index, TIMER_DIRECTION dir)
Definition: listbox.c:2326
#define LB_SCROLL_TIMEOUT
Definition: listbox.c:46
UINT_PTR WINAPI SetSystemTimer(HWND, UINT_PTR, UINT, TIMERPROC)
Definition: ntwrapper.h:106

◆ LISTBOX_HandleMouseWheel()

static LRESULT LISTBOX_HandleMouseWheel ( LB_DESCR descr,
SHORT  delta 
)
static

Definition at line 2023 of file listbox.c.

2024{
2025 UINT pulScrollLines = 3;
2026
2027 SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0);
2028
2029 /* if scrolling changes direction, ignore left overs */
2030 if ((delta < 0 && descr->wheel_remain < 0) ||
2031 (delta > 0 && descr->wheel_remain > 0))
2032 descr->wheel_remain += delta;
2033 else
2034 descr->wheel_remain = delta;
2035
2036 if (descr->wheel_remain && pulScrollLines)
2037 {
2038 int cLineScroll;
2039 pulScrollLines = min((UINT) descr->page_size, pulScrollLines);
2040 cLineScroll = pulScrollLines * (float)descr->wheel_remain / WHEEL_DELTA;
2041 descr->wheel_remain -= WHEEL_DELTA * cLineScroll / (int)pulScrollLines;
2042#ifdef __REACTOS__
2043 if (cLineScroll < 0)
2044 cLineScroll -= descr->page_size;
2045#endif
2046 LISTBOX_SetTopItem( descr, descr->top_item - cLineScroll, TRUE );
2047 }
2048 return 0;
2049}
static float(__cdecl *square_half_float)(float x
#define WHEEL_DELTA
Definition: treelist.c:99
BOOL WINAPI SystemParametersInfoW(_In_ UINT uiAction, _In_ UINT uiParam, _Inout_opt_ PVOID pvParam, _In_ UINT fWinIni)

◆ LISTBOX_HandleSystemTimer()

static LRESULT LISTBOX_HandleSystemTimer ( LB_DESCR descr)
static

Definition at line 2293 of file listbox.c.

2294{
2295 if (!LISTBOX_HandleTimer( descr, descr->focus_item, LISTBOX_Timer ))
2296 {
2299 }
2300 return 0;
2301}

◆ LISTBOX_HandleTimer()

static LRESULT LISTBOX_HandleTimer ( LB_DESCR descr,
INT  index,
TIMER_DIRECTION  dir 
)
static

Definition at line 2259 of file listbox.c.

2260{
2261 switch(dir)
2262 {
2263 case LB_TIMER_UP:
2264 if (descr->top_item) index = descr->top_item - 1;
2265 else index = 0;
2266 break;
2267 case LB_TIMER_LEFT:
2268 if (descr->top_item) index -= descr->page_size;
2269 break;
2270 case LB_TIMER_DOWN:
2272 if (index == descr->focus_item) index++;
2273 if (index >= descr->nb_items) index = descr->nb_items - 1;
2274 break;
2275 case LB_TIMER_RIGHT:
2276 if (index + descr->page_size < descr->nb_items)
2277 index += descr->page_size;
2278 break;
2279 case LB_TIMER_NONE:
2280 break;
2281 }
2282 if (index == descr->focus_item) return FALSE;
2284 return TRUE;
2285}

◆ LISTBOX_HandleVScroll()

static LRESULT LISTBOX_HandleVScroll ( LB_DESCR descr,
WORD  scrollReq,
WORD  pos 
)
static

Definition at line 1889 of file listbox.c.

1890{
1892
1893 if (descr->style & LBS_MULTICOLUMN) return 0;
1894 switch(scrollReq)
1895 {
1896 case SB_LINEUP:
1897 LISTBOX_SetTopItem( descr, descr->top_item - 1, TRUE );
1898 break;
1899 case SB_LINEDOWN:
1900 LISTBOX_SetTopItem( descr, descr->top_item + 1, TRUE );
1901 break;
1902 case SB_PAGEUP:
1903 LISTBOX_SetTopItem( descr, descr->top_item -
1905 break;
1906 case SB_PAGEDOWN:
1907 LISTBOX_SetTopItem( descr, descr->top_item +
1909 break;
1910 case SB_THUMBPOSITION:
1912 break;
1913 case SB_THUMBTRACK:
1914 info.cbSize = sizeof(info);
1915 info.fMask = SIF_TRACKPOS;
1916 GetScrollInfo( descr->self, SB_VERT, &info );
1917 LISTBOX_SetTopItem( descr, info.nTrackPos, TRUE );
1918 break;
1919 case SB_TOP:
1921 break;
1922 case SB_BOTTOM:
1923 LISTBOX_SetTopItem( descr, descr->nb_items, TRUE );
1924 break;
1925 }
1926 return 0;
1927}
#define SB_LINEUP
Definition: winuser.h:564
#define SB_BOTTOM
Definition: winuser.h:577
#define SB_PAGEDOWN
Definition: winuser.h:569
#define SB_LINEDOWN
Definition: winuser.h:565
#define SB_TOP
Definition: winuser.h:578
#define SB_PAGEUP
Definition: winuser.h:568

◆ LISTBOX_InitStorage()

static LRESULT LISTBOX_InitStorage ( LB_DESCR descr,
INT  nb_items 
)
static

Definition at line 717 of file listbox.c.

718{
720
721 nb_items += LB_ARRAY_GRANULARITY - 1;
722 nb_items -= (nb_items % LB_ARRAY_GRANULARITY);
723 if (descr->items) {
724 nb_items += HeapSize( GetProcessHeap(), 0, descr->items ) / sizeof(*item);
725 item = HeapReAlloc( GetProcessHeap(), 0, descr->items,
726 nb_items * sizeof(LB_ITEMDATA));
727 }
728 else {
730 nb_items * sizeof(LB_ITEMDATA));
731 }
732
733 if (!item)
734 {
736 return LB_ERRSPACE;
737 }
738 descr->items = item;
739 return LB_OKAY;
740}
#define LB_ARRAY_GRANULARITY
Definition: listbox.c:43
#define HeapReAlloc
Definition: compat.h:734
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
#define LBN_ERRSPACE
Definition: winuser.h:2075
#define LB_ERRSPACE
Definition: winuser.h:2436

◆ LISTBOX_InsertItem()

static LRESULT LISTBOX_InsertItem ( LB_DESCR descr,
INT  index,
LPWSTR  str,
ULONG_PTR  data 
)
static

Definition at line 1528 of file listbox.c.

1530{
1532 INT max_items;
1533 INT oldfocus = descr->focus_item;
1534
1535 if (index == -1) index = descr->nb_items;
1536 else if ((index < 0) || (index > descr->nb_items)) return LB_ERR;
1537 if (!descr->items) max_items = 0;
1538 else max_items = HeapSize( GetProcessHeap(), 0, descr->items ) / sizeof(*item);
1539 if (descr->nb_items == max_items)
1540 {
1541 /* We need to grow the array */
1542 max_items += LB_ARRAY_GRANULARITY;
1543 if (descr->items)
1544 item = HeapReAlloc( GetProcessHeap(), 0, descr->items,
1545 max_items * sizeof(LB_ITEMDATA) );
1546 else
1548 max_items * sizeof(LB_ITEMDATA) );
1549 if (!item)
1550 {
1552 return LB_ERRSPACE;
1553 }
1554 descr->items = item;
1555 }
1556
1557 /* Insert the item structure */
1558
1559 item = &descr->items[index];
1560 if (index < descr->nb_items)
1561 RtlMoveMemory( item + 1, item,
1562 (descr->nb_items - index) * sizeof(LB_ITEMDATA) );
1563 item->str = str;
1564 item->data = data;
1565 item->height = 0;
1566 item->selected = FALSE;
1567 descr->nb_items++;
1568
1569 /* Get item height */
1570
1571 if (descr->style & LBS_OWNERDRAWVARIABLE)
1572 {
1574 UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID );
1575
1576 mis.CtlType = ODT_LISTBOX;
1577 mis.CtlID = id;
1578 mis.itemID = index;
1579 mis.itemData = descr->items[index].data;
1580 mis.itemHeight = descr->item_height;
1581 SendMessageW( descr->owner, WM_MEASUREITEM, id, (LPARAM)&mis );
1582 item->height = mis.itemHeight ? mis.itemHeight : 1;
1583 TRACE("[%p]: measure item %d (%s) = %d\n",
1584 descr->self, index, str ? debugstr_w(str) : "", item->height );
1585 }
1586
1587 /* Repaint the items */
1588
1591
1592 /* Move selection and focused item */
1593 /* If listbox was empty, set focus to the first item */
1594 if (descr->nb_items == 1)
1596 /* single select don't change selection index in win31 */
1597 else if ((ISWIN31) && !(IS_MULTISELECT(descr)))
1598 {
1599 descr->selected_item++;
1600 LISTBOX_SetSelection( descr, descr->selected_item-1, TRUE, FALSE );
1601 }
1602 else
1603 {
1604 if (index <= descr->selected_item)
1605 {
1606 descr->selected_item++;
1607 descr->focus_item = oldfocus; /* focus not changed */
1608 }
1609 }
1610 return LB_OKAY;
1611}
static void LISTBOX_InvalidateItems(LB_DESCR *descr, INT index)
Definition: listbox.c:1238
#define ISWIN31
Definition: listbox.c:115
static void LISTBOX_UpdateScroll(LB_DESCR *descr)
Definition: listbox.c:303
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

◆ LISTBOX_InsertString()

static LRESULT LISTBOX_InsertString ( LB_DESCR descr,
INT  index,
LPCWSTR  str 
)
static

Definition at line 1617 of file listbox.c.

1618{
1619 LPWSTR new_str = NULL;
1620 ULONG_PTR data = 0;
1621 LRESULT ret;
1622
1623 if (HAS_STRINGS(descr))
1624 {
1625 static const WCHAR empty_stringW[] = { 0 };
1626 if (!str) str = empty_stringW;
1627 if (!(new_str = HeapAlloc( GetProcessHeap(), 0, (strlenW(str) + 1) * sizeof(WCHAR) )))
1628 {
1630 return LB_ERRSPACE;
1631 }
1632 strcpyW(new_str, str);
1633 }
1634 else data = (ULONG_PTR)str;
1635
1636 if (index == -1) index = descr->nb_items;
1637 if ((ret = LISTBOX_InsertItem( descr, index, new_str, data )) != 0)
1638 {
1639 HeapFree( GetProcessHeap(), 0, new_str );
1640 return ret;
1641 }
1642
1643 TRACE("[%p]: added item %d %s\n",
1644 descr->self, index, HAS_STRINGS(descr) ? debugstr_w(new_str) : "" );
1645 return index;
1646}
static LRESULT LISTBOX_InsertItem(LB_DESCR *descr, INT index, LPWSTR str, ULONG_PTR data)
Definition: listbox.c:1632
static const WCHAR empty_stringW[]
Definition: edit.c:173

◆ LISTBOX_InvalidateItemRect()

static void LISTBOX_InvalidateItemRect ( LB_DESCR descr,
INT  index 
)
static

Definition at line 1169 of file listbox.c.

1170{
1171 RECT rect;
1172
1173 if (LISTBOX_GetItemRect( descr, index, &rect ) == 1)
1174 InvalidateRect( descr->self, &rect, TRUE );
1175}
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)

◆ LISTBOX_InvalidateItems()

static void LISTBOX_InvalidateItems ( LB_DESCR descr,
INT  index 
)
static

Definition at line 1145 of file listbox.c.

1146{
1147 RECT rect;
1148
1149 if (LISTBOX_GetItemRect( descr, index, &rect ) == 1)
1150 {
1151 if (descr->style & LBS_NOREDRAW)
1152 {
1153 descr->style |= LBS_DISPLAYCHANGED;
1154 return;
1155 }
1156 rect.bottom = descr->height;
1157 InvalidateRect( descr->self, &rect, TRUE );
1158 if (descr->style & LBS_MULTICOLUMN)
1159 {
1160 /* Repaint the other columns */
1161 rect.left = rect.right;
1162 rect.right = descr->width;
1163 rect.top = 0;
1164 InvalidateRect( descr->self, &rect, TRUE );
1165 }
1166 }
1167}
#define LBS_DISPLAYCHANGED
Definition: listbox.c:52
#define LBS_NOREDRAW
Definition: pedump.c:680

◆ LISTBOX_lstrcmpiW()

static INT LISTBOX_lstrcmpiW ( LCID  lcid,
LPCWSTR  str1,
LPCWSTR  str2 
)
inlinestatic

Definition at line 828 of file listbox.c.

829{
830 INT ret = CompareStringW( lcid, NORM_IGNORECASE, str1, -1, str2, -1 );
831 if (ret == CSTR_LESS_THAN)
832 return -1;
833 if (ret == CSTR_EQUAL)
834 return 0;
835 if (ret == CSTR_GREATER_THAN)
836 return 1;
837 return -1;
838}
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: locale.c:4013
#define NORM_IGNORECASE
Definition: winnls.h:176
#define CSTR_EQUAL
Definition: winnls.h:456
#define CSTR_LESS_THAN
Definition: winnls.h:455
#define CSTR_GREATER_THAN
Definition: winnls.h:457

◆ LISTBOX_MakeItemVisible()

static void LISTBOX_MakeItemVisible ( LB_DESCR descr,
INT  index,
BOOL  fully 
)
static

Definition at line 1334 of file listbox.c.

1335{
1336 INT top;
1337
1338 TRACE("current top item %d, index %d, fully %d\n", descr->top_item, index, fully);
1339
1340 if (index <= descr->top_item) top = index;
1341 else if (descr->style & LBS_MULTICOLUMN)
1342 {
1343 INT cols = descr->width;
1344 if (!fully) cols += descr->column_width - 1;
1345 if (cols >= descr->column_width) cols /= descr->column_width;
1346 else cols = 1;
1347 if (index < descr->top_item + (descr->page_size * cols)) return;
1348 top = index - descr->page_size * (cols - 1);
1349 }
1350 else if (descr->style & LBS_OWNERDRAWVARIABLE)
1351 {
1352 INT height = fully ? descr->items[index].height : 1;
1353 for (top = index; top > descr->top_item; top--)
1354 if ((height += descr->items[top-1].height) > descr->height) break;
1355 }
1356 else
1357 {
1358 if (index < descr->top_item + descr->page_size) return;
1359 if (!fully && (index == descr->top_item + descr->page_size) &&
1360 (descr->height > (descr->page_size * descr->item_height))) return;
1361 top = index - descr->page_size + 1;
1362 }
1364}
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859

◆ LISTBOX_MoveCaret()

static void LISTBOX_MoveCaret ( LB_DESCR descr,
INT  index,
BOOL  fully_visible 
)
static

Definition at line 1481 of file listbox.c.

1482{
1483 TRACE("old focus %d, index %d\n", descr->focus_item, index);
1484
1485 if ((index < 0) || (index >= descr->nb_items))
1486 return;
1487
1488 /* Important, repaint needs to be done in this order if
1489 you want to mimic Windows behavior:
1490 1. Remove the focus and paint the item
1491 2. Remove the selection and paint the item(s)
1492 3. Set the selection and repaint the item(s)
1493 4. Set the focus to 'index' and repaint the item */
1494
1495 /* 1. remove the focus and repaint the item */
1497
1498 /* 2. then turn off the previous selection */
1499 /* 3. repaint the new selected item */
1500 if (descr->style & LBS_EXTENDEDSEL)
1501 {
1502 if (descr->anchor_item != -1)
1503 {
1504 INT first = min( index, descr->anchor_item );
1505 INT last = max( index, descr->anchor_item );
1506 if (first > 0)
1510 }
1511 }
1512 else if (!(descr->style & LBS_MULTIPLESEL))
1513 {
1514 /* Set selection to new caret item */
1516 }
1517
1518 /* 4. repaint the new item with the focus */
1519 descr->focus_item = index;
1520 LISTBOX_MakeItemVisible( descr, index, fully_visible );
1522}
static void LISTBOX_DrawFocusRect(LB_DESCR *descr, BOOL on)
Definition: listbox.c:772
static void LISTBOX_MakeItemVisible(LB_DESCR *descr, INT index, BOOL fully)
Definition: listbox.c:1434
static LRESULT LISTBOX_SelectItemRange(LB_DESCR *descr, INT first, INT last, BOOL on)
Definition: listbox.c:1502
const GLint * first
Definition: glext.h:5794
static UINT UINT last
Definition: font.c:45

◆ LISTBOX_Paint()

static LRESULT LISTBOX_Paint ( LB_DESCR descr,
HDC  hdc 
)
static

Definition at line 1026 of file listbox.c.

1027{
1028 INT i, col_pos = descr->page_size - 1;
1029 RECT rect;
1030 RECT focusRect = {-1, -1, -1, -1};
1031 HFONT oldFont = 0;
1032 HBRUSH hbrush, oldBrush = 0;
1033
1034 if (descr->style & LBS_NOREDRAW) return 0;
1035
1036 SetRect( &rect, 0, 0, descr->width, descr->height );
1037 if (descr->style & LBS_MULTICOLUMN)
1038 rect.right = rect.left + descr->column_width;
1039 else if (descr->horz_pos)
1040 {
1041 SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
1042 rect.right += descr->horz_pos;
1043 }
1044
1045 if (descr->font) oldFont = SelectObject( hdc, descr->font );
1046#ifdef __REACTOS__
1048#else
1049 hbrush = (HBRUSH)SendMessageW( descr->owner, WM_CTLCOLORLISTBOX,
1050 (WPARAM)hdc, (LPARAM)descr->self );
1051#endif
1052 if (hbrush) oldBrush = SelectObject( hdc, hbrush );
1054
1055 if (!descr->nb_items && (descr->focus_item != -1) && descr->caret_on &&
1056 (descr->in_focus))
1057 {
1058 /* Special case for empty listbox: paint focus rect */
1059 rect.bottom = rect.top + descr->item_height;
1061 &rect, NULL, 0, NULL );
1062 LISTBOX_PaintItem( descr, hdc, &rect, descr->focus_item, ODA_FOCUS, FALSE );
1063 rect.top = rect.bottom;
1064 }
1065
1066 /* Paint all the item, regarding the selection
1067 Focus state will be painted after */
1068
1069 for (i = descr->top_item; i < descr->nb_items; i++)
1070 {
1071 if (!(descr->style & LBS_OWNERDRAWVARIABLE))
1072 rect.bottom = rect.top + descr->item_height;
1073 else
1074 rect.bottom = rect.top + descr->items[i].height;
1075
1076 /* keep the focus rect, to paint the focus item after */
1077 if (i == descr->focus_item)
1078 focusRect = rect;
1079
1081 rect.top = rect.bottom;
1082
1083 if ((descr->style & LBS_MULTICOLUMN) && !col_pos)
1084 {
1085 if (!IS_OWNERDRAW(descr))
1086 {
1087 /* Clear the bottom of the column */
1088 if (rect.top < descr->height)
1089 {
1090 rect.bottom = descr->height;
1092 &rect, NULL, 0, NULL );
1093 }
1094 }
1095
1096 /* Go to the next column */
1097 rect.left += descr->column_width;
1098 rect.right += descr->column_width;
1099 rect.top = 0;
1100 col_pos = descr->page_size - 1;
1101 }
1102 else
1103 {
1104 col_pos--;
1105 if (rect.top >= descr->height) break;
1106 }
1107 }
1108
1109 /* Paint the focus item now */
1110 if (focusRect.top != focusRect.bottom &&
1111 descr->caret_on && descr->in_focus)
1112 LISTBOX_PaintItem( descr, hdc, &focusRect, descr->focus_item, ODA_FOCUS, FALSE );
1113
1114 if (!IS_OWNERDRAW(descr))
1115 {
1116 /* Clear the remainder of the client area */
1117 if (rect.top < descr->height)
1118 {
1119 rect.bottom = descr->height;
1121 &rect, NULL, 0, NULL );
1122 }
1123 if (rect.right < descr->width)
1124 {
1125 rect.left = rect.right;
1126 rect.right = descr->width;
1127 rect.top = 0;
1128 rect.bottom = descr->height;
1130 &rect, NULL, 0, NULL );
1131 }
1132 }
1133 if (oldFont) SelectObject( hdc, oldFont );
1134 if (oldBrush) SelectObject( hdc, oldBrush );
1135 return 0;
1136}
static HBRUSH hbrush
LONG top
Definition: windef.h:307
HBRUSH FASTCALL GetControlColor(PWND pwndParent, PWND pwnd, HDC hdc, UINT CtlMsg)
Definition: misc.c:154
UINT_PTR WPARAM
Definition: windef.h:207
#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
#define ODA_DRAWENTIRE
Definition: winuser.h:2545
#define WM_CTLCOLORLISTBOX
Definition: winuser.h:1771

◆ LISTBOX_PaintItem()

static void LISTBOX_PaintItem ( LB_DESCR descr,
HDC  hdc,
const RECT rect,
INT  index,
UINT  action,
BOOL  ignoreFocus 
)
static

Definition at line 521 of file listbox.c.

523{
525 if (index < descr->nb_items) item = &descr->items[index];
526
527 if (IS_OWNERDRAW(descr))
528 {
529 DRAWITEMSTRUCT dis;
530 RECT r;
531 HRGN hrgn;
532
533 if (!item)
534 {
535 if (action == ODA_FOCUS)
536 { // REACTOS
537 if (!(descr->UIState & UISF_HIDEFOCUS))
539 } //
540 else
541 ERR("called with an out of bounds index %d(%d) in owner draw, Not good.\n",index,descr->nb_items);
542 return;
543 }
544
545 /* some programs mess with the clipping region when
546 drawing the item, *and* restore the previous region
547 after they are done, so a region has better to exist
548 else everything ends clipped */
549 GetClientRect(descr->self, &r);
551
552 dis.CtlType = ODT_LISTBOX;
553 dis.CtlID = GetWindowLongPtrW( descr->self, GWLP_ID );
554 dis.hwndItem = descr->self;
555 dis.itemAction = action;
556 dis.hDC = hdc;
557 dis.itemID = index;
558 dis.itemState = 0;
559 if (item->selected) dis.itemState |= ODS_SELECTED;
560 if (!ignoreFocus && (descr->focus_item == index) &&
561 (descr->caret_on) &&
562 (descr->in_focus)) dis.itemState |= ODS_FOCUS;
563 if (!IsWindowEnabled(descr->self)) dis.itemState |= ODS_DISABLED;
564 dis.itemData = item->data;
565 dis.rcItem = *rect;
566 TRACE("[%p]: drawitem %d (%s) action=%02x state=%02x rect=%s\n",
567 descr->self, index, debugstr_w(item->str), action,
569 SendMessageW(descr->owner, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
571 if (hrgn) DeleteObject( hrgn );
572 }
573 else
574 {
575 COLORREF oldText = 0, oldBk = 0;
576
577 if (action == ODA_FOCUS)
578 {
579 if (!(descr->UIState & UISF_HIDEFOCUS)) // REACTOS
581 return;
582 }
583 if (item && item->selected)
584 {
587 }
588
589 TRACE("[%p]: painting %d (%s) action=%02x rect=%s\n",
590 descr->self, index, item ? debugstr_w(item->str) : "", action,
592 if (!item)
593 ExtTextOutW( hdc, rect->left + 1, rect->top,
595 else if (!(descr->style & LBS_USETABSTOPS))
596 ExtTextOutW( hdc, rect->left + 1, rect->top,
598 strlenW(item->str), NULL );
599 else
600 {
601 /* Output empty string to paint background in the full width. */
602 ExtTextOutW( hdc, rect->left + 1, rect->top,
604 TabbedTextOutW( hdc, rect->left + 1 , rect->top,
605 item->str, strlenW(item->str),
606 descr->nb_tabs, descr->tabs, 0);
607 }
608 if (item && item->selected)
609 {
610 SetBkColor( hdc, oldBk );
611 SetTextColor( hdc, oldText );
612 }
613 if (!ignoreFocus && (descr->focus_item == index) &&
614 (descr->caret_on) &&
615 (descr->in_focus) &&
616 !(descr->UIState & UISF_HIDEFOCUS)) DrawFocusRect( hdc, rect );
617 }
618}
static HRGN hrgn
HRGN set_control_clipping(HDC hdc, const RECT *rect)
Definition: button.c:242
const WCHAR * action
Definition: action.c:7509
pKey DeleteObject()
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define LBS_USETABSTOPS
Definition: pedump.c:685
ULONG_PTR itemData
Definition: winuser.h:3096
DWORD COLORREF
Definition: windef.h:300
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:999
int WINAPI SelectClipRgn(_In_ HDC, _In_opt_ HRGN)
#define ODS_DISABLED
Definition: winuser.h:2550
#define ODS_SELECTED
Definition: winuser.h:2548
#define COLOR_HIGHLIGHT
Definition: winuser.h:929
#define WM_DRAWITEM
Definition: winuser.h:1648
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:930
BOOL WINAPI DrawFocusRect(_In_ HDC, _In_ LPCRECT)
#define ODS_FOCUS
Definition: winuser.h:2552
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)

◆ LISTBOX_RemoveItem()

static LRESULT LISTBOX_RemoveItem ( LB_DESCR descr,
INT  index 
)
static

Definition at line 1690 of file listbox.c.

1691{
1693 INT max_items;
1694
1695 if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
1696
1697 /* We need to invalidate the original rect instead of the updated one. */
1699
1700 descr->nb_items--;
1702
1703 if (!descr->nb_items) return LB_OKAY;
1704
1705 /* Remove the item */
1706
1707 item = &descr->items[index];
1708 if (index < descr->nb_items)
1709 RtlMoveMemory( item, item + 1,
1710 (descr->nb_items - index) * sizeof(LB_ITEMDATA) );
1711 if (descr->anchor_item == descr->nb_items) descr->anchor_item--;
1712
1713 /* Shrink the item array if possible */
1714
1715 max_items = HeapSize( GetProcessHeap(), 0, descr->items ) / sizeof(LB_ITEMDATA);
1716 if (descr->nb_items < max_items - 2*LB_ARRAY_GRANULARITY)
1717 {
1718 max_items -= LB_ARRAY_GRANULARITY;
1719 item = HeapReAlloc( GetProcessHeap(), 0, descr->items,
1720 max_items * sizeof(LB_ITEMDATA) );
1721 if (item) descr->items = item;
1722 }
1723 /* Repaint the items */
1724
1726 /* if we removed the scrollbar, reset the top of the list
1727 (correct for owner-drawn ???) */
1728 if (descr->nb_items == descr->page_size)
1730
1731 /* Move selection and focused item */
1732 if (!IS_MULTISELECT(descr))
1733 {
1734 if (index == descr->selected_item)
1735 descr->selected_item = -1;
1736 else if (index < descr->selected_item)
1737 {
1738 descr->selected_item--;
1739 if (ISWIN31) /* win 31 do not change the selected item number */
1740 LISTBOX_SetSelection( descr, descr->selected_item + 1, TRUE, FALSE);
1741 }
1742 }
1743
1744 if (descr->focus_item >= descr->nb_items)
1745 {
1746 descr->focus_item = descr->nb_items - 1;
1747 if (descr->focus_item < 0) descr->focus_item = 0;
1748 }
1749 return LB_OKAY;
1750}
static void LISTBOX_DeleteItem(LB_DESCR *descr, INT index)
Definition: listbox.c:1731

◆ LISTBOX_RepaintItem()

static void LISTBOX_RepaintItem ( LB_DESCR descr,
INT  index,
UINT  action 
)
static

Definition at line 653 of file listbox.c.

654{
655 HDC hdc;
656 RECT rect;
657 HFONT oldFont = 0;
658 HBRUSH hbrush, oldBrush = 0;
659
660 /* Do not repaint the item if the item is not visible */
661 if (!IsWindowVisible(descr->self)) return;
662 if (descr->style & LBS_NOREDRAW)
663 {
664 descr->style |= LBS_DISPLAYCHANGED;
665 return;
666 }
667 if (LISTBOX_GetItemRect( descr, index, &rect ) != 1) return;
668 if (!(hdc = GetDCEx( descr->self, 0, DCX_CACHE ))) return;
669 if (descr->font) oldFont = SelectObject( hdc, descr->font );
670#ifdef __REACTOS__
672#else
673 hbrush = (HBRUSH)SendMessageW( descr->owner, WM_CTLCOLORLISTBOX,
674 (WPARAM)hdc, (LPARAM)descr->self );
675#endif
676 if (hbrush) oldBrush = SelectObject( hdc, hbrush );
677 if (!IsWindowEnabled(descr->self))
679 SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
681 if (oldFont) SelectObject( hdc, oldFont );
682 if (oldBrush) SelectObject( hdc, oldBrush );
683 ReleaseDC( descr->self, hdc );
684}

◆ LISTBOX_ResetContent()

static void LISTBOX_ResetContent ( LB_DESCR descr)
static

Definition at line 1756 of file listbox.c.

1757{
1758 INT i;
1759
1760 for(i = descr->nb_items - 1; i>=0; i--) LISTBOX_DeleteItem( descr, i);
1761 HeapFree( GetProcessHeap(), 0, descr->items );
1762 descr->nb_items = 0;
1763 descr->top_item = 0;
1764 descr->selected_item = -1;
1765 descr->focus_item = 0;
1766 descr->anchor_item = -1;
1767 descr->items = NULL;
1768}

◆ LISTBOX_SelectItemRange()

static LRESULT LISTBOX_SelectItemRange ( LB_DESCR descr,
INT  first,
INT  last,
BOOL  on 
)
static

Definition at line 1398 of file listbox.c.

1400{
1401 INT i;
1402
1403 /* A few sanity checks */
1404
1405 if (descr->style & LBS_NOSEL) return LB_ERR;
1406 if (!(descr->style & LBS_MULTIPLESEL)) return LB_ERR;
1407
1408 if (!descr->nb_items) return LB_OKAY;
1409
1410 if (last == -1 || last >= descr->nb_items) last = descr->nb_items - 1;
1411 if (first < 0) first = 0;
1412 if (last < first) return LB_OKAY;
1413
1414 if (on) /* Turn selection on */
1415 {
1416 for (i = first; i <= last; i++)
1417 {
1418 if (descr->items[i].selected) continue;
1419 descr->items[i].selected = TRUE;
1421 }
1422 }
1423 else /* Turn selection off */
1424 {
1425 for (i = first; i <= last; i++)
1426 {
1427 if (!descr->items[i].selected) continue;
1428 descr->items[i].selected = FALSE;
1430 }
1431 }
1432 return LB_OKAY;
1433}
static void LISTBOX_InvalidateItemRect(LB_DESCR *descr, INT index)
Definition: listbox.c:1262

◆ LISTBOX_SetCaretIndex()

static LRESULT LISTBOX_SetCaretIndex ( LB_DESCR descr,
INT  index,
BOOL  fully_visible 
)
static

Definition at line 1373 of file listbox.c.

1374{
1375 INT oldfocus = descr->focus_item;
1376
1377 TRACE("old focus %d, index %d\n", oldfocus, index);
1378
1379 if (descr->style & LBS_NOSEL) return LB_ERR;
1380 if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
1381 if (index == oldfocus) return LB_OKAY;
1382
1384 descr->focus_item = index;
1385
1386 LISTBOX_MakeItemVisible( descr, index, fully_visible );
1388
1389 return LB_OKAY;
1390}

◆ LISTBOX_SetColumnWidth()

static LRESULT LISTBOX_SetColumnWidth ( LB_DESCR descr,
INT  width 
)
static

Definition at line 1288 of file listbox.c.

1289{
1290 if (width == descr->column_width) return LB_OKAY;
1291 TRACE("[%p]: new column width = %d\n", descr->self, width );
1292 descr->column_width = width;
1294 return LB_OKAY;
1295}
static void LISTBOX_UpdatePage(LB_DESCR *descr)
Definition: listbox.c:435
GLint GLint GLsizei width
Definition: gl.h:1546

◆ LISTBOX_SetCount()

static LRESULT LISTBOX_SetCount ( LB_DESCR descr,
INT  count 
)
static

Definition at line 1774 of file listbox.c.

1775{
1776 LRESULT ret;
1777
1778 if (HAS_STRINGS(descr))
1779 {
1781 return LB_ERR;
1782 }
1783
1784 /* FIXME: this is far from optimal... */
1785 if (count > descr->nb_items)
1786 {
1787 while (count > descr->nb_items)
1788 if ((ret = LISTBOX_InsertString( descr, -1, 0 )) < 0)
1789 return ret;
1790 }
1791 else if (count < descr->nb_items)
1792 {
1793 while (count < descr->nb_items)
1794 if ((ret = LISTBOX_RemoveItem( descr, (descr->nb_items - 1) )) < 0)
1795 return ret;
1796 }
1797
1798 InvalidateRect( descr->self, NULL, TRUE );
1799 return LB_OKAY;
1800}
static LRESULT LISTBOX_RemoveItem(LB_DESCR *descr, INT index)
Definition: listbox.c:1759
#define ERROR_SETCOUNT_ON_BAD_LB
Definition: winerror.h:914

◆ LISTBOX_SetFont()

static INT LISTBOX_SetFont ( LB_DESCR descr,
HFONT  font 
)
static

Definition at line 1303 of file listbox.c.

1304{
1305 HDC hdc;
1306 HFONT oldFont = 0;
1307 const char *alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
1308 SIZE sz;
1309
1310 descr->font = font;
1311
1312 if (!(hdc = GetDCEx( descr->self, 0, DCX_CACHE )))
1313 {
1314 ERR("unable to get DC.\n" );
1315 return 16;
1316 }
1317 if (font) oldFont = SelectObject( hdc, font );
1318 GetTextExtentPointA( hdc, alphabet, 52, &sz);
1319 if (oldFont) SelectObject( hdc, oldFont );
1320 ReleaseDC( descr->self, hdc );
1321
1322 descr->avg_char_width = (sz.cx / 26 + 1) / 2;
1323 if (!IS_OWNERDRAW(descr))
1325 return sz.cy;
1326}
static LRESULT LISTBOX_SetItemHeight(LB_DESCR *descr, INT index, INT height, BOOL repaint)
Definition: listbox.c:1291
Definition: mk_font.cpp:20
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
BOOL WINAPI GetTextExtentPointA(_In_ HDC hdc, _In_reads_(c) LPCSTR lpString, _In_ int c, _Out_ LPSIZE lpsz)

◆ LISTBOX_SetHorizontalExtent()

static LRESULT LISTBOX_SetHorizontalExtent ( LB_DESCR descr,
INT  extent 
)
static

Definition at line 1262 of file listbox.c.

1263{
1264 if (descr->style & LBS_MULTICOLUMN)
1265 return LB_OKAY;
1266 if (extent == descr->horz_extent) return LB_OKAY;
1267 TRACE("[%p]: new horz extent = %d\n", descr->self, extent );
1268 descr->horz_extent = extent;
1269 if (descr->style & WS_HSCROLL) {
1271 info.cbSize = sizeof(info);
1272 info.nMin = 0;
1273 info.nMax = descr->horz_extent ? descr->horz_extent - 1 : 0;
1274 info.fMask = SIF_RANGE;
1275 if (descr->style & LBS_DISABLENOSCROLL)
1276 info.fMask |= SIF_DISABLENOSCROLL;
1277 SetScrollInfo( descr->self, SB_HORZ, &info, TRUE );
1278 }
1279 if (descr->horz_pos > extent - descr->width)
1281 return LB_OKAY;
1282}
#define LBS_DISABLENOSCROLL
Definition: pedump.c:690
#define SIF_RANGE
Definition: winuser.h:1238
#define SIF_DISABLENOSCROLL
Definition: winuser.h:1239
int WINAPI SetScrollInfo(_In_ HWND, _In_ int, _In_ LPCSCROLLINFO, _In_ BOOL)

◆ LISTBOX_SetHorizontalPos()

static void LISTBOX_SetHorizontalPos ( LB_DESCR descr,
INT  pos 
)
static

Definition at line 1234 of file listbox.c.

1235{
1236 INT diff;
1237
1238 if (pos > descr->horz_extent - descr->width)
1239 pos = descr->horz_extent - descr->width;
1240 if (pos < 0) pos = 0;
1241 if (!(diff = descr->horz_pos - pos)) return;
1242 TRACE("[%p]: new horz pos = %d\n", descr->self, pos );
1243 descr->horz_pos = pos;
1245 if (abs(diff) < descr->width)
1246 {
1247 RECT rect;
1248 /* Invalidate the focused item so it will be repainted correctly */
1249 if (LISTBOX_GetItemRect( descr, descr->focus_item, &rect ) == 1)
1250 InvalidateRect( descr->self, &rect, TRUE );
1251 ScrollWindowEx( descr->self, diff, 0, NULL, NULL, 0, NULL,
1253 }
1254 else
1255 InvalidateRect( descr->self, NULL, TRUE );
1256}
#define abs(i)
Definition: fconv.c:206
#define SW_SCROLLCHILDREN
Definition: winuser.h:2581
#define SW_INVALIDATE
Definition: winuser.h:2582
#define SW_ERASE
Definition: winuser.h:2583
int WINAPI ScrollWindowEx(_In_ HWND, _In_ int, _In_ int, _In_opt_ LPCRECT, _In_opt_ LPCRECT, _In_opt_ HRGN, _Out_opt_ LPRECT, _In_ UINT)

◆ LISTBOX_SetItemHeight()

static LRESULT LISTBOX_SetItemHeight ( LB_DESCR descr,
INT  index,
INT  height,
BOOL  repaint 
)
static

Definition at line 1198 of file listbox.c.

1199{
1200 if (height > MAXBYTE)
1201 return -1;
1202
1203 if (!height) height = 1;
1204
1205 if (descr->style & LBS_OWNERDRAWVARIABLE)
1206 {
1207 if ((index < 0) || (index >= descr->nb_items))
1208 {
1210 return LB_ERR;
1211 }
1212 TRACE("[%p]: item %d height = %d\n", descr->self, index, height );
1213 descr->items[index].height = height;
1215 if (repaint)
1217 }
1218 else if (height != descr->item_height)
1219 {
1220 TRACE("[%p]: new height = %d\n", descr->self, height );
1221 descr->item_height = height;
1224 if (repaint)
1225 InvalidateRect( descr->self, 0, TRUE );
1226 }
1227 return LB_OKAY;
1228}
#define MAXBYTE

◆ LISTBOX_SetRedraw()

static void LISTBOX_SetRedraw ( LB_DESCR descr,
BOOL  on 
)
static

Definition at line 626 of file listbox.c.

627{
628 if (on)
629 {
630 if (!(descr->style & LBS_NOREDRAW)) return;
631 descr->style &= ~LBS_NOREDRAW;
632 if (descr->style & LBS_DISPLAYCHANGED)
633 { /* page was changed while setredraw false, refresh automatically */
634 InvalidateRect(descr->self, NULL, TRUE);
635 if ((descr->top_item + descr->page_size) > descr->nb_items)
636 { /* reset top of page if less than number of items/page */
637 descr->top_item = descr->nb_items - descr->page_size;
638 if (descr->top_item < 0) descr->top_item = 0;
639 }
640 descr->style &= ~LBS_DISPLAYCHANGED;
641 }
643 }
644 else descr->style |= LBS_NOREDRAW;
645}

◆ LISTBOX_SetSelection()

static LRESULT LISTBOX_SetSelection ( LB_DESCR descr,
INT  index,
BOOL  on,
BOOL  send_notify 
)
static

Definition at line 1438 of file listbox.c.

1440{
1441 TRACE( "cur_sel=%d index=%d notify=%s\n",
1442 descr->selected_item, index, send_notify ? "YES" : "NO" );
1443
1444 if (descr->style & LBS_NOSEL)
1445 {
1446 descr->selected_item = index;
1447 return LB_ERR;
1448 }
1449 if ((index < -1) || (index >= descr->nb_items)) return LB_ERR;
1450 if (descr->style & LBS_MULTIPLESEL)
1451 {
1452 if (index == -1) /* Select all items */
1453 return LISTBOX_SelectItemRange( descr, 0, descr->nb_items, on );
1454 else /* Only one item */
1455 return LISTBOX_SelectItemRange( descr, index, index, on );
1456 }
1457 else
1458 {
1459 INT oldsel = descr->selected_item;
1460 if (index == oldsel) return LB_OKAY;
1461 if (oldsel != -1) descr->items[oldsel].selected = FALSE;
1462 if (index != -1) descr->items[index].selected = TRUE;
1463 if (oldsel != -1) LISTBOX_RepaintItem( descr, oldsel, ODA_SELECT );
1464 descr->selected_item = index;
1466 if (send_notify && descr->nb_items) SEND_NOTIFICATION( descr,
1467 (index != -1) ? LBN_SELCHANGE : LBN_SELCANCEL );
1468 else
1469 if( descr->lphc ) /* set selection change flag for parent combo */
1470 descr->lphc->wState |= CBF_SELCHANGE;
1471 }
1472 return LB_OKAY;
1473}
#define CBF_SELCHANGE
Definition: controls.h:55
static void LISTBOX_RepaintItem(LB_DESCR *descr, INT index, UINT action)
Definition: listbox.c:739
static void send_notify(HWND pager, UINT unicode, UINT ansi, LPARAM lParam, BOOL code_change)
Definition: pager.c:918
#define LBN_SELCANCEL
Definition: winuser.h:2077
#define ODA_SELECT
Definition: winuser.h:2546

◆ LISTBOX_SetTabStops()

static BOOL LISTBOX_SetTabStops ( LB_DESCR descr,
INT  count,
LPINT  tabs 
)
static

Definition at line 746 of file listbox.c.

747{
748 INT i;
749
750 if (!(descr->style & LBS_USETABSTOPS))
751 {
753 return FALSE;
754 }
755
756 HeapFree( GetProcessHeap(), 0, descr->tabs );
757 if (!(descr->nb_tabs = count))
758 {
759 descr->tabs = NULL;
760 return TRUE;
761 }
762 if (!(descr->tabs = HeapAlloc( GetProcessHeap(), 0,
763 descr->nb_tabs * sizeof(INT) )))
764 return FALSE;
765 memcpy( descr->tabs, tabs, descr->nb_tabs * sizeof(INT) );
766
767 /* convert into "dialog units"*/
768 for (i = 0; i < descr->nb_tabs; i++)
769 descr->tabs[i] = MulDiv(descr->tabs[i], descr->avg_char_width, 4);
770
771 return TRUE;
772}
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
#define ERROR_LB_WITHOUT_TABSTOPS
Definition: winerror.h:915

◆ LISTBOX_SetTopItem()

static LRESULT LISTBOX_SetTopItem ( LB_DESCR descr,
INT  index,
BOOL  scroll 
)
static

Definition at line 292 of file listbox.c.

293{
295
296 TRACE("setting top item %d, scroll %d\n", index, scroll);
297
298 if (index > max) index = max;
299 if (index < 0) index = 0;
300 if (descr->style & LBS_MULTICOLUMN) index -= index % descr->page_size;
301 if (descr->top_item == index) return LB_OKAY;
302 if (scroll)
303 {
304 INT diff;
305 if (descr->style & LBS_MULTICOLUMN)
306 diff = (descr->top_item - index) / descr->page_size * descr->column_width;
307 else if (descr->style & LBS_OWNERDRAWVARIABLE)
308 {
309 INT i;
310 diff = 0;
311 if (index > descr->top_item)
312 {
313 for (i = index - 1; i >= descr->top_item; i--)
314 diff -= descr->items[i].height;
315 }
316 else
317 {
318 for (i = index; i < descr->top_item; i++)
319 diff += descr->items[i].height;
320 }
321 }
322 else
323 diff = (descr->top_item - index) * descr->item_height;
324
325#ifdef __REACTOS__
326 if (descr->style & LBS_MULTICOLUMN)
327 ScrollWindowEx(descr->self, diff, 0, NULL, NULL, 0, NULL,
329 else
330#endif
331 ScrollWindowEx( descr->self, 0, diff, NULL, NULL, 0, NULL,
333 }
334 else
335 InvalidateRect( descr->self, NULL, TRUE );
336 descr->top_item = index;
338 return LB_OKAY;
339}
static INT LISTBOX_GetMaxTopIndex(const LB_DESCR *descr)
Definition: listbox.c:271
if(dx< 0)
Definition: linetemp.h:194

◆ LISTBOX_update_uistate()

static BOOL LISTBOX_update_uistate ( LB_DESCR descr)
static

Definition at line 2498 of file listbox.c.

2499{
2500 LONG prev_flags;
2501
2502 prev_flags = descr->UIState;
2503 descr->UIState = DefWindowProcW(descr->self, WM_QUERYUISTATE, 0, 0);
2504 return prev_flags != descr->UIState;
2505}
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)

Referenced by LISTBOX_Create(), and ListBoxWndProc_common().

◆ LISTBOX_UpdatePage()

static void LISTBOX_UpdatePage ( LB_DESCR descr)
static

Definition at line 348 of file listbox.c.

349{
351
352 if ((descr->item_height == 0) || (page_size = descr->height / descr->item_height) < 1)
353 page_size = 1;
354 if (page_size == descr->page_size) return;
355 descr->page_size = page_size;
356 if (descr->style & LBS_MULTICOLUMN)
357 InvalidateRect( descr->self, NULL, TRUE );
358 LISTBOX_SetTopItem( descr, descr->top_item, FALSE );
359}
static DWORD page_size
Definition: loader.c:53

◆ LISTBOX_UpdateScroll()

static void LISTBOX_UpdateScroll ( LB_DESCR descr)
static

Definition at line 209 of file listbox.c.

210{
212
213 /* Check the listbox scroll bar flags individually before we call
214 SetScrollInfo otherwise when the listbox style is WS_HSCROLL and
215 no WS_VSCROLL, we end up with an uninitialized, visible horizontal
216 scroll bar when we do not need one.
217 if (!(descr->style & WS_VSCROLL)) return;
218 */
219
220 /* It is important that we check descr->style, and not wnd->dwStyle,
221 for WS_VSCROLL, as the former is exactly the one passed in
222 argument to CreateWindow.
223 In Windows (and from now on in Wine :) a listbox created
224 with such a style (no WS_SCROLL) does not update
225 the scrollbar with listbox-related data, thus letting
226 the programmer use it for his/her own purposes. */
227
228 if (descr->style & LBS_NOREDRAW) return;
229 info.cbSize = sizeof(info);
230
231 if (descr->style & LBS_MULTICOLUMN)
232 {
233 info.nMin = 0;
234 info.nMax = (descr->nb_items - 1) / descr->page_size;
235 info.nPos = descr->top_item / descr->page_size;
236 info.nPage = descr->width / descr->column_width;
237 if (info.nPage < 1) info.nPage = 1;
238 info.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
239 if (descr->style & LBS_DISABLENOSCROLL)
240 info.fMask |= SIF_DISABLENOSCROLL;
241 if (descr->style & WS_HSCROLL)
242 SetScrollInfo( descr->self, SB_HORZ, &info, TRUE );
243 info.nMax = 0;
244 info.fMask = SIF_RANGE;
245 if (descr->style & WS_VSCROLL)
246 SetScrollInfo( descr->self, SB_VERT, &info, TRUE );
247 }
248 else
249 {
250 info.nMin = 0;
251 info.nMax = descr->nb_items - 1;
252 info.nPos = descr->top_item;
254 info.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
255 if (descr->style & LBS_DISABLENOSCROLL)
256 info.fMask |= SIF_DISABLENOSCROLL;
257 if (descr->style & WS_VSCROLL)
258 SetScrollInfo( descr->self, SB_VERT, &info, TRUE );
259
260 if ((descr->style & WS_HSCROLL) && descr->horz_extent)
261 {
262 info.nPos = descr->horz_pos;
263 info.nPage = descr->width;
264 info.fMask = SIF_POS | SIF_PAGE;
265 if (descr->style & LBS_DISABLENOSCROLL)
266 info.fMask |= SIF_DISABLENOSCROLL;
267 SetScrollInfo( descr->self, SB_HORZ, &info, TRUE );
268 }
269 else
270 {
271 if (descr->style & LBS_DISABLENOSCROLL)
272 {
273 info.nMin = 0;
274 info.nMax = 0;
276 SetScrollInfo( descr->self, SB_HORZ, &info, TRUE );
277 }
278 else
279 {
280 ShowScrollBar( descr->self, SB_HORZ, FALSE );
281 }
282 }
283 }
284}
#define SIF_PAGE
Definition: winuser.h:1236
#define SIF_POS
Definition: winuser.h:1237
BOOL WINAPI ShowScrollBar(_In_ HWND, _In_ int, _In_ BOOL)

◆ LISTBOX_UpdateSize()

static void LISTBOX_UpdateSize ( LB_DESCR descr)
static

Definition at line 368 of file listbox.c.

369{
370 RECT rect;
372
373 GetClientRect( descr->self, &rect );
374 if (style & WS_HSCROLL)
376 descr->width = rect.right - rect.left;
377 descr->height = rect.bottom - rect.top;
378 if (!(descr->style & LBS_NOINTEGRALHEIGHT) && !(descr->style & LBS_OWNERDRAWVARIABLE))
379 {
380 INT remaining;
381 RECT rect;
382
383 GetWindowRect( descr->self, &rect );
384 if(descr->item_height != 0)
385 remaining = descr->height % descr->item_height;
386 else
387 remaining = 0;
388 if ((descr->height > descr->item_height) && remaining)
389 {
390 TRACE("[%p]: changing height %d -> %d\n",
391 descr->self, descr->height, descr->height - remaining );
392 SetWindowPos( descr->self, 0, 0, 0, rect.right - rect.left,
393 rect.bottom - rect.top - remaining,
395 return;
396 }
397 }
398 TRACE("[%p]: new size = %d,%d\n", descr->self, descr->width, descr->height );
401
402 /* Invalidate the focused item so it will be repainted correctly */
403 if (LISTBOX_GetItemRect( descr, descr->focus_item, &rect ) == 1)
404 {
405 InvalidateRect( descr->self, &rect, FALSE );
406 }
407}
#define SWP_NOACTIVATE
Definition: winuser.h:1245
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define SWP_NOMOVE
Definition: winuser.h:1247
#define SWP_NOZORDER
Definition: winuser.h:1250

◆ ListBoxWndProc_common()

LRESULT WINAPI ListBoxWndProc_common ( HWND  hwnd,
UINT  msg,
WPARAM  wParam,
LPARAM  lParam,
BOOL  unicode 
)

Definition at line 2614 of file listbox.c.

2616{
2618 LPHEADCOMBO lphc = 0;
2619 LRESULT ret;
2620#ifdef __REACTOS__
2621 PWND pWnd;
2622
2623 pWnd = ValidateHwnd(hwnd);
2624 if (pWnd)
2625 {
2626 if (!pWnd->fnid)
2627 {
2628 NtUserSetWindowFNID(hwnd, FNID_LISTBOX); // Could be FNID_COMBOLBOX by class.
2629 }
2630 else
2631 {
2632 if (pWnd->fnid != FNID_LISTBOX)
2633 {
2634 ERR("Wrong window class for listbox! fnId 0x%x\n",pWnd->fnid);
2635 return 0;
2636 }
2637 }
2638 }
2639#endif
2640
2641 if (!descr)
2642 {
2643 if (!IsWindow(hwnd)) return 0;
2644
2645 if (msg == WM_CREATE)
2646 {
2648 if (lpcs->style & LBS_COMBOBOX) lphc = lpcs->lpCreateParams;
2649 if (!LISTBOX_Create( hwnd, lphc )) return -1;
2650 TRACE("creating hwnd %p descr %p\n", hwnd, (void *)GetWindowLongPtrW( hwnd, 0 ) );
2651 return 0;
2652 }
2653 /* Ignore all other messages before we get a WM_CREATE */
2654 return unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) :
2656 }
2657 if (descr->style & LBS_COMBOBOX) lphc = descr->lphc;
2658
2659 TRACE("[%p]: msg %s wp %08lx lp %08lx\n",
2660 descr->self, SPY_GetMsgName(msg, descr->self), wParam, lParam );
2661
2662 switch(msg)
2663 {
2664 case LB_RESETCONTENT:
2667 InvalidateRect( descr->self, NULL, TRUE );
2668 return 0;
2669
2670 case LB_ADDSTRING:
2671#ifdef __REACTOS__
2672 case LB_ADDSTRING_LOWER:
2673 case LB_ADDSTRING_UPPER:
2674#endif
2675 {
2676 INT ret;
2677 LPWSTR textW;
2678 if(unicode || !HAS_STRINGS(descr))
2679 textW = (LPWSTR)lParam;
2680 else
2681 {
2683 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
2684 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
2685 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
2686 else
2687 return LB_ERRSPACE;
2688 }
2689#ifdef __REACTOS__
2690 /* in the unicode the version, the string is really overwritten
2691 during the converting case */
2692 if (msg == LB_ADDSTRING_LOWER)
2693 strlwrW(textW);
2694 else if (msg == LB_ADDSTRING_UPPER)
2695 struprW(textW);
2696#endif
2699 if (!unicode && HAS_STRINGS(descr))
2701 return ret;
2702 }
2703
2704 case LB_INSERTSTRING:
2705#ifdef __REACTOS__
2708#endif
2709 {
2710 INT ret;
2711 LPWSTR textW;
2712 if(unicode || !HAS_STRINGS(descr))
2713 textW = (LPWSTR)lParam;
2714 else
2715 {
2717 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
2718 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
2719 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
2720 else
2721 return LB_ERRSPACE;
2722 }
2723#ifdef __REACTOS__
2724 /* in the unicode the version, the string is really overwritten
2725 during the converting case */
2727 strlwrW(textW);
2728 else if (msg == LB_INSERTSTRING_UPPER)
2729 struprW(textW);
2730#endif
2732 if(!unicode && HAS_STRINGS(descr))
2734 return ret;
2735 }
2736
2737 case LB_ADDFILE:
2738 {
2739 INT ret;
2740 LPWSTR textW;
2741 if(unicode || !HAS_STRINGS(descr))
2742 textW = (LPWSTR)lParam;
2743 else
2744 {
2746 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
2747 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
2748 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
2749 else
2750 return LB_ERRSPACE;
2751 }
2754 if(!unicode && HAS_STRINGS(descr))
2756 return ret;
2757 }
2758
2759 case LB_DELETESTRING:
2761 return descr->nb_items;
2762 else
2763 {
2765 return LB_ERR;
2766 }
2767
2768 case LB_GETITEMDATA:
2769 if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
2770 {
2772 return LB_ERR;
2773 }
2774 return descr->items[wParam].data;
2775
2776 case LB_SETITEMDATA:
2777 if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
2778 {
2780 return LB_ERR;
2781 }
2782 descr->items[wParam].data = lParam;
2783 /* undocumented: returns TRUE, not LB_OKAY (0) */
2784 return TRUE;
2785
2786 case LB_GETCOUNT:
2787 return descr->nb_items;
2788
2789 case LB_GETTEXT:
2790 return LISTBOX_GetText( descr, wParam, (LPWSTR)lParam, unicode );
2791
2792 case LB_GETTEXTLEN:
2793 if ((INT)wParam >= descr->nb_items || (INT)wParam < 0)
2794 {
2796 return LB_ERR;
2797 }
2798 if (!HAS_STRINGS(descr)) return sizeof(DWORD);
2799 if (unicode) return strlenW( descr->items[wParam].str );
2800 return WideCharToMultiByte( CP_ACP, 0, descr->items[wParam].str,
2801 strlenW(descr->items[wParam].str), NULL, 0, NULL, NULL );
2802
2803 case LB_GETCURSEL:
2804 if (descr->nb_items == 0)
2805 return LB_ERR;
2806 if (!IS_MULTISELECT(descr))
2807 return descr->selected_item;
2808 if (descr->selected_item != -1)
2809 return descr->selected_item;
2810 return descr->focus_item;
2811 /* otherwise, if the user tries to move the selection with the */
2812 /* arrow keys, we will give the application something to choke on */
2813 case LB_GETTOPINDEX:
2814 return descr->top_item;
2815
2816 case LB_GETITEMHEIGHT:
2818
2819 case LB_SETITEMHEIGHT:
2821
2822 case LB_ITEMFROMPOINT:
2823 {
2824 POINT pt;
2825 RECT rect;
2826 int index;
2827 BOOL hit = TRUE;
2828
2829 /* The hiword of the return value is not a client area
2830 hittest as suggested by MSDN, but rather a hittest on
2831 the returned listbox item. */
2832
2833 if(descr->nb_items == 0)
2834 return 0x1ffff; /* win9x returns 0x10000, we copy winnt */
2835
2836 pt.x = (short)LOWORD(lParam);
2837 pt.y = (short)HIWORD(lParam);
2838
2839 SetRect(&rect, 0, 0, descr->width, descr->height);
2840
2841 if(!PtInRect(&rect, pt))
2842 {
2843 pt.x = min(pt.x, rect.right - 1);
2844 pt.x = max(pt.x, 0);
2845 pt.y = min(pt.y, rect.bottom - 1);
2846 pt.y = max(pt.y, 0);
2847 hit = FALSE;
2848 }
2849
2851
2852 if(index == -1)
2853 {
2854 index = descr->nb_items - 1;
2855 hit = FALSE;
2856 }
2857 return MAKELONG(index, hit ? 0 : 1);
2858 }
2859
2860 case LB_SETCARETINDEX:
2861 if ((!IS_MULTISELECT(descr)) && (descr->selected_item != -1)) return LB_ERR;
2863 return LB_ERR;
2864 else if (ISWIN31)
2865 return wParam;
2866 else
2867 return LB_OKAY;
2868
2869 case LB_GETCARETINDEX:
2870 return descr->focus_item;
2871
2872 case LB_SETTOPINDEX:
2873 return LISTBOX_SetTopItem( descr, wParam, TRUE );
2874
2875 case LB_SETCOLUMNWIDTH:
2877
2878 case LB_GETITEMRECT:
2880
2881 case LB_FINDSTRING:
2882 {
2883 INT ret;
2884 LPWSTR textW;
2885 if(unicode || !HAS_STRINGS(descr))
2886 textW = (LPWSTR)lParam;
2887 else
2888 {
2890 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
2891 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
2892 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
2893 }
2895 if(!unicode && HAS_STRINGS(descr))
2897 return ret;
2898 }
2899
2900 case LB_FINDSTRINGEXACT:
2901 {
2902 INT ret;
2903 LPWSTR textW;
2904 if(unicode || !HAS_STRINGS(descr))
2905 textW = (LPWSTR)lParam;
2906 else
2907 {
2909 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
2910 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
2911 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
2912 }
2914 if(!unicode && HAS_STRINGS(descr))
2916 return ret;
2917 }
2918
2919 case LB_SELECTSTRING:
2920 {
2921 INT index;
2922 LPWSTR textW;
2923
2924 if(HAS_STRINGS(descr))
2925 TRACE("LB_SELECTSTRING: %s\n", unicode ? debugstr_w((LPWSTR)lParam) :
2927 if(unicode || !HAS_STRINGS(descr))
2928 textW = (LPWSTR)lParam;
2929 else
2930 {
2932 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
2933 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
2934 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
2935 }
2937 if(!unicode && HAS_STRINGS(descr))
2939 if (index != LB_ERR)
2940 {
2943 }
2944 return index;
2945 }
2946
2947 case LB_GETSEL:
2948 if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
2949 return LB_ERR;
2950 return descr->items[wParam].selected;
2951
2952 case LB_SETSEL:
2954
2955 case LB_SETCURSEL:
2956 if (IS_MULTISELECT(descr)) return LB_ERR;
2959 if (ret != LB_ERR) ret = descr->selected_item;
2960 return ret;
2961
2962 case LB_GETSELCOUNT:
2963 return LISTBOX_GetSelCount( descr );
2964
2965 case LB_GETSELITEMS:
2967
2968 case LB_SELITEMRANGE:
2969 if (LOWORD(lParam) <= HIWORD(lParam))
2971 HIWORD(lParam), wParam );
2972 else
2974 LOWORD(lParam), wParam );
2975
2976 case LB_SELITEMRANGEEX:
2977 if ((INT)lParam >= (INT)wParam)
2979 else
2981
2983 return descr->horz_extent;
2984
2987
2988 case LB_GETANCHORINDEX:
2989 return descr->anchor_item;
2990
2991 case LB_SETANCHORINDEX:
2992 if (((INT)wParam < -1) || ((INT)wParam >= descr->nb_items))
2993 {
2995 return LB_ERR;
2996 }
2997 descr->anchor_item = (INT)wParam;
2998 return LB_OKAY;
2999
3000 case LB_DIR:
3001 {
3002 INT ret;
3003 LPWSTR textW;
3004 if(unicode)
3005 textW = (LPWSTR)lParam;
3006 else
3007 {
3009 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
3010 if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
3011 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
3012 }
3014 if(!unicode)
3016 return ret;
3017 }
3018
3019 case LB_GETLOCALE:
3020 return descr->locale;
3021
3022 case LB_SETLOCALE:
3023 {
3024 LCID ret;
3026 return LB_ERR;
3027 ret = descr->locale;
3028 descr->locale = (LCID)wParam;
3029 return ret;
3030 }
3031
3032 case LB_INITSTORAGE:
3033 return LISTBOX_InitStorage( descr, wParam );
3034
3035 case LB_SETCOUNT:
3036 return LISTBOX_SetCount( descr, (INT)wParam );
3037
3038 case LB_SETTABSTOPS:
3040
3041 case LB_CARETON:
3042 if (descr->caret_on)
3043 return LB_OKAY;
3044 descr->caret_on = TRUE;
3045 if ((descr->focus_item != -1) && (descr->in_focus))
3046 LISTBOX_RepaintItem( descr, descr->focus_item, ODA_FOCUS );
3047 return LB_OKAY;
3048
3049 case LB_CARETOFF:
3050 if (!descr->caret_on)
3051 return LB_OKAY;
3052 descr->caret_on = FALSE;
3053 if ((descr->focus_item != -1) && (descr->in_focus))
3054 LISTBOX_RepaintItem( descr, descr->focus_item, ODA_FOCUS );
3055 return LB_OKAY;
3056
3057 case LB_GETLISTBOXINFO:
3058 return descr->page_size;
3059
3060 case WM_DESTROY:
3061 return LISTBOX_Destroy( descr );
3062
3063 case WM_ENABLE:
3064 InvalidateRect( descr->self, NULL, TRUE );
3065 return 0;
3066
3067 case WM_SETREDRAW:
3069 return 0;
3070
3071 case WM_GETDLGCODE:
3073
3074 case WM_PRINTCLIENT:
3075 case WM_PAINT:
3076 {
3077 PAINTSTRUCT ps;
3078 HDC hdc = ( wParam ) ? ((HDC)wParam) : BeginPaint( descr->self, &ps );
3079 ret = LISTBOX_Paint( descr, hdc );
3080 if( !wParam ) EndPaint( descr->self, &ps );
3081 }
3082 return ret;
3083 case WM_SIZE:
3085 return 0;
3086 case WM_GETFONT:
3087 return (LRESULT)descr->font;
3088 case WM_SETFONT:
3090 if (lParam) InvalidateRect( descr->self, 0, TRUE );
3091 return 0;
3092 case WM_SETFOCUS:
3093 descr->in_focus = TRUE;
3094 descr->caret_on = TRUE;
3095 if (descr->focus_item != -1)
3098 return 0;
3099 case WM_KILLFOCUS:
3100 LISTBOX_HandleLButtonUp( descr ); /* Release capture if we have it */
3101 descr->in_focus = FALSE;
3102 descr->wheel_remain = 0;
3103 if ((descr->focus_item != -1) && descr->caret_on)
3104 LISTBOX_RepaintItem( descr, descr->focus_item, ODA_FOCUS );
3106 return 0;
3107 case WM_HSCROLL:
3109 case WM_VSCROLL:
3111 case WM_MOUSEWHEEL: