ComboEx patch

Dimitrie O. Paun dpaun at rogers.com
Wed Apr 3 23:52:12 CST 2002


This one fixes a number of bugs. I plan on implementing the 
missing features next.

ChangeLog:
  -- fix edit box placement
  -- reorganize drawing for proper handling of edit box
  -- typesafety when processing messages
  -- subclass edit to handle up/down arrows
  -- more robust handling of failure cases
  -- numerous bugs fixed
  -- complete unicodification
  -- more specific debug messages
  -- remove cvs log info from file
  -- consistent indentation

Index: dlls/comctl32/comboex.c
===================================================================
RCS file: /var/cvs/wine/dlls/comctl32/comboex.c,v
retrieving revision 1.41
diff -u -r1.41 comboex.c
--- dlls/comctl32/comboex.c	9 Mar 2002 23:29:34 -0000	1.41
+++ dlls/comctl32/comboex.c	4 Apr 2002 05:47:06 -0000
@@ -1,7 +1,9 @@
 /*
- * ComboBoxEx control v2 (mod6)
+ * ComboBoxEx control
  *
  * Copyright 1998, 1999 Eric Kohl
+ * Copyright 2000, 2001, 2002 Guy Albertelli <galberte at neo.lrun.com>
+ * Copyright 2002 Dimitrie O. Paun
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -17,12 +19,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 at abo.rhein-zeitung.de>
- *
- *
  * TODO   <-------------
  *  1. The following extended styles need to be implemented, use will
  *     result in a FIXME:
@@ -39,58 +35,6 @@
  *  3. No use is made of the iOverlay image.
  *  4. Notify CBEN_DRAGBEGIN is not implemented.
  *
- *
- * Changes  Guy Albertelli <galberte at neo.lrun.com>
- * v1  Implemented messages: CB_SETITEMHEIGHT, WM_WINDOWPOSCHANGING,
- *      WM_DRAWITEM, and WM_MEASUREITEM. Fixed WM_CREATE. Fixed height
- *      of window rect reported fixing rebar control.
- * v2
- *   1. Rewrite of WM_Create for own created EDIT control. Also try to
- *      generate message sequence similar to native DLL.
- *   2. Handle case where CBEM_SETITEM is called to display data in EDIT
- *      Control. 
- *   3. Add override for WNDPROC for the EDIT control (reqed for VK_RETURN).
- *   4. Dump input data for things using COMBOBOXEXITEM{A|W}.
- *   5. Handle positioning EDIT control based on whether icon present.
- *   6. Make InsertItemA use InsertItemW, and store all data in ..W form.
- *   7. Implement CBEM_DELETEITEM, CBEM_GETITEM{A|W}, CB_SETCURSEL,
- *      CBEM_{GET|SET}UNICODEFORMAT.
- *   8. Add override for WNDPROC for the COMBO control.
- *   9. Support extended style CBES_EX_NOEDITIMAGE and warn others are not
- *      supported.
- *  10. Implement CB_FINDSTRINGEXACT in both the Combo and ComboEx window
- *      procs to match the items. This eliminates dup entries in the listbox.
- *
- *  mod 4
- *   1. Implemented CBN_SELCHANGE, CBN_KILLFOCUS, and CBN_SELENDOK.
- *   2. Fix putting text in CBEN_ENDEDIT notifies for CBN_DROPDOWN case.
- *   3. Lock image selected status to focus state of edit control if
- *      edit control exists. Mimics native actions.
- *   4. Implemented WM_SETFOCUS in EditWndProc to track status of 
- *      focus for 3 above.
- *   5. The LBN_SELCHANGE is just for documentation purposes.
- *
- *  mod 5
- *   1. Add support for CB_GETITEMDATA to a Comboex. Returns the LPARAM
- *      passed during insert of item.
- *   2. Remember selected item and don't issue CB_SETCURSEL unless needed.
- *   3. Add initial support for WM_NCCREATE to remove unwanted window styles
- *      (Currently just WS_VSCROLL and WS_HSCROLL, but probably should be
- *       more.)
- *   4. Improve some traces.
- *   5. Add support for CB_SETITEMDATA sets LPARAM value from item.
- *
- *  mod 6
- *   1. Add support for WM_NOTIFYFORMAT (both incoming and outgoing) and do 
- *      WM_NOTIFY correctly based on results.
- *   2. Fix memory leaks of text strings in COMBOEX_WM_DELETEITEM.
- *   3. Add routines to handle special cases of NMCBEENDEDIT and NMCOMBOXEX
- *      so translation to ANSI is done correctly. 
- *   4. Fix some issues with COMBOEX_DrawItem.
- *
- * Test vehicals were the ControlSpy modules (rebar.exe and comboboxex.exe),
- *  WinRAR, and IE 4.0.
- *
  */
 
 #include <string.h>
@@ -128,15 +72,15 @@
     HWND         hwndCombo;
     HWND         hwndEdit;
     WNDPROC      prevEditWndProc;  /* previous Edit WNDPROC value */
-    WNDPROC      prevComboWndProc;   /* previous Combo WNDPROC value */
+    WNDPROC      prevComboWndProc; /* previous Combo WNDPROC value */
     DWORD        dwExtStyle;
     INT          selected;         /* index of selected item */
     DWORD        flags;            /* WINE internal flags */
-    HFONT        hDefaultFont;
+    HFONT        defaultFont;
     HFONT        font;
     INT          nb_items;         /* Number of items */
-    BOOL         bUnicode;        /* TRUE if this window is Unicode   */
-    BOOL         NtfUnicode;      /* TRUE if parent wants notify in Unicode */
+    BOOL         unicode;          /* TRUE if this window is Unicode   */
+    BOOL         NtfUnicode;       /* TRUE if parent wants notify in Unicode */
     CBE_ITEMDATA *edit;            /* item data for edit item */
     CBE_ITEMDATA *items;           /* Array of items */
 } COMBOEX_INFO;
@@ -147,6 +91,7 @@
                                              * but CBEN_ENDEDIT{A|W}
                                              * not yet issued. */
 #define  WCBE_EDITCHG        0x00000002     /* Edit issued EN_CHANGE */
+#define  WCBE_EDITHASCHANGED (WCBE_ACTEDIT | WCBE_EDITCHG)
 #define  WCBE_EDITFOCUSED    0x00000004     /* Edit control has focus */
 
 
@@ -179,69 +124,51 @@
 /* Offset between image and text */
 #define CBE_SEP   4
 
-#define COMBOEX_GetInfoPtr(hwnd) ((COMBOEX_INFO *)GetWindowLongA (hwnd, 0))
+#define COMBOEX_SUBCLASS_PROP "CCComboEx32SubclassInfo"
+#define COMBOEX_GetInfoPtr(hwnd) ((COMBOEX_INFO *)GetWindowLongW (hwnd, 0))
 
 
 /* Things common to the entire DLL */
-static ATOM ComboExInfo;
 static LRESULT WINAPI
 COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 static LRESULT WINAPI
 COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
-static void
-COMBOEX_DumpItem (CBE_ITEMDATA *item)
+static void COMBOEX_DumpItem (CBE_ITEMDATA *item)
 {
-    if (TRACE_ON(comboex)){
-      TRACE("item %p - mask=%08x, pszText=%p, cchTM=%d, iImage=%d\n",
-	    item, item->mask, item->pszText, item->cchTextMax,
-	    item->iImage);
-      TRACE("item %p - iSelectedImage=%d, iOverlay=%d, iIndent=%d, lParam=%08lx\n",
-	    item, item->iSelectedImage, item->iOverlay, item->iIndent, item->lParam);
-      if ((item->mask & CBEIF_TEXT) && item->pszText)
-	  TRACE("item %p - pszText=%s\n",
-		item, debugstr_w((const WCHAR *)item->pszText));
-    }
+    TRACE("item %p - mask=%08x, pszText=%p, cchTM=%d, iImage=%d\n",
+          item, item->mask, item->pszText, item->cchTextMax, item->iImage);
+    TRACE("item %p - iSelectedImage=%d, iOverlay=%d, iIndent=%d, lParam=%08lx\n",
+          item, item->iSelectedImage, item->iOverlay, item->iIndent, item->lParam);
+    if ((item->mask & CBEIF_TEXT) && item->pszText)
+        TRACE("item %p - pszText=%s\n", item, debugstr_w(item->pszText));
 }
 
 
