Commit in reactos on MAIN
w32api/include/commctrl.h+41.2 -> 1.3
include/wine/commctrl.h+11.9 -> 1.10
lib/comctl32/string.c+853added 1.1
            /Makefile.in+21.2 -> 1.3
            /comctl32.h+3-21.4 -> 1.5
            /comctl32.spec+17-171.1 -> 1.2
            /comctl32undoc.c+121-3161.6 -> 1.7
            /commctrl.c+39-151.7 -> 1.8
            /draglist.c+257-481.2 -> 1.3
            /flatsb.c+42-61.5 -> 1.6
            /imagelist.c+111-441.7 -> 1.8
            /listview.c+24-41.6 -> 1.7
            /propsheet.c+33-31.4 -> 1.5
            /rebar.c+2-41.7 -> 1.8
            /rsrc.rc+271.1 -> 1.2
            /smoothscroll.c+7-31.2 -> 1.3
            /tab.c+191-1981.6 -> 1.7
            /toolbar.c+158-241.8 -> 1.9
            /tooltips.c+9-91.3 -> 1.4
            /treeview.c+3-31.6 -> 1.7
            /winehq2ros.patch+1041.3 -> 1.4
+2008-696
1 added + 20 modified, total 21 files
Sync to Wine-20040309:
Robert Shearman <R.J.Shearman@warwick.ac.uk>
- Implement the drag list control.
- Fix tabs in LBItemFromPt.
- Move string functions to separate file.
- Implement string functions in comctl32.
- Use CompareString in shlwapi wherever possible instead of ugly
  helpers.
- Forward some wrapper functions since we don't care about compatibility
  with Win98 in this case.
- Documentation update.
- Update common control function documentation.
- Don't allocate space for text when nMaxTextRows = 0.
- Support custom check background.
- Reduce number of parameters needed for DrawString function.
- Fix some traces.
- The TBM_GET*HOTLIST functions take imagelist ID in wParam.
- Implement TBM_GETSTRING{A,W}.
- Implement undocumented 0x462 message.
Alexandre Julliard
- Removed a couple of unneeded helper functions.
Maxime BellengT <maxime.bellenge@laposte.net>
- Fix a regression in ImageList_Create when creating a dibsection.
Ulrich Czekalla <ulrich@codeweavers.com>
- Use dibsections for the images.
Dimitrie O. Paun <dpaun@rogers.com>
- LVN_BEGINRDRAG is implemented now. Fix typo.
Aric Stewart <aric@codeweavers.com>
- Implemented LISTVIEW_ApproximateViewRect for LVS_REPORT.
Fabian Cenedese <Cenedese@indel.ch>
- ListView should behave in OWNERDRAW as in FULLROWSELECT. This allows
  to select cells not in the first column in REPORT mode with OWNERDRAW
  style set.
Matt Chapman <matthewc@cse.unsw.edu.au>
- Fix a reentrancy issue in the property sheet implementation by not
  caching a pointer that can change.
- REBAR_Layout should respect the minimum size of bands even when
  RBBS_FIXEDSIZE is not set.
- REBAR_ShowBand needs to force layout of the rebar after a band is
  hidden/unhidden.
Vitaliy Margolen <wine-patch@kievinfo.com>
- Adjust all dimensions to match native.
- Invalidate whole tab area when multi-line.
- In vertical tab placement go from top to bottom.
- Fix annoying visual artifacts.
Huw Davies <huw@codeweavers.com>
- If TBSTYLE_EX_HIDECLIPPEDBUTTONS is set then invalidate the area that
  changes in a resize.
- Don't call SWP unless we're actually adjusting anything.
Christian Costa <titan.costa@wanadoo.fr>
- Accept null module instance, Loadstring can handle it.
Steve Lustbader <slustbader@verizon.net>
- Handle the firstVisible item being NULL in
Mike Hearn <mike@theoretic.com>
- Grow the treeview control expander button by 1px in each direction to
  match the native look.

reactos/w32api/include
commctrl.h 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- commctrl.h	26 Feb 2004 13:45:44 -0000	1.2
+++ commctrl.h	11 Mar 2004 11:13:27 -0000	1.3
@@ -605,6 +605,8 @@
 #define TB_SETINSERTMARKCOLOR	(WM_USER+88)
 #define TB_GETINSERTMARKCOLOR	(WM_USER+89)
 #define TB_MAPACCELERATORW	(WM_USER+90)
+#define TB_GETSTRINGW		(WM_USER+91)
+#define TB_GETSTRINGA		(WM_USER+92)
 #define TB_SETCOLORSCHEME	CCM_SETCOLORSCHEME
 #define TB_GETCOLORSCHEME	CCM_GETCOLORSCHEME
 #define TB_SETUNICODEFORMAT	CCM_SETUNICODEFORMAT
@@ -3235,6 +3237,7 @@
 #define TB_INSERTBUTTON TB_INSERTBUTTONW
 #define TB_ADDBUTTONS TB_ADDBUTTONSW
 #define TB_MAPACCELERATOR TB_MAPACCELERATORW
+#define TB_GETSTRING TB_GETSTRINGW
 #define TBBUTTONINFO TBBUTTONINFOW
 #define LPTBBUTTONINFO LPTBBUTTONINFOW
 #define TBN_GETDISPINFO TBN_GETDISPINFOW
@@ -3372,6 +3375,7 @@
 #define TB_INSERTBUTTON TB_INSERTBUTTONA
 #define TB_ADDBUTTONS TB_ADDBUTTONSA
 #define TB_MAPACCELERATOR TB_MAPACCELERATORA
+#define TB_GETSTRING TB_GETSTRINGA
 #define NMCOMBOBOXEX	NMCOMBOBOXEXA
 #define PNMCOMBOBOXEX	PNMCOMBOBOXEXA
 #define CBEN_DRAGBEGIN	CBEN_DRAGBEGINA

reactos/include/wine
commctrl.h 1.9 -> 1.10
diff -u -r1.9 -r1.10
--- commctrl.h	15 Jan 2004 22:21:36 -0000	1.9
+++ commctrl.h	11 Mar 2004 11:13:28 -0000	1.10
@@ -47,6 +47,7 @@
 #define TB_UNKWN45D              (WM_USER+93)
 #define TB_UNKWN45E              (WM_USER+94)
 #define TB_UNKWN460              (WM_USER+96)
+#define TB_UNKWN462              (WM_USER+98)
 #define TB_UNKWN463              (WM_USER+99)
 #define TB_UNKWN464              (WM_USER+100)
 

reactos/lib/comctl32
string.c added at 1.1
diff -N string.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ string.c	11 Mar 2004 11:13:28 -0000	1.1
@@ -0,0 +1,853 @@
+/*
+ * String manipulation functions
+ *
+ * Copyright 1998 Eric Kohl
+ *           1998 Juergen Schmied <j.schmied@metronet.de>
+ *           2000 Eric Kohl for CodeWeavers
+ * Copyright 2002 Jon Griffiths
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * 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
+ *
+ */
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h> /* atoi */
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winnls.h"
+
+#include "wine/unicode.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
+
+/*************************************************************************
+ * COMCTL32_ChrCmpHelperA
+ *
+ * Internal helper for ChrCmpA/COMCTL32_ChrCmpIA.
+ *
+ * NOTES
+ *  Both this function and its Unicode counterpart are very inneficient. To
+ *  fix this, CompareString must be completely implemented and optimised
+ *  first. Then the core character test can be taken out of that function and
+ *  placed here, so that it need never be called at all. Until then, do not
+ *  attempt to optimise this code unless you are willing to test that it
+ *  still performs correctly.
+ */
+static BOOL COMCTL32_ChrCmpHelperA(WORD ch1, WORD ch2, DWORD dwFlags)
+{
+  char str1[3], str2[3];
+
+  str1[0] = LOBYTE(ch1);
+  if (IsDBCSLeadByte(str1[0]))
+  {
+    str1[1] = HIBYTE(ch1);
+    str1[2] = '\0';
+  }
+  else
+    str1[1] = '\0';
+
+  str2[0] = LOBYTE(ch2);
+  if (IsDBCSLeadByte(str2[0]))
+  {
+    str2[1] = HIBYTE(ch2);
+    str2[2] = '\0';
+  }
+  else
+    str2[1] = '\0';
+
+  return CompareStringA(GetThreadLocale(), dwFlags, str1, -1, str2, -1) - 2;
+}
+
+/*************************************************************************
+ * COMCTL32_ChrCmpHelperW
+ *
+ * Internal helper for COMCTL32_ChrCmpW/ChrCmpIW.
+ */
+static BOOL COMCTL32_ChrCmpHelperW(WCHAR ch1, WCHAR ch2, DWORD dwFlags)
+{
+  WCHAR str1[2], str2[2];
+
+  str1[0] = ch1;
+  str1[1] = '\0';
+  str2[0] = ch2;
+  str2[1] = '\0';
+  return CompareStringW(GetThreadLocale(), dwFlags, str1, 2, str2, 2) - 2;
+}
+
+/*************************************************************************
+ * COMCTL32_ChrCmpA (internal)
+ *
+ * Internal helper function.
+ */
+static BOOL COMCTL32_ChrCmpA(WORD ch1, WORD ch2)
+{
+  return COMCTL32_ChrCmpHelperA(ch1, ch2, 0);
+}
+
+/*************************************************************************
+ * COMCTL32_ChrCmpIA	(internal)
+ *
+ * Compare two characters, ignoring case.
+ *
+ * PARAMS
+ *  ch1 [I] First character to compare
+ *  ch2 [I] Second character to compare
+ *
+ * RETURNS
+ *  FALSE, if the characters are equal.
+ *  Non-zero otherwise.
+ */
+static BOOL COMCTL32_ChrCmpIA(WORD ch1, WORD ch2)
+{
+  TRACE("(%d,%d)\n", ch1, ch2);
+
+  return COMCTL32_ChrCmpHelperA(ch1, ch2, NORM_IGNORECASE);
+}
+
+/*************************************************************************
+ * COMCTL32_ChrCmpW
+ *
+ * Internal helper function.
+ */
+static BOOL COMCTL32_ChrCmpW(WCHAR ch1, WCHAR ch2)
+{
+  return COMCTL32_ChrCmpHelperW(ch1, ch2, 0);
+}
+
+/**************************************************************************
+ * StrChrA [COMCTL32.350]
+ *
+ * Find a given character in a string.
+ *
+ * PARAMS
+ *  lpszStr [I] String to search in.
+ *  ch      [I] Character to search for.
+ *
+ * RETURNS
+ *  Success: A pointer to the first occurrence of ch in lpszStr, or NULL if
+ *           not found.
+ *  Failure: NULL, if any arguments are invalid.
+ */
+LPSTR WINAPI StrChrA(LPCSTR lpszStr, WORD ch)
+{
+  TRACE("(%s,%i)\n", debugstr_a(lpszStr), ch);
+
+  if (lpszStr)
+  {
+    while (*lpszStr)
+    {
+      if (!COMCTL32_ChrCmpA(*lpszStr, ch))
+        return (LPSTR)lpszStr;
+      lpszStr = CharNextA(lpszStr);
+    }
+  }
+  return NULL;
+}
+
+/*************************************************************************
+ * COMCTL32_StrStrHelperA
+ *
+ * Internal implementation of StrStrA/StrStrIA
+ */
+static LPSTR COMCTL32_StrStrHelperA(LPCSTR lpszStr, LPCSTR lpszSearch,
+                                    int (*pStrCmpFn)(LPCSTR,LPCSTR,size_t))
+{
+  size_t iLen;
+
+  if (!lpszStr || !lpszSearch || !*lpszSearch)
+    return NULL;
+
+  iLen = strlen(lpszSearch);
+
+  while (*lpszStr)
+  {
+    if (!pStrCmpFn(lpszStr, lpszSearch, iLen))
+      return (LPSTR)lpszStr;
+    lpszStr = CharNextA(lpszStr);
+  }
+  return NULL;
+}
+
+/*************************************************************************
+ * COMCTL32_StrStrHelperW
+ *
+ * Internal implementation of StrStrW/StrStrIW
+ */
+static LPWSTR COMCTL32_StrStrHelperW(LPCWSTR lpszStr, LPCWSTR lpszSearch,
+                                     int (*pStrCmpFn)(LPCWSTR,LPCWSTR,int))
+{
+  int iLen;
+
+  if (!lpszStr || !lpszSearch || !*lpszSearch)
+    return NULL;
+
+  iLen = strlenW(lpszSearch);
+
+  while (*lpszStr)
+  {
+    if (!pStrCmpFn(lpszStr, lpszSearch, iLen))
+      return (LPWSTR)lpszStr;
+    lpszStr = CharNextW(lpszStr);
+  }
+  return NULL;
+}
+
+/**************************************************************************
+ * StrStrIA [COMCTL32.355]
+ *
+ * Find a substring within a string, ignoring case.
+ *
+ * PARAMS
+ *  lpszStr    [I] String to search in
+ *  lpszSearch [I] String to look for
+ *
+ * RETURNS
+ *  The start of lpszSearch within lpszStr, or NULL if not found.
+ */
+LPSTR WINAPI StrStrIA(LPCSTR lpszStr, LPCSTR lpszSearch)
+{
+  TRACE("(%s,%s)\n", debugstr_a(lpszStr), debugstr_a(lpszSearch));
+
+  return COMCTL32_StrStrHelperA(lpszStr, lpszSearch, strncasecmp);
+}
+
+/**************************************************************************
+ * StrToIntA [COMCTL32.357]
+ *
+ * Read a signed integer from a string.
+ *
+ * PARAMS
+ *  lpszStr [I] String to read integer from
+ *
+ * RETURNS
+ *   The signed integer value represented by the string, or 0 if no integer is
+ *   present.
+ */
+INT WINAPI StrToIntA (LPSTR lpszStr)
+{
+    return atoi(lpszStr);
+}
+
+/**************************************************************************
+ * StrStrIW [COMCTL32.363]
+ *
+ * See StrStrIA.
+ */
+LPWSTR WINAPI StrStrIW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
+{
+  TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
+
+  return COMCTL32_StrStrHelperW(lpszStr, lpszSearch, (int (*)(LPCWSTR,LPCWSTR,int)) wcsnicmp);
+}
+
+/**************************************************************************
+ * StrToIntW [COMCTL32.365]
+ *
+ * See StrToIntA.
+ */
+INT WINAPI StrToIntW (LPWSTR lpString)
+{
+    return atoiW(lpString);
+}
+
+/*************************************************************************
+ * COMCTL32_StrSpnHelperA (internal)
+ *
+ * Internal implementation of StrSpnA/StrCSpnA/StrCSpnIA
+ */
+static int COMCTL32_StrSpnHelperA(LPCSTR lpszStr, LPCSTR lpszMatch,
+                                  LPSTR (WINAPI *pStrChrFn)(LPCSTR,WORD),
+                                  BOOL bInvert)
+{
+  LPCSTR lpszRead = lpszStr;
+  if (lpszStr && *lpszStr && lpszMatch)
+  {
+    while (*lpszRead)
+    {
+      LPCSTR lpszTest = pStrChrFn(lpszMatch, *lpszRead);
+
+      if (!bInvert && !lpszTest)
+        break;
+      if (bInvert && lpszTest)
+        break;
+      lpszRead = CharNextA(lpszRead);
+    };
+  }
+  return lpszRead - lpszStr;
+}
+
+/**************************************************************************
+ * StrCSpnA [COMCTL32.356]
+ *
+ * Find the length of the start of a string that does not contain certain
+ * characters.
+ *
+ * PARAMS
+ *  lpszStr   [I] String to search
+ *  lpszMatch [I] Characters that cannot be in the substring
+ *
+ * RETURNS
+ *  The length of the part of lpszStr containing only chars not in lpszMatch,
+ *  or 0 if any parameter is invalid.
+ */
+int WINAPI StrCSpnA(LPCSTR lpszStr, LPCSTR lpszMatch)
+{
+  TRACE("(%s,%s)\n",debugstr_a(lpszStr), debugstr_a(lpszMatch));
+
+  return COMCTL32_StrSpnHelperA(lpszStr, lpszMatch, StrChrA, TRUE);
+}
+
+/**************************************************************************
+ * StrChrW [COMCTL32.358]
+ *
+ * See StrChrA.
+ */
+LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
+{
+  LPWSTR lpszRet = NULL;
+
+  TRACE("(%s,%i)\n", debugstr_w(lpszStr), ch);
+
+  if (lpszStr)
+    lpszRet = strchrW(lpszStr, ch);
+  return lpszRet;
+}
+
+/**************************************************************************
+ * StrCmpNA [COMCTL32.352]
+ *
+ * Compare two strings, up to a maximum length.
+ *
+ * PARAMS
+ *  lpszStr  [I] First string to compare
+ *  lpszComp [I] Second string to compare
+ *  iLen     [I] Maximum number of chars to compare.
+ *
+ * RETURNS
+ *  An integer less than, equal to or greater than 0, indicating that
+ *  lpszStr is less than, the same, or greater than lpszComp.
+ */
+INT WINAPI StrCmpNA(LPCSTR lpszStr, LPCSTR lpszComp, INT iLen)
+{
+  INT iRet;
+
+  TRACE("(%s,%s,%i)\n", debugstr_a(lpszStr), debugstr_a(lpszComp), iLen);
+
+  iRet = CompareStringA(GetThreadLocale(), 0, lpszStr, iLen, lpszComp, iLen);
+  return iRet == CSTR_LESS_THAN ? -1 : iRet == CSTR_GREATER_THAN ? 1 : 0;
+}
+
+/**************************************************************************
+ * StrCmpNIA [COMCTL32.353]
+ *
+ * Compare two strings, up to a maximum length, ignoring case.
+ *
+ * PARAMS
+ *  lpszStr  [I] First string to compare
+ *  lpszComp [I] Second string to compare
+ *  iLen     [I] Maximum number of chars to compare.
+ *
+ * RETURNS
+ *  An integer less than, equal to or greater than 0, indicating that
+ *  lpszStr is less than, the same, or greater than lpszComp.
+ */
+int WINAPI StrCmpNIA(LPCSTR lpszStr, LPCSTR lpszComp, int iLen)
+{
+  INT iRet;
+
+  TRACE("(%s,%s,%i)\n", debugstr_a(lpszStr), debugstr_a(lpszComp), iLen);
+
+  iRet = CompareStringA(GetThreadLocale(), NORM_IGNORECASE, lpszStr, iLen, lpszComp, iLen);
+  return iRet == CSTR_LESS_THAN ? -1 : iRet == CSTR_GREATER_THAN ? 1 : 0;
+}
+
+/*************************************************************************
+ * StrCmpNIW	[COMCTL32.361]
+ *
+ * See StrCmpNIA.
+ */
+INT WINAPI StrCmpNIW(LPCWSTR lpszStr, LPCWSTR lpszComp, int iLen)
+{
+  INT iRet;
+
+  TRACE("(%s,%s,%i)\n", debugstr_w(lpszStr), debugstr_w(lpszComp), iLen);
+
+  iRet = CompareStringW(GetThreadLocale(), NORM_IGNORECASE, lpszStr, iLen, lpszComp, iLen);
+  return iRet == CSTR_LESS_THAN ? -1 : iRet == CSTR_GREATER_THAN ? 1 : 0;
+}
+
+/**************************************************************************
+ * StrCmpNW [COMCTL32.360]
+ *
+ * See StrCmpNA.
+ */
+INT WINAPI StrCmpNW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
+{
+  INT iRet;
+
+  TRACE("(%s,%s,%i)\n", debugstr_w(lpszStr), debugstr_w(lpszComp), iLen);
+
+  iRet = CompareStringW(GetThreadLocale(), 0, lpszStr, iLen, lpszComp, iLen);
+  return iRet == CSTR_LESS_THAN ? -1 : iRet == CSTR_GREATER_THAN ? 1 : 0;
+}
+
+/**************************************************************************
+ * StrRChrA [COMCTL32.351]
+ *
+ * Find the last occurence of a character in string.
+ *
+ * PARAMS
+ *  lpszStr [I] String to search in
+ *  lpszEnd [I] Place to end search, or NULL to search until the end of lpszStr
+ *  ch      [I] Character to search for.
+ *
+ * RETURNS
+ *  Success: A pointer to the last occurrence of ch in lpszStr before lpszEnd,
+ *           or NULL if not found.
+ *  Failure: NULL, if any arguments are invalid.
+ */
+LPSTR WINAPI StrRChrA(LPCSTR lpszStr, LPCSTR lpszEnd, WORD ch)
+{
+  LPCSTR lpszRet = NULL;
+
+  TRACE("(%s,%s,%x)\n", debugstr_a(lpszStr), debugstr_a(lpszEnd), ch);
+
+  if (lpszStr)
+  {
+    WORD ch2;
+
+    if (!lpszEnd)
+      lpszEnd = lpszStr + lstrlenA(lpszStr);
+
+    while (*lpszStr && lpszStr <= lpszEnd)
+    {
+      ch2 = IsDBCSLeadByte(*lpszStr)? *lpszStr << 8 | lpszStr[1] : *lpszStr;
+
+      if (!COMCTL32_ChrCmpA(ch, ch2))
+        lpszRet = lpszStr;
+      lpszStr = CharNextA(lpszStr);
+    }
+  }
+  return (LPSTR)lpszRet;
+}
+
+
+/**************************************************************************
+ * StrRChrW [COMCTL32.359]
+ *
+ * See StrRChrA.
+ */
+LPWSTR WINAPI StrRChrW(LPCWSTR lpszStr, LPCWSTR lpszEnd, WORD ch)
+{
+  LPCWSTR lpszRet = NULL;
+
+  TRACE("(%s,%s,%x)\n", debugstr_w(lpszStr), debugstr_w(lpszEnd), ch);
+
+  if (lpszStr)
+  {
+    if (!lpszEnd)
+      lpszEnd = lpszStr + strlenW(lpszStr);
+
+    while (*lpszStr && lpszStr <= lpszEnd)
+    {
+      if (!COMCTL32_ChrCmpW(ch, *lpszStr))
+        lpszRet = lpszStr;
+      lpszStr = CharNextW(lpszStr);
+    }
+  }
+  return (LPWSTR)lpszRet;
+}
+
+/**************************************************************************
+ * StrStrA [COMCTL32.354]
+ *
+ * Find a substring within a string.
+ *
+ * PARAMS
+ *  lpszStr    [I] String to search in
+ *  lpszSearch [I] String to look for
+ *
+ * RETURNS
+ *  The start of lpszSearch within lpszStr, or NULL if not found.
+ */
+LPSTR WINAPI StrStrA(LPCSTR lpszStr, LPCSTR lpszSearch)
+{
+  TRACE("(%s,%s)\n", debugstr_a(lpszStr), debugstr_a(lpszSearch));
+
+  return COMCTL32_StrStrHelperA(lpszStr, lpszSearch, strncmp);
+}
+
+/**************************************************************************
+ * StrStrW [COMCTL32.362]
+ *
+ * See StrStrA.
+ */
+LPWSTR WINAPI StrStrW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
+{
+  TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
+
+  return COMCTL32_StrStrHelperW(lpszStr, lpszSearch, (int (*)(LPCWSTR,LPCWSTR,int)) wcsncmp);
+}
+
+/*************************************************************************
+ * StrChrIA	[COMCTL32.366]
+ *
+ * Find a given character in a string, ignoring case.
+ *
+ * PARAMS
+ *  lpszStr [I] String to search in.
+ *  ch      [I] Character to search for.
+ *
+ * RETURNS
+ *  Success: A pointer to the first occurrence of ch in lpszStr, or NULL if
+ *           not found.
+ *  Failure: NULL, if any arguments are invalid.
+ */
+LPSTR WINAPI StrChrIA(LPCSTR lpszStr, WORD ch)
+{
+  TRACE("(%s,%i)\n", debugstr_a(lpszStr), ch);
+
+  if (lpszStr)
+  {
+    while (*lpszStr)
+    {
+      if (!COMCTL32_ChrCmpIA(*lpszStr, ch))
+        return (LPSTR)lpszStr;
+      lpszStr = CharNextA(lpszStr);
+    }
+  }
+  return NULL;
+}
+
+/*************************************************************************
+ * StrChrIW	[COMCTL32.367]
+ *
+ * See StrChrA.
+ */
+LPWSTR WINAPI StrChrIW(LPCWSTR lpszStr, WCHAR ch)
+{
+  TRACE("(%s,%i)\n", debugstr_w(lpszStr), ch);
+
+  if (lpszStr)
+  {
+    ch = toupperW(ch);
+    while (*lpszStr)
+    {
+      if (toupperW(*lpszStr) == ch)
+        return (LPWSTR)lpszStr;
+      lpszStr = CharNextW(lpszStr);
+    }
+    lpszStr = NULL;
+  }
+  return (LPWSTR)lpszStr;
+}
+
+/*************************************************************************
+ * StrRStrIA	[COMCTL32.372]
+ *
+ * Find the last occurence of a substring within a string.
+ *
+ * PARAMS
+ *  lpszStr    [I] String to search in
+ *  lpszEnd    [I] End of lpszStr
+ *  lpszSearch [I] String to look for
+ *
+ * RETURNS
+ *  The last occurence lpszSearch within lpszStr, or NULL if not found.
+ */
+LPSTR WINAPI StrRStrIA(LPCSTR lpszStr, LPCSTR lpszEnd, LPCSTR lpszSearch)
+{
+  LPSTR lpszRet = NULL;
+  WORD ch1, ch2;
+  INT iLen;
+ 
+  TRACE("(%s,%s)\n", debugstr_a(lpszStr), debugstr_a(lpszSearch));
+ 
+  if (!lpszStr || !lpszSearch || !*lpszSearch)
+    return NULL;
+
+  if (!lpszEnd)
+    lpszEnd = lpszStr + lstrlenA(lpszStr);
+
+  if (IsDBCSLeadByte(*lpszSearch))
+    ch1 = *lpszSearch << 8 | lpszSearch[1];
+  else
+    ch1 = *lpszSearch;
+  iLen = lstrlenA(lpszSearch);
+
+  while (lpszStr <= lpszEnd  && *lpszStr)
+  {
+    ch2 = IsDBCSLeadByte(*lpszStr)? *lpszStr << 8 | lpszStr[1] : *lpszStr;
+    if (!COMCTL32_ChrCmpIA(ch1, ch2))
+    {
+      if (!StrCmpNIA(lpszStr, lpszSearch, iLen))
+        lpszRet = (LPSTR)lpszStr;
+    }
+    lpszStr = CharNextA(lpszStr);
+  }
+  return lpszRet;
+}
+
+/*************************************************************************
+ * StrRStrIW	[COMCTL32.373]
+ *
+ * See StrRStrIA.
+ */
+LPWSTR WINAPI StrRStrIW(LPCWSTR lpszStr, LPCWSTR lpszEnd, LPCWSTR lpszSearch)
+{
+  LPWSTR lpszRet = NULL;
+  INT iLen;
+
+  TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
+
+  if (!lpszStr || !lpszSearch || !*lpszSearch)
+    return NULL;
+
+  if (!lpszEnd)
+    lpszEnd = lpszStr + strlenW(lpszStr);
+
+  iLen = strlenW(lpszSearch);
+
+  while (lpszStr <= lpszEnd  && *lpszStr)
+  {
+    if (!COMCTL32_ChrCmpIA(*lpszSearch, *lpszStr))
+    {
+      if (!StrCmpNIW(lpszStr, lpszSearch, iLen))
+        lpszRet = (LPWSTR)lpszStr;
+    }
+    lpszStr = CharNextW(lpszStr);
+  }
+  return lpszRet;
+}
+
+/*************************************************************************
+ * COMCTL32_StrSpnHelperW
+ *
+ * Internal implementation of StrSpnW/StrCSpnW/StrCSpnIW
+ */
+static int COMCTL32_StrSpnHelperW(LPCWSTR lpszStr, LPCWSTR lpszMatch,
+                                  LPWSTR (WINAPI *pStrChrFn)(LPCWSTR,WCHAR),
+                                  BOOL bInvert)
+{
+  LPCWSTR lpszRead = lpszStr;
+  if (lpszStr && *lpszStr && lpszMatch)
+  {
+    while (*lpszRead)
+    {
+      LPCWSTR lpszTest = pStrChrFn(lpszMatch, *lpszRead);
+
+      if (!bInvert && !lpszTest)
+        break;
+      if (bInvert && lpszTest)
+        break;
+      lpszRead = CharNextW(lpszRead);
+    };
+  }
+  return lpszRead - lpszStr;
+}
+
+/*************************************************************************
+ * StrCSpnIA	[COMCTL32.374]
+ *
+ * Find the length of the start of a string that does not contain certain
+ * characters, ignoring case.
+ *
+ * PARAMS
+ *  lpszStr   [I] String to search
+ *  lpszMatch [I] Characters that cannot be in the substring
+ *
+ * RETURNS
+ *  The length of the part of lpszStr containing only chars not in lpszMatch,
+ *  or 0 if any parameter is invalid.
+ */
+int WINAPI StrCSpnIA(LPCSTR lpszStr, LPCSTR lpszMatch)
+{
+  TRACE("(%s,%s)\n",debugstr_a(lpszStr), debugstr_a(lpszMatch));
+
+  return COMCTL32_StrSpnHelperA(lpszStr, lpszMatch, StrChrIA, TRUE);
+}
+
+/*************************************************************************
+ * StrCSpnIW	[COMCTL32.375]
+ *
+ * See StrCSpnIA.
+ */
+int WINAPI StrCSpnIW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
+{
+  TRACE("(%s,%s)\n",debugstr_w(lpszStr), debugstr_w(lpszMatch));
+
+  return COMCTL32_StrSpnHelperW(lpszStr, lpszMatch, StrChrIW, TRUE);
+}
+
+/**************************************************************************
+ * StrRChrIA	[COMCTL32.368]
+ *
+ * Find the last occurence of a character in string, ignoring case.
+ *
+ * PARAMS
+ *  lpszStr [I] String to search in
+ *  lpszEnd [I] Place to end search, or NULL to search until the end of lpszStr
+ *  ch      [I] Character to search for.
+ *
+ * RETURNS
+ *  Success: A pointer to the last occurrence of ch in lpszStr before lpszEnd,
+ *           or NULL if not found.
+ *  Failure: NULL, if any arguments are invalid.
+ */
+LPSTR WINAPI StrRChrIA(LPCSTR lpszStr, LPCSTR lpszEnd, WORD ch)
+{
+  LPCSTR lpszRet = NULL;
+
+  TRACE("(%s,%s,%x)\n", debugstr_a(lpszStr), debugstr_a(lpszEnd), ch);
+
+  if (lpszStr)
+  {
+    WORD ch2;
+
+    if (!lpszEnd)
+      lpszEnd = lpszStr + lstrlenA(lpszStr);
+
+    while (*lpszStr && lpszStr <= lpszEnd)
+    {
+      ch2 = IsDBCSLeadByte(*lpszStr)? *lpszStr << 8 | lpszStr[1] : *lpszStr;
+
+      if (ch == ch2)
+        lpszRet = lpszStr;
+      lpszStr = CharNextA(lpszStr);
+    }
+  }
+  return (LPSTR)lpszRet;
+}
+
+/**************************************************************************
+ * StrRChrIW	[COMCTL32.369]
+ *
+ * See StrRChrIA.
+ */
+LPWSTR WINAPI StrRChrIW(LPCWSTR lpszStr, LPCWSTR lpszEnd, WORD ch)
+{
+  LPCWSTR lpszRet = NULL;
+
+  TRACE("(%s,%s,%x)\n", debugstr_w(lpszStr), debugstr_w(lpszEnd), ch);
+
+  if (lpszStr)
+  {
+    if (!lpszEnd)
+      lpszEnd = lpszStr + strlenW(lpszStr);
+
+    while (*lpszStr && lpszStr <= lpszEnd)
+    {
+      if (ch == *lpszStr)
+        lpszRet = lpszStr;
+      lpszStr = CharNextW(lpszStr);
+    }
+  }
+  return (LPWSTR)lpszRet;
+}
+
+/*************************************************************************
+ * StrSpnW	[COMCTL32.364]
+ *
+ * See StrSpnA.
+ */
+int WINAPI StrSpnW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
+{
+  TRACE("(%s,%s)\n",debugstr_w(lpszStr), debugstr_w(lpszMatch));
+
+  return COMCTL32_StrSpnHelperW(lpszStr, lpszMatch, StrChrW, FALSE);
+}
+
+/*************************************************************************
+ * StrCSpnW	[COMCTL32.@]
+ *
+ * See StrCSpnA.
+ */
+int WINAPI StrCSpnW(LPCWSTR lpszStr, LPCWSTR lpszMatch)
+{
+  TRACE("(%s,%s)\n",debugstr_w(lpszStr), debugstr_w(lpszMatch));
+
+  return COMCTL32_StrSpnHelperW(lpszStr, lpszMatch, StrChrW, TRUE);
+}
+
+/*************************************************************************
+ * IntlStrEqWorkerA	[COMCTL32.376]
+ *
+ * Compare two strings.
+ *
+ * PARAMS
+ *  bCase    [I] Whether to compare case sensitively
+ *  lpszStr  [I] First string to compare
+ *  lpszComp [I] Second string to compare
+ *  iLen     [I] Length to compare
+ *
+ * RETURNS
+ *  TRUE  If the strings are equal.
+ *  FALSE Otherwise.
+ */
+BOOL WINAPI IntlStrEqWorkerA(BOOL bCase, LPCSTR lpszStr, LPCSTR lpszComp,
+                             int iLen)
+{
+  DWORD dwFlags = LOCALE_USE_CP_ACP;
+  int iRet;
+
+  TRACE("(%d,%s,%s,%d)\n", bCase,
+        debugstr_a(lpszStr), debugstr_a(lpszComp), iLen);
+
+  /* FIXME: These flags are undocumented and unknown by our CompareString.
+   *        We need defines for them.
+   */
+  dwFlags |= bCase ? 0x10000000 : 0x10000001;
+
+  iRet = CompareStringA(GetThreadLocale(),
+                        dwFlags, lpszStr, iLen, lpszComp, iLen);
+
+  if (!iRet)
+    iRet = CompareStringA(2048, dwFlags, lpszStr, iLen, lpszComp, iLen);
+
+  return iRet == 2 ? TRUE : FALSE;
+}
+
+/*************************************************************************
+ * IntlStrEqWorkerW	[COMCTL32.377]
+ *
+ * See IntlStrEqWorkerA.
+ */
+BOOL WINAPI IntlStrEqWorkerW(BOOL bCase, LPCWSTR lpszStr, LPCWSTR lpszComp,
+                             int iLen)
+{
+  DWORD dwFlags;
+  int iRet;
+
+  TRACE("(%d,%s,%s,%d)\n", bCase,
+        debugstr_w(lpszStr),debugstr_w(lpszComp), iLen);
+
+  /* FIXME: These flags are undocumented and unknown by our CompareString.
+   *        We need defines for them.
+   */
+  dwFlags = bCase ? 0x10000000 : 0x10000001;
+
+  iRet = CompareStringW(GetThreadLocale(),
+                        dwFlags, lpszStr, iLen, lpszComp, iLen);
+
+  if (!iRet)
+    iRet = CompareStringW(2048, dwFlags, lpszStr, iLen, lpszComp, iLen);
+
+  return iRet == 2 ? TRUE : FALSE;
+}

reactos/lib/comctl32
Makefile.in 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- Makefile.in	28 Jan 2004 21:40:09 -0000	1.2
+++ Makefile.in	11 Mar 2004 11:13:28 -0000	1.3
@@ -28,6 +28,7 @@
 	propsheet.c \
 	rebar.c \
 	smoothscroll.c \
+	string.c \
 	status.c \
 	tab.c \
 	toolbar.c \
@@ -45,6 +46,7 @@
 	idb_std_small.bmp \
 	idb_view_large.bmp \
 	idb_view_small.bmp \
+	idc_copy.cur \
 	idc_divider.cur \
 	idc_divideropen.cur \
 	idi_dragarrow.ico \

reactos/lib/comctl32
comctl32.h 1.4 -> 1.5
diff -u -r1.4 -r1.5
--- comctl32.h	2 Jan 2004 19:49:45 -0000	1.4
+++ comctl32.h	11 Mar 2004 11:13:28 -0000	1.5
@@ -102,8 +102,9 @@
 #define IDC_DIVIDEROPEN                 107
 
 
-/* DragList icon */
-#define IDI_DRAGARROW                   150
+/* DragList resources */
+#define IDI_DRAGARROW                   501
+#define IDC_COPY                        502
 
 
 /* HOTKEY internal strings */

reactos/lib/comctl32
comctl32.spec 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- comctl32.spec	2 Jan 2004 19:49:45 -0000	1.1
+++ comctl32.spec	11 Mar 2004 11:13:28 -0000	1.2
@@ -77,16 +77,16 @@
 363 stdcall -noname StrStrIW(wstr wstr)
 364 stdcall -noname StrSpnW(wstr wstr)
 365 stdcall -noname StrToIntW(wstr)
-366 stub -noname StrChrIA
-367 stub -noname StrChrIW
-368 stub -noname StrRChrIA
-369 stub -noname StrRChrIW
-372 stub -noname StrRStrIA
-373 stub -noname StrRStrIW
-374 stub -noname StrCSpnIA
-375 stub -noname StrCSpnIW
-376 stub -noname IntlStrEqWorkerA
-377 stub -noname IntlStrEqWorkerW
+366 stdcall -noname StrChrIA(str long)
+367 stdcall -noname StrChrIW(wstr long)
+368 stdcall -noname StrRChrIA(str str long)
+369 stdcall -noname StrRChrIW(wstr wstr long)
+372 stdcall -noname StrRStrIA(str str str)
+373 stdcall -noname StrRStrIW(wstr wstr wstr)
+374 stdcall -noname StrCSpnIA(str str)
+375 stdcall -noname StrCSpnIW(wstr wstr)
+376 stdcall -noname IntlStrEqWorkerA(long str str long)
+377 stdcall -noname IntlStrEqWorkerW(long wstr wstr long)
 382 stdcall -noname SmoothScrollWindow(ptr)
 383 stub -noname DoReaderMode
 384 stub -noname SetPathWordBreakProc
@@ -106,13 +106,13 @@
 412 stdcall RemoveWindowSubclass(long ptr long)
 413 stdcall DefSubclassProc(long long long long)
 414 stub -noname MirrorIcon
-415 stdcall -noname DrawTextWrap(long long long long long)
-416 stub -noname DrawTextExPrivWrap
-417 stdcall -noname ExtTextOutWrap(long long long long ptr wstr long ptr)
-418 stub -noname GetCharWidthWrap
-419 stdcall -noname GetTextExtentPointWrap(long long long long)
-420 stub -noname GetTextExtentPoint32Wrap
-421 stub -noname TextOutWrap
+415 stdcall DrawTextWrap(long wstr long ptr long) user32.DrawTextW
+416 stdcall DrawTextExPrivWrap(long wstr long ptr long ptr) user32.DrawTextExW
+417 stdcall ExtTextOutWrap(long long long long ptr wstr long ptr) gdi32.ExtTextOutW
+418 stdcall GetCharWidthWrap(long long long long) gdi32.GetCharWidthW
+419 stdcall GetTextExtentPointWrap(long wstr long ptr) gdi32.GetTextExtentPointW
+420 stdcall GetTextExtentPoint32Wrap(long wstr long ptr) gdi32.GetTextExtentPoint32W
+421 stdcall TextOutWrap(long long long wstr long) gdi32.TextOutW
 
 # Functions imported by name
 

reactos/lib/comctl32
comctl32undoc.c 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- comctl32undoc.c	17 Feb 2004 22:32:53 -0000	1.6
+++ comctl32undoc.c	11 Mar 2004 11:13:28 -0000	1.7
@@ -25,16 +25,12 @@
  *     These functions are used by EXPLORER.EXE, IEXPLORE.EXE and
  *     COMCTL32.DLL (internally).
  *
- * TODO
- *     - Add more functions.
- *     - Write some documentation.
  */
 #include "config.h"
 #include "wine/port.h"
 
 #include <stdarg.h>
 #include <string.h>
-#include <stdlib.h> /* atoi */
 #include <ctype.h>
 #include <limits.h>
 
@@ -101,6 +97,10 @@
  *     pStream  [I] pointer to a stream
  *     lParam   [I] application specific value
  *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE 
+ *
  * NOTES
  *     No more information available yet!
  */
@@ -196,6 +196,10 @@
  *     pStream  [I] pointer to a stream
  *     lParam   [I] application specific value
  *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE 
+ *
  * NOTES
  *     No more information available yet!
  */
@@ -222,6 +226,10 @@
  *     pfnMerge    [I] pointer to merge function
  *     lParam      [I] application specific value
  *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE 
+ *
  * NOTES
  *     No more information available yet!
  */
@@ -505,8 +513,9 @@
 #define WMRUF_CHANGED  0x0001   /* MRU list has changed              */
 
 /**************************************************************************
- *              MRU_SaveChanged - Localize MRU saving code
+ *              MRU_SaveChanged (internal)
  *
+ * Localize MRU saving code
  */
 VOID MRU_SaveChanged( LPWINEMRULIST mp )
 {
@@ -570,11 +579,16 @@
 /**************************************************************************
  *              FreeMRUList [COMCTL32.152]
  *
+ * Frees a most-recently-used items list.
+ *
  * PARAMS
  *     hMRUList [I] Handle to list.
  *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
  */
-DWORD WINAPI
+BOOL WINAPI
 FreeMRUList (HANDLE hMRUList)
 {
     LPWINEMRULIST mp = (LPWINEMRULIST)hMRUList;
@@ -764,6 +778,8 @@
 
 /**************************************************************************
  *              AddMRUStringA [COMCTL32.153]
+ *
+ * See AddMRUStringW.
  */
 INT WINAPI
 AddMRUStringA(HANDLE hList, LPCSTR lpszString)
@@ -794,6 +810,8 @@
 
 /**************************************************************************
  *                  FindMRUStringW [COMCTL32.402]
+ *
+ * See FindMRUStringA.
  */
 INT WINAPI
 FindMRUStringW (HANDLE hList, LPCWSTR lpszString, LPINT lpRegNum)
@@ -831,7 +849,7 @@
 }
 
 /*************************************************************************
- *                 CreateMRUListLazy_common
+ *                 CreateMRUListLazy_common (internal)
  */
 HANDLE CreateMRUListLazy_common(LPWINEMRULIST mp)
 {
@@ -915,6 +933,8 @@
 
 /**************************************************************************
  *                  CreateMRUListLazyW [COMCTL32.404]
+ *
+ * See CreateMRUListLazyA.
  */
 HANDLE WINAPI
 CreateMRUListLazyW (LPCREATEMRULISTW lpcml, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
@@ -938,6 +958,17 @@
 
 /**************************************************************************
  *                  CreateMRUListLazyA [COMCTL32.157]
+ *
+ * Creates a most-recently-used list.
+ *
+ * PARAMS
+ *     lpcml    [I] ptr to CREATEMRULIST structure.
+ *     dwParam2 [I] Unknown
+ *     dwParam3 [I] Unknown
+ *     dwParam4 [I] Unknown
+ *
+ * RETURNS
+ *     Handle to MRU list.
  */
 HANDLE WINAPI
 CreateMRUListLazyA (LPCREATEMRULISTA lpcml, DWORD dwParam2, DWORD dwParam3, DWORD dwParam4)
@@ -964,11 +995,7 @@
 /**************************************************************************
  *              CreateMRUListW [COMCTL32.400]
  *
- * PARAMS
- *     lpcml [I] ptr to CREATEMRULIST structure.
- *
- * RETURNS
- *     Handle to MRU list.
+ * See CreateMRUListA.
  */
 HANDLE WINAPI
 CreateMRUListW (LPCREATEMRULISTW lpcml)
@@ -978,6 +1005,14 @@
 
 /**************************************************************************
  *              CreateMRUListA [COMCTL32.151]
+ *
+ * Creates a most-recently-used list.
+ *
+ * PARAMS
+ *     lpcml [I] ptr to CREATEMRULIST structure.
+ *
+ * RETURNS
+ *     Handle to MRU list.
  */
 HANDLE WINAPI
 CreateMRUListA (LPCREATEMRULISTA lpcml)
@@ -989,7 +1024,7 @@
 /**************************************************************************
  *                EnumMRUListW [COMCTL32.403]
  *
- * Enumerate item in a list
+ * Enumerate item in a most-recenty-used list
  *
  * PARAMS
  *    hList [I] list handle
@@ -1027,6 +1062,7 @@
 /**************************************************************************
  *                EnumMRUListA [COMCTL32.154]
  *
+ * See EnumMRUListW.
  */
 INT WINAPI EnumMRUListA(HANDLE hList, INT nItemPos, LPVOID lpBuffer,
 DWORD nBufferSize)
@@ -1061,12 +1097,15 @@
 /**************************************************************************
  * Str_GetPtrA [COMCTL32.233]
  *
+ * Copies a string into a destination buffer.
+ *
  * PARAMS
- *     lpSrc   [I]
- *     lpDest  [O]
- *     nMaxLen [I]
+ *     lpSrc   [I] Source string
+ *     lpDest  [O] Destination buffer
+ *     nMaxLen [I] Size of buffer in characters
  *
  * RETURNS
+ *     The number of characters copied.
  */
 
 INT WINAPI
@@ -1101,11 +1140,19 @@
 /**************************************************************************
  * Str_SetPtrA [COMCTL32.234]
  *
+ * Makes a copy of a string, allocating memory if necessary.
+ *
  * PARAMS
- *     lppDest [O]
- *     lpSrc   [I]
+ *     lppDest [O] Pointer to destination string
+ *     lpSrc   [I] Source string
  *
  * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * NOTES
+ *     Set lpSrc to NULL to free the memory allocated by a previous call
+ *     to this function.
  */
 
 BOOL WINAPI
@@ -1134,12 +1181,7 @@
 /**************************************************************************
  * Str_GetPtrW [COMCTL32.235]
  *
- * PARAMS
- *     lpSrc   [I]
- *     lpDest  [O]
- *     nMaxLen [I]
- *
- * RETURNS
+ * See Str_GetPtrA.
  */
 
 INT WINAPI
@@ -1174,11 +1216,7 @@
 /**************************************************************************
  * Str_SetPtrW [COMCTL32.236]
  *
- * PARAMS
- *     lpDest [O]
- *     lpSrc  [I]
- *
- * RETURNS
+ * See Str_SetPtrA.
  */
 
 BOOL WINAPI
@@ -1292,13 +1330,9 @@
 
 
 /**************************************************************************
- * The DSA-API is a set of functions to create and manipulate arrays of
- * fixed-size memory blocks. These arrays can store any kind of data
- * (strings, icons...).
- */
-
-/**************************************************************************
- * DSA_Create [COMCTL32.320] Creates a dynamic storage array
+ * DSA_Create [COMCTL32.320]
+ *
+ * Creates a dynamic storage array
  *
  * PARAMS
  *     nSize [I] size of the array elements
@@ -1307,6 +1341,11 @@
  * RETURNS
  *     Success: pointer to an array control structure. Use this like a handle.
  *     Failure: NULL
+ *
+ * NOTES
+ *     The DSA_ functions can be used to create and manipulate arrays of
+ *     fixed-size memory blocks. These arrays can store any kind of data
+ *     (e.g. strings and icons).
  */
 
 HDSA WINAPI
@@ -1331,7 +1370,9 @@
 
 
 /**************************************************************************
- * DSA_Destroy [COMCTL32.321] Destroys a dynamic storage array
+ * DSA_Destroy [COMCTL32.321]
+ * 
+ * Destroys a dynamic storage array
  *
  * PARAMS
  *     hdsa [I] pointer to the array control structure
@@ -1359,6 +1400,8 @@
 /**************************************************************************
  * DSA_GetItem [COMCTL32.322]
  *
+ * Copies the specified item into a caller-supplied buffer.
+ *
  * PARAMS
  *     hdsa   [I] pointer to the array control structure
  *     nIndex [I] number of the Item to get
@@ -1483,6 +1526,8 @@
 /**************************************************************************
  * DSA_InsertItem [COMCTL32.324]
  *
+ * Inserts an item into the array at the specified index.
+ *
  * PARAMS
  *     hdsa   [I] pointer to the array control structure
  *     nIndex [I] index for the new item
@@ -1545,6 +1590,8 @@
 /**************************************************************************
  * DSA_DeleteItem [COMCTL32.326]
  *
+ * Deletes the specified item from the array.
+ *
  * PARAMS
  *     hdsa   [I] pointer to the array control structure
  *     nIndex [I] index for the element to delete
@@ -1627,12 +1674,9 @@
 
 
 /**************************************************************************
- * The DPA-API is a set of functions to create and manipulate arrays of
- * pointers.
- */
-
-/**************************************************************************
- * DPA_Destroy [COMCTL32.329] Destroys a dynamic pointer array
+ * DPA_Destroy [COMCTL32.329]
+ *
+ * Destroys a dynamic pointer array
  *
  * PARAMS
  *     hdpa [I] handle (pointer) to the pointer array
@@ -2180,6 +2224,10 @@
  * RETURNS
  *     Success: handle (pointer) to the pointer array.
  *     Failure: NULL
+ *
+ * NOTES
+ *     The DPA_ functions can be used to create and manipulate arrays of
+ *     pointers.
  */
 
 HDPA WINAPI
@@ -2209,7 +2257,9 @@
 
 
 /**************************************************************************
- * DPA_Create [COMCTL32.328] Creates a dynamic pointer array
+ * DPA_Create [COMCTL32.328]
+ *
+ * Creates a dynamic pointer array.
  *
  * PARAMS
  *     nGrow [I] number of items by which the array grows when it is filled
@@ -2217,6 +2267,10 @@
  * RETURNS
  *     Success: handle (pointer) to the pointer array.
  *     Failure: NULL
+ *
+ * NOTES
+ *     The DPA_ functions can be used to create and manipulate arrays of
+ *     pointers.
  */
 
 HDPA WINAPI
@@ -2281,15 +2335,22 @@
 /**************************************************************************
  * SendNotify [COMCTL32.341]
  *
+ * Sends a WM_NOTIFY message to the specified window.
+ *
  * PARAMS
- *     hwndTo   [I]
- *     hwndFrom [I]
- *     uCode    [I]
- *     lpHdr    [I]
+ *     hwndTo   [I] Window to receive the message
+ *     hwndFrom [I] Window that the message is from (see notes)
+ *     uCode    [I] Notification code
+ *     lpHdr    [I] The NMHDR and any additional information to send or NULL
  *
  * RETURNS
  *     Success: return value from notification
  *     Failure: 0
+ *
+ * NOTES
+ *     If hwndFrom is -1 then the identifier of the control sending the
+ *     message is taken from the NMHDR structure.
+ *     If hwndFrom is not -1 then lpHdr can be NULL.
  */
 
 LRESULT WINAPI SendNotify (HWND hwndTo, HWND hwndFrom, UINT uCode, LPNMHDR lpHdr)
@@ -2311,16 +2372,23 @@
 /**************************************************************************
  * SendNotifyEx [COMCTL32.342]
  *
+ * Sends a WM_NOTIFY message to the specified window.
+ *
  * PARAMS
- *     hwndFrom [I]
- *     hwndTo   [I]
- *     uCode    [I]
- *     lpHdr    [I]
- *     dwParam5 [I]
+ *     hwndFrom [I] Window to receive the message
+ *     hwndTo   [I] Window that the message is from
+ *     uCode    [I] Notification code
+ *     lpHdr    [I] The NMHDR and any additional information to send or NULL
+ *     dwParam5 [I] Unknown
  *
  * RETURNS
  *     Success: return value from notification
  *     Failure: 0
+ *
+ * NOTES
+ *     If hwndFrom is -1 then the identifier of the control sending the
+ *     message is taken from the NMHDR structure.
+ *     If hwndFrom is not -1 then lpHdr can be NULL.
  */
 
 LRESULT WINAPI SendNotifyEx (HWND hwndTo, HWND hwndFrom, UINT uCode,
@@ -2350,96 +2418,6 @@
 }
 
 
-/**************************************************************************
- * StrChrA [COMCTL32.350]
- *
- */
-
-LPSTR WINAPI StrChrA (LPCSTR lpString, CHAR cChar)
-{
-    return strchr (lpString, cChar);
-}
-
-
-/**************************************************************************
- * StrStrIA [COMCTL32.355]
- */
-
-LPSTR WINAPI StrStrIA (LPCSTR lpStr1, LPCSTR lpStr2)
-{
-    INT len1, len2, i;
-    CHAR  first;
-
-    if (*lpStr2 == 0)
-	return ((LPSTR)lpStr1);
-    len1 = 0;
-    while (lpStr1[len1] != 0) ++len1;
-    len2 = 0;
-    while (lpStr2[len2] != 0) ++len2;
-    if (len2 == 0)
-	return ((LPSTR)(lpStr1 + len1));
-    first = tolower (*lpStr2);
-    while (len1 >= len2) {
-	if (tolower(*lpStr1) == first) {
-	    for (i = 1; i < len2; ++i)
-		if (tolower (lpStr1[i]) != tolower(lpStr2[i]))
-		    break;
-	    if (i >= len2)
-		return ((LPSTR)lpStr1);
-        }
-	++lpStr1; --len1;
-    }
-    return (NULL);
-}
-
-/**************************************************************************
- * StrToIntA [COMCTL32.357] Converts a string to a signed integer.
- */
-
-INT WINAPI StrToIntA (LPSTR lpString)
-{
-    return atoi(lpString);
-}
-
-/**************************************************************************
- * StrStrIW [COMCTL32.363]
- */
-
-LPWSTR WINAPI StrStrIW (LPCWSTR lpStr1, LPCWSTR lpStr2)
-{
-    INT len1, len2, i;
-    WCHAR  first;
-
-    if (*lpStr2 == 0)
-	return ((LPWSTR)lpStr1);
-    len1 = 0;
-    while (lpStr1[len1] != 0) ++len1;
-    len2 = 0;
-    while (lpStr2[len2] != 0) ++len2;
-    if (len2 == 0)
-	return ((LPWSTR)(lpStr1 + len1));
-    first = tolowerW (*lpStr2);
-    while (len1 >= len2) {
-	if (tolowerW (*lpStr1) == first) {
-	    for (i = 1; i < len2; ++i)
-		if (tolowerW (lpStr1[i]) != tolowerW(lpStr2[i]))
-		    break;
-	    if (i >= len2)
-		return ((LPWSTR)lpStr1);
-        }
-	++lpStr1; --len1;
-    }
-    return (NULL);
-}
-
-/**************************************************************************
- * StrToIntW [COMCTL32.365] Converts a wide char string to a signed integer.
- */
-
-INT WINAPI StrToIntW (LPWSTR lpString)
-{
-    return atoiW(lpString);
-}
 
 
 /**************************************************************************
@@ -2559,176 +2537,3 @@
     DSA_EnumCallback (hdsa, enumProc, lParam);
     DSA_Destroy (hdsa);
 }
-
-/**************************************************************************
- * StrCSpnA [COMCTL32.356]
- *
- */
-INT WINAPI StrCSpnA( LPCSTR lpStr, LPCSTR lpSet)
-{
-  return strcspn(lpStr, lpSet);
-}
-
-/**************************************************************************
- * StrChrW [COMCTL32.358]
- *
- */
-LPWSTR WINAPI StrChrW( LPCWSTR lpStart, WORD wMatch)
-{
-  return strchrW(lpStart, wMatch);
-}
-
-/**************************************************************************
- * StrCmpNA [COMCTL32.352]
- *
- */
-INT WINAPI StrCmpNA( LPCSTR lpStr1, LPCSTR lpStr2, int nChar)
-{
-  return strncmp(lpStr1, lpStr2, nChar);
-}
-
-/**************************************************************************
- * StrCmpNIA [COMCTL32.353]
- *
- */
-INT WINAPI StrCmpNIA( LPCSTR lpStr1, LPCSTR lpStr2, int nChar)
-{
-  return strncasecmp(lpStr1, lpStr2, nChar);
-}
-
-/**************************************************************************
- * StrCmpNW [COMCTL32.360]
- *
- */
-INT WINAPI StrCmpNW( LPCWSTR lpStr1, LPCWSTR lpStr2, int nChar)
-{
-  return strncmpW(lpStr1, lpStr2, nChar);
-}
-
-/**************************************************************************
- * StrCmpNIW [COMCTL32.361]
- *
- */
-INT WINAPI StrCmpNIW( LPCWSTR lpStr1, LPCWSTR lpStr2, int nChar)
-{
-  FIXME("(%s, %s, %i): stub\n", debugstr_w(lpStr1), debugstr_w(lpStr2), nChar);
-  return 0;
-}
-
-/**************************************************************************
- * StrRChrA [COMCTL32.351]
- *
- */
-LPSTR WINAPI StrRChrA( LPCSTR lpStart, LPCSTR lpEnd, WORD wMatch )
-{
-    LPCSTR lpGotIt = NULL;
-    BOOL dbcs = IsDBCSLeadByte( LOBYTE(wMatch) );
-
-    TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
-
-    if (!lpEnd) lpEnd = lpStart + strlen(lpStart);
-
-    for(; lpStart < lpEnd; lpStart = CharNextA(lpStart))
-    {
-        if (*lpStart != LOBYTE(wMatch)) continue;
-        if (dbcs && lpStart[1] != HIBYTE(wMatch)) continue;
-        lpGotIt = lpStart;
-    }
-    return (LPSTR)lpGotIt;
-}
-
-
-/**************************************************************************
- * StrRChrW [COMCTL32.359]
- *
- */
-LPWSTR WINAPI StrRChrW( LPCWSTR lpStart, LPCWSTR lpEnd, WORD wMatch)
-{
-    LPCWSTR lpGotIt = NULL;
-
-    TRACE("(%p, %p, %x)\n", lpStart, lpEnd, wMatch);
-    if (!lpEnd) lpEnd = lpStart + strlenW(lpStart);
-
-    for(; lpStart < lpEnd; lpStart = CharNextW(lpStart))
-        if (*lpStart == wMatch) lpGotIt = lpStart;
-
-    return (LPWSTR)lpGotIt;
-}
-
-
-/**************************************************************************
- * StrStrA [COMCTL32.354]
- *
- */
-LPSTR WINAPI StrStrA( LPCSTR lpFirst, LPCSTR lpSrch)
-{
-  return strstr(lpFirst, lpSrch);
-}
-
-/**************************************************************************
- * StrStrW [COMCTL32.362]
- *
- */
-LPWSTR WINAPI StrStrW( LPCWSTR lpFirst, LPCWSTR lpSrch)
-{
-  return strstrW(lpFirst, lpSrch);
-}
-
-/**************************************************************************
- * StrSpnW [COMCTL32.364]
- *
- */
-INT WINAPI StrSpnW( LPWSTR lpStr, LPWSTR lpSet)
-{
-  LPWSTR lpLoop = lpStr;
-
-  /* validate ptr */
-  if ((lpStr == 0) || (lpSet == 0)) return 0;
-
-/* while(*lpLoop) { if lpLoop++; } */
-
-  for(; (*lpLoop != 0); lpLoop++)
-    if( strchrW(lpSet, *(WORD*)lpLoop))
-      return (INT)(lpLoop-lpStr);
-
-  return (INT)(lpLoop-lpStr);
-}
-
-/**************************************************************************
- * @ [COMCTL32.415]
- *
- * FIXME: What's this supposed to do?
- *        Parameter 1 is an HWND, you're on your own for the rest.
- */
-
-BOOL WINAPI DrawTextWrap( HWND hwnd, DWORD b, DWORD c, DWORD d, DWORD e)
-{
-
-   FIXME("(%p, %lx, %lx, %lx, %lx): stub!\n", hwnd, b, c, d, e);
-
-   return TRUE;
-}
-
-/**************************************************************************
- * @ [COMCTL32.417]
- *
- */
-BOOL WINAPI ExtTextOutWrap(HDC hdc, INT x, INT y, UINT flags, const RECT *lprect,
-                         LPCWSTR str, UINT count, const INT *lpDx)
-{
-    return ExtTextOutW(hdc, x, y, flags, lprect, str, count, lpDx);
-}
-
-/**************************************************************************
- * @ [COMCTL32.419]
- *
- * FIXME: What's this supposed to do?
- */
-
-BOOL WINAPI GetTextExtentPointWrap( DWORD a, DWORD b, DWORD c, DWORD d)
-{
-
-   FIXME("(%lx, %lx, %lx, %lx): stub!\n", a, b, c, d);
-
-   return TRUE;
-}

reactos/lib/comctl32
commctrl.c 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- commctrl.c	28 Jan 2004 21:40:09 -0000	1.7
+++ commctrl.c	11 Mar 2004 11:13:28 -0000	1.8
@@ -131,7 +131,9 @@
 
 
 /***********************************************************************
- * DllMain [Internal] Initializes the internal 'COMCTL32.DLL'.
+ * DllMain [Internal]
+ *
+ * Initializes the internal 'COMCTL32.DLL'.
  *
  * PARAMS
  *     hinstDLL    [I] handle to the 'dlls' instance
@@ -223,6 +225,9 @@
 /***********************************************************************
  * MenuHelp [COMCTL32.2]
  *
+ * Handles the setting of status bar help messages when the user
+ * selects menu items.
+ *
  * PARAMS
  *     uMsg       [I] message (WM_MENUSELECT) (see NOTES)
  *     wParam     [I] wParam of the message uMsg
@@ -378,6 +383,8 @@
 /***********************************************************************
  * GetEffectiveClientRect [COMCTL32.4]
  *
+ * Calculates the coordinates of a rectangle in the client area.
+ *
  * PARAMS
  *     hwnd   [I] handle to the client window.
  *     lpRect [O] pointer to the rectangle of the client window
@@ -536,7 +543,9 @@
 
 
 /***********************************************************************
- * CreateStatusWindowW [COMCTL32.@] Creates a status bar control
+ * CreateStatusWindowW [COMCTL32.@]
+ *
+ * Creates a status bar control
  *
  * PARAMS
  *     style  [I] window style
@@ -560,7 +569,9 @@
 
 
 /***********************************************************************
- * CreateUpDownControl [COMCTL32.16] Creates an up-down control
+ * CreateUpDownControl [COMCTL32.16]
+ *
+ * Creates an up-down control
  *
  * PARAMS
  *     style  [I] window styles
@@ -711,7 +722,9 @@
 
 
 /***********************************************************************
- * CreateToolbarEx [COMCTL32.@] Creates a tool bar window
+ * CreateToolbarEx [COMCTL32.@]
+ *
+ * Creates a toolbar window.
  *
  * PARAMS
  *     hwnd
@@ -794,12 +807,14 @@
 /***********************************************************************
  * CreateMappedBitmap [COMCTL32.8]
  *
+ * Loads a bitmap resource using a colour map.
+ *
  * PARAMS
- *     hInstance  [I]
- *     idBitmap   [I]
- *     wFlags     [I]
- *     lpColorMap [I]
- *     iNumMaps   [I]
+ *     hInstance  [I] Handle to the module containing the bitmap.
+ *     idBitmap   [I] The bitmap resource ID.
+ *     wFlags     [I] CMB_MASKED for using bitmap as a mask or 0 for normal.
+ *     lpColorMap [I] Colour information needed for the bitmap or NULL (uses system colours).
+ *     iNumMaps   [I] Number of COLORMAP's pointed to by lpColorMap.
  *
  * RETURNS
  *     Success: handle to the new bitmap
@@ -900,7 +915,9 @@
 
 
 /***********************************************************************
- * CreateToolbar [COMCTL32.7] Creates a tool bar control
+ * CreateToolbar [COMCTL32.7]
+ *
+ * Creates a toolbar control.
  *
  * PARAMS
  *     hwnd
@@ -969,6 +986,12 @@
 
 /***********************************************************************
  *		DllInstall (COMCTL32.@)
+ *
+ * Installs the ComCtl32 DLL.
+ *
+ * RETURNS
+ *     Success: S_OK
+ *     Failure: A HRESULT error
  */
 HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline)
 {
@@ -1011,9 +1034,10 @@
 /*************************************************************************
  * GetMUILanguage [COMCTL32.@]
  *
- * FIXME: "Returns the language currently in use by the common controls
- * for a particular process." (MSDN)
+ * Returns the user interface language in use by the current process.
  *
+ * RETURNS
+ *      Language ID in use by the current process.
  */
 LANGID WINAPI GetMUILanguage (VOID)
 {
@@ -1024,11 +1048,11 @@
 /*************************************************************************
  * InitMUILanguage [COMCTL32.@]
  *
- * FIXME: "Enables an application to specify a language to be used with
- * the common controls that is different than the system language." (MSDN)
+ * Sets the user interface language to be used by the current process.
  *
+ * RETURNS
+ *      Nothing.
  */
-
 VOID WINAPI InitMUILanguage (LANGID uiLang)
 {
    COMCTL32_uiLang = uiLang;

reactos/lib/comctl32
draglist.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- draglist.c	6 Oct 2003 16:13:26 -0000	1.2
+++ draglist.c	11 Mar 2004 11:13:28 -0000	1.3
@@ -2,6 +2,7 @@
  * Drag List control
  *
  * Copyright 1999 Eric Kohl
+ * Copyright 2004 Robert Shearman
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -17,13 +18,6 @@
  * 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 is just a dummy control. An author is needed! Any volunteers?
- *   I will only improve this control once in a while.
- *     Eric <ekohl@abo.rhein-zeitung.de>
- *
- * TODO:
- *   - Everything.
  */
 
 #include <stdarg.h>
@@ -33,37 +27,265 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "winnls.h"
+#include "winnt.h"
 #include "commctrl.h"
+#include "comctl32.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(commctrl);
 
+#ifndef TEXT
+# define TEXT(string) string
+#endif
+
+#define DRAGLIST_SUBCLASSID     0
+#define DRAGLIST_SCROLLPERIOD 200
+#define DRAGLIST_TIMERID      666
+
+/* properties relating to IDI_DRAGICON */
+#define DRAGICON_HOTSPOT_X 17
+#define DRAGICON_HOTSPOT_Y  7
+#define DRAGICON_HEIGHT    32
 
+/* internal Wine specific data for the drag list control */
+typedef struct _DRAGLISTDATA
+{
+	/* are we currently in dragging mode? */
+	BOOL dragging;
+
+	/* cursor to use as determined by DL_DRAGGING notification.
+     * NOTE: as we use LoadCursor we don't have to use DeleteCursor
+     * when we are finished with it */
+	HCURSOR cursor;
+
+    /* optimisation so that we don't have to load the cursor
+     * all of the time whilst dragging */
+	LRESULT last_dragging_response;
+    /* prevents flicker with drawing drag arrow */
+    RECT last_drag_icon_rect;
+} DRAGLISTDATA;
+
+static UINT uDragListMessage = 0; /* registered window message code */
 static DWORD dwLastScrollTime = 0;
+static HICON hDragArrow = NULL;
+
+/***********************************************************************
+ *		DragList_Notify (internal)
+ *
+ * Sends notification messages to the parent control. Note that it
+ * does not use WM_NOTIFY like the rest of the controls, but a registered
+ * window message.
+ */
+static LRESULT DragList_Notify(HWND hwndLB, UINT uNotification)
+{
+    DRAGLISTINFO dli;
+    dli.hWnd = hwndLB;
+    dli.uNotification = uNotification;
+    GetCursorPos(&dli.ptCursor);
+    return SendMessageW(GetParent(hwndLB), uDragListMessage, GetDlgCtrlID(hwndLB), (LPARAM)&dli);
+}
+
+/* cleans up after dragging */
+static inline void DragList_EndDrag(HWND hwnd, DRAGLISTDATA * data)
+{
+    KillTimer(hwnd, DRAGLIST_TIMERID);
+    ReleaseCapture();
+    data->dragging = FALSE;
+    /* clear any drag insert icon present */
+    InvalidateRect(GetParent(hwnd), &data->last_drag_icon_rect, TRUE);
+}
+
+/***********************************************************************
+ *		DragList_SubclassWindowProc (internal)
+ *
+ * Handles certain messages to enable dragging for the ListBox and forwards
+ * the rest to the ListBox.
+ */
+static LRESULT CALLBACK
+DragList_SubclassWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
+{
+    DRAGLISTDATA * data = (DRAGLISTDATA*)dwRefData;
+    switch (uMsg)
+    {
+    case WM_LBUTTONDOWN:
+        SetFocus(hwnd);
+        data->cursor = NULL;
+        SetRectEmpty(&data->last_drag_icon_rect);
+        data->dragging = DragList_Notify(hwnd, DL_BEGINDRAG);
+        if (data->dragging)
+        {
+            SetCapture(hwnd);
+            SetTimer(hwnd, DRAGLIST_TIMERID, DRAGLIST_SCROLLPERIOD, NULL);
+        }
+        /* note that we don't absorb this message to let the list box
+         * do its thing (normally selecting an item) */
+        break;
+
+    case WM_KEYDOWN:
+    case WM_RBUTTONDOWN:
+        /* user cancelled drag by either right clicking or
+         * by pressing the escape key */
+        if ((data->dragging) &&
+            ((uMsg == WM_RBUTTONDOWN) || (wParam == VK_ESCAPE)))
+        {
+            /* clean up and absorb message */
+            DragList_EndDrag(hwnd, data);
+            DragList_Notify(hwnd, DL_CANCELDRAG);
+            return 0;
+        }
+        break;
+
+    case WM_MOUSEMOVE:
+    case WM_TIMER:
+        if (data->dragging)
+        {
+            LRESULT cursor = DragList_Notify(hwnd, DL_DRAGGING);
+            /* optimisation so that we don't have to load the cursor
+             * all of the time whilst dragging */
+            if (data->last_dragging_response != cursor)
+            {
+                switch (cursor)
+                {
+                case DL_STOPCURSOR:
+                    data->cursor = LoadCursorW(NULL, (LPCWSTR)IDC_NO);
+                    SetCursor(data->cursor);
+                    break;
+                case DL_COPYCURSOR:
+                    data->cursor = LoadCursorW(COMCTL32_hModule, (LPCWSTR)IDC_COPY);
+                    SetCursor(data->cursor);
+                    break;
+                case DL_MOVECURSOR:
+                    data->cursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
+                    SetCursor(data->cursor);
+                    break;
+                }
+                data->last_dragging_response = cursor;
+            }
+            /* don't pass this message on to List Box */
+            return 0;
+        }
+        break;
+
+    case WM_LBUTTONUP:
+        if (data->dragging)
+        {
+            DragList_EndDrag(hwnd, data);
+            DragList_Notify(hwnd, DL_DROPPED);
+        }
+        break;
+
+	case WM_SETCURSOR:
+	    /* if app has told us to set a cursor then do so */
+        if (data->dragging && data->cursor)
+        {
+            SetCursor(data->cursor);
+            return TRUE;
+        }
+        break;
+
+    case WM_GETDLGCODE:
+        /* tell dialog boxes that we want to receive WM_KEYDOWN events
+         * for keys like VK_ESCAPE */
+        if (data->dragging)
+            return DLGC_WANTALLKEYS;
+        break;
+    case WM_NCDESTROY:
+        RemoveWindowSubclass(hwnd, DragList_SubclassWindowProc, DRAGLIST_SUBCLASSID);
+        Free(data);
+        break;
+    }
+    return DefSubclassProc(hwnd, uMsg, wParam, lParam);
+}
 
 /***********************************************************************
  *		MakeDragList (COMCTL32.13)
+ *
+ * Makes a normal ListBox into a DragList by subclassing it.
+ *
+ * RETURNS
+ *      Success: Non-zero
+ *      Failure: Zero
  */
 BOOL WINAPI MakeDragList (HWND hwndLB)
 {
-    FIXME("(%p)\n", hwndLB);
+    DRAGLISTDATA * data = Alloc(sizeof(DRAGLISTDATA));
 
+    TRACE("(%p)\n", hwndLB);
 
-    return FALSE;
+    if (!uDragListMessage)
+        uDragListMessage = RegisterWindowMessageA(DRAGLISTMSGSTRING);
+
+    return SetWindowSubclass(hwndLB, DragList_SubclassWindowProc, DRAGLIST_SUBCLASSID, (DWORD_PTR)data);
 }
 
 /***********************************************************************
  *		DrawInsert (COMCTL32.15)
+ *
+ * Draws insert arrow by the side of the ListBox item in the parent window.
+ *
+ * RETURNS
+ *      Nothing.
  */
 VOID WINAPI DrawInsert (HWND hwndParent, HWND hwndLB, INT nItem)
 {
-    FIXME("(%p %p %d)\n", hwndParent, hwndLB, nItem);
+    RECT rcItem, rcListBox, rcDragIcon;
+    HDC hdc;
+    DRAGLISTDATA * data;
+
+    TRACE("(%p %p %d)\n", hwndParent, hwndLB, nItem);
+
+    if (!hDragArrow)
+        hDragArrow = LoadIconW(COMCTL32_hModule, (LPCWSTR)IDI_DRAGARROW);
+
+    if (LB_ERR == SendMessageW(hwndLB, LB_GETITEMRECT, nItem, (LPARAM)&rcItem))
+        return;
+
+    if (!GetWindowRect(hwndLB, &rcListBox))
+        return;
+
+    /* convert item rect to parent co-ordinates */
+    if (!MapWindowPoints(hwndLB, hwndParent, (LPPOINT)&rcItem, 2))
+        return;
+
+    /* convert list box rect to parent co-ordinates */
+    if (!MapWindowPoints(HWND_DESKTOP, hwndParent, (LPPOINT)&rcListBox, 2))
+        return;
+
+    rcDragIcon.left = rcListBox.left - DRAGICON_HOTSPOT_X;
+    rcDragIcon.top = rcItem.top - DRAGICON_HOTSPOT_Y;
+    rcDragIcon.right = rcListBox.left;
+    rcDragIcon.bottom = rcDragIcon.top + DRAGICON_HEIGHT;
+
+    if (!GetWindowSubclass(hwndLB, DragList_SubclassWindowProc, DRAGLIST_SUBCLASSID, (DWORD_PTR*)&data))
+        return;
+
+    /* prevent flicker by only redrawing when necessary */
+    if (!EqualRect(&rcDragIcon, &data->last_drag_icon_rect))
+    {
+        /* get rid of any previous inserts drawn */
+        RedrawWindow(hwndParent, &data->last_drag_icon_rect, NULL,
+            RDW_INTERNALPAINT | RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);
+
+        if (nItem >= 0)
+        {
+            hdc = GetDC(hwndParent);
 
+            DrawIcon(hdc, rcDragIcon.left, rcDragIcon.top, hDragArrow);
 
+            ReleaseDC(hwndParent, hdc);
+        }
+    }
+    CopyRect(&data->last_drag_icon_rect, &rcDragIcon);
 }
 
 /***********************************************************************
  *		LBItemFromPt (COMCTL32.14)
+ *
+ * Gets the index of the ListBox item under the specified point,
+ * scrolling if bAutoScroll is TRUE and pt is outside of the ListBox.
+ *
+ * RETURNS
+ *      The ListBox item ID if pt is over a list item or -1 otherwise.
  */
 INT WINAPI LBItemFromPt (HWND hwndLB, POINT pt, BOOL bAutoScroll)
 {
@@ -71,8 +293,8 @@
     INT nIndex;
     DWORD dwScrollTime;
 
-    FIXME("(%p %ld x %ld %s)\n",
-	   hwndLB, pt.x, pt.y, bAutoScroll ? "TRUE" : "FALSE");
+    TRACE("(%p %ld x %ld %s)\n",
+           hwndLB, pt.x, pt.y, bAutoScroll ? "TRUE" : "FALSE");
 
     ScreenToClient (hwndLB, &pt);
     GetClientRect (hwndLB, &rcClient);
@@ -80,54 +302,41 @@
 
     if (PtInRect (&rcClient, pt))
     {
-	/* point is inside -- get the item index */
-	while (TRUE)
-	{
-	    if (SendMessageA (hwndLB, LB_GETITEMRECT, nIndex, (LPARAM)&rcClient) == LB_ERR)
-		return -1;
+        /* point is inside -- get the item index */
+        while (TRUE)
+        {
+            if (SendMessageA (hwndLB, LB_GETITEMRECT, nIndex, (LPARAM)&rcClient) == LB_ERR)
+                return -1;
 
-	    if (PtInRect (&rcClient, pt))
-		return nIndex;
+            if (PtInRect (&rcClient, pt))
+                return nIndex;
 
-	    nIndex++;
-	}
+            nIndex++;
+        }
     }
     else
     {
-	/* point is outside */
-	if (!bAutoScroll)
-	    return -1;
+        /* point is outside */
+        if (!bAutoScroll)
+            return -1;
 
-	if ((pt.x > rcClient.right) || (pt.x < rcClient.left))
-	    return -1;
+        if ((pt.x > rcClient.right) || (pt.x < rcClient.left))
+            return -1;
 
-	if (pt.y < 0)
-	    nIndex--;
-	else
-	    nIndex++;
+        if (pt.y < 0)
+            nIndex--;
+        else
+            nIndex++;
 
-	dwScrollTime = GetTickCount ();
+        dwScrollTime = GetTickCount ();
 
-	if ((dwScrollTime - dwLastScrollTime) < 200)
-	    return -1;
+        if ((dwScrollTime - dwLastScrollTime) < DRAGLIST_SCROLLPERIOD)
+            return -1;
 
-	dwLastScrollTime = dwScrollTime;
+        dwLastScrollTime = dwScrollTime;
 
-	SendMessageA (hwndLB, LB_SETTOPINDEX, (WPARAM)nIndex, 0);
+        SendMessageA (hwndLB, LB_SETTOPINDEX, (WPARAM)nIndex, 0);
     }
 
     return -1;
 }
-
-
-#if 0
-static LRESULT CALLBACK
-DRAGLIST_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
-
-    return FALSE;
-}
-#endif
-
-
-

reactos/lib/comctl32
flatsb.c 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- flatsb.c	2 Jan 2004 19:49:45 -0000	1.5
+++ flatsb.c	11 Mar 2004 11:13:28 -0000	1.6
@@ -53,8 +53,15 @@
 /***********************************************************************
  *		InitializeFlatSB (COMCTL32.@)
  *
- *	returns nonzero if successful, zero otherwise
+ * Initializes flat scroll bars for the specified window.
  *
+ * RETURNS
+ *     Success: Non-zero
+ *     Failure: Zero
+ *
+ * NOTES
+ *     Subclasses specified window so that flat scroll bars may be drawn
+ *     and used.
  */
 BOOL WINAPI InitializeFlatSB(HWND hwnd)
 {
@@ -65,11 +72,16 @@
 /***********************************************************************
  *		UninitializeFlatSB (COMCTL32.@)
  *
- *	returns:
+ * Uninitializes flat scroll bars for the specified window.
+ *
+ * RETURNS
  *	E_FAIL		if one of the scroll bars is currently in use
- *	S_FALSE		if InitializeFlatSB was never called on this hwnd
+ *	S_FALSE		if InitializeFlatSB() was never called on this hwnd
  *	S_OK		otherwise
  *
+ * NOTES
+ *     Removes any subclassing on the specified window so that regular
+ *     scroll bars are drawn and used.
  */
 HRESULT WINAPI UninitializeFlatSB(HWND hwnd)
 {
@@ -80,10 +92,12 @@
 /***********************************************************************
  *		FlatSB_GetScrollProp (COMCTL32.@)
  *
- *	Returns nonzero if successful, or zero otherwise. If index is WSB_PROP_HSTYLE,
- *	the return is nonzero if InitializeFlatSB has been called for this window, or
- *	zero otherwise.
+ * Retrieves flat-scroll-bar-specific properties for the specified window.
  *
+ * RETURNS
+ *     nonzero if successful, or zero otherwise. If index is WSB_PROP_HSTYLE,
+ *     the return is nonzero if InitializeFlatSB has been called for this window, or
+ *     zero otherwise.
  */
 BOOL WINAPI
 FlatSB_GetScrollProp(HWND hwnd, INT propIndex, LPINT prop)
@@ -94,6 +108,12 @@
 
 /***********************************************************************
  *		FlatSB_SetScrollProp (COMCTL32.@)
+ *
+ * Sets flat-scroll-bar-specific properties for the specified window.
+ *
+ * RETURNS
+ *     Success: Non-zero
+ *     Failure: Zero
  */
 BOOL WINAPI
 FlatSB_SetScrollProp(HWND hwnd, UINT index, INT newValue, BOOL flag)
@@ -120,6 +140,8 @@
 
 /***********************************************************************
  *		FlatSB_EnableScrollBar (COMCTL32.@)
+ *
+ * See EnableScrollBar.
  */
 BOOL WINAPI
 FlatSB_EnableScrollBar(HWND hwnd, int nBar, UINT flags)
@@ -129,6 +151,8 @@
 
 /***********************************************************************
  *		FlatSB_ShowScrollBar (COMCTL32.@)
+ *
+ * See ShowScrollBar.
  */
 BOOL WINAPI
 FlatSB_ShowScrollBar(HWND hwnd, int nBar, BOOL fShow)
@@ -138,6 +162,8 @@
 
 /***********************************************************************
  *		FlatSB_GetScrollRange (COMCTL32.@)
+ *
+ * See GetScrollRange.
  */
 BOOL WINAPI
 FlatSB_GetScrollRange(HWND hwnd, int nBar, LPINT min, LPINT max)
@@ -147,6 +173,8 @@
 
 /***********************************************************************
  *		FlatSB_GetScrollInfo (COMCTL32.@)
+ *
+ * See GetScrollInfo.
  */
 BOOL WINAPI
 FlatSB_GetScrollInfo(HWND hwnd, int nBar, LPSCROLLINFO info)
@@ -156,6 +184,8 @@
 
 /***********************************************************************
  *		FlatSB_GetScrollPos (COMCTL32.@)
+ *
+ * See GetScrollPos.
  */
 INT WINAPI
 FlatSB_GetScrollPos(HWND hwnd, int nBar)
@@ -165,6 +195,8 @@
 
 /***********************************************************************
  *		FlatSB_SetScrollPos (COMCTL32.@)
+ *
+ * See SetScrollPos.
  */
 INT WINAPI
 FlatSB_SetScrollPos(HWND hwnd, int nBar, INT pos, BOOL bRedraw)
@@ -174,6 +206,8 @@
 
 /***********************************************************************
  *		FlatSB_SetScrollInfo (COMCTL32.@)
+ *
+ * See SetScrollInfo.
  */
 INT WINAPI
 FlatSB_SetScrollInfo(HWND hwnd, int nBar, LPSCROLLINFO info, BOOL bRedraw)
@@ -183,6 +217,8 @@
 
 /***********************************************************************
  *		FlatSB_SetScrollRange (COMCTL32.@)
+ *
+ * See SetScrollRange.
  */
 INT WINAPI
 FlatSB_SetScrollRange(HWND hwnd, int nBar, INT min, INT max, BOOL bRedraw)

reactos/lib/comctl32
imagelist.c 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- imagelist.c	22 Jan 2004 18:45:19 -0000	1.7
+++ imagelist.c	11 Mar 2004 11:13:28 -0000	1.8
@@ -33,6 +33,7 @@
  *  TODO:
  *    - Add support for ILD_PRESERVEALPHA, ILD_SCALE, ILD_DPISCALE
  *    - Add support for ILS_GLOW, ILS_SHADOW, ILS_SATURATE, ILS_ALPHA
+ *    - Thread-safe locking
  *
  *  FIXME:
  *    - Hotspot handling still not correct. The Hotspot passed to BeginDrag
@@ -80,6 +81,7 @@
 
 static INTERNALDRAG InternalDrag = { 0, 0, 0, 0, 0, 0, FALSE, 0, FALSE };
 
+static HBITMAP ImageList_CreateImage(HDC hdc, HIMAGELIST himl, UINT width, UINT height);
 
 static inline BOOL is_valid(HIMAGELIST himl)
 {
@@ -120,31 +122,36 @@
     TRACE("Create expanded bitmaps : himl=%p x=%d y=%d count=%d\n", himl, nNewWidth, cy, nNewCount);
     hdcBitmap = CreateCompatibleDC (0);
 
-    hbmNewBitmap =
-        CreateBitmap (nNewWidth, cy, 1, himl->uBitsPixel, NULL);
+    hbmNewBitmap = ImageList_CreateImage(hdcBitmap, himl, nNewWidth, cy);
+
     if (hbmNewBitmap == 0)
         ERR("creating new image bitmap (x=%d y=%d)!\n", nNewWidth, cy);
 
-    hbmNull = SelectObject (hdcBitmap, hbmNewBitmap);
-    BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, cy,
-              himl->hdcImage, 0, 0, SRCCOPY);
-
-    SelectObject (hdcBitmap, hbmNull);
+    if(himl->cCurImage)
+    {
+        hbmNull = SelectObject (hdcBitmap, hbmNewBitmap);
+        BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, cy,
+                himl->hdcImage, 0, 0, SRCCOPY);
+        SelectObject (hdcBitmap, hbmNull);
+    }
     SelectObject (himl->hdcImage, hbmNewBitmap);
     DeleteObject (himl->hbmImage);
     himl->hbmImage = hbmNewBitmap;
 
-    if (himl->hbmMask) {
-        hbmNewBitmap =
-            CreateBitmap (nNewWidth, cy, 1, 1, NULL);
+    if (himl->flags & ILC_MASK)
+    {
+        hbmNewBitmap = CreateBitmap (nNewWidth, cy, 1, 1, NULL);
 
         if (hbmNewBitmap == 0)
             ERR("creating new mask bitmap!\n");
 
-        SelectObject (hdcBitmap, hbmNewBitmap);
-        BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, cy,
-                  himl->hdcMask, 0, 0, SRCCOPY);
-        SelectObject (hdcBitmap, hbmNull);
+	if(himl->cCurImage)
+	{
+	    hbmNull = SelectObject (hdcBitmap, hbmNewBitmap);
+	    BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, cy,
+		    himl->hdcMask, 0, 0, SRCCOPY);
+	    SelectObject (hdcBitmap, hbmNull);
+	}
         SelectObject (himl->hdcMask, hbmNewBitmap);
         DeleteObject (himl->hbmMask);
         himl->hbmMask = hbmNewBitmap;
@@ -524,7 +531,9 @@
 
 
 /*************************************************************************
- * ImageList_Create [COMCTL32.@]  Creates a new image list.
+ * ImageList_Create [COMCTL32.@]
+ *
+ * Creates a new image list.
  *
  * PARAMS
  *     cx       [I] image height
@@ -537,7 +546,6 @@
  *     Success: Handle to the created image list
  *     Failure: NULL
  */
-
 HIMAGELIST WINAPI
 ImageList_Create (INT cx, INT cy, UINT flags,
 		  INT cInitial, INT cGrow)
@@ -545,6 +553,7 @@
     HIMAGELIST himl;
     INT      nCount;
     HBITMAP  hbmTemp;
+    UINT     ilc = (flags & 0xFE);
     static WORD aBitBlend25[] =
         {0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
 
@@ -583,22 +592,22 @@
             goto cleanup;
     }
 
-    himl->uBitsPixel = (UINT)GetDeviceCaps (himl->hdcImage, BITSPIXEL);
+    /* Default to ILC_COLOR4 if non of the ILC_COLOR* flags are specified */
+    if (ilc == ILC_COLOR)
+        ilc = ILC_COLOR4;
 
-    TRACE("Image: %d Bits per Pixel\n", himl->uBitsPixel);
+    if (ilc >= ILC_COLOR4 && ilc <= ILC_COLOR32)
+        himl->uBitsPixel = ilc;
+    else
+        himl->uBitsPixel = (UINT)GetDeviceCaps (himl->hdcImage, BITSPIXEL);
 
     if (himl->cMaxImage > 0) {
-        himl->hbmImage =
-	  CreateBitmap (himl->cx * himl->cMaxImage, himl->cy,
-                        1, himl->uBitsPixel, NULL);
-	if (himl->hbmImage == 0) {
-	    ERR("Error creating image bitmap!\n");
-            goto cleanup;
-	}
-        SelectObject(himl->hdcImage, himl->hbmImage);
-    }
+        himl->hbmImage = ImageList_CreateImage(himl->hdcImage, himl, cx * himl->cMaxImage, cy);
+	SelectObject(himl->hdcImage, himl->hbmImage);
+    } else
+        himl->hbmImage = 0;
 
-    if (himl->flags & ILC_MASK) {
+    if ((himl->cMaxImage > 0) && (himl->flags & ILC_MASK)) {
         himl->hbmMask =
           CreateBitmap (himl->cx * himl->cMaxImage, himl->cy,
 			1, 1, NULL);
@@ -953,7 +962,9 @@
 
 
 /*************************************************************************
- * ImageList_Draw [COMCTL32.@] Draws an image.
+ * ImageList_Draw [COMCTL32.@]
+ *
+ * Draws an image.
  *
  * PARAMS
  *     himl   [I] handle to image list
@@ -1034,7 +1045,7 @@
 /*************************************************************************
  * ImageList_DrawIndirect [COMCTL32.@]
  *
- * Draws an image using ...
+ * Draws an image using various parameters specified in pimldp.
  *
  * PARAMS
  *     pimldp [I] pointer to IMAGELISTDRAWPARAMS structure.
@@ -1071,8 +1082,8 @@
     bIsTransparent = (fStyle & ILD_TRANSPARENT) || clrBk == CLR_NONE;
     bBlend = fStyle & (ILD_BLEND25 | ILD_BLEND50);
 
-    TRACE("hbmMask(%p) iImage(%d) x(%d) y(%d) cx(%d) cy(%d)\n",
-          himl->hbmMask, pimldp->i, pimldp->x, pimldp->y, cx, cy);
+    TRACE("himl(0x%lx) hbmMask(%p) iImage(%d) x(%d) y(%d) cx(%d) cy(%d)\n",
+          (DWORD)himl, himl->hbmMask, pimldp->i, pimldp->x, pimldp->y, cx, cy);
 
     /* we will use these DCs to access the images and masks in the ImageList */
     hImageListDC = himl->hdcImage;
@@ -1200,7 +1211,9 @@
 
 
 /*************************************************************************
- * ImageList_Duplicate [COMCTL32.@] Duplicates an image list.
+ * ImageList_Duplicate [COMCTL32.@]
+ *
+ * Duplicates an image list.
  *
  * PARAMS
  *     himlSrc [I] source image list handle
@@ -1240,7 +1253,7 @@
 
 
 /*************************************************************************
- * ImageList_EndDrag [COMCTL32.@] Finishes a drag operation.
+ * ImageList_EndDrag [COMCTL32.@]
  *
  * Finishes a drag operation.
  *
@@ -1326,6 +1339,14 @@
 /*************************************************************************
  * ImageList_GetFlags [COMCTL32.@]
  *
+ * Gets the flags of the specified image list.
+ *
+ * PARAMS
+ *     himl [I] Handle to image list
+ *
+ * RETURNS
+ *     Image list flags.
+ *
  * BUGS
  *    Stub.
  */
@@ -2012,7 +2033,9 @@
 
 
 /*************************************************************************
- * ImageList_Remove [COMCTL32.@] Removes an image from an image list
+ * ImageList_Remove [COMCTL32.@]
+ *
+ * Removes an image from an image list
  *
  * PARAMS
  *     himl [I] image list handle
@@ -2055,8 +2078,7 @@
         for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
              himl->nOvlIdx[nCount] = -1;
 
-        hbmNewImage = CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
-                            1, himl->uBitsPixel, NULL);
+        hbmNewImage = ImageList_CreateImage(himl->hdcImage, himl, himl->cMaxImage * himl->cx, himl->cy);
         SelectObject (himl->hdcImage, hbmNewImage);
         DeleteObject (himl->hbmImage);
         himl->hbmImage = hbmNewImage;
@@ -2074,15 +2096,15 @@
         TRACE("Remove single image! %d\n", i);
 
         /* create new bitmap(s) */
-        cxNew = (himl->cCurImage + himl->cGrow - 1) * himl->cx;
+        nCount = (himl->cCurImage + himl->cGrow - 1);
+	cxNew = nCount * himl->cx;
 
         TRACE(" - Number of images: %d / %d (Old/New)\n",
                  himl->cCurImage, himl->cCurImage - 1);
         TRACE(" - Max. number of images: %d / %d (Old/New)\n",
                  himl->cMaxImage, himl->cCurImage + himl->cGrow - 1);
 
-        hbmNewImage =
-            CreateBitmap (cxNew, himl->cy, 1, himl->uBitsPixel, NULL);
+        hbmNewImage = ImageList_CreateImage(himl->hdcImage, himl, cxNew, himl->cy);
 
         if (himl->hbmMask)
             hbmNewMask = CreateBitmap (cxNew, himl->cy, 1, 1, NULL);
@@ -2438,6 +2460,15 @@
 /*************************************************************************
  * ImageList_SetFlags [COMCTL32.@]
  *
+ * Sets the image list flags.
+ *
+ * PARAMS
+ *     himl  [I] Handle to image list
+ *     flags [I] Flags to set
+ *
+ * RETURNS
+ *     Old flags?
+ *
  * BUGS
  *    Stub.
  */
@@ -2484,8 +2515,7 @@
     for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
         himl->nOvlIdx[nCount] = -1;
 
-    hbmNew = CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
-                        1, himl->uBitsPixel, NULL);
+    hbmNew = ImageList_CreateImage(himl->hdcImage, himl, himl->cMaxImage * himl->cx, himl->cy);
     SelectObject (himl->hdcImage, hbmNew);
     DeleteObject (himl->hbmImage);
     himl->hbmImage = hbmNew;
@@ -2540,8 +2570,8 @@
 
     hdcBitmap = CreateCompatibleDC (0);
 
-    hbmNewBitmap = CreateBitmap (nNewCount * himl->cx, himl->cy,
-                                   1, himl->uBitsPixel, NULL);
+    hbmNewBitmap = ImageList_CreateImage(hdcBitmap, himl, nNewCount * himl->cx, himl->cy);
+
     if (hbmNewBitmap != 0)
     {
         SelectObject (hdcBitmap, hbmNewBitmap);
@@ -2782,3 +2812,40 @@
 
     return TRUE;
 }
+
+
+static HBITMAP ImageList_CreateImage(HDC hdc, HIMAGELIST himl, UINT width, UINT height)
+{
+    HBITMAP hbmNewBitmap;
+    UINT ilc = (himl->flags & 0xFE);
+
+    if ((ilc >= ILC_COLOR4 && ilc <= ILC_COLOR32) || ilc == ILC_COLOR)
+    {
+        VOID* bits;
+        BITMAPINFO bmi;
+
+        TRACE("Creating DIBSection: %d Bits per Pixel\n", himl->uBitsPixel);
+
+	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+	bmi.bmiHeader.biWidth = width;
+	bmi.bmiHeader.biHeight = height;
+	bmi.bmiHeader.biPlanes = 1;
+	bmi.bmiHeader.biBitCount = himl->uBitsPixel;
+	bmi.bmiHeader.biCompression = BI_RGB;
+	bmi.bmiHeader.biSizeImage = 0;
+	bmi.bmiHeader.biXPelsPerMeter = 0;
+	bmi.bmiHeader.biYPelsPerMeter = 0;
+	bmi.bmiHeader.biClrUsed = 0;
+	bmi.bmiHeader.biClrImportant = 0;
+
+	hbmNewBitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &bits, 0, 0);
+    }
+    else /*if (ilc == ILC_COLORDDB)*/
+    {
+        TRACE("Creating Bitmap: %d Bits per Pixel\n", himl->uBitsPixel);
+
+        hbmNewBitmap = CreateBitmap (width, height, 1, himl->uBitsPixel, NULL);
+    }
+
+    return hbmNewBitmap;
+}

reactos/lib/comctl32
listview.c 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- listview.c	17 Feb 2004 22:33:55 -0000	1.6
+++ listview.c	11 Mar 2004 11:13:28 -0000	1.7
@@ -93,7 +93,6 @@
  *   -- LVS_EX_UNDERLINEHOT
  *   
  * Notifications:
- *   -- LVN_BEGINRDRAG
  *   -- LVN_BEGINSCROLL, LVN_ENDSCROLL
  *   -- LVN_GETINFOTIP
  *   -- LVN_HOTTRACK
@@ -4000,7 +3999,26 @@
     dwViewRect = MAKELONG(wWidth, wHeight);
   }
   else if (uView == LVS_REPORT)
-    FIXME("uView == LVS_REPORT: not implemented\n");
+  {
+    RECT rcBox;
+
+    if (infoPtr->nItemCount > 0)
+    {
+      LISTVIEW_GetItemBox(infoPtr, 0, &rcBox);
+      wWidth = rcBox.right - rcBox.left;
+      wHeight = (rcBox.bottom - rcBox.top) * nItemCount;
+    }
+    else
+    {
+      /* use current height and width */
+      if (wHeight == 0xffff)
+          wHeight = infoPtr->rcList.bottom - infoPtr->rcList.top;
+      if (wWidth == 0xffff)
+          wWidth = infoPtr->rcList.right - infoPtr->rcList.left;
+    }
+
+    dwViewRect = MAKELONG(wWidth, wHeight);
+  }
   else if (uView == LVS_SMALLICON)
     FIXME("uView == LVS_SMALLICON: not implemented\n");
   else if (uView == LVS_ICON)
@@ -4971,7 +4989,7 @@
  *   the buffer pointer you provided on input. Most code already does
  *   that, so it's not a problem.
  *   For the two cases when the text must be copied (that is,
- *   for LVM_GETITEM, and LVMGETITEMTEXT), use LISTVIEW_GetItemExtT.
+ *   for LVM_GETITEM, and LVM_GETITEMTEXT), use LISTVIEW_GetItemExtT.
  *
  * RETURN:
  *   SUCCESS : TRUE
@@ -5980,7 +5998,9 @@
 	}
     }
 
-    if (select && !(uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)))
+    if (select && !(uView == LVS_REPORT &&
+                    ((infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT) ||
+                     (infoPtr->dwStyle & LVS_OWNERDRAWFIXED))))
     {
         if (uView == LVS_REPORT)
         {

reactos/lib/comctl32
propsheet.c 1.4 -> 1.5
diff -u -r1.4 -r1.5
--- propsheet.c	28 Jan 2004 21:40:09 -0000	1.4
+++ propsheet.c	11 Mar 2004 11:13:28 -0000	1.5
@@ -1381,7 +1381,6 @@
   DLGTEMPLATE* pTemplate;
   HWND hwndPage;
   RECT rc;
-  PropPageInfo* ppInfo = psInfo->proppage;
   PADDING_INFO padding;
   UINT pageWidth,pageHeight;
   DWORD resSize;
@@ -1494,7 +1493,7 @@
   if(temp)
       Free(temp);
 
-  ppInfo[index].hwndPage = hwndPage;
+  psInfo->proppage[index].hwndPage = hwndPage;
 
   if (psInfo->ppshheader.dwFlags & INTRNL_ANY_WIZARD) {
       /* FIXME: This code may no longer be correct.
@@ -2278,7 +2277,6 @@
   if (!psInfo) {
     return FALSE;
   }
-  oldPages = psInfo->proppage;
   /*
    * hpage takes precedence over index.
    */
@@ -2345,6 +2343,7 @@
   /* Remove the tab */
   SendMessageW(hwndTabControl, TCM_DELETEITEM, index, 0);
 
+  oldPages = psInfo->proppage;
   psInfo->nPages--;
   psInfo->proppage = Alloc(sizeof(PropPageInfo) * psInfo->nPages);
 
@@ -2478,6 +2477,15 @@
 /******************************************************************************
  *            PropertySheet    (COMCTL32.@)
  *            PropertySheetA   (COMCTL32.@)
+ *
+ * Creates a property sheet in the specified property sheet header.
+ *
+ * RETURNS
+ *     Modal property sheets: Positive if successful or -1 otherwise.
+ *     Modeless property sheets: Property sheet handle.
+ *     Or:
+ *| ID_PSREBOOTSYSTEM - The user must reboot the computer for the changes to take effect.
+ *| ID_PSRESTARTWINDOWS - The user must restart Windows for the changes to take effect.
  */
 INT WINAPI PropertySheetA(LPCPROPSHEETHEADERA lppsh)
 {
@@ -2523,6 +2531,8 @@
 
 /******************************************************************************
  *            PropertySheetW   (COMCTL32.@)
+ *
+ * See PropertySheetA.
  */
 INT WINAPI PropertySheetW(LPCPROPSHEETHEADERW lppsh)
 {
@@ -2569,6 +2579,16 @@
 /******************************************************************************
  *            CreatePropertySheetPage    (COMCTL32.@)
  *            CreatePropertySheetPageA   (COMCTL32.@)
+ *
+ * Creates a new property sheet page.
+ *
+ * RETURNS
+ *     Success: Handle to new property sheet page.
+ *     Failure: NULL.
+ *
+ * NOTES
+ *     An application must use the PSM_ADDPAGE message to add the new page to
+ *     an existing property sheet.
  */
 HPROPSHEETPAGE WINAPI CreatePropertySheetPageA(
                           LPCPROPSHEETPAGEA lpPropSheetPage)
@@ -2602,6 +2622,8 @@
 
 /******************************************************************************
  *            CreatePropertySheetPageW   (COMCTL32.@)
+ *
+ * See CreatePropertySheetA.
  */
 HPROPSHEETPAGE WINAPI CreatePropertySheetPageW(LPCPROPSHEETPAGEW lpPropSheetPage)
 {
@@ -2639,6 +2661,14 @@
 
 /******************************************************************************
  *            DestroyPropertySheetPage   (COMCTL32.@)
+ *
+ * Destroys a property sheet page previously created with
+ * CreatePropertySheetA() or CreatePropertySheetW() and frees the associated
+ * memory.
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
  */
 BOOL WINAPI DestroyPropertySheetPage(HPROPSHEETPAGE hPropPage)
 {

reactos/lib/comctl32
rebar.c 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- rebar.c	26 Feb 2004 13:45:44 -0000	1.7
+++ rebar.c	11 Mar 2004 11:13:28 -0000	1.8
@@ -1497,10 +1497,7 @@
 
 	/* separator from previous band */
 	cxsep = (cntonrow == 0) ? 0 : SEP_WIDTH;
-
-	/* Header: includes gripper, text, image */
-	cx = lpBand->cxHeader;
-	if (lpBand->fStyle & RBBS_FIXEDSIZE) cx = lpBand->lcx;
+	cx = lpBand->lcx;
 
 	if (infoPtr->dwStyle & CCS_VERT)
 	    dobreak = (y + cx + cxsep > adjcy);
@@ -3747,6 +3744,7 @@
 	    ShowWindow (lpBand->hwndChild, SW_HIDE);
     }
 
+    infoPtr->fStatus |= BAND_NEEDS_LAYOUT;
     REBAR_Layout (infoPtr, NULL, TRUE, FALSE);
     InvalidateRect(infoPtr->hwndSelf, 0, 1);
 

reactos/lib/comctl32
rsrc.rc 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- rsrc.rc	2 Jan 2004 19:49:45 -0000	1.1
+++ rsrc.rc	11 Mar 2004 11:13:28 -0000	1.2
@@ -971,6 +971,33 @@
 } */
 
 
+/* BINRES idc_copy.cur */
+IDC_COPY CURSOR LOADONCALL DISCARDABLE idc_copy.cur
+/* {
+ '00 00 02 00 01 00 20 20 00 00 00 00 00 00 30 01'
+ '00 00 16 00 00 00 28 00 00 00 20 00 00 00 40 00'
+ '00 00 01 00 01 00 00 00 00 00 00 01 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+ '00 00 00 00 00 00 00 00 00 00 00 C0 00 00 00 C0'
+ '00 00 01 80 00 00 01 80 00 00 03 00 00 00 43 00'
+ '00 00 66 00 00 00 76 00 00 00 7E 00 00 00 7F C0'
+ '00 00 7F 80 00 00 7F 00 00 00 7E 00 00 00 7C 00'
+ '00 00 78 00 00 00 70 00 00 00 60 00 00 00 40 00'
+ '00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
+ 'FF FF FF FF FF FF FF FD FF FF FF FD FF FF FF F0'
+ '7F FF FF FD FF FF FF 3D FF FF FE 1F FF FF FE 1F'
+ 'FF FF FC 3F FF FF 7C 3F FF FF 38 7F FF FF 18 7F'
+ 'FF FF 00 FF FF FF 00 FF FF FF 00 0F FF FF 00 1F'
+ 'FF FF 00 3F FF FF 00 7F FF FF 00 FF FF FF 01 FF'
+ 'FF FF 03 FF FF FF 07 FF FF FF 0F FF FF FF 1F FF'
+ 'FF FF 3F FF FF FF'
+} */
+
+
 /* BINRES idc_divider.cur */
 IDC_DIVIDER CURSOR LOADONCALL DISCARDABLE idc_divider.cur
 /* {

reactos/lib/comctl32
smoothscroll.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- smoothscroll.c	6 Oct 2003 16:13:28 -0000	1.2
+++ smoothscroll.c	11 Mar 2004 11:13:28 -0000	1.3
@@ -63,10 +63,14 @@
  *
  * Lots of magic for smooth scrolling windows.
  *
- * Currently only scrolls ONCE. The comctl32 implementation uses GetTickCount
- * and what else to do smooth scrolling.
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ *
+ * BUGS
+ *     Currently only scrolls ONCE. The comctl32 implementation uses GetTickCount
+ *     and what else to do smooth scrolling.
  */
-
 BOOL WINAPI SmoothScrollWindow( SMOOTHSCROLLSTRUCT *smooth ) {
    LPRECT	lpupdaterect = smooth->lpupdaterect;
    HRGN		hrgnupdate = smooth->hrgnupdate;

reactos/lib/comctl32
tab.c 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- tab.c	17 Feb 2004 22:38:03 -0000	1.6
+++ tab.c	11 Mar 2004 11:13:28 -0000	1.7
@@ -33,8 +33,6 @@
  *   TCM_GETEXTENDEDSTYLE
  *   TCM_SETEXTENDEDSTYLE
  *
- * FIXME:
- *  UpDown control not displayed until after a tab is clicked on
  */
 
 #include <stdarg.h>
@@ -107,7 +105,7 @@
 #define CONTROL_BORDER_SIZEX    2
 #define CONTROL_BORDER_SIZEY    2
 #define BUTTON_SPACINGX         3
-#define BUTTON_SPACINGY         4
+#define BUTTON_SPACINGY         3
 #define FLAT_BTN_SPACINGX       8
 #define DEFAULT_TAB_WIDTH       96
 
@@ -327,40 +325,29 @@
   /* calculate the times bottom and top based on the row */
   GetClientRect(hwnd, &clientRect);
 
-  if ((lStyle & TCS_BOTTOM) && !(lStyle & TCS_VERTICAL))
+  if ((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
   {
-    itemRect->bottom = clientRect.bottom -
-                   itemRect->top * (infoPtr->tabHeight - 2) -
-                   ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : SELECTED_TAB_OFFSET);
-
-    itemRect->top = clientRect.bottom -
-                   infoPtr->tabHeight -
-                   itemRect->top * (infoPtr->tabHeight - 2) -
-                   ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : SELECTED_TAB_OFFSET);
-  }
-  else if((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
-  {
-    itemRect->right = clientRect.right - SELECTED_TAB_OFFSET - itemRect->left * (infoPtr->tabHeight - 2) -
-                      ((lStyle & TCS_BUTTONS) ? itemRect->left * BUTTON_SPACINGY : 0);
-    itemRect->left = clientRect.right - infoPtr->tabHeight - itemRect->left * (infoPtr->tabHeight - 2) -
-                      ((lStyle & TCS_BUTTONS) ? itemRect->left * BUTTON_SPACINGY : 0);
-  }
-  else if((lStyle & TCS_VERTICAL) && !(lStyle & TCS_BOTTOM))
-  {
-    itemRect->right = clientRect.left + infoPtr->tabHeight + itemRect->left * (infoPtr->tabHeight - 2) +
-                      ((lStyle & TCS_BUTTONS) ? itemRect->left * BUTTON_SPACINGY : 0);
-    itemRect->left = clientRect.left + SELECTED_TAB_OFFSET + itemRect->left * (infoPtr->tabHeight - 2) +
-                      ((lStyle & TCS_BUTTONS) ? itemRect->left * BUTTON_SPACINGY : 0);
-  }
-  else if(!(lStyle & TCS_VERTICAL) && !(lStyle & TCS_BOTTOM)) /* not TCS_BOTTOM and not TCS_VERTICAL */
-  {
-    itemRect->bottom = clientRect.top +
-                      infoPtr->tabHeight +
-                      itemRect->top * (infoPtr->tabHeight - 2) +
-                      ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : SELECTED_TAB_OFFSET);
-    itemRect->top = clientRect.top +
-                   itemRect->top * (infoPtr->tabHeight - 2) +
-                   ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : SELECTED_TAB_OFFSET);
+    itemRect->right  = clientRect.right - SELECTED_TAB_OFFSET - itemRect->left * infoPtr->tabHeight -
+                       ((lStyle & TCS_BUTTONS) ? itemRect->left * BUTTON_SPACINGX : 0);
+    itemRect->left   = itemRect->right - infoPtr->tabHeight;
+  }
+  else if (lStyle & TCS_VERTICAL)
+  {
+    itemRect->left   = clientRect.left + SELECTED_TAB_OFFSET + itemRect->left * infoPtr->tabHeight +
+                       ((lStyle & TCS_BUTTONS) ? itemRect->left * BUTTON_SPACINGX : 0);
+    itemRect->right  = itemRect->left + infoPtr->tabHeight;
+  }
+  else if (lStyle & TCS_BOTTOM)
+  {
+    itemRect->bottom = clientRect.bottom - itemRect->top * infoPtr->tabHeight -
+                       ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : SELECTED_TAB_OFFSET);
+    itemRect->top    = itemRect->bottom - infoPtr->tabHeight;
+  }
+  else /* not TCS_BOTTOM and not TCS_VERTICAL */
+  {
+    itemRect->top    = clientRect.top + itemRect->top * infoPtr->tabHeight +
+                       ((lStyle & TCS_BUTTONS) ? itemRect->top * BUTTON_SPACINGY : SELECTED_TAB_OFFSET);
+    itemRect->bottom = itemRect->top + infoPtr->tabHeight;
  }
 
   /*
@@ -371,7 +358,7 @@
   {
     OffsetRect(itemRect,
 	     0,
-	     -(clientRect.bottom - infoPtr->items[infoPtr->leftmostVisible].rect.bottom));
+	     -infoPtr->items[infoPtr->leftmostVisible].rect.top);
 
     /*
      * Move the rectangle so the first item is slightly offset from
@@ -379,7 +366,7 @@
      */
     OffsetRect(itemRect,
 	     0,
-	     -SELECTED_TAB_OFFSET);
+	     SELECTED_TAB_OFFSET);
 
   } else
   {
@@ -411,23 +398,23 @@
       InflateRect(selectedRect, SELECTED_TAB_OFFSET, 0);
 
     /* If it also a bit higher. */
-    if ((lStyle & TCS_BOTTOM) && !(lStyle & TCS_VERTICAL))
+    if ((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
     {
-      selectedRect->bottom += SELECTED_TAB_OFFSET;
+      selectedRect->left   -= 2; /* the border is thicker on the right */
+      selectedRect->right  += SELECTED_TAB_OFFSET;
     }
-    else if((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
+    else if (lStyle & TCS_VERTICAL)
     {
-      selectedRect->left -= 2; /* the border is thicker on the right */
-      selectedRect->right += SELECTED_TAB_OFFSET;
+      selectedRect->left   -= SELECTED_TAB_OFFSET;
+      selectedRect->right  += 1;
     }
-    else if(lStyle & TCS_VERTICAL)
+    else if (lStyle & TCS_BOTTOM)
     {
-      selectedRect->left -= SELECTED_TAB_OFFSET;
-      selectedRect->right += 1;
+      selectedRect->bottom += SELECTED_TAB_OFFSET;
     }
-    else
+    else /* not TCS_BOTTOM and not TCS_VERTICAL */
     {
-      selectedRect->top -= SELECTED_TAB_OFFSET;
+      selectedRect->top    -= SELECTED_TAB_OFFSET;
       selectedRect->bottom -= 1;
     }
   }
@@ -853,72 +840,53 @@
   WPARAM fLarger,
   LPRECT prc)
 {
-  TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);
-  DWORD lStyle = GetWindowLongA(hwnd, GWL_STYLE);
-
-  if(lStyle & TCS_VERTICAL)
-  {
-    if (fLarger) /* Go from display rectangle */
-    {
-      /* Add the height of the tabs. */
-      if (lStyle & TCS_BOTTOM)
-        prc->right += (infoPtr->tabHeight - 2) * infoPtr->uNumRows + 2;
-      else
-        prc->left -= (infoPtr->tabHeight - 2) * infoPtr->uNumRows + 2;
+    TAB_INFO *infoPtr = TAB_GetInfoPtr(hwnd);
+    DWORD lStyle = GetWindowLongA(hwnd, GWL_STYLE);
+    LONG *iRightBottom, *iLeftTop;
 
-      /* FIXME: not sure if these InflateRect's need to have different values for TCS_VERTICAL */
-      /* Inflate the rectangle for the padding */
-      InflateRect(prc, DISPLAY_AREA_PADDINGX, DISPLAY_AREA_PADDINGY);
+    TRACE ("hwnd=%p fLarger=%d (%ld,%ld)-(%ld,%ld)\n", hwnd, fLarger, prc->left, prc->top, prc->right, prc->bottom);
 
-      /* Inflate for the border */
-      InflateRect(prc, CONTROL_BORDER_SIZEX, CONTROL_BORDER_SIZEX);
+    if(lStyle & TCS_VERTICAL)
+    {
+	iRightBottom = &(prc->right);
+	iLeftTop     = &(prc->left);
     }
-    else /* Go from window rectangle. */
+    else
     {
-      /* FIXME: not sure if these InflateRect's need to have different values for TCS_VERTICAL */
-      /* Deflate the rectangle for the border */
-      InflateRect(prc, -CONTROL_BORDER_SIZEX, -CONTROL_BORDER_SIZEX);
-
-      /* Deflate the rectangle for the padding */
-      InflateRect(prc, -DISPLAY_AREA_PADDINGX, -DISPLAY_AREA_PADDINGY);
-
-      /* Remove the height of the tabs. */
-      if (lStyle & TCS_BOTTOM)
-        prc->right -= (infoPtr->tabHeight - 2) * infoPtr->uNumRows + 2;
-      else
-        prc->left += (infoPtr->tabHeight - 2) * infoPtr->uNumRows + 2;
+	iRightBottom = &(prc->bottom);
+	iLeftTop     = &(prc->top);
     }
-  }
-  else {
+
     if (fLarger) /* Go from display rectangle */
     {
-      /* Add the height of the tabs. */
-      if (lStyle & TCS_BOTTOM)
-        prc->bottom += (infoPtr->tabHeight - 2) * infoPtr->uNumRows + 2;
-      else
-        prc->top -= (infoPtr->tabHeight - 2) * infoPtr->uNumRows + 2;
+        /* Add the height of the tabs. */
+	if (lStyle & TCS_BOTTOM)
+	    *iRightBottom += infoPtr->tabHeight * infoPtr->uNumRows;
+	else
+	    *iLeftTop -= infoPtr->tabHeight * infoPtr->uNumRows +
+			 ((lStyle & TCS_BUTTONS)? 3 * (infoPtr->uNumRows - 1) : 0);
 
-      /* Inflate the rectangle for the padding */
-      InflateRect(prc, DISPLAY_AREA_PADDINGX, DISPLAY_AREA_PADDINGY);
+	/* Inflate the rectangle for the padding */
+	InflateRect(prc, DISPLAY_AREA_PADDINGX, DISPLAY_AREA_PADDINGY); 
 
-      /* Inflate for the border */
-      InflateRect(prc, CONTROL_BORDER_SIZEX, CONTROL_BORDER_SIZEX);
+	/* Inflate for the border */
+	InflateRect(prc, CONTROL_BORDER_SIZEX, CONTROL_BORDER_SIZEY);
     }
     else /* Go from window rectangle. */
     {
-      /* Deflate the rectangle for the border */
-      InflateRect(prc, -CONTROL_BORDER_SIZEX, -CONTROL_BORDER_SIZEX);
+	/* Deflate the rectangle for the border */
+	InflateRect(prc, -CONTROL_BORDER_SIZEX, -CONTROL_BORDER_SIZEY);
 
-      /* Deflate the rectangle for the padding */
-      InflateRect(prc, -DISPLAY_AREA_PADDINGX, -DISPLAY_AREA_PADDINGY);
+	/* Deflate the rectangle for the padding */
+	InflateRect(prc, -DISPLAY_AREA_PADDINGX, -DISPLAY_AREA_PADDINGY);
 
-      /* Remove the height of the tabs. */
-      if (lStyle & TCS_BOTTOM)
-        prc->bottom -= (infoPtr->tabHeight - 2) * infoPtr->uNumRows + 2;
-      else
-        prc->top += (infoPtr->tabHeight - 2) * infoPtr->uNumRows + 2;
+	/* Remove the height of the tabs. */
+	if (lStyle & TCS_BOTTOM)
+	    *iRightBottom -= infoPtr->tabHeight * infoPtr->uNumRows;
+	else
+	    *iLeftTop += (infoPtr->tabHeight) * infoPtr->uNumRows +
+			 ((lStyle & TCS_BUTTONS)? 3 * (infoPtr->uNumRows - 1) : 0);
     }
-  }
 
   return 0;
 }
@@ -1147,7 +1115,7 @@
      * Make sure there is enough space for the letters + icon + growing the
      * selected item + extra space for the selected item.
      */
-    infoPtr->tabHeight = item_height + SELECTED_TAB_OFFSET +
+    infoPtr->tabHeight = item_height + 
 	                 ((lStyle & TCS_BUTTONS) ? 2 : 1) *
                           infoPtr->uVItemPadding;
 
@@ -1201,12 +1169,13 @@
      * Check if this is a multiline tab control and if so
      * check to see if we should wrap the tabs
      *
-     * Wrap all these tabs. We will arange them evenly later.
+     * Wrap all these tabs. We will arrange them evenly later.
      *
      */
 
     if (((lStyle & TCS_MULTILINE) || (lStyle & TCS_VERTICAL)) &&
-        (infoPtr->items[curItem].rect.right > clientRect.right))
+        (infoPtr->items[curItem].rect.right > 
+	(clientRect.right - CONTROL_BORDER_SIZEX - DISPLAY_AREA_PADDINGX)))
     {
         infoPtr->items[curItem].rect.right -=
                                       infoPtr->items[curItem].rect.left;
@@ -1268,7 +1237,7 @@
   /* Set the number of rows */
   infoPtr->uNumRows = curItemRowCount;
 
-  /* Arange all tabs evenly if style says so */
+  /* Arrange all tabs evenly if style says so */
    if (!(lStyle & TCS_RAGGEDRIGHT) &&  ((lStyle & TCS_MULTILINE) || (lStyle & TCS_VERTICAL)) && (infoPtr->uNumItem > 0))
    {
       INT tabPerRow,remTab;
@@ -1303,17 +1272,6 @@
           /* move to the next row, reset our current item left position and */
           /* the count of items on this row */
 
-	  /* ************  FIXME FIXME FIXME  *************** */
-	  /*                                                  */
-	  /* FIXME:                                           */
-	  /* if vertical,                                     */
-	  /*   if item n and n+1 are in the same row,         */
-	  /*      then the display has n+1 lower (toward the  */
-	  /*      bottom) than n. We do it just the           */
-	  /*      opposite!!!                                 */
-	  /*                                                  */
-	  /* ************  FIXME FIXME FIXME  *************** */
-
 	  if (lStyle & TCS_VERTICAL) {
 	      /* Vert: Add the remaining tabs in the *last* remainder rows */
 	      if (iCount >= ((iRow>=(INT)infoPtr->uNumRows - remTab)?tabPerRow + 1:tabPerRow)) {
@@ -1429,8 +1387,8 @@
 
       rcOriginal = *rcItem;
 
-      /* this is rotating the items by 90 degrees around the center of the control */
-      rcItem->top = (clientRect.right - (rcOriginal.left - clientRect.left)) - (rcOriginal.right - rcOriginal.left);
+      /* this is rotating the items by 90 degrees clockwise around the center of the control */
+      rcItem->top = (rcOriginal.left - clientRect.left);
       rcItem->bottom = rcItem->top + (rcOriginal.right - rcOriginal.left);
       rcItem->left = rcOriginal.top;
       rcItem->right = rcOriginal.bottom;
@@ -1533,7 +1491,7 @@
   INT    oldBkMode;
   HFONT  hOldFont;
   
-  if (drawRect == NULL)
+/*  if (drawRect == NULL) */
   {
     BOOL isVisible;
     RECT itemRect;
@@ -1557,40 +1515,75 @@
      * would have liked to avoid code duplication, but couldn't figure
      * out how without making spaghetti of TAB_DrawItem.
      */
+    if (iItem == infoPtr->iSelected)
+      *drawRect = selectedRect;
+    else
+      *drawRect = itemRect;
+        
     if (lStyle & TCS_BUTTONS)
     {
-      *drawRect = itemRect;
       if (iItem == infoPtr->iSelected)
       {
-	OffsetRect(drawRect, 1, 1);
+	drawRect->left   += 4;
+	drawRect->top    += 4;
+	drawRect->right  -= 4;
+	drawRect->bottom -= 1;
+      }
+      else
+      {
+	drawRect->left   += 2;
+	drawRect->top    += 2;
+	drawRect->right  -= 2;
+	drawRect->bottom -= 2;
       }
     }
     else
     {
-      if (iItem == infoPtr->iSelected)
+      if ((lStyle & TCS_VERTICAL) && (lStyle & TCS_BOTTOM))
       {
-        *drawRect = selectedRect;
-	if (lStyle & TCS_BOTTOM)
+        if (iItem != infoPtr->iSelected)
 	{
-	  if (lStyle & TCS_VERTICAL)
-	  {
-	    drawRect->left++;
-	  }
-	  else
-	  {
-	    drawRect->top += 3;
-	    drawRect->left += 1;
-	  }
+	  drawRect->left   += 2;
+	  drawRect->top    += 2;
+	  drawRect->bottom -= 2;
+	}
+      }
+      else if (lStyle & TCS_VERTICAL)
+      {
+        if (iItem == infoPtr->iSelected)
+	{
+	  drawRect->right  += 1;
+	}
+	else
+	{
+	  drawRect->top    += 2;
+	  drawRect->right  -= 2;
+	  drawRect->bottom -= 2;
+	}
+      }
+      else if (lStyle & TCS_BOTTOM)
+      {
+        if (iItem == infoPtr->iSelected)
+	{
+	  drawRect->top    -= 2;
+	}
+	else
+	{
+	  InflateRect(drawRect, -2, -2);
+          drawRect->bottom += 2;
 	}
       }
       else
-        *drawRect = itemRect;
-
-
-      if (lStyle & TCS_BOTTOM && !(lStyle & TCS_VERTICAL))
       {
-        drawRect->top--;
-        drawRect->bottom--;
+        if (iItem == infoPtr->iSelected)
+	{
+	  drawRect->bottom += 3;
+	}
+	else
+	{
+	  drawRect->bottom -= (infoPtr->items[iItem].rect.top != infoPtr->uNumRows-1)? 2:2;
+	  InflateRect(drawRect, -2, 0);
+	}
       }
     }
   }
@@ -1661,7 +1654,6 @@
     dis.hwndItem = hwnd;		/* */
     dis.hDC      = hdc;
     CopyRect(&dis.rcItem,drawRect);
-    InflateRect(&dis.rcItem, -2, -2);
     dis.itemData = infoPtr->items[iItem].lParam;
 
     /*
@@ -1717,6 +1709,9 @@
       if (center_offset_h < 2)
         center_offset_h = 2;
 	
+      if (center_offset_v < 0)
+        center_offset_v = 0;
+	
       TRACE("for <%s>, c_o_h=%d, c_o_v=%d, draw=(%ld,%ld)-(%ld,%ld), textlen=%ld\n",
 	  debugstr_w(infoPtr->items[iItem].pszText), center_offset_h, center_offset_v,
 	  drawRect->left, drawRect->top, drawRect->right, drawRect->bottom,
@@ -1773,14 +1768,22 @@
       else
         drawRect->bottom-=center_offset_h;
 
-      drawRect->left += ((drawRect->right - drawRect->left) - ((rcText.bottom - rcText.top) + infoPtr->uVItemPadding)) / 2;
+      center_offset_v = ((drawRect->right - drawRect->left) - ((rcText.bottom - rcText.top) + infoPtr->uVItemPadding)) / 2;
     }
     else
     {
       drawRect->left += center_offset_h;
-      drawRect->top += ((drawRect->bottom - drawRect->top) - ((rcText.bottom - rcText.top) + infoPtr->uVItemPadding)) / 2;
+      center_offset_v = ((drawRect->bottom - drawRect->top) - ((rcText.bottom - rcText.top) + infoPtr->uVItemPadding)) / 2;
     }
 
+    if (center_offset_v < 0)
+      center_offset_v = 0;
+
+    if(lStyle & TCS_VERTICAL)
+      drawRect->left += center_offset_v;
+    else
+      drawRect->top += center_offset_v;
+
     /* Draw the text */
     if(lStyle & TCS_VERTICAL) /* if we are vertical rotate the text and each character */
     {
@@ -1830,6 +1833,10 @@
     }
     else
     {
+      TRACE("for <%s>, c_o_h=%d, c_o_v=%d, draw=(%ld,%ld)-(%ld,%ld), textlen=%ld\n",
+	  debugstr_w(infoPtr->items[iItem].pszText), center_offset_h, center_offset_v,
+	  drawRect->left, drawRect->top, drawRect->right, drawRect->bottom,
+	  (rcText.right-rcText.left));
       DrawTextW
       (
         hdc,
@@ -1958,10 +1965,10 @@
 
 	    /* if leftmost draw the line longer */
 	    if(selectedRect.top == 0)
-		fillRect.top += 2;
+		fillRect.top += CONTROL_BORDER_SIZEY;
 	    /* if rightmost draw the line longer */
 	    if(selectedRect.bottom == clBottom)
-		fillRect.bottom -= 2;
+		fillRect.bottom -= CONTROL_BORDER_SIZEY;
 	}
 
         if (lStyle & TCS_BOTTOM)
@@ -1969,7 +1976,7 @@
 	  /* Adjust both rectangles to match native */
 	  r.left += (1-ZZ);
 
-	  TRACE("<left> item=%d, fill=(%ld,%ld)-(%ld,%ld), edge=(%ld,%ld)-(%ld,%ld)\n",
+	  TRACE("<right> item=%d, fill=(%ld,%ld)-(%ld,%ld), edge=(%ld,%ld)-(%ld,%ld)\n",
 		iItem,
 		fillRect.left,fillRect.top,fillRect.right,fillRect.bottom,
 		r.left,r.top,r.right,r.bottom);
@@ -2010,9 +2017,6 @@
         }
         else
         {
-	  /* Adjust both rectangles to match native */
-	  fillRect.right += (1-ZZ);
-
 	  TRACE("<left> item=%d, fill=(%ld,%ld)-(%ld,%ld), edge=(%ld,%ld)-(%ld,%ld)\n",
 		iItem,
 		fillRect.left,fillRect.top,fillRect.right,fillRect.bottom,
@@ -2049,26 +2053,23 @@
       {
 	/* These are for adjusting the drawing of a Selected tab      */
 	/* The initial values are for the normal case of non-Selected */
-	int ZZ = 1;   /* Do not strech if selected */
 	if (iItem == infoPtr->iSelected) {
-	    ZZ = 0;
-
 	    /* if leftmost draw the line longer */
 	    if(selectedRect.left == 0)
-		fillRect.left += 2;
+		fillRect.left += CONTROL_BORDER_SIZEX;
 	    /* if rightmost draw the line longer */
 	    if(selectedRect.right == clRight)
-		fillRect.right -= 2;
+		fillRect.right -= CONTROL_BORDER_SIZEX;
 	}
 
         if (lStyle & TCS_BOTTOM)
         {
-
-	  /* Adjust both rectangles to match native */
-	  fillRect.top--;
-	  fillRect.bottom--;
-	  r.bottom--;
-	  r.top -= ZZ;
+	  /* Adjust both rectangles for topmost row */
+	  if (infoPtr->items[iItem].rect.top == infoPtr->uNumRows-1)
+	  {
+	    fillRect.top -= 2;
+	    r.top -= 1;
+	  }
 
 	  TRACE("<bottom> item=%d, fill=(%ld,%ld)-(%ld,%ld), edge=(%ld,%ld)-(%ld,%ld)\n",
 		iItem,
@@ -2117,9 +2118,12 @@
         }
         else
         {
-
-	  /* Adjust both rectangles to match native */
-	  fillRect.bottom += (1-ZZ);
+	  /* Adjust both rectangles for bottommost row */
+	  if (infoPtr->items[iItem].rect.top == infoPtr->uNumRows-1)
+	  {
+	    fillRect.bottom += 3;
+	    r.bottom += 2;
+	  }
 
 	  TRACE("<top> item=%d, fill=(%ld,%ld)-(%ld,%ld), edge=(%ld,%ld)-(%ld,%ld)\n",
 		iItem,
@@ -2151,7 +2155,6 @@
 	  ExtTextOutA(hdc, 0, 0, 2, &r1, NULL, 0, 0);
 	  r1.top++;
 	  DrawEdge(hdc, &r1, EDGE_RAISED, BF_SOFT|BF_DIAGONAL_ENDTOPRIGHT);
-
         }
       }
     }
@@ -2184,21 +2187,13 @@
   if (infoPtr->uNumItem)
   {
     if ((lStyle & TCS_BOTTOM) && !(lStyle & TCS_VERTICAL))
-    {
-      rect.bottom -= (infoPtr->tabHeight - 2) * infoPtr->uNumRows + 3;
-    }
+      rect.bottom -= infoPtr->tabHeight * infoPtr->uNumRows + CONTROL_BORDER_SIZEX;
     else if((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
-    {
-      rect.right -= (infoPtr->tabHeight - 2) * infoPtr->uNumRows + 2;
-    }
+      rect.right  -= infoPtr->tabHeight * infoPtr->uNumRows + CONTROL_BORDER_SIZEX;
     else if(lStyle & TCS_VERTICAL)
-    {
-      rect.left += (infoPtr->tabHeight - 2) * infoPtr->uNumRows + 2;
-    }
+      rect.left   += infoPtr->tabHeight * infoPtr->uNumRows + CONTROL_BORDER_SIZEX;
     else /* not TCS_VERTICAL and not TCS_BOTTOM */
-    {
-      rect.top += (infoPtr->tabHeight - 2) * infoPtr->uNumRows + 2;
-    }
+      rect.top    += infoPtr->tabHeight * infoPtr->uNumRows + CONTROL_BORDER_SIZEX;
   }
 
   TRACE("border=(%ld,%ld)-(%ld,%ld)\n",
@@ -2418,7 +2413,7 @@
   HWND      hwnd,
   TAB_INFO* infoPtr)
 {
-  RECT clientRect, rInvalidate;
+  RECT clientRect, rInvalidate, rAdjClient;
   DWORD lStyle = GetWindowLongA(hwnd, GWL_STYLE);
   INT lastRow = infoPtr->uNumRows - 1;
   RECT rect;
@@ -2427,36 +2422,34 @@
 
   GetClientRect(hwnd, &clientRect);
   rInvalidate = clientRect;
+  rAdjClient = clientRect;
+
+  TAB_AdjustRect(hwnd, 0, &rAdjClient);
 
   TAB_InternalGetItemRect(hwnd, infoPtr, infoPtr->uNumItem-1 , &rect, NULL);
-  if ((lStyle & TCS_BOTTOM) && !(lStyle & TCS_VERTICAL))
+  if ((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
   {
-    rInvalidate.top = clientRect.bottom -
-                   infoPtr->tabHeight -
-                   lastRow * (infoPtr->tabHeight - 2) -
-                   ((lStyle & TCS_BUTTONS) ? lastRow * BUTTON_SPACINGY : 0) - 3;
-    rInvalidate.right = clientRect.left + rect.right + 2 * SELECTED_TAB_OFFSET;
-  }
-  else if((lStyle & TCS_BOTTOM) && (lStyle & TCS_VERTICAL))
-  {
-    rInvalidate.left = clientRect.right - infoPtr->tabHeight -
-                      lastRow * (infoPtr->tabHeight - 2) -
-                      ((lStyle & TCS_BUTTONS) ? lastRow * BUTTON_SPACINGY : 0) - 2;
-    rInvalidate.bottom = clientRect.top + rect.bottom + 2 * SELECTED_TAB_OFFSET;
+    rInvalidate.left = rAdjClient.right;
+    if (infoPtr->uNumRows == 1)
+      rInvalidate.bottom = clientRect.top + rect.bottom + 2 * SELECTED_TAB_OFFSET;
   }
   else if(lStyle & TCS_VERTICAL)
   {
-    rInvalidate.right = clientRect.left + infoPtr->tabHeight +
-                       lastRow * (infoPtr->tabHeight - 2) -
-                      ((lStyle & TCS_BUTTONS) ? lastRow * BUTTON_SPACINGY : 0) + 2;
-    rInvalidate.bottom = clientRect.top + rect.bottom + 2 * SELECTED_TAB_OFFSET;
+    rInvalidate.right = rAdjClient.left;
+    if (infoPtr->uNumRows == 1)
+      rInvalidate.bottom = clientRect.top + rect.bottom + 2 * SELECTED_TAB_OFFSET;
   }
-  else
+  else if (lStyle & TCS_BOTTOM)
+  {
+    rInvalidate.top = rAdjClient.bottom;
+    if (infoPtr->uNumRows == 1)
+      rInvalidate.right = clientRect.left + rect.right + 2 * SELECTED_TAB_OFFSET;
+  }
+  else 
   {
-    rInvalidate.bottom = clientRect.top + infoPtr->tabHeight +
-                      lastRow * (infoPtr->tabHeight - 2) +
-                      ((lStyle & TCS_BUTTONS) ? lastRow * BUTTON_SPACINGY : 0) + 2;
-    rInvalidate.right = clientRect.left + rect.right + 2 * SELECTED_TAB_OFFSET;
+    rInvalidate.bottom = rAdjClient.top;
+    if (infoPtr->uNumRows == 1)
+      rInvalidate.right = clientRect.left + rect.right + 2 * SELECTED_TAB_OFFSET;
   }
   
   /* Punch out the updown control */
@@ -2470,8 +2463,8 @@
   }
   
   TRACE("invalidate (%ld,%ld)-(%ld,%ld)\n",
-	clientRect.left,clientRect.top,
-	clientRect.right,clientRect.bottom);
+	rInvalidate.left,  rInvalidate.top,
+	rInvalidate.right, rInvalidate.bottom);
  
   InvalidateRect(hwnd, &rInvalidate, TRUE);
 }

reactos/lib/comctl32
toolbar.c 1.8 -> 1.9
diff -u -r1.8 -r1.9
--- toolbar.c	17 Feb 2004 22:39:49 -0000	1.8
+++ toolbar.c	11 Mar 2004 11:13:28 -0000	1.9
@@ -113,6 +113,7 @@
     DWORD      dwStructSize;   /* size of TBBUTTON struct */
     INT      nHeight;        /* height of the toolbar */
     INT      nWidth;         /* width of the toolbar */
+    RECT     client_rect;
     INT      nButtonHeight;
     INT      nButtonWidth;
     INT      nBitmapHeight;
@@ -392,8 +393,8 @@
 
     if (!TOOLBAR_IsValidBitmapIndex(infoPtr,btnPtr->iBitmap)) {
 	if (btnPtr->iBitmap == I_IMAGENONE) return FALSE;
-	ERR("index %d is not valid, max %d\n",
-	    btnPtr->iBitmap, infoPtr->nNumBitmaps);
+	ERR("index %d,%d is not valid, max %d\n",
+	    HIWORD(btnPtr->iBitmap), LOWORD(btnPtr->iBitmap), infoPtr->nNumBitmaps);
 	return FALSE;
     }
 
@@ -497,7 +498,7 @@
 /***********************************************************************
 * 		TOOLBAR_DrawDDFlatSeparator
 *
-* This function draws the separator that was flaged as BTNS_DROPDOWN.
+* This function draws the separator that was flagged as BTNS_DROPDOWN.
 * In this case, the separator is a pixel high line of COLOR_BTNSHADOW,
 * followed by a pixel high line of COLOR_BTNHIGHLIGHT. These separators
 * are horizontal as opposed to the vertical separators for not dropdown
@@ -565,13 +566,13 @@
  *      an image list
  */
 static void
-TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr,
-		    HDC hdc, DWORD dwStyle,
-                    RECT *rcText, LPWSTR lpText, NMTBCUSTOMDRAW *tbcd)
+TOOLBAR_DrawString (TOOLBAR_INFO *infoPtr, RECT *rcText, LPWSTR lpText,
+                    NMTBCUSTOMDRAW *tbcd)
 {
     HFONT  hOldFont = 0;
     COLORREF clrOld = 0;
     UINT state = tbcd->nmcd.uItemState;
+    HDC hdc = tbcd->nmcd.hdc;
 
     /* draw text */
     if (lpText) {
@@ -604,12 +605,15 @@
 
 
 static void
-TOOLBAR_DrawPattern (HDC hdc, LPRECT lpRect)
+TOOLBAR_DrawPattern (LPRECT lpRect, NMTBCUSTOMDRAW *tbcd)
 {
+    HDC hdc = tbcd->nmcd.hdc;
     HBRUSH hbr = SelectObject (hdc, COMCTL32_hPattern55AABrush);
     INT cx = lpRect->right - lpRect->left;
     INT cy = lpRect->bottom - lpRect->top;
-    PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, 0x00FA0089);
+    SetTextColor(hdc, tbcd->clrBtnHighlight);
+    SetBkColor(hdc, tbcd->clrBtnFace);
+    PatBlt (hdc, lpRect->left, lpRect->top, cx, cy, PATCOPY);
     SelectObject (hdc, hbr);
 }
 
@@ -801,9 +805,10 @@
     /* NOTE: applications can and do alter this to customize their  */
     /* toolbars */
     tbcd.nmcd.uItemState = TOOLBAR_TranslateState(btnPtr);
+    tbcd.nmcd.hdc = hdc;
+    tbcd.hbrMonoDither = COMCTL32_hPattern55AABrush;
 
     /* FIXME: what should these be set to ????? */
-    tbcd.hbrMonoDither = 0;
     tbcd.hbrLines = 0;
     tbcd.hpenLines = 0;
 
@@ -813,7 +818,6 @@
     if (infoPtr->dwBaseCustDraw & CDRF_NOTIFYITEMDRAW)
     {
 	tbcd.nmcd.dwDrawStage = CDDS_ITEMPREPAINT;
-	tbcd.nmcd.hdc = hdc;
 	tbcd.nmcd.rc = rc;
 	tbcd.nmcd.dwItemSpec = btnPtr->idCommand;
 	tbcd.nmcd.lItemlParam = btnPtr->dwData;
@@ -896,7 +900,7 @@
 	    TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top);
 
 	if (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || (btnPtr->fsStyle & BTNS_SHOWTEXT))
-	    TOOLBAR_DrawString (infoPtr, btnPtr, hdc, dwStyle, &rcText, lpText, &tbcd);
+	    TOOLBAR_DrawString (infoPtr, &rcText, lpText, &tbcd);
 	goto FINALNOTIFY;
     }
 
@@ -927,7 +931,7 @@
 			       ILD_NORMAL);
 
 	if (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || (btnPtr->fsStyle & BTNS_SHOWTEXT))
-	    TOOLBAR_DrawString (infoPtr, btnPtr, hdc, dwStyle, &rcText, lpText, &tbcd);
+	    TOOLBAR_DrawString (infoPtr, &rcText, lpText, &tbcd);
 	goto FINALNOTIFY;
     }
 
@@ -944,14 +948,14 @@
 			  BF_RECT | BF_MIDDLE | BF_ADJUST);
 	}
 
-	TOOLBAR_DrawPattern (hdc, &rc);
+	TOOLBAR_DrawPattern (&rc, &tbcd);
 
 	TOOLBAR_DrawImageList (infoPtr, btnPtr, IMAGE_LIST_DEFAULT,
 			       hdc, rcBitmap.left+1, rcBitmap.top+1,
 			       ILD_NORMAL);
 
 	if (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || (btnPtr->fsStyle & BTNS_SHOWTEXT))
-	    TOOLBAR_DrawString (infoPtr, btnPtr, hdc, dwStyle, &rcText, lpText, &tbcd);
+	    TOOLBAR_DrawString (infoPtr, &rcText, lpText, &tbcd);
 	goto FINALNOTIFY;
     }
 
@@ -961,10 +965,10 @@
 	    DrawEdge (hdc, &rc, EDGE_RAISED,
 		      BF_SOFT | BF_RECT | BF_MIDDLE | BF_ADJUST);
 
-	TOOLBAR_DrawPattern (hdc, &rc);
+	TOOLBAR_DrawPattern (&rc, &tbcd);
 	TOOLBAR_DrawMasked (infoPtr, btnPtr, hdc, rcBitmap.left, rcBitmap.top);
 	if (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || (btnPtr->fsStyle & BTNS_SHOWTEXT))
-	    TOOLBAR_DrawString (infoPtr, btnPtr, hdc, dwStyle, &rcText, lpText, &tbcd);
+	    TOOLBAR_DrawString (infoPtr, &rcText, lpText, &tbcd);
 	goto FINALNOTIFY;
     }
 
@@ -1011,7 +1015,7 @@
 
 
     if (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) || (btnPtr->fsStyle & BTNS_SHOWTEXT))
-        TOOLBAR_DrawString (infoPtr, btnPtr, hdc, dwStyle, &rcText, lpText, &tbcd);
+        TOOLBAR_DrawString (infoPtr, &rcText, lpText, &tbcd);
 
  FINALNOTIFY:
     if (infoPtr->dwItemCustDraw & CDRF_NOTIFYPOSTPAINT)
@@ -1116,7 +1120,8 @@
     lpSize->cx = 0;
     lpSize->cy = 0;
 
-    if (!(btnPtr->fsState & TBSTATE_HIDDEN) &&
+    if (infoPtr->nMaxTextRows > 0 &&
+        !(btnPtr->fsState & TBSTATE_HIDDEN) &&
         (!(infoPtr->dwExStyle & TBSTYLE_EX_MIXEDBUTTONS) ||
         (btnPtr->fsStyle & BTNS_SHOWTEXT)) )
     {
@@ -3290,7 +3295,9 @@
 static LRESULT
 TOOLBAR_GetDisabledImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    return (LRESULT)GETDISIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), 0);
+    TRACE("hwnd=%p, wParam=%d, lParam=0x%lx\n", hwnd, wParam, lParam);
+    /* UNDOCUMENTED: wParam is actually the ID of the image list to return */
+    return (LRESULT)GETDISIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), wParam);
 }
 
 
@@ -3308,7 +3315,9 @@
 static LRESULT
 TOOLBAR_GetHotImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    return (LRESULT)GETHOTIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), 0);
+    TRACE("hwnd=%p, wParam=%d, lParam=0x%lx\n", hwnd, wParam, lParam);
+    /* UNDOCUMENTED: wParam is actually the ID of the image list to return */
+    return (LRESULT)GETHOTIMAGELIST(TOOLBAR_GetInfoPtr (hwnd), wParam);
 }
 
 
@@ -3330,7 +3339,9 @@
 static LRESULT
 TOOLBAR_GetDefImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    return (LRESULT) GETDEFIMAGELIST(TOOLBAR_GetInfoPtr(hwnd), 0);
+    TRACE("hwnd=%p, wParam=%d, lParam=0x%lx\n", hwnd, wParam, lParam);
+    /* UNDOCUMENTED: wParam is actually the ID of the image list to return */
+    return (LRESULT) GETDEFIMAGELIST(TOOLBAR_GetInfoPtr(hwnd), wParam);
 }
 
 
@@ -4305,6 +4316,12 @@
     return (LRESULT)dwTemp;
 }
 
+/* This function differs a bit from what MSDN says it does:
+ * 1. lParam contains extended style flags to OR with current style
+ *  (MSDN isn't clear on the OR bit)
+ * 2. wParam appears to contain extended style flags to be reset
+ *  (MSDN says that this parameter is reserved)
+ */
 static LRESULT
 TOOLBAR_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
@@ -4312,6 +4329,7 @@
     DWORD dwTemp;
 
     dwTemp = infoPtr->dwExStyle;
+    infoPtr->dwExStyle &= ~wParam;
     infoPtr->dwExStyle |= (DWORD)lParam;
 
     TRACE("new style 0x%08lx\n", infoPtr->dwExStyle);
@@ -4653,6 +4671,57 @@
     return iOldVersion;
 }
 
+
+static LRESULT
+TOOLBAR_GetStringA (HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
+    WORD iString = HIWORD(wParam);
+    WORD buffersize = LOWORD(wParam);
+    LPSTR str = (LPSTR)lParam;
+    LRESULT ret = -1;
+
+    TRACE("hwnd=%p, iString=%d, buffersize=%d, string=%p\n", hwnd, iString, buffersize, str);
+
+    if (iString < infoPtr->nNumStrings)
+    {
+        ret = WideCharToMultiByte(CP_ACP, 0, infoPtr->strings[iString], -1, str, buffersize, NULL, NULL);
+
+        TRACE("returning %s\n", debugstr_a(str));
+    }
+    else
+        ERR("String index %d out of range (largest is %d)\n", iString, infoPtr->nNumStrings - 1);
+
+    return ret;
+}
+
+
+static LRESULT
+TOOLBAR_GetStringW (HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
+    WORD iString = HIWORD(wParam);
+    WORD len = LOWORD(wParam)/sizeof(WCHAR) - 1;
+    LPWSTR str = (LPWSTR)lParam;
+    LRESULT ret = -1;
+
+    TRACE("hwnd=%p, iString=%d, buffersize=%d, string=%p\n", hwnd, iString, LOWORD(wParam), str);
+
+    if (iString < infoPtr->nNumStrings)
+    {
+        len = min(len, strlenW(infoPtr->strings[iString]));
+        ret = (len+1)*sizeof(WCHAR);
+        memcpy(str, infoPtr->strings[iString], ret);
+        str[len] = '\0';
+
+        TRACE("returning %s\n", debugstr_w(str));
+    }
+    else
+        ERR("String index %d out of range (largest is %d)\n", iString, infoPtr->nNumStrings - 1);
+
+    return ret;
+}
+
 static LRESULT TOOLBAR_Unkwn45D(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
     FIXME("hwnd=%p wParam %08x lParam %08lx stub!\n", hwnd, wParam, lParam);
@@ -4713,12 +4782,23 @@
 
 static LRESULT TOOLBAR_Unkwn460(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    TRACE("hwnd=%p wParam %08x lParam %08lx\n", hwnd, wParam, lParam);
+    FIXME("hwnd=%p wParam %08x lParam %08lx\n", hwnd, wParam, lParam);
 
     InvalidateRect(hwnd, NULL, TRUE);
     return 0;
 }
 
+/* UNDOCUMENTED MESSAGE: This returns the number of maximum number
+ * of image lists associated with the various states. */
+static LRESULT TOOLBAR_Unkwn462(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    TOOLBAR_INFO *infoPtr = TOOLBAR_GetInfoPtr(hwnd);
+
+    TRACE("hwnd=%p wParam %08x lParam %08lx\n", hwnd, wParam, lParam);
+
+    return max(infoPtr->cimlDef, max(infoPtr->cimlHot, infoPtr->cimlDis));
+}
+
 static LRESULT
 TOOLBAR_Unkwn463 (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
@@ -4775,7 +4855,7 @@
 
 static LRESULT TOOLBAR_Unkwn464(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-    TRACE("hwnd=%p wParam %08x lParam %08lx\n", hwnd, wParam, lParam);
+    FIXME("hwnd=%p wParam %08x lParam %08lx\n", hwnd, wParam, lParam);
 
     InvalidateRect(hwnd, NULL, TRUE);
     return 1;
@@ -4789,6 +4869,8 @@
     DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
     LOGFONTA logFont;
 
+    TRACE("hwnd = %p\n", hwnd);
+
     /* initialize info structure */
     infoPtr->nButtonHeight = 22;
     infoPtr->nButtonWidth = 24;
@@ -4819,6 +4901,7 @@
     infoPtr->clrBtnShadow = CLR_DEFAULT;
     infoPtr->szPadding.cx = 7;
     infoPtr->szPadding.cy = 6;
+    GetClientRect(hwnd, &infoPtr->client_rect);
     TOOLBAR_NotifyFormat(infoPtr, (WPARAM)hwnd, (LPARAM)NF_REQUERY);
 
     SystemParametersInfoA (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
@@ -5701,8 +5784,50 @@
 	    cx += GetSystemMetrics(SM_CYEDGE);
 	}
 
-	SetWindowPos (hwnd, 0,  x,  y, cx, cy, uPosFlags | SWP_NOZORDER);
+        if(infoPtr->dwExStyle & TBSTYLE_EX_HIDECLIPPEDBUTTONS)
+        {
+            RECT delta_width, delta_height, client, dummy;
+            DWORD min_x, max_x, min_y, max_y;
+            TBUTTON_INFO *btnPtr;
+            INT i;
+
+            GetClientRect(hwnd, &client);
+            if(client.right > infoPtr->client_rect.right)
+            {
+                min_x = infoPtr->client_rect.right;
+                max_x = client.right;
+            }
+            else
+            {
+                max_x = infoPtr->client_rect.right;
+                min_x = client.right;
+            }
+            if(client.bottom > infoPtr->client_rect.bottom)
+            {
+                min_y = infoPtr->client_rect.bottom;
+                max_y = client.bottom;
+            }
+            else
+            {
+                max_y = infoPtr->client_rect.bottom;
+                min_y = client.bottom;
+            }
+
+            SetRect(&delta_width, min_x, 0, max_x, min_y);
+            SetRect(&delta_height, 0, min_y, max_x, max_y);
+
+            TRACE("delta_width %s delta_height %s\n", wine_dbgstr_rect(&delta_width), wine_dbgstr_rect(&delta_height));
+            btnPtr = infoPtr->buttons;
+            for (i = 0; i < infoPtr->nNumButtons; i++, btnPtr++)
+                if(IntersectRect(&dummy, &delta_width, &btnPtr->rect) ||
+                   IntersectRect(&dummy, &delta_height, &btnPtr->rect))
+                    InvalidateRect(hwnd, &btnPtr->rect, TRUE);
+        }
+
+        if((uPosFlags & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE)) 
+            SetWindowPos (hwnd, 0,  x,  y, cx, cy, uPosFlags | SWP_NOZORDER);
     }
+    GetClientRect(hwnd, &infoPtr->client_rect);
     return 0;
 }
 
@@ -5867,6 +5992,12 @@
 	case TB_GETSTATE:
 	    return TOOLBAR_GetState (hwnd, wParam, lParam);
 
+	case TB_GETSTRINGA:
+        return TOOLBAR_GetStringA (hwnd, wParam, lParam);
+
+	case TB_GETSTRINGW:
+	    return TOOLBAR_GetStringW (hwnd, wParam, lParam);
+
 	case TB_GETSTYLE:
 	    return TOOLBAR_GetStyle (hwnd, wParam, lParam);
 
@@ -6015,6 +6146,9 @@
 	case TB_UNKWN460:
 	    return TOOLBAR_Unkwn460(hwnd, wParam, lParam);
 
+	case TB_UNKWN462:
+	    return TOOLBAR_Unkwn462(hwnd, wParam, lParam);
+
 	case TB_UNKWN463:
 	    return TOOLBAR_Unkwn463 (hwnd, wParam, lParam);
 

reactos/lib/comctl32
tooltips.c 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- tooltips.c	19 Dec 2003 16:41:02 -0000	1.3
+++ tooltips.c	11 Mar 2004 11:13:28 -0000	1.4
@@ -701,7 +701,7 @@
     toolPtr->rect   = lpToolInfo->rect;
     toolPtr->hinst  = lpToolInfo->hinst;
 
-    if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)) {
+    if (HIWORD(lpToolInfo->lpszText) == 0) {
 	TRACE("add string id %x!\n", (int)lpToolInfo->lpszText);
 	toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
     }
@@ -779,7 +779,7 @@
     toolPtr->rect   = lpToolInfo->rect;
     toolPtr->hinst  = lpToolInfo->hinst;
 
-    if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)) {
+    if (HIWORD(lpToolInfo->lpszText) == 0) {
 	TRACE("add string id %x!\n", (int)lpToolInfo->lpszText);
 	toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
     }
@@ -842,7 +842,7 @@
 
     /* delete text string */
     toolPtr = &infoPtr->tools[nTool];
-    if ((toolPtr->hinst) && (toolPtr->lpszText)) {
+    if (toolPtr->lpszText) {
 	if ( (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) &&
 	     (HIWORD((INT)toolPtr->lpszText) != 0) )
 	    Free (toolPtr->lpszText);
@@ -917,7 +917,7 @@
 
     /* delete text string */
     toolPtr = &infoPtr->tools[nTool];
-    if ((toolPtr->hinst) && (toolPtr->lpszText)) {
+    if (toolPtr->lpszText) {
 	if ( (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) &&
 	     (HIWORD((INT)toolPtr->lpszText) != 0) )
 	    Free (toolPtr->lpszText);
@@ -1632,7 +1632,7 @@
     toolPtr->rect   = lpToolInfo->rect;
     toolPtr->hinst  = lpToolInfo->hinst;
 
-    if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)) {
+    if (HIWORD(lpToolInfo->lpszText) == 0) {
 	TRACE("set string id %x!\n", (INT)lpToolInfo->lpszText);
 	toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
     }
@@ -1689,7 +1689,7 @@
     toolPtr->rect   = lpToolInfo->rect;
     toolPtr->hinst  = lpToolInfo->hinst;
 
-    if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)) {
+    if (HIWORD(lpToolInfo->lpszText) == 0) {
 	TRACE("set string id %x!\n", (INT)lpToolInfo->lpszText);
 	toolPtr->lpszText = lpToolInfo->lpszText;
     }
@@ -1805,7 +1805,7 @@
     /* copy tool text */
     toolPtr->hinst  = lpToolInfo->hinst;
 
-    if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)){
+    if (HIWORD(lpToolInfo->lpszText) == 0){
 	toolPtr->lpszText = (LPWSTR)lpToolInfo->lpszText;
     }
     else if (lpToolInfo->lpszText) {
@@ -1862,7 +1862,7 @@
     /* copy tool text */
     toolPtr->hinst  = lpToolInfo->hinst;
 
-    if ((lpToolInfo->hinst) && (HIWORD((INT)lpToolInfo->lpszText) == 0)){
+    if (HIWORD(lpToolInfo->lpszText) == 0){
 	toolPtr->lpszText = lpToolInfo->lpszText;
     }
     else if (lpToolInfo->lpszText) {
@@ -1958,7 +1958,7 @@
     if (infoPtr->tools) {
 	for (i = 0; i < infoPtr->uNumTools; i++) {
 	    toolPtr = &infoPtr->tools[i];
-	    if ((toolPtr->hinst) && (toolPtr->lpszText)) {
+	    if (toolPtr->lpszText) {
 		if ( (toolPtr->lpszText != LPSTR_TEXTCALLBACKW) &&
 		     (HIWORD((INT)toolPtr->lpszText) != 0) )
 		{

reactos/lib/comctl32
treeview.c 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- treeview.c	17 Feb 2004 22:40:47 -0000	1.6
+++ treeview.c	11 Mar 2004 11:13:28 -0000	1.7
@@ -2289,8 +2289,8 @@
 	    HBRUSH hbr    = CreateSolidBrush(infoPtr->clrBk);
 	    HBRUSH hbrOld = SelectObject(hdc, hbr);
 
-	    Rectangle(hdc, centerx - rectsize, centery - rectsize,
-		      centerx + rectsize + 1, centery + rectsize + 1);
+           Rectangle(hdc, centerx - rectsize - 1, centery - rectsize - 1,
+                     centerx + rectsize + 2, centery + rectsize + 2);
 
 	    SelectObject(hdc, hbrOld);
 	    DeleteObject(hbr);
@@ -2599,7 +2599,7 @@
     if (vert)
     {
 	si.nPage = TREEVIEW_GetVisibleCount(infoPtr);
-       if ( si.nPage )
+       if ( si.nPage && NULL != infoPtr->firstVisible)
        {
            si.nPos  = infoPtr->firstVisible->visibleOrder;
            si.nMax  = infoPtr->maxVisibleOrder - 1;

reactos/lib/comctl32
winehq2ros.patch 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- winehq2ros.patch	28 Jan 2004 21:40:09 -0000	1.3
+++ winehq2ros.patch	11 Mar 2004 11:13:28 -0000	1.4
@@ -0,0 +1,104 @@
+Index: comctl32.spec
+===================================================================
+RCS file: /home/wine/wine/dlls/comctl32/comctl32.spec,v
+retrieving revision 1.43
+diff -u -r1.43 comctl32.spec
+--- comctl32.spec	20 Feb 2004 05:16:37 -0000	1.43
++++ comctl32.spec	11 Mar 2004 11:16:16 -0000
+@@ -106,13 +106,13 @@
+ 412 stdcall RemoveWindowSubclass(long ptr long)
+ 413 stdcall DefSubclassProc(long long long long)
+ 414 stub -noname MirrorIcon
+-415 stdcall -noname DrawTextWrap(long wstr long ptr long) user32.DrawTextW
+-416 stdcall -noname DrawTextExPrivWrap(long wstr long ptr long ptr) user32.DrawTextExW
+-417 stdcall -noname ExtTextOutWrap(long long long long ptr wstr long ptr) gdi32.ExtTextOutW
+-418 stdcall -noname GetCharWidthWrap(long long long long) gdi32.GetCharWidthW
+-419 stdcall -noname GetTextExtentPointWrap(long wstr long ptr) gdi32.GetTextExtentPointW
+-420 stdcall -noname GetTextExtentPoint32Wrap(long wstr long ptr) gdi32.GetTextExtentPoint32W
+-421 stdcall -noname TextOutWrap(long long long wstr long) gdi32.TextOutW
++415 stdcall DrawTextWrap(long wstr long ptr long) user32.DrawTextW
++416 stdcall DrawTextExPrivWrap(long wstr long ptr long ptr) user32.DrawTextExW
++417 stdcall ExtTextOutWrap(long long long long ptr wstr long ptr) gdi32.ExtTextOutW
++418 stdcall GetCharWidthWrap(long long long long) gdi32.GetCharWidthW
++419 stdcall GetTextExtentPointWrap(long wstr long ptr) gdi32.GetTextExtentPointW
++420 stdcall GetTextExtentPoint32Wrap(long wstr long ptr) gdi32.GetTextExtentPoint32W
++421 stdcall TextOutWrap(long long long wstr long) gdi32.TextOutW
+ 
+ # Functions imported by name
+ 
+Index: rebar.c
+===================================================================
+RCS file: /home/wine/wine/dlls/comctl32/rebar.c,v
+retrieving revision 1.85
+diff -u -r1.85 rebar.c
+--- rebar.c	27 Feb 2004 04:32:54 -0000	1.85
++++ rebar.c	11 Mar 2004 11:16:19 -0000
+@@ -985,7 +985,7 @@
+       }
+ 
+       /* text is visible */
+-      if (lpBand->fStatus & HAS_TEXT) {
++      if ((lpBand->fStatus & HAS_TEXT) && !(lpBand->fStyle & RBBS_HIDETITLE)) {
+ 	  lpBand->fDraw |= DRAW_TEXT;
+ 	  lpBand->rcCapText.right = max(lpBand->rcCapText.left,
+ 					lpBand->rcCapText.right-REBAR_POST_TEXT);
+@@ -1131,7 +1131,7 @@
+ 	}
+ 
+ 	/* text is visible */
+-	if (lpBand->fStatus & HAS_TEXT) {
++	if ((lpBand->fStatus & HAS_TEXT) && !(lpBand->fStyle & RBBS_HIDETITLE)) {
+ 	    lpBand->fDraw |= DRAW_TEXT;
+ 	    lpBand->rcCapText.bottom = max(lpBand->rcCapText.top,
+ 					   lpBand->rcCapText.bottom);
+@@ -2027,7 +2027,8 @@
+     }
+ 
+     /* text is visible */
+-    if ((lpBand->fMask & RBBIM_TEXT) && (lpBand->lpText)) {
++    if ((lpBand->fMask & RBBIM_TEXT) && (lpBand->lpText) &&
++        !(lpBand->fStyle & RBBS_HIDETITLE)) {
+ 	HDC hdc = GetDC (0);
+ 	HFONT hOldFont = SelectObject (hdc, infoPtr->hFont);
+ 	SIZE size;
+Index: string.c
+===================================================================
+RCS file: /home/wine/wine/dlls/comctl32/string.c,v
+retrieving revision 1.3
+diff -u -r1.3 string.c
+--- string.c	20 Feb 2004 19:58:39 -0000	1.3
++++ string.c	11 Mar 2004 11:16:19 -0000
+@@ -254,7 +254,7 @@
+ {
+   TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
+ 
+-  return COMCTL32_StrStrHelperW(lpszStr, lpszSearch, strncmpiW);
++  return COMCTL32_StrStrHelperW(lpszStr, lpszSearch, (int (*)(LPCWSTR,LPCWSTR,int)) wcsnicmp);
+ }
+ 
+ /**************************************************************************
+@@ -503,7 +503,7 @@
+ {
+   TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszSearch));
+ 
+-  return COMCTL32_StrStrHelperW(lpszStr, lpszSearch, strncmpW);
++  return COMCTL32_StrStrHelperW(lpszStr, lpszSearch, (int (*)(LPCWSTR,LPCWSTR,int)) wcsncmp);
+ }
+ 
+ /*************************************************************************
+Index: toolbar.c
+===================================================================
+RCS file: /home/wine/wine/dlls/comctl32/toolbar.c,v
+retrieving revision 1.160
+diff -u -r1.160 toolbar.c
+--- toolbar.c	7 Mar 2004 03:13:26 -0000	1.160
++++ toolbar.c	11 Mar 2004 11:16:21 -0000
+@@ -2299,7 +2299,7 @@
+ 	TRACE ("creating default image list!\n");
+ 
+     himlDef = ImageList_Create (infoPtr->nBitmapWidth, infoPtr->nBitmapHeight, 
+-		ILC_COLOR | ILC_MASK, nButtons, 2);
++		ILC_COLORDDB | ILC_MASK, nButtons, 2);
+ 	TOOLBAR_InsertImageList(&infoPtr->himlDef, &infoPtr->cimlDef, himlDef, 0);
+     infoPtr->himlInt = himlDef;
+     }
CVSspam 0.2.8