ReactOS 0.4.15-dev-8191-gbc6c731
listbox.c File Reference
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "commctrl.h"
#include "uxtheme.h"
#include "vssym32.h"
#include "wine/unicode.h"
#include "wine/exception.h"
#include "wine/debug.h"
#include "comctl32.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 (listbox2)
 
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_NCPaint (LB_DESCR *descr, HRGN region)
 
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_Create (HWND hwnd, LPHEADCOMBO lphc)
 
static BOOL LISTBOX_Destroy (LB_DESCR *descr)
 
static LRESULT CALLBACK LISTBOX_WindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 
void LISTBOX_Register (void)
 
void COMBOLBOX_Register (void)
 

Variables

static TIMER_DIRECTION LISTBOX_Timer = LB_TIMER_NONE
 

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 100 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 104 of file listbox.c.

◆ IS_OWNERDRAW

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

Definition at line 97 of file listbox.c.

◆ ISWIN31

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

Definition at line 112 of file listbox.c.

◆ LB_ARRAY_GRANULARITY

#define LB_ARRAY_GRANULARITY   16

Definition at line 45 of file listbox.c.

◆ LB_SCROLL_TIMEOUT

#define LB_SCROLL_TIMEOUT   50

Definition at line 48 of file listbox.c.

◆ LB_TIMER_ID

#define LB_TIMER_ID   2

Definition at line 51 of file listbox.c.

◆ LBS_DISPLAYCHANGED

#define LBS_DISPLAYCHANGED   0x80000000

Definition at line 54 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:4009
#define GetWindowLongPtrW
Definition: winuser.h:4829
#define WM_COMMAND
Definition: winuser.h:1740
#define GWLP_ID
Definition: winuser.h:860
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)

Definition at line 108 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 115 of file listbox.c.

116{
TIMER_DIRECTION
Definition: listbox.c:116
@ LB_TIMER_NONE
Definition: listbox.c:117
@ LB_TIMER_UP
Definition: listbox.c:118
@ LB_TIMER_RIGHT
Definition: listbox.c:121
@ LB_TIMER_DOWN
Definition: listbox.c:120
@ LB_TIMER_LEFT
Definition: listbox.c:119

Function Documentation

◆ COMBOLBOX_Register()

void COMBOLBOX_Register ( void  )

Definition at line 3069 of file listbox.c.

3070{
3071 static const WCHAR combolboxW[] = {'C','o','m','b','o','L','B','o','x',0};
3072 WNDCLASSW wndClass;
3073
3074 memset(&wndClass, 0, sizeof(wndClass));
3077 wndClass.cbClsExtra = 0;
3078 wndClass.cbWndExtra = sizeof(LB_DESCR *);
3079 wndClass.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
3080 wndClass.hbrBackground = NULL;
3081 wndClass.lpszClassName = combolboxW;
3082 RegisterClassW(&wndClass);
3083}
#define NULL
Definition: types.h:112
static LRESULT CALLBACK LISTBOX_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: listbox.c:2570
#define memset(x, y, z)
Definition: compat.h:39
LPCWSTR lpszClassName
Definition: winuser.h:3185
HBRUSH hbrBackground
Definition: winuser.h:3183
int cbClsExtra
Definition: winuser.h:3178
UINT style
Definition: winuser.h:3176
WNDPROC lpfnWndProc
Definition: winuser.h:3177
int cbWndExtra
Definition: winuser.h:3179
HCURSOR hCursor
Definition: winuser.h:3182
static const WCHAR combolboxW[]
Definition: listbox.c:141
#define CS_DROPSHADOW
Definition: winuser.h:660
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
#define IDC_ARROW
Definition: winuser.h:687
#define CS_DBLCLKS
Definition: winuser.h:651
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2136
#define CS_GLOBALCLASS
Definition: winuser.h:652
#define CS_SAVEBITS
Definition: winuser.h:657
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by DllMain().

◆ LISTBOX_Create()

static BOOL LISTBOX_Create ( HWND  hwnd,
LPHEADCOMBO  lphc 
)
static

Definition at line 2473 of file listbox.c.

2474{
2475 LB_DESCR *descr;
2477 RECT rect;
2478
2479 if (!(descr = HeapAlloc( GetProcessHeap(), 0, sizeof(*descr) )))
2480 return FALSE;
2481
2482 GetClientRect( hwnd, &rect );
2483 descr->self = hwnd;
2484 descr->owner = GetParent( descr->self );
2485 descr->style = GetWindowLongW( descr->self, GWL_STYLE );
2486 descr->width = rect.right - rect.left;
2487 descr->height = rect.bottom - rect.top;
2488 descr->items = NULL;
2489 descr->nb_items = 0;
2490 descr->top_item = 0;
2491 descr->selected_item = -1;
2492 descr->focus_item = 0;
2493 descr->anchor_item = -1;
2494 descr->item_height = 1;
2495 descr->page_size = 1;
2496 descr->column_width = 150;
2497 descr->horz_extent = 0;
2498 descr->horz_pos = 0;
2499 descr->nb_tabs = 0;
2500 descr->tabs = NULL;
2501 descr->wheel_remain = 0;
2502 descr->caret_on = !lphc;
2503 if (descr->style & LBS_NOSEL) descr->caret_on = FALSE;
2504 descr->in_focus = FALSE;
2505 descr->captured = FALSE;
2506 descr->font = 0;
2507 descr->locale = GetUserDefaultLCID();
2508 descr->lphc = lphc;
2509
2510 if( lphc )
2511 {
2512 TRACE("[%p]: resetting owner %p -> %p\n", descr->self, descr->owner, lphc->self );
2513 descr->owner = lphc->self;
2514 }
2515
2516 SetWindowLongPtrW( descr->self, 0, (LONG_PTR)descr );
2517
2518/* if (wnd->dwExStyle & WS_EX_NOPARENTNOTIFY) descr->style &= ~LBS_NOTIFY;
2519 */
2520 if (descr->style & LBS_EXTENDEDSEL) descr->style |= LBS_MULTIPLESEL;
2521 if (descr->style & LBS_MULTICOLUMN) descr->style &= ~LBS_OWNERDRAWVARIABLE;
2522 if (descr->style & LBS_OWNERDRAWVARIABLE) descr->style |= LBS_NOINTEGRALHEIGHT;
2523 descr->item_height = LISTBOX_SetFont( descr, 0 );
2524
2525 if (descr->style & LBS_OWNERDRAWFIXED)
2526 {
2527 if( descr->lphc && (descr->lphc->dwStyle & CBS_DROPDOWN))
2528 {
2529 /* WinWord gets VERY unhappy if we send WM_MEASUREITEM from here */
2530 descr->item_height = lphc->fixedOwnerDrawHeight;
2531 }
2532 else
2533 {
2534 UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID );
2535 mis.CtlType = ODT_LISTBOX;
2536 mis.CtlID = id;
2537 mis.itemID = -1;
2538 mis.itemWidth = 0;
2539 mis.itemData = 0;
2540 mis.itemHeight = descr->item_height;
2541 SendMessageW( descr->owner, WM_MEASUREITEM, id, (LPARAM)&mis );
2542 descr->item_height = mis.itemHeight ? mis.itemHeight : 1;
2543 }
2544 }
2545
2547
2548 TRACE("owner: %p, style: %08x, width: %d, height: %d\n", descr->owner, descr->style, descr->width, descr->height);
2549 return TRUE;
2550}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static INT LISTBOX_SetFont(LB_DESCR *descr, HFONT font)
Definition: listbox.c:1285
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
LCID WINAPI GetUserDefaultLCID(void)
Definition: locale.c:1210
HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR classlist)
Definition: system.c:835
GLuint id
Definition: glext.h:5910
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define LBS_OWNERDRAWFIXED
Definition: pedump.c:682
#define LBS_MULTICOLUMN
Definition: pedump.c:687
#define LBS_OWNERDRAWVARIABLE
Definition: pedump.c:683
#define LBS_NOINTEGRALHEIGHT
Definition: pedump.c:686
#define WC_LISTBOXW
Definition: commctrl.h:4711
#define TRACE(s)
Definition: solgame.cpp:4
& rect
Definition: startmenu.cpp:1413
INT fixedOwnerDrawHeight
Definition: comctl32.h:155
HWND self
Definition: comctl32.h:144
ULONG_PTR itemData
Definition: winuser.h:3646
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define CBS_DROPDOWN
Definition: winuser.h:283
#define WM_MEASUREITEM
Definition: winuser.h:1646
HWND WINAPI GetParent(_In_ HWND)
#define SetWindowLongPtrW
Definition: winuser.h:5355
#define GWL_STYLE
Definition: winuser.h:852
#define ODT_LISTBOX
Definition: winuser.h:2538

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_DeleteItem()

static void LISTBOX_DeleteItem ( LB_DESCR descr,
INT  index 
)
static

Definition at line 1634 of file listbox.c.

1635{
1636 /* save the item data before it gets freed by LB_RESETCONTENT */
1637 ULONG_PTR item_data = descr->items[index].data;
1638 LPWSTR item_str = descr->items[index].str;
1639
1640 if (!descr->nb_items)
1641 SendMessageW( descr->self, LB_RESETCONTENT, 0, 0 );
1642
1643 /* Note: Win 3.1 only sends DELETEITEM on owner-draw items,
1644 * while Win95 sends it for all items with user data.
1645 * It's probably better to send it too often than not
1646 * often enough, so this is what we do here.
1647 */
1648 if (IS_OWNERDRAW(descr) || item_data)
1649 {
1650 DELETEITEMSTRUCT dis;
1651 UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID );
1652
1653 dis.CtlType = ODT_LISTBOX;
1654 dis.CtlID = id;
1655 dis.itemID = index;
1656 dis.hwndItem = descr->self;
1657 dis.itemData = item_data;
1658 SendMessageW( descr->owner, WM_DELETEITEM, id, (LPARAM)&dis );
1659 }
1660 if (HAS_STRINGS(descr))
1661 HeapFree( GetProcessHeap(), 0, item_str );
1662}
#define index(s, c)
Definition: various.h:29
#define HAS_STRINGS(descr)
Definition: listbox.c:100
#define IS_OWNERDRAW(descr)
Definition: listbox.c:97
#define HeapFree(x, y, z)
Definition: compat.h:735
ULONG_PTR itemData
Definition: winuser.h:3044
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define WM_DELETEITEM
Definition: winuser.h:1647
#define LB_RESETCONTENT
Definition: winuser.h:2055

Referenced by LISTBOX_RemoveItem(), and LISTBOX_ResetContent().

◆ LISTBOX_Destroy()

static BOOL LISTBOX_Destroy ( LB_DESCR descr)
static

Definition at line 2556 of file listbox.c.

2557{
2558 HTHEME theme = GetWindowTheme( descr->self );
2559 CloseThemeData( theme );
2561 SetWindowLongPtrW( descr->self, 0, 0 );
2562 HeapFree( GetProcessHeap(), 0, descr );
2563 return TRUE;
2564}
static void LISTBOX_ResetContent(LB_DESCR *descr)
Definition: listbox.c:1736
HTHEME WINAPI GetWindowTheme(HWND hwnd)
Definition: system.c:851
HRESULT WINAPI CloseThemeData(HTHEME hTheme)
Definition: system.c:950
static HTHEME(WINAPI *pOpenThemeDataEx)(HWND

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_Directory()

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

Definition at line 1786 of file listbox.c.

1788{
1789 HANDLE handle;
1792 int pos;
1793 LRESULT maxinsert = LB_ERR;
1794
1795 /* don't scan directory if we just want drives exclusively */
1796 if (attrib != (DDL_DRIVES | DDL_EXCLUSIVE)) {
1797 /* scan directory */
1798 if ((handle = FindFirstFileW(filespec, &entry)) == INVALID_HANDLE_VALUE)
1799 {
1800 int le = GetLastError();
1801 if ((le != ERROR_NO_MORE_FILES) && (le != ERROR_FILE_NOT_FOUND)) return LB_ERR;
1802 }
1803 else
1804 {
1805 do
1806 {
1807 WCHAR buffer[270];
1808 if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1809 {
1810 static const WCHAR bracketW[] = { ']',0 };
1811 static const WCHAR dotW[] = { '.',0 };
1812 if (!(attrib & DDL_DIRECTORY) ||
1813 !strcmpW( entry.cFileName, dotW )) continue;
1814 buffer[0] = '[';
1815 if (!long_names && entry.cAlternateFileName[0])
1816 strcpyW( buffer + 1, entry.cAlternateFileName );
1817 else
1818 strcpyW( buffer + 1, entry.cFileName );
1819 strcatW(buffer, bracketW);
1820 }
1821 else /* not a directory */
1822 {
1823#define ATTRIBS (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | \
1824 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE)
1825
1826 if ((attrib & DDL_EXCLUSIVE) &&
1827 ((attrib & ATTRIBS) != (entry.dwFileAttributes & ATTRIBS)))
1828 continue;
1829#undef ATTRIBS
1830 if (!long_names && entry.cAlternateFileName[0])
1831 strcpyW( buffer, entry.cAlternateFileName );
1832 else
1833 strcpyW( buffer, entry.cFileName );
1834 }
1835 if (!long_names) CharLowerW( buffer );
1837 if ((ret = LISTBOX_InsertString( descr, pos, buffer )) < 0)
1838 break;
1839 if (ret <= maxinsert) maxinsert++; else maxinsert = ret;
1840 } while (FindNextFileW( handle, &entry ));
1841 FindClose( handle );
1842 }
1843 }
1844 if (ret >= 0)
1845 {
1846 ret = maxinsert;
1847
1848 /* scan drives */
1849 if (attrib & DDL_DRIVES)
1850 {
1851 WCHAR buffer[] = {'[','-','a','-',']',0};
1852 WCHAR root[] = {'A',':','\\',0};
1853 int drive;
1854 for (drive = 0; drive < 26; drive++, buffer[2]++, root[0]++)
1855 {
1856 if (GetDriveTypeW(root) <= DRIVE_NO_ROOT_DIR) continue;
1857 if ((ret = LISTBOX_InsertString( descr, -1, buffer )) < 0)
1858 break;
1859 }
1860 }
1861 }
1862 return ret;
1863}
static LRESULT LISTBOX_InsertString(LB_DESCR *descr, INT index, LPCWSTR str)
Definition: listbox.c:1599
#define ATTRIBS
static INT LISTBOX_FindFileStrPos(LB_DESCR *descr, LPCWSTR str)
Definition: listbox.c:833
#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:2432
#define LB_OKAY
Definition: winuser.h:2431
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

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_DrawFocusRect()

