Index: trunk/src/user32/combo.cpp
===================================================================
--- trunk/src/user32/combo.cpp	(revision 1783)
+++ trunk/src/user32/combo.cpp	(revision 1784)
@@ -1,3 +1,3 @@
-/* $Id: combo.cpp,v 1.15 1999-11-19 17:59:33 cbratschi Exp $ */
+/* $Id: combo.cpp,v 1.16 1999-11-19 21:22:01 cbratschi Exp $ */
 /*
  * Combo controls
@@ -14,4 +14,5 @@
  - problems with focus handling (Win32 <-> OS/2)
    will be fixed soon
+ - several other bugs
 */
 
@@ -30,5 +31,4 @@
  */
 
-#define CB_GETPTR( hwnd )      ((LPHEADCOMBO)(GetInfoPtr(hwnd)))
 #define CB_NOTIFY( lphc, code ) \
         (SendMessageA( (lphc)->owner, WM_COMMAND, \
@@ -38,10 +38,4 @@
 
 /*
- * Drawing globals
- */
-static HBITMAP  hComboBmp = 0;
-static UINT     CBitHeight, CBitWidth;
-
-/*
  * Look and feel dependant "constants"
  */
@@ -53,44 +47,4 @@
 
 /***********************************************************************
- *           COMBO_Init
- *
- * Load combo button bitmap.
- */
-static BOOL COMBO_Init()
-{
-  HDC           hDC;
-
-  if( hComboBmp ) return TRUE;
-  hDC = CreateCompatibleDC(0);
-  if(hDC)
-  {
-    BOOL      bRet = FALSE;
-
-    hComboBmp = LoadBitmapA(hInstanceUser32, MAKEINTRESOURCEA(OBM_COMBO));
-    if(hComboBmp)
-    {
-      BITMAP      bm;
-      HBITMAP     hPrevB;
-      RECT        r;
-
-      GetObjectA( hComboBmp, sizeof(bm), &bm );
-      CBitHeight = bm.bmHeight;
-      CBitWidth  = bm.bmWidth;
-
-      //TRACE("combo bitmap [%i,%i]\n", CBitWidth, CBitHeight );
-
-      hPrevB = SelectObject( hDC, hComboBmp);
-      SetRect( &r, 0, 0, CBitWidth, CBitHeight );
-      InvertRect( hDC, &r );
-      SelectObject( hDC, hPrevB );
-      bRet = TRUE;
-    }
-    DeleteDC( hDC );
-    return bRet;
-  }
-  return FALSE;
-}
-
-/***********************************************************************
  *           COMBO_NCCreate
  */
@@ -99,5 +53,5 @@
    LPHEADCOMBO          lphc;
 
-   if ( hwnd && COMBO_Init() &&
+   if ( hwnd &&
       (lphc = (LPHEADCOMBO)HeapAlloc(GetProcessHeap(), 0, sizeof(HEADCOMBO))) )
    {
@@ -144,6 +98,4 @@
    if( lphc )
    {
-       HWND hwnd = lphc->hwndself;
-
        //TRACE("[%04x]: freeing storage\n", CB_HWND(lphc));
 
@@ -942,5 +894,5 @@
   HDC   hDC;
 
-  hDC = (wParam) ? (HDC)wParam:BeginPaint( lphc->hwndself, &ps);
+  hDC = (wParam) ? (HDC)wParam:BeginPaint(hwnd,&ps);
 
 
@@ -953,5 +905,5 @@
        * DC.
        */
-      hBkgBrush = COMBO_PrepareColors(lphc->hwndself, lphc, hDC);
+      hBkgBrush = COMBO_PrepareColors(hwnd,lphc,hDC);
 
       hPrevBrush = SelectObject( hDC, hBkgBrush );
@@ -980,5 +932,5 @@
   }
 
-  if(!wParam) EndPaint(lphc->hwndself, &ps);
+  if(!wParam) EndPaint(hwnd,&ps);
 
   return 0;
@@ -1447,12 +1399,11 @@
 
 /***********************************************************************
- *           COMBO_ItemOp
+ *           COMBO_HandleItem
  *
  * Fixup an ownerdrawn item operation and pass it up to the combobox owner.
  */
-static LRESULT COMBO_ItemOp( LPHEADCOMBO lphc, UINT msg,
-                               WPARAM wParam, LPARAM lParam )
-{
-   HWND hWnd = lphc->hwndself;
+static LRESULT COMBO_HandleItem(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+   LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
 
    //TRACE("[%04x]: ownerdraw op %04x\n", CB_HWND(lphc), msg );
@@ -1462,25 +1413,25 @@
    /* two first items are the same in all 4 structs */
    lpIS->CtlType = ODT_COMBOBOX;
-   lpIS->CtlID   = GetWindowLongA(lphc->hwndself,GWL_ID);
+   lpIS->CtlID   = GetWindowLongA(hwnd,GWL_ID);
 
    switch( msg )        /* patch window handle */
    {
         case WM_DELETEITEM:
-             lpIS->hwndItem = hWnd;
+             lpIS->hwndItem = hwnd;
 #undef  lpIS
              break;
         case WM_DRAWITEM:
 #define lpIS    ((LPDRAWITEMSTRUCT)lParam)
-             lpIS->hwndItem = hWnd;
+             lpIS->hwndItem = hwnd;
 #undef  lpIS
              break;
         case WM_COMPAREITEM:
 #define lpIS    ((LPCOMPAREITEMSTRUCT)lParam)
-             lpIS->hwndItem = hWnd;
+             lpIS->hwndItem = hwnd;
 #undef  lpIS
              break;
    }
 
-   return SendMessageA( lphc->owner, msg, GetWindowLongA(lphc->hwndself,GWL_ID), lParam );
+   return SendMessageA( lphc->owner, msg, GetWindowLongA(hwnd,GWL_ID), lParam );
 }
 
@@ -1535,4 +1486,21 @@
 }
 
+static LRESULT COMBO_HandleText(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  if ((message == WM_GETTEXTLENGTH) && !(lphc->wState & CBF_EDIT))
+  {
+    int j = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
+
+    if (j == -1) return 0;
+    return SendMessageA( lphc->hWndLBox, LB_GETTEXTLEN, j, 0);
+  } else if( lphc->wState & CBF_EDIT )
+  {
+    lphc->wState |= CBF_NOEDITNOTIFY;
+
+    return SendMessageA( lphc->hWndEdit, message, wParam, lParam );
+  } else return  CB_ERR;
+}
 
 /***********************************************************************
@@ -1592,5 +1560,5 @@
   if(lphc->hWndLBox && !(lphc->wState & CBF_NORESIZE))
   {
-    CBCalcPlacement(lphc->hwndself,
+    CBCalcPlacement(hwnd,
                     lphc,
                     &lphc->textRect,
@@ -1629,5 +1597,5 @@
   if ( CB_GETTYPE(lphc) == CBS_SIMPLE)
   {
-    CBCalcPlacement(lphc->hwndself,
+    CBCalcPlacement(hwnd,
                     lphc,
                     &lphc->textRect,
@@ -1654,70 +1622,14 @@
 
 /***********************************************************************
- *           COMBO_SetItemHeight
- */
-static LRESULT COMBO_SetItemHeight( LPHEADCOMBO lphc, INT index, INT height )
-{
-   LRESULT      lRet = CB_ERR;
-
-   if( index == -1 ) /* set text field height */
-   {
-       if( height < 32768 )
-       {
-           lphc->editHeight = height;
-
-         /*
-          * Redo the layout of the control.
-          */
-         if ( CB_GETTYPE(lphc) == CBS_SIMPLE)
-         {
-           CBCalcPlacement(lphc->hwndself,
-                           lphc,
-                           &lphc->textRect,
-                           &lphc->buttonRect,
-                           &lphc->droppedRect);
-
-           CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
-         }
-         else
-         {
-           CBForceDummyResize(lphc);
-         }
-
-           lRet = height;
-       }
-   }
-   else if ( CB_OWNERDRAWN(lphc) )      /* set listbox item height */
-        lRet = SendMessageA( lphc->hWndLBox, LB_SETITEMHEIGHT,
-                              (WPARAM)index, (LPARAM)height );
-   return lRet;
-}
-
-/***********************************************************************
- *           COMBO_SelectString
- */
-static LRESULT COMBO_SelectString( LPHEADCOMBO lphc, INT start, LPCSTR pText )
-{
-   INT index = SendMessageA( lphc->hWndLBox, LB_SELECTSTRING,
-                                 (WPARAM)start, (LPARAM)pText );
-   if( index >= 0 )
-   {
-     if( lphc->wState & CBF_EDIT )
-       CBUpdateEdit( lphc, index );
-     else
-     {
-       InvalidateRect(CB_HWND(lphc), &lphc->textRect, TRUE);
-     }
-   }
-   return (LRESULT)index;
-}
-
-/***********************************************************************
  *           COMBO_LButtonDown
  */
-static void COMBO_LButtonDown( LPHEADCOMBO lphc, LPARAM lParam )
-{
+static LRESULT COMBO_LButtonDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+   LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
    POINT     pt;
    BOOL      bButton;
-   HWND      hWnd = lphc->hwndself;
+
+   if(!(lphc->wState & CBF_FOCUSED)) SetFocus(hwnd);
+   if(!(lphc->wState & CBF_FOCUSED)) return 0;
 
    pt.x = LOWORD(lParam);
@@ -1735,5 +1647,5 @@
            lphc->wState &= ~CBF_BUTTONDOWN;
            CBRollUp( lphc, TRUE, FALSE );
-           if( !IsWindow( hWnd ) ) return;
+           if( !IsWindow( hwnd ) ) return 0;
 
            if( lphc->wState & CBF_CAPTURE )
@@ -1749,8 +1661,10 @@
            lphc->wState |= CBF_CAPTURE;
            CBDropDown( lphc );
-           SetCapture( hWnd );
+           SetCapture( hwnd );
        }
        if( bButton ) CBRepaintButton( lphc );
    }
+
+   return 0;
 }
 
@@ -1760,6 +1674,8 @@
  * Release capture and stop tracking if needed.
  */
-static void COMBO_LButtonUp( LPHEADCOMBO lphc, LPARAM lParam )
-{
+static LRESULT COMBO_LButtonUp(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+   LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
    if( lphc->wState & CBF_CAPTURE )
    {
@@ -1780,4 +1696,6 @@
        CBRepaintButton( lphc );
    }
+
+   return 0;
 }
 
@@ -1788,8 +1706,11 @@
  * pointer goes into the listbox.
  */
-static void COMBO_MouseMove( LPHEADCOMBO lphc, WPARAM wParam, LPARAM lParam )
-{
+static LRESULT COMBO_MouseMove(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+   LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
    POINT  pt;
    RECT   lbRect;
+
+   if(!(lphc->wState & CBF_CAPTURE)) return 0;
 
    pt.x = LOWORD(lParam);
@@ -1810,5 +1731,5 @@
 
    GetClientRect( lphc->hWndLBox, &lbRect );
-   MapWindowPoints( lphc->hwndself, lphc->hWndLBox, &pt, 1 );
+   MapWindowPoints(hwnd, lphc->hWndLBox, &pt, 1 );
    if( PtInRect(&lbRect, pt) )
    {
@@ -1820,6 +1741,383 @@
        SendMessageA( lphc->hWndLBox, WM_LBUTTONDOWN, wParam, lParam );
    }
-}
-
+
+   return 0;
+}
+
+static LRESULT COMBO_Enable(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  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(CB_HWND(lphc), NULL, TRUE);
+
+  return 0;
+}
+
+static LRESULT COMBO_SetRedraw(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  if( wParam )
+    lphc->wState &= ~CBF_NOREDRAW;
+  else
+    lphc->wState |= CBF_NOREDRAW;
+
+  if( lphc->wState & CBF_EDIT )
+    SendMessageA( lphc->hWndEdit, WM_SETREDRAW, wParam, lParam );
+  SendMessageA( lphc->hWndLBox, WM_SETREDRAW, wParam, lParam );
+
+  return 0;
+}
+
+static LRESULT COMBO_SysKeyDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  if( KEYDATA_ALT & HIWORD(lParam) )
+    if( wParam == VK_UP || wParam == VK_DOWN )
+      COMBO_FlipListbox( lphc, TRUE );
+
+  return DefWindowProcA(hwnd,WM_SYSKEYDOWN,wParam,lParam);
+}
+
+static LRESULT COMBO_HandleKey(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  if( lphc->wState & CBF_EDIT )
+    return  SendMessageA( lphc->hWndEdit, message, wParam, lParam );
+  else
+    return  SendMessageA( lphc->hWndLBox, message, wParam, lParam );
+}
+
+/* combobox messages */
+
+static LRESULT COMBO_AddString(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA(lphc->hWndLBox,LB_ADDSTRING,0,lParam);
+}
+
+static LRESULT COMBO_InsertString(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA(lphc->hWndLBox,LB_INSERTSTRING,wParam,lParam);
+}
+
+static LRESULT COMBO_DeleteString(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA(lphc->hWndLBox,LB_DELETESTRING,wParam,0);
+}
+
+/***********************************************************************
+ *           COMBO_SelectString
+ */
+static LRESULT COMBO_SelectString(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+  INT index = SendMessageA(lphc->hWndLBox,LB_SELECTSTRING,wParam,lParam);
+
+  if( index >= 0 )
+  {
+    if( lphc->wState & CBF_EDIT )
+      CBUpdateEdit( lphc, index );
+    else
+      InvalidateRect(CB_HWND(lphc), &lphc->textRect, TRUE);
+  }
+
+  return (LRESULT)index;
+}
+
+static LRESULT COMBO_FindString(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA(lphc->hWndLBox,LB_FINDSTRING,wParam,lParam);
+}
+
+static LRESULT COMBO_FindStringExact(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA(lphc->hWndLBox,LB_FINDSTRINGEXACT,wParam,lParam);
+}
+
+/***********************************************************************
+ *           COMBO_SetItemHeight
+ */
+static LRESULT COMBO_SetItemHeight(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+   LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+   LRESULT      lRet = CB_ERR;
+
+   if( wParam == -1 ) /* set text field height */
+   {
+       if( lParam < 32768 )
+       {
+           lphc->editHeight = lParam;
+
+         /*
+          * Redo the layout of the control.
+          */
+         if ( CB_GETTYPE(lphc) == CBS_SIMPLE)
+         {
+           CBCalcPlacement(hwnd,
+                           lphc,
+                           &lphc->textRect,
+                           &lphc->buttonRect,
+                           &lphc->droppedRect);
+
+           CBResetPos( lphc, &lphc->textRect, &lphc->droppedRect, TRUE );
+         }
+         else
+         {
+           CBForceDummyResize(lphc);
+         }
+
+           lRet = lParam;
+       }
+   }
+   else if ( CB_OWNERDRAWN(lphc) )      /* set listbox item height */
+        lRet = SendMessageA( lphc->hWndLBox, LB_SETITEMHEIGHT,
+                              wParam,lParam);
+   return lRet;
+}
+
+static LRESULT COMBO_GetItemHeight(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  if( (INT)wParam >= 0 )  /* listbox item */
+    return SendMessageA( lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0);
+
+  return CBGetTextAreaHeight(hwnd, lphc);
+}
+
+static LRESULT COMBO_ResetContent(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  SendMessageA( lphc->hWndLBox, LB_RESETCONTENT, 0, 0 );
+  InvalidateRect(CB_HWND(lphc), NULL, TRUE);
+
+  return  TRUE;
+}
+
+static LRESULT COMBO_InitStorage(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA( lphc->hWndLBox, LB_INITSTORAGE, wParam, lParam);
+}
+
+static LRESULT COMBO_GetHorizontalExtent(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA( lphc->hWndLBox, LB_GETHORIZONTALEXTENT, 0, 0);
+}
+
+static LRESULT COMBO_SetHorizontalExtent(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA( lphc->hWndLBox, LB_SETHORIZONTALEXTENT, wParam, 0);
+}
+
+static LRESULT COMBO_GetTopIndex(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA( lphc->hWndLBox, LB_GETTOPINDEX, 0, 0);
+}
+
+static LRESULT COMBO_GetLocale(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA( lphc->hWndLBox, LB_GETLOCALE, 0, 0);
+}
+
+static LRESULT COMBO_SetLocale(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA( lphc->hWndLBox, LB_SETLOCALE, wParam, 0);
+}
+
+static LRESULT COMBO_GetDroppedWidth(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  if( lphc->droppedWidth )
+    return  lphc->droppedWidth;
+
+  return lphc->droppedRect.right - lphc->droppedRect.left;
+}
+
+static LRESULT COMBO_SetDroppedWidth(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  if( (CB_GETTYPE(lphc) != CBS_SIMPLE) &&
+      (INT)wParam < 32768 ) lphc->droppedWidth = (INT)wParam;
+
+  return CB_ERR;
+}
+
+static LRESULT COMBO_GetDroppedControlRect(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  if( lParam ) CBGetDroppedControlRect(lphc, (LPRECT)lParam );
+
+  return CB_OKAY;
+}
+
+static LRESULT COMBO_GetDroppedState(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return (lphc->wState & CBF_DROPPED) ? TRUE : FALSE;
+}
+
+static LRESULT COMBO_Dir(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return COMBO_Directory( lphc, (UINT)wParam,
+                          (LPSTR)lParam,TRUE);
+}
+
+static LRESULT COMBO_ShowDropDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  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;
+}
+
+static LRESULT COMBO_GetCount(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA( lphc->hWndLBox, LB_GETCOUNT, 0, 0);
+}
+
+static LRESULT COMBO_GetCurSel(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0);
+}
+
+static LRESULT COMBO_SetCurSel(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  lParam = SendMessageA( lphc->hWndLBox, LB_SETCURSEL, wParam, 0);
+  if( lphc->wState & CBF_SELCHANGE )
+  {
+    /* no LBN_SELCHANGE in this case, update manually */
+    InvalidateRect(CB_HWND(lphc), &lphc->textRect, TRUE);
+    lphc->wState &= ~CBF_SELCHANGE;
+  }
+
+  return lParam;
+}
+
+static LRESULT COMBO_GetLBText(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA( lphc->hWndLBox, LB_GETTEXT, wParam, lParam);
+}
+
+static LRESULT COMBO_GetLBTextLen(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA( lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0);
+}
+
+static LRESULT COMBO_GetItemData(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA( lphc->hWndLBox, LB_GETITEMDATA, wParam, 0);
+}
+
+static LRESULT COMBO_SetItemData(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return SendMessageA( lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam);
+}
+
+static LRESULT COMBO_GetEditSel(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  if( lphc->wState & CBF_EDIT )
+  {
+    INT a, b;
+
+    return  SendMessageA( lphc->hWndEdit, EM_GETSEL,
+                          (wParam) ? wParam : (WPARAM)&a,
+                          (lParam) ? lParam : (LPARAM)&b );
+  }
+
+  return CB_ERR;
+}
+
+static LRESULT COMBO_SetEditSel(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  if( lphc->wState & CBF_EDIT )
+    return  SendMessageA( lphc->hWndEdit, EM_SETSEL,
+                          (INT)(INT16)LOWORD(lParam), (INT)(INT16)HIWORD(lParam) );
+
+  return CB_ERR;
+}
+
+static LRESULT COMBO_SetExtendedUI(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  if( CB_GETTYPE(lphc) == CBS_SIMPLE )
+    return  CB_ERR;
+  if( wParam )
+    lphc->wState |= CBF_EUI;
+  else lphc->wState &= ~CBF_EUI;
+    return CB_OKAY;
+}
+
+static LRESULT COMBO_GetExtendedUI(HWND hwnd,WPARAM wParam,LPARAM lParam)
+{
+  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
+
+  return (lphc->wState & CBF_EUI) ? TRUE : FALSE;
+}
 
 /***********************************************************************
@@ -1831,14 +2129,7 @@
                              WPARAM wParam, LPARAM lParam )
 {
-      LPHEADCOMBO   lphc = NULL;
-      LONG          ptr = GetInfoPtr(hwnd);
-
-      if(ptr)
-        lphc = (LPHEADCOMBO)ptr;
-
       //TRACE("[%04x]: msg %s wp %08x lp %08lx\n",
       //             pWnd->hwndSelf, SPY_GetMsgName(message), wParam, lParam );
 
-      if( lphc || message == WM_NCCREATE )
       switch(message)
       {
@@ -1890,5 +2181,5 @@
         case WM_GETTEXT:
           return COMBO_GetText(hwnd,wParam,lParam);
-//CB:
+
         case WM_SETTEXT:
         case WM_GETTEXTLENGTH:
@@ -1897,174 +2188,132 @@
         case WM_PASTE:
         case WM_COPY:
-                if ((message == WM_GETTEXTLENGTH) && !(lphc->wState & CBF_EDIT))
-                {
-                int j = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
-                if (j == -1) return 0;
-                return SendMessageA( lphc->hWndLBox, LB_GETTEXTLEN, j, 0);
-                }
-                else if( lphc->wState & CBF_EDIT )
-                {
-                    lphc->wState |= CBF_NOEDITNOTIFY;
-
-                    return SendMessageA( lphc->hWndEdit, message, wParam, lParam );
-                }
-                else return  CB_ERR;
+          return COMBO_HandleText(hwnd,message,wParam,lParam);
+
         case WM_DRAWITEM:
         case WM_DELETEITEM:
         case WM_COMPAREITEM:
         case WM_MEASUREITEM:
-                return  COMBO_ItemOp( lphc, message, wParam, lParam );
+          return COMBO_HandleItem(hwnd,message,wParam,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(CB_HWND(lphc), NULL, TRUE);
-                return  TRUE;
+          return COMBO_Enable(hwnd,wParam,lParam);
+
         case WM_SETREDRAW:
-                if( wParam )
-                    lphc->wState &= ~CBF_NOREDRAW;
-                else
-                    lphc->wState |= CBF_NOREDRAW;
-
-                if( lphc->wState & CBF_EDIT )
-                    SendMessageA( lphc->hWndEdit, message, wParam, lParam );
-                SendMessageA( lphc->hWndLBox, message, wParam, lParam );
-                return  0;
+          return COMBO_SetRedraw(hwnd,wParam,lParam);
+
         case WM_SYSKEYDOWN:
-                if( KEYDATA_ALT & HIWORD(lParam) )
-                    if( wParam == VK_UP || wParam == VK_DOWN )
-                        COMBO_FlipListbox( lphc, TRUE );
-                break;/* -> DefWindowProc */
+          return COMBO_SysKeyDown(hwnd,wParam,lParam);
 
         case WM_CHAR:
         case WM_KEYDOWN:
