[CALC] Fix input bug when display is in error. (#5988)
[reactos.git] / win32ss / user / user32 / controls / combo.c
index 54c08d3..c118b31 100644 (file)
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  *
- * NOTES
- *
- * This code was audited for completeness against the documented features
- * of Comctl32.dll version 6.0 on Oct. 4, 2004, by Dimitrie O. Paun.
- * 
- * Unless otherwise noted, we believe this code to be complete, as per
- * the specification mentioned above.
- * If you discover missing features, or bugs, please note them below.
- * 
  * TODO:
- *   - ComboBox_[GS]etMinVisible()
- *   - CB_GETMINVISIBLE, CB_SETMINVISIBLE
  *   - CB_SETTOPINDEX
  */
 
 #include <user32.h>
 
-#include <wine/debug.h>
 WINE_DEFAULT_DEBUG_CHANNEL(combo);
 
 /*
@@ -49,8 +37,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(combo);
 #define CB_OWNERDRAWN( lphc ) ((lphc)->dwStyle & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE))
 #define CB_HASSTRINGS( lphc ) ((lphc)->dwStyle & CBS_HASSTRINGS)
 #define CB_HWND( lphc )       ((lphc)->self)
-// ReactOS already define in include/controls.h We have it here as a sync note.
-//#define CB_GETTYPE( lphc )    ((lphc)->dwStyle & (CBS_DROPDOWNLIST))
+#ifndef __REACTOS__
+/* ReactOS already define in include/controls.h We have it here as a sync note. */
+#define CB_GETTYPE( lphc )    ((lphc)->dwStyle & (CBS_DROPDOWNLIST))
+#endif
 
 #define ISWIN31 (LOWORD(GetVersion()) == 0x0a03)
 
@@ -78,8 +68,12 @@ const struct builtin_class_descr COMBO_builtin_class =
 {
     comboboxW,            /* name */
     CS_PARENTDC | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, /* style  */
+#ifdef __REACTOS__
     ComboWndProcA,        /* procA */
     ComboWndProcW,        /* procW */
+#else
+    WINPROC_COMBO,        /* proc */
+#endif
     sizeof(HEADCOMBO *),  /* extra */
     IDC_ARROW,            /* cursor */
     0                     /* brush */
@@ -123,7 +117,7 @@ static BOOL COMBO_Init(void)
   return FALSE;
 }
 
-
+#ifdef __REACTOS__
 /* Retrieve the UI state for the control */
 static BOOL COMBO_update_uistate(LPHEADCOMBO lphc)
 {
@@ -133,6 +127,7 @@ static BOOL COMBO_update_uistate(LPHEADCOMBO lphc)
     lphc->UIState = DefWindowProcW(lphc->self, WM_QUERYUISTATE, 0, 0);
     return prev_flags != lphc->UIState;
 }
+#endif
 
 /***********************************************************************
  *           COMBO_NCCreate
@@ -146,7 +141,9 @@ static LRESULT COMBO_NCCreate(HWND hwnd, LONG style)
         lphc->self = hwnd;
         SetWindowLongPtrW( hwnd, 0, (LONG_PTR)lphc );
 
+#ifdef __REACTOS__
         COMBO_update_uistate(lphc);
+#endif
 
        /* some braindead apps do try to use scrollbar/border flags */
 
@@ -176,18 +173,17 @@ static LRESULT COMBO_NCCreate(HWND hwnd, LONG style)
  */
 static LRESULT COMBO_NCDestroy( LPHEADCOMBO lphc )
 {
+    if (lphc)
+    {
+        TRACE("[%p]: freeing storage\n", lphc->self);
 
-   if( lphc )
-   {
-       TRACE("[%p]: freeing storage\n", lphc->self);
-
-       if( (CB_GETTYPE(lphc) != CBS_SIMPLE) && lphc->hWndLBox )
-          DestroyWindow( lphc->hWndLBox );
+        if ( (CB_GETTYPE(lphc) != CBS_SIMPLE) && lphc->hWndLBox )
+            DestroyWindow( lphc->hWndLBox );
 
-       SetWindowLongPtrW( lphc->self, 0, 0 );
-       HeapFree( GetProcessHeap(), 0, lphc );
-   }
-   return 0;
+        SetWindowLongPtrW( lphc->self, 0, 0 );
+        HeapFree( GetProcessHeap(), 0, lphc );
+    }
+    return 0;
 }
 
 /***********************************************************************
@@ -643,6 +639,58 @@ static void CBPaintButton( LPHEADCOMBO lphc, HDC hdc, RECT rectButton)
     DrawFrameControl(hdc, &rectButton, DFC_SCROLL, buttonState);
 }
 
+/***********************************************************************
+ *           COMBO_PrepareColors
+ *
+ * This method will sent the appropriate WM_CTLCOLOR message to
+ * prepare and setup the colors for the combo's DC.
+ *
+ * It also returns the brush to use for the background.
+ */
+static HBRUSH COMBO_PrepareColors(
+  LPHEADCOMBO lphc,
+  HDC         hDC)
+{
+  HBRUSH  hBkgBrush;
+
+  /*
+   * Get the background brush for this control.
+   */
+  if (CB_DISABLED(lphc))
+  {
+#ifdef __REACTOS__
+    hBkgBrush = GetControlColor(lphc->owner, lphc->self, hDC, WM_CTLCOLORSTATIC);
+#else
+    hBkgBrush = (HBRUSH)SendMessageW(lphc->owner, WM_CTLCOLORSTATIC,
+            (WPARAM)hDC, (LPARAM)lphc->self );
+#endif
+    /*
+     * We have to change the text color since WM_CTLCOLORSTATIC will
+     * set it to the "enabled" color. This is the same behavior as the
+     * edit control
+     */
+    SetTextColor(hDC, GetSysColor(COLOR_GRAYTEXT));
+  }
+  else
+  {
+      /* FIXME: In which cases WM_CTLCOLORLISTBOX should be sent? */
+#ifdef __REACTOS__
+      hBkgBrush = GetControlColor(lphc->owner, lphc->self, hDC, WM_CTLCOLOREDIT);
+#else
+      hBkgBrush = (HBRUSH)SendMessageW(lphc->owner, WM_CTLCOLOREDIT,
+              (WPARAM)hDC, (LPARAM)lphc->self );
+#endif
+  }
+
+  /*
+   * Catch errors.
+   */
+  if( !hBkgBrush )
+    hBkgBrush = GetSysColorBrush(COLOR_WINDOW);
+
+  return hBkgBrush;
+}
+
 /***********************************************************************
  *           CBPaintText
  *
@@ -650,14 +698,12 @@ static void CBPaintButton( LPHEADCOMBO lphc, HDC hdc, RECT rectButton)
  */
 static void CBPaintText(
   LPHEADCOMBO lphc,
-  HDC         hdc,
-  RECT        rectEdit)
+  HDC         hdc_paint)
 {
+   RECT rectEdit = lphc->textRect;
    INT id, size = 0;
    LPWSTR pText = NULL;
 
-   if( lphc->wState & CBF_NOREDRAW ) return;
-
    TRACE("\n");
 
    /* follow Windows combobox that sends a bunch of text
@@ -675,27 +721,31 @@ static void CBPaintText(
            pText[size] = '\0'; /* just in case */
        } else return;
    }
-   else
-       if( !CB_OWNERDRAWN(lphc) )
-          return;
 
    if( lphc->wState & CBF_EDIT )
    {
         static const WCHAR empty_stringW[] = { 0 };
        if( CB_HASSTRINGS(lphc) ) SetWindowTextW( lphc->hWndEdit, pText ? pText : empty_stringW );
        if( lphc->wState & CBF_FOCUSED )
-           SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1));
+           SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, MAXLONG);
    }