static void LISTBOX_DrawFocusRect ( LB_DESCR descr,
BOOL  on 
)
static

Definition at line 646 of file listbox.c.

647{
648 HDC hdc;
649 RECT rect;
650 HFONT oldFont = 0;
651
652 /* Do not repaint the item if the item is not visible */
653 if (!IsWindowVisible(descr->self)) return;
654
655 if (descr->focus_item == -1) return;
656 if (!descr->caret_on || !descr->in_focus) return;
657
658 if (LISTBOX_GetItemRect( descr, descr->focus_item, &rect ) != 1) return;
659 if (!(hdc = GetDCEx( descr->self, 0, DCX_CACHE ))) return;
660 if (descr->font) oldFont = SelectObject( hdc, descr->font );
661 if (!IsWindowEnabled(descr->self))
663 SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
664 LISTBOX_PaintItem( descr, hdc, &rect, descr->focus_item, ODA_FOCUS, !on );
665 if (oldFont) SelectObject( hdc, oldFont );
666 ReleaseDC( descr->self, hdc );
667}
static LRESULT LISTBOX_GetItemRect(const LB_DESCR *descr, INT index, RECT *rect)
Definition: listbox.c:381
static void LISTBOX_PaintItem(LB_DESCR *descr, HDC hdc, const RECT *rect, INT index, UINT action, BOOL ignoreFocus)
Definition: listbox.c:486
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:92
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:1539
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:932
#define DCX_CACHE
Definition: winuser.h:2114
#define ODA_FOCUS
Definition: winuser.h:2544
HDC WINAPI GetDCEx(_In_opt_ HWND, _In_opt_ HRGN, _In_ DWORD)
BOOL WINAPI IsWindowEnabled(_In_ HWND)
BOOL WINAPI IsWindowVisible(_In_ HWND)

Referenced by LISTBOX_MoveCaret(), LISTBOX_SetCaretIndex(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_FindFileStrPos()

static INT LISTBOX_FindFileStrPos ( LB_DESCR descr,
LPCWSTR  str 
)
static

Definition at line 833 of file listbox.c.

834{
835 INT min, max, res;
836
837 if (!HAS_STRINGS(descr))
839 min = 0;
840 max = descr->nb_items;
841 while (min != max)
842 {
843 INT index = (min + max) / 2;
844 LPCWSTR p = descr->items[index].str;
845 if (*p == '[') /* drive or directory */
846 {
847 if (*str != '[') res = -1;
848 else if (p[1] == '-') /* drive */
849 {
850 if (str[1] == '-') res = str[2] - p[2];
851 else res = -1;
852 }
853 else /* directory */
854 {
855 if (str[1] == '-') res = 1;
856 else res = LISTBOX_lstrcmpiW( descr->locale, str, p );
857 }
858 }
859 else /* filename */
860 {
861 if (*str == '[') res = 1;
862 else res = LISTBOX_lstrcmpiW( descr->locale, str, p );
863 }
864 if (!res) return index;
865 if (res < 0) max = index;
866 else min = index + 1;
867 }
868 return max;
869}
static INT LISTBOX_FindStringPos(LB_DESCR *descr, LPCWSTR str, BOOL exact)
Definition: listbox.c:790
static INT LISTBOX_lstrcmpiW(LCID lcid, LPCWSTR str1, LPCWSTR str2)
Definition: listbox.c:772
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

Referenced by LISTBOX_Directory(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_FindString()

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

Definition at line 877 of file listbox.c.

878{
879 INT i;
881
882 if (start >= descr->nb_items) start = -1;
883 item = descr->items + start + 1;
884 if (HAS_STRINGS(descr))
885 {
886 if (!str || ! str[0] ) return LB_ERR;
887 if (exact)
888 {
889 for (i = start + 1; i < descr->nb_items; i++, item++)
890 if (!LISTBOX_lstrcmpiW( descr->locale, str, item->str )) return i;
891 for (i = 0, item = descr->items; i <= start; i++, item++)
892 if (!LISTBOX_lstrcmpiW( descr->locale, str, item->str )) return i;
893 }
894 else
895 {
896 /* Special case for drives and directories: ignore prefix */
897#define CHECK_DRIVE(item) \
898 if ((item)->str[0] == '[') \
899 { \
900 if (!strncmpiW( str, (item)->str+1, len )) return i; \
901 if (((item)->str[1] == '-') && !strncmpiW(str, (item)->str+2, len)) \
902 return i; \
903 }
904
905 INT len = strlenW(str);
906 for (i = start + 1; i < descr->nb_items; i++, item++)
907 {
908 if (!strncmpiW( str, item->str, len )) return i;
910 }
911 for (i = 0, item = descr->items; i <= start; i++, item++)
912 {
913 if (!strncmpiW( str, item->str, len )) return i;
915 }
916#undef CHECK_DRIVE
917 }
918 }
919 else
920 {
921 if (exact && (descr->style & LBS_SORT))
922 /* If sorted, use a WM_COMPAREITEM binary search */
924
925 /* Otherwise use a linear search */
926 for (i = start + 1; i < descr->nb_items; i++, item++)
927 if (item->data == (ULONG_PTR)str) return i;
928 for (i = 0, item = descr->items; i <= start; i++, item++)
929 if (item->data == (ULONG_PTR)str) return i;
930 }
931 return LB_ERR;
932}
#define CHECK_DRIVE(item)
GLuint start
Definition: gl.h:1545
#define LBS_SORT
Definition: pedump.c:679
#define strlenW(s)
Definition: unicode.h:34

Referenced by LISTBOX_HandleChar(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_FindStringPos()

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

Definition at line 790 of file listbox.c.

791{
792 INT index, min, max, res;
793
794 if (!(descr->style & LBS_SORT)) return -1; /* Add it at the end */
795 min = 0;
796 max = descr->nb_items;
797 while (min != max)
798 {
799 index = (min + max) / 2;
800 if (HAS_STRINGS(descr))
801 res = LISTBOX_lstrcmpiW( descr->locale, str, descr->items[index].str);
802 else
803 {
805 UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID );
806
807 cis.CtlType = ODT_LISTBOX;
808 cis.CtlID = id;
809 cis.hwndItem = descr->self;
810 /* note that some application (MetaStock) expects the second item
811 * to be in the listbox */
812 cis.itemID1 = -1;
813 cis.itemData1 = (ULONG_PTR)str;
814 cis.itemID2 = index;
815 cis.itemData2 = descr->items[index].data;
816 cis.dwLocaleId = descr->locale;
817 res = SendMessageW( descr->owner, WM_COMPAREITEM, id, (LPARAM)&cis );
818 }
819 if (!res) return index;
820 if (res < 0) max = index;
821 else min = index + 1;
822 }
823 return exact ? -1 : max;
824}
#define ULONG_PTR
Definition: config.h:101
ULONG_PTR itemData1
Definition: winuser.h:2994
ULONG_PTR itemData2
Definition: winuser.h:2996
#define WM_COMPAREITEM
Definition: winuser.h:1655

Referenced by LISTBOX_FindFileStrPos(), LISTBOX_FindString(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_GetCurrentPageSize()

static INT LISTBOX_GetCurrentPageSize ( const LB_DESCR descr)
static

Definition at line 133 of file listbox.c.

134{
135 INT i, height;
136 if (!(descr->style & LBS_OWNERDRAWVARIABLE)) return descr->page_size;
137 for (i = descr->top_item, height = 0; i < descr->nb_items; i++)
138 {
139 if ((height += descr->items[i].height) > descr->height) break;
140 }
141 if (i == descr->top_item) return 1;
142 else return i - descr->top_item;
143}
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546

Referenced by LISTBOX_HandleKeyDown(), LISTBOX_HandleTimer(), LISTBOX_HandleVScroll(), and LISTBOX_UpdateScroll().

◆ LISTBOX_GetItemFromPoint()

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

Definition at line 439 of file listbox.c.

440{
441 INT index = descr->top_item;
442
443 if (!descr->nb_items) return -1; /* No items */
444 if (descr->style & LBS_OWNERDRAWVARIABLE)
445 {
446 INT pos = 0;
447 if (y >= 0)
448 {
449 while (index < descr->nb_items)
450 {
451 if ((pos += descr->items[index].height) > y) break;
452 index++;
453 }
454 }
455 else
456 {
457 while (index > 0)
458 {
459 index--;
460 if ((pos -= descr->items[index].height) <= y) break;
461 }
462 }
463 }
464 else if (descr->style & LBS_MULTICOLUMN)
465 {
466 if (y >= descr->item_height * descr->page_size) return -1;
467 if (y >= 0) index += y / descr->item_height;
468 if (x >= 0) index += (x / descr->column_width) * descr->page_size;
469 else index -= (((x + 1) / descr->column_width) - 1) * descr->page_size;
470 }
471 else
472 {
473 index += (y / descr->item_height);
474 }
475 if (index < 0) return 0;
476 if (index >= descr->nb_items) return -1;
477 return index;
478}
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548

Referenced by LISTBOX_HandleLButtonDown(), LISTBOX_HandleMouseMove(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_GetItemHeight()

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

Definition at line 1162 of file listbox.c.

1163{
1164 if (descr->style & LBS_OWNERDRAWVARIABLE && descr->nb_items > 0)
1165 {
1166 if ((index < 0) || (index >= descr->nb_items))
1167 {
1169 return LB_ERR;
1170 }
1171 return descr->items[index].height;
1172 }
1173 else return descr->item_height;
1174}
#define SetLastError(x)
Definition: compat.h:752
#define ERROR_INVALID_INDEX
Definition: winerror.h:894

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_GetItemRect()

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

Definition at line 381 of file listbox.c.

382{
383 /* Index <= 0 is legal even on empty listboxes */
384 if (index && (index >= descr->nb_items))
385 {
388 return LB_ERR;
389 }
390 SetRect( rect, 0, 0, descr->width, descr->height );
391 if (descr->style & LBS_MULTICOLUMN)
392 {
393 INT col = (index / descr->page_size) -
394 (descr->top_item / descr->page_size);
395 rect->left += col * descr->column_width;
396 rect->right = rect->left + descr->column_width;
397 rect->top += (index % descr->page_size) * descr->item_height;
398 rect->bottom = rect->top + descr->item_height;
399 }
400 else if (descr->style & LBS_OWNERDRAWVARIABLE)
401 {
402 INT i;
403 rect->right += descr->horz_pos;
404 if ((index >= 0) && (index < descr->nb_items))
405 {
406 if (index < descr->top_item)
407 {
408 for (i = descr->top_item-1; i >= index; i--)
409 rect->top -= descr->items[i].height;
410 }
411 else
412 {
413 for (i = descr->top_item; i < index; i++)
414 rect->top += descr->items[i].height;
415 }
416 rect->bottom = rect->top + descr->items[index].height;
417
418 }
419 }
420 else
421 {
422 rect->top += (index - descr->top_item) * descr->item_height;
423 rect->bottom = rect->top + descr->item_height;
424 rect->right += descr->horz_pos;
425 }
426
427 TRACE("item %d, rect %s\n", index, wine_dbgstr_rect(rect));
428
429 return ((rect->left < descr->width) && (rect->right > 0) &&
430 (rect->top < descr->height) && (rect->bottom > 0));
431}
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)

Referenced by LISTBOX_DrawFocusRect(), LISTBOX_InvalidateItemRect(), LISTBOX_InvalidateItems(), LISTBOX_RepaintItem(), LISTBOX_SetHorizontalPos(), LISTBOX_UpdateSize(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_GetMaxTopIndex()

static INT LISTBOX_GetMaxTopIndex ( const LB_DESCR descr)
static

Definition at line 151 of file listbox.c.

152{
153 INT max, page;
154
155 if (descr->style & LBS_OWNERDRAWVARIABLE)
156 {
157 page = descr->height;
158 for (max = descr->nb_items - 1; max >= 0; max--)
159 if ((page -= descr->items[max].height) < 0) break;
160 if (max < descr->nb_items - 1) max++;
161 }
162 else if (descr->style & LBS_MULTICOLUMN)
163 {
164 if ((page = descr->width / descr->column_width) < 1) page = 1;
165 max = (descr->nb_items + descr->page_size - 1) / descr->page_size;
166 max = (max - page) * descr->page_size;
167 }
168 else
169 {
170 max = descr->nb_items - descr->page_size;
171 }
172 if (max < 0) max = 0;
173 return max;
174}
Definition: module.h:576

Referenced by LISTBOX_SetTopItem().

◆ LISTBOX_GetSelCount()

static LRESULT LISTBOX_GetSelCount ( const LB_DESCR descr)
static

Definition at line 938 of file listbox.c.

939{
940 INT i, count;
941 const LB_ITEMDATA *item = descr->items;
942
943 if (!(descr->style & LBS_MULTIPLESEL) ||
944 (descr->style & LBS_NOSEL))
945 return LB_ERR;
946 for (i = count = 0; i < descr->nb_items; i++, item++)
947 if (item->selected) count++;
948 return count;
949}
GLuint GLuint GLsizei count
Definition: gl.h:1545

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_GetSelItems()

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

Definition at line 955 of file listbox.c.

956{
957 INT i, count;
958 const LB_ITEMDATA *item = descr->items;
959
960 if (!(descr->style & LBS_MULTIPLESEL)) return LB_ERR;
961 for (i = count = 0; (i < descr->nb_items) && (count < max); i++, item++)
962 if (item->selected) array[count++] = i;
963 return count;
964}

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_GetText()

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

Definition at line 734 of file listbox.c.

735{
736 DWORD len;
737
738 if ((index < 0) || (index >= descr->nb_items))
739 {
741 return LB_ERR;
742 }
743
744 if (HAS_STRINGS(descr))
745 {
746 if (!buffer)
747 return strlenW(descr->items[index].str);
748
749 TRACE("index %d (0x%04x) %s\n", index, index, debugstr_w(descr->items[index].str));
750
751 __TRY /* hide a Delphi bug that passes a read-only buffer */
752 {
753 strcpyW( buffer, descr->items[index].str );
754 len = strlenW(buffer);
755 }
757 {
758 WARN( "got an invalid buffer (Delphi bug?)\n" );
760 return LB_ERR;
761 }
763 } else
764 {
765 if (buffer)
766 *((DWORD *)buffer) = *(DWORD *)&descr->items[index].data;
767 len = sizeof(DWORD);
768 }
769 return len;
770}
#define WARN(fmt,...)
Definition: debug.h:115
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define __TRY
Definition: compat.h:80
#define __ENDTRY
Definition: compat.h:82
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:81
unsigned long DWORD
Definition: ntddk_ex.h:95
#define debugstr_w
Definition: kernel32.h:32

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_HandleChar()

static LRESULT LISTBOX_HandleChar ( LB_DESCR descr,
WCHAR  charW 
)
static

Definition at line 2441 of file listbox.c.

2442{
2443 INT caret = -1;
2444 WCHAR str[2];
2445
2446 str[0] = charW;
2447 str[1] = '\0';
2448
2449 if (descr->style & LBS_WANTKEYBOARDINPUT)
2450 {
2451 caret = SendMessageW( descr->owner, WM_CHARTOITEM,
2452 MAKEWPARAM(charW, descr->focus_item),
2453 (LPARAM)descr->self );
2454 if (caret == -2) return 0;
2455 }
2456 if (caret == -1)
2457 caret = LISTBOX_FindString( descr, descr->focus_item, str, FALSE);
2458 if (caret != -1)
2459 {
2460 if ((!IS_MULTISELECT(descr)) && descr->selected_item == -1)
2462 LISTBOX_MoveCaret( descr, caret, TRUE );
2463 if ((descr->style & LBS_NOTIFY) && descr->nb_items)
2465 }
2466 return 0;
2467}
#define SEND_NOTIFICATION(descr, code)
Definition: listbox.c:108
static LRESULT LISTBOX_SetSelection(LB_DESCR *descr, INT index, BOOL on, BOOL send_notify)
Definition: listbox.c:1420
#define IS_MULTISELECT(descr)
Definition: listbox.c:104
static void LISTBOX_MoveCaret(LB_DESCR *descr, INT index, BOOL fully_visible)
Definition: listbox.c:1463
static INT LISTBOX_FindString(LB_DESCR *descr, INT start, LPCWSTR str, BOOL exact)
Definition: listbox.c:877
#define LBS_NOTIFY
Definition: pedump.c:678
#define LBS_WANTKEYBOARDINPUT
Definition: pedump.c:688
#define WM_CHARTOITEM
Definition: winuser.h:1649
#define LBN_SELCHANGE
Definition: winuser.h:2075

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_HandleHScroll()

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

Definition at line 1913 of file listbox.c.

1914{
1916 INT page;
1917
1918 if (descr->style & LBS_MULTICOLUMN)
1919 {
1920 switch(scrollReq)
1921 {
1922 case SB_LINELEFT:
1923 LISTBOX_SetTopItem( descr, descr->top_item-descr->page_size,
1924 TRUE );
1925 break;
1926 case SB_LINERIGHT:
1927 LISTBOX_SetTopItem( descr, descr->top_item+descr->page_size,
1928 TRUE );
1929 break;
1930 case SB_PAGELEFT:
1931 page = descr->width / descr->column_width;
1932 if (page < 1) page = 1;
1934 descr->top_item - page * descr->page_size, TRUE );
1935 break;
1936 case SB_PAGERIGHT:
1937 page = descr->width / descr->column_width;
1938 if (page < 1) page = 1;
1940 descr->top_item + page * descr->page_size, TRUE );
1941 break;
1942 case SB_THUMBPOSITION:
1943 LISTBOX_SetTopItem( descr, pos*descr->page_size, TRUE );
1944 break;
1945 case SB_THUMBTRACK:
1946 info.cbSize = sizeof(info);
1947 info.fMask = SIF_TRACKPOS;
1948 GetScrollInfo( descr->self, SB_VERT, &info );
1949 LISTBOX_SetTopItem( descr, info.nTrackPos*descr->page_size,
1950 TRUE );
1951 break;
1952 case SB_LEFT:
1954 break;
1955 case SB_RIGHT:
1956 LISTBOX_SetTopItem( descr, descr->nb_items, TRUE );
1957 break;
1958 }
1959 }
1960 else if (descr->horz_extent)
1961 {
1962 switch(scrollReq)
1963 {
1964 case SB_LINELEFT:
1965 LISTBOX_SetHorizontalPos( descr, descr->horz_pos - 1 );
1966 break;
1967 case SB_LINERIGHT:
1968 LISTBOX_SetHorizontalPos( descr, descr->horz_pos + 1 );
1969 break;
1970 case SB_PAGELEFT:
1972 descr->horz_pos - descr->width );
1973 break;
1974 case SB_PAGERIGHT:
1976 descr->horz_pos + descr->width );
1977 break;
1978 case SB_THUMBPOSITION:
1980 break;
1981 case SB_THUMBTRACK:
1982 info.cbSize = sizeof(info);
1983 info.fMask = SIF_TRACKPOS;
1984 GetScrollInfo( descr->self, SB_HORZ, &info );
1985 LISTBOX_SetHorizontalPos( descr, info.nTrackPos );
1986 break;
1987 case SB_LEFT:
1989 break;
1990 case SB_RIGHT:
1992 descr->horz_extent - descr->width );
1993 break;
1994 }
1995 }
1996 return 0;
1997}
static void LISTBOX_SetHorizontalPos(LB_DESCR *descr, INT pos)
Definition: listbox.c:1216
static LRESULT LISTBOX_SetTopItem(LB_DESCR *descr, INT index, BOOL scroll)
Definition: listbox.c:266
#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:1237
#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

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_HandleKeyDown()

