Author: jimtabor Date: Wed Oct 24 05:04:06 2007 New Revision: 29839
URL: http://svn.reactos.org/svn/reactos?rev=29839&view=rev Log: - Sync to Wine: Listbox controls - Implement NtUserGetListBoxInfo and GetListBoxInfo. Fix header entry. - Add LB_GETLISTBOXINFO to psdk.
Modified: trunk/reactos/dll/win32/user32/controls/listbox.c trunk/reactos/include/psdk/winuser.h trunk/reactos/include/reactos/win32k/ntuser.h trunk/reactos/media/doc/README.WINE trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c trunk/reactos/subsystems/win32/win32k/ntuser/window.c
Modified: trunk/reactos/dll/win32/user32/controls/listbox.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/controls/l... ============================================================================== --- trunk/reactos/dll/win32/user32/controls/listbox.c (original) +++ trunk/reactos/dll/win32/user32/controls/listbox.c Wed Oct 24 05:04:06 2007 @@ -16,12 +16,26 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * NOTES + * + * This code was audited for completeness against the documented features + * of Comctl32.dll version 6.0 on Oct. 9, 2004, by Dimitrie O. Paun. + * + * Unless otherwise noted, we believe this code to be complete, as per + * the specification mentioned above. + * If you discover missing features, or bugs, please note them below. + * + * TODO: + * - GetListBoxInfo() + * - LB_GETLISTBOXINFO + * - LBS_NODATA */
#include <user32.h>
#include <wine/debug.h> -WINE_DECLARE_DEBUG_CHANNEL(combo); + WINE_DEFAULT_DEBUG_CHANNEL(listbox);
/* Start of hack section -------------------------------- */ @@ -41,14 +55,6 @@ BOOL STDCALL KillSystemTimer(HWND,UINT_PTR);
/* End of hack section -------------------------------- */ - -/* Unimplemented yet: - * - LBS_USETABSTOPS - * - Locale handling - * - * Probably needs improvement: - * - LBS_NOSEL - */
/* Items array granularity */ #define LB_ARRAY_GRANULARITY 16 @@ -341,10 +347,12 @@ * * Set the top item of the listbox, scrolling up or down if necessary. */ -static LRESULT LISTBOX_SetTopItem( LB_DESCR *descr, INT index, - BOOL scroll ) +static LRESULT LISTBOX_SetTopItem( LB_DESCR *descr, INT index, BOOL scroll ) { INT max = LISTBOX_GetMaxTopIndex( descr ); + + TRACE("setting top item %d, scroll %d\n", index, scroll); + if (index > max) index = max; if (index < 0) index = 0; if (descr->style & LBS_MULTICOLUMN) index -= index % descr->page_size; @@ -519,6 +527,8 @@ rect->bottom = rect->top + descr->item_height; rect->right += descr->horz_pos; } + + TRACE("item %d, rect %s\n", index, wine_dbgstr_rect(rect));
return ((rect->left < descr->width) && (rect->right > 0) && (rect->top < descr->height) && (rect->bottom > 0)); @@ -704,8 +714,7 @@ * * Repaint a single item synchronously. */ -static void LISTBOX_RepaintItem( LB_DESCR *descr, INT index, - UINT action ) +static void LISTBOX_RepaintItem( LB_DESCR *descr, INT index, UINT action ) { HDC hdc; RECT rect; @@ -736,6 +745,33 @@
/*********************************************************************** + * LISTBOX_DrawFocusRect + */ +static void LISTBOX_DrawFocusRect( LB_DESCR *descr, BOOL on ) +{ + HDC hdc; + RECT rect; + HFONT oldFont = 0; + + /* Do not repaint the item if the item is not visible */ + if (!IsWindowVisible(descr->self)) return; + + if (descr->focus_item == -1) return; + if (!descr->caret_on || !descr->in_focus) return; + + if (LISTBOX_GetItemRect( descr, descr->focus_item, &rect ) != 1) return; + if (!(hdc = GetDCEx( descr->self, 0, DCX_CACHE ))) return; + if (descr->font) oldFont = SelectObject( hdc, descr->font ); + if (!IsWindowEnabled(descr->self)) + SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) ); + SetWindowOrgEx( hdc, descr->horz_pos, 0, NULL ); + LISTBOX_PaintItem( descr, hdc, &rect, descr->focus_item, ODA_FOCUS, on ? FALSE : TRUE ); + if (oldFont) SelectObject( hdc, oldFont ); + ReleaseDC( descr->self, hdc ); +} + + +/*********************************************************************** * LISTBOX_InitStorage */ static LRESULT LISTBOX_InitStorage( LB_DESCR *descr, INT nb_items ) @@ -767,8 +803,7 @@ /*********************************************************************** * LISTBOX_SetTabStops */ -static BOOL LISTBOX_SetTabStops( LB_DESCR *descr, INT count, - LPINT tabs, BOOL short_ints ) +static BOOL LISTBOX_SetTabStops( LB_DESCR *descr, INT count, LPINT tabs, BOOL short_ints ) { INT i;
@@ -1375,6 +1410,8 @@ { INT top;
+ TRACE("current top item %d, index %d, fully %d\n", descr->top_item, index, fully); + if (index <= descr->top_item) top = index; else if (descr->style & LBS_MULTICOLUMN) { @@ -1413,16 +1450,17 @@ { INT oldfocus = descr->focus_item;
+ TRACE("old focus %d, index %d\n", oldfocus, index); + if (descr->style & LBS_NOSEL) return LB_ERR; if ((index < 0) || (index >= descr->nb_items)) return LB_ERR; if (index == oldfocus) return LB_OKAY; + + LISTBOX_DrawFocusRect( descr, FALSE ); descr->focus_item = index; - if ((oldfocus != -1) && descr->caret_on && (descr->in_focus)) - LISTBOX_RepaintItem( descr, oldfocus, ODA_FOCUS );
LISTBOX_MakeItemVisible( descr, index, fully_visible ); - if (descr->caret_on && (descr->in_focus)) - LISTBOX_RepaintItem( descr, index, ODA_FOCUS ); + LISTBOX_DrawFocusRect( descr, TRUE );
return LB_OKAY; } @@ -1476,7 +1514,8 @@ static LRESULT LISTBOX_SetSelection( LB_DESCR *descr, INT index, BOOL on, BOOL send_notify ) { - TRACE( "index=%d notify=%s\n", index, send_notify ? "YES" : "NO" ); + TRACE( "cur_sel=%d index=%d notify=%s\n", + descr->selected_item, index, send_notify ? "YES" : "NO" );
if (descr->style & LBS_NOSEL) { @@ -1497,8 +1536,8 @@ if (index == oldsel) return LB_OKAY; if (oldsel != -1) descr->items[oldsel].selected = FALSE; if (index != -1) descr->items[index].selected = TRUE; + if (oldsel != -1) LISTBOX_RepaintItem( descr, oldsel, ODA_SELECT ); descr->selected_item = index; - if (oldsel != -1) LISTBOX_RepaintItem( descr, oldsel, ODA_SELECT ); if (index != -1) LISTBOX_RepaintItem( descr, index, ODA_SELECT ); if (send_notify && descr->nb_items) SEND_NOTIFICATION( descr, (index != -1) ? LBN_SELCHANGE : LBN_SELCANCEL ); @@ -1518,7 +1557,7 @@ static void LISTBOX_MoveCaret( LB_DESCR *descr, INT index, BOOL fully_visible ) { - INT oldfocus = descr->focus_item; + TRACE("old focus %d, index %d\n", descr->focus_item, index);
if ((index < 0) || (index >= descr->nb_items)) return; @@ -1531,9 +1570,7 @@ 4. Set the focus to 'index' and repaint the item */
/* 1. remove the focus and repaint the item */ - descr->focus_item = -1; - if ((oldfocus != -1) && descr->caret_on && (descr->in_focus)) - LISTBOX_RepaintItem( descr, oldfocus, ODA_FOCUS ); + LISTBOX_DrawFocusRect( descr, FALSE );
/* 2. then turn off the previous selection */ /* 3. repaint the new selected item */ @@ -1558,8 +1595,7 @@ /* 4. repaint the new item with the focus */ descr->focus_item = index; LISTBOX_MakeItemVisible( descr, index, fully_visible ); - if (descr->caret_on && (descr->in_focus)) - LISTBOX_RepaintItem( descr, index, ODA_FOCUS ); + LISTBOX_DrawFocusRect( descr, TRUE ); }
@@ -1712,7 +1748,7 @@ dis.itemData = descr->items[index].data; SendMessageW( descr->owner, WM_DELETEITEM, id, (LPARAM)&dis ); } - if (HAS_STRINGS(descr) && descr->items[index].str) + if (HAS_STRINGS(descr)) HeapFree( GetProcessHeap(), 0, descr->items[index].str ); }
@@ -2066,7 +2102,10 @@ DWORD keys, INT x, INT y ) { INT index = LISTBOX_GetItemFromPoint( descr, x, y ); - TRACE("[%p]: lbuttondown %d,%d item %d\n", descr->self, x, y, index ); + + TRACE("[%p]: lbuttondown %d,%d item %d, focus item %d\n", + descr->self, x, y, index, descr->focus_item); + if (!descr->caret_on && (descr->in_focus)) return 0;
if (!descr->in_focus) @@ -2076,6 +2115,16 @@ }
if (index == -1) return 0; + + if (!descr->lphc) + { + if (descr->style & LBS_NOTIFY ) + SendMessageW( descr->owner, WM_LBTRACKPOINT, index, + MAKELPARAM( x, y ) ); + } + + descr->captured = TRUE; + SetCapture( descr->self );
if (descr->style & (LBS_EXTENDEDSEL | LBS_MULTIPLESEL)) { @@ -2119,14 +2168,8 @@ TRUE, (descr->style & LBS_NOTIFY) != 0 ); }
- descr->captured = TRUE; - SetCapture( descr->self ); - if (!descr->lphc) { - if (descr->style & LBS_NOTIFY ) - SendMessageW( descr->owner, WM_LBTRACKPOINT, index, - MAKELPARAM( x, y ) ); if (GetWindowLongW( descr->self, GWL_EXSTYLE ) & WS_EX_DRAGDETECT) { POINT pt; @@ -2147,7 +2190,7 @@ * * Process LButtonDown message for the ComboListBox * -nn * PARAMS + * PARAMS * pWnd [I] The windows internal structure * pDescr [I] The ListBox internal structure * wParam [I] Key Flag (WM_LBUTTONDOWN doc for more info) @@ -2467,7 +2510,6 @@ } } return 0; - }
@@ -2614,8 +2656,8 @@ WPARAM wParam, LPARAM lParam, BOOL unicode ) { LB_DESCR *descr = (LB_DESCR *)GetWindowLongPtrW( hwnd, 0 ); + LPHEADCOMBO lphc = 0; LRESULT ret; - LPHEADCOMBO lphc = 0;
if (!descr) { @@ -2625,8 +2667,7 @@ { CREATESTRUCTW *lpcs = (CREATESTRUCTW *)lParam; if (lpcs->style & LBS_COMBOBOX) lphc = (LPHEADCOMBO)lpcs->lpCreateParams; - if (!LISTBOX_Create( hwnd, lphc )) - return -1; + if (!LISTBOX_Create( hwnd, lphc )) return -1; TRACE("creating wnd=%p descr=%lx\n", hwnd, GetWindowLongPtrW( hwnd, 0 ) ); return 0; } @@ -2638,6 +2679,7 @@
TRACE("[%p]: msg %s wp %08x lp %08lx\n", hwnd, SPY_GetMsgName(msg, hwnd), wParam, lParam ); + switch(msg) { #ifndef __REACTOS__ @@ -2843,16 +2885,38 @@ { POINT pt; RECT rect; - - pt.x = LOWORD(lParam); - pt.y = HIWORD(lParam); - rect.left = 0; - rect.top = 0; - rect.right = descr->width; - rect.bottom = descr->height; - - return MAKELONG( LISTBOX_GetItemFromPoint(descr, pt.x, pt.y), - !PtInRect( &rect, pt ) ); + int index; + BOOL hit = TRUE; + + /* The hiword of the return value is not a client area + hittest as suggested by MSDN, but rather a hittest on + the returned listbox item. */ + + if(descr->nb_items == 0) + return 0x1ffff; /* win9x returns 0x10000, we copy winnt */ + + pt.x = (short)LOWORD(lParam); + pt.y = (short)HIWORD(lParam); + + SetRect(&rect, 0, 0, descr->width, descr->height); + + if(!PtInRect(&rect, pt)) + { + pt.x = min(pt.x, rect.right - 1); + pt.x = max(pt.x, 0); + pt.y = min(pt.y, rect.bottom - 1); + pt.y = max(pt.y, 0); + hit = FALSE; + } + + index = LISTBOX_GetItemFromPoint(descr, pt.x, pt.y); + + if(index == -1) + { + index = descr->nb_items - 1; + hit = FALSE; + } + return MAKELONG(index, hit ? 0 : 1); }
#ifndef __REACTOS__ @@ -3153,6 +3217,10 @@ if ((descr->focus_item != -1) && (descr->in_focus)) LISTBOX_RepaintItem( descr, descr->focus_item, ODA_FOCUS ); return LB_OKAY; + + case LB_GETLISTBOXINFO: + FIXME("LB_GETLISTBOXINFO: stub!\n"); + return 0;
case WM_DESTROY: return LISTBOX_Destroy( descr ); @@ -3190,7 +3258,7 @@ descr->in_focus = TRUE; descr->caret_on = TRUE; if (descr->focus_item != -1) - LISTBOX_RepaintItem( descr, descr->focus_item, ODA_FOCUS ); + LISTBOX_DrawFocusRect( descr, TRUE ); SEND_NOTIFICATION( descr, LBN_SETFOCUS ); return 0; case WM_KILLFOCUS: @@ -3325,6 +3393,7 @@ if( lphc ) return 0; return unicode ? SendMessageW( descr->owner, msg, wParam, lParam ) : SendMessageA( descr->owner, msg, wParam, lParam ); + case WM_NCDESTROY: if( lphc && (lphc->dwStyle & CBS_DROPDOWNLIST) != CBS_SIMPLE ) lphc->hWndLBox = 0; @@ -3364,12 +3433,11 @@ }
/*********************************************************************** - * GetListBoxInfo + * GetListBoxInfo !REACTOS! */ DWORD STDCALL GetListBoxInfo(HWND hwnd) { - UNIMPLEMENTED; - return 0; -} - + return NtUserGetListBoxInfo(hwnd); // Do it right! Have the message org from kmode! +} +
Modified: trunk/reactos/include/psdk/winuser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/winuser.h?rev=... ============================================================================== --- trunk/reactos/include/psdk/winuser.h (original) +++ trunk/reactos/include/psdk/winuser.h Wed Oct 24 05:04:06 2007 @@ -1847,6 +1847,7 @@ #define LB_GETITEMDATA 409 #define LB_GETITEMHEIGHT 417 #define LB_GETITEMRECT 408 +#define LB_GETLISTBOXINFO 434 #define LB_GETLOCALE 422 #define LB_GETSEL 391 #define LB_GETSELCOUNT 400
Modified: trunk/reactos/include/reactos/win32k/ntuser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntus... ============================================================================== --- trunk/reactos/include/reactos/win32k/ntuser.h (original) +++ trunk/reactos/include/reactos/win32k/ntuser.h Wed Oct 24 05:04:06 2007 @@ -1161,7 +1161,7 @@ DWORD NTAPI NtUserGetListBoxInfo( - DWORD Unknown0); + HWND hWnd);
typedef struct tagNTUSERGETMESSAGEINFO {
Modified: trunk/reactos/media/doc/README.WINE URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=2... ============================================================================== --- trunk/reactos/media/doc/README.WINE (original) +++ trunk/reactos/media/doc/README.WINE Wed Oct 24 05:04:06 2007 @@ -125,7 +125,7 @@ reactos/dll/win32/user32/controls/combo.c # Synced at 20071022 reactos/dll/win32/user32/controls/edit.c # Synced at 20071022 reactos/dll/win32/user32/controls/icontitle.c # Synced at 20060617 - reactos/dll/win32/user32/controls/listbox.c # Synced at 20060616 + reactos/dll/win32/user32/controls/listbox.c # Synced at 20071023 reactos/dll/win32/user32/controls/scrollbar.c # Forked reactos/dll/win32/user32/controls/static.c # Synced at 20060908
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c Wed Oct 24 05:04:06 2007 @@ -336,16 +336,6 @@
DWORD STDCALL -NtUserGetListBoxInfo( - DWORD Unknown0) -{ - UNIMPLEMENTED - - return 0; -} - -DWORD -STDCALL NtUserGetMouseMovePointsEx( UINT cbSize, LPMOUSEMOVEPOINT lppt,
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/window.c (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c Wed Oct 24 05:04:06 2007 @@ -2871,6 +2871,32 @@ return NULL; #endif } + + +DWORD +STDCALL +NtUserGetListBoxInfo( + HWND hWnd) +{ + PWINDOW_OBJECT Wnd; + DECLARE_RETURN(DWORD); + + DPRINT("Enter NtUserGetListBoxInfo\n"); + UserEnterExclusive(); + + if (!(Wnd = UserGetWindowObject(hWnd))) + { + RETURN( 0 ); + } + + RETURN( (DWORD) co_IntSendMessage( Wnd->hSelf, LB_GETLISTBOXINFO, 0, 0 )); + +CLEANUP: + DPRINT("Leave NtUserGetListBoxInfo, ret=%i\n",_ret_); + UserLeave(); + END_CLEANUP; +} +
/* * NtUserGetParent