From 7462099847e88cd330e606e376422b0a2fff2a3a Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Tue, 9 Jan 2001 21:51:04 +0000 Subject: [PATCH] Added unicode window proc for the listbox control. Replaced all ansi calls by their unicode equivalents. Removed use of the custom local heap. --- controls/combo.c | 24 +-- controls/listbox.c | 566 +++++++++++++++++++++++++++++++-------------------- dlls/user/controls.h | 2 - 3 files changed, 351 insertions(+), 241 deletions(-) diff --git a/controls/combo.c b/controls/combo.c index b8869937525..419f92f93db 100644 --- a/controls/combo.c +++ b/controls/combo.c @@ -2005,7 +2005,7 @@ static LRESULT ComboWndProc_locked( WND* pWnd, UINT message, if ((wParam == VK_RETURN || wParam == VK_ESCAPE) && (lphc->wState & CBF_DROPPED)) { - CBRollUp( lphc, (CHAR)wParam == VK_RETURN, FALSE ); + CBRollUp( lphc, wParam == VK_RETURN, FALSE ); return TRUE; } @@ -2136,25 +2136,13 @@ static LRESULT ComboWndProc_locked( WND* pWnd, UINT message, return (lphc->wState & CBF_DROPPED) ? TRUE : FALSE; case CB_DIR16: lParam = (LPARAM)MapSL(lParam); + message = LB_DIR16; /* fall through */ case CB_DIR: - { - LRESULT res; - LPSTR dir; /* temporary, until listbox is unicoded */ - if(unicode) - { - LPWSTR textW = (LPWSTR)lParam; - INT countA = WideCharToMultiByte(CP_ACP, 0, textW, -1, NULL, 0, NULL, NULL); - dir = HeapAlloc(GetProcessHeap(), 0, countA); - WideCharToMultiByte(CP_ACP, 0, textW, -1, dir, countA, NULL, NULL); - } - else - dir = (LPSTR)lParam; - res = COMBO_Directory(lphc, (UINT)wParam, dir, (message == CB_DIR)); - if(unicode) - HeapFree(GetProcessHeap(), 0, dir); - return res; - } + if(message == CB_DIR) message = LB_DIR; + return unicode ? SendMessageW(lphc->hWndLBox, message, wParam, lParam) : + SendMessageA(lphc->hWndLBox, message, wParam, lParam); + case CB_SHOWDROPDOWN16: case CB_SHOWDROPDOWN: if( CB_GETTYPE(lphc) != CBS_SIMPLE ) diff --git a/controls/listbox.c b/controls/listbox.c index 4742d4c4bd0..3e4d442c88f 100644 --- a/controls/listbox.c +++ b/controls/listbox.c @@ -11,9 +11,9 @@ #include "wingdi.h" #include "wine/winuser16.h" #include "wine/winbase16.h" +#include "wine/unicode.h" #include "winuser.h" #include "winerror.h" -#include "heap.h" #include "spy.h" #include "win.h" #include "controls.h" @@ -25,7 +25,6 @@ DECLARE_DEBUG_CHANNEL(combo); /* Unimplemented yet: * - LBS_USETABSTOPS - * - Unicode * - Locale handling * * Probably needs improvement: @@ -47,16 +46,15 @@ DECLARE_DEBUG_CHANNEL(combo); /* Item structure */ typedef struct { - LPSTR str; /* Item text */ + LPWSTR str; /* Item text */ BOOL selected; /* Is item selected? */ UINT height; /* Item height (only for OWNERDRAWVARIABLE) */ - DWORD data; /* User data */ + DWORD data; /* User data */ } LB_ITEMDATA; /* Listbox structure */ typedef struct { - HANDLE heap; /* Heap for this listbox */ HWND owner; /* Owner window to send notifications to */ UINT style; /* Window style */ INT width; /* Window width */ @@ -94,7 +92,7 @@ typedef struct ((descr)->style & LBS_MULTIPLESEL || ((descr)->style & LBS_EXTENDEDSEL)) #define SEND_NOTIFICATION(wnd,descr,code) \ - (SendMessageA( (descr)->owner, WM_COMMAND, \ + (SendMessageW( (descr)->owner, WM_COMMAND, \ MAKEWPARAM((wnd)->wIDmenu, (code)), (wnd)->hwndSelf )) #define ISWIN31 (LOWORD(GetVersion()) == 0x0a03) @@ -112,10 +110,11 @@ typedef enum static TIMER_DIRECTION LISTBOX_Timer = LB_TIMER_NONE; static LRESULT WINAPI ComboLBWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); +static LRESULT WINAPI ComboLBWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); static LRESULT WINAPI ListBoxWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); +static LRESULT WINAPI ListBoxWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ); -static LRESULT LISTBOX_GetItemRect( WND *wnd, LB_DESCR *descr, INT index, - RECT *rect ); +static LRESULT LISTBOX_GetItemRect( LB_DESCR *descr, INT index, RECT *rect ); /********************************************************************* * listbox class descriptor @@ -125,7 +124,7 @@ const struct builtin_class_descr LISTBOX_builtin_class = "ListBox", /* name */ CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/, /* style */ ListBoxWndProcA, /* procA */ - NULL, /* procW (FIXME) */ + ListBoxWndProcW, /* procW */ sizeof(LB_DESCR *), /* extra */ IDC_ARROWA, /* cursor */ 0 /* brush */ @@ -140,7 +139,7 @@ const struct builtin_class_descr COMBOLBOX_builtin_class = "ComboLBox", /* name */ CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS, /* style */ ComboLBWndProcA, /* procA */ - NULL, /* procW (FIXME) */ + ComboLBWndProcW, /* procW */ sizeof(LB_DESCR *), /* extra */ IDC_ARROWA, /* cursor */ 0 /* brush */ @@ -157,13 +156,13 @@ void LISTBOX_Dump( WND *wnd ) LB_DESCR *descr = *(LB_DESCR **)wnd->wExtra; TRACE( "Listbox:\n" ); - TRACE( "hwnd=%04x descr=%08x heap=%08x items=%d top=%d\n", - wnd->hwndSelf, (UINT)descr, descr->heap, descr->nb_items, + TRACE( "hwnd=%04x descr=%08x items=%d top=%d\n", + wnd->hwndSelf, (UINT)descr, descr->nb_items, descr->top_item ); for (i = 0, item = descr->items; i < descr->nb_items; i++, item++) { TRACE( "%4d: %-40s %d %08lx %3d\n", - i, item->str, item->selected, item->data, item->height ); + i, debugstr_w(item->str), item->selected, item->data, item->height ); } } @@ -173,7 +172,7 @@ void LISTBOX_Dump( WND *wnd ) * * Return the current page size */ -static INT LISTBOX_GetCurrentPageSize( WND *wnd, LB_DESCR *descr ) +static INT LISTBOX_GetCurrentPageSize( LB_DESCR *descr ) { INT i, height; if (!(descr->style & LBS_OWNERDRAWVARIABLE)) return descr->page_size; @@ -191,7 +190,7 @@ static INT LISTBOX_GetCurrentPageSize( WND *wnd, LB_DESCR *descr ) * * Return the maximum possible index for the top of the listbox. */ -static INT LISTBOX_GetMaxTopIndex( WND *wnd, LB_DESCR *descr ) +static INT LISTBOX_GetMaxTopIndex( LB_DESCR *descr ) { INT max, page; @@ -267,7 +266,7 @@ static void LISTBOX_UpdateScroll( WND *wnd, LB_DESCR *descr ) info.nMin = 0; info.nMax = descr->nb_items - 1; info.nPos = descr->top_item; - info.nPage = LISTBOX_GetCurrentPageSize( wnd, descr ); + info.nPage = LISTBOX_GetCurrentPageSize( descr ); info.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; if (descr->style & LBS_DISABLENOSCROLL) info.fMask |= SIF_DISABLENOSCROLL; @@ -285,7 +284,6 @@ static void LISTBOX_UpdateScroll( WND *wnd, LB_DESCR *descr ) info.fMask |= SIF_DISABLENOSCROLL; if (descr->style & WS_HSCROLL) SetScrollInfo( wnd->hwndSelf, SB_HORZ, &info, TRUE ); - } } } @@ -299,7 +297,7 @@ static void LISTBOX_UpdateScroll( WND *wnd, LB_DESCR *descr ) static LRESULT LISTBOX_SetTopItem( WND *wnd, LB_DESCR *descr, INT index, BOOL scroll ) { - INT max = LISTBOX_GetMaxTopIndex( wnd, descr ); + INT max = LISTBOX_GetMaxTopIndex( descr ); if (index > max) index = max; if (index < 0) index = 0; if (descr->style & LBS_MULTICOLUMN) index -= index % descr->page_size; @@ -383,7 +381,7 @@ static void LISTBOX_UpdateSize( WND *wnd, LB_DESCR *descr ) descr->height = rect.bottom - rect.top; if (!(descr->style & LBS_NOINTEGRALHEIGHT) && !(descr->style & LBS_OWNERDRAWVARIABLE)) { - UINT remaining; + INT remaining; if(descr->item_height != 0) remaining = descr->height % descr->item_height; @@ -415,7 +413,7 @@ static void LISTBOX_UpdateSize( WND *wnd, LB_DESCR *descr ) LISTBOX_UpdateScroll( wnd, descr ); /* Invalidate the focused item so it will be repainted correctly */ - if (1==LISTBOX_GetItemRect( wnd, descr, descr->focus_item, &rect )) + if (LISTBOX_GetItemRect( descr, descr->focus_item, &rect ) == 1) { InvalidateRect( wnd->hwndSelf, &rect, FALSE ); } @@ -428,8 +426,7 @@ static void LISTBOX_UpdateSize( WND *wnd, LB_DESCR *descr ) * Get the rectangle enclosing an item, in listbox client coordinates. * Return 1 if the rectangle is (partially) visible, 0 if hidden, -1 on error. */ -static LRESULT LISTBOX_GetItemRect( WND *wnd, LB_DESCR *descr, INT index, - RECT *rect ) +static LRESULT LISTBOX_GetItemRect( LB_DESCR *descr, INT index, RECT *rect ) { /* Index <= 0 is legal even on empty listboxes */ if (index && (index >= descr->nb_items)) return -1; @@ -480,8 +477,7 @@ static LRESULT LISTBOX_GetItemRect( WND *wnd, LB_DESCR *descr, INT index, * * Return the item nearest from point (x,y) (in client coordinates). */ -static INT LISTBOX_GetItemFromPoint( WND *wnd, LB_DESCR *descr, - INT x, INT y ) +static INT LISTBOX_GetItemFromPoint( LB_DESCR *descr, INT x, INT y ) { INT index = descr->top_item; @@ -574,10 +570,10 @@ static void LISTBOX_PaintItem( WND *wnd, LB_DESCR *descr, HDC hdc, dis.rcItem = *rect; TRACE("[%04x]: drawitem %d (%s) action=%02x " "state=%02x rect=%d,%d-%d,%d\n", - wnd->hwndSelf, index, item ? item->str : "", action, + wnd->hwndSelf, index, item ? debugstr_w(item->str) : "", action, dis.itemState, rect->left, rect->top, rect->right, rect->bottom ); - SendMessageA(descr->owner, WM_DRAWITEM, wnd->wIDmenu, (LPARAM)&dis); + SendMessageW(descr->owner, WM_DRAWITEM, wnd->wIDmenu, (LPARAM)&dis); } else { @@ -596,23 +592,23 @@ static void LISTBOX_PaintItem( WND *wnd, LB_DESCR *descr, HDC hdc, TRACE("[%04x]: painting %d (%s) action=%02x " "rect=%d,%d-%d,%d\n", - wnd->hwndSelf, index, item ? item->str : "", action, + wnd->hwndSelf, index, item ? debugstr_w(item->str) : "", action, rect->left, rect->top, rect->right, rect->bottom ); if (!item) - ExtTextOutA( hdc, rect->left + 1, rect->top, + ExtTextOutW( hdc, rect->left + 1, rect->top, ETO_OPAQUE | ETO_CLIPPED, rect, NULL, 0, NULL ); - else if (!(descr->style & LBS_USETABSTOPS)) - ExtTextOutA( hdc, rect->left + 1, rect->top, - ETO_OPAQUE | ETO_CLIPPED, rect, item->str, - strlen(item->str), NULL ); + else if (!(descr->style & LBS_USETABSTOPS)) + ExtTextOutW( hdc, rect->left + 1, rect->top, + ETO_OPAQUE | ETO_CLIPPED, rect, item->str, + strlenW(item->str), NULL ); else { /* Output empty string to paint background in the full width. */ - ExtTextOutA( hdc, rect->left + 1, rect->top, - ETO_OPAQUE | ETO_CLIPPED, rect, NULL, 0, NULL ); - TabbedTextOutA( hdc, rect->left + 1 , rect->top, - item->str, strlen(item->str), - descr->nb_tabs, descr->tabs, 0); + ExtTextOutW( hdc, rect->left + 1, rect->top, + ETO_OPAQUE | ETO_CLIPPED, rect, NULL, 0, NULL ); + TabbedTextOutW( hdc, rect->left + 1 , rect->top, + item->str, strlenW(item->str), + descr->nb_tabs, descr->tabs, 0); } if (item && item->selected) { @@ -669,14 +665,14 @@ static void LISTBOX_RepaintItem( WND *wnd, LB_DESCR *descr, INT index, /* Do not repaint the item if the item is not visible */ if (!IsWindowVisible(wnd->hwndSelf)) return; if (descr->style & LBS_NOREDRAW) - { + { descr->style |= LBS_DISPLAYCHANGED; return; - } - if (LISTBOX_GetItemRect( wnd, descr, index, &rect ) != 1) return; + } + if (LISTBOX_GetItemRect( descr, index, &rect ) != 1) return; if (!(hdc = GetDCEx( wnd->hwndSelf, 0, DCX_CACHE ))) return; if (descr->font) oldFont = SelectObject( hdc, descr->font ); - hbrush = SendMessageA( descr->owner, WM_CTLCOLORLISTBOX, + hbrush = SendMessageW( descr->owner, WM_CTLCOLORLISTBOX, hdc, (LPARAM)wnd->hwndSelf ); if (hbrush) oldBrush = SelectObject( hdc, hbrush ); if (wnd->dwStyle & WS_DISABLED) @@ -692,16 +688,15 @@ static void LISTBOX_RepaintItem( WND *wnd, LB_DESCR *descr, INT index, /*********************************************************************** * LISTBOX_InitStorage */ -static LRESULT LISTBOX_InitStorage( WND *wnd, LB_DESCR *descr, INT nb_items, - DWORD bytes ) +static LRESULT LISTBOX_InitStorage( WND *wnd, LB_DESCR *descr, INT nb_items ) { LB_ITEMDATA *item; nb_items += LB_ARRAY_GRANULARITY - 1; nb_items -= (nb_items % LB_ARRAY_GRANULARITY); if (descr->items) - nb_items += HeapSize( descr->heap, 0, descr->items ) / sizeof(*item); - if (!(item = HeapReAlloc( descr->heap, 0, descr->items, + nb_items += HeapSize( GetProcessHeap(), 0, descr->items ) / sizeof(*item); + if (!(item = HeapReAlloc( GetProcessHeap(), 0, descr->items, nb_items * sizeof(LB_ITEMDATA) ))) { SEND_NOTIFICATION( wnd, descr, LBN_ERRSPACE ); @@ -719,14 +714,14 @@ static BOOL LISTBOX_SetTabStops( WND *wnd, LB_DESCR *descr, INT count, LPINT tabs, BOOL short_ints ) { if (!(descr->style & LBS_USETABSTOPS)) return TRUE; - if (descr->tabs) HeapFree( descr->heap, 0, descr->tabs ); + if (descr->tabs) HeapFree( GetProcessHeap(), 0, descr->tabs ); if (!(descr->nb_tabs = count)) { descr->tabs = NULL; return TRUE; } /* FIXME: count = 1 */ - if (!(descr->tabs = (INT *)HeapAlloc( descr->heap, 0, + if (!(descr->tabs = (INT *)HeapAlloc( GetProcessHeap(), 0, descr->nb_tabs * sizeof(INT) ))) return FALSE; if (short_ints) @@ -750,19 +745,28 @@ static BOOL LISTBOX_SetTabStops( WND *wnd, LB_DESCR *descr, INT count, /*********************************************************************** * LISTBOX_GetText */ -static LRESULT LISTBOX_GetText( WND *wnd, LB_DESCR *descr, INT index, - LPSTR buffer ) +static LRESULT LISTBOX_GetText( LB_DESCR *descr, INT index, LPARAM lParam, BOOL unicode ) { if ((index < 0) || (index >= descr->nb_items)) return LB_ERR; if (HAS_STRINGS(descr)) { - if (!buffer) - return strlen(descr->items[index].str); - strcpy( buffer, descr->items[index].str ); - return strlen(buffer); + if (!lParam) + return strlenW(descr->items[index].str); + + if(unicode) + { + LPWSTR buffer = (LPWSTR)lParam; + strcpyW( buffer, descr->items[index].str ); + return strlenW(buffer); + } + else + { + LPSTR buffer = (LPSTR)lParam; + return WideCharToMultiByte(CP_ACP, 0, descr->items[index].str, -1, buffer, 0x7FFFFFFF, NULL, NULL); + } } else { - if (buffer) - *((LPDWORD)buffer)=*(LPDWORD)(&descr->items[index].data); + if (lParam) + *((LPDWORD)lParam)=*(LPDWORD)(&descr->items[index].data); return sizeof(DWORD); } } @@ -774,7 +778,7 @@ static LRESULT LISTBOX_GetText( WND *wnd, LB_DESCR *descr, INT index, * Find the nearest string located before a given string in sort order. * If 'exact' is TRUE, return an error if we don't get an exact match. */ -static INT LISTBOX_FindStringPos( WND *wnd, LB_DESCR *descr, LPCSTR str, +static INT LISTBOX_FindStringPos( WND *wnd, LB_DESCR *descr, LPCWSTR str, BOOL exact ) { INT index, min, max, res = -1; @@ -786,7 +790,7 @@ static INT LISTBOX_FindStringPos( WND *wnd, LB_DESCR *descr, LPCSTR str, { index = (min + max) / 2; if (HAS_STRINGS(descr)) - res = lstrcmpiA( descr->items[index].str, str ); + res = lstrcmpiW( descr->items[index].str, str ); else { COMPAREITEMSTRUCT cis; @@ -799,7 +803,7 @@ static INT LISTBOX_FindStringPos( WND *wnd, LB_DESCR *descr, LPCSTR str, cis.itemID2 = -1; cis.itemData2 = (DWORD)str; cis.dwLocaleId = descr->locale; - res = SendMessageA( descr->owner, WM_COMPAREITEM, + res = SendMessageW( descr->owner, WM_COMPAREITEM, wnd->wIDmenu, (LPARAM)&cis ); } if (!res) return index; @@ -816,7 +820,7 @@ static INT LISTBOX_FindStringPos( WND *wnd, LB_DESCR *descr, LPCSTR str, * Find the nearest string located before a given string in directory * sort order (i.e. first files, then directories, then drives). */ -static INT LISTBOX_FindFileStrPos( WND *wnd, LB_DESCR *descr, LPCSTR str ) +static INT LISTBOX_FindFileStrPos( WND *wnd, LB_DESCR *descr, LPCWSTR str ) { INT min, max, res = -1; @@ -827,7 +831,7 @@ static INT LISTBOX_FindFileStrPos( WND *wnd, LB_DESCR *descr, LPCSTR str ) while (min != max) { INT index = (min + max) / 2; - const char *p = descr->items[index].str; + LPCWSTR p = descr->items[index].str; if (*p == '[') /* drive or directory */ { if (*str != '[') res = -1; @@ -839,13 +843,13 @@ static INT LISTBOX_FindFileStrPos( WND *wnd, LB_DESCR *descr, LPCSTR str ) else /* directory */ { if (str[1] == '-') res = 1; - else res = lstrcmpiA( str, p ); + else res = lstrcmpiW( str, p ); } } else /* filename */ { if (*str == '[') res = 1; - else res = lstrcmpiA( str, p ); + else res = lstrcmpiW( str, p ); } if (!res) return index; if (res < 0) max = index; @@ -861,7 +865,7 @@ static INT LISTBOX_FindFileStrPos( WND *wnd, LB_DESCR *descr, LPCSTR str ) * Find the item beginning with a given string. */ static INT LISTBOX_FindString( WND *wnd, LB_DESCR *descr, INT start, - LPCSTR str, BOOL exact ) + LPCWSTR str, BOOL exact ) { INT i; LB_ITEMDATA *item; @@ -874,9 +878,9 @@ static INT LISTBOX_FindString( WND *wnd, LB_DESCR *descr, INT start, if (exact) { for (i = start + 1; i < descr->nb_items; i++, item++) - if (!lstrcmpiA( str, item->str )) return i; + if (!lstrcmpiW( str, item->str )) return i; for (i = 0, item = descr->items; i <= start; i++, item++) - if (!lstrcmpiA( str, item->str )) return i; + if (!lstrcmpiW( str, item->str )) return i; } else { @@ -884,20 +888,20 @@ static INT LISTBOX_FindString( WND *wnd, LB_DESCR *descr, INT start, #define CHECK_DRIVE(item) \ if ((item)->str[0] == '[') \ { \ - if (!strncasecmp( str, (item)->str+1, len )) return i; \ - if (((item)->str[1] == '-') && !strncasecmp(str,(item)->str+2,len)) \ + if (!strncmpiW( str, (item)->str+1, len )) return i; \ + if (((item)->str[1] == '-') && !strncmpiW(str, (item)->str+2, len)) \ return i; \ } - INT len = strlen(str); + INT len = strlenW(str); for (i = start + 1; i < descr->nb_items; i++, item++) { - if (!strncasecmp( str, item->str, len )) return i; + if (!strncmpiW( str, item->str, len )) return i; CHECK_DRIVE(item); } for (i = 0, item = descr->items; i <= start; i++, item++) { - if (!strncasecmp( str, item->str, len )) return i; + if (!strncmpiW( str, item->str, len )) return i; CHECK_DRIVE(item); } #undef CHECK_DRIVE @@ -922,7 +926,7 @@ static INT LISTBOX_FindString( WND *wnd, LB_DESCR *descr, INT start, /*********************************************************************** * LISTBOX_GetSelCount */ -static LRESULT LISTBOX_GetSelCount( WND *wnd, LB_DESCR *descr ) +static LRESULT LISTBOX_GetSelCount( LB_DESCR *descr ) { INT i, count; LB_ITEMDATA *item = descr->items; @@ -937,8 +941,7 @@ static LRESULT LISTBOX_GetSelCount( WND *wnd, LB_DESCR *descr ) /*********************************************************************** * LISTBOX_GetSelItems16 */ -static LRESULT LISTBOX_GetSelItems16( WND *wnd, LB_DESCR *descr, INT16 max, - LPINT16 array ) +static LRESULT LISTBOX_GetSelItems16( LB_DESCR *descr, INT16 max, LPINT16 array ) { INT i, count; LB_ITEMDATA *item = descr->items; @@ -951,10 +954,9 @@ static LRESULT LISTBOX_GetSelItems16( WND *wnd, LB_DESCR *descr, INT16 max, /*********************************************************************** - * LISTBOX_GetSelItems32 + * LISTBOX_GetSelItems */ -static LRESULT LISTBOX_GetSelItems( WND *wnd, LB_DESCR *descr, INT max, - LPINT array ) +static LRESULT LISTBOX_GetSelItems( LB_DESCR *descr, INT max, LPINT array ) { INT i, count; LB_ITEMDATA *item = descr->items; @@ -989,7 +991,7 @@ static LRESULT LISTBOX_Paint( WND *wnd, LB_DESCR *descr, HDC hdc ) } if (descr->font) oldFont = SelectObject( hdc, descr->font ); - hbrush = SendMessageA( descr->owner, WM_CTLCOLORLISTBOX, + hbrush = SendMessageW( descr->owner, WM_CTLCOLORLISTBOX, hdc, (LPARAM)wnd->hwndSelf ); if (hbrush) oldBrush = SelectObject( hdc, hbrush ); if (wnd->dwStyle & WS_DISABLED) @@ -1034,7 +1036,7 @@ static LRESULT LISTBOX_Paint( WND *wnd, LB_DESCR *descr, HDC hdc ) if (rect.top < descr->height) { rect.bottom = descr->height; - ExtTextOutA( hdc, 0, 0, ETO_OPAQUE | ETO_CLIPPED, + ExtTextOutW( hdc, 0, 0, ETO_OPAQUE | ETO_CLIPPED, &rect, NULL, 0, NULL ); } } @@ -1062,7 +1064,7 @@ static LRESULT LISTBOX_Paint( WND *wnd, LB_DESCR *descr, HDC hdc ) if (rect.top < descr->height) { rect.bottom = descr->height; - ExtTextOutA( hdc, 0, 0, ETO_OPAQUE | ETO_CLIPPED, + ExtTextOutW( hdc, 0, 0, ETO_OPAQUE | ETO_CLIPPED, &rect, NULL, 0, NULL ); } if (rect.right < descr->width) @@ -1071,7 +1073,7 @@ static LRESULT LISTBOX_Paint( WND *wnd, LB_DESCR *descr, HDC hdc ) rect.right = descr->width; rect.top = 0; rect.bottom = descr->height; - ExtTextOutA( hdc, 0, 0, ETO_OPAQUE | ETO_CLIPPED, + ExtTextOutW( hdc, 0, 0, ETO_OPAQUE | ETO_CLIPPED, &rect, NULL, 0, NULL ); } } @@ -1091,7 +1093,7 @@ static void LISTBOX_InvalidateItems( WND *wnd, LB_DESCR *descr, INT index ) { RECT rect; - if (LISTBOX_GetItemRect( wnd, descr, index, &rect ) == 1) + if (LISTBOX_GetItemRect( descr, index, &rect ) == 1) { if (descr->style & LBS_NOREDRAW) { @@ -1115,7 +1117,7 @@ static void LISTBOX_InvalidateItems( WND *wnd, LB_DESCR *descr, INT index ) /*********************************************************************** * LISTBOX_GetItemHeight */ -static LRESULT LISTBOX_GetItemHeight( WND *wnd, LB_DESCR *descr, INT index ) +static LRESULT LISTBOX_GetItemHeight( LB_DESCR *descr, INT index ) { if (descr->style & LBS_OWNERDRAWVARIABLE) { @@ -1130,7 +1132,7 @@ static LRESULT LISTBOX_GetItemHeight( WND *wnd, LB_DESCR *descr, INT index ) * LISTBOX_SetItemHeight */ static LRESULT LISTBOX_SetItemHeight( WND *wnd, LB_DESCR *descr, INT index, - UINT height ) + INT height ) { if (!height) height = 1; @@ -1183,7 +1185,7 @@ static void LISTBOX_SetHorizontalPos( WND *wnd, LB_DESCR *descr, INT pos ) * LISTBOX_SetHorizontalExtent */ static LRESULT LISTBOX_SetHorizontalExtent( WND *wnd, LB_DESCR *descr, - UINT extent ) + INT extent ) { if (!descr->horz_extent || (descr->style & LBS_MULTICOLUMN)) return LB_OKAY; @@ -1203,7 +1205,7 @@ static LRESULT LISTBOX_SetHorizontalExtent( WND *wnd, LB_DESCR *descr, /*********************************************************************** * LISTBOX_SetColumnWidth */ -static LRESULT LISTBOX_SetColumnWidth( WND *wnd, LB_DESCR *descr, UINT width) +static LRESULT LISTBOX_SetColumnWidth( WND *wnd, LB_DESCR *descr, INT width) { if (width == descr->column_width) return LB_OKAY; TRACE("[%04x]: new column width = %d\n", @@ -1223,7 +1225,7 @@ static INT LISTBOX_SetFont( WND *wnd, LB_DESCR *descr, HFONT font ) { HDC hdc; HFONT oldFont = 0; - TEXTMETRICA tm; + TEXTMETRICW tm; descr->font = font; @@ -1233,7 +1235,7 @@ static INT LISTBOX_SetFont( WND *wnd, LB_DESCR *descr, HFONT font ) return 16; } if (font) oldFont = SelectObject( hdc, font ); - GetTextMetricsA( hdc, &tm ); + GetTextMetricsW( hdc, &tm ); if (oldFont) SelectObject( hdc, oldFont ); ReleaseDC( wnd->hwndSelf, hdc ); if (!IS_OWNERDRAW(descr)) @@ -1441,7 +1443,7 @@ static void LISTBOX_MoveCaret( WND *wnd, LB_DESCR *descr, INT index, * LISTBOX_InsertItem */ static LRESULT LISTBOX_InsertItem( WND *wnd, LB_DESCR *descr, INT index, - LPSTR str, DWORD data ) + LPWSTR str, DWORD data ) { LB_ITEMDATA *item; INT max_items; @@ -1450,12 +1452,12 @@ static LRESULT LISTBOX_InsertItem( WND *wnd, LB_DESCR *descr, INT index, if (index == -1) index = descr->nb_items; else if ((index < 0) || (index > descr->nb_items)) return LB_ERR; if (!descr->items) max_items = 0; - else max_items = HeapSize( descr->heap, 0, descr->items ) / sizeof(*item); + else max_items = HeapSize( GetProcessHeap(), 0, descr->items ) / sizeof(*item); if (descr->nb_items == max_items) { /* We need to grow the array */ max_items += LB_ARRAY_GRANULARITY; - if (!(item = HeapReAlloc( descr->heap, 0, descr->items, + if (!(item = HeapReAlloc( GetProcessHeap(), 0, descr->items, max_items * sizeof(LB_ITEMDATA) ))) { SEND_NOTIFICATION( wnd, descr, LBN_ERRSPACE ); @@ -1487,10 +1489,10 @@ static LRESULT LISTBOX_InsertItem( WND *wnd, LB_DESCR *descr, INT index, mis.itemID = index; mis.itemData = descr->items[index].data; mis.itemHeight = descr->item_height; - SendMessageA( descr->owner, WM_MEASUREITEM, wnd->wIDmenu, (LPARAM)&mis ); + SendMessageW( descr->owner, WM_MEASUREITEM, wnd->wIDmenu, (LPARAM)&mis ); item->height = mis.itemHeight ? mis.itemHeight : 1; TRACE("[%04x]: measure item %d (%s) = %d\n", - wnd->hwndSelf, index, str ? str : "", item->height ); + wnd->hwndSelf, index, str ? debugstr_w(str) : "", item->height ); } /* Repaint the items */ @@ -1524,32 +1526,34 @@ static LRESULT LISTBOX_InsertItem( WND *wnd, LB_DESCR *descr, INT index, * LISTBOX_InsertString */ static LRESULT LISTBOX_InsertString( WND *wnd, LB_DESCR *descr, INT index, - LPCSTR str ) + LPCWSTR str ) { - LPSTR new_str = NULL; + LPWSTR new_str = NULL; DWORD data = 0; LRESULT ret; if (HAS_STRINGS(descr)) { - if (!str) str=""; - if (!(new_str = HEAP_strdupA( descr->heap, 0, str ))) + static const WCHAR empty_stringW[] = { 0 }; + if (!str) str = empty_stringW; + if (!(new_str = HeapAlloc( GetProcessHeap(), 0, (strlenW(str) + 1) * sizeof(WCHAR) ))) { SEND_NOTIFICATION( wnd, descr, LBN_ERRSPACE ); return LB_ERRSPACE; } + strcpyW(new_str, str); } else data = (DWORD)str; if (index == -1) index = descr->nb_items; if ((ret = LISTBOX_InsertItem( wnd, descr, index, new_str, data )) != 0) { - if (new_str) HeapFree( descr->heap, 0, new_str ); + if (new_str) HeapFree( GetProcessHeap(), 0, new_str ); return ret; } TRACE("[%04x]: added item %d '%s'\n", - wnd->hwndSelf, index, HAS_STRINGS(descr) ? new_str : "" ); + wnd->hwndSelf, index, HAS_STRINGS(descr) ? debugstr_w(new_str) : "" ); return index; } @@ -1575,10 +1579,10 @@ static void LISTBOX_DeleteItem( WND *wnd, LB_DESCR *descr, INT index ) dis.itemID = index; dis.hwndItem = wnd->hwndSelf; dis.itemData = descr->items[index].data; - SendMessageA( descr->owner, WM_DELETEITEM, wnd->wIDmenu, (LPARAM)&dis ); + SendMessageW( descr->owner, WM_DELETEITEM, wnd->wIDmenu, (LPARAM)&dis ); } if (HAS_STRINGS(descr) && descr->items[index].str) - HeapFree( descr->heap, 0, descr->items[index].str ); + HeapFree( GetProcessHeap(), 0, descr->items[index].str ); } @@ -1611,11 +1615,11 @@ static LRESULT LISTBOX_RemoveItem( WND *wnd, LB_DESCR *descr, INT index ) /* Shrink the item array if possible */ - max_items = HeapSize( descr->heap, 0, descr->items ) / sizeof(LB_ITEMDATA); + max_items = HeapSize( GetProcessHeap(), 0, descr->items ) / sizeof(LB_ITEMDATA); if (descr->nb_items < max_items - 2*LB_ARRAY_GRANULARITY) { max_items -= LB_ARRAY_GRANULARITY; - item = HeapReAlloc( descr->heap, 0, descr->items, + item = HeapReAlloc( GetProcessHeap(), 0, descr->items, max_items * sizeof(LB_ITEMDATA) ); if (item) descr->items = item; } @@ -1657,7 +1661,7 @@ static void LISTBOX_ResetContent( WND *wnd, LB_DESCR *descr ) INT i; for (i = 0; i < descr->nb_items; i++) LISTBOX_DeleteItem( wnd, descr, i ); - if (descr->items) HeapFree( descr->heap, 0, descr->items ); + if (descr->items) HeapFree( GetProcessHeap(), 0, descr->items ); descr->nb_items = 0; descr->top_item = 0; descr->selected_item = -1; @@ -1696,17 +1700,17 @@ static LRESULT LISTBOX_SetCount( WND *wnd, LB_DESCR *descr, INT count ) * LISTBOX_Directory */ static LRESULT LISTBOX_Directory( WND *wnd, LB_DESCR *descr, UINT attrib, - LPCSTR filespec, BOOL long_names ) + LPCWSTR filespec, BOOL long_names ) { HANDLE handle; LRESULT ret = LB_OKAY; - WIN32_FIND_DATAA entry; + WIN32_FIND_DATAW entry; int pos; /* don't scan directory if we just want drives exclusively */ if (attrib != (DDL_DRIVES | DDL_EXCLUSIVE)) { /* scan directory */ - if ((handle = FindFirstFileA(filespec,&entry)) == INVALID_HANDLE_VALUE) + if ((handle = FindFirstFileW(filespec, &entry)) == INVALID_HANDLE_VALUE) { if (GetLastError() != ERROR_NO_MORE_FILES) return LB_ERR; } @@ -1714,13 +1718,17 @@ static LRESULT LISTBOX_Directory( WND *wnd, LB_DESCR *descr, UINT attrib, { do { - char buffer[270]; + WCHAR buffer[270]; if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + static const WCHAR bracketW[] = { ']',0 }; + static const WCHAR dotW[] = { '.',0 }; if (!(attrib & DDL_DIRECTORY) || - !strcmp( entry.cAlternateFileName, "." )) continue; - if (long_names) sprintf( buffer, "[%s]", entry.cFileName ); - else sprintf( buffer, "[%s]", entry.cAlternateFileName ); + !strcmpW( entry.cAlternateFileName, dotW )) continue; + buffer[0] = '['; + if (long_names) strcpyW( buffer + 1, entry.cFileName ); + else strcpyW( buffer + 1, entry.cAlternateFileName ); + strcatW(buffer, bracketW); } else /* not a directory */ { @@ -1731,14 +1739,14 @@ static LRESULT LISTBOX_Directory( WND *wnd, LB_DESCR *descr, UINT attrib, ((attrib & ATTRIBS) != (entry.dwFileAttributes & ATTRIBS))) continue; #undef ATTRIBS - if (long_names) strcpy( buffer, entry.cFileName ); - else strcpy( buffer, entry.cAlternateFileName ); + if (long_names) strcpyW( buffer, entry.cFileName ); + else strcpyW( buffer, entry.cAlternateFileName ); } - if (!long_names) CharLowerA( buffer ); + if (!long_names) CharLowerW( buffer ); pos = LISTBOX_FindFileStrPos( wnd, descr, buffer ); if ((ret = LISTBOX_InsertString( wnd, descr, pos, buffer )) < 0) break; - } while (FindNextFileA( handle, &entry )); + } while (FindNextFileW( handle, &entry )); FindClose( handle ); } } @@ -1746,12 +1754,12 @@ static LRESULT LISTBOX_Directory( WND *wnd, LB_DESCR *descr, UINT attrib, /* scan drives */ if ((ret >= 0) && (attrib & DDL_DRIVES)) { - char buffer[] = "[-a-]"; - char root[] = "A:\\"; + WCHAR buffer[] = {'[','-','a','-',']',0}; + WCHAR root[] = {'A',':','\\',0}; int drive; for (drive = 0; drive < 26; drive++, buffer[2]++, root[0]++) { - if (GetDriveTypeA(root) <= DRIVE_NO_ROOT_DIR) continue; + if (GetDriveTypeW(root) <= DRIVE_NO_ROOT_DIR) continue; if ((ret = LISTBOX_InsertString( wnd, descr, -1, buffer )) < 0) break; } @@ -1763,8 +1771,7 @@ static LRESULT LISTBOX_Directory( WND *wnd, LB_DESCR *descr, UINT attrib, /*********************************************************************** * LISTBOX_HandleVScroll */ -static LRESULT LISTBOX_HandleVScroll( WND *wnd, LB_DESCR *descr, - WPARAM wParam, LPARAM lParam ) +static LRESULT LISTBOX_HandleVScroll( WND *wnd, LB_DESCR *descr, WPARAM wParam ) { SCROLLINFO info; @@ -1779,11 +1786,11 @@ static LRESULT LISTBOX_HandleVScroll( WND *wnd, LB_DESCR *descr, break; case SB_PAGEUP: LISTBOX_SetTopItem( wnd, descr, descr->top_item - - LISTBOX_GetCurrentPageSize( wnd, descr ), TRUE ); + LISTBOX_GetCurrentPageSize( descr ), TRUE ); break; case SB_PAGEDOWN: LISTBOX_SetTopItem( wnd, descr, descr->top_item + - LISTBOX_GetCurrentPageSize( wnd, descr ), TRUE ); + LISTBOX_GetCurrentPageSize( descr ), TRUE ); break; case SB_THUMBPOSITION: LISTBOX_SetTopItem( wnd, descr, HIWORD(wParam), TRUE ); @@ -1808,8 +1815,7 @@ static LRESULT LISTBOX_HandleVScroll( WND *wnd, LB_DESCR *descr, /*********************************************************************** * LISTBOX_HandleHScroll */ -static LRESULT LISTBOX_HandleHScroll( WND *wnd, LB_DESCR *descr, - WPARAM wParam, LPARAM lParam ) +static LRESULT LISTBOX_HandleHScroll( WND *wnd, LB_DESCR *descr, WPARAM wParam ) { SCROLLINFO info; INT page; @@ -1896,7 +1902,7 @@ static LRESULT LISTBOX_HandleHScroll( WND *wnd, LB_DESCR *descr, return 0; } -static LRESULT LISTBOX_HandleMouseWheel(WND *wnd, LB_DESCR *descr,WPARAM wParam, LPARAM lParam ) +static LRESULT LISTBOX_HandleMouseWheel(WND *wnd, LB_DESCR *descr, WPARAM wParam ) { short gcWheelDelta = 0; UINT pulScrollLines = 3; @@ -1920,7 +1926,7 @@ static LRESULT LISTBOX_HandleMouseWheel(WND *wnd, LB_DESCR *descr,WPARAM wParam, static LRESULT LISTBOX_HandleLButtonDown( WND *wnd, LB_DESCR *descr, WPARAM wParam, INT x, INT y ) { - INT index = LISTBOX_GetItemFromPoint( wnd, descr, x, y ); + INT index = LISTBOX_GetItemFromPoint( descr, x, y ); TRACE("[%04x]: lbuttondown %d,%d item %d\n", wnd->hwndSelf, x, y, index ); if (!descr->caret_on && (descr->in_focus)) return 0; @@ -1967,7 +1973,7 @@ static LRESULT LISTBOX_HandleLButtonDown( WND *wnd, LB_DESCR *descr, if (!descr->lphc) { if (descr->style & LBS_NOTIFY ) - SendMessageA( descr->owner, WM_LBTRACKPOINT, index, + SendMessageW( descr->owner, WM_LBTRACKPOINT, index, MAKELPARAM( x, y ) ); if (wnd->dwExStyle & WS_EX_DRAGDETECT) { @@ -1977,7 +1983,7 @@ static LRESULT LISTBOX_HandleLButtonDown( WND *wnd, LB_DESCR *descr, pt.y = y; if (DragDetect( wnd->hwndSelf, pt )) - SendMessageA( descr->owner, WM_BEGINDRAG, 0, 0 ); + SendMessageW( descr->owner, WM_BEGINDRAG, 0, 0 ); } } return 0; @@ -2071,7 +2077,7 @@ static LRESULT LISTBOX_HandleLButtonDownCombo( WND *pWnd, LB_DESCR *pDescr, if(nHitTestType != 0) { - SendMessageA(pWnd->hwndSelf, WM_NCLBUTTONDOWN, nHitTestType, + SendMessageW(pWnd->hwndSelf, WM_NCLBUTTONDOWN, nHitTestType, MAKELONG(screenMousePos.x, screenMousePos.y)); } /* Resume the Capture after scrolling is complete @@ -2123,7 +2129,7 @@ static LRESULT LISTBOX_HandleTimer( WND *wnd, LB_DESCR *descr, if (descr->top_item) index -= descr->page_size; break; case LB_TIMER_DOWN: - index = descr->top_item + LISTBOX_GetCurrentPageSize( wnd, descr ); + index = descr->top_item + LISTBOX_GetCurrentPageSize( descr ); if (index == descr->focus_item) index++; if (index >= descr->nb_items) index = descr->nb_items - 1; break; @@ -2192,7 +2198,7 @@ static void LISTBOX_HandleMouseMove( WND *wnd, LB_DESCR *descr, else if (y >= descr->height) dir = LB_TIMER_DOWN; /* below */ } - index = LISTBOX_GetItemFromPoint( wnd, descr, x, y ); + index = LISTBOX_GetItemFromPoint( descr, x, y ); if (index == -1) index = descr->focus_item; if (!LISTBOX_HandleTimer( wnd, descr, index, dir )) dir = LB_TIMER_NONE; @@ -2218,7 +2224,7 @@ static LRESULT LISTBOX_HandleKeyDown( WND *wnd, LB_DESCR *descr, WPARAM wParam ) if (descr->style & LBS_WANTKEYBOARDINPUT) { - caret = SendMessageA( descr->owner, WM_VKEYTOITEM, + caret = SendMessageW( descr->owner, WM_VKEYTOITEM, MAKEWPARAM(LOWORD(wParam), descr->focus_item), wnd->hwndSelf ); if (caret == -2) return 0; @@ -2259,7 +2265,7 @@ static LRESULT LISTBOX_HandleKeyDown( WND *wnd, LB_DESCR *descr, WPARAM wParam ) if (page < 1) page = 1; caret = descr->focus_item - (page * descr->page_size) + 1; } - else caret = descr->focus_item-LISTBOX_GetCurrentPageSize(wnd,descr)+1; + else caret = descr->focus_item-LISTBOX_GetCurrentPageSize(descr) + 1; if (caret < 0) caret = 0; break; case VK_NEXT: @@ -2269,7 +2275,7 @@ static LRESULT LISTBOX_HandleKeyDown( WND *wnd, LB_DESCR *descr, WPARAM wParam ) if (page < 1) page = 1; caret = descr->focus_item + (page * descr->page_size) - 1; } - else caret = descr->focus_item+LISTBOX_GetCurrentPageSize(wnd,descr)-1; + else caret = descr->focus_item + LISTBOX_GetCurrentPageSize(descr) - 1; if (caret >= descr->nb_items) caret = descr->nb_items - 1; break; case VK_HOME: @@ -2316,19 +2322,18 @@ static LRESULT LISTBOX_HandleKeyDown( WND *wnd, LB_DESCR *descr, WPARAM wParam ) /*********************************************************************** * LISTBOX_HandleChar */ -static LRESULT LISTBOX_HandleChar( WND *wnd, LB_DESCR *descr, - WPARAM wParam ) +static LRESULT LISTBOX_HandleChar( WND *wnd, LB_DESCR *descr, WCHAR charW ) { INT caret = -1; - char str[2]; - - str[0] = wParam & 0xff; + WCHAR str[2]; + + str[0] = charW; str[1] = '\0'; if (descr->style & LBS_WANTKEYBOARDINPUT) { - caret = SendMessageA( descr->owner, WM_CHARTOITEM, - MAKEWPARAM(LOWORD(wParam), descr->focus_item), + caret = SendMessageW( descr->owner, WM_CHARTOITEM, + MAKEWPARAM(charW, descr->focus_item), wnd->hwndSelf ); if (caret == -2) return 0; } @@ -2357,11 +2362,7 @@ static BOOL LISTBOX_Create( WND *wnd, LPHEADCOMBO lphc ) if (!(descr = HeapAlloc( GetProcessHeap(), 0, sizeof(*descr) ))) return FALSE; - if (!(descr->heap = HeapCreate( 0, 0x10000, 0 ))) - { - HeapFree( GetProcessHeap(), 0, descr ); - return FALSE; - } + GetClientRect( wnd->hwndSelf, &rect ); descr->owner = GetParent( wnd->hwndSelf ); descr->style = wnd->dwStyle; @@ -2430,7 +2431,7 @@ static BOOL LISTBOX_Create( WND *wnd, LPHEADCOMBO lphc ) mis.itemWidth = 0; mis.itemData = 0; mis.itemHeight = descr->item_height; - SendMessageA( descr->owner, WM_MEASUREITEM, wnd->wIDmenu, (LPARAM)&mis ); + SendMessageW( descr->owner, WM_MEASUREITEM, wnd->wIDmenu, (LPARAM)&mis ); descr->item_height = mis.itemHeight ? mis.itemHeight : 1; } } @@ -2446,7 +2447,6 @@ static BOOL LISTBOX_Create( WND *wnd, LPHEADCOMBO lphc ) static BOOL LISTBOX_Destroy( WND *wnd, LB_DESCR *descr ) { LISTBOX_ResetContent( wnd, descr ); - HeapDestroy( descr->heap ); HeapFree( GetProcessHeap(), 0, descr ); wnd->wExtra[0] = 0; return TRUE; @@ -2456,8 +2456,8 @@ static BOOL LISTBOX_Destroy( WND *wnd, LB_DESCR *descr ) /*********************************************************************** * ListBoxWndProc */ -static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, - WPARAM wParam, LPARAM lParam ) +static LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, + WPARAM wParam, LPARAM lParam, BOOL unicode ) { LRESULT ret; LB_DESCR *descr; @@ -2493,11 +2493,12 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, } /* Ignore all other messages before we get a WM_CREATE */ - return DefWindowProcA( hwnd, msg, wParam, lParam ); + return unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) : + DefWindowProcA( hwnd, msg, wParam, lParam ); } TRACE("[%04x]: msg %s wp %08x lp %08lx\n", - wnd->hwndSelf, SPY_GetMsgName(msg), wParam, lParam ); + wnd->hwndSelf, SPY_GetMsgName(msg), wParam, lParam ); switch(msg) { case LB_RESETCONTENT16: @@ -2511,29 +2512,77 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, if (HAS_STRINGS(descr)) lParam = (LPARAM)MapSL(lParam); /* fall through */ case LB_ADDSTRING: - wParam = LISTBOX_FindStringPos( wnd, descr, (LPCSTR)lParam, FALSE ); - return LISTBOX_InsertString( wnd, descr, wParam, (LPCSTR)lParam ); + { + INT ret; + LPWSTR textW; + if(unicode || !HAS_STRINGS(descr)) + textW = (LPWSTR)lParam; + else + { + LPSTR textA = (LPSTR)lParam; + INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0); + if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)))) + MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW); + } + wParam = LISTBOX_FindStringPos( wnd, descr, textW, FALSE ); + ret = LISTBOX_InsertString( wnd, descr, wParam, textW ); + if (!unicode && HAS_STRINGS(descr)) + HeapFree(GetProcessHeap(), 0, textW); + return ret; + } case LB_INSERTSTRING16: if (HAS_STRINGS(descr)) lParam = (LPARAM)MapSL(lParam); wParam = (INT)(INT16)wParam; /* fall through */ case LB_INSERTSTRING: - return LISTBOX_InsertString( wnd, descr, wParam, (LPCSTR)lParam ); + { + INT ret; + LPWSTR textW; + if(unicode || !HAS_STRINGS(descr)) + textW = (LPWSTR)lParam; + else + { + LPSTR textA = (LPSTR)lParam; + INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0); + if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)))) + MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW); + } + ret = LISTBOX_InsertString( wnd, descr, wParam, textW ); + if(!unicode && HAS_STRINGS(descr)) + HeapFree(GetProcessHeap(), 0, textW); + return ret; + } case LB_ADDFILE16: if (HAS_STRINGS(descr)) lParam = (LPARAM)MapSL(lParam); /* fall through */ case LB_ADDFILE: - wParam = LISTBOX_FindFileStrPos( wnd, descr, (LPCSTR)lParam ); - return LISTBOX_InsertString( wnd, descr, wParam, (LPCSTR)lParam ); + { + INT ret; + LPWSTR textW; + if(unicode || !HAS_STRINGS(descr)) + textW = (LPWSTR)lParam; + else + { + LPSTR textA = (LPSTR)lParam; + INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0); + if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)))) + MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW); + } + wParam = LISTBOX_FindFileStrPos( wnd, descr, textW ); + ret = LISTBOX_InsertString( wnd, descr, wParam, textW ); + if(!unicode && HAS_STRINGS(descr)) + HeapFree(GetProcessHeap(), 0, textW); + return ret; + } case LB_DELETESTRING16: case LB_DELETESTRING: if (LISTBOX_RemoveItem( wnd, descr, wParam) != LB_ERR) return descr->nb_items; else - return LB_ERR; + return LB_ERR; case LB_GETITEMDATA16: case LB_GETITEMDATA: @@ -2556,14 +2605,14 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, lParam = (LPARAM)MapSL(lParam); /* fall through */ case LB_GETTEXT: - return LISTBOX_GetText( wnd, descr, wParam, (LPSTR)lParam ); + return LISTBOX_GetText( descr, wParam, lParam, unicode ); case LB_GETTEXTLEN16: /* fall through */ case LB_GETTEXTLEN: - if (wParam >= descr->nb_items) + if ((INT)wParam >= descr->nb_items || (INT)wParam < 0) return LB_ERR; - return (HAS_STRINGS(descr) ? strlen(descr->items[wParam].str) + return (HAS_STRINGS(descr) ? strlenW(descr->items[wParam].str) : sizeof(DWORD)); case LB_GETCURSEL16: @@ -2585,7 +2634,7 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, case LB_GETITEMHEIGHT16: case LB_GETITEMHEIGHT: - return LISTBOX_GetItemHeight( wnd, descr, wParam ); + return LISTBOX_GetItemHeight( descr, wParam ); case LB_SETITEMHEIGHT16: lParam = LOWORD(lParam); @@ -2605,7 +2654,7 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, rect.right = descr->width; rect.bottom = descr->height; - return MAKELONG( LISTBOX_GetItemFromPoint(wnd, descr, pt.x, pt.y), + return MAKELONG( LISTBOX_GetItemFromPoint(descr, pt.x, pt.y), !PtInRect( &rect, pt ) ); } @@ -2634,41 +2683,84 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, case LB_GETITEMRECT16: { RECT rect; - ret = LISTBOX_GetItemRect( wnd, descr, (INT16)wParam, &rect ); + ret = LISTBOX_GetItemRect( descr, (INT16)wParam, &rect ); CONV_RECT32TO16( &rect, MapSL(lParam) ); } return ret; case LB_GETITEMRECT: - return LISTBOX_GetItemRect( wnd, descr, wParam, (RECT *)lParam ); + return LISTBOX_GetItemRect( descr, wParam, (RECT *)lParam ); case LB_FINDSTRING16: wParam = (INT)(INT16)wParam; if (HAS_STRINGS(descr)) lParam = (LPARAM)MapSL(lParam); /* fall through */ case LB_FINDSTRING: - return LISTBOX_FindString( wnd, descr, wParam, (LPCSTR)lParam, FALSE ); + { + INT ret; + LPWSTR textW; + if(unicode || !HAS_STRINGS(descr)) + textW = (LPWSTR)lParam; + else + { + LPSTR textA = (LPSTR)lParam; + INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0); + if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)))) + MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW); + } + ret = LISTBOX_FindString( wnd, descr, wParam, textW, FALSE ); + if(!unicode && HAS_STRINGS(descr)) + HeapFree(GetProcessHeap(), 0, textW); + return ret; + } case LB_FINDSTRINGEXACT16: wParam = (INT)(INT16)wParam; if (HAS_STRINGS(descr)) lParam = (LPARAM)MapSL(lParam); /* fall through */ case LB_FINDSTRINGEXACT: - return LISTBOX_FindString( wnd, descr, wParam, (LPCSTR)lParam, TRUE ); + { + INT ret; + LPWSTR textW; + if(unicode || !HAS_STRINGS(descr)) + textW = (LPWSTR)lParam; + else + { + LPSTR textA = (LPSTR)lParam; + INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0); + if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)))) + MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW); + } + ret = LISTBOX_FindString( wnd, descr, wParam, textW, TRUE ); + if(!unicode && HAS_STRINGS(descr)) + HeapFree(GetProcessHeap(), 0, textW); + return ret; + } case LB_SELECTSTRING16: wParam = (INT)(INT16)wParam; if (HAS_STRINGS(descr)) lParam = (LPARAM)MapSL(lParam); /* fall through */ case LB_SELECTSTRING: + { + INT index; + LPWSTR textW; + if(unicode || !HAS_STRINGS(descr)) + textW = (LPWSTR)lParam; + else { - INT index = LISTBOX_FindString( wnd, descr, wParam, - (LPCSTR)lParam, FALSE ); - if (index == LB_ERR) - return LB_ERR; - LISTBOX_SetSelection( wnd, descr, index, TRUE, FALSE ); - return index; + LPSTR textA = (LPSTR)lParam; + INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0); + if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)))) + MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW); } + index = LISTBOX_FindString( wnd, descr, wParam, textW, FALSE ); + if(!unicode && HAS_STRINGS(descr)) + HeapFree(GetProcessHeap(), 0, textW); + if (index != LB_ERR) + LISTBOX_SetSelection( wnd, descr, index, TRUE, FALSE ); + return index; + } case LB_GETSEL16: wParam = (INT)(INT16)wParam; @@ -2694,14 +2786,13 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, case LB_GETSELCOUNT16: case LB_GETSELCOUNT: - return LISTBOX_GetSelCount( wnd, descr ); + return LISTBOX_GetSelCount( descr ); case LB_GETSELITEMS16: - return LISTBOX_GetSelItems16( wnd, descr, wParam, - (LPINT16)MapSL(lParam) ); + return LISTBOX_GetSelItems16( descr, wParam, (LPINT16)MapSL(lParam) ); case LB_GETSELITEMS: - return LISTBOX_GetSelItems( wnd, descr, wParam, (LPINT)lParam ); + return LISTBOX_GetSelItems( descr, wParam, (LPINT)lParam ); case LB_SELITEMRANGE16: case LB_SELITEMRANGE: @@ -2744,10 +2835,26 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, /* according to Win16 docs, DDL_DRIVES should make DDL_EXCLUSIVE * be set automatically (this is different in Win32) */ if (wParam & DDL_DRIVES) wParam |= DDL_EXCLUSIVE; - return LISTBOX_Directory( wnd, descr, wParam, MapSL(lParam), FALSE ); - + lParam = (LPARAM)MapSL(lParam); + /* fall through */ case LB_DIR: - return LISTBOX_Directory( wnd, descr, wParam, (LPCSTR)lParam, TRUE ); + { + INT ret; + LPWSTR textW; + if(unicode) + textW = (LPWSTR)lParam; + else + { + LPSTR textA = (LPSTR)lParam; + INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0); + if((textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)))) + MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW); + } + ret = LISTBOX_Directory( wnd, descr, wParam, textW, msg == LB_DIR ); + if(!unicode) + HeapFree(GetProcessHeap(), 0, textW); + return ret; + } case LB_GETLOCALE: return descr->locale; @@ -2757,7 +2864,7 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, return LB_OKAY; case LB_INITSTORAGE: - return LISTBOX_InitStorage( wnd, descr, wParam, (DWORD)lParam ); + return LISTBOX_InitStorage( wnd, descr, wParam ); case LB_SETCOUNT: return LISTBOX_SetCount( wnd, descr, (INT)wParam ); @@ -2832,15 +2939,16 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, SEND_NOTIFICATION( wnd, descr, LBN_KILLFOCUS ); return 0; case WM_HSCROLL: - return LISTBOX_HandleHScroll( wnd, descr, wParam, lParam ); + return LISTBOX_HandleHScroll( wnd, descr, wParam ); case WM_VSCROLL: - return LISTBOX_HandleVScroll( wnd, descr, wParam, lParam ); + return LISTBOX_HandleVScroll( wnd, descr, wParam ); case WM_MOUSEACTIVATE: return MA_NOACTIVATE; case WM_MOUSEWHEEL: if (wParam & (MK_SHIFT | MK_CONTROL)) - return DefWindowProcA( hwnd, msg, wParam, lParam ); - return LISTBOX_HandleMouseWheel( wnd, descr, wParam, lParam ); + return unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) : + DefWindowProcA( hwnd, msg, wParam, lParam ); + return LISTBOX_HandleMouseWheel( wnd, descr, wParam ); case WM_LBUTTONDOWN: return LISTBOX_HandleLButtonDown( wnd, descr, wParam, (INT16)LOWORD(lParam), @@ -2859,23 +2967,34 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, case WM_KEYDOWN: return LISTBOX_HandleKeyDown( wnd, descr, wParam ); case WM_CHAR: - return LISTBOX_HandleChar( wnd, descr, wParam ); + { + WCHAR charW; + if(unicode) + charW = (WCHAR)wParam; + else + { + CHAR charA = (CHAR)wParam; + MultiByteToWideChar(CP_ACP, 0, &charA, 1, &charW, 1); + } + return LISTBOX_HandleChar( wnd, descr, charW ); + } case WM_SYSTIMER: return LISTBOX_HandleSystemTimer( wnd, descr ); case WM_ERASEBKGND: if ((IS_OWNERDRAW(descr)) && !(descr->style & LBS_DISPLAYCHANGED)) { RECT rect; - HBRUSH hbrush = SendMessageA( descr->owner, WM_CTLCOLORLISTBOX, + HBRUSH hbrush = SendMessageW( descr->owner, WM_CTLCOLORLISTBOX, wParam, (LPARAM)wnd->hwndSelf ); GetClientRect(hwnd, &rect); if (hbrush) FillRect( (HDC)wParam, &rect, hbrush ); } return 1; case WM_DROPFILES: - if( !descr->lphc ) - return SendMessageA( descr->owner, msg, wParam, lParam ); - break; + if( !descr->lphc ) + return unicode ? SendMessageW( descr->owner, msg, wParam, lParam ) : + SendMessageA( descr->owner, msg, wParam, lParam ); + break; case WM_DROPOBJECT: case WM_QUERYDROPOBJECT: @@ -2884,17 +3003,18 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, if( !descr->lphc ) { LPDRAGINFO16 dragInfo = MapSL( lParam ); - dragInfo->l = LISTBOX_GetItemFromPoint( wnd, descr, dragInfo->pt.x, + dragInfo->l = LISTBOX_GetItemFromPoint( descr, dragInfo->pt.x, dragInfo->pt.y ); - return SendMessageA( descr->owner, msg, wParam, lParam ); + return SendMessage16( descr->owner, msg, wParam, lParam ); } break; default: if ((msg >= WM_USER) && (msg < 0xc000)) WARN("[%04x]: unknown msg %04x wp %08x lp %08lx\n", - hwnd, msg, wParam, lParam ); - return DefWindowProcA( hwnd, msg, wParam, lParam ); + hwnd, msg, wParam, lParam ); + return unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) : + DefWindowProcA( hwnd, msg, wParam, lParam ); } return 0; } @@ -2908,34 +3028,22 @@ static inline LRESULT WINAPI ListBoxWndProc_locked( WND* wnd, UINT msg, static LRESULT WINAPI ListBoxWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { WND* wndPtr = WIN_FindWndPtr( hwnd ); - LRESULT res = ListBoxWndProc_locked(wndPtr,msg,wParam,lParam); + LRESULT res = ListBoxWndProc_locked(wndPtr, msg, wParam, lParam, FALSE); WIN_ReleaseWndPtr(wndPtr); return res; } /*********************************************************************** - * COMBO_Directory + * ListBoxWndProcW */ -LRESULT COMBO_Directory( LPHEADCOMBO lphc, UINT attrib, LPSTR dir, BOOL bLong) +static LRESULT WINAPI ListBoxWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { - WND *wnd = WIN_FindWndPtr( lphc->hWndLBox ); - - if( wnd ) - { - LB_DESCR *descr = *(LB_DESCR **)wnd->wExtra; - if( descr ) - { - LRESULT lRet = LISTBOX_Directory( wnd, descr, attrib, dir, bLong ); + WND* wndPtr = WIN_FindWndPtr( hwnd ); + LRESULT res = ListBoxWndProc_locked(wndPtr, msg, wParam, lParam, TRUE); - RedrawWindow( lphc->self->hwndSelf, NULL, 0, - RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW ); - WIN_ReleaseWndPtr(wnd); - return lRet; - } - WIN_ReleaseWndPtr(wnd); - } - return CB_ERR; + WIN_ReleaseWndPtr(wndPtr); + return res; } /*********************************************************************** @@ -2943,8 +3051,8 @@ LRESULT COMBO_Directory( LPHEADCOMBO lphc, UINT attrib, LPSTR dir, BOOL bLong) * * The real combo listbox wndproc, but called with locked WND struct. */ -static inline LRESULT WINAPI ComboLBWndProc_locked( WND* wnd, UINT msg, - WPARAM wParam, LPARAM lParam ) +static LRESULT WINAPI ComboLBWndProc_locked( WND* wnd, UINT msg, + WPARAM wParam, LPARAM lParam, BOOL unicode ) { LRESULT lRet = 0; HWND hwnd = wnd->hwndSelf; @@ -3012,7 +3120,8 @@ static inline LRESULT WINAPI ComboLBWndProc_locked( WND* wnd, UINT msg, /* * If we are in Win3.1 look, go with the default behavior. */ - return ListBoxWndProcA( hwnd, msg, wParam, lParam ); + return unicode ? ListBoxWndProcW( hwnd, msg, wParam, lParam ) : + ListBoxWndProcA( hwnd, msg, wParam, lParam ); } case WM_LBUTTONUP: if (TWEAK_WineLook > WIN31_LOOK) @@ -3036,7 +3145,7 @@ static inline LRESULT WINAPI ComboLBWndProc_locked( WND* wnd, UINT msg, * 0xFFFFFFF as the mouse location, we must also revert the * selection to the original selection. */ - if ( (lParam == 0xFFFFFFFF) || + if ( (lParam == (LPARAM)-1) || (!PtInRect( &clientRect, mousePos )) ) { LISTBOX_MoveCaret( wnd, @@ -3073,7 +3182,8 @@ static inline LRESULT WINAPI ComboLBWndProc_locked( WND* wnd, UINT msg, case LB_SETCURSEL16: case LB_SETCURSEL: - lRet = ListBoxWndProcA( hwnd, msg, wParam, lParam ); + lRet = unicode ? ListBoxWndProcW( hwnd, msg, wParam, lParam ) : + ListBoxWndProcA( hwnd, msg, wParam, lParam ); lRet =(lRet == LB_ERR) ? lRet : descr->selected_item; return lRet; case WM_NCDESTROY: @@ -3082,10 +3192,12 @@ static inline LRESULT WINAPI ComboLBWndProc_locked( WND* wnd, UINT msg, /* fall through */ default: - return ListBoxWndProcA( hwnd, msg, wParam, lParam ); + return unicode ? ListBoxWndProcW( hwnd, msg, wParam, lParam ) : + ListBoxWndProcA( hwnd, msg, wParam, lParam ); } } - lRet = DefWindowProcA( hwnd, msg, wParam, lParam ); + lRet = unicode ? DefWindowProcW( hwnd, msg, wParam, lParam ) : + DefWindowProcA( hwnd, msg, wParam, lParam ); TRACE_(combo)("\t default on msg [%04x]\n", (UINT16)msg ); } @@ -3093,7 +3205,7 @@ static inline LRESULT WINAPI ComboLBWndProc_locked( WND* wnd, UINT msg, } /*********************************************************************** - * ComboLBWndProc + * ComboLBWndProcA * * NOTE: in Windows, winproc address of the ComboLBox is the same * as that of the Listbox. @@ -3105,7 +3217,19 @@ LRESULT WINAPI ComboLBWndProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { WND *wnd = WIN_FindWndPtr( hwnd ); - LRESULT res = ComboLBWndProc_locked(wnd,msg,wParam,lParam); + LRESULT res = ComboLBWndProc_locked(wnd, msg, wParam, lParam, FALSE); + + WIN_ReleaseWndPtr(wnd); + return res; +} + +/*********************************************************************** + * ComboLBWndProcW + */ +LRESULT WINAPI ComboLBWndProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + WND *wnd = WIN_FindWndPtr( hwnd ); + LRESULT res = ComboLBWndProc_locked(wnd, msg, wParam, lParam, TRUE); WIN_ReleaseWndPtr(wnd); return res; diff --git a/dlls/user/controls.h b/dlls/user/controls.h index 2aa8e836dfe..34eff8f30bf 100644 --- a/dlls/user/controls.h +++ b/dlls/user/controls.h @@ -109,8 +109,6 @@ typedef struct #define CB_HWND( lphc ) ((lphc)->self->hwndSelf) extern BOOL COMBO_FlipListbox( LPHEADCOMBO, BOOL, BOOL ); -extern LRESULT COMBO_Directory( LPHEADCOMBO, UINT, LPSTR, BOOL ); - /* Dialog info structure. * This structure is stored into the window extra bytes (cbWndExtra). -- 2.11.4.GIT