static LRESULT LISTBOX_HandleKeyDown ( LB_DESCR descr,
DWORD  key 
)
static

Definition at line 2329 of file listbox.c.

2330{
2331 INT caret = -1;
2332 BOOL bForceSelection = TRUE; /* select item pointed to by focus_item */
2333 if ((IS_MULTISELECT(descr)) || (descr->selected_item == descr->focus_item))
2334 bForceSelection = FALSE; /* only for single select list */
2335
2336 if (descr->style & LBS_WANTKEYBOARDINPUT)
2337 {
2338 caret = SendMessageW( descr->owner, WM_VKEYTOITEM,
2339 MAKEWPARAM(LOWORD(key), descr->focus_item),
2340 (LPARAM)descr->self );
2341 if (caret == -2) return 0;
2342 }
2343 if (caret == -1) switch(key)
2344 {
2345 case VK_LEFT:
2346 if (descr->style & LBS_MULTICOLUMN)
2347 {
2348 bForceSelection = FALSE;
2349 if (descr->focus_item >= descr->page_size)
2350 caret = descr->focus_item - descr->page_size;
2351 break;
2352 }
2353 /* fall through */
2354 case VK_UP:
2355 caret = descr->focus_item - 1;
2356 if (caret < 0) caret = 0;
2357 break;
2358 case VK_RIGHT:
2359 if (descr->style & LBS_MULTICOLUMN)
2360 {
2361 bForceSelection = FALSE;
2362 if (descr->focus_item + descr->page_size < descr->nb_items)
2363 caret = descr->focus_item + descr->page_size;
2364 break;
2365 }
2366 /* fall through */
2367 case VK_DOWN:
2368 caret = descr->focus_item + 1;
2369 if (caret >= descr->nb_items) caret = descr->nb_items - 1;
2370 break;
2371
2372 case VK_PRIOR:
2373 if (descr->style & LBS_MULTICOLUMN)
2374 {
2375 INT page = descr->width / descr->column_width;
2376 if (page < 1) page = 1;
2377 caret = descr->focus_item - (page * descr->page_size) + 1;
2378 }
2379 else caret = descr->focus_item-LISTBOX_GetCurrentPageSize(descr) + 1;
2380 if (caret < 0) caret = 0;
2381 break;
2382 case VK_NEXT:
2383 if (descr->style & LBS_MULTICOLUMN)
2384 {
2385 INT page = descr->width / descr->column_width;
2386 if (page < 1) page = 1;
2387 caret = descr->focus_item + (page * descr->page_size) - 1;
2388 }
2389 else caret = descr->focus_item + LISTBOX_GetCurrentPageSize(descr) - 1;
2390 if (caret >= descr->nb_items) caret = descr->nb_items - 1;
2391 break;
2392 case VK_HOME:
2393 caret = 0;
2394 break;
2395 case VK_END:
2396 caret = descr->nb_items - 1;
2397 break;
2398 case VK_SPACE:
2399 if (descr->style & LBS_EXTENDEDSEL) caret = descr->focus_item;
2400 else if (descr->style & LBS_MULTIPLESEL)
2401 {
2402 LISTBOX_SetSelection( descr, descr->focus_item,
2403 !descr->items[descr->focus_item].selected,
2404 (descr->style & LBS_NOTIFY) != 0 );
2405 }
2406 break;
2407 default:
2408 bForceSelection = FALSE;
2409 }
2410 if (bForceSelection) /* focused item is used instead of key */
2411 caret = descr->focus_item;
2412 if (caret >= 0)
2413 {
2414 if (((descr->style & LBS_EXTENDEDSEL) &&
2415 !(GetKeyState( VK_SHIFT ) & 0x8000)) ||
2417 descr->anchor_item = caret;
2418 LISTBOX_MoveCaret( descr, caret, TRUE );
2419
2420 if (descr->style & LBS_MULTIPLESEL)
2421 descr->selected_item = caret;
2422 else
2424 if (descr->style & LBS_NOTIFY)
2425 {
2426 if (descr->lphc && IsWindowVisible( descr->self ))
2427 {
2428 /* make sure that combo parent doesn't hide us */
2429 descr->lphc->wState |= CBF_NOROLLUP;
2430 }
2431 if (descr->nb_items) SEND_NOTIFICATION( descr, LBN_SELCHANGE );
2432 }
2433 }
2434 return 0;
2435}
#define CBF_NOROLLUP
Definition: controls.h:47
static INT LISTBOX_GetCurrentPageSize(const LB_DESCR *descr)
Definition: listbox.c:133
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:2219
#define VK_UP
Definition: winuser.h:2225
#define VK_NEXT
Definition: winuser.h:2221
#define VK_END
Definition: winuser.h:2222
#define VK_HOME
Definition: winuser.h:2223
#define VK_LEFT
Definition: winuser.h:2224
#define VK_RIGHT
Definition: winuser.h:2226
#define VK_DOWN
Definition: winuser.h:2227
#define VK_SHIFT
Definition: winuser.h:2202
#define VK_PRIOR
Definition: winuser.h:2220
SHORT WINAPI GetKeyState(_In_ int)
#define WM_VKEYTOITEM
Definition: winuser.h:1648

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_HandleLButtonDown()

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

Definition at line 2026 of file listbox.c.

2027{
2029
2030 TRACE("[%p]: lbuttondown %d,%d item %d, focus item %d\n",
2031 descr->self, x, y, index, descr->focus_item);
2032
2033 if (!descr->caret_on && (descr->in_focus)) return 0;
2034
2035 if (!descr->in_focus)
2036 {
2037 if( !descr->lphc ) SetFocus( descr->self );
2038 else SetFocus( (descr->lphc->hWndEdit) ? descr->lphc->hWndEdit : descr->lphc->self );
2039 }
2040
2041 if (index == -1) return 0;
2042
2043 if (!descr->lphc)
2044 {
2045 if (descr->style & LBS_NOTIFY )
2047 MAKELPARAM( x, y ) );
2048 }
2049
2050 descr->captured = TRUE;
2051 SetCapture( descr->self );
2052
2053 if (descr->style & (LBS_EXTENDEDSEL | LBS_MULTIPLESEL))
2054 {
2055 /* we should perhaps make sure that all items are deselected
2056 FIXME: needed for !LBS_EXTENDEDSEL, too ?
2057 if (!(keys & (MK_SHIFT|MK_CONTROL)))
2058 LISTBOX_SetSelection( descr, -1, FALSE, FALSE);
2059 */
2060
2061 if (!(keys & MK_SHIFT)) descr->anchor_item = index;
2062 if (keys & MK_CONTROL)
2063 {
2066 !descr->items[index].selected,
2067 (descr->style & LBS_NOTIFY) != 0);
2068 }
2069 else
2070 {
2072
2073 if (descr->style & LBS_EXTENDEDSEL)
2074 {
2076 descr->items[index].selected,
2077 (descr->style & LBS_NOTIFY) != 0 );
2078 }
2079 else
2080 {
2082 !descr->items[index].selected,
2083 (descr->style & LBS_NOTIFY) != 0 );
2084 }
2085 }
2086 }
2087 else
2088 {
2089 descr->anchor_item = index;
2092 TRUE, (descr->style & LBS_NOTIFY) != 0 );
2093 }
2094
2095 if (!descr->lphc)
2096 {
2098 {
2099 POINT pt;
2100
2101 pt.x = x;
2102 pt.y = y;
2103
2104 if (DragDetect( descr->self, pt ))
2105 SendMessageW( descr->owner, WM_BEGINDRAG, 0, 0 );
2106 }
2107 }
2108 return 0;
2109}
static LRESULT LISTBOX_SetCaretIndex(LB_DESCR *descr, INT index, BOOL fully_visible)
Definition: listbox.c:1355
static INT LISTBOX_GetItemFromPoint(const LB_DESCR *descr, INT x, INT y)
Definition: listbox.c:439
#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:2369
#define MAKELPARAM(l, h)
Definition: winuser.h:4008
HWND WINAPI SetFocus(_In_opt_ HWND)
#define MK_CONTROL
Definition: winuser.h:2370
BOOL WINAPI DragDetect(_In_ HWND, _In_ POINT)
#define GWL_EXSTYLE
Definition: winuser.h:851