-   else /* paint text field ourselves */
+   else if(!(lphc->wState & CBF_NOREDRAW) && IsWindowVisible( lphc->self ))
    {
-     UINT      itemState = ODS_COMBOBOXEDIT;
-     HFONT     hPrevFont = (lphc->hFont) ? SelectObject(hdc, lphc->hFont) : 0;
+     /* paint text field ourselves */
+     HDC hdc = hdc_paint ? hdc_paint : GetDC(lphc->self);
+     UINT itemState = ODS_COMBOBOXEDIT;
+     HFONT hPrevFont = (lphc->hFont) ? SelectObject(hdc, lphc->hFont) : 0;
+     HBRUSH hPrevBrush, hBkgBrush;
 
      /*
       * Give ourselves some space.
       */
      InflateRect( &rectEdit, -1, -1 );
 
+     hBkgBrush = COMBO_PrepareColors( lphc, hdc );
+     hPrevBrush = SelectObject( hdc, hBkgBrush );
+     FillRect( hdc, &rectEdit, hBkgBrush );
+
      if( CB_OWNERDRAWN(lphc) )
      {
        DRAWITEMSTRUCT dis;
@@ -717,7 +767,7 @@ static void CBPaintText(
        dis.itemState   = itemState;
        dis.hDC         = hdc;
        dis.rcItem      = rectEdit;
-       dis.itemData    = SendMessageW(lphc->hWndLBox, LB_GETITEMDATA, id, 0 );
+       dis.itemData     = SendMessageW(lphc->hWndLBox, LB_GETITEMDATA, id, 0);
 
        /*
        * Clip the DC and have the parent draw the item.
@@ -726,7 +776,7 @@ static void CBPaintText(
 
        SendMessageW(lphc->owner, WM_DRAWITEM, ctlid, (LPARAM)&dis );
 
-       SelectClipRgn( hdc, clipRegion);
+       SelectClipRgn( hdc, clipRegion );
        if (clipRegion) DeleteObject( clipRegion );
      }
      else
@@ -749,15 +799,28 @@ static void CBPaintText(
                    &rectEdit,
                    pText ? pText : empty_stringW , size, NULL );
 
-       if(lphc->wState & CBF_FOCUSED && !(lphc->wState & CBF_DROPPED) &&
+#ifdef __REACTOS__
+       if(lphc->wState & CBF_FOCUSED &&
+          !(lphc->wState & CBF_DROPPED) &&
           !(lphc->UIState & UISF_HIDEFOCUS))
+#else
+       if(lphc->wState & CBF_FOCUSED && !(lphc->wState & CBF_DROPPED))
+#endif
         DrawFocusRect( hdc, &rectEdit );
      }
 
      if( hPrevFont )
        SelectObject(hdc, hPrevFont );
+
+     if( hPrevBrush )
+        SelectObject( hdc, hPrevBrush );
+
+     if( !hdc_paint )
+       ReleaseDC( lphc->self, hdc );
    }
+#ifdef __REACTOS__
    if (pText)
+#endif
        HeapFree( GetProcessHeap(), 0, pText );
 }
 
@@ -786,73 +849,28 @@ static void CBPaintBorder(
   DrawEdge(hdc, &clientRect, EDGE_SUNKEN, BF_RECT);
 }
 
-/***********************************************************************
- *           COMBO_PrepareColors
- *
- * This method will sent the appropriate WM_CTLCOLOR message to
- * prepare and setup the colors for the combo's DC.
- *
- * It also returns the brush to use for the background.
- */
-static HBRUSH COMBO_PrepareColors(
-  LPHEADCOMBO lphc,
-  HDC         hDC)
-{
-  HBRUSH  hBkgBrush;
-
-  /*
-   * Get the background brush for this control.
-   */
-  if (CB_DISABLED(lphc))
-  {
-     hBkgBrush = GetControlColor(lphc->owner, lphc->self, hDC, WM_CTLCOLORSTATIC);
-    /*
-     * We have to change the text color since WM_CTLCOLORSTATIC will
-     * set it to the "enabled" color. This is the same behavior as the
-     * edit control
-     */
-    SetTextColor(hDC, GetSysColor(COLOR_GRAYTEXT));
-  }
-  else
-  {
-      /* FIXME: In which cases WM_CTLCOLORLISTBOX should be sent? */
-     hBkgBrush = GetControlColor(lphc->owner, lphc->self, hDC, WM_CTLCOLOREDIT);
-  }
-
-  /*
-   * Catch errors.
-   */
-  if( !hBkgBrush )
-    hBkgBrush = GetSysColorBrush(COLOR_WINDOW);
-
-  return hBkgBrush;
-}
-
-
 /***********************************************************************
  *           COMBO_Paint
  */
 static LRESULT COMBO_Paint(LPHEADCOMBO lphc, HDC hParamDC)
 {
   PAINTSTRUCT ps;
-  HDC  hDC;
+  HDC hDC;
 
-  hDC = (hParamDC) ? hParamDC
-                  : BeginPaint( lphc->self, &ps);
+  hDC = (hParamDC) ? hParamDC : BeginPaint(lphc->self, &ps);
 
   TRACE("hdc=%p\n", hDC);
 
   if( hDC && !(lphc->wState & CBF_NOREDRAW) )
   {
-      HBRUSH   hPrevBrush, hBkgBrush;
+      HBRUSH hPrevBrush, hBkgBrush;
 
       /*
        * Retrieve the background brush and select it in the
        * DC.
        */
       hBkgBrush = COMBO_PrepareColors(lphc, hDC);
-
-      hPrevBrush = SelectObject( hDC, hBkgBrush );
+      hPrevBrush = SelectObject(hDC, hBkgBrush);
       if (!(lphc->wState & CBF_EDIT))
         FillRect(hDC, &lphc->textRect, hBkgBrush);
 
@@ -861,10 +879,8 @@ static LRESULT COMBO_Paint(LPHEADCOMBO lphc, HDC hParamDC)
        */
       CBPaintBorder(lphc->self, lphc, hDC);
 
-      if( !IsRectEmpty(&lphc->buttonRect) )
-      {
-       CBPaintButton(lphc, hDC, lphc->buttonRect);
-      }
+      if (!IsRectEmpty(&lphc->buttonRect))
+          CBPaintButton(lphc, hDC, lphc->buttonRect);
 
       /* paint the edit control padding area */
       if (CB_GETTYPE(lphc) != CBS_DROPDOWNLIST)
@@ -873,14 +889,14 @@ static LRESULT COMBO_Paint(LPHEADCOMBO lphc, HDC hParamDC)
 
           InflateRect(&rPadEdit, EDIT_CONTROL_PADDING(), EDIT_CONTROL_PADDING());
 
-          FrameRect( hDC, &rPadEdit, GetSysColorBrush(COLOR_WINDOW) );
+          FrameRect(hDC, &rPadEdit, GetSysColorBrush(COLOR_WINDOW));
       }
 
-      if( !(lphc->wState & CBF_EDIT) )
-       CBPaintText( lphc, hDC, lphc->textRect);
+      if (!(lphc->wState & CBF_EDIT))
+          CBPaintText( lphc, hDC );
 
-      if( hPrevBrush )
-       SelectObject( hDC, hPrevBrush );
+      if (hPrevBrush)
+          SelectObject( hDC, hPrevBrush );
   }
 
   if( !hParamDC )
@@ -902,7 +918,7 @@ static INT CBUpdateLBox( LPHEADCOMBO lphc, BOOL bSelect )
    idx = LB_ERR;
    length = SendMessageW( lphc->hWndEdit, WM_GETTEXTLENGTH, 0, 0 );
 
-   if( length > 0 )
+   if (length > 0)
        pText = HeapAlloc( GetProcessHeap(), 0, (length + 1) * sizeof(WCHAR));
 
    TRACE("\t edit text length %i\n", length );
@@ -910,8 +926,7 @@ static INT CBUpdateLBox( LPHEADCOMBO lphc, BOOL bSelect )
    if( pText )
    {
        GetWindowTextW( lphc->hWndEdit, pText, length + 1);
-       idx = SendMessageW(lphc->hWndLBox, LB_FINDSTRING,
-                            (WPARAM)(-1), (LPARAM)pText );
+       idx = SendMessageW(lphc->hWndLBox, LB_FINDSTRING, (WPARAM)(-1), (LPARAM)pText);
        HeapFree( GetProcessHeap(), 0, pText );
    }
 
@@ -942,11 +957,8 @@ static void CBUpdateEdit( LPHEADCOMBO lphc , INT index )
        length = SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, (WPARAM)index, 0);
        if( length != LB_ERR)
        {
-          if( (pText = HeapAlloc( GetProcessHeap(), 0, (length + 1) * sizeof(WCHAR))) )
-          {
-               SendMessageW(lphc->hWndLBox, LB_GETTEXT,
-                               (WPARAM)index, (LPARAM)pText );
-          }
+           if ((pText = HeapAlloc(GetProcessHeap(), 0, (length + 1) * sizeof(WCHAR))))
+               SendMessageW(lphc->hWndLBox, LB_GETTEXT, (WPARAM)index, (LPARAM)pText );
        }
    }
 
@@ -996,7 +1008,7 @@ static void CBDropDown( LPHEADCOMBO lphc )
        lphc->droppedIndex = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
 
        SendMessageW(lphc->hWndLBox, LB_SETTOPINDEX,
-                     (WPARAM)(lphc->droppedIndex == LB_ERR ? 0 : lphc->droppedIndex), 0 );
+                    (WPARAM)(lphc->droppedIndex == LB_ERR ? 0 : lphc->droppedIndex), 0);
        SendMessageW(lphc->hWndLBox, LB_CARETON, 0, 0);
    }
 