-                if( lphc->wState & CBF_EDIT )
-                    return  SendMessageA( lphc->hWndEdit, message, wParam, lParam );
-                else
-                    return  SendMessageA( lphc->hWndLBox, message, wParam, lParam );
+          return COMBO_HandleKey(hwnd,message,wParam,lParam);
+
         case WM_LBUTTONDOWN:
-                if( !(lphc->wState & CBF_FOCUSED) ) SetFocus( lphc->hwndself );
-                if( lphc->wState & CBF_FOCUSED ) COMBO_LButtonDown( lphc, lParam );
-                return  TRUE;
+          return COMBO_LButtonDown(hwnd,wParam,lParam);
+
         case WM_LBUTTONUP:
-                COMBO_LButtonUp( lphc, lParam );
-                return  TRUE;
+          return COMBO_LButtonUp(hwnd,wParam,lParam);
+
         case WM_MOUSEMOVE:
-                if( lphc->wState & CBF_CAPTURE )
-                    COMBO_MouseMove( lphc, wParam, lParam );
-                return  0;
+          return COMBO_MouseMove(hwnd,wParam,lParam);
+
         /* Combo messages */
 
         case CB_ADDSTRING:
-                return  SendMessageA( lphc->hWndLBox, LB_ADDSTRING, 0, lParam);
+          return COMBO_AddString(hwnd,wParam,lParam);
+
         case CB_INSERTSTRING:
-                return  SendMessageA( lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam);
+          return COMBO_InsertString(hwnd,wParam,lParam);
+
         case CB_DELETESTRING:
-                return  SendMessageA( lphc->hWndLBox, LB_DELETESTRING, wParam, 0);
+          return COMBO_DeleteString(hwnd,wParam,lParam);
+
         case CB_SELECTSTRING:
-                return  COMBO_SelectString( lphc, (INT)wParam, (LPSTR)lParam );
+          return COMBO_SelectString(hwnd,wParam,lParam);
+
         case CB_FINDSTRING:
-                return  SendMessageA( lphc->hWndLBox, LB_FINDSTRING, wParam, lParam);
+          return COMBO_FindString(hwnd,wParam,lParam);
+
         case CB_FINDSTRINGEXACT:
-                return  SendMessageA( lphc->hWndLBox, LB_FINDSTRINGEXACT,
-                                                       wParam, lParam );
+          return COMBO_FindStringExact(hwnd,wParam,lParam);
+
         case CB_SETITEMHEIGHT:
-                return  COMBO_SetItemHeight( lphc, (INT)wParam, (INT)lParam);
+          return COMBO_SetItemHeight(hwnd,wParam,lParam);
+
         case CB_GETITEMHEIGHT:
-                if( (INT)wParam >= 0 )  /* listbox item */
-                    return  SendMessageA( lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0);
-                return  CBGetTextAreaHeight(hwnd, lphc);
+          return COMBO_GetItemHeight(hwnd,wParam,lParam);
+
         case CB_RESETCONTENT:
-                SendMessageA( lphc->hWndLBox, LB_RESETCONTENT, 0, 0 );
-                InvalidateRect(CB_HWND(lphc), NULL, TRUE);
-                return  TRUE;
+          return COMBO_ResetContent(hwnd,wParam,lParam);
+
         case CB_INITSTORAGE:
-                return  SendMessageA( lphc->hWndLBox, LB_INITSTORAGE, wParam, lParam);
+          return COMBO_InitStorage(hwnd,wParam,lParam);
+
         case CB_GETHORIZONTALEXTENT:
-                return  SendMessageA( lphc->hWndLBox, LB_GETHORIZONTALEXTENT, 0, 0);
+          return COMBO_GetHorizontalExtent(hwnd,wParam,lParam);
+
         case CB_SETHORIZONTALEXTENT:
-                return  SendMessageA( lphc->hWndLBox, LB_SETHORIZONTALEXTENT, wParam, 0);
+          return COMBO_SetHorizontalExtent(hwnd,wParam,lParam);
+
         case CB_GETTOPINDEX:
-                return  SendMessageA( lphc->hWndLBox, LB_GETTOPINDEX, 0, 0);
+          return COMBO_GetTopIndex(hwnd,wParam,lParam);
+
         case CB_GETLOCALE:
-                return  SendMessageA( lphc->hWndLBox, LB_GETLOCALE, 0, 0);
+          return COMBO_GetLocale(hwnd,wParam,lParam);
+
         case CB_SETLOCALE:
-                return  SendMessageA( lphc->hWndLBox, LB_SETLOCALE, wParam, 0);
+          return COMBO_SetLocale(hwnd,wParam,lParam);
+
         case CB_GETDROPPEDWIDTH:
-                if( lphc->droppedWidth )
-                    return  lphc->droppedWidth;
-                return  lphc->droppedRect.right - lphc->droppedRect.left;
+          return COMBO_GetDroppedWidth(hwnd,wParam,lParam);
+
         case CB_SETDROPPEDWIDTH:
-                if( (CB_GETTYPE(lphc) != CBS_SIMPLE) &&
-                    (INT)wParam < 32768 ) lphc->droppedWidth = (INT)wParam;
-                return  CB_ERR;
+          return COMBO_SetDroppedWidth(hwnd,wParam,lParam);
+
         case CB_GETDROPPEDCONTROLRECT:
-                if( lParam ) CBGetDroppedControlRect(lphc, (LPRECT)lParam );
-                return  CB_OKAY;
+          return COMBO_GetDroppedControlRect(hwnd,wParam,lParam);
+
         case CB_GETDROPPEDSTATE:
-                return  (lphc->wState & CBF_DROPPED) ? TRUE : FALSE;
+          return COMBO_GetDroppedState(hwnd,wParam,lParam);
+
         case CB_DIR:
-                return  COMBO_Directory( lphc, (UINT)wParam,
-                                       (LPSTR)lParam, (message == CB_DIR));
+          return COMBO_Dir(hwnd,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;
+          return COMBO_ShowDropDown(hwnd,wParam,lParam);
+
         case CB_GETCOUNT:
-                return  SendMessageA( lphc->hWndLBox, LB_GETCOUNT, 0, 0);
+          return COMBO_GetCount(hwnd,wParam,lParam);
+
         case CB_GETCURSEL:
-                return  SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0);
+          return COMBO_GetCurSel(hwnd,wParam,lParam);
+
         case CB_SETCURSEL:
-                lParam = SendMessageA( lphc->hWndLBox, LB_SETCURSEL, wParam, 0);
-                if( lphc->wState & CBF_SELCHANGE )
-                {
-                    /* no LBN_SELCHANGE in this case, update manually */
-                    InvalidateRect(CB_HWND(lphc), &lphc->textRect, TRUE);
-                    lphc->wState &= ~CBF_SELCHANGE;
-                }
-                return  lParam;
+          return COMBO_SetCurSel(hwnd,wParam,lParam);
+
         case CB_GETLBTEXT:
-                return  SendMessageA( lphc->hWndLBox, LB_GETTEXT, wParam, lParam);
+          return COMBO_GetLBText(hwnd,wParam,lParam);
+
         case CB_GETLBTEXTLEN:
-                return  SendMessageA( lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0);
+          return COMBO_GetLBTextLen(hwnd,wParam,lParam);
+
         case CB_GETITEMDATA:
-                return  SendMessageA( lphc->hWndLBox, LB_GETITEMDATA, wParam, 0);
+          return COMBO_GetItemData(hwnd,wParam,lParam);
+
         case CB_SETITEMDATA:
-                return  SendMessageA( lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam);
+          return COMBO_SetItemData(hwnd,wParam,lParam);
+
         case CB_GETEDITSEL:
-                if( lphc->wState & CBF_EDIT )
-                {
-                    INT a, b;
-
-                    return  SendMessageA( lphc->hWndEdit, EM_GETSEL,
-                                           (wParam) ? wParam : (WPARAM)&a,
-                                           (lParam) ? lParam : (LPARAM)&b );
-                }
-                return  CB_ERR;
+          return COMBO_GetEditSel(hwnd,wParam,lParam);
+
         case CB_SETEDITSEL:
-                if( lphc->wState & CBF_EDIT )
-                    return  SendMessageA( lphc->hWndEdit, EM_SETSEL,
-                          (INT)(INT16)LOWORD(lParam), (INT)(INT16)HIWORD(lParam) );
-                return  CB_ERR;
+          return COMBO_SetEditSel(hwnd,wParam,lParam);
+
         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;
+          return COMBO_SetExtendedUI(hwnd,wParam,lParam);
+
         case CB_GETEXTENDEDUI:
-                return  (lphc->wState & CBF_EUI) ? TRUE : FALSE;
+          return COMBO_GetExtendedUI(hwnd,wParam,lParam);
+
         //case (WM_USER + 0x1B):
         //        WARN("[%04x]: undocumented msg!\n", hwnd );