Referenced by LISTBOX_HandleLButtonDownCombo(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_HandleLButtonDownCombo()

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

Definition at line 2131 of file listbox.c.

2132{
2133 RECT clientRect, screenRect;
2134 POINT mousePos;
2135
2136 mousePos.x = x;
2137 mousePos.y = y;
2138
2139 GetClientRect(descr->self, &clientRect);
2140
2141 if(PtInRect(&clientRect, mousePos))
2142 {
2143 /* MousePos is in client, resume normal processing */
2144 if (msg == WM_LBUTTONDOWN)
2145 {
2146 descr->lphc->droppedIndex = descr->nb_items ? descr->selected_item : -1;
2147 return LISTBOX_HandleLButtonDown( descr, keys, x, y);
2148 }
2149 else if (descr->style & LBS_NOTIFY)
2151 }
2152 else
2153 {
2154 POINT screenMousePos;
2155 HWND hWndOldCapture;
2156
2157 /* Check the Non-Client Area */
2158 screenMousePos = mousePos;
2159 hWndOldCapture = GetCapture();
2161 GetWindowRect(descr->self, &screenRect);
2162 ClientToScreen(descr->self, &screenMousePos);
2163
2164 if(!PtInRect(&screenRect, screenMousePos))
2165 {
2166 LISTBOX_SetCaretIndex( descr, descr->lphc->droppedIndex, FALSE );
2167 LISTBOX_SetSelection( descr, descr->lphc->droppedIndex, FALSE, FALSE );
2169 }
2170 else
2171 {
2172 /* Check to see the NC is a scrollbar */
2173 INT nHitTestType=0;
2175 /* Check Vertical scroll bar */
2176 if (style & WS_VSCROLL)
2177 {
2178 clientRect.right += GetSystemMetrics(SM_CXVSCROLL);
2179 if (PtInRect( &clientRect, mousePos ))
2180 nHitTestType = HTVSCROLL;
2181 }
2182 /* Check horizontal scroll bar */
2183 if (style & WS_HSCROLL)
2184 {
2185 clientRect.bottom += GetSystemMetrics(SM_CYHSCROLL);
2186 if (PtInRect( &clientRect, mousePos ))
2187 nHitTestType = HTHSCROLL;
2188 }
2189 /* Windows sends this message when a scrollbar is clicked
2190 */
2191
2192 if(nHitTestType != 0)
2193 {
2194 SendMessageW(descr->self, WM_NCLBUTTONDOWN, nHitTestType,
2195 MAKELONG(screenMousePos.x, screenMousePos.y));
2196 }
2197 /* Resume the Capture after scrolling is complete
2198 */
2199 if(hWndOldCapture != 0)
2200 SetCapture(hWndOldCapture);
2201 }
2202 }
2203 return 0;
2204}
#define msg(x)
Definition: auth_time.c:54
BOOL COMBO_FlipListbox(LPHEADCOMBO lphc, BOOL ok, BOOL bRedrawButton)
Definition: combo.c:1116
static LRESULT LISTBOX_HandleLButtonDown(LB_DESCR *descr, DWORD keys, INT x, INT y)
Definition: listbox.c:2026
#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:2071
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define SM_CXVSCROLL
Definition: winuser.h:961
#define HTVSCROLL
Definition: winuser.h:2482
#define HTHSCROLL
Definition: winuser.h:2481
HWND WINAPI GetCapture(void)
Definition: message.c:2881
#define WM_LBUTTONDOWN
Definition: winuser.h:1776
BOOL WINAPI ClientToScreen(_In_ HWND, _Inout_ LPPOINT)
#define SM_CYHSCROLL
Definition: winuser.h:962
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
int WINAPI GetSystemMetrics(_In_ int)
#define WM_NCLBUTTONDOWN
Definition: winuser.h:1692

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_HandleLButtonUp()

static LRESULT LISTBOX_HandleLButtonUp ( LB_DESCR descr)
static

Definition at line 2209 of file listbox.c.

2210{
2214 if (descr->captured)
2215 {
2216 descr->captured = FALSE;
2217 if (GetCapture() == descr->self) ReleaseCapture();
2218 if ((descr->style & LBS_NOTIFY) && descr->nb_items)
2220 }
2221 return 0;
2222}
static TIMER_DIRECTION LISTBOX_Timer
Definition: listbox.c:124
#define LB_TIMER_ID
Definition: listbox.c:51
BOOL WINAPI KillSystemTimer(HWND, UINT_PTR)
Definition: timer.c:35

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_HandleMouseMove()

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

Definition at line 2281 of file listbox.c.

2283{
2284 INT index;
2286
2287 if (!descr->captured) return;
2288
2289 if (descr->style & LBS_MULTICOLUMN)
2290 {
2291 if (y < 0) y = 0;
2292 else if (y >= descr->item_height * descr->page_size)
2293 y = descr->item_height * descr->page_size - 1;
2294
2295 if (x < 0)
2296 {
2298 x = 0;
2299 }
2300 else if (x >= descr->width)
2301 {
2303 x = descr->width - 1;
2304 }
2305 }
2306 else
2307 {
2308 if (y < 0) dir = LB_TIMER_UP; /* above */
2309 else if (y >= descr->height) dir = LB_TIMER_DOWN; /* below */
2310 }
2311
2313 if (index == -1) index = descr->focus_item;
2315
2316 /* Start/stop the system timer */
2317
2318 if (dir != LB_TIMER_NONE)
2320 else if (LISTBOX_Timer != LB_TIMER_NONE)
2323}
unsigned int dir
Definition: maze.c:112
static LRESULT LISTBOX_HandleTimer(LB_DESCR *descr, INT index, TIMER_DIRECTION dir)
Definition: listbox.c:2231
#define LB_SCROLL_TIMEOUT
Definition: listbox.c:48
UINT_PTR WINAPI SetSystemTimer(HWND, UINT_PTR, UINT, TIMERPROC)
Definition: ntwrapper.h:106

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_HandleMouseWheel()

static LRESULT LISTBOX_HandleMouseWheel ( LB_DESCR descr,
SHORT  delta 
)
static

Definition at line 1999 of file listbox.c.

2000{
2001 UINT pulScrollLines = 3;
2002
2003 SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0);
2004
2005 /* if scrolling changes direction, ignore left overs */
2006 if ((delta < 0 && descr->wheel_remain < 0) ||
2007 (delta > 0 && descr->wheel_remain > 0))
2008 descr->wheel_remain += delta;
2009 else
2010 descr->wheel_remain = delta;
2011
2012 if (descr->wheel_remain && pulScrollLines)
2013 {
2014 int cLineScroll;
2015 pulScrollLines = min((UINT) descr->page_size, pulScrollLines);
2016 cLineScroll = pulScrollLines * (float)descr->wheel_remain / WHEEL_DELTA;
2017 descr->wheel_remain -= WHEEL_DELTA * cLineScroll / (int)pulScrollLines;
2018 LISTBOX_SetTopItem( descr, descr->top_item - cLineScroll, TRUE );
2019 }
2020 return 0;
2021}
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)

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_HandleSystemTimer()

static LRESULT LISTBOX_HandleSystemTimer ( LB_DESCR descr)
static

Definition at line 2265 of file listbox.c.

2266{
2267 if (!LISTBOX_HandleTimer( descr, descr->focus_item, LISTBOX_Timer ))
2268 {
2271 }
2272 return 0;
2273}

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_HandleTimer()

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

Definition at line 2231 of file listbox.c.

2232{
2233 switch(dir)
2234 {
2235 case LB_TIMER_UP:
2236 if (descr->top_item) index = descr->top_item - 1;
2237 else index = 0;
2238 break;
2239 case LB_TIMER_LEFT:
2240 if (descr->top_item) index -= descr->page_size;
2241 break;
2242 case LB_TIMER_DOWN:
2244 if (index == descr->focus_item) index++;
2245 if (index >= descr->nb_items) index = descr->nb_items - 1;
2246 break;
2247 case LB_TIMER_RIGHT:
2248 if (index + descr->page_size < descr->nb_items)
2249 index += descr->page_size;
2250 break;
2251 case LB_TIMER_NONE:
2252 break;
2253 }
2254 if (index == descr->focus_item) return FALSE;
2256 return TRUE;
2257}

Referenced by LISTBOX_HandleMouseMove(), and LISTBOX_HandleSystemTimer().

◆ LISTBOX_HandleVScroll()

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

Definition at line 1869 of file listbox.c.

1870{
1872
1873 if (descr->style & LBS_MULTICOLUMN) return 0;
1874 switch(scrollReq)
1875 {
1876 case SB_LINEUP:
1877 LISTBOX_SetTopItem( descr, descr->top_item - 1, TRUE );
1878 break;
1879 case SB_LINEDOWN:
1880 LISTBOX_SetTopItem( descr, descr->top_item + 1, TRUE );
1881 break;
1882 case SB_PAGEUP:
1883 LISTBOX_SetTopItem( descr, descr->top_item -
1885 break;
1886 case SB_PAGEDOWN:
1887 LISTBOX_SetTopItem( descr, descr->top_item +
1889 break;
1890 case SB_THUMBPOSITION:
1892 break;
1893 case SB_THUMBTRACK:
1894 info.cbSize = sizeof(info);
1895 info.fMask = SIF_TRACKPOS;
1896 GetScrollInfo( descr->self, SB_VERT, &info );
1897 LISTBOX_SetTopItem( descr, info.nTrackPos, TRUE );
1898 break;
1899 case SB_TOP:
1901 break;
1902 case SB_BOTTOM:
1903 LISTBOX_SetTopItem( descr, descr->nb_items, TRUE );
1904 break;
1905 }
1906 return 0;
1907}
#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

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_InitStorage()

static LRESULT LISTBOX_InitStorage ( LB_DESCR descr,
INT  nb_items 
)
static

Definition at line 673 of file listbox.c.

674{
676
677 nb_items += LB_ARRAY_GRANULARITY - 1;
678 nb_items -= (nb_items % LB_ARRAY_GRANULARITY);
679 if (descr->items) {
680 nb_items += HeapSize( GetProcessHeap(), 0, descr->items ) / sizeof(*item);
681 item = HeapReAlloc( GetProcessHeap(), 0, descr->items,
682 nb_items * sizeof(LB_ITEMDATA));
683 }
684 else {
686 nb_items * sizeof(LB_ITEMDATA));
687 }
688
689 if (!item)
690 {
692 return LB_ERRSPACE;
693 }
694 descr->items = item;
695 return LB_OKAY;
696}
#define LB_ARRAY_GRANULARITY
Definition: listbox.c:45
#define HeapReAlloc
Definition: compat.h:734
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
#define LBN_ERRSPACE
Definition: winuser.h:2072
#define LB_ERRSPACE
Definition: winuser.h:2433

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_InsertItem()

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

Definition at line 1510 of file listbox.c.

1512{
1514 INT max_items;
1515 INT oldfocus = descr->focus_item;
1516
1517 if (index == -1) index = descr->nb_items;
1518 else if ((index < 0) || (index > descr->nb_items)) return LB_ERR;
1519 if (!descr->items) max_items = 0;
1520 else max_items = HeapSize( GetProcessHeap(), 0, descr->items ) / sizeof(*item);
1521 if (descr->nb_items == max_items)
1522 {
1523 /* We need to grow the array */
1524 max_items += LB_ARRAY_GRANULARITY;
1525 if (descr->items)
1526 item = HeapReAlloc( GetProcessHeap(), 0, descr->items,
1527 max_items * sizeof(LB_ITEMDATA) );
1528 else
1530 max_items * sizeof(LB_ITEMDATA) );
1531 if (!item)
1532 {
1534 return LB_ERRSPACE;
1535 }
1536 descr->items = item;
1537 }
1538
1539 /* Insert the item structure */
1540
1541 item = &descr->items[index];
1542 if (index < descr->nb_items)
1543 RtlMoveMemory( item + 1, item,
1544 (descr->nb_items - index) * sizeof(LB_ITEMDATA) );
1545 item->str = str;
1546 item->data = HAS_STRINGS(descr) ? 0 : data;
1547 item->height = 0;
1548 item->selected = FALSE;
1549 descr->nb_items++;
1550
1551 /* Get item height */
1552
1553 if (descr->style & LBS_OWNERDRAWVARIABLE)
1554 {
1556 UINT id = (UINT)GetWindowLongPtrW( descr->self, GWLP_ID );
1557
1558 mis.CtlType = ODT_LISTBOX;
1559 mis.CtlID = id;
1560 mis.itemID = index;
1561 mis.itemData = data;
1562 mis.itemHeight = descr->item_height;
1563 SendMessageW( descr->owner, WM_MEASUREITEM, id, (LPARAM)&mis );
1564 item->height = mis.itemHeight ? mis.itemHeight : 1;
1565 TRACE("[%p]: measure item %d (%s) = %d\n",
1566 descr->self, index, str ? debugstr_w(str) : "", item->height );
1567 }
1568
1569 /* Repaint the items */
1570
1573
1574 /* Move selection and focused item */
1575 /* If listbox was empty, set focus to the first item */
1576 if (descr->nb_items == 1)
1578 /* single select don't change selection index in win31 */
1579 else if ((ISWIN31) && !(IS_MULTISELECT(descr)))
1580 {
1581 descr->selected_item++;
1582 LISTBOX_SetSelection( descr, descr->selected_item-1, TRUE, FALSE );
1583 }
1584 else
1585 {
1586 if (index <= descr->selected_item)
1587 {
1588 descr->selected_item++;
1589 descr->focus_item = oldfocus; /* focus not changed */
1590 }
1591 }
1592 return LB_OKAY;
1593}
static void LISTBOX_InvalidateItems(LB_DESCR *descr, INT index)
Definition: listbox.c:1127
#define ISWIN31
Definition: listbox.c:112
static void LISTBOX_UpdateScroll(LB_DESCR *descr)
Definition: listbox.c:183
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