@@ -1032,14 +1044,6 @@ static void CBDropDown( LPHEADCOMBO lphc )
 
       if (nHeight < nDroppedHeight - COMBO_YBORDERSIZE())
          nDroppedHeight = nHeight + COMBO_YBORDERSIZE();
-
-      if (nDroppedHeight < nHeight)
-      {
-            if (nItems < 5)
-                nDroppedHeight = (nItems+1)*nIHeight;
-            else if (nDroppedHeight < 6*nIHeight)
-                nDroppedHeight = 6*nIHeight;
-      }
    }
 
    r.left = rect.left;
@@ -1052,19 +1056,18 @@ static void CBDropDown( LPHEADCOMBO lphc )
    mon_info.cbSize = sizeof(mon_info);
    GetMonitorInfoW( monitor, &mon_info );
 
-   if (r.bottom > mon_info.rcWork.bottom )
+   if (r.bottom > mon_info.rcWork.bottom)
    {
        r.top = max( rect.top - nDroppedHeight, mon_info.rcWork.top );
        r.bottom = min( r.top + nDroppedHeight, mon_info.rcWork.bottom );
    }
-   //// ReactOS : Use HWND_TOPMOST See Bug 5705 or CORE-5186....
+
    SetWindowPos( lphc->hWndLBox, HWND_TOPMOST, r.left, r.top, r.right - r.left, r.bottom - r.top,
-                SWP_NOACTIVATE | SWP_SHOWWINDOW);
+                 SWP_NOACTIVATE | SWP_SHOWWINDOW );
 
 
    if( !(lphc->wState & CBF_NOREDRAW) )
-     RedrawWindow( lphc->self, NULL, 0, RDW_INVALIDATE |
-                          RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN );
+     RedrawWindow( lphc->self, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW );
 
    EnableWindow( lphc->hWndLBox, TRUE );
    if (GetCapture() != lphc->self)
@@ -1189,7 +1192,7 @@ static void COMBO_KillFocus( LPHEADCOMBO lphc )
            if( CB_GETTYPE(lphc) == CBS_DROPDOWNLIST )
                SendMessageW(lphc->hWndLBox, LB_CARETOFF, 0, 0);
 
-          lphc->wState &= ~CBF_FOCUSED;
+          lphc->wState &= ~CBF_FOCUSED;
 
            /* redraw text */
           if( !(lphc->wState & CBF_EDIT) )
@@ -1297,7 +1300,7 @@ static LRESULT COMBO_Command( LPHEADCOMBO lphc, WPARAM wParam, HWND hWnd )
                       lphc->wState |= CBF_NOLBSELECT;
                       CBUpdateEdit( lphc, index );
                       /* select text in edit, as Windows does */
-                      SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1));
+               SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1));
                   }
                   else
                    {
@@ -1557,7 +1560,7 @@ static void COMBO_Size( LPHEADCOMBO lphc )
                  &lphc->buttonRect,
                  &lphc->droppedRect);
 
-  CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );  
+  CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, FALSE );
 }
 
 
@@ -1633,8 +1636,7 @@ static LRESULT COMBO_SetItemHeight( LPHEADCOMBO lphc, INT index, INT height )
        }
    }
    else if ( CB_OWNERDRAWN(lphc) )     /* set listbox item height */
-       lRet = SendMessageW(lphc->hWndLBox, LB_SETITEMHEIGHT,
-                             (WPARAM)index, (LPARAM)height );
+       lRet = SendMessageW(lphc->hWndLBox, LB_SETITEMHEIGHT, (WPARAM)index, (LPARAM)height);
    return lRet;
 }
 
@@ -1799,7 +1801,9 @@ static char *strdupA(LPCSTR str)
 
     len = strlen(str);
     ret = HeapAlloc(GetProcessHeap(), 0, len + 1);
+#ifdef __REACTOS__
     if (ret != NULL)
+#endif
         memcpy(ret, str, len + 1);
     return ret;
 }
@@ -1807,413 +1811,434 @@ static char *strdupA(LPCSTR str)
 /***********************************************************************
  *           ComboWndProc_common
  */