-static void
-COMBOEX_DumpInput (COMBOBOXEXITEMA *input, BOOL true_for_w)
-{
-    if (TRACE_ON(comboex)){
-      TRACE("input - mask=%08x, iItem=%d, pszText=%p, cchTM=%d, iImage=%d\n",
-	    input->mask, input->iItem, input->pszText, input->cchTextMax,
-	    input->iImage);
-      if ((input->mask & CBEIF_TEXT) && input->pszText) {
-	  if (true_for_w)
-	      TRACE("input - pszText=<%s>\n", 
-		    debugstr_w((const WCHAR *)input->pszText));
-	  else 
-	      TRACE("input - pszText=<%s>\n", 
-		    debugstr_a((const char *)input->pszText));
-      }
-      TRACE("input - iSelectedImage=%d, iOverlay=%d, iIndent=%d, lParam=%08lx\n",
-	    input->iSelectedImage, input->iOverlay, input->iIndent, input->lParam);
-    }
+static void COMBOEX_DumpInput (COMBOBOXEXITEMW *input)
+{
+    TRACE("input - mask=%08x, iItem=%d, pszText=%p, cchTM=%d, iImage=%d\n",
+          input->mask, input->iItem, input->pszText, input->cchTextMax,
+          input->iImage);
+    if ((input->mask & CBEIF_TEXT) && input->pszText)
+        TRACE("input - pszText=<%s>\n", debugstr_w(input->pszText));
+    TRACE("input - iSelectedImage=%d, iOverlay=%d, iIndent=%d, lParam=%08lx\n",
+          input->iSelectedImage, input->iOverlay, input->iIndent, input->lParam);
 }
 
 
 inline static LRESULT
-COMBOEX_Forward (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+COMBOEX_Forward (COMBOEX_INFO *infoPtr, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-
     if (infoPtr->hwndCombo)    
-	return SendMessageA (infoPtr->hwndCombo, uMsg, wParam, lParam);
+	return SendMessageW (infoPtr->hwndCombo, uMsg, wParam, lParam);
 
     return 0;
 }
 
 
-static INT
-COMBOEX_Notify (COMBOEX_INFO *infoPtr, INT code, NMHDR *hdr)
+static INT COMBOEX_Notify (COMBOEX_INFO *infoPtr, INT code, NMHDR *hdr)
 {
-
     hdr->idFrom = GetDlgCtrlID (infoPtr->hwndSelf);
     hdr->hwndFrom = infoPtr->hwndSelf;
     hdr->code = code;
@@ -277,6 +204,7 @@
 	    len = WideCharToMultiByte (CP_ACP, 0, str, -1, 0, 0, NULL, NULL);
 	    if (len > 0) {
 		hdr->ceItem.pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(CHAR));
+		//FIXME: what if alloc failed?
 		WideCharToMultiByte (CP_ACP, 0, str, -1, (LPSTR)hdr->ceItem.pszText,
 				     len, NULL, NULL);
 	    }
@@ -321,8 +249,7 @@
 }
 
 
-static void
-COMBOEX_GetComboFontSize (COMBOEX_INFO *infoPtr, SIZE *size)
+static void COMBOEX_GetComboFontSize (COMBOEX_INFO *infoPtr, SIZE *size)
 {
     HFONT nfont, ofont;
     HDC mydc;
@@ -337,8 +264,7 @@
 }
 
 
-static void
-COMBOEX_CopyItem (COMBOEX_INFO *infoPtr, CBE_ITEMDATA *item, COMBOBOXEXITEMW *cit)
+static void COMBOEX_CopyItem (CBE_ITEMDATA *item, COMBOBOXEXITEMW *cit)
 {
     if (cit->mask & CBEIF_TEXT) {
         /*
@@ -364,12 +290,10 @@
 	cit->iIndent        = item->iIndent;
     if (cit->mask & CBEIF_LPARAM)
 	cit->lParam         = item->lParam;
-
 }
 
 
-static void
-COMBOEX_AdjustEditPos (COMBOEX_INFO *infoPtr)
+static void COMBOEX_AdjustEditPos (COMBOEX_INFO *infoPtr)
 {
     SIZE mysize;
     IMAGEINFO iinfo;
@@ -377,6 +301,7 @@
     RECT rect;
 
     if (!infoPtr->hwndEdit) return;
+
     iinfo.rcImage.left = iinfo.rcImage.right = 0;
     if (infoPtr->himl) {
 	ImageList_GetImageInfo(infoPtr->himl, 0, &iinfo);
@@ -390,22 +315,18 @@
     COMBOEX_GetComboFontSize (infoPtr, &mysize);
     TRACE("Combo font x=%ld, y=%ld\n", mysize.cx, mysize.cy);
     x = xoff + CBE_STARTOFFSET + 1;
-    y = CBE_EXTRA + 1;
     w = rect.right-rect.left - x - GetSystemMetrics(SM_CXVSCROLL) - 1;
     h = mysize.cy + 1;
+    y = rect.bottom - h - 1;
 
     TRACE("Combo client (%d,%d)-(%d,%d), setting Edit to (%d,%d)-(%d,%d)\n",
-	  rect.left, rect.top, rect.right, rect.bottom,
-	  x, y, x + w, y + h);
-    SetWindowPos(infoPtr->hwndEdit, HWND_TOP,
-		 x, y,
-		 w, h,
+	  rect.left, rect.top, rect.right, rect.bottom, x, y, x + w, y + h);
+    SetWindowPos(infoPtr->hwndEdit, HWND_TOP, x, y, w, h,
 		 SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER);
 }
 
 
-static void
-COMBOEX_ReSize (HWND hwnd, COMBOEX_INFO *infoPtr)
+static void COMBOEX_ReSize (COMBOEX_INFO *infoPtr)
 {
     SIZE mysize;
     UINT cy;
@@ -418,15 +339,14 @@
 	cy = max (iinfo.rcImage.bottom - iinfo.rcImage.top, cy);
 	TRACE("upgraded height due to image:  height=%d\n", cy);
     }
-    SendMessageW (hwnd, CB_SETITEMHEIGHT, (WPARAM) -1, (LPARAM) cy);
+    SendMessageW (infoPtr->hwndSelf, CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)cy);
     if (infoPtr->hwndCombo)
         SendMessageW (infoPtr->hwndCombo, CB_SETITEMHEIGHT,
 		      (WPARAM) 0, (LPARAM) cy);
 }
 
 
-static void
-COMBOEX_SetEditText (COMBOEX_INFO *infoPtr, CBE_ITEMDATA *item)
+static void COMBOEX_SetEditText (COMBOEX_INFO *infoPtr, CBE_ITEMDATA *item)
 {
     if (!infoPtr->hwndEdit) return;
     /* native issues the following messages to the {Edit} control */
@@ -441,8 +361,7 @@
 }
 
  
-static CBE_ITEMDATA *
-COMBOEX_FindItem(COMBOEX_INFO *infoPtr, INT index)
+static CBE_ITEMDATA * COMBOEX_FindItem(COMBOEX_INFO *infoPtr, INT index)
 {
     CBE_ITEMDATA *item;
     INT i;
@@ -460,15 +379,20 @@
 	i--;
     }
     if (!item || (i != index)) {
-	FIXME("COMBOBOXEX item structures broken. Please report!\n");
+	ERR("COMBOBOXEX item structures broken. Please report!\n");
 	return 0;
     }
     return item;
 }
 
 
-static void
-COMBOEX_WarnCallBack (CBE_ITEMDATA *item)
+static inline BOOL COMBOEX_HasEdit(COMBOEX_INFO *infoPtr)
+{
+    return infoPtr->hwndEdit;
+}
+ 
+
+static void COMBOEX_WarnCallBack (CBE_ITEMDATA *item)
 {
     if (item->pszText == LPSTR_TEXTCALLBACKW)
 	FIXME("Callback not implemented yet for pszText\n");
@@ -486,25 +410,15 @@
 /* ***  CBEM_xxx message support  *** */
 
 
-static LRESULT
-COMBOEX_DeleteItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static INT COMBOEX_DeleteItem (COMBOEX_INFO *infoPtr, INT index)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-    INT index = (INT) wParam;
     CBE_ITEMDATA *item;
 
-    TRACE("(0x%08x 0x%08lx)\n", wParam, lParam);
+    TRACE("(index=%d)\n", index);
 
     /* if item number requested does not exist then return failure */
-    if ((index > infoPtr->nb_items) || (index < 0)) {
-	ERR("attempt to delete item that does not exist\n");
-	return CB_ERR;
-    }
-
-    if (!(item = COMBOEX_FindItem(infoPtr, index))) {
-	ERR("attempt to delete item that was not found!\n");
-	return CB_ERR;
-    }
+    if ((index > infoPtr->nb_items) || (index < 0)) return CB_ERR;
+    if (!(item = COMBOEX_FindItem(infoPtr, index))) return CB_ERR;
 
     /* doing this will result in WM_DELETEITEM being issued */
     SendMessageW (infoPtr->hwndCombo, CB_DELETESTRING, (WPARAM)index, 0);
@@ -513,106 +427,40 @@
 }
 
 
-inline static LRESULT
-COMBOEX_GetComboControl (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-
-    TRACE("\n");
-
-    return (LRESULT)infoPtr->hwndCombo;
-}
-
-
-inline static LRESULT
-COMBOEX_GetEditControl (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static BOOL COMBOEX_GetItemW (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMW *cit)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-
-    if ((GetWindowLongA (hwnd, GWL_STYLE) & CBS_DROPDOWNLIST) != CBS_DROPDOWN)
-	return 0;
-
-    TRACE("-- 0x%x\n", infoPtr->hwndEdit);
-
-    return (LRESULT)infoPtr->hwndEdit;
-}
-
-
-inline static LRESULT
-COMBOEX_GetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-
-    TRACE("-- 0x%08lx\n", infoPtr->dwExtStyle);
-
-    return (LRESULT)infoPtr->dwExtStyle;
-}
-
-
-inline static LRESULT
-COMBOEX_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-
-    TRACE("-- %p\n", infoPtr->himl);
-
-    return (LRESULT)infoPtr->himl;
-}
-
-
-static LRESULT
-COMBOEX_GetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-    COMBOBOXEXITEMW *cit = (COMBOBOXEXITEMW *) lParam;
-    INT index;
+    INT index = cit->iItem;
     CBE_ITEMDATA *item;
 
-    TRACE("(0x%08x 0x%08lx)\n", wParam, lParam);
-
-    /* get real index of item to insert */
-    index = cit->iItem;
+    TRACE("(...)\n");
 
     /* if item number requested does not exist then return failure */
-    if ((index > infoPtr->nb_items) || (index < -1)) {
-	ERR("attempt to get item that does not exist\n");
-	return 0;
-    }
+    if ((index > infoPtr->nb_items) || (index < -1)) return FALSE;
 
     /* if the item is the edit control and there is no edit control, skip */
-    if ((index == -1) && 
-        ((GetWindowLongA (hwnd, GWL_STYLE) & CBS_DROPDOWNLIST) != CBS_DROPDOWN))
-	    return 0;
+    if ((index == -1) && !COMBOEX_HasEdit(infoPtr)) return FALSE;
 
-    if (!(item = COMBOEX_FindItem(infoPtr, index))) {
-	ERR("attempt to get item that was not found!\n");
-	return 0;
-    }
+    if (!(item = COMBOEX_FindItem(infoPtr, index))) return FALSE;
 
-    COMBOEX_CopyItem (infoPtr, item, cit);
+    COMBOEX_CopyItem (item, cit);
 
     return TRUE;
 }
 
 
-inline static LRESULT
-COMBOEX_GetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static BOOL COMBOEX_GetItemA (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMA *cit)
 {
-    COMBOBOXEXITEMA *cit = (COMBOBOXEXITEMA *) lParam;
     COMBOBOXEXITEMW tmpcit;
-    INT len;
 
-    TRACE("(0x%08x 0x%08lx)\n", wParam, lParam);
+    TRACE("(...)\n");
 
     tmpcit.mask = cit->mask;
     tmpcit.iItem = cit->iItem;
     tmpcit.pszText = 0;
-    COMBOEX_GetItemW (hwnd, wParam, (LPARAM) &tmpcit);
+    if(!COMBOEX_GetItemW (infoPtr, &tmpcit)) return FALSE;
 
-    len = WideCharToMultiByte (CP_ACP, 0, tmpcit.pszText, -1, 0, 0, NULL, NULL);
-    if (len > 0) 
-	WideCharToMultiByte (CP_ACP, 0, tmpcit.pszText, -1, 
-			     cit->pszText, cit->cchTextMax, NULL, NULL);
+    WideCharToMultiByte (CP_ACP, 0, tmpcit.pszText, -1, 
+			 cit->pszText, cit->cchTextMax, NULL, NULL);
 
     cit->iImage = tmpcit.iImage;
     cit->iSelectedImage = tmpcit.iSelectedImage;
@@ -624,44 +472,22 @@
 }
 
 
-inline static LRESULT
-COMBOEX_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-
-    TRACE("%s hwnd=0x%x\n", 
-	   infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
-
-    return infoPtr->bUnicode;
-}
-
-
-inline static LRESULT
-COMBOEX_HasEditChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
+inline static BOOL COMBOEX_HasEditChanged (COMBOEX_INFO *infoPtr)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-
-    if ((GetWindowLongA (hwnd, GWL_STYLE) & CBS_DROPDOWNLIST) != CBS_DROPDOWN)
-	return FALSE;
-    if ((infoPtr->flags & (WCBE_ACTEDIT | WCBE_EDITCHG)) == 
-	(WCBE_ACTEDIT | WCBE_EDITCHG))
-	return TRUE;
-    return FALSE;
+    return COMBOEX_HasEdit(infoPtr) &&
+	   (infoPtr->flags & WCBE_EDITHASCHANGED) == WCBE_EDITHASCHANGED;
 }
 
 