Referenced by LISTBOX_InsertString().

◆ LISTBOX_InsertString()

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

Definition at line 1599 of file listbox.c.

1600{
1601 LPWSTR new_str = NULL;
1602 LRESULT ret;
1603
1604 if (HAS_STRINGS(descr))
1605 {
1606 static const WCHAR empty_stringW[] = { 0 };
1607 if (!str) str = empty_stringW;
1608 if (!(new_str = HeapAlloc( GetProcessHeap(), 0, (strlenW(str) + 1) * sizeof(WCHAR) )))
1609 {
1611 return LB_ERRSPACE;
1612 }
1613 strcpyW(new_str, str);
1614 }
1615
1616 if (index == -1) index = descr->nb_items;
1617 if ((ret = LISTBOX_InsertItem( descr, index, new_str, (ULONG_PTR)str )) != 0)
1618 {
1619 HeapFree( GetProcessHeap(), 0, new_str );
1620 return ret;
1621 }
1622
1623 TRACE("[%p]: added item %d %s\n",
1624 descr->self, index, HAS_STRINGS(descr) ? debugstr_w(new_str) : "" );
1625 return index;
1626}
static LRESULT LISTBOX_InsertItem(LB_DESCR *descr, INT index, LPWSTR str, ULONG_PTR data)
Definition: listbox.c:1510
static const WCHAR empty_stringW[]
Definition: edit.c:173

Referenced by LISTBOX_Directory(), LISTBOX_SetCount(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_InvalidateItemRect()

static void LISTBOX_InvalidateItemRect ( LB_DESCR descr,
INT  index 
)
static

Definition at line 1151 of file listbox.c.

1152{
1153 RECT rect;
1154
1155 if (LISTBOX_GetItemRect( descr, index, &rect ) == 1)
1156 InvalidateRect( descr->self, &rect, TRUE );
1157}
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)

Referenced by LISTBOX_SelectItemRange().

◆ LISTBOX_InvalidateItems()

static void LISTBOX_InvalidateItems ( LB_DESCR descr,
INT  index 
)
static

Definition at line 1127 of file listbox.c.

1128{
1129 RECT rect;
1130
1131 if (LISTBOX_GetItemRect( descr, index, &rect ) == 1)
1132 {
1133 if (descr->style & LBS_NOREDRAW)
1134 {
1135 descr->style |= LBS_DISPLAYCHANGED;
1136 return;
1137 }
1138 rect.bottom = descr->height;
1139 InvalidateRect( descr->self, &rect, TRUE );
1140 if (descr->style & LBS_MULTICOLUMN)
1141 {
1142 /* Repaint the other columns */
1143 rect.left = rect.right;
1144 rect.right = descr->width;
1145 rect.top = 0;
1146 InvalidateRect( descr->self, &rect, TRUE );
1147 }
1148 }
1149}
#define LBS_DISPLAYCHANGED
Definition: listbox.c:54
#define LBS_NOREDRAW
Definition: pedump.c:680

Referenced by LISTBOX_InsertItem(), LISTBOX_RemoveItem(), and LISTBOX_SetItemHeight().

◆ LISTBOX_lstrcmpiW()

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

Definition at line 772 of file listbox.c.

773{
774 INT ret = CompareStringW( lcid, NORM_IGNORECASE, str1, -1, str2, -1 );
775 if (ret == CSTR_LESS_THAN)
776 return -1;
777 if (ret == CSTR_EQUAL)
778 return 0;
779 if (ret == CSTR_GREATER_THAN)
780 return 1;
781 return -1;
782}
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

Referenced by LISTBOX_FindFileStrPos(), LISTBOX_FindString(), and LISTBOX_FindStringPos().

◆ LISTBOX_MakeItemVisible()

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

Definition at line 1316 of file listbox.c.

1317{
1318 INT top;
1319
1320 TRACE("current top item %d, index %d, fully %d\n", descr->top_item, index, fully);
1321
1322 if (index <= descr->top_item) top = index;
1323 else if (descr->style & LBS_MULTICOLUMN)
1324 {
1325 INT cols = descr->width;
1326 if (!fully) cols += descr->column_width - 1;
1327 if (cols >= descr->column_width) cols /= descr->column_width;
1328 else cols = 1;
1329 if (index < descr->top_item + (descr->page_size * cols)) return;
1330 top = index - descr->page_size * (cols - 1);
1331 }
1332 else if (descr->style & LBS_OWNERDRAWVARIABLE)
1333 {
1334 INT height = fully ? descr->items[index].height : 1;
1335 for (top = index; top > descr->top_item; top--)
1336 if ((height += descr->items[top-1].height) > descr->height) break;
1337 }
1338 else
1339 {
1340 if (index < descr->top_item + descr->page_size) return;
1341 if (!fully && (index == descr->top_item + descr->page_size) &&
1342 (descr->height > (descr->page_size * descr->item_height))) return;
1343 top = index - descr->page_size + 1;
1344 }
1346}
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859

Referenced by LISTBOX_MoveCaret(), and LISTBOX_SetCaretIndex().

◆ LISTBOX_MoveCaret()

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

Definition at line 1463 of file listbox.c.

1464{
1465 TRACE("old focus %d, index %d\n", descr->focus_item, index);
1466
1467 if ((index < 0) || (index >= descr->nb_items))
1468 return;
1469
1470 /* Important, repaint needs to be done in this order if
1471 you want to mimic Windows behavior:
1472 1. Remove the focus and paint the item
1473 2. Remove the selection and paint the item(s)
1474 3. Set the selection and repaint the item(s)
1475 4. Set the focus to 'index' and repaint the item */
1476
1477 /* 1. remove the focus and repaint the item */
1479
1480 /* 2. then turn off the previous selection */
1481 /* 3. repaint the new selected item */
1482 if (descr->style & LBS_EXTENDEDSEL)
1483 {
1484 if (descr->anchor_item != -1)
1485 {
1486 INT first = min( index, descr->anchor_item );
1487 INT last = max( index, descr->anchor_item );
1488 if (first > 0)
1492 }
1493 }
1494 else if (!(descr->style & LBS_MULTIPLESEL))
1495 {
1496 /* Set selection to new caret item */
1498 }
1499
1500 /* 4. repaint the new item with the focus */
1501 descr->focus_item = index;
1502 LISTBOX_MakeItemVisible( descr, index, fully_visible );
1504}
static void LISTBOX_DrawFocusRect(LB_DESCR *descr, BOOL on)
Definition: listbox.c:646
static void LISTBOX_MakeItemVisible(LB_DESCR *descr, INT index, BOOL fully)
Definition: listbox.c:1316
static LRESULT LISTBOX_SelectItemRange(LB_DESCR *descr, INT first, INT last, BOOL on)
Definition: listbox.c:1380
const GLint * first
Definition: glext.h:5794
static UINT UINT last
Definition: font.c:45

Referenced by LISTBOX_HandleChar(), LISTBOX_HandleKeyDown(), LISTBOX_HandleLButtonDown(), LISTBOX_HandleTimer(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_NCPaint()

static void LISTBOX_NCPaint ( LB_DESCR descr,
HRGN  region 
)
static

Definition at line 1078 of file listbox.c.

1079{
1080 DWORD exstyle = GetWindowLongW( descr->self, GWL_EXSTYLE);
1081 HTHEME theme = GetWindowTheme( descr->self );
1082 HRGN cliprgn = region;
1083 int cxEdge, cyEdge;
1084 HDC hdc;
1085 RECT r;
1086
1087 if (!theme || !(exstyle & WS_EX_CLIENTEDGE))
1088 return;
1089
1090 cxEdge = GetSystemMetrics(SM_CXEDGE),
1091 cyEdge = GetSystemMetrics(SM_CYEDGE);
1092
1093 GetWindowRect(descr->self, &r);
1094
1095 /* New clipping region passed to default proc to exclude border */
1096 cliprgn = CreateRectRgn(r.left + cxEdge, r.top + cyEdge,
1097 r.right - cxEdge, r.bottom - cyEdge);
1098 if (region != (HRGN)1)
1099 CombineRgn(cliprgn, cliprgn, region, RGN_AND);
1100 OffsetRect(&r, -r.left, -r.top);
1101
1102#ifdef __REACTOS__ /* r73789 */
1103 hdc = GetWindowDC(descr->self);
1104 /* Exclude client part */
1106 r.left + cxEdge,
1107 r.top + cyEdge,
1108 r.right - cxEdge,
1109 r.bottom -cyEdge);
1110#else
1111 hdc = GetDCEx(descr->self, region, DCX_WINDOW|DCX_INTERSECTRGN);
1112 OffsetRect(&r, -r.left, -r.top);
1113#endif
1114
1115 if (IsThemeBackgroundPartiallyTransparent (theme, 0, 0))
1117 DrawThemeBackground (theme, hdc, 0, 0, &r, 0);
1118 ReleaseDC(descr->self, hdc);
1119}
HRESULT WINAPI DrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect)
Definition: draw.c:128
BOOL WINAPI IsThemeBackgroundPartiallyTransparent(HTHEME hTheme, int iPartId, int iStateId)
Definition: draw.c:1883
HRESULT WINAPI DrawThemeParentBackground(HWND hwnd, HDC hdc, RECT *prc)
Definition: draw.c:72
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
HRGN WINAPI CreateRectRgn(_In_ int, _In_ int, _In_ int, _In_ int)
int WINAPI ExcludeClipRect(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
int WINAPI CombineRgn(_In_opt_ HRGN hrgnDest, _In_opt_ HRGN hrgnSrc1, _In_opt_ HRGN hrgnSrc2, _In_ int fnCombineMode)
#define RGN_AND
Definition: wingdi.h:356
HDC WINAPI GetWindowDC(_In_opt_ HWND)
#define SM_CYEDGE
Definition: winuser.h:1009
#define DCX_WINDOW
Definition: winuser.h:2113
#define SM_CXEDGE
Definition: winuser.h:1008
#define DCX_INTERSECTRGN
Definition: winuser.h:2122
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384

Referenced by LISTBOX_WindowProc().

◆ LISTBOX_Paint()

static LRESULT LISTBOX_Paint ( LB_DESCR descr,
HDC  hdc 
)
static

Definition at line 970 of file listbox.c.

971{
972 INT i, col_pos = descr->page_size - 1;
973 RECT rect;
974 RECT focusRect = {-1, -1, -1, -1};
975 HFONT oldFont = 0;
976 HBRUSH hbrush, oldBrush = 0;
977
978 if (descr->style & LBS_NOREDRAW) return 0;
979
980 SetRect( &rect, 0, 0, descr->width, descr->height );
981 if (descr->style & LBS_MULTICOLUMN)
982 rect.right = rect.left + descr->column_width;
983 else if (descr->horz_pos)
984 {
985 SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
986 rect.right += descr->horz_pos;
987 }
988
989 if (descr->font) oldFont = SelectObject( hdc, descr->font );
990 hbrush = (HBRUSH)SendMessageW( descr->owner, WM_CTLCOLORLISTBOX,
991 (WPARAM)hdc, (LPARAM)descr->self );
992 if (hbrush) oldBrush = SelectObject( hdc, hbrush );
994
995 if (!descr->nb_items && (descr->focus_item != -1) && descr->caret_on &&
996 (descr->in_focus))
997 {
998 /* Special case for empty listbox: paint focus rect */
999 rect.bottom = rect.top + descr->item_height;
1001 &rect, NULL, 0, NULL );
1002 LISTBOX_PaintItem( descr, hdc, &rect, descr->focus_item, ODA_FOCUS, FALSE );
1003 rect.top = rect.bottom;
1004 }
1005
1006 /* Paint all the item, regarding the selection
1007 Focus state will be painted after */
1008
1009 for (i = descr->top_item; i < descr->nb_items; i++)
1010 {
1011 if (!(descr->style & LBS_OWNERDRAWVARIABLE))
1012 rect.bottom = rect.top + descr->item_height;
1013 else
1014 rect.bottom = rect.top + descr->items[i].height;
1015
1016 /* keep the focus rect, to paint the focus item after */
1017 if (i == descr->focus_item)
1018 focusRect = rect;
1019
1021 rect.top = rect.bottom;
1022
1023 if ((descr->style & LBS_MULTICOLUMN) && !col_pos)
1024 {
1025 if (!IS_OWNERDRAW(descr))
1026 {
1027 /* Clear the bottom of the column */
1028 if (rect.top < descr->height)
1029 {
1030 rect.bottom = descr->height;
1032 &rect, NULL, 0, NULL );
1033 }
1034 }
1035
1036 /* Go to the next column */
1037 rect.left += descr->column_width;
1038 rect.right += descr->column_width;
1039 rect.top = 0;
1040 col_pos = descr->page_size - 1;
1041 }
1042 else
1043 {
1044 col_pos--;
1045 if (rect.top >= descr->height) break;
1046 }
1047 }
1048
1049 /* Paint the focus item now */
1050 if (focusRect.top != focusRect.bottom &&
1051 descr->caret_on && descr->in_focus)
1052 LISTBOX_PaintItem( descr, hdc, &focusRect, descr->focus_item, ODA_FOCUS, FALSE );
1053
1054 if (!IS_OWNERDRAW(descr))
1055 {
1056 /* Clear the remainder of the client area */
1057 if (rect.top < descr->height)
1058 {
1059 rect.bottom = descr->height;
1061 &rect, NULL, 0, NULL );
1062 }
1063 if (rect.right < descr->width)
1064 {
1065 rect.left = rect.right;
1066 rect.right = descr->width;
1067 rect.top = 0;
1068 rect.bottom = descr->height;
1070 &rect, NULL, 0, NULL );
1071 }
1072 }
1073 if (oldFont) SelectObject( hdc, oldFont );
1074 if (oldBrush) SelectObject( hdc, oldBrush );
1075 return 0;
1076}
static HBRUSH hbrush
LONG top
Definition: windef.h:307
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:2542
#define WM_CTLCOLORLISTBOX
Definition: winuser.h:1768

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_PaintItem()

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

Definition at line 486 of file listbox.c.

488{
490 if (index < descr->nb_items) item = &descr->items[index];
491
492 if (IS_OWNERDRAW(descr))
493 {
494 DRAWITEMSTRUCT dis;
495 RECT r;
496 HRGN hrgn;
497
498 if (!item)
499 {
500 if (action == ODA_FOCUS)
502 else
503 ERR("called with an out of bounds index %d(%d) in owner draw, Not good.\n",index,descr->nb_items);
504 return;
505 }
506
507 /* some programs mess with the clipping region when
508 drawing the item, *and* restore the previous region
509 after they are done, so a region has better to exist
510 else everything ends clipped */
511 GetClientRect(descr->self, &r);
513
514 dis.CtlType = ODT_LISTBOX;
515 dis.CtlID = GetWindowLongPtrW( descr->self, GWLP_ID );
516 dis.hwndItem = descr->self;
517 dis.itemAction = action;
518 dis.hDC = hdc;
519 dis.itemID = index;
520 dis.itemState = 0;
521 if (item->selected) dis.itemState |= ODS_SELECTED;
522 if (!ignoreFocus && (descr->focus_item == index) &&
523 (descr->caret_on) &&
524 (descr->in_focus)) dis.itemState |= ODS_FOCUS;
525 if (!IsWindowEnabled(descr->self)) dis.itemState |= ODS_DISABLED;
526 dis.itemData = item->data;
527 dis.rcItem = *rect;
528 TRACE("[%p]: drawitem %d (%s) action=%02x state=%02x rect=%s\n",
529 descr->self, index, debugstr_w(item->str), action,
531 SendMessageW(descr->owner, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
533 if (hrgn) DeleteObject( hrgn );
534 }
535 else
536 {
537 COLORREF oldText = 0, oldBk = 0;
538
539 if (action == ODA_FOCUS)
540 {
542 return;
543 }
544 if (item && item->selected)
545 {
548 }
549
550 TRACE("[%p]: painting %d (%s) action=%02x rect=%s\n",
551 descr->self, index, item ? debugstr_w(item->str) : "", action,
553 if (!item)
554 ExtTextOutW( hdc, rect->left + 1, rect->top,
556 else if (!(descr->style & LBS_USETABSTOPS))
557 ExtTextOutW( hdc, rect->left + 1, rect->top,
559 strlenW(item->str), NULL );
560 else
561 {
562 /* Output empty string to paint background in the full width. */
563 ExtTextOutW( hdc, rect->left + 1, rect->top,
565 TabbedTextOutW( hdc, rect->left + 1 , rect->top,
566 item->str, strlenW(item->str),
567 descr->nb_tabs, descr->tabs, 0);
568 }
569 if (item && item->selected)
570 {
571 SetBkColor( hdc, oldBk );
572 SetTextColor( hdc, oldText );
573 }
574 if (!ignoreFocus && (descr->focus_item == index) &&
575 (descr->caret_on) &&
576 (descr->in_focus)) DrawFocusRect( hdc, rect );
577 }
578}
static HRGN hrgn
#define ERR(fmt,...)
Definition: debug.h:113
HRGN set_control_clipping(HDC hdc, const RECT *rect)
Definition: button.c:239
const WCHAR * action
Definition: action.c:7479
pKey DeleteObject()
#define LBS_USETABSTOPS
Definition: pedump.c:685
ULONG_PTR itemData
Definition: winuser.h:3093
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:2547
#define ODS_SELECTED
Definition: winuser.h:2545
#define COLOR_HIGHLIGHT
Definition: winuser.h:926
#define WM_DRAWITEM
Definition: winuser.h:1645
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:927
BOOL WINAPI DrawFocusRect(_In_ HDC, _In_ LPCRECT)
#define ODS_FOCUS
Definition: winuser.h:2549
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)

Referenced by LISTBOX_DrawFocusRect(), LISTBOX_Paint(), and LISTBOX_RepaintItem().

◆ LISTBOX_Register()

void LISTBOX_Register ( void  )

Definition at line 3054 of file listbox.c.

3055{
3056 WNDCLASSW wndClass;
3057
3058 memset(&wndClass, 0, sizeof(wndClass));
3061 wndClass.cbClsExtra = 0;
3062 wndClass.cbWndExtra = sizeof(LB_DESCR *);
3063 wndClass.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
3064 wndClass.hbrBackground = NULL;
3065 wndClass.lpszClassName = WC_LISTBOXW;
3066 RegisterClassW(&wndClass);
3067}
#define CS_PARENTDC
Definition: winuser.h:656

Referenced by DllMain().

◆ LISTBOX_RemoveItem()

static LRESULT LISTBOX_RemoveItem ( LB_DESCR descr,
INT  index 
)
static

Definition at line 1670 of file listbox.c.

1671{
1673 INT max_items;
1674
1675 if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
1676
1677 /* We need to invalidate the original rect instead of the updated one. */
1679
1680 descr->nb_items--;
1682
1683 if (!descr->nb_items) return LB_OKAY;
1684
1685 /* Remove the item */
1686
1687 item = &descr->items[index];
1688 if (index < descr->nb_items)
1689 RtlMoveMemory( item, item + 1,
1690 (descr->nb_items - index) * sizeof(LB_ITEMDATA) );
1691 if (descr->anchor_item == descr->nb_items) descr->anchor_item--;
1692
1693 /* Shrink the item array if possible */
1694
1695 max_items = HeapSize( GetProcessHeap(), 0, descr->items ) / sizeof(LB_ITEMDATA);
1696 if (descr->nb_items < max_items - 2*LB_ARRAY_GRANULARITY)
1697 {
1698 max_items -= LB_ARRAY_GRANULARITY;
1699 item = HeapReAlloc( GetProcessHeap(), 0, descr->items,
1700 max_items * sizeof(LB_ITEMDATA) );
1701 if (item) descr->items = item;
1702 }
1703 /* Repaint the items */
1704
1706 /* if we removed the scrollbar, reset the top of the list
1707 (correct for owner-drawn ???) */
1708 if (descr->nb_items == descr->page_size)
1710
1711 /* Move selection and focused item */
1712 if (!IS_MULTISELECT(descr))
1713 {
1714 if (index == descr->selected_item)
1715 descr->selected_item = -1;
1716 else if (index < descr->selected_item)
1717 {
1718 descr->selected_item--;
1719 if (ISWIN31) /* win 31 do not change the selected item number */
1720 LISTBOX_SetSelection( descr, descr->selected_item + 1, TRUE, FALSE);
1721 }
1722 }
1723
1724 if (descr->focus_item >= descr->nb_items)
1725 {
1726 descr->focus_item = descr->nb_items - 1;
1727 if (descr->focus_item < 0) descr->focus_item = 0;
1728 }
1729 return LB_OKAY;
1730}
static void LISTBOX_DeleteItem(LB_DESCR *descr, INT index)
Definition: listbox.c:1634

Referenced by LISTBOX_SetCount(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_RepaintItem()

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

Definition at line 613 of file listbox.c.

614{
615 HDC hdc;
616 RECT rect;
617 HFONT oldFont = 0;
618 HBRUSH hbrush, oldBrush = 0;
619
620 /* Do not repaint the item if the item is not visible */
621 if (!IsWindowVisible(descr->self)) return;
622 if (descr->style & LBS_NOREDRAW)
623 {
624 descr->style |= LBS_DISPLAYCHANGED;
625 return;
626 }
627 if (LISTBOX_GetItemRect( descr, index, &rect ) != 1) return;
628 if (!(hdc = GetDCEx( descr->self, 0, DCX_CACHE ))) return;
629 if (descr->font) oldFont = SelectObject( hdc, descr->font );
630 hbrush = (HBRUSH)SendMessageW( descr->owner, WM_CTLCOLORLISTBOX,
631 (WPARAM)hdc, (LPARAM)descr->self );
632 if (hbrush) oldBrush = SelectObject( hdc, hbrush );
633 if (!IsWindowEnabled(descr->self))
635 SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL );
637 if (oldFont) SelectObject( hdc, oldFont );
638 if (oldBrush) SelectObject( hdc, oldBrush );
639 ReleaseDC( descr->self, hdc );
640}

Referenced by LISTBOX_SetSelection(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_ResetContent()

static void LISTBOX_ResetContent ( LB_DESCR descr)
static

Definition at line 1736 of file listbox.c.

1737{
1738 INT i;
1739
1740 for(i = descr->nb_items - 1; i>=0; i--) LISTBOX_DeleteItem( descr, i);
1741 HeapFree( GetProcessHeap(), 0, descr->items );
1742 descr->nb_items = 0;
1743 descr->top_item = 0;
1744 descr->selected_item = -1;
1745 descr->focus_item = 0;
1746 descr->anchor_item = -1;
1747 descr->items = NULL;
1748}

Referenced by LISTBOX_Destroy(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_SelectItemRange()

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

Definition at line 1380 of file listbox.c.

1382{
1383 INT i;
1384
1385 /* A few sanity checks */
1386
1387 if (descr->style & LBS_NOSEL) return LB_ERR;
1388 if (!(descr->style & LBS_MULTIPLESEL)) return LB_ERR;
1389
1390 if (!descr->nb_items) return LB_OKAY;
1391
1392 if (last == -1 || last >= descr->nb_items) last = descr->nb_items - 1;
1393 if (first < 0) first = 0;
1394 if (last < first) return LB_OKAY;
1395
1396 if (on) /* Turn selection on */
1397 {
1398 for (i = first; i <= last; i++)
1399 {
1400 if (descr->items[i].selected) continue;
1401 descr->items[i].selected = TRUE;
1403 }
1404 }
1405 else /* Turn selection off */
1406 {
1407 for (i = first; i <= last; i++)
1408 {
1409 if (!descr->items[i].selected) continue;
1410 descr->items[i].selected = FALSE;
1412 }
1413 }
1414 return LB_OKAY;
1415}
static void LISTBOX_InvalidateItemRect(LB_DESCR *descr, INT index)
Definition: listbox.c:1151

Referenced by LISTBOX_MoveCaret(), LISTBOX_SetSelection(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_SetCaretIndex()

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

Definition at line 1355 of file listbox.c.

1356{
1357 INT oldfocus = descr->focus_item;
1358
1359 TRACE("old focus %d, index %d\n", oldfocus, index);
1360
1361 if (descr->style & LBS_NOSEL) return LB_ERR;
1362 if ((index < 0) || (index >= descr->nb_items)) return LB_ERR;
1363 if (index == oldfocus) return LB_OKAY;
1364
1366 descr->focus_item = index;
1367
1368 LISTBOX_MakeItemVisible( descr, index, fully_visible );
1370
1371 return LB_OKAY;
1372}

Referenced by LISTBOX_HandleLButtonDown(), LISTBOX_HandleLButtonDownCombo(), LISTBOX_InsertItem(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_SetColumnWidth()

static LRESULT LISTBOX_SetColumnWidth ( LB_DESCR descr,
INT  width 
)
static

Definition at line 1270 of file listbox.c.

1271{
1272 if (width == descr->column_width) return LB_OKAY;
1273 TRACE("[%p]: new column width = %d\n", descr->self, width );
1274 descr->column_width = width;
1276 return LB_OKAY;
1277}
static void LISTBOX_UpdatePage(LB_DESCR *descr)
Definition: listbox.c:316
GLint GLint GLsizei width
Definition: gl.h:1546

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_SetCount()

static LRESULT LISTBOX_SetCount ( LB_DESCR descr,
INT  count 
)
static

Definition at line 1754 of file listbox.c.

1755{
1756 LRESULT ret;
1757
1758 if (HAS_STRINGS(descr))
1759 {
1761 return LB_ERR;
1762 }
1763
1764 /* FIXME: this is far from optimal... */
1765 if (count > descr->nb_items)
1766 {
1767 while (count > descr->nb_items)
1768 if ((ret = LISTBOX_InsertString( descr, -1, 0 )) < 0)
1769 return ret;
1770 }
1771 else if (count < descr->nb_items)
1772 {
1773 while (count < descr->nb_items)
1774 if ((ret = LISTBOX_RemoveItem( descr, (descr->nb_items - 1) )) < 0)
1775 return ret;
1776 }
1777
1778 InvalidateRect( descr->self, NULL, TRUE );
1779 return LB_OKAY;
1780}
static LRESULT LISTBOX_RemoveItem(LB_DESCR *descr, INT index)
Definition: listbox.c:1670
#define ERROR_SETCOUNT_ON_BAD_LB
Definition: winerror.h:914

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_SetFont()

static INT LISTBOX_SetFont ( LB_DESCR descr,
HFONT  font 
)
static

Definition at line 1285 of file listbox.c.

1286{
1287 HDC hdc;
1288 HFONT oldFont = 0;
1289 const char *alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
1290 SIZE sz;
1291
1292 descr->font = font;
1293
1294 if (!(hdc = GetDCEx( descr->self, 0, DCX_CACHE )))
1295 {
1296 ERR("unable to get DC.\n" );
1297 return 16;
1298 }
1299 if (font) oldFont = SelectObject( hdc, font );
1300 GetTextExtentPointA( hdc, alphabet, 52, &sz);
1301 if (oldFont) SelectObject( hdc, oldFont );
1302 ReleaseDC( descr->self, hdc );
1303
1304 descr->avg_char_width = (sz.cx / 26 + 1) / 2;
1305 if (!IS_OWNERDRAW(descr))
1307 return sz.cy;
1308}
static LRESULT LISTBOX_SetItemHeight(LB_DESCR *descr, INT index, INT height, BOOL repaint)
Definition: listbox.c:1180
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)

Referenced by LISTBOX_Create(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_SetHorizontalExtent()

static LRESULT LISTBOX_SetHorizontalExtent ( LB_DESCR descr,
INT  extent 
)
static

Definition at line 1244 of file listbox.c.

1245{
1246 if (descr->style & LBS_MULTICOLUMN)
1247 return LB_OKAY;
1248 if (extent == descr->horz_extent) return LB_OKAY;
1249 TRACE("[%p]: new horz extent = %d\n", descr->self, extent );
1250 descr->horz_extent = extent;
1251 if (descr->style & WS_HSCROLL) {
1253 info.cbSize = sizeof(info);
1254 info.nMin = 0;
1255 info.nMax = descr->horz_extent ? descr->horz_extent - 1 : 0;
1256 info.fMask = SIF_RANGE;
1257 if (descr->style & LBS_DISABLENOSCROLL)
1258 info.fMask |= SIF_DISABLENOSCROLL;
1259 SetScrollInfo( descr->self, SB_HORZ, &info, TRUE );
1260 }
1261 if (descr->horz_pos > extent - descr->width)
1263 return LB_OKAY;
1264}
#define LBS_DISABLENOSCROLL
Definition: pedump.c:690
#define SIF_RANGE
Definition: winuser.h:1235
#define SIF_DISABLENOSCROLL
Definition: winuser.h:1236
int WINAPI SetScrollInfo(_In_ HWND, _In_ int, _In_ LPCSCROLLINFO, _In_ BOOL)

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_SetHorizontalPos()

static void LISTBOX_SetHorizontalPos ( LB_DESCR descr,
INT  pos 
)
static

Definition at line 1216 of file listbox.c.

1217{
1218 INT diff;
1219
1220 if (pos > descr->horz_extent - descr->width)
1221 pos = descr->horz_extent - descr->width;
1222 if (pos < 0) pos = 0;
1223 if (!(diff = descr->horz_pos - pos)) return;
1224 TRACE("[%p]: new horz pos = %d\n", descr->self, pos );
1225 descr->horz_pos = pos;
1227 if (abs(diff) < descr->width)
1228 {
1229 RECT rect;
1230 /* Invalidate the focused item so it will be repainted correctly */
1231 if (LISTBOX_GetItemRect( descr, descr->focus_item, &rect ) == 1)
1232 InvalidateRect( descr->self, &rect, TRUE );
1233 ScrollWindowEx( descr->self, diff, 0, NULL, NULL, 0, NULL,
1235 }
1236 else
1237 InvalidateRect( descr->self, NULL, TRUE );
1238}
#define abs(i)
Definition: fconv.c:206
#define SW_SCROLLCHILDREN
Definition: winuser.h:2578
#define SW_INVALIDATE
Definition: winuser.h:2579
#define SW_ERASE
Definition: winuser.h:2580
int WINAPI ScrollWindowEx(_In_ HWND, _In_ int, _In_ int, _In_opt_ LPCRECT, _In_opt_ LPCRECT, _In_opt_ HRGN, _Out_opt_ LPRECT, _In_ UINT)

Referenced by LISTBOX_HandleHScroll(), and LISTBOX_SetHorizontalExtent().

◆ LISTBOX_SetItemHeight()

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

Definition at line 1180 of file listbox.c.

1181{
1182 if (height > MAXBYTE)
1183 return -1;
1184
1185 if (!height) height = 1;
1186
1187 if (descr->style & LBS_OWNERDRAWVARIABLE)
1188 {
1189 if ((index < 0) || (index >= descr->nb_items))
1190 {
1192 return LB_ERR;
1193 }
1194 TRACE("[%p]: item %d height = %d\n", descr->self, index, height );
1195 descr->items[index].height = height;
1197 if (repaint)
1199 }
1200 else if (height != descr->item_height)
1201 {
1202 TRACE("[%p]: new height = %d\n", descr->self, height );
1203 descr->item_height = height;
1206 if (repaint)
1207 InvalidateRect( descr->self, 0, TRUE );
1208 }
1209 return LB_OKAY;
1210}
#define MAXBYTE

Referenced by LISTBOX_SetFont(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_SetRedraw()

static void LISTBOX_SetRedraw ( LB_DESCR descr,
BOOL  on 
)
static

Definition at line 586 of file listbox.c.

587{
588 if (on)
589 {
590 if (!(descr->style & LBS_NOREDRAW)) return;
591 descr->style &= ~LBS_NOREDRAW;
592 if (descr->style & LBS_DISPLAYCHANGED)
593 { /* page was changed while setredraw false, refresh automatically */
594 InvalidateRect(descr->self, NULL, TRUE);
595 if ((descr->top_item + descr->page_size) > descr->nb_items)
596 { /* reset top of page if less than number of items/page */
597 descr->top_item = descr->nb_items - descr->page_size;
598 if (descr->top_item < 0) descr->top_item = 0;
599 }
600 descr->style &= ~LBS_DISPLAYCHANGED;
601 }
603 }
604 else descr->style |= LBS_NOREDRAW;
605}

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_SetSelection()

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

Definition at line 1420 of file listbox.c.

1422{
1423 TRACE( "cur_sel=%d index=%d notify=%s\n",
1424 descr->selected_item, index, send_notify ? "YES" : "NO" );
1425
1426 if (descr->style & LBS_NOSEL)
1427 {
1428 descr->selected_item = index;
1429 return LB_ERR;
1430 }
1431 if ((index < -1) || (index >= descr->nb_items)) return LB_ERR;
1432 if (descr->style & LBS_MULTIPLESEL)
1433 {
1434 if (index == -1) /* Select all items */
1435 return LISTBOX_SelectItemRange( descr, 0, descr->nb_items, on );
1436 else /* Only one item */
1437 return LISTBOX_SelectItemRange( descr, index, index, on );
1438 }
1439 else
1440 {
1441 INT oldsel = descr->selected_item;
1442 if (index == oldsel) return LB_OKAY;
1443 if (oldsel != -1) descr->items[oldsel].selected = FALSE;
1444 if (index != -1) descr->items[index].selected = TRUE;
1445 if (oldsel != -1) LISTBOX_RepaintItem( descr, oldsel, ODA_SELECT );
1446 descr->selected_item = index;
1448 if (send_notify && descr->nb_items) SEND_NOTIFICATION( descr,
1449 (index != -1) ? LBN_SELCHANGE : LBN_SELCANCEL );
1450 else
1451 if( descr->lphc ) /* set selection change flag for parent combo */
1452 descr->lphc->wState |= CBF_SELCHANGE;
1453 }
1454 return LB_OKAY;
1455}
#define CBF_SELCHANGE
Definition: controls.h:55
static void LISTBOX_RepaintItem(LB_DESCR *descr, INT index, UINT action)
Definition: listbox.c:613
static void send_notify(HWND pager, UINT unicode, UINT ansi, LPARAM lParam, BOOL code_change)
Definition: pager.c:933
#define LBN_SELCANCEL
Definition: winuser.h:2074
#define ODA_SELECT
Definition: winuser.h:2543

Referenced by LISTBOX_HandleChar(), LISTBOX_HandleKeyDown(), LISTBOX_HandleLButtonDown(), LISTBOX_HandleLButtonDownCombo(), LISTBOX_InsertItem(), LISTBOX_MoveCaret(), LISTBOX_RemoveItem(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_SetTabStops()

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

Definition at line 702 of file listbox.c.

703{
704 INT i;
705
706 if (!(descr->style & LBS_USETABSTOPS))
707 {
709 return FALSE;
710 }
711
712 HeapFree( GetProcessHeap(), 0, descr->tabs );
713 if (!(descr->nb_tabs = count))
714 {
715 descr->tabs = NULL;
716 return TRUE;
717 }
718 if (!(descr->tabs = HeapAlloc( GetProcessHeap(), 0,
719 descr->nb_tabs * sizeof(INT) )))
720 return FALSE;
721 memcpy( descr->tabs, tabs, descr->nb_tabs * sizeof(INT) );
722
723 /* convert into "dialog units"*/
724 for (i = 0; i < descr->nb_tabs; i++)
725 descr->tabs[i] = MulDiv(descr->tabs[i], descr->avg_char_width, 4);
726
727 return TRUE;
728}
#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

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_SetTopItem()

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

Definition at line 266 of file listbox.c.

267{
269
270 TRACE("setting top item %d, scroll %d\n", index, scroll);
271
272 if (index > max) index = max;
273 if (index < 0) index = 0;
274 if (descr->style & LBS_MULTICOLUMN) index -= index % descr->page_size;
275 if (descr->top_item == index) return LB_OKAY;
276 if (scroll)
277 {
278 INT diff;
279 if (descr->style & LBS_MULTICOLUMN)
280 diff = (descr->top_item - index) / descr->page_size * descr->column_width;
281 else if (descr->style & LBS_OWNERDRAWVARIABLE)
282 {
283 INT i;
284 diff = 0;
285 if (index > descr->top_item)
286 {
287 for (i = index - 1; i >= descr->top_item; i--)
288 diff -= descr->items[i].height;
289 }
290 else
291 {
292 for (i = index; i < descr->top_item; i++)
293 diff += descr->items[i].height;
294 }
295 }
296 else
297 diff = (descr->top_item - index) * descr->item_height;
298
299 ScrollWindowEx( descr->self, 0, diff, NULL, NULL, 0, NULL,
301 }
302 else
303 InvalidateRect( descr->self, NULL, TRUE );
304 descr->top_item = index;
306 return LB_OKAY;
307}
static INT LISTBOX_GetMaxTopIndex(const LB_DESCR *descr)
Definition: listbox.c:151
if(dx< 0)
Definition: linetemp.h:194

Referenced by LISTBOX_HandleHScroll(), LISTBOX_HandleMouseWheel(), LISTBOX_HandleVScroll(), LISTBOX_MakeItemVisible(), LISTBOX_RemoveItem(), LISTBOX_UpdatePage(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_UpdatePage()

static void LISTBOX_UpdatePage ( LB_DESCR descr)
static

Definition at line 316 of file listbox.c.

317{
319
320 if ((descr->item_height == 0) || (page_size = descr->height / descr->item_height) < 1)
321 page_size = 1;
322 if (page_size == descr->page_size) return;
323 descr->page_size = page_size;
324 if (descr->style & LBS_MULTICOLUMN)
325 InvalidateRect( descr->self, NULL, TRUE );
326 LISTBOX_SetTopItem( descr, descr->top_item, FALSE );
327}
static DWORD page_size
Definition: loader.c:53

Referenced by LISTBOX_SetColumnWidth(), LISTBOX_SetItemHeight(), and LISTBOX_UpdateSize().

◆ LISTBOX_UpdateScroll()

static void LISTBOX_UpdateScroll ( LB_DESCR descr)
static

Definition at line 183 of file listbox.c.

184{
186
187 /* Check the listbox scroll bar flags individually before we call
188 SetScrollInfo otherwise when the listbox style is WS_HSCROLL and
189 no WS_VSCROLL, we end up with an uninitialized, visible horizontal
190 scroll bar when we do not need one.
191 if (!(descr->style & WS_VSCROLL)) return;
192 */
193
194 /* It is important that we check descr->style, and not wnd->dwStyle,
195 for WS_VSCROLL, as the former is exactly the one passed in
196 argument to CreateWindow.
197 In Windows (and from now on in Wine :) a listbox created
198 with such a style (no WS_SCROLL) does not update
199 the scrollbar with listbox-related data, thus letting
200 the programmer use it for his/her own purposes. */
201
202 if (descr->style & LBS_NOREDRAW) return;
203 info.cbSize = sizeof(info);
204
205 if (descr->style & LBS_MULTICOLUMN)
206 {
207 info.nMin = 0;
208 info.nMax = (descr->nb_items - 1) / descr->page_size;
209 info.nPos = descr->top_item / descr->page_size;
210 info.nPage = descr->width / descr->column_width;
211 if (info.nPage < 1) info.nPage = 1;
212 info.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
213 if (descr->style & LBS_DISABLENOSCROLL)
214 info.fMask |= SIF_DISABLENOSCROLL;
215 if (descr->style & WS_HSCROLL)
216 SetScrollInfo( descr->self, SB_HORZ, &info, TRUE );
217 info.nMax = 0;
218 info.fMask = SIF_RANGE;
219 if (descr->style & WS_VSCROLL)
220 SetScrollInfo( descr->self, SB_VERT, &info, TRUE );
221 }
222 else
223 {
224 info.nMin = 0;
225 info.nMax = descr->nb_items - 1;
226 info.nPos = descr->top_item;
228 info.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
229 if (descr->style & LBS_DISABLENOSCROLL)
230 info.fMask |= SIF_DISABLENOSCROLL;
231 if (descr->style & WS_VSCROLL)
232 SetScrollInfo( descr->self, SB_VERT, &info, TRUE );
233
234 if ((descr->style & WS_HSCROLL) && descr->horz_extent)
235 {
236 info.nPos = descr->horz_pos;
237 info.nPage = descr->width;
238 info.fMask = SIF_POS | SIF_PAGE;
239 if (descr->style & LBS_DISABLENOSCROLL)
240 info.fMask |= SIF_DISABLENOSCROLL;
241 SetScrollInfo( descr->self, SB_HORZ, &info, TRUE );
242 }
243 else
244 {
245 if (descr->style & LBS_DISABLENOSCROLL)
246 {
247 info.nMin = 0;
248 info.nMax = 0;
250 SetScrollInfo( descr->self, SB_HORZ, &info, TRUE );
251 }
252 else
253 {
254 ShowScrollBar( descr->self, SB_HORZ, FALSE );
255 }
256 }
257 }
258}
#define SIF_PAGE
Definition: winuser.h:1233
#define SIF_POS
Definition: winuser.h:1234
BOOL WINAPI ShowScrollBar(_In_ HWND, _In_ int, _In_ BOOL)

Referenced by LISTBOX_InsertItem(), LISTBOX_RemoveItem(), LISTBOX_SetHorizontalPos(), LISTBOX_SetItemHeight(), LISTBOX_SetRedraw(), LISTBOX_SetTopItem(), LISTBOX_UpdateSize(), LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_UpdateSize()

static void LISTBOX_UpdateSize ( LB_DESCR descr)
static

Definition at line 336 of file listbox.c.

337{
338 RECT rect;
339
340 GetClientRect( descr->self, &rect );
341 descr->width = rect.right - rect.left;
342 descr->height = rect.bottom - rect.top;
343 if (!(descr->style & LBS_NOINTEGRALHEIGHT) && !(descr->style & LBS_OWNERDRAWVARIABLE))
344 {
345 INT remaining;
346 RECT rect;
347
348 GetWindowRect( descr->self, &rect );
349 if(descr->item_height != 0)
350 remaining = descr->height % descr->item_height;
351 else
352 remaining = 0;
353 if ((descr->height > descr->item_height) && remaining)
354 {
355 TRACE("[%p]: changing height %d -> %d\n",
356 descr->self, descr->height, descr->height - remaining );
357 SetWindowPos( descr->self, 0, 0, 0, rect.right - rect.left,
358 rect.bottom - rect.top - remaining,
360 return;
361 }
362 }
363 TRACE("[%p]: new size = %d,%d\n", descr->self, descr->width, descr->height );
366
367 /* Invalidate the focused item so it will be repainted correctly */
368 if (LISTBOX_GetItemRect( descr, descr->focus_item, &rect ) == 1)
369 {
370 InvalidateRect( descr->self, &rect, FALSE );
371 }
372}
#define SWP_NOACTIVATE
Definition: winuser.h:1242
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define SWP_NOMOVE
Definition: winuser.h:1244
#define SWP_NOZORDER
Definition: winuser.h:1247

Referenced by LISTBOX_WindowProc(), and ListBoxWndProc_common().

◆ LISTBOX_WindowProc()

static LRESULT CALLBACK LISTBOX_WindowProc ( HWND  hwnd,
UINT  msg,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 2570 of file listbox.c.

2571{
2573 HEADCOMBO *lphc = NULL;
2574 HTHEME theme;
2575 LRESULT ret;
2576
2577 if (!descr)
2578 {
2579 if (!IsWindow(hwnd)) return 0;
2580
2581 if (msg == WM_CREATE)
2582 {
2584 if (lpcs->style & LBS_COMBOBOX) lphc = lpcs->lpCreateParams;
2585 if (!LISTBOX_Create( hwnd, lphc )) return -1;
2586 TRACE("creating hwnd %p descr %p\n", hwnd, (void *)GetWindowLongPtrW( hwnd, 0 ) );
2587 return 0;
2588 }
2589 /* Ignore all other messages before we get a WM_CREATE */
2590 return DefWindowProcW( hwnd, msg, wParam, lParam );
2591 }
2592 if (descr->style & LBS_COMBOBOX) lphc = descr->lphc;
2593
2594 TRACE("[%p]: msg %#x wp %08lx lp %08lx\n", descr->self, msg, wParam, lParam );
2595
2596 switch(msg)
2597 {
2598 case LB_RESETCONTENT:
2601 InvalidateRect( descr->self, NULL, TRUE );
2602 return 0;
2603
2604 case LB_ADDSTRING:
2605 {
2606 const WCHAR *textW = (const WCHAR *)lParam;
2609 }
2610
2611 case LB_INSERTSTRING:
2612 return LISTBOX_InsertString( descr, wParam, (const WCHAR *)lParam );
2613
2614 case LB_ADDFILE:
2615 {
2616 const WCHAR *textW = (const WCHAR *)lParam;
2619 }
2620
2621 case LB_DELETESTRING:
2623 return descr->nb_items;
2624 else
2625 {
2627 return LB_ERR;
2628 }
2629
2630 case LB_GETITEMDATA:
2631 if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
2632 {
2634 return LB_ERR;
2635 }
2636 return descr->items[wParam].data;
2637
2638 case LB_SETITEMDATA:
2639 if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
2640 {
2642 return LB_ERR;
2643 }
2644 descr->items[wParam].data = lParam;
2645 /* undocumented: returns TRUE, not LB_OKAY (0) */
2646 return TRUE;
2647
2648 case LB_GETCOUNT:
2649 return descr->nb_items;
2650
2651 case LB_GETTEXT:
2653
2654 case LB_GETTEXTLEN:
2655 if ((INT)wParam >= descr->nb_items || (INT)wParam < 0)
2656 {
2658 return LB_ERR;
2659 }
2660 if (!HAS_STRINGS(descr)) return sizeof(DWORD);
2661 return strlenW( descr->items[wParam].str );
2662
2663 case LB_GETCURSEL:
2664 if (descr->nb_items == 0)
2665 return LB_ERR;
2666 if (!IS_MULTISELECT(descr))
2667 return descr->selected_item;
2668 if (descr->selected_item != -1)
2669 return descr->selected_item;
2670 return descr->focus_item;
2671 /* otherwise, if the user tries to move the selection with the */
2672 /* arrow keys, we will give the application something to choke on */
2673 case LB_GETTOPINDEX:
2674 return descr->top_item;
2675
2676 case LB_GETITEMHEIGHT:
2678
2679 case LB_SETITEMHEIGHT:
2681
2682 case LB_ITEMFROMPOINT:
2683 {
2684 POINT pt;
2685 RECT rect;
2686 int index;
2687 BOOL hit = TRUE;
2688
2689 /* The hiword of the return value is not a client area
2690 hittest as suggested by MSDN, but rather a hittest on
2691 the returned listbox item. */
2692
2693 if(descr->nb_items == 0)
2694 return 0x1ffff; /* win9x returns 0x10000, we copy winnt */
2695
2696 pt.x = (short)LOWORD(lParam);
2697 pt.y = (short)HIWORD(lParam);
2698
2699 SetRect(&rect, 0, 0, descr->width, descr->height);
2700
2701 if(!PtInRect(&rect, pt))
2702 {
2703 pt.x = min(pt.x, rect.right - 1);
2704 pt.x = max(pt.x, 0);
2705 pt.y = min(pt.y, rect.bottom - 1);
2706 pt.y = max(pt.y, 0);
2707 hit = FALSE;
2708 }
2709
2711
2712 if(index == -1)
2713 {
2714 index = descr->nb_items - 1;
2715 hit = FALSE;
2716 }
2717 return MAKELONG(index, hit ? 0 : 1);
2718 }
2719
2720 case LB_SETCARETINDEX:
2721 if ((!IS_MULTISELECT(descr)) && (descr->selected_item != -1)) return LB_ERR;
2723 return LB_ERR;
2724 else if (ISWIN31)
2725 return wParam;
2726 else
2727 return LB_OKAY;
2728
2729 case LB_GETCARETINDEX:
2730 return descr->focus_item;
2731
2732 case LB_SETTOPINDEX:
2733 return LISTBOX_SetTopItem( descr, wParam, TRUE );
2734
2735 case LB_SETCOLUMNWIDTH:
2737
2738 case LB_GETITEMRECT:
2740
2741 case LB_FINDSTRING:
2742 return LISTBOX_FindString( descr, wParam, (const WCHAR *)lParam, FALSE );
2743
2744 case LB_FINDSTRINGEXACT:
2745 return LISTBOX_FindString( descr, wParam, (const WCHAR *)lParam, TRUE );
2746
2747 case LB_SELECTSTRING:
2748 {
2749 const WCHAR *textW = (const WCHAR *)lParam;
2750 INT index;
2751
2752 if (HAS_STRINGS(descr))
2753 TRACE("LB_SELECTSTRING: %s\n", debugstr_w(textW));
2754
2756 if (index != LB_ERR)
2757 {
2760 }
2761 return index;
2762 }
2763
2764 case LB_GETSEL:
2765 if (((INT)wParam < 0) || ((INT)wParam >= descr->nb_items))
2766 return LB_ERR;
2767 return descr->items[wParam].selected;
2768
2769 case LB_SETSEL:
2771
2772 case LB_SETCURSEL:
2773 if (IS_MULTISELECT(descr)) return LB_ERR;
2776 if (ret != LB_ERR) ret = descr->selected_item;
2777 return ret;
2778
2779 case LB_GETSELCOUNT:
2780 return LISTBOX_GetSelCount( descr );
2781
2782 case LB_GETSELITEMS:
2784
2785 case LB_SELITEMRANGE:
2786 if (LOWORD(lParam) <= HIWORD(lParam))
2788 HIWORD(lParam), wParam );
2789 else
2791 LOWORD(lParam), wParam );
2792
2793 case LB_SELITEMRANGEEX:
2794 if ((INT)lParam >= (INT)wParam)
2796 else
2798
2800 return descr->horz_extent;
2801
2804
2805 case LB_GETANCHORINDEX:
2806 return descr->anchor_item;
2807
2808 case LB_SETANCHORINDEX:
2809 if (((INT)wParam < -1) || ((INT)wParam >= descr->nb_items))
2810 {
2812 return LB_ERR;
2813 }
2814 descr->anchor_item = (INT)wParam;
2815 return LB_OKAY;
2816
2817 case LB_DIR:
2818 return LISTBOX_Directory( descr, wParam, (const WCHAR *)lParam, msg == LB_DIR );
2819
2820 case LB_GETLOCALE:
2821 return descr->locale;
2822
2823 case LB_SETLOCALE:
2824 {
2825 LCID ret;
2827 return LB_ERR;
2828 ret = descr->locale;
2829 descr->locale = (LCID)wParam;
2830 return ret;
2831 }
2832
2833 case LB_INITSTORAGE:
2834 return LISTBOX_InitStorage( descr, wParam );
2835
2836 case LB_SETCOUNT:
2837 return LISTBOX_SetCount( descr, (INT)wParam );
2838
2839 case LB_SETTABSTOPS:
2841
2842 case LB_CARETON:
2843 if (descr->caret_on)
2844 return LB_OKAY;
2845 descr->caret_on = TRUE;
2846 if ((descr->focus_item != -1) && (descr->in_focus))
2847 LISTBOX_RepaintItem( descr, descr->focus_item, ODA_FOCUS );
2848 return LB_OKAY;
2849
2850 case LB_CARETOFF:
2851 if (!descr->caret_on)
2852 return LB_OKAY;
2853 descr->caret_on = FALSE;
2854 if ((descr->focus_item != -1) && (descr->in_focus))
2855 LISTBOX_RepaintItem( descr, descr->focus_item, ODA_FOCUS );
2856 return LB_OKAY;
2857
2858 case LB_GETLISTBOXINFO:
2859 return descr->page_size;
2860
2861 case WM_DESTROY:
2862 return LISTBOX_Destroy( descr );
2863
2864 case WM_ENABLE:
2865 InvalidateRect( descr->self, NULL, TRUE );
2866 return 0;
2867
2868 case WM_SETREDRAW:
2870 return 0;
2871
2872 case WM_GETDLGCODE:
2874
2875 case WM_PRINTCLIENT:
2876 case WM_PAINT:
2877 {
2878 PAINTSTRUCT ps;
2879 HDC hdc = ( wParam ) ? ((HDC)wParam) : BeginPaint( descr->self, &ps );
2880 ret = LISTBOX_Paint( descr, hdc );
2881 if( !wParam ) EndPaint( descr->self, &ps );
2882 }
2883 return ret;
2884
2885 case WM_NCPAINT:
2886 LISTBOX_NCPaint( descr, (HRGN)wParam );
2887 break;
2888
2889 case WM_SIZE:
2891 return 0;
2892 case WM_GETFONT:
2893 return (LRESULT)descr->font;
2894 case WM_SETFONT:
2896 if (lParam) InvalidateRect( descr->self, 0, TRUE );
2897 return 0;
2898 case WM_SETFOCUS:
2899 descr->in_focus = TRUE;
2900 descr->caret_on = TRUE;
2901 if (descr->focus_item != -1)
2904 return 0;
2905 case WM_KILLFOCUS:
2906 LISTBOX_HandleLButtonUp( descr ); /* Release capture if we have it */
2907 descr->in_focus = FALSE;
2908 descr->wheel_remain = 0;
2909 if ((descr->focus_item != -1) && descr->caret_on)
2910 LISTBOX_RepaintItem( descr, descr->focus_item, ODA_FOCUS );
2912 return 0;
2913 case WM_HSCROLL:
2915 case WM_VSCROLL:
2917 case WM_MOUSEWHEEL:
2918 if (wParam & (MK_SHIFT | MK_CONTROL))
2919 return DefWindowProcW( descr->self, msg, wParam, lParam );
2921 case WM_LBUTTONDOWN:
2922 if (lphc)
2925 (INT16)HIWORD(lParam) );
2928 (INT16)HIWORD(lParam) );
2929 case WM_LBUTTONDBLCLK:
2930 if (lphc)
2933 (INT16)HIWORD(lParam) );
2934 if (descr->style & LBS_NOTIFY)
2936 return 0;
2937 case WM_MOUSEMOVE:
2938 if ( lphc && ((lphc->dwStyle & CBS_DROPDOWNLIST) != CBS_SIMPLE) )
2939 {
2940 BOOL captured = descr->captured;
2941 POINT mousePos;
2942 RECT clientRect;
2943
2944 mousePos.x = (INT16)LOWORD(lParam);
2945 mousePos.y = (INT16)HIWORD(lParam);
2946
2947 /*
2948 * If we are in a dropdown combobox, we simulate that
2949 * the mouse is captured to show the tracking of the item.
2950 */
2951 if (GetClientRect(descr->self, &clientRect) && PtInRect( &clientRect, mousePos ))
2952 descr->captured = TRUE;
2953
2954 LISTBOX_HandleMouseMove( descr, mousePos.x, mousePos.y);
2955
2956 descr->captured = captured;
2957 }
2958 else if (GetCapture() == descr->self)
2959 {
2961 (INT16)HIWORD(lParam) );
2962 }
2963 return 0;
2964 case WM_LBUTTONUP:
2965 if (lphc)
2966 {
2967 POINT mousePos;
2968 RECT clientRect;
2969
2970 /*
2971 * If the mouse button "up" is not in the listbox,
2972 * we make sure there is no selection by re-selecting the
2973 * item that was selected when the listbox was made visible.
2974 */
2975 mousePos.x = (INT16)LOWORD(lParam);
2976 mousePos.y = (INT16)