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/…
==============================================================================
--- 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/ntu…
==============================================================================
--- 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=…
==============================================================================
--- 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/nt…
==============================================================================
--- 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/nt…
==============================================================================
--- 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