-LRESULT WINAPI ComboWndProc_common( HWND hwnd, UINT message,
-                                  WPARAM wParam, LPARAM lParam, BOOL unicode )
+LRESULT WINAPI ComboWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL unicode )
 {
-      LPHEADCOMBO lphc = (LPHEADCOMBO)GetWindowLongPtrW( hwnd, 0 );
+    LPHEADCOMBO lphc = (LPHEADCOMBO)GetWindowLongPtrW( hwnd, 0 );
 #ifdef __REACTOS__
-      PWND pWnd;
+    PWND pWnd;
 
-      pWnd = ValidateHwnd(hwnd);
-      if (pWnd)
-      {
-         if (!pWnd->fnid)
-         {
+    pWnd = ValidateHwnd(hwnd);
+    if (pWnd)
+    {
+        if (!pWnd->fnid)
+        {
             NtUserSetWindowFNID(hwnd, FNID_COMBOBOX);
-         }
-         else
-         {
+        }
+        else
+        {
             if (pWnd->fnid != FNID_COMBOBOX)
             {
-               ERR("Wrong window class for ComboBox! fnId 0x%x\n",pWnd->fnid);
-               return 0;
+                ERR("Wrong window class for ComboBox! fnId 0x%x\n",pWnd->fnid);
+                return 0;
             }
          }
-      }    
-#endif    
+    }
+#endif
 
-      TRACE("[%p]: msg %s wp %08lx lp %08lx\n",
-            hwnd, SPY_GetMsgName(message, hwnd), wParam, lParam );
+    TRACE("[%p]: msg %s wp %08lx lp %08lx\n", hwnd, SPY_GetMsgName(message, hwnd), wParam, lParam);
 
-      if( lphc || message == WM_NCCREATE )
-      switch(message)
-      {
+#ifndef __REACTOS__
+    if (!IsWindow(hwnd)) return 0;
+#endif
 
-       /* System messages */
+    if (lphc || message == WM_NCCREATE)
+    switch(message)
+    {
+    case WM_NCCREATE:
+    {
+        LONG style = unicode ? ((LPCREATESTRUCTW)lParam)->style : ((LPCREATESTRUCTA)lParam)->style;
+        return COMBO_NCCreate(hwnd, style);
+    }
+    case WM_NCDESTROY:
+        COMBO_NCDestroy(lphc);
+#ifdef __REACTOS__
+        NtUserSetWindowFNID(hwnd, FNID_DESTROY);
+#endif
+        break;/* -> DefWindowProc */
 
-       case WM_NCCREATE:
-       {
-               LONG style = unicode ? ((LPCREATESTRUCTW)lParam)->style :
-                                      ((LPCREATESTRUCTA)lParam)->style;
-                return COMBO_NCCreate(hwnd, style);
-       }
-       case WM_NCDESTROY:
-               COMBO_NCDestroy(lphc);
+    case WM_CREATE:
+    {
+        HWND hwndParent;
+        LONG style;
+        if(unicode)
+        {
+            hwndParent = ((LPCREATESTRUCTW)lParam)->hwndParent;
+            style = ((LPCREATESTRUCTW)lParam)->style;
+        }
+        else
+        {
+            hwndParent = ((LPCREATESTRUCTA)lParam)->hwndParent;
+            style = ((LPCREATESTRUCTA)lParam)->style;
+        }
+        return COMBO_Create(hwnd, lphc, hwndParent, style, unicode);
+    }
+    case WM_PRINTCLIENT:
+        /* Fallthrough */
+    case WM_PAINT:
+        /* wParam may contain a valid HDC! */
+        return  COMBO_Paint(lphc, (HDC)wParam);
+    case WM_ERASEBKGND:
+        /* do all painting in WM_PAINT like Windows does */
+        return 1;
+
+    case WM_GETDLGCODE:
+    {
+        LRESULT result = DLGC_WANTARROWS | DLGC_WANTCHARS;
+        if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN))
+        {
+            int vk = (int)((LPMSG)lParam)->wParam;
+
+            if ((vk == VK_RETURN || vk == VK_ESCAPE) && (lphc->wState & CBF_DROPPED))
+                result |= DLGC_WANTMESSAGE;
+        }
+        return  result;
+    }
+    case WM_SIZE:
+        if (lphc->hWndLBox && !(lphc->wState & CBF_NORESIZE))
+            COMBO_Size( lphc );
+        return  TRUE;
+    case WM_SETFONT:
+        COMBO_Font( lphc, (HFONT)wParam, (BOOL)lParam );
+        return TRUE;
+    case WM_GETFONT:
+        return (LRESULT)lphc->hFont;
+    case WM_SETFOCUS:
+        if (lphc->wState & CBF_EDIT)
+        {
+            SetFocus( lphc->hWndEdit );
+            /* The first time focus is received, select all the text */
+            if (!(lphc->wState & CBF_BEENFOCUSED))
+            {
+                SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, -1);
+                lphc->wState |= CBF_BEENFOCUSED;
+            }
+        }
+        else
+            COMBO_SetFocus( lphc );
+        return  TRUE;
+    case WM_KILLFOCUS:
+    {
+        HWND hwndFocus = WIN_GetFullHandle((HWND)wParam);
+        if (!hwndFocus || (hwndFocus != lphc->hWndEdit && hwndFocus != lphc->hWndLBox))
+            COMBO_KillFocus( lphc );
+        return  TRUE;
+    }
+    case WM_COMMAND:
+        return COMBO_Command( lphc, wParam, WIN_GetFullHandle((HWND)lParam) );
+    case WM_GETTEXT:
+        return unicode ? COMBO_GetTextW( lphc, wParam, (LPWSTR)lParam )
+                       : COMBO_GetTextA( lphc, wParam, (LPSTR)lParam );
+    case WM_SETTEXT:
+    case WM_GETTEXTLENGTH:
+    case WM_CLEAR:
+        if ((message == WM_GETTEXTLENGTH) && !ISWIN31 && !(lphc->wState & CBF_EDIT))
+        {
+            int j = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
+            if (j == -1) return 0;
+            return unicode ? SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, j, 0) :
+                             SendMessageA(lphc->hWndLBox, LB_GETTEXTLEN, j, 0);
+        }
+        else if ( lphc->wState & CBF_EDIT )
+        {
+            LRESULT ret;
+            lphc->wState |= CBF_NOEDITNOTIFY;
+            ret = unicode ? SendMessageW(lphc->hWndEdit, message, wParam, lParam) :
+                            SendMessageA(lphc->hWndEdit, message, wParam, lParam);
+            lphc->wState &= ~CBF_NOEDITNOTIFY;
+            return ret;
+        }
+        else
+            return CB_ERR;
+    case WM_CUT:
+    case WM_PASTE:
+    case WM_COPY:
+        if (lphc->wState & CBF_EDIT)
+        {
+            return unicode ? SendMessageW(lphc->hWndEdit, message, wParam, lParam) :
+                             SendMessageA(lphc->hWndEdit, message, wParam, lParam);
+        }
+        else return  CB_ERR;
+
+    case WM_DRAWITEM:
+    case WM_DELETEITEM:
+    case WM_COMPAREITEM:
+    case WM_MEASUREITEM:
+        return COMBO_ItemOp(lphc, message, lParam);
+    case WM_ENABLE:
+        if (lphc->wState & CBF_EDIT)
+            EnableWindow( lphc->hWndEdit, (BOOL)wParam );
+        EnableWindow( lphc->hWndLBox, (BOOL)wParam );
+
+        /* Force the control to repaint when the enabled state changes. */
+        InvalidateRect(lphc->self, NULL, TRUE);
+        return  TRUE;
+    case WM_SETREDRAW:
+        if (wParam)
+            lphc->wState &= ~CBF_NOREDRAW;
+        else
+            lphc->wState |= CBF_NOREDRAW;
+
+        if ( lphc->wState & CBF_EDIT )
+            SendMessageW(lphc->hWndEdit, message, wParam, lParam);
+        SendMessageW(lphc->hWndLBox, message, wParam, lParam);
+        return  0;
+    case WM_SYSKEYDOWN:
 #ifdef __REACTOS__
-                NtUserSetWindowFNID(hwnd, FNID_DESTROY);
+        if ( KF_ALTDOWN & HIWORD(lParam) )
+#else
+        if ( KEYDATA_ALT & HIWORD(lParam) )
+#endif
+            if( wParam == VK_UP || wParam == VK_DOWN )
+#ifdef __REACTOS__
+            {
+#endif
+                COMBO_FlipListbox( lphc, FALSE, FALSE );
+        return  0;
+#ifdef __REACTOS__
+            }
+        break;
 #endif
-               break;/* -> DefWindowProc */
 
-       case WM_CREATE:
-       {
-               HWND hwndParent;
-               LONG style;
-               if(unicode)
-               {
-                   hwndParent = ((LPCREATESTRUCTW)lParam)->hwndParent;
-                   style = ((LPCREATESTRUCTW)lParam)->style;
-               }
-               else
-               {
-                   hwndParent = ((LPCREATESTRUCTA)lParam)->hwndParent;
-                   style = ((LPCREATESTRUCTA)lParam)->style;
-               }
-                return COMBO_Create(hwnd, lphc, hwndParent, style, unicode);
-       }
+    case WM_KEYDOWN:
+        if ((wParam == VK_RETURN || wParam == VK_ESCAPE) &&
+                (lphc->wState & CBF_DROPPED))
+        {
+            CBRollUp( lphc, wParam == VK_RETURN, FALSE );
+            return TRUE;
+        }
+        else if ((wParam == VK_F4) && !(lphc->wState & CBF_EUI))
+        {
+            COMBO_FlipListbox( lphc, FALSE, FALSE );
+            return TRUE;
+        }
+        /* fall through */
+    case WM_CHAR:
+    case WM_IME_CHAR:
+        {
+            HWND hwndTarget;
 
-        case WM_PRINTCLIENT:
-               /* Fallthrough */
-       case WM_PAINT:
-               /* wParam may contain a valid HDC! */
-               return  COMBO_Paint(lphc, (HDC)wParam);
+#ifdef __REACTOS__
+            if (lphc->wState & CBF_DROPPED)
+                lphc->wState |= CBF_NOROLLUP;
+#endif
+            if ( lphc->wState & CBF_EDIT )
+                hwndTarget = lphc->hWndEdit;
+            else
+                hwndTarget = lphc->hWndLBox;
 
-       case WM_ERASEBKGND:
-                /* do all painting in WM_PAINT like Windows does */
-                return 1;
+            return unicode ? SendMessageW(hwndTarget, message, wParam, lParam) :
+                             SendMessageA(hwndTarget, message, wParam, lParam);
+        }
+    case WM_LBUTTONDOWN:
+        if ( !(lphc->wState & CBF_FOCUSED) ) SetFocus( lphc->self );
+        if ( lphc->wState & CBF_FOCUSED ) COMBO_LButtonDown( lphc, lParam );
+        return  TRUE;
+    case WM_LBUTTONUP:
+        COMBO_LButtonUp( lphc );
+        return  TRUE;
+    case WM_MOUSEMOVE:
+        if ( lphc->wState & CBF_CAPTURE )
+            COMBO_MouseMove( lphc, wParam, lParam );
+        return  TRUE;
+
+    case WM_MOUSEWHEEL:
+        if (wParam & (MK_SHIFT | MK_CONTROL))
+            return unicode ? DefWindowProcW(hwnd, message, wParam, lParam) :
+                             DefWindowProcA(hwnd, message, wParam, lParam);
+
+        if (GET_WHEEL_DELTA_WPARAM(wParam) > 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_UP, 0);
+        if (GET_WHEEL_DELTA_WPARAM(wParam) < 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_DOWN, 0);
+        return TRUE;
 
-       case WM_GETDLGCODE:
-       {
-               LRESULT result = DLGC_WANTARROWS | DLGC_WANTCHARS;
-               if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN))
-               {
-                  int vk = (int)((LPMSG)lParam)->wParam;
+    case WM_CTLCOLOR:
+    case WM_CTLCOLORMSGBOX:
+    case WM_CTLCOLOREDIT:
+    case WM_CTLCOLORLISTBOX:
+    case WM_CTLCOLORBTN:
+    case WM_CTLCOLORDLG:
+    case WM_CTLCOLORSCROLLBAR:
+    case WM_CTLCOLORSTATIC:
+#ifdef __REACTOS__
+        if (pWnd && !(pWnd->state2 & WNDS2_WIN40COMPAT)) break; // Must be Win 4.0 and above.
+#endif
+        if (lphc->owner)
+            return SendMessageW(lphc->owner, message, wParam, lParam);
+        break;
 
-                  if ((vk == VK_RETURN || vk == VK_ESCAPE) && (lphc->wState & CBF_DROPPED))
-                      result |= DLGC_WANTMESSAGE;
-               }
-               return  result;
-       }
-       case WM_SIZE:
-               if( lphc->hWndLBox &&
-                 !(lphc->wState & CBF_NORESIZE) ) COMBO_Size( lphc );
-               return  TRUE;
-       case WM_SETFONT:
-               COMBO_Font( lphc, (HFONT)wParam, (BOOL)lParam );
-               return  TRUE;
-       case WM_GETFONT:
-               return  (LRESULT)lphc->hFont;
-       case WM_SETFOCUS:
-               if( lphc->wState & CBF_EDIT ) {
-                   SetFocus( lphc->hWndEdit );
-                   /* The first time focus is received, select all the text */
-                   if( !(lphc->wState & CBF_BEENFOCUSED) ) {
-                       SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, -1);
-                       lphc->wState |= CBF_BEENFOCUSED;
-                   }
-               }
-                else
-                    COMBO_SetFocus( lphc );
-               return  TRUE;
-       case WM_KILLFOCUS:
+    /* Combo messages */
+    case CB_ADDSTRING:
+        if (unicode)
+        {
+            if (lphc->dwStyle & CBS_LOWERCASE)
+                CharLowerW((LPWSTR)lParam);
+            else if (lphc->dwStyle & CBS_UPPERCASE)
+                CharUpperW((LPWSTR)lParam);
+            return SendMessageW(lphc->hWndLBox, LB_ADDSTRING, 0, lParam);
+        }
+        else /* unlike the unicode version, the ansi version does not overwrite
+                the string if converting case */
+        {
+            char *string = NULL;
+            LRESULT ret;
+            if (lphc->dwStyle & CBS_LOWERCASE)
             {
-                HWND hwndFocus = WIN_GetFullHandle( (HWND)wParam );
-               if( !hwndFocus ||
-                   (hwndFocus != lphc->hWndEdit && hwndFocus != lphc->hWndLBox ))
-                   COMBO_KillFocus( lphc );
-               return  TRUE;
+                string = strdupA((LPSTR)lParam);
+                CharLowerA(string);
             }
-       case WM_COMMAND:
-               return  COMBO_Command( lphc, wParam, WIN_GetFullHandle( (HWND)lParam ) );
-       case WM_GETTEXT:
-            return unicode ? COMBO_GetTextW( lphc, wParam, (LPWSTR)lParam )
-                           : COMBO_GetTextA( lphc, wParam, (LPSTR)lParam );
-       case WM_SETTEXT:
-       case WM_GETTEXTLENGTH:
-       case WM_CLEAR:
-                if ((message == WM_GETTEXTLENGTH) && !ISWIN31 && !(lphc->wState & CBF_EDIT))
-                {
-                    int j = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
-                    if (j == -1) return 0;
-                    return unicode ? SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, j, 0) :
-                                     SendMessageA(lphc->hWndLBox, LB_GETTEXTLEN, j, 0);
-                }
-               else if( lphc->wState & CBF_EDIT )
-               {
-                   LRESULT ret;
-                   lphc->wState |= CBF_NOEDITNOTIFY;
-                   ret = unicode ? SendMessageW(lphc->hWndEdit, message, wParam, lParam) :
-                                   SendMessageA(lphc->hWndEdit, message, wParam, lParam);
-                   lphc->wState &= ~CBF_NOEDITNOTIFY;
-                   return ret;
-               }
-               else return CB_ERR;
-       case WM_CUT:
-        case WM_PASTE:
-       case WM_COPY:
-               if( lphc->wState & CBF_EDIT )
-               {
-                   return unicode ? SendMessageW(lphc->hWndEdit, message, wParam, lParam) :
-                                    SendMessageA(lphc->hWndEdit, message, wParam, lParam);
-               }
-               else return  CB_ERR;
-
-       case WM_DRAWITEM:
-       case WM_DELETEITEM:
-       case WM_COMPAREITEM:
-       case WM_MEASUREITEM:
-               return COMBO_ItemOp(lphc, message, lParam);
-       case WM_ENABLE:
-               if( lphc->wState & CBF_EDIT )
-                   EnableWindow( lphc->hWndEdit, (BOOL)wParam );
-               EnableWindow( lphc->hWndLBox, (BOOL)wParam );
-
-               /* Force the control to repaint when the enabled state changes. */
-               InvalidateRect(lphc->self, NULL, TRUE);
-               return  TRUE;
-       case WM_SETREDRAW:
-               if( wParam )
-                   lphc->wState &= ~CBF_NOREDRAW;
-               else
-                   lphc->wState |= CBF_NOREDRAW;
-
-               if( lphc->wState & CBF_EDIT )
-                   SendMessageW(lphc->hWndEdit, message, wParam, lParam);
-               SendMessageW(lphc->hWndLBox, message, wParam, lParam);
-               return  0;
-       case WM_SYSKEYDOWN:
-               if( KF_ALTDOWN & HIWORD(lParam) ) // ReactOS (wine) KEYDATA_ALT
-                   if( wParam == VK_UP || wParam == VK_DOWN )
-                       COMBO_FlipListbox( lphc, FALSE, FALSE );
-                return  0;
-
-       case WM_KEYDOWN:
-               if ((wParam == VK_RETURN || wParam == VK_ESCAPE) &&
-                    (lphc->wState & CBF_DROPPED))
-               {
-                  CBRollUp( lphc, wParam == VK_RETURN, FALSE );
-                  return TRUE;
-               }
-               else if ((wParam == VK_F4) && !(lphc->wState & CBF_EUI))
-               {
-                  COMBO_FlipListbox( lphc, FALSE, FALSE );
-                  return TRUE;
-               }
-               /* fall through */
-       case WM_CHAR:
-       case WM_IME_CHAR:
-        {
-               HWND hwndTarget;
 
-               if( lphc->wState & CBF_EDIT )
-                   hwndTarget = lphc->hWndEdit;
-               else
-                   hwndTarget = lphc->hWndLBox;
-
-               return unicode ? SendMessageW(hwndTarget, message, wParam, lParam) :
-                                SendMessageA(hwndTarget, message, wParam, lParam);
-       }
-       case WM_LBUTTONDOWN:
-               if( !(lphc->wState & CBF_FOCUSED) ) SetFocus( lphc->self );
-               if( lphc->wState & CBF_FOCUSED ) COMBO_LButtonDown( lphc, lParam );
-               return  TRUE;
-       case WM_LBUTTONUP:
-               COMBO_LButtonUp( lphc );
-               return  TRUE;
-       case WM_MOUSEMOVE:
-               if( lphc->wState & CBF_CAPTURE )
-                   COMBO_MouseMove( lphc, wParam, lParam );
-               return  TRUE;
-
-        case WM_MOUSEWHEEL:
-                if (wParam & (MK_SHIFT | MK_CONTROL))
-                    return unicode ? DefWindowProcW(hwnd, message, wParam, lParam) :
-                                    DefWindowProcA(hwnd, message, wParam, lParam);
-
-                if (GET_WHEEL_DELTA_WPARAM(wParam) > 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_UP, 0);
-                if (GET_WHEEL_DELTA_WPARAM(wParam) < 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_DOWN, 0);
-                return TRUE;
-
-       /* Combo messages */
-
-       case CB_ADDSTRING:
-               if( unicode )
-                {
-                    if( lphc->dwStyle & CBS_LOWERCASE )
-                        CharLowerW((LPWSTR)lParam);
-                    else if( lphc->dwStyle & CBS_UPPERCASE )
-                        CharUpperW((LPWSTR)lParam);
-                    return SendMessageW(lphc->hWndLBox, LB_ADDSTRING, 0, lParam);
-                }
-                else /* unlike the unicode version, the ansi version does not overwrite
-                        the string if converting case */
-                {
-                    char *string = NULL;
-                    LRESULT ret;
-                    if( lphc->dwStyle & CBS_LOWERCASE )
-                    {
-                        string = strdupA((LPSTR)lParam);
-                        CharLowerA(string);
-                    }
-
-                    else if( lphc->dwStyle & CBS_UPPERCASE )
-                    {
-                        string = strdupA((LPSTR)lParam);
-                        CharUpperA(string);
-                    }
-
-                    ret = SendMessageA(lphc->hWndLBox, LB_ADDSTRING, 0, string ? (LPARAM)string : lParam);
-                    HeapFree(GetProcessHeap(), 0, string);
-                    return ret;
-                }
-       case CB_INSERTSTRING:
-               if( unicode )
-                {
-                    if( lphc->dwStyle & CBS_LOWERCASE )
-                        CharLowerW((LPWSTR)lParam);
-                    else if( lphc->dwStyle & CBS_UPPERCASE )
-                        CharUpperW((LPWSTR)lParam);
-                    return SendMessageW(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam);
-                }
-                else
-                {
-                    if( lphc->dwStyle & CBS_LOWERCASE )
-                        CharLowerA((LPSTR)lParam);
-                    else if( lphc->dwStyle & CBS_UPPERCASE )
-                        CharUpperA((LPSTR)lParam);
+            else if (lphc->dwStyle & CBS_UPPERCASE)
+            {
+                string = strdupA((LPSTR)lParam);
+                CharUpperA(string);
+            }
 
-                    return SendMessageA(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam);
-                }
-       case CB_DELETESTRING:
-               return unicode ? SendMessageW(lphc->hWndLBox, LB_DELETESTRING, wParam, 0) :
-                                SendMessageA(lphc->hWndLBox, LB_DELETESTRING, wParam, 0);
-       case CB_SELECTSTRING:
-               return COMBO_SelectString(lphc, (INT)wParam, lParam, unicode);
-       case CB_FINDSTRING:
-               return unicode ? SendMessageW(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam) :
-                                SendMessageA(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam);
-       case CB_FINDSTRINGEXACT:
-               return unicode ? SendMessageW(lphc->hWndLBox, LB_FINDSTRINGEXACT, wParam, lParam) :
-                                SendMessageA(lphc->hWndLBox, LB_FINDSTRINGEXACT, wParam, lParam);
-       case CB_SETITEMHEIGHT:
-               return  COMBO_SetItemHeight( lphc, (INT)wParam, (INT)lParam);
-       case CB_GETITEMHEIGHT:
-               if( (INT)wParam >= 0 )  /* listbox item */
-                    return SendMessageW(lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0);
-                return  CBGetTextAreaHeight(hwnd, lphc);
-       case CB_RESETCONTENT:
-               SendMessageW(lphc->hWndLBox, LB_RESETCONTENT, 0, 0);
-                if( (lphc->wState & CBF_EDIT) && CB_HASSTRINGS(lphc) )
-               {
-                   static const WCHAR empty_stringW[] = { 0 };
-                    SendMessageW(lphc->hWndEdit, WM_SETTEXT, 0, (LPARAM)empty_stringW);
-               }
-                else
-                    InvalidateRect(lphc->self, NULL, TRUE);
-               return  TRUE;
-       case CB_INITSTORAGE:
-               return SendMessageW(lphc->hWndLBox, LB_INITSTORAGE, wParam, lParam);
-       case CB_GETHORIZONTALEXTENT:
-               return SendMessageW(lphc->hWndLBox, LB_GETHORIZONTALEXTENT, 0, 0);
-       case CB_SETHORIZONTALEXTENT:
-               return SendMessageW(lphc->hWndLBox, LB_SETHORIZONTALEXTENT, wParam, 0);
-       case CB_GETTOPINDEX:
-               return SendMessageW(lphc->hWndLBox, LB_GETTOPINDEX, 0, 0);
-       case CB_GETLOCALE:
-               return SendMessageW(lphc->hWndLBox, LB_GETLOCALE, 0, 0);
-       case CB_SETLOCALE:
-               return SendMessageW(lphc->hWndLBox, LB_SETLOCALE, wParam, 0);
-        case CB_SETDROPPEDWIDTH:
-                if( (CB_GETTYPE(lphc) == CBS_SIMPLE) ||
-                    (INT)wParam >= 32768 )
-                    return CB_ERR;
-                /* new value must be higher than combobox width */
-                if((INT)wParam >= lphc->droppedRect.right - lphc->droppedRect.left)
-                    lphc->droppedWidth = wParam;
-                else if(wParam)
-                    lphc->droppedWidth = 0;
-
-                /* recalculate the combobox area */
-                CBCalcPlacement(hwnd, lphc, &lphc->textRect, &lphc->buttonRect, &lphc->droppedRect );
-
-                /* fall through */
-       case CB_GETDROPPEDWIDTH:
-               if( lphc->droppedWidth )
-                    return  lphc->droppedWidth;
-               return  lphc->droppedRect.right - lphc->droppedRect.left;
-       case CB_GETDROPPEDCONTROLRECT:
-               if( lParam ) CBGetDroppedControlRect(lphc, (LPRECT)lParam );
-               return  CB_OKAY;
-       case CB_GETDROPPEDSTATE:
-               return  (lphc->wState & CBF_DROPPED) ? TRUE : FALSE;
-       case CB_DIR:
-               return unicode ? SendMessageW(lphc->hWndLBox, LB_DIR, wParam, lParam) :
-                                SendMessageA(lphc->hWndLBox, LB_DIR, wParam, lParam);
-
-       case CB_SHOWDROPDOWN:
-               if( CB_GETTYPE(lphc) != CBS_SIMPLE )
-               {
-                   if( wParam )
-                   {
-                       if( !(lphc->wState & CBF_DROPPED) )
-                           CBDropDown( lphc );
-                   }
-                   else
-                       if( lphc->wState & CBF_DROPPED )
-                           CBRollUp( lphc, FALSE, TRUE );
-               }
-               return  TRUE;
-       case CB_GETCOUNT:
-               return SendMessageW(lphc->hWndLBox, LB_GETCOUNT, 0, 0);
-       case CB_GETCURSEL:
-               return SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
-       case CB_SETCURSEL:
-               lParam = SendMessageW(lphc->hWndLBox, LB_SETCURSEL, wParam, 0);
-               if( lParam >= 0 )
-                   SendMessageW(lphc->hWndLBox, LB_SETTOPINDEX, wParam, 0);
-
-               /* no LBN_SELCHANGE in this case, update manually */
-               if( lphc->wState & CBF_EDIT )
-                   CBUpdateEdit( lphc, (INT)wParam );
-               else
-                   InvalidateRect(lphc->self, &lphc->textRect, TRUE);
-               lphc->wState &= ~CBF_SELCHANGE;
-               return  lParam;
-       case CB_GETLBTEXT:
-               return unicode ? SendMessageW(lphc->hWndLBox, LB_GETTEXT, wParam, lParam) :
-                                SendMessageA(lphc->hWndLBox, LB_GETTEXT, wParam, lParam);
-       case CB_GETLBTEXTLEN:
-                return unicode ? SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0) :
-                                 SendMessageA(lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0);
-       case CB_GETITEMDATA:
-               return SendMessageW(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0);
-       case CB_SETITEMDATA:
-               return SendMessageW(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam);
-       case CB_GETEDITSEL:
-               /* Edit checks passed parameters itself */
-               if( lphc->wState & CBF_EDIT )
-                   return SendMessageW(lphc->hWndEdit, EM_GETSEL, wParam, lParam);
-               return  CB_ERR;
-       case CB_SETEDITSEL:
-               if( lphc->wState & CBF_EDIT )
-                    return SendMessageW(lphc->hWndEdit, EM_SETSEL,
-                         (INT)(INT16)LOWORD(lParam), (INT)(INT16)HIWORD(lParam) );
-               return  CB_ERR;
-       case CB_SETEXTENDEDUI:
-                if( CB_GETTYPE(lphc) == CBS_SIMPLE )
-                    return  CB_ERR;
-               if( wParam )
-                   lphc->wState |= CBF_EUI;
-               else lphc->wState &= ~CBF_EUI;
-               return  CB_OKAY;
-       case CB_GETEXTENDEDUI:
-               return  (lphc->wState & CBF_EUI) ? TRUE : FALSE;
-       case CB_GETCOMBOBOXINFO:
-               return COMBO_GetComboBoxInfo(lphc, (COMBOBOXINFO *)lParam);
-       case CB_LIMITTEXT:
-               if( lphc->wState & CBF_EDIT )
-                       return SendMessageW(lphc->hWndEdit, EM_LIMITTEXT, wParam, lParam);
-                return  TRUE;
+            ret = SendMessageA(lphc->hWndLBox, LB_ADDSTRING, 0, string ? (LPARAM)string : lParam);
+            HeapFree(GetProcessHeap(), 0, string);
+            return ret;
+        }
+    case CB_INSERTSTRING:
+        if (unicode)
+        {
+            if (lphc->dwStyle & CBS_LOWERCASE)
+                CharLowerW((LPWSTR)lParam);
+            else if (lphc->dwStyle & CBS_UPPERCASE)
+                CharUpperW((LPWSTR)lParam);
+            return SendMessageW(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam);
+        }
+        else
+        {
+            if (lphc->dwStyle & CBS_LOWERCASE)
+                CharLowerA((LPSTR)lParam);
+            else if (lphc->dwStyle & CBS_UPPERCASE)
+                CharUpperA((LPSTR)lParam);
+            return SendMessageA(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam);
+        }
+    case CB_DELETESTRING:
+        return unicode ? SendMessageW(lphc->hWndLBox, LB_DELETESTRING, wParam, 0) :
+                         SendMessageA(lphc->hWndLBox, LB_DELETESTRING, wParam, 0);
+    case CB_SELECTSTRING:
+        return COMBO_SelectString(lphc, (INT)wParam, lParam, unicode);
+    case CB_FINDSTRING:
+        return unicode ? SendMessageW(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam) :
+                         SendMessageA(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam);
+    case CB_FINDSTRINGEXACT:
+        return unicode ? SendMessageW(lphc->hWndLBox, LB_FINDSTRINGEXACT, wParam, lParam) :
+                         SendMessageA(lphc->hWndLBox, LB_FINDSTRINGEXACT, wParam, lParam);
+    case CB_SETITEMHEIGHT:
+        return  COMBO_SetItemHeight( lphc, (INT)wParam, (INT)lParam);
+    case CB_GETITEMHEIGHT:
+        if ((INT)wParam >= 0) /* listbox item */
+            return SendMessageW(lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0);
+        return  CBGetTextAreaHeight(hwnd, lphc);
+    case CB_RESETCONTENT:
+        SendMessageW(lphc->hWndLBox, LB_RESETCONTENT, 0, 0);
+        if ((lphc->wState & CBF_EDIT) && CB_HASSTRINGS(lphc))
+        {
+            static const WCHAR empty_stringW[] = { 0 };
+            SendMessageW(lphc->hWndEdit, WM_SETTEXT, 0, (LPARAM)empty_stringW);
+        }
+        else
+            InvalidateRect(lphc->self, NULL, TRUE);
+        return  TRUE;
+    case CB_INITSTORAGE:
+        return SendMessageW(lphc->hWndLBox, LB_INITSTORAGE, wParam, lParam);
+    case CB_GETHORIZONTALEXTENT:
+        return SendMessageW(lphc->hWndLBox, LB_GETHORIZONTALEXTENT, 0, 0);
+    case CB_SETHORIZONTALEXTENT:
+        return SendMessageW(lphc->hWndLBox, LB_SETHORIZONTALEXTENT, wParam, 0);
+    case CB_GETTOPINDEX:
+        return SendMessageW(lphc->hWndLBox, LB_GETTOPINDEX, 0, 0);
+    case CB_GETLOCALE:
+        return SendMessageW(lphc->hWndLBox, LB_GETLOCALE, 0, 0);
+    case CB_SETLOCALE:
+        return SendMessageW(lphc->hWndLBox, LB_SETLOCALE, wParam, 0);
+    case CB_SETDROPPEDWIDTH:
+        if ((CB_GETTYPE(lphc) == CBS_SIMPLE) || (INT)wParam >= 32768)
+            return CB_ERR;
+        /* new value must be higher than combobox width */
+        if ((INT)wParam >= lphc->droppedRect.right - lphc->droppedRect.left)
+            lphc->droppedWidth = wParam;
+        else if (wParam)
+            lphc->droppedWidth = 0;
+
+        /* recalculate the combobox area */
+        CBCalcPlacement(hwnd, lphc, &lphc->textRect, &lphc->buttonRect, &lphc->droppedRect );
+
+        /* fall through */
+    case CB_GETDROPPEDWIDTH:
+        if (lphc->droppedWidth)
+            return lphc->droppedWidth;
+        return  lphc->droppedRect.right - lphc->droppedRect.left;
+    case CB_GETDROPPEDCONTROLRECT:
+        if (lParam) CBGetDroppedControlRect(lphc, (LPRECT)lParam );
+        return  CB_OKAY;
+    case CB_GETDROPPEDSTATE:
+        return (lphc->wState & CBF_DROPPED) != 0;
+    case CB_DIR:
+        return unicode ? SendMessageW(lphc->hWndLBox, LB_DIR, wParam, lParam) :
+                         SendMessageA(lphc->hWndLBox, LB_DIR, wParam, lParam);
+
+    case CB_SHOWDROPDOWN:
+        if (CB_GETTYPE(lphc) != CBS_SIMPLE)
+        {
+            if (wParam)
+            {
+                if (!(lphc->wState & CBF_DROPPED))
+                    CBDropDown( lphc );
+            }
+            else if (lphc->wState & CBF_DROPPED)
+                CBRollUp( lphc, FALSE, TRUE );
+        }
+        return  TRUE;
+    case CB_GETCOUNT:
+        return SendMessageW(lphc->hWndLBox, LB_GETCOUNT, 0, 0);
+    case CB_GETCURSEL:
+        return SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
+    case CB_SETCURSEL:
+        lParam = SendMessageW(lphc->hWndLBox, LB_SETCURSEL, wParam, 0);
+        if (lParam >= 0)
+            SendMessageW(lphc->hWndLBox, LB_SETTOPINDEX, wParam, 0);
+
+        /* no LBN_SELCHANGE in this case, update manually */
+        CBPaintText(lphc, NULL);
+        lphc->wState &= ~CBF_SELCHANGE;
+        return lParam;
+    case CB_GETLBTEXT:
+        return unicode ? SendMessageW(lphc->hWndLBox, LB_GETTEXT, wParam, lParam) :
+                         SendMessageA(lphc->hWndLBox, LB_GETTEXT, wParam, lParam);
+    case CB_GETLBTEXTLEN:
+        return unicode ? SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0) :
+                         SendMessageA(lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0);
+    case CB_GETITEMDATA:
+        return SendMessageW(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0);
+    case CB_SETITEMDATA:
+        return SendMessageW(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam);
+    case CB_GETEDITSEL:
+        /* Edit checks passed parameters itself */
+        if (lphc->wState & CBF_EDIT)
+            return SendMessageW(lphc->hWndEdit, EM_GETSEL, wParam, lParam);
+        return  CB_ERR;
+    case CB_SETEDITSEL:
+        if (lphc->wState & CBF_EDIT)
+            return SendMessageW(lphc->hWndEdit, EM_SETSEL, (INT)(INT16)LOWORD(lParam), (INT)(INT16)HIWORD(lParam) );
+        return  CB_ERR;
+    case CB_SETEXTENDEDUI:
+        if (CB_GETTYPE(lphc) == CBS_SIMPLE )
+            return  CB_ERR;
+        if (wParam)
+            lphc->wState |= CBF_EUI;
+        else lphc->wState &= ~CBF_EUI;
+        return  CB_OKAY;
+    case CB_GETEXTENDEDUI:
+        return (lphc->wState & CBF_EUI) != 0;
+    case CB_GETCOMBOBOXINFO:
+        return COMBO_GetComboBoxInfo(lphc, (COMBOBOXINFO *)lParam);
+    case CB_LIMITTEXT:
+        if (lphc->wState & CBF_EDIT)
+            return SendMessageW(lphc->hWndEdit, EM_LIMITTEXT, wParam, lParam);
+        return  TRUE;
 
+#ifdef __REACTOS__
     case WM_UPDATEUISTATE:
         if (unicode)
             DefWindowProcW(lphc->self, message, wParam, lParam);
@@ -2223,52 +2248,67 @@ LRESULT WINAPI ComboWndProc_common( HWND hwnd, UINT message,
         if (COMBO_update_uistate(lphc))
         {
            /* redraw text */
-           if( !(lphc->wState & CBF_EDIT) )
+           if (!(lphc->wState & CBF_EDIT))
                 NtUserInvalidateRect(lphc->self, &lphc->textRect, TRUE);
         }
         break;
 
-       default:
-               if (message >= WM_USER)
-                   WARN("unknown msg WM_USER+%04x wp=%04lx lp=%08lx\n",
-                       message - WM_USER, wParam, lParam );
-               break;
-      }
-      return unicode ? DefWindowProcW(hwnd, message, wParam, lParam) :
-                       DefWindowProcA(hwnd, message, wParam, lParam);
+    case WM_CBLOSTTEXTFOCUS: /* undocumented message - deselects the text when focus is lost */
+        if (lphc->hWndEdit != NULL)
+        {
+            SendMessage(lphc->self, WM_LBUTTONUP, 0, 0xFFFFFFFF);
+            SendMessage(lphc->hWndEdit, EM_SETSEL, 0, 0);
+            lphc->wState &= ~(CBF_FOCUSED | CBF_BEENFOCUSED);
+            CB_NOTIFY(lphc, CBN_KILLFOCUS);
+        }
+        return TRUE;
+#endif
+
+    default:
+        if (message >= WM_USER)
+            WARN("unknown msg WM_USER+%04x wp=%04lx lp=%08lx\n", message - WM_USER, wParam, lParam );
+        break;
+    }
+    return unicode ? DefWindowProcW(hwnd, message, wParam, lParam) :
+                     DefWindowProcA(hwnd, message, wParam, lParam);
 }
 
+#ifdef __REACTOS__
+
 /***********************************************************************
  *           ComboWndProcA
  *
  * This is just a wrapper for the real ComboWndProc which locks/unlocks
  * window structs.
  */
-LRESULT WINAPI ComboWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
+LRESULT WINAPI ComboWndProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
     if (!IsWindow(hwnd)) return 0;
-    return ComboWndProc_common( hwnd, message, wParam, lParam, FALSE );
+    return ComboWndProc_common(hwnd, message, wParam, lParam, FALSE);
 }
 
 /***********************************************************************
  *           ComboWndProcW
  */
-LRESULT WINAPI ComboWndProcW( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
+LRESULT WINAPI ComboWndProcW(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
     if (!IsWindow(hwnd)) return 0;
-    return ComboWndProc_common( hwnd, message, wParam, lParam, TRUE );
+    return ComboWndProc_common(hwnd, message, wParam, lParam, TRUE);
 }
 
+#endif /* __REACTOS__ */
+
 /*************************************************************************
  *           GetComboBoxInfo   (USER32.@)
  */
-BOOL WINAPI GetComboBoxInfo(HWND hwndCombo,      /* [in] handle to combo box */
-                           PCOMBOBOXINFO pcbi   /* [in/out] combo box information */)
+BOOL WINAPI GetComboBoxInfo(
+    HWND hwndCombo,      /* [in] handle to combo box */
+    PCOMBOBOXINFO pcbi   /* [in/out] combo box information */)
 {
     TRACE("(%p, %p)\n", hwndCombo, pcbi);
-#ifndef __REACTOS__
-    return SendMessageW(hwndCombo, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi);
-#else
+#ifdef __REACTOS__
     return NtUserGetComboBoxInfo(hwndCombo, pcbi);
+#else
+    return SendMessageW(hwndCombo, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi);
 #endif
 }