Ignore:
Timestamp:
May 22, 2000, 7:21:11 PM (25 years ago)
Author:
cbratschi
Message:

merged controls with Corel WINE 20000513, maximize/minimize fix

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/user32/combo.cpp

    r3261 r3584  
    1 /* $Id: combo.cpp,v 1.30 2000-03-28 17:13:46 sandervl Exp $ */
     1/* $Id: combo.cpp,v 1.31 2000-05-22 17:21:07 cbratschi Exp $ */
    22/*
    33 * Combo controls
     
    88 * FIXME: roll up in Netscape 3.01.
    99 *
    10  * Corel version: 20000317
     10 * Corel version: 20000513
    1111 * (WINE version: 991212)
    1212 *
     
    419419    if (posChanging->cy != newComboHeight)
    420420    {
    421       lphc->droppedRect.bottom = lphc->droppedRect.top + posChanging->cy - newComboHeight;
    422 
     421      if (posChanging->cy > newComboHeight)
     422         lphc->droppedRect.bottom = lphc->droppedRect.top + posChanging->cy - newComboHeight;
    423423      posChanging->cy = newComboHeight;
    424424    }
     
    495495      /* create listbox popup */
    496496
    497       lbeStyle = (LBS_NOTIFY | WS_BORDER | WS_CLIPSIBLINGS) |
     497      lbeStyle = (LBS_NOTIFY | WS_BORDER | WS_CLIPSIBLINGS | WS_CHILD) |
    498498                 (lpcs->style & (WS_VSCROLL | CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE));
    499499
     
    509509      if( CB_GETTYPE(lphc) == CBS_SIMPLE )      /* child listbox */
    510510      {
    511         lbeStyle |= WS_CHILD | WS_VISIBLE;
     511        lbeStyle |= WS_VISIBLE;
    512512
    513513        /*
     
    518518        lbeExStyle |= WS_EX_CLIENTEDGE;
    519519      }
    520       else                                      /* popup listbox */
    521       {
    522         lbeStyle |= WS_POPUP;
    523         lbeStyle |= WS_EX_TOOLWINDOW;
    524       }
    525 
    526      /* Dropdown ComboLBox is not a child window and we cannot pass
    527       * ID_CB_LISTBOX directly because it will be treated as a menu handle.
    528       */
     520
    529521      lphc->hWndLBox = CreateWindowExA(lbeExStyle,
    530522                                       clbName,
     
    536528                                       lphc->droppedRect.bottom - lphc->droppedRect.top,
    537529                                       lphc->hwndself,
    538                                        (lphc->dwStyle & CBS_DROPDOWN)? (HMENU)0 : (HMENU)ID_CB_LISTBOX,
     530                                       (HMENU)ID_CB_LISTBOX,
    539531                                       GetWindowLongA(lphc->hwndself,GWL_HINSTANCE),
    540532                                       (LPVOID)lphc );
    541 
    542       /*
    543        * The ComboLBox is a strange little beast (when it's not a CBS_SIMPLE)...
    544        * It's a popup window but, when you get the window style, you get WS_CHILD.
    545        * When created, it's parent is the combobox but, when you ask for it's parent
    546        * after that, you're supposed to get the desktop. (see MFC code function
    547        * AfxCancelModes)
    548        * To achieve this in Wine, we have to create it as a popup and change
    549        * it's style to child after the creation.
    550        */
    551       if ( (lphc->hWndLBox!= 0) &&
    552            (CB_GETTYPE(lphc) != CBS_SIMPLE) )
    553       {
    554         /*  Not using SetWindowLongA here because it doesn't allow us to
    555          *  change the WS_CHILD style. This code should be equivalent (excluding
    556          *  the change in owner) to:
    557          *       SetWindowLongA(lphc->hWndLBox, GWL_STYLE,
    558          *      (GetWindowLongA(lphc->hWndLBox,GWL_STYLE) | WS_CHILD) & ~WS_POPUP);
    559          */
    560         STYLESTRUCT style;
    561         Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(lphc->hWndLBox);
    562 
    563         if (!win32wnd)
    564         {
    565           /* Is this the right error? */
    566           SetLastError( ERROR_INVALID_WINDOW_HANDLE );
    567           return 0;
    568         }
    569 
    570         /* save old style, set new style */
    571         style.styleOld = win32wnd->getStyle();
    572         style.styleNew = (style.styleOld | WS_CHILD) & ~WS_POPUP;
    573 
    574         SendMessageA(lphc->hWndLBox,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
    575 #if 0 //CB: our code doesn't work with this style change
    576         win32wnd->setStyle(style.styleNew);
    577 #endif
    578         SendMessageA(lphc->hWndLBox,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
    579 
    580         /* Set owner to NULL - it seems to be what Windows does to a ComboLBox
    581          * after creation.
    582          */
    583         win32wnd->setOwner(NULL);
    584       }
    585533
    586534      if( lphc->hWndLBox )
    587535      {
    588536          BOOL  bEdit = TRUE;
    589           lbeStyle = WS_CHILD | WS_VISIBLE | ES_NOHIDESEL | ES_LEFT;
     537          lbeStyle = WS_CHILD | WS_VISIBLE | ES_NOHIDESEL | ES_LEFT | ES_COMBO;
    590538
    591539          /*
     
    622570          if( bEdit )
    623571          {
    624             /*
    625              * If the combo is a dropdown, we must resize the control to fit only
    626              * the text area and button. To do this, we send a dummy resize and the
    627              * WM_WINDOWPOSCHANGING message will take care of setting the height for
    628              * us.
    629              */
    630             if( CB_GETTYPE(lphc) != CBS_SIMPLE )
    631             {
     572            if( CB_GETTYPE(lphc) != CBS_SIMPLE )
     573            {
     574              /* Now do the trick with parent */
     575              SetParent(lphc->hWndLBox, HWND_DESKTOP);
     576
     577              /*
     578               * If the combo is a dropdown, we must resize the control to fit only
     579               * the text area and button. To do this, we send a dummy resize and the
     580               * WM_WINDOWPOSCHANGING message will take care of setting the height for
     581               * us.
     582               */
     583
    632584              CBForceDummyResize(lphc);
    633585            }
     
    918870static LRESULT COMBO_GetDlgCode(HWND hwnd,WPARAM wParam,LPARAM lParam)
    919871{
    920   return DLGC_WANTARROWS | DLGC_WANTCHARS;
     872  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
     873  LRESULT result = DLGC_WANTARROWS | DLGC_WANTCHARS;
     874
     875  if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN))
     876  {
     877    int vk = (int)((LPMSG)lParam)->wParam;
     878
     879    if ((vk == VK_RETURN || vk == VK_ESCAPE) && (lphc->wState & CBF_DROPPED))
     880      result |= DLGC_WANTMESSAGE;
     881  }
     882  return  result;
    921883}
    922884
     
    985947 * Select listbox entry according to the contents of the edit control.
    986948 */
    987 static INT CBUpdateLBox( LPHEADCOMBO lphc )
     949static INT CBUpdateLBox( LPHEADCOMBO lphc, BOOL bSelect )
    988950{
    989951   INT  length, idx;
     
    1007969   }
    1008970
    1009    if( idx >= 0 )
    1010    {
    1011        /* the LB_SETCARETINDEX message should scroll the list box if required
    1012           and sending LB_SETTOPINDEX can generate annoying behaviors  */
    1013        /* probably superfluous but Windows sends this too */
    1014        SendMessageA( lphc->hWndLBox, LB_SETCARETINDEX, (WPARAM)idx, 0 );
    1015    }
     971   SendMessageA( lphc->hWndLBox, LB_SETCURSEL, (WPARAM)(bSelect ? idx : -1), 0 );
     972
     973   /* the LB_SETCARETINDEX message should scroll the list box if required
     974      and sending LB_SETTOPINDEX can generate annoying behaviors  */
     975   /* probably superfluous but Windows sends this too */
     976   SendMessageA( lphc->hWndLBox, LB_SETCARETINDEX, (WPARAM)(idx < 0 ? 0 : idx), 0 );
     977   SendMessageA( lphc->hWndLBox, LB_SETTOPINDEX, (WPARAM)(idx < 0 ? 0 : idx), 0 );
     978
    1016979   return idx;
    1017980}
     
    10451008
    10461009   SendMessageA( lphc->hWndEdit, WM_SETTEXT, 0, pText ? (LPARAM)pText : (LPARAM)"" );
     1010
     1011   lphc->wState &= ~CBF_NOEDITNOTIFY;
     1012
    10471013   if( lphc->wState & CBF_FOCUSED )
    10481014     SendMessageA( lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1) );
     
    10621028   RECT rect;
    10631029   int nItems = 0;
    1064    int i;
    1065    int nHeight;
    1066    int nDroppedHeight,nTempDroppedHeight;
    1067    int screenH
     1030   int nDroppedHeight;
     1031
     1032   HWND hWnd = 0;
     1033   RECT DesktopRect;
    10681034
    10691035   //TRACE("[%04x]: drop down\n", CB_HWND(lphc));
     
    10761042   if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
    10771043   {
    1078        lphc->droppedIndex = CBUpdateLBox( lphc );
     1044       lphc->droppedIndex = CBUpdateLBox( lphc,TRUE );
    10791045
    10801046       if( !(lphc->wState & CBF_CAPTURE) )
     
    10881054         lphc->droppedIndex = 0;
    10891055
    1090        SendMessageA( lphc->hWndLBox, LB_SETTOPINDEX, (WPARAM)lphc->droppedIndex, 0 );
     1056       SendMessageA( lphc->hWndLBox, LB_SETTOPINDEX,
     1057                     (WPARAM)(lphc->droppedIndex == LB_ERR ? 0 : lphc->droppedIndex), 0 );
    10911058       SendMessageA( lphc->hWndLBox, LB_CARETON, 0, 0 );
    10921059   }
     
    11081075   nDroppedHeight = lphc->droppedRect.bottom - lphc->droppedRect.top;
    11091076   nItems = (int)SendMessageA (lphc->hWndLBox, LB_GETCOUNT, 0, 0);
    1110    nHeight = COMBO_YBORDERSIZE();
    1111    nTempDroppedHeight = 0;
    1112    for (i = 0; i < nItems; i++)
    1113    {
    1114      nHeight += (int)SendMessageA (lphc->hWndLBox, LB_GETITEMHEIGHT, i, 0);
    1115 
    1116      /* Did we pass the limit of what can be displayed */
    1117      if (nHeight > nDroppedHeight)
    1118      {
    1119        break;
     1077
     1078   if (nItems > 0)
     1079   {
     1080      int nHeight;
     1081
     1082      nHeight = (int)SendMessageA (lphc->hWndLBox, LB_GETITEMHEIGHT, 0, 0);
     1083      nHeight *= nItems;
     1084
     1085      if (nHeight < nDroppedHeight - COMBO_YBORDERSIZE())
     1086         nDroppedHeight = nHeight + COMBO_YBORDERSIZE();
    11201087   }
    1121      nTempDroppedHeight = nHeight;
     1088
     1089   /*Now we should know screen size. */
     1090   hWnd = GetDesktopWindow();
     1091
     1092   if( hWnd )
     1093   {
     1094     GetClientRect( hWnd, &DesktopRect );
    11221095   }
    11231096
    1124    nDroppedHeight = nTempDroppedHeight;
    11251097
    11261098   /*If height of dropped rectangle gets beyond a screen size it should go up, otherwise down.*/
    1127    screenH = GetSystemMetrics(SM_CYSCREEN);
    1128    if((rect.bottom + nDroppedHeight) >= screenH)
    1129    {
    1130      SetWindowPos( lphc->hWndLBox, HWND_TOP, rect.left, rect.top - nDroppedHeight,
    1131                  lphc->droppedRect.right - lphc->droppedRect.left,
    1132                  nDroppedHeight,
    1133                  SWP_NOACTIVATE | SWP_NOREDRAW);
    1134    }
    1135    else
    1136    {
    1137      SetWindowPos( lphc->hWndLBox, HWND_TOP, rect.left, rect.bottom,
    1138                  lphc->droppedRect.right - lphc->droppedRect.left,
    1139                  nDroppedHeight,
    1140                  SWP_NOACTIVATE | SWP_NOREDRAW);
    1141    }
     1099   if((rect.bottom + nDroppedHeight) >= DesktopRect.bottom)
     1100      rect.bottom = rect.top - nDroppedHeight;
     1101
     1102   SetWindowPos( lphc->hWndLBox, HWND_TOP, rect.left, rect.bottom,
     1103                 lphc->droppedRect.right - lphc->droppedRect.left,
     1104                 nDroppedHeight,
     1105                 SWP_NOACTIVATE | SWP_SHOWWINDOW);
     1106
    11421107
    11431108   if( !(lphc->wState & CBF_NOREDRAW) )
    11441109     RedrawWindow( lphc->hwndself, NULL, 0, RDW_INVALIDATE |
    1145                            RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN );
     1110                           RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN );
    11461111
    11471112   EnableWindow( lphc->hWndLBox, TRUE );
    1148    //SvL: Don't activate combo listbox window or else focus will change
    1149    //     (this window's parent is the desktop)
    1150    ShowWindow( lphc->hWndLBox, SW_SHOWNOACTIVATE);
    1151 
     1113   if (GetCapture() != lphc->hwndself)
     1114      SetCapture(lphc->hWndLBox);
    11521115}
    11531116
     
    11731136
    11741137           lphc->wState &= ~CBF_DROPPED;
     1138           /* By hiding the window, the capture by lphc->hWndLBox will be released too */
     1139       
    11751140           ShowWindow( lphc->hWndLBox, SW_HIDE );
    1176            if(GetCapture() == lphc->hWndLBox)
    1177            {
    1178                ReleaseCapture();
    1179            }
    11801141
    11811142           if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
    11821143           {
    1183                INT index = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
    1184                CBUpdateEdit( lphc, index );
    1185                rect = lphc->buttonRect;
     1144               rect = lphc->buttonRect;
    11861145           }
    11871146           else
     
    12121171 * Used by the ComboLBox to show/hide itself in response to VK_F4, etc...
    12131172 */
    1214 BOOL COMBO_FlipListbox( LPHEADCOMBO lphc, BOOL bRedrawButton )
     1173BOOL COMBO_FlipListbox( LPHEADCOMBO lphc, BOOL ok, BOOL bRedrawButton )
    12151174{
    12161175   if( lphc->wState & CBF_DROPPED )
    12171176   {
    1218        CBRollUp( lphc, TRUE, bRedrawButton );
     1177       CBRollUp( lphc, ok, bRedrawButton );
    12191178       return FALSE;
    12201179   }
     
    12231182   return TRUE;
    12241183}
    1225 
    1226 /***********************************************************************
    1227  *           COMBO_GetLBWindow
    1228  *
    1229  * Edit control helper.
    1230  */
    1231 HWND COMBO_GetLBWindow( HWND hwnd )
    1232 {
    1233   LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
    1234 
    1235   return lphc ? lphc->hWndLBox:0;
    1236 }
    1237 
    12381184
    12391185/***********************************************************************
     
    13791325                else
    13801326                {
    1381                   CBUpdateLBox( lphc );
     1327                  CBUpdateLBox( lphc, lphc->wState & CBF_DROPPED );
    13821328                }
    13831329                break;
     
    14281374                 * by arrowkeys in the dropdown listbox */
    14291375
    1430                 if( (lphc->dwStyle & CBS_SIMPLE) ||
     1376                if( (CB_GETTYPE(lphc) == CBS_SIMPLE) ||
    14311377                    ((lphc->wState & CBF_DROPPED) && !(lphc->wState & CBF_NOROLLUP)) )
    14321378                {
     
    14351381                else lphc->wState &= ~CBF_NOROLLUP;
    14361382
    1437                 if( lphc->wState & CBF_EDIT )
    1438                 {
    1439                     INT index = SendMessageA(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
    1440 
    1441                     lphc->wState |= CBF_NOLBSELECT;
    1442                     CBUpdateEdit( lphc, index );
    1443                     /* select text in edit, as Windows does */
    1444                     SendMessageA( lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1) );
     1383                CB_NOTIFY( lphc, CBN_SELCHANGE );
     1384
     1385                if( HIWORD(wParam) == LBN_SELCHANGE)
     1386                {
     1387                  if( lphc->wState & CBF_EDIT )
     1388                  {
     1389                      INT index = SendMessageA(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
     1390
     1391                      lphc->wState |= CBF_NOLBSELECT;
     1392                      CBUpdateEdit( lphc, index );
     1393                      /* select text in edit, as Windows does */
     1394                      SendMessageA( lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1) );
     1395                  }
     1396                  else
     1397                      InvalidateRect(CB_HWND(lphc), &lphc->textRect, TRUE);
    14451398                }
    1446                 else
    1447                     InvalidateRect(CB_HWND(lphc), &lphc->textRect, TRUE);
    1448 
    1449                 CB_NOTIFY( lphc, CBN_SELCHANGE );
     1399
    14501400                /* fall through */
    14511401
     
    15481498}
    15491499
     1500static LRESULT COMBO_GetTextLength(HWND hwnd,WPARAM wParam,LPARAM lParam)
     1501{
     1502  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
     1503
     1504  if (!(lphc->wState & CBF_EDIT))
     1505  {
     1506    int idx = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
     1507
     1508    if (idx == -1) return 0;
     1509    return SendMessageA( lphc->hWndLBox, LB_GETTEXTLEN, idx, 0 );
     1510  } else if (lphc->wState & CBF_EDIT)
     1511  {
     1512    /* Don't bother turning on CBF_NOEDITNOTIFY. */
     1513    return SendMessageA( lphc->hWndEdit, WM_GETTEXTLENGTH, wParam, lParam );
     1514  } else return CB_ERR;
     1515}
     1516
    15501517static LRESULT COMBO_HandleText(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
    15511518{
     
    15581525  }
    15591526
    1560   if ((message == WM_GETTEXTLENGTH) && !(lphc->wState & CBF_EDIT))
    1561   {
    1562     int j = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 );
    1563 
    1564     if (j == -1) return 0;
    1565     return SendMessageA( lphc->hWndLBox, LB_GETTEXTLEN, j, 0);
    1566   } else if( lphc->wState & CBF_EDIT )
    1567   {
     1527  if (lphc->wState & CBF_EDIT)
     1528  {
     1529    LRESULT res;
     1530
    15681531    lphc->wState |= CBF_NOEDITNOTIFY;
    1569 
    1570     return SendMessageA( lphc->hWndEdit, message, wParam, lParam );
    1571   } else return  CB_ERR;
     1532    res = SendMessageA( lphc->hWndEdit, message, wParam, lParam );
     1533    lphc->wState &= ~CBF_NOEDITNOTIFY;
     1534    return res;
     1535  } else return CB_ERR;
    15721536}
    15731537
     
    17281692
    17291693           lphc->wState |= CBF_CAPTURE;
     1694           SetCapture( hwnd );
    17301695           CBDropDown( lphc );
    1731            SetCapture( hwnd );
    17321696       }
    17331697       if( bButton ) CBRepaintButton( lphc );
     
    17511715       if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
    17521716       {
    1753            INT index = CBUpdateLBox( lphc );
    1754            CBUpdateEdit( lphc, index );
     1717           INT index = CBUpdateLBox( lphc, TRUE );
     1718
     1719           lphc->wState |= CBF_NOLBSELECT;
     1720           CBUpdateEdit( lphc, index );
     1721           lphc->wState &= ~CBF_NOLBSELECT;
    17551722       }
    1756        ReleaseCapture();
    1757 //SvL: Don't set the capture here. Otherwise other controls don't respond the first time!
    1758 //       SetCapture(lphc->hWndLBox);
     1723       SetCapture(lphc->hWndLBox);
    17591724   }
    17601725
     
    18041769       lphc->wState &= ~CBF_CAPTURE;
    18051770       ReleaseCapture();
    1806        if( CB_GETTYPE(lphc) == CBS_DROPDOWN ) CBUpdateLBox( lphc );
     1771       if( CB_GETTYPE(lphc) == CBS_DROPDOWN ) CBUpdateLBox( lphc,TRUE );
    18071772
    18081773       /* hand over pointer tracking */
     
    18601825  if( KEYDATA_ALT & HIWORD(lParam) )
    18611826    if( wParam == VK_UP || wParam == VK_DOWN )
    1862       COMBO_FlipListbox( lphc, TRUE );
    1863 
    1864   return DefWindowProcA(hwnd,WM_SYSKEYDOWN,wParam,lParam);
     1827      COMBO_FlipListbox( lphc,FALSE,FALSE );
     1828
     1829  return 0;
    18651830}
    18661831
     
    18681833{
    18691834  LPHEADCOMBO lphc = (LPHEADCOMBO)GetInfoPtr(hwnd);
     1835
     1836  if (((CHAR)wParam == VK_RETURN || (CHAR)wParam == VK_ESCAPE) && (lphc->wState & CBF_DROPPED))
     1837  {
     1838    CBRollUp( lphc, (CHAR)wParam == VK_RETURN, FALSE );
     1839    return TRUE;
     1840  }
    18701841
    18711842  if( lphc->wState & CBF_EDIT )
     
    22722243          return COMBO_GetText(hwnd,wParam,lParam);
    22732244
     2245        case WM_GETTEXTLENGTH:
     2246          return COMBO_GetTextLength(hwnd,wParam,lParam);
     2247
    22742248        case WM_SETTEXT:
    2275         case WM_GETTEXTLENGTH:
    22762249        case WM_CLEAR:
    22772250        case WM_CUT:
Note: See TracChangeset for help on using the changeset viewer.