Fixed a few behaviors of the combobox that were broken.

diff --git a/controls/combo.c b/controls/combo.c
index 150f858..63f8692 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -548,11 +548,28 @@
 				       lphc->droppedRect.top, 
 				       lphc->droppedRect.right - lphc->droppedRect.left, 
 				       lphc->droppedRect.bottom - lphc->droppedRect.top, 
-			lphc->self->hwndSelf, 
+				       lphc->self->hwndSelf, 
 		       (lphc->dwStyle & CBS_DROPDOWN)? (HMENU)0 : (HMENU)ID_CB_LISTBOX,
 				       lphc->self->hInstance,
 				       (LPVOID)lphc );
 
+      /*
+       * The ComboLBox is a strange little beast (when it's not a CBS_SIMPLE)...
+       * It's a popup window but, when you get the window style, you get WS_CHILD.
+       * When created, it's parent is the combobox but, when you ask for it's parent
+       * after that, you're supposed to get the desktop. (see MFC code function
+       * AfxCancelModes)
+       * To achieve this in Wine, we have to create it as a popup and change 
+       * it's style to child after the creation. 
+       */
+      if ( (lphc->hWndLBox!= 0) &&
+	   (CB_GETTYPE(lphc) != CBS_SIMPLE) )
+      {
+	SetWindowLongA(lphc->hWndLBox, 
+		       GWL_STYLE, 
+		       (GetWindowLongA(lphc->hWndLBox, GWL_STYLE) | WS_CHILD) & ~WS_POPUP);
+      }
+
       if( lphc->hWndLBox )
       {
 	  BOOL	bEdit = TRUE;
@@ -1040,6 +1057,9 @@
 	   {
 		SendMessageA( lphc->hWndLBox, LB_GETTEXT, 
 				(WPARAM)index, (LPARAM)pText );
+
+		lphc->wState |= CBF_NOEDITNOTIFY;
+
 		SendMessageA( lphc->hWndEdit, WM_SETTEXT, 0, (LPARAM)pText );
 		SendMessageA( lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1) );
 		HeapFree( GetProcessHeap(), 0, pText );
@@ -1055,7 +1075,6 @@
  */
 static void CBDropDown( LPHEADCOMBO lphc )
 {
-   INT	index;
    RECT	rect;
 
    TRACE("[%04x]: drop down\n", CB_HWND(lphc));
@@ -1067,14 +1086,19 @@
    lphc->wState |= CBF_DROPPED;
    if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
    {
-       index = CBUpdateLBox( lphc );
-       if( !(lphc->wState & CBF_CAPTURE) ) CBUpdateEdit( lphc, index );
+       lphc->droppedIndex = CBUpdateLBox( lphc );
+
+       if( !(lphc->wState & CBF_CAPTURE) ) 
+	 CBUpdateEdit( lphc, lphc->droppedIndex );
    }
    else
    {
-       index = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
-       if( index == LB_ERR ) index = 0;
-       SendMessageA( lphc->hWndLBox, LB_SETTOPINDEX, (WPARAM)index, 0 );
+       lphc->droppedIndex = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
+
+       if( lphc->droppedIndex == LB_ERR ) 
+	 lphc->droppedIndex = 0;
+
+       SendMessageA( lphc->hWndLBox, LB_SETTOPINDEX, (WPARAM)lphc->droppedIndex, 0 );
        SendMessageA( lphc->hWndLBox, LB_CARETON, 0, 0 );
    }
 
@@ -1116,8 +1140,11 @@
 
        TRACE("[%04x]: roll up [%i]\n", CB_HWND(lphc), (INT)ok );
 
-       /* always send WM_LBUTTONUP? */
-       SendMessageA( lphc->hWndLBox, WM_LBUTTONUP, 0, (LPARAM)(-1) );
+       /* 
+	* It seems useful to send the WM_LBUTTONUP with (-1,-1) when cancelling 
+	* and with (0,0) (anywhere in the listbox) when Oking.
+	*/
+       SendMessageA( lphc->hWndLBox, WM_LBUTTONUP, 0, ok ? (LPARAM)0 : (LPARAM)(-1) );       
 
        if( lphc->wState & CBF_DROPPED ) 
        {
@@ -1252,7 +1279,7 @@
  */
 static LRESULT COMBO_Command( LPHEADCOMBO lphc, WPARAM wParam, HWND hWnd )
 {
-   if( lphc->wState & CBF_EDIT && lphc->hWndEdit == hWnd )
+   if ( lphc->wState & CBF_EDIT && lphc->hWndEdit == hWnd )
    {
        /* ">> 8" makes gcc generate jump-table instead of cmp ladder */
 
@@ -1282,7 +1309,22 @@
 
 
 	   case (EN_CHANGE >> 8):
-		CB_NOTIFY( lphc, CBN_EDITCHANGE );
+	       /*
+	        * In some circumstances (when the selection of the combobox
+		* is changed for example) we don't wans the EN_CHANGE notification
+		* to be forwarded to the parent of the combobox. This code
+		* checks a flag that is set in these occasions and ignores the 
+		* notification.
+	        */
+	        if (lphc->wState & CBF_NOEDITNOTIFY)
+		{
+		  lphc->wState &= ~CBF_NOEDITNOTIFY;
+		}
+		else
+		{
+		  CB_NOTIFY( lphc, CBN_EDITCHANGE );
+		}
+
 		CBUpdateLBox( lphc );
 		break;
 
@@ -1763,7 +1805,11 @@
         case WM_PASTE:
 	case WM_COPY:
 		if( lphc->wState & CBF_EDIT )
-                    return  SendMessageA( lphc->hWndEdit, message, wParam, lParam );
+		{
+		    lphc->wState |= CBF_NOEDITNOTIFY;
+
+		    return SendMessageA( lphc->hWndEdit, message, wParam, lParam );
+		}
 		return  CB_ERR;
 	case WM_DRAWITEM:
 	case WM_DELETEITEM:
diff --git a/controls/listbox.c b/controls/listbox.c
index 7cb45b9..9d03437 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -1281,7 +1281,7 @@
             LISTBOX_SelectItemRange( wnd, descr, first, last, TRUE );
         }
     }
-    else if (!(descr->style & LBS_MULTIPLESEL) && (descr->selected_item != -1))
+    else if (!(descr->style & LBS_MULTIPLESEL))
     {
         /* Set selection to new caret item */
         LISTBOX_SetSelection( wnd, descr, index, TRUE, FALSE );
@@ -2611,6 +2611,82 @@
 		     lphc = (LPHEADCOMBO)(lpcs->lpCreateParams);
 #undef  lpcs
 		     return LISTBOX_Create( wnd, lphc );
+	        case WM_MOUSEMOVE:
+		     if ( (TWEAK_WineLook > WIN31_LOOK) &&
+			  (CB_GETTYPE(lphc) != CBS_SIMPLE) )
+		     {
+		       POINT   mousePos;
+		       BOOL    captured;
+		       RECT    clientRect;
+
+		       mousePos.x = (INT16)LOWORD(lParam);
+		       mousePos.y = (INT16)HIWORD(lParam);
+
+		       /*
+			* If we are in a dropdown combobox, we simulate that
+			* the mouse is captured to show the tracking of the item.
+			*/
+		       captured = descr->captured;
+		       descr->captured = TRUE;			 
+		       
+		       LISTBOX_HandleMouseMove( wnd, 
+						descr, 
+						mousePos.x, mousePos.y);
+		       
+		       descr->captured = captured;
+
+		       /*
+			* However, when tracking, it is important that we do not
+			* perform a selection if the cursor is outside the list.
+			*/
+		       GetClientRect(hwnd, &clientRect);
+
+		       if (!PtInRect( &clientRect, mousePos ))
+		       {
+			 LISTBOX_MoveCaret( wnd, descr, -1, FALSE );
+		       }
+
+		       return 0;
+		     }
+		     else
+		     {
+		       /*
+			* If we are in Win3.1 look, go with the default behavior.
+			*/
+		       return ListBoxWndProc( hwnd, msg, wParam, lParam );
+		     }
+  	        case WM_LBUTTONUP:
+		     if (TWEAK_WineLook > WIN31_LOOK)
+		     {
+		       POINT mousePos;
+		       RECT  clientRect;
+
+		       /*
+			* If the mouse button "up" is not in the listbox,
+			* we make sure there is no selection by re-selecting the
+			* item that was selected when the listbox was made visible.
+			*/
+		       mousePos.x = (INT16)LOWORD(lParam);
+		       mousePos.y = (INT16)HIWORD(lParam);
+
+		       GetClientRect(hwnd, &clientRect);
+
+		       /*
+			* When the user clicks outside the combobox and the focus
+			* is lost, the owning combobox will send a fake buttonup with
+			* 0xFFFFFFF as the mouse location, we must also revert the
+			* selection to the original selection.
+			*/
+		       if ( (lParam == 0xFFFFFFFF) ||
+			    (!PtInRect( &clientRect, mousePos )) )
+		       {
+			 LISTBOX_MoveCaret( wnd,
+					    descr, 
+					    lphc->droppedIndex, 
+					    FALSE );
+		       }
+		     }
+		     return LISTBOX_HandleLButtonUp( wnd, descr );
 		case WM_LBUTTONDOWN:
 		     return LISTBOX_HandleLButtonDown( wnd, descr, wParam,
                              (INT16)LOWORD(lParam), (INT16)HIWORD(lParam));
diff --git a/include/combo.h b/include/combo.h
index 4886ba9..67d6ea8 100644
--- a/include/combo.h
+++ b/include/combo.h
@@ -21,6 +21,7 @@
 #define CBF_NOTIFY		0x0100
 #define CBF_NOREDRAW            0x0200
 #define CBF_SELCHANGE		0x0400
+#define CBF_NOEDITNOTIFY        0x1000
 #define CBF_EUI                 0x8000
 
 /* Combo state struct */
@@ -37,6 +38,7 @@
    RECT         textRect;
    RECT         buttonRect;
    RECT         droppedRect;
+   INT          droppedIndex;
    INT          fixedOwnerDrawHeight;
    INT   	droppedWidth;		/* last two are not used unless set */
    INT   	editHeight;		/* explicitly */