-static LRESULT
-COMBOEX_InsertItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static INT COMBOEX_InsertItemW (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMW *cit)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-    COMBOBOXEXITEMW *cit = (COMBOBOXEXITEMW *) lParam;
     INT index;
     CBE_ITEMDATA *item;
     NMCOMBOBOXEXW nmcit;
 
     TRACE("\n");
 
-    COMBOEX_DumpInput ((COMBOBOXEXITEMA *) cit, TRUE);
+    if (TRACE_ON(comboex)) COMBOEX_DumpInput (cit);
 
     /* get real index of item to insert */
     index = cit->iItem;
@@ -669,7 +495,8 @@
     if (index > infoPtr->nb_items) index = infoPtr->nb_items;
 
     /* get space and chain it in */
-    item = (CBE_ITEMDATA *)COMCTL32_Alloc (sizeof (CBE_ITEMDATA));
+    if(!(item = (CBE_ITEMDATA *)COMCTL32_Alloc (sizeof(*item)))) return -1;
+    
     item->next = NULL;
     item->pszText = NULL;
 
@@ -688,7 +515,7 @@
 	    i--;
 	}
 	if (!moving) {
-	    FIXME("COMBOBOXEX item structures broken. Please report!\n");
+	    ERR("COMBOBOXEX item structures broken. Please report!\n");
 	    COMCTL32_Free(item);
 	    return -1;
 	}
@@ -707,6 +534,7 @@
 	len = strlenW (str);
 	if (len > 0) {
 	    item->pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
+	    //FIXME: what if allocation fails?
 	    strcpyW (item->pszText, str);
 	}
 	else
@@ -714,26 +542,26 @@
         item->cchTextMax   = cit->cchTextMax;
     }
     if (item->mask & CBEIF_IMAGE)
-      item->iImage         = cit->iImage;
+        item->iImage         = cit->iImage;
     if (item->mask & CBEIF_SELECTEDIMAGE)
-      item->iSelectedImage = cit->iSelectedImage;
+        item->iSelectedImage = cit->iSelectedImage;
     if (item->mask & CBEIF_OVERLAY)
-      item->iOverlay       = cit->iOverlay;
+        item->iOverlay       = cit->iOverlay;
     if (item->mask & CBEIF_INDENT)
-      item->iIndent        = cit->iIndent;
+        item->iIndent        = cit->iIndent;
     if (item->mask & CBEIF_LPARAM)
-      item->lParam         = cit->lParam;
+        item->lParam         = cit->lParam;
     infoPtr->nb_items++;
 
     COMBOEX_WarnCallBack (item);
 
-    COMBOEX_DumpItem (item);
+    if (TRACE_ON(comboex)) COMBOEX_DumpItem (item);
 
     SendMessageW (infoPtr->hwndCombo, CB_INSERTSTRING, 
 		  (WPARAM)cit->iItem, (LPARAM)item);
 
     memset (&nmcit.ceItem, 0, sizeof(nmcit.ceItem));
-    COMBOEX_CopyItem (infoPtr, item, &nmcit.ceItem);
+    COMBOEX_CopyItem (item, &nmcit.ceItem);
     COMBOEX_NotifyItem (infoPtr, CBEN_INSERTITEM, &nmcit);
 
     return index;
@@ -741,55 +569,50 @@
 }
 
 
-static LRESULT
-COMBOEX_InsertItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static INT COMBOEX_InsertItemA (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMA *cit)
 {
-    COMBOBOXEXITEMA	*cit = (COMBOBOXEXITEMA *) lParam;
-    COMBOBOXEXITEMW	citW;
-    LRESULT		ret;
+    COMBOBOXEXITEMW citW;
+    INT	ret;
 
     memcpy(&citW,cit,sizeof(COMBOBOXEXITEMA));
     if (cit->mask & CBEIF_TEXT) {
-        LPSTR str;
-	INT len;
+        LPSTR str = cit->pszText;
+	INT len = 0;
 
-        str = cit->pszText;
-        if (!str) str="";
-	len = MultiByteToWideChar (CP_ACP, 0, str, -1, NULL, 0);
+        if (str) len = MultiByteToWideChar (CP_ACP, 0, str, -1, NULL, 0);
 	if (len > 0) {
 	    citW.pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
+	    if (!citW.pszText) return -1;
 	    MultiByteToWideChar (CP_ACP, 0, str, -1, citW.pszText, len);
 	}
     }
-    ret = COMBOEX_InsertItemW(hwnd,wParam,(LPARAM)&citW);;
-
-    if (cit->mask & CBEIF_TEXT)
-	COMCTL32_Free(citW.pszText);
+    ret = COMBOEX_InsertItemW(infoPtr, &citW);;
+    
+    if (citW.pszText) COMCTL32_Free(citW.pszText);
+    
     return ret;
 }
 
 
-static LRESULT
-COMBOEX_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static DWORD 
+COMBOEX_SetExtendedStyle (COMBOEX_INFO *infoPtr, DWORD mask, DWORD style)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
     DWORD dwTemp;
 
-    TRACE("(0x%08x 0x%08lx)\n", wParam, lParam);
+    TRACE("(mask=x%08lx, style=0x%08lx)\n", mask, style);
 
     dwTemp = infoPtr->dwExtStyle;
 
-    if (lParam & (CBES_EX_NOEDITIMAGEINDENT |
+    if (style &  (CBES_EX_NOEDITIMAGEINDENT |
 		  CBES_EX_PATHWORDBREAKPROC |
 		  CBES_EX_NOSIZELIMIT |
 		  CBES_EX_CASESENSITIVE))
-	FIXME("Extended style not implemented %08lx\n", lParam);
+	FIXME("Extended style not implemented %08lx\n", style);
 
-    if ((DWORD)wParam) {
-	infoPtr->dwExtStyle = (infoPtr->dwExtStyle & ~(DWORD)wParam) | (DWORD)lParam;
-    }
+    if (mask)
+	infoPtr->dwExtStyle = (infoPtr->dwExtStyle & ~mask) | style;
     else
-	infoPtr->dwExtStyle = (DWORD)lParam;
+	infoPtr->dwExtStyle = style;
 
     /*
      * native does this for CBES_EX_NOEDITIMAGE state change
@@ -798,95 +621,76 @@
 	(dwTemp & CBES_EX_NOEDITIMAGE)) {
 	/* if state of EX_NOEDITIMAGE changes, invalidate all */
 	TRACE("EX_NOEDITIMAGE state changed to %ld\n",
-	    infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGE);
-	InvalidateRect (hwnd, NULL, TRUE);
+	      infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGE);
+	InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
 	COMBOEX_AdjustEditPos (infoPtr);
 	if (infoPtr->hwndEdit)
 	    InvalidateRect (infoPtr->hwndEdit, NULL, TRUE);
     }
 
-    return (LRESULT)dwTemp;
+    return dwTemp;
 }
 
 
-inline static LRESULT
-COMBOEX_SetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static HIMAGELIST COMBOEX_SetImageList (COMBOEX_INFO *infoPtr, HIMAGELIST himl)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-    HIMAGELIST himlTemp;
+    HIMAGELIST himlTemp = infoPtr->himl;
 
-    TRACE("(0x%08x 0x%08lx)\n", wParam, lParam);
+    TRACE("(...)\n");
 
-    himlTemp = infoPtr->himl;
-    infoPtr->himl = (HIMAGELIST)lParam;
+    infoPtr->himl = himl;
 
-    COMBOEX_ReSize (hwnd, infoPtr);
+    COMBOEX_ReSize (infoPtr);
     InvalidateRect (infoPtr->hwndCombo, NULL, TRUE);
 
     /* reposition the Edit control based on whether icon exists */
     COMBOEX_AdjustEditPos (infoPtr);
-    return (LRESULT)himlTemp;
+    return himlTemp;
 }
 
-static LRESULT
-COMBOEX_SetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static BOOL COMBOEX_SetItemW (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMW *cit)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-    COMBOBOXEXITEMW *cit = (COMBOBOXEXITEMW *) lParam;
-    INT index;
+    INT index = cit->iItem;
     CBE_ITEMDATA *item;
 
-    COMBOEX_DumpInput ((COMBOBOXEXITEMA *) cit, TRUE);
-
-    /* get real index of item to insert */
-    index = cit->iItem;
+    if (TRACE_ON(comboex)) COMBOEX_DumpInput (cit);
 
     /* if item number requested does not exist then return failure */
-    if ((index > infoPtr->nb_items) || (index < -1)) {
-	ERR("attempt to set item that does not exist yet!\n");
-	return 0;
-    }
+    if ((index > infoPtr->nb_items) || (index < -1)) return FALSE;
 
     /* if the item is the edit control and there is no edit control, skip */
-    if ((index == -1) && 
-        ((GetWindowLongA (hwnd, GWL_STYLE) & CBS_DROPDOWNLIST) != CBS_DROPDOWN))
-	    return 0;
+    if ((index == -1) && !COMBOEX_HasEdit(infoPtr)) return FALSE;
 
-    if (!(item = COMBOEX_FindItem(infoPtr, index))) {
-	ERR("attempt to set item that was not found!\n");
-	return 0;
-    }
+    if (!(item = COMBOEX_FindItem(infoPtr, index))) return FALSE;
 
     /* add/change stuff to the internal item structure */ 
     item->mask |= cit->mask;
     if (cit->mask & CBEIF_TEXT) {
-        LPWSTR str;
-	INT len;
-	WCHAR emptystr[1] = {0};
+        LPWSTR str = cit->pszText;
+	INT len = 0;
 
-        str = cit->pszText;
-        if (!str) str=emptystr;
-	len = strlenW(str);
+        if (str) len = strlenW(str);
 	if (len > 0) {
 	    item->pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
-	    strcpyW(item->pszText,str);
+	    if (!item->pszText) return FALSE;
+	    strcpyW(item->pszText, str);
 	}
         item->cchTextMax   = cit->cchTextMax;
     }
     if (cit->mask & CBEIF_IMAGE)
-      item->iImage         = cit->iImage;
+        item->iImage         = cit->iImage;
     if (cit->mask & CBEIF_SELECTEDIMAGE)
-      item->iSelectedImage = cit->iSelectedImage;
+        item->iSelectedImage = cit->iSelectedImage;
     if (cit->mask & CBEIF_OVERLAY)
-      item->iOverlay       = cit->iOverlay;
+        item->iOverlay       = cit->iOverlay;
     if (cit->mask & CBEIF_INDENT)
-      item->iIndent        = cit->iIndent;
+        item->iIndent        = cit->iIndent;
     if (cit->mask & CBEIF_LPARAM)
-      cit->lParam         = cit->lParam;
+        cit->lParam         = cit->lParam;
 
     COMBOEX_WarnCallBack (item);
 
-    COMBOEX_DumpItem (item);
+    if (TRACE_ON(comboex)) COMBOEX_DumpItem (item);
 
     /* if original request was to update edit control, do some fast foot work */
     if (cit->iItem == -1) {
@@ -896,69 +700,61 @@
     return TRUE;
 }
 
-static LRESULT
-COMBOEX_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static BOOL COMBOEX_SetItemA (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMA *cit)
 {
-    COMBOBOXEXITEMA	*cit = (COMBOBOXEXITEMA *) lParam;
     COMBOBOXEXITEMW	citW;
-    LRESULT		ret;
+    BOOL		ret;
 
-    memcpy(&citW,cit,sizeof(COMBOBOXEXITEMA));
+    memcpy(&citW, cit, sizeof(COMBOBOXEXITEMA));
     if (cit->mask & CBEIF_TEXT) {
-        LPSTR str;
-	INT len;
+        LPSTR str = cit->pszText;
+	INT len = 0;
 
         str = cit->pszText;
-        if (!str) str="";
-	len = MultiByteToWideChar (CP_ACP, 0, str, -1, NULL, 0);
+        if (str) len = MultiByteToWideChar (CP_ACP, 0, str, -1, NULL, 0);
 	if (len > 0) {
 	    citW.pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
+	    if (!citW.pszText) return FALSE;
 	    MultiByteToWideChar (CP_ACP, 0, str, -1, citW.pszText, len);
 	}
     }
-    ret = COMBOEX_SetItemW(hwnd,wParam,(LPARAM)&citW);;
+    ret = COMBOEX_SetItemW(infoPtr, &citW);;
+
+    if (citW.pszText) COMCTL32_Free(citW.pszText);
 
-    if (cit->mask & CBEIF_TEXT)
-	COMCTL32_Free(citW.pszText);
     return ret;
 }
 
 
-inline static LRESULT
-COMBOEX_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static BOOL COMBOEX_SetUnicodeFormat (COMBOEX_INFO *infoPtr, BOOL value)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-    BOOL bTemp = infoPtr->bUnicode;
+    BOOL bTemp = infoPtr->unicode;
 
-    TRACE("to %s hwnd=0x%04x, was %s\n", 
-	  ((BOOL)wParam) ? "TRUE" : "FALSE", hwnd,
-	  (bTemp) ? "TRUE" : "FALSE");
+    TRACE("to %s, was %s\n", value ? "TRUE":"FALSE", bTemp ? "TRUE":"FALSE");
 
-    infoPtr->bUnicode = (BOOL)wParam;
+    infoPtr->unicode = value;
 
     return bTemp;
 }
 
 
-
 /* ***  CB_xxx message support  *** */
 
-
-static LRESULT
-COMBOEX_FindStringExact (COMBOEX_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+static INT
+COMBOEX_FindStringExact (COMBOEX_INFO *infoPtr, INT start, LPCSTR str)
 {
     INT i, count;
     CBE_ITEMDATA *item;
     LPWSTR desired = NULL;
-    INT start = (INT) wParam;
 
-    i = MultiByteToWideChar (CP_ACP, 0, (LPSTR)lParam, -1, NULL, 0);
+    i = MultiByteToWideChar (CP_ACP, 0, str, -1, NULL, 0);
     if (i > 0) {
 	desired = (LPWSTR)COMCTL32_Alloc ((i + 1)*sizeof(WCHAR));
-	MultiByteToWideChar (CP_ACP, 0, (LPSTR)lParam, -1, desired, i);
+	if (!desired) return CB_ERR;
+	MultiByteToWideChar (CP_ACP, 0, str, -1, desired, i);
     }
 
-    count = SendMessageW (infoPtr->hwndCombo, CB_GETCOUNT, 0 , 0);
+    count = SendMessageW (infoPtr->hwndCombo, CB_GETCOUNT, 0, 0);
 
     /* now search from after starting loc and wrapping back to start */
     for(i=start+1; i<count; i++) {
@@ -986,65 +782,52 @@
 }
 
 
-static LRESULT
-COMBOEX_GetItemData (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static DWORD COMBOEX_GetItemData (COMBOEX_INFO *infoPtr, INT index)
 {
-    INT index = wParam;
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
     CBE_ITEMDATA *item1, *item2;
-    LRESULT lret = 0;
+    DWORD ret = 0;
 
-    item1 = (CBE_ITEMDATA *)COMBOEX_Forward (hwnd, CB_GETITEMDATA, 
-					     wParam, lParam);
+    item1 = (CBE_ITEMDATA *)COMBOEX_Forward (infoPtr, CB_GETITEMDATA, index, 0);
     if ((item1 != NULL) && ((LRESULT)item1 != CB_ERR)) {
 	item2 = COMBOEX_FindItem (infoPtr, index);
 	if (item2 != item1) {
 	    ERR("data structures damaged!\n");
 	    return CB_ERR;
 	}
-	if (item1->mask & CBEIF_LPARAM)
-	    lret = (LRESULT) item1->lParam;
-	TRACE("returning 0x%08lx\n", lret);
-	return lret;
+	if (item1->mask & CBEIF_LPARAM) ret = item1->lParam;
+	TRACE("returning 0x%08lx\n", ret);
+    } else {
+        ret = (DWORD)item1;
+        TRACE("non-valid result from combo, returning 0x%08lx\n", ret);
     }
-    lret = (LRESULT)item1;
-    TRACE("non-valid result from combo, returning 0x%08lx\n", lret);
-    return lret;
+    return ret;
 }
 
 
-static LRESULT
-COMBOEX_SetCursel (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static INT COMBOEX_SetCursel (COMBOEX_INFO *infoPtr, INT index)
 {
-    INT index = wParam;
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
     CBE_ITEMDATA *item;
-    LRESULT lret;
+    INT sel;
 
-    if (!(item = COMBOEX_FindItem(infoPtr, index))) {
-	/* FIXME: need to clear selection */
-	return CB_ERR;
-    }
+    if (!(item = COMBOEX_FindItem(infoPtr, index)))
+	return SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL, index, 0);
 
     TRACE("selecting item %d text=%s\n", index, (item->pszText) ?
 	  debugstr_w(item->pszText) : "<null>");
     infoPtr->selected = index;
 
-    lret = SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL, wParam, lParam);
+    sel = (INT)SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL, index, 0);
     COMBOEX_SetEditText (infoPtr, item);
-    return lret;
+    return sel;
 }
 
 
-static LRESULT
-COMBOEX_SetItemData (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static DWORD COMBOEX_SetItemData (COMBOEX_INFO *infoPtr, INT index, DWORD data)
 {
-    INT index = wParam;
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
     CBE_ITEMDATA *item1, *item2;
 
-    item1 = (CBE_ITEMDATA *)COMBOEX_Forward (hwnd, CB_GETITEMDATA, 
-					     wParam, lParam);
+    item1 = (CBE_ITEMDATA *)COMBOEX_Forward (infoPtr,CB_GETITEMDATA,index,data);
+    
     if ((item1 != NULL) && ((LRESULT)item1 != CB_ERR)) {
 	item2 = COMBOEX_FindItem (infoPtr, index);
 	if (item2 != item1) {
@@ -1052,8 +835,8 @@
 	    return CB_ERR;
 	}
 	item1->mask |= CBEIF_LPARAM;
-	item1->lParam = lParam;
-	TRACE("setting lparam to 0x%08lx\n", lParam);
+	item1->lParam = data;
+	TRACE("setting lparam to 0x%08lx\n", data);
 	return 0;
     }
     TRACE("non-valid result from combo 0x%08lx\n", (DWORD)item1);
@@ -1061,22 +844,19 @@
 }
 
 
-static LRESULT
-COMBOEX_SetItemHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static INT COMBOEX_SetItemHeight (COMBOEX_INFO *infoPtr, INT index, UINT height)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
     RECT cb_wrect, cbx_wrect, cbx_crect;
-    LRESULT ret = 0;
-    UINT height;
 
     /* First, lets forward the message to the normal combo control
        just like Windows.     */
-    if (infoPtr->hwndCombo)    
-       SendMessageW (infoPtr->hwndCombo, CB_SETITEMHEIGHT, wParam, lParam);
+    if (infoPtr->hwndCombo)
+       if (SendMessageW (infoPtr->hwndCombo, CB_SETITEMHEIGHT,
+			 index, height) == CB_ERR) return CB_ERR;
 
     GetWindowRect (infoPtr->hwndCombo, &cb_wrect);
-    GetWindowRect (hwnd, &cbx_wrect);
-    GetClientRect (hwnd, &cbx_crect);
+    GetWindowRect (infoPtr->hwndSelf, &cbx_wrect);
+    GetClientRect (infoPtr->hwndSelf, &cbx_crect);
     /* the height of comboex as height of the combo + comboex border */ 
     height = cb_wrect.bottom-cb_wrect.top
              + cbx_wrect.bottom-cbx_wrect.top
@@ -1087,59 +867,51 @@
     TRACE("CB window=(%d,%d)-(%d,%d), EX setting=(0,0)-(%d,%d)\n",
 	  cb_wrect.left, cb_wrect.top, cb_wrect.right, cb_wrect.bottom,
 	  cbx_wrect.right-cbx_wrect.left, height);
-    SetWindowPos (hwnd, HWND_TOP, 0, 0,
-		  cbx_wrect.right-cbx_wrect.left,
-		  height,
+    SetWindowPos (infoPtr->hwndSelf, HWND_TOP, 0, 0,
+		  cbx_wrect.right-cbx_wrect.left, height,
 		  SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE);
 
-    return ret;
+    return 0;
 }
 
 
 /* ***  WM_xxx message support  *** */
 
 
-static LRESULT
-COMBOEX_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static LRESULT COMBOEX_Create (HWND hwnd, LPCREATESTRUCTA cs)
 {
-    LPCREATESTRUCTA cs = (LPCREATESTRUCTA) lParam;
+    WCHAR COMBOBOX[] = { 'C', 'o', 'm', 'b', 'o', 'B', 'o', 'x', 0 };
+    WCHAR EDIT[] = { 'E', 'D', 'I', 'T', 0 };
+    WCHAR NIL[] = { 0 };
     COMBOEX_INFO *infoPtr;
     DWORD dwComboStyle;
-    LOGFONTA mylogfont;
-    CBE_ITEMDATA *item;
+    LOGFONTW mylogfont;
     RECT wnrc1, clrc1, cmbwrc;
-    LONG test;
     INT i;
 
     /* allocate memory for info structure */
     infoPtr = (COMBOEX_INFO *)COMCTL32_Alloc (sizeof(COMBOEX_INFO));
-    if (infoPtr == NULL) {
-	ERR("could not allocate info memory!\n");
-	return 0;
-    }
+    if (!infoPtr) return -1;
 
     /* initialize info structure */
-
-    infoPtr->items    = NULL;
-    infoPtr->nb_items = 0;
+    /* note that infoPtr is allocated zero-filled */
+    
     infoPtr->hwndSelf = hwnd;
     infoPtr->selected = -1;
 
-    infoPtr->bUnicode = IsWindowUnicode (hwnd);
+    infoPtr->unicode = IsWindowUnicode (hwnd);
 
-    i = SendMessageA(GetParent (hwnd),
-		     WM_NOTIFYFORMAT, hwnd, NF_QUERY);
-    if ((i < NFR_ANSI) || (i > NFR_UNICODE)) {
-	ERR("wrong response to WM_NOTIFYFORMAT (%d), assuming ANSI\n",
-	    i);
+    i = SendMessageW(GetParent (hwnd), WM_NOTIFYFORMAT, hwnd, NF_QUERY);
+    if ((i != NFR_ANSI) && (i != NFR_UNICODE)) {
+	WARN("wrong response to WM_NOTIFYFORMAT (%d), assuming ANSI\n", i);
 	i = NFR_ANSI;
     }
-    infoPtr->NtfUnicode = (i == NFR_UNICODE) ? 1 : 0;
+    infoPtr->NtfUnicode = (i == NFR_UNICODE);
 
-    SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
+    SetWindowLongW (hwnd, 0, (DWORD)infoPtr);
 
     /* create combo box */
-    dwComboStyle = GetWindowLongA (hwnd, GWL_STYLE) &
+    dwComboStyle = GetWindowLongW (hwnd, GWL_STYLE) &
 			(CBS_SIMPLE|CBS_DROPDOWN|CBS_DROPDOWNLIST|WS_CHILD);
 
     GetWindowRect(hwnd, &wnrc1);
@@ -1159,15 +931,15 @@
     /* We also need to place the edit control at the proper location    */
     /* (allow space for the icons).                                     */
 
-    infoPtr->hwndCombo = CreateWindowA ("ComboBox", "",
+    infoPtr->hwndCombo = CreateWindowW (COMBOBOX, NIL,
 			 /* following line added to match native */
                          WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VSCROLL |
                          CBS_NOINTEGRALHEIGHT | CBS_DROPDOWNLIST | 
 			 /* was base and is necessary */
 			 WS_CHILD | WS_VISIBLE | CBS_OWNERDRAWFIXED | dwComboStyle,
 			 cs->y, cs->x, cs->cx, cs->cy, hwnd,
-			 (HMENU) GetWindowLongA (hwnd, GWL_ID),
-			 GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
+			 (HMENU) GetWindowLongW (hwnd, GWL_ID),
+			 GetWindowLongW (hwnd, GWL_HINSTANCE), NULL);
 
     /* 
      * native does the following at this point according to trace:
@@ -1181,11 +953,8 @@
      * Setup a property to hold the pointer to the COMBOBOXEX 
      * data structure.
      */
-    test = GetPropA(infoPtr->hwndCombo, (LPCSTR)(LONG)ComboExInfo);
-    if (!test || ((COMBOEX_INFO *)test != infoPtr)) {
-	SetPropA(infoPtr->hwndCombo, "CC32SubclassInfo", (LONG)infoPtr);
-    }
-    infoPtr->prevComboWndProc = (WNDPROC)SetWindowLongA(infoPtr->hwndCombo, 
+    SetPropA(infoPtr->hwndCombo, COMBOEX_SUBCLASS_PROP, hwnd);
+    infoPtr->prevComboWndProc = (WNDPROC)SetWindowLongW(infoPtr->hwndCombo, 
 	                        GWL_WNDPROC, (LONG)COMBOEX_ComboWndProc);
     infoPtr->font = SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0);
 
@@ -1195,12 +964,12 @@
      * It is created only for CBS_DROPDOWN style
      */
     if ((cs->style & CBS_DROPDOWNLIST) == CBS_DROPDOWN) {
-	infoPtr->hwndEdit = CreateWindowExA (0, "EDIT", "",
+	infoPtr->hwndEdit = CreateWindowExW (0, EDIT, NIL,
 		    WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | ES_AUTOHSCROLL,
 		    0, 0, 0, 0,  /* will set later */
 		    infoPtr->hwndCombo, 
-		    (HMENU) GetWindowLongA (hwnd, GWL_ID),
-		    GetWindowLongA (hwnd, GWL_HINSTANCE),
+		    (HMENU) GetWindowLongW (hwnd, GWL_ID),
+		    GetWindowLongW (hwnd, GWL_HINSTANCE),
 		    NULL);
 
 	/* native does the following at this point according to trace:
@@ -1214,27 +983,20 @@
 	 * Setup a property to hold the pointer to the COMBOBOXEX 
 	 * data structure.
 	 */
-	test = GetPropA(infoPtr->hwndEdit, (LPCSTR)(LONG)ComboExInfo);
-	if (!test || ((COMBOEX_INFO *)test != infoPtr)) {
-	    SetPropA(infoPtr->hwndEdit, "CC32SubclassInfo", (LONG)infoPtr);
-	}
-	infoPtr->prevEditWndProc = (WNDPROC)SetWindowLongA(infoPtr->hwndEdit, 
+        SetPropA(infoPtr->hwndEdit, COMBOEX_SUBCLASS_PROP, hwnd);
+	infoPtr->prevEditWndProc = (WNDPROC)SetWindowLongW(infoPtr->hwndEdit, 
 				 GWL_WNDPROC, (LONG)COMBOEX_EditWndProc);
 	infoPtr->font = SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0);
     }
-    else {
-	infoPtr->hwndEdit = 0;
-	infoPtr->font = 0;
-    }
 
     /*
      * Locate the default font if necessary and then set it in
      * all associated controls
      */
     if (!infoPtr->font) {
-	SystemParametersInfoA (SPI_GETICONTITLELOGFONT, sizeof(mylogfont), 
+	SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof(mylogfont), 
 			       &mylogfont, 0);
-	infoPtr->font = infoPtr->hDefaultFont = CreateFontIndirectA (&mylogfont);
+	infoPtr->font = infoPtr->defaultFont = CreateFontIndirectW (&mylogfont);
     }
     SendMessageW (infoPtr->hwndCombo, WM_SETFONT, (WPARAM)infoPtr->font, 0);
     if (infoPtr->hwndEdit) {
@@ -1242,7 +1004,7 @@
 	SendMessageW (infoPtr->hwndEdit, EM_SETMARGINS, (WPARAM)EC_USEFONTINFO, 0);
     }
 
-    COMBOEX_ReSize (hwnd, infoPtr);
+    COMBOEX_ReSize (infoPtr);
 
     /* Above is fairly certain, below is much less certain. */
 
@@ -1268,37 +1030,37 @@
 
     /*
      * Create an item structure to represent the data in the 
-     * EDIT control.
+     * EDIT control. It is allocated zero-filled.
      */
-    item = (CBE_ITEMDATA *)COMCTL32_Alloc (sizeof (CBE_ITEMDATA));
-    item->next = NULL;
-    item->pszText = NULL;
-    item->mask = 0;
-    infoPtr->edit = item;
+    infoPtr->edit = (CBE_ITEMDATA *)COMCTL32_Alloc (sizeof (CBE_ITEMDATA));
+    //FIXME: what if allocation failed?
 
     return 0;
 }
 
 
-inline static LRESULT
-COMBOEX_Command (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static LRESULT COMBOEX_Command (COMBOEX_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 {
     LRESULT lret;
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
     INT command = HIWORD(wParam);
     CBE_ITEMDATA *item = 0;
     WCHAR wintext[520];
     INT cursel, n, oldItem;
     NMCBEENDEDITW cbeend;
     DWORD oldflags;
+    HWND parent = GetParent (infoPtr->hwndSelf);
 
     TRACE("for command %d\n", command);
 
     switch (command)
     {
     case CBN_DROPDOWN:
-	SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 
-			     (LPARAM)hwnd);
+	SetFocus (infoPtr->hwndCombo);
+	ShowWindow (infoPtr->hwndEdit, SW_HIDE);
+	return SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
+	
+    case CBN_CLOSEUP:
+	SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
 	/*
 	 * from native trace of first dropdown after typing in URL in IE4 
 	 *  CB_GETCURSEL(Combo)
@@ -1312,6 +1074,9 @@
 	 *  SetFocus(Combo)
 	 * the rest is supposition  
 	 */
+	ShowWindow (infoPtr->hwndEdit, SW_SHOW);
+	InvalidateRect (infoPtr->hwndCombo, 0, TRUE);
+	InvalidateRect (infoPtr->hwndEdit, 0, TRUE);
 	cursel = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0);
 	if (cursel == -1) {
 	    /* find match from edit against those in Combobox */
@@ -1366,7 +1131,7 @@
 	cursel = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0);
 	if ((oldflags & WCBE_EDITCHG) || (cursel != infoPtr->selected)) {
 	    infoPtr->selected = cursel;
-	    SendMessageW (hwnd, CB_SETCURSEL, cursel, 0);
+	    SendMessageW (infoPtr->hwndSelf, CB_SETCURSEL, cursel, 0);
 	    SetFocus(infoPtr->hwndCombo);
 	}
 	return 0;
@@ -1392,16 +1157,14 @@
 	}
 	infoPtr->selected = oldItem;
 	COMBOEX_SetEditText (infoPtr, item);
-	return SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 
-			     (LPARAM)hwnd);
+	return SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
 
     case CBN_SELENDOK:
 	/* 
 	 * We have to change the handle since we are the control
 	 * issuing the message. IE4 depends on this.
 	 */
-	return SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 
-			     (LPARAM)hwnd);
+	return SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
 
     case CBN_KILLFOCUS:
 	/*
@@ -1415,8 +1178,7 @@
 	 *  InvalidateRect(Combo, 0, 0)
 	 *  return 0
 	 */
-	SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 
-			     (LPARAM)hwnd);
+	SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
 	if (infoPtr->flags & WCBE_ACTEDIT) {
 	    GetWindowTextW (infoPtr->hwndEdit, wintext, 260);
 	    cbeend.fChanged = (infoPtr->flags & WCBE_EDITCHG);
@@ -1435,7 +1197,6 @@
 	InvalidateRect (infoPtr->hwndCombo, 0, 0);
 	return 0;
 
-    case CBN_CLOSEUP:
     default:
 	/* 
 	 * We have to change the handle since we are the control
@@ -1443,8 +1204,7 @@
 	 * We also need to set the focus back to the Edit control
 	 * after passing the command to the parent of the ComboEx.
 	 */
-	lret = SendMessageW (GetParent (hwnd), WM_COMMAND, wParam, 
-			     (LPARAM)hwnd);
+	lret = SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
 	if (infoPtr->hwndEdit)
 	    SetFocus(infoPtr->hwndEdit);
 	return lret;
@@ -1453,14 +1213,11 @@
 }
 
 
-inline static LRESULT
-COMBOEX_WM_DeleteItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static BOOL COMBOEX_WM_DeleteItem (COMBOEX_INFO *infoPtr, DELETEITEMSTRUCT *dis)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-    DELETEITEMSTRUCT *dis = (DELETEITEMSTRUCT *)lParam;
     CBE_ITEMDATA *item, *olditem;
-    INT i;
     NMCOMBOBOXEXW nmcit;
+    INT i;
 
     TRACE("CtlType=%08x, CtlID=%08x, itemID=%08x, hwnd=%x, data=%08lx\n",
 	  dis->CtlType, dis->CtlID, dis->itemID, dis->hwndItem, dis->itemData);
@@ -1483,7 +1240,7 @@
 	    i--;
 	}
 	if (!item->next || (i != dis->itemID)) {
-	    FIXME("COMBOBOXEX item structures broken. Please report!\n");
+	    ERR("COMBOBOXEX item structures broken. Please report!\n");
 	    return FALSE;
 	}
 	olditem = item->next;
@@ -1492,33 +1249,29 @@
     infoPtr->nb_items--;
 
     memset (&nmcit.ceItem, 0, sizeof(nmcit.ceItem));
-    COMBOEX_CopyItem (infoPtr, olditem, &nmcit.ceItem);
+    COMBOEX_CopyItem (olditem, &nmcit.ceItem);
     COMBOEX_NotifyItem (infoPtr, CBEN_DELETEITEM, &nmcit);
 
-    if (olditem->pszText)
-	COMCTL32_Free(olditem->pszText);
+    if (olditem->pszText) COMCTL32_Free(olditem->pszText);
     COMCTL32_Free(olditem);
 
     return TRUE;
-
 }
 
 
-inline static LRESULT
-COMBOEX_DrawItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static LRESULT COMBOEX_DrawItem (COMBOEX_INFO *infoPtr, DRAWITEMSTRUCT *dis)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-    DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
+    WCHAR nil[] = { 0 };
     CBE_ITEMDATA *item = 0;
     SIZE txtsize;
     RECT rect;
-    LPWSTR str;
+    LPCWSTR str = nil;
     int drawimage, drawstate;
     UINT xbase, x, y;
     UINT xioff = 0;               /* size and spacer of image if any */
     IMAGEINFO iinfo;
     INT len;
-    COLORREF nbkc, ntxc;
+    COLORREF nbkc, ntxc, bkc, txc;
 
     if (!IsWindowEnabled(infoPtr->hwndCombo)) return 0;
 
@@ -1560,7 +1313,7 @@
 	    /* testing */
 	    {
 		RECT exrc, cbrc, edrc;
-		GetWindowRect (hwnd, &exrc);
+		GetWindowRect (infoPtr->hwndSelf, &exrc);
 		GetWindowRect (infoPtr->hwndCombo, &cbrc);
 		edrc.left=edrc.top=edrc.right=edrc.bottom=-1;
 		if (infoPtr->hwndEdit)
@@ -1582,12 +1335,10 @@
 
     /* If draw item is -1 (edit control) setup the item pointer */
     if (dis->itemID == 0xffffffff) {
-	CHAR str[260];
-	INT wlen, alen;
-
 	item = infoPtr->edit;
 
 	if (infoPtr->hwndEdit) {
+	    INT len;
 
 	    /* free previous text of edit item */
 	    if (item->pszText) {
@@ -1595,32 +1346,30 @@
 		item->pszText = 0;
 		item->mask &= ~CBEIF_TEXT;
 	    }
-	    alen = SendMessageA (infoPtr->hwndEdit, WM_GETTEXT, 260, (LPARAM)&str);
-	    TRACE("edit control hwndEdit=%0x, text len=%d str=<%s>\n",
-		  infoPtr->hwndEdit, alen, str);
-	    if (alen > 0) {
+	    if( (len = GetWindowTextLengthW(infoPtr->hwndEdit)) ) {
 		item->mask |= CBEIF_TEXT;
-		wlen = MultiByteToWideChar (CP_ACP, 0, str, -1, NULL, 0);
-		if (wlen > 0) {
-		    item->pszText = (LPWSTR)COMCTL32_Alloc ((wlen + 1)*sizeof(WCHAR));
-		    MultiByteToWideChar (CP_ACP, 0, str, -1, item->pszText, wlen);
-		}
+		item->pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
+		//FIXME: what if alloc failed?
+		GetWindowTextW(infoPtr->hwndEdit, item->pszText, len+1);
+	    
+	       TRACE("edit control hwndEdit=%0x, text len=%d str=%s\n",
+		     infoPtr->hwndEdit, len, debugstr_w(item->pszText));
 	    }
 	}
     }
 
+
     /* if the item pointer is not set, then get the data and locate it */
     if (!item) {
 	item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo,
 			     CB_GETITEMDATA, (WPARAM)dis->itemID, 0);
-	if (item == (CBE_ITEMDATA *)CB_ERR)
-	    {
-		FIXME("invalid item for id %d \n",dis->itemID);
-		return 0;
-	    }
+	if (item == (CBE_ITEMDATA *)CB_ERR) {
+	    ERR("invalid item for id %d \n", dis->itemID);
+	    return 0;
+	}
     }
 
-    COMBOEX_DumpItem (item);
+    if (TRACE_ON(comboex)) COMBOEX_DumpItem (item);
 
     xbase = CBE_STARTOFFSET;
     if ((item->mask & CBEIF_INDENT) && (dis->itemState & ODS_COMBOEXLBOX))
@@ -1630,38 +1379,16 @@
 	xioff = (iinfo.rcImage.right - iinfo.rcImage.left + CBE_SEP);
     }
 
-    switch (dis->itemAction) {
-    case ODA_FOCUS:
-        if (dis->itemState & ODS_SELECTED /*1*/) {
-	    if ((item->mask & CBEIF_TEXT) && item->pszText) {
-		RECT rect2;
-
-	        len = strlenW (item->pszText);
-		GetTextExtentPointW (dis->hDC, item->pszText, len, &txtsize);
-		rect.left = xbase + xioff - 1;
-		rect.right = rect.left + txtsize.cx + 2;
-		rect.top = dis->rcItem.top;
-		rect.bottom = dis->rcItem.bottom;
-		GetClipBox (dis->hDC, &rect2);
-		TRACE("drawing item %d focus, rect=(%d,%d)-(%d,%d)\n",
-		      dis->itemID, rect.left, rect.top,
-		      rect.right, rect.bottom);
-		TRACE("                      clip=(%d,%d)-(%d,%d)\n",
-		      rect2.left, rect2.top,
-		      rect2.right, rect2.bottom);
+    /* setup pointer to text to be drawn */
+    if (item && (item->mask & CBEIF_TEXT) && item->pszText)
+	str = item->pszText;
+    else
+	str = nil;
 
-		DrawFocusRect(dis->hDC, &rect);
-	    }
-	    else {
-		FIXME("ODA_FOCUS and ODS_SELECTED but no text\n");
-	    }
-	}
-	else {
-	    FIXME("ODA_FOCUS but not ODS_SELECTED\n");
-	}
-        break;
-    case ODA_SELECT:
-    case ODA_DRAWENTIRE:
+    len = strlenW (str);
+    GetTextExtentPoint32W (dis->hDC, str, len, &txtsize);
+    
+    if (dis->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)) {
         drawimage = -1;
 	drawstate = ILD_NORMAL;
 	if (!(infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGE)) {
@@ -1677,7 +1404,7 @@
 	    }
 	    else {
 		/* drawing combo/edit entry */
-		if (infoPtr->hwndEdit) {
+		if (IsWindowVisible(infoPtr->hwndEdit)) {
 		    /* if we have an edit control, the slave the 
                      * selection state to the Edit focus state 
 		     */
@@ -1705,21 +1432,14 @@
 			    xbase, dis->rcItem.top, drawstate);
 	}
 
-	/* setup pointer to text to be drawn */
-	if ((item->mask & CBEIF_TEXT) && item->pszText)
-	    str = item->pszText;
-	else
-	    str = (LPWSTR) L"";
-
 	/* now draw the text */
-	len = lstrlenW (str);
-	GetTextExtentPointW (dis->hDC, str, len, &txtsize);
+	if (!IsWindowVisible (infoPtr->hwndEdit)) {
 	nbkc = GetSysColor ((dis->itemState & ODS_SELECTED) ?
 			    COLOR_HIGHLIGHT : COLOR_WINDOW);
-	SetBkColor (dis->hDC, nbkc);
+	bkc = SetBkColor (dis->hDC, nbkc);
 	ntxc = GetSysColor ((dis->itemState & ODS_SELECTED) ?
 			    COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT);
-	SetTextColor (dis->hDC, ntxc);
+	txc = SetTextColor (dis->hDC, ntxc);
 	x = xbase + xioff;
 	y = dis->rcItem.top +
 	    (dis->rcItem.bottom - dis->rcItem.top - txtsize.cy) / 2;
@@ -1731,30 +1451,25 @@
 	      dis->itemID, rect.left, rect.top, rect.right, rect.bottom);
 	ExtTextOutW (dis->hDC, x, y, ETO_OPAQUE | ETO_CLIPPED,
 		     &rect, str, len, 0);
-	if (dis->itemState & ODS_FOCUS) {
-	    rect.top -= 1;
-	    rect.bottom += 1;
-	    rect.left -= 1;
-	    rect.right += 1;
-	    TRACE("drawing item %d focus after text, rect=(%d,%d)-(%d,%d)\n",
-		  dis->itemID, rect.left, rect.top, rect.right, rect.bottom);
-	    DrawFocusRect (dis->hDC, &rect);
+	SetBkColor (dis->hDC, bkc);
+	SetTextColor (dis->hDC, txc);
 	}
-	break;
-    default:
-        FIXME("unknown action hwnd=%08x, wparam=%08x, lparam=%08lx, action=%d\n", 
-	      hwnd, wParam, lParam, dis->itemAction);
+    }
+    
+    if (dis->itemAction & ODA_FOCUS) {
+	rect.left = xbase + xioff - 1;
+	rect.right = rect.left + txtsize.cx + 2;
+	rect.top = dis->rcItem.top;
+	rect.bottom = dis->rcItem.bottom;
+	DrawFocusRect(dis->hDC, &rect);
     }
 
     return 0;
 }
 
 
-static LRESULT
-COMBOEX_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static LRESULT COMBOEX_Destroy (COMBOEX_INFO *infoPtr)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-
     if (infoPtr->hwndCombo)
 	DestroyWindow (infoPtr->hwndCombo);
 
@@ -1774,24 +1489,23 @@
 	    COMCTL32_Free (this);
 	    this = next;
 	}
+	infoPtr->items = 0;
     }
 
-    if (infoPtr->hDefaultFont) DeleteObject (infoPtr->hDefaultFont);
+    if (infoPtr->defaultFont) 
+	DeleteObject (infoPtr->defaultFont);
 
     /* free comboex info data */
     COMCTL32_Free (infoPtr);
-    SetWindowLongA (hwnd, 0, 0);
+    SetWindowLongW (infoPtr->hwndSelf, 0, 0);
     return 0;
 }
 
 
-static LRESULT
-COMBOEX_MeasureItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static LRESULT COMBOEX_MeasureItem (COMBOEX_INFO *infoPtr, MEASUREITEMSTRUCT *mis)
 {
-    /*COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);*/
-    MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *) lParam;
-    HDC hdc;
     SIZE mysize;
+    HDC hdc;
 
     hdc = GetDC (0);
     GetTextExtentPointA (hdc, "W", 1, &mysize);
@@ -1799,62 +1513,49 @@
     mis->itemHeight = mysize.cy + CBE_EXTRA;
 
     TRACE("adjusted height hwnd=%08x, height=%d\n",
-	  hwnd, mis->itemHeight);
+	  infoPtr->hwndSelf, mis->itemHeight);
 
     return 0;
 }
 
 
-static LRESULT
-COMBOEX_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static LRESULT COMBOEX_NCCreate (HWND hwnd)
 {
     /* WARNING: The COMBOEX_INFO structure is not yet created */
     DWORD oldstyle, newstyle;
 
-    oldstyle = (DWORD)GetWindowLongA (hwnd, GWL_STYLE);
+    oldstyle = (DWORD)GetWindowLongW (hwnd, GWL_STYLE);
     newstyle = oldstyle & ~(WS_VSCROLL | WS_HSCROLL);
     if (newstyle != oldstyle) {
 	TRACE("req style %08lx, reseting style %08lx\n",
 	      oldstyle, newstyle);
-	SetWindowLongA (hwnd, GWL_STYLE, newstyle);
+	SetWindowLongW (hwnd, GWL_STYLE, newstyle);
     }
     return 1;
 }
 
 
-static LRESULT
-COMBOEX_NotifyFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static LRESULT COMBOEX_NotifyFormat (COMBOEX_INFO *infoPtr, LPARAM lParam)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-    INT i;
-
     if (lParam == NF_REQUERY) {
-	i = SendMessageA(GetParent (hwnd),
+	INT i = SendMessageW(GetParent (infoPtr->hwndSelf),
 			 WM_NOTIFYFORMAT, infoPtr->hwndSelf, NF_QUERY);
 	if ((i < NFR_ANSI) || (i > NFR_UNICODE)) {
-	    ERR("wrong response to WM_NOTIFYFORMAT (%d), assuming ANSI\n",
-		i);
+	    ERR("wrong response to WM_NOTIFYFORMAT (%d), set to ANSI\n", i);
 	    i = NFR_ANSI;
 	}
 	infoPtr->NtfUnicode = (i == NFR_UNICODE) ? 1 : 0;
 	return (LRESULT)i;
     }
-    return (LRESULT)((infoPtr->bUnicode) ? NFR_UNICODE : NFR_ANSI);
+    return (LRESULT)(infoPtr->unicode ? NFR_UNICODE : NFR_ANSI);
 }
 
 
-static LRESULT
-COMBOEX_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static LRESULT COMBOEX_Size (COMBOEX_INFO *infoPtr, INT width, INT height)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
-    RECT rect;
-
-    GetWindowRect (hwnd, &rect);
-    TRACE("my rect (%d,%d)-(%d,%d)\n",
-	  rect.left, rect.top, rect.right, rect.bottom);
+    TRACE("(width=%d, height=%d)\n", width, height); 
 
-    MoveWindow (infoPtr->hwndCombo, 0, 0, rect.right -rect.left,
-		  rect.bottom - rect.top, TRUE);
+    MoveWindow (infoPtr->hwndCombo, 0, 0, width, height, TRUE);
 
     COMBOEX_AdjustEditPos (infoPtr);
 
@@ -1862,16 +1563,13 @@
 }
 
 
-static LRESULT
-COMBOEX_WindowPosChanging (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static LRESULT COMBOEX_WindowPosChanging (COMBOEX_INFO *infoPtr, WINDOWPOS *wp)
 {
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
     RECT cbx_wrect, cbx_crect, cb_wrect;
     UINT width, height;
-    WINDOWPOS *wp = (WINDOWPOS *)lParam;
 
-    GetWindowRect (hwnd, &cbx_wrect);
-    GetClientRect (hwnd, &cbx_crect);
+    GetWindowRect (infoPtr->hwndSelf, &cbx_wrect);
+    GetClientRect (infoPtr->hwndSelf, &cbx_crect);
     GetWindowRect (infoPtr->hwndCombo, &cb_wrect);
 
     /* width is winpos value + border width of comboex */
@@ -1912,10 +1610,11 @@
 static LRESULT WINAPI
 COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-    COMBOEX_INFO *infoPtr = (COMBOEX_INFO *)GetPropA (hwnd, (LPCSTR)(LONG) ComboExInfo);
+    HWND hwndComboex = (HWND)GetPropA(hwnd, COMBOEX_SUBCLASS_PROP);
+    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwndComboex);
     NMCBEENDEDITW cbeend;
     WCHAR edit_text[260];
-    COLORREF nbkc, obkc;
+    COLORREF obkc;
     HDC hDC;
     RECT rect;
     LRESULT lret;
@@ -1928,30 +1627,29 @@
     switch (uMsg)
     {
 
-    case WM_CHAR:
+	case WM_CHAR:
 	    /* handle (ignore) the return character */
 	    if (wParam == VK_RETURN) return 0;
 	    /* all other characters pass into the real Edit */
-	    return CallWindowProcA (infoPtr->prevEditWndProc, 
+	    return CallWindowProcW (infoPtr->prevEditWndProc, 
 				   hwnd, uMsg, wParam, lParam);
 
-    case WM_ERASEBKGND:
+	case WM_ERASEBKGND:
 	    /*
 	     * The following was determined by traces of the native 
 	     */
             hDC = (HDC) wParam;
-	    nbkc = GetSysColor (COLOR_WINDOW);
-	    obkc = SetBkColor (hDC, nbkc);
+	    obkc = SetBkColor (hDC, GetSysColor (COLOR_WINDOW));
             GetClientRect (hwnd, &rect);
 	    TRACE("erasing (%d,%d)-(%d,%d)\n",
 		  rect.left, rect.top, rect.right, rect.bottom);
 	    ExtTextOutW (hDC, 0, 0, ETO_OPAQUE, &rect, 0, 0, 0);
             SetBkColor (hDC, obkc);
-	    return CallWindowProcA (infoPtr->prevEditWndProc, 
+	    return CallWindowProcW (infoPtr->prevEditWndProc, 
 				   hwnd, uMsg, wParam, lParam);
 
-    case WM_KEYDOWN: {
-	    INT oldItem, selected;
+	case WM_KEYDOWN: {
+	    INT oldItem, selected, step = 1;
 	    CBE_ITEMDATA *item;
 
 	    switch ((INT)wParam)
@@ -1989,7 +1687,7 @@
 		    TRACE("Notify requested abort of change\n");
 		    return 0;
 		}
-		oldItem = SendMessageW (infoPtr->hwndCombo,CB_GETCURSEL, 0, 0);
+		oldItem = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0);
 		InvalidateRect (infoPtr->hwndCombo, 0, 0);
 		if (!(item = COMBOEX_FindItem(infoPtr, oldItem))) {
 		    ERR("item %d not found. Problem!\n", oldItem);
@@ -2064,21 +1762,29 @@
 		SetFocus(infoPtr->hwndEdit);
 		break;
 
+	    case VK_UP:
+		step = -1;
+	    case VK_DOWN:
+		/* by default, step is 1 */
+		oldItem = SendMessageW (infoPtr->hwndSelf, CB_GETCURSEL, 0, 0);
+		if (oldItem >= 0 && oldItem + step >= 0)
+		    SendMessageW (infoPtr->hwndSelf, CB_SETCURSEL, oldItem + step, 0);
+	    	return 0;
 	    default:
-		return CallWindowProcA (infoPtr->prevEditWndProc,
+		return CallWindowProcW (infoPtr->prevEditWndProc,
 				       hwnd, uMsg, wParam, lParam);
 	    }
 	    return 0;
             }
 
-    case WM_SETFOCUS:
+	case WM_SETFOCUS:
 	    /* remember the focus to set state of icon */
-	    lret = CallWindowProcA (infoPtr->prevEditWndProc, 
+	    lret = CallWindowProcW (infoPtr->prevEditWndProc, 
 				   hwnd, uMsg, wParam, lParam);
 	    infoPtr->flags |= WCBE_EDITFOCUSED;
 	    return lret;
 
-    case WM_KILLFOCUS:
+	case WM_KILLFOCUS:
 	    /* 
 	     * do NOTIFY CBEN_ENDEDIT with CBENF_KILLFOCUS
 	     */
@@ -2096,8 +1802,8 @@
 	    }
 	    /* fall through */
 
-    default:
-	    return CallWindowProcA (infoPtr->prevEditWndProc, 
+	default:
+	    return CallWindowProcW (infoPtr->prevEditWndProc, 
 				   hwnd, uMsg, wParam, lParam);
     }
     return 0;
@@ -2107,10 +1813,11 @@
 static LRESULT WINAPI
 COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-    COMBOEX_INFO *infoPtr = (COMBOEX_INFO *)GetPropA (hwnd, (LPCSTR)(LONG) ComboExInfo);
+    HWND hwndComboex = (HWND)GetPropA(hwnd, COMBOEX_SUBCLASS_PROP);
+    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwndComboex);
     NMCBEENDEDITW cbeend;
     NMMOUSE nmmse;
-    COLORREF nbkc, obkc;
+    COLORREF obkc;
     HDC hDC;
     HWND focusedhwnd;
     RECT rect;
@@ -2125,7 +1832,7 @@
     {
 
     case CB_FINDSTRINGEXACT:
-	    return COMBOEX_FindStringExact (infoPtr, wParam, lParam);
+	    return COMBOEX_FindStringExact (infoPtr, (INT)wParam, (LPCSTR)lParam);
 
     case WM_DRAWITEM:
 	    /*
@@ -2134,7 +1841,7 @@
 	     * that ComboEx knows this is listbox.
 	     */
 	    ((DRAWITEMSTRUCT *)lParam)->itemState |= ODS_COMBOEXLBOX;
-	    return CallWindowProcA (infoPtr->prevComboWndProc, 
+	    return CallWindowProcW (infoPtr->prevComboWndProc, 
 				   hwnd, uMsg, wParam, lParam);
 
     case WM_ERASEBKGND:
@@ -2142,14 +1849,13 @@
 	     * The following was determined by traces of the native 
 	     */
             hDC = (HDC) wParam;
-	    nbkc = GetSysColor (COLOR_WINDOW);
-	    obkc = SetBkColor (hDC, nbkc);
+	    obkc = SetBkColor (hDC, GetSysColor (COLOR_WINDOW));
             GetClientRect (hwnd, &rect);
 	    TRACE("erasing (%d,%d)-(%d,%d)\n",
 		  rect.left, rect.top, rect.right, rect.bottom);
 	    ExtTextOutW (hDC, 0, 0, ETO_OPAQUE, &rect, 0, 0, 0);
             SetBkColor (hDC, obkc);
-	    return CallWindowProcA (infoPtr->prevComboWndProc, 
+	    return CallWindowProcW (infoPtr->prevComboWndProc, 
 				   hwnd, uMsg, wParam, lParam);
 
     case WM_SETCURSOR:
@@ -2164,7 +1870,7 @@
 	    nmmse.pt.y = 0;
 	    nmmse.dwHitInfo = lParam;
 	    COMBOEX_Notify (infoPtr, NM_SETCURSOR, (NMHDR *)&nmmse);
-	    return CallWindowProcA (infoPtr->prevComboWndProc, 
+	    return CallWindowProcW (infoPtr->prevComboWndProc, 
 				   hwnd, uMsg, wParam, lParam);
 
     case WM_COMMAND:
@@ -2266,7 +1972,7 @@
 		}
 
 		TRACE("handling EN_CHANGE, selected = %d, selected_text=%s\n",
-		    selected, debugstr_w(lastwrk));
+		      selected, debugstr_w(lastwrk));
 		TRACE("handling EN_CHANGE, edittext=%s\n",
 		      debugstr_w(edit_text));
 
@@ -2319,7 +2025,7 @@
 		break;
 	    }/* fall through */
     default:
-	    return CallWindowProcA (infoPtr->prevComboWndProc, 
+	    return CallWindowProcW (infoPtr->prevComboWndProc, 
 				   hwnd, uMsg, wParam, lParam);
     }
     return 0;
@@ -2333,65 +2039,66 @@
 
     TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx\n", hwnd, uMsg, wParam, lParam);
 
-    if (!COMBOEX_GetInfoPtr (hwnd)) {
+    if (!infoPtr) {
 	if (uMsg == WM_CREATE)
-	    return COMBOEX_Create (hwnd, wParam, lParam);
+	    return COMBOEX_Create (hwnd, (LPCREATESTRUCTA)lParam);
 	if (uMsg == WM_NCCREATE)
-	    COMBOEX_NCCreate (hwnd, wParam, lParam);
-        return DefWindowProcA (hwnd, uMsg, wParam, lParam);
+	    COMBOEX_NCCreate (hwnd);
+        return DefWindowProcW (hwnd, uMsg, wParam, lParam);
     }
 
     switch (uMsg)
     {
-        case CBEM_DELETEITEM:  /* maps to CB_DELETESTRING */
-	    return COMBOEX_DeleteItem (hwnd, wParam, lParam);
+        case CBEM_DELETEITEM:
+	    return COMBOEX_DeleteItem (infoPtr, wParam);
 
 	case CBEM_GETCOMBOCONTROL:
-	    return COMBOEX_GetComboControl (hwnd, wParam, lParam);
+	    return infoPtr->hwndCombo;
 
 	case CBEM_GETEDITCONTROL:
-	    return COMBOEX_GetEditControl (hwnd, wParam, lParam);
+	    return infoPtr->hwndEdit;
 
 	case CBEM_GETEXTENDEDSTYLE:
-	    return COMBOEX_GetExtendedStyle (hwnd, wParam, lParam);
+	    return infoPtr->dwExtStyle;
 
 	case CBEM_GETIMAGELIST:
-	    return COMBOEX_GetImageList (hwnd, wParam, lParam);
+	    return (LRESULT)infoPtr->himl;
 
 	case CBEM_GETITEMA:
-	    return COMBOEX_GetItemA (hwnd, wParam, lParam);
+	    return (LRESULT)COMBOEX_GetItemA (infoPtr, (COMBOBOXEXITEMA *)lParam);
 
 	case CBEM_GETITEMW:
-	    return COMBOEX_GetItemW (hwnd, wParam, lParam);
+	    return (LRESULT)COMBOEX_GetItemW (infoPtr, (COMBOBOXEXITEMW *)lParam);
 
 	case CBEM_GETUNICODEFORMAT:
-	    return COMBOEX_GetUnicodeFormat (hwnd, wParam, lParam);
+	    return infoPtr->unicode;
 
 	case CBEM_HASEDITCHANGED:
-	    return COMBOEX_HasEditChanged (hwnd, wParam, lParam);
+	    return COMBOEX_HasEditChanged (infoPtr);
 
 	case CBEM_INSERTITEMA:
-	    return COMBOEX_InsertItemA (hwnd, wParam, lParam);
+	    return COMBOEX_InsertItemA (infoPtr, (COMBOBOXEXITEMA *)lParam);
 
 	case CBEM_INSERTITEMW:
-	    return COMBOEX_InsertItemW (hwnd, wParam, lParam);
+	    return COMBOEX_InsertItemW (infoPtr, (COMBOBOXEXITEMW *)lParam);
 
-	case CBEM_SETEXSTYLE:	/* FIXME: obsoleted, should be the same as: */
+	case CBEM_SETEXSTYLE:
 	case CBEM_SETEXTENDEDSTYLE:
-	    return COMBOEX_SetExtendedStyle (hwnd, wParam, lParam);
+	    return COMBOEX_SetExtendedStyle (infoPtr, (DWORD)wParam, (DWORD)lParam);
 
 	case CBEM_SETIMAGELIST:
-	    return COMBOEX_SetImageList (hwnd, wParam, lParam);
+	    return (LRESULT)COMBOEX_SetImageList (infoPtr, (HIMAGELIST)lParam);
 
 	case CBEM_SETITEMA:
-	    return COMBOEX_SetItemA (hwnd, wParam, lParam);
+	    return COMBOEX_SetItemA (infoPtr, (COMBOBOXEXITEMA *)lParam);
 
 	case CBEM_SETITEMW:
-	    return COMBOEX_SetItemW (hwnd, wParam, lParam);
+	    return COMBOEX_SetItemW (infoPtr, (COMBOBOXEXITEMW *)lParam);
 
 	case CBEM_SETUNICODEFORMAT:
-	    return COMBOEX_SetUnicodeFormat (hwnd, wParam, lParam);
+	    return COMBOEX_SetUnicodeFormat (infoPtr, wParam);
 
+	/* case CBEM_SETWINDOWTHEME: FIXME */
 
 /*   Combo messages we are not sure if we need to process or just forward */
 	case CB_GETDROPPEDCONTROLRECT:
@@ -2406,7 +2113,6 @@
 	case WM_GETTEXT:
 	    FIXME("(0x%x 0x%x 0x%lx): possibly missing function\n",
 		  uMsg, wParam, lParam);
-	    return COMBOEX_Forward (hwnd, uMsg, wParam, lParam);
 
 /*   Combo messages OK to just forward to the regular COMBO */
 	case CB_GETCOUNT:        
@@ -2415,95 +2121,87 @@
         case CB_SETDROPPEDWIDTH:
         case CB_SETEXTENDEDUI:
         case CB_SHOWDROPDOWN:
-	    return COMBOEX_Forward (hwnd, uMsg, wParam, lParam);
+	    return COMBOEX_Forward (infoPtr, uMsg, wParam, lParam);
 
 /*   Combo messages we need to process specially */
         case CB_FINDSTRINGEXACT:
-	    return COMBOEX_FindStringExact (COMBOEX_GetInfoPtr (hwnd), 
-					    wParam, lParam);
+	    return COMBOEX_FindStringExact (infoPtr, (INT)wParam, (LPCSTR)lParam);
 
 	case CB_GETITEMDATA:
-	    return COMBOEX_GetItemData (hwnd, wParam, lParam);
+	    return COMBOEX_GetItemData (infoPtr, (INT)wParam);
 
 	case CB_SETCURSEL:
-	    return COMBOEX_SetCursel (hwnd, wParam, lParam);
+	    return COMBOEX_SetCursel (infoPtr, (INT)wParam);
 
 	case CB_SETITEMDATA:
-	    return COMBOEX_SetItemData (hwnd, wParam, lParam);
+	    return COMBOEX_SetItemData (infoPtr, (INT)wParam, (DWORD)lParam);
 
 	case CB_SETITEMHEIGHT:
-	    return COMBOEX_SetItemHeight (hwnd, wParam, lParam);
+	    return COMBOEX_SetItemHeight (infoPtr, (INT)wParam, (UINT)lParam);
 
 
 
 /*   Window messages passed to parent */
 	case WM_COMMAND:
-	    return COMBOEX_Command (hwnd, wParam, lParam);
+	    return COMBOEX_Command (infoPtr, wParam, lParam);
 
 	case WM_NOTIFY:
 	    if (infoPtr->NtfUnicode)
-		return SendMessageW (GetParent (hwnd),
-				     uMsg, wParam, lParam);
+		return SendMessageW (GetParent (hwnd), uMsg, wParam, lParam);
 	    else
-		return SendMessageA (GetParent (hwnd),
-				     uMsg, wParam, lParam);
+		return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
 
 
 /*   Window messages we need to process */
         case WM_DELETEITEM:
-	    return COMBOEX_WM_DeleteItem (hwnd, wParam, lParam);
+	    return COMBOEX_WM_DeleteItem (infoPtr, (DELETEITEMSTRUCT *)lParam);
 
         case WM_DRAWITEM:
-            return COMBOEX_DrawItem (hwnd, wParam, lParam);
+            return COMBOEX_DrawItem (infoPtr, (DRAWITEMSTRUCT *)lParam);
 
 	case WM_DESTROY:
-	    return COMBOEX_Destroy (hwnd, wParam, lParam);
+	    return COMBOEX_Destroy (infoPtr);
 
         case WM_MEASUREITEM:
-            return COMBOEX_MeasureItem (hwnd, wParam, lParam);
+            return COMBOEX_MeasureItem (infoPtr, (MEASUREITEMSTRUCT *)lParam);
 
         case WM_NOTIFYFORMAT:
-	    return COMBOEX_NotifyFormat (hwnd, wParam, lParam);
+	    return COMBOEX_NotifyFormat (infoPtr, lParam);
 
 	case WM_SIZE:
-	    return COMBOEX_Size (hwnd, wParam, lParam);
+	    return COMBOEX_Size (infoPtr, LOWORD(lParam), HIWORD(lParam));
 
         case WM_WINDOWPOSCHANGING:
-	    return COMBOEX_WindowPosChanging (hwnd, wParam, lParam);
+	    return COMBOEX_WindowPosChanging (infoPtr, (WINDOWPOS *)lParam);
 
 	default:
 	    if (uMsg >= WM_USER)
-		ERR("unknown msg %04x wp=%08x lp=%08lx\n",
-		     uMsg, wParam, lParam);
-	    return DefWindowProcA (hwnd, uMsg, wParam, lParam);
+		ERR("unknown msg %04x wp=%08x lp=%08lx\n",uMsg,wParam,lParam);
+	    return DefWindowProcW (hwnd, uMsg, wParam, lParam);
     }
     return 0;
 }
 
 
-VOID
-COMBOEX_Register (void)
+void COMBOEX_Register (void)
 {
-    WNDCLASSA wndClass;
+    WNDCLASSW wndClass;
 
-    ZeroMemory (&wndClass, sizeof(WNDCLASSA));
+    ZeroMemory (&wndClass, sizeof(WNDCLASSW));
     wndClass.style         = CS_GLOBALCLASS;
     wndClass.lpfnWndProc   = (WNDPROC)COMBOEX_WindowProc;
     wndClass.cbClsExtra    = 0;
     wndClass.cbWndExtra    = sizeof(COMBOEX_INFO *);
-    wndClass.hCursor       = LoadCursorA (0, IDC_ARROWA);
+    wndClass.hCursor       = LoadCursorW (0, IDC_ARROWW);
     wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
-    wndClass.lpszClassName = WC_COMBOBOXEXA;
+    wndClass.lpszClassName = WC_COMBOBOXEXW;
  
-    RegisterClassA (&wndClass);
-
-    ComboExInfo = GlobalAddAtomA("CC32SubclassInfo");
+    RegisterClassW (&wndClass);
 }
 
 
-VOID
-COMBOEX_Unregister (void)
+void COMBOEX_Unregister (void)
 {
-    UnregisterClassA (WC_COMBOBOXEXA, (HINSTANCE)NULL);
+    UnregisterClassW (WC_COMBOBOXEXW, (HINSTANCE)NULL);
 }
 




More information about the wine-patches mailing list