Changeset 3584 for trunk/src/user32/combo.cpp
- Timestamp:
- May 22, 2000, 7:21:11 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/user32/combo.cpp
r3261 r3584 1 /* $Id: combo.cpp,v 1.3 0 2000-03-28 17:13:46 sandervlExp $ */1 /* $Id: combo.cpp,v 1.31 2000-05-22 17:21:07 cbratschi Exp $ */ 2 2 /* 3 3 * Combo controls … … 8 8 * FIXME: roll up in Netscape 3.01. 9 9 * 10 * Corel version: 20000 31710 * Corel version: 20000513 11 11 * (WINE version: 991212) 12 12 * … … 419 419 if (posChanging->cy != newComboHeight) 420 420 { 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; 423 423 posChanging->cy = newComboHeight; 424 424 } … … 495 495 /* create listbox popup */ 496 496 497 lbeStyle = (LBS_NOTIFY | WS_BORDER | WS_CLIPSIBLINGS ) |497 lbeStyle = (LBS_NOTIFY | WS_BORDER | WS_CLIPSIBLINGS | WS_CHILD) | 498 498 (lpcs->style & (WS_VSCROLL | CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)); 499 499 … … 509 509 if( CB_GETTYPE(lphc) == CBS_SIMPLE ) /* child listbox */ 510 510 { 511 lbeStyle |= WS_ CHILD | WS_VISIBLE;511 lbeStyle |= WS_VISIBLE; 512 512 513 513 /* … … 518 518 lbeExStyle |= WS_EX_CLIENTEDGE; 519 519 } 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 529 521 lphc->hWndLBox = CreateWindowExA(lbeExStyle, 530 522 clbName, … … 536 528 lphc->droppedRect.bottom - lphc->droppedRect.top, 537 529 lphc->hwndself, 538 ( lphc->dwStyle & CBS_DROPDOWN)? (HMENU)0 : (HMENU)ID_CB_LISTBOX,530 (HMENU)ID_CB_LISTBOX, 539 531 GetWindowLongA(lphc->hwndself,GWL_HINSTANCE), 540 532 (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 parent546 * after that, you're supposed to get the desktop. (see MFC code function547 * AfxCancelModes)548 * To achieve this in Wine, we have to create it as a popup and change549 * 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 to555 * change the WS_CHILD style. This code should be equivalent (excluding556 * 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 change576 win32wnd->setStyle(style.styleNew);577 #endif578 SendMessageA(lphc->hWndLBox,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);579 580 /* Set owner to NULL - it seems to be what Windows does to a ComboLBox581 * after creation.582 */583 win32wnd->setOwner(NULL);584 }585 533 586 534 if( lphc->hWndLBox ) 587 535 { 588 536 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; 590 538 591 539 /* … … 622 570 if( bEdit ) 623 571 { 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 632 584 CBForceDummyResize(lphc); 633 585 } … … 918 870 static LRESULT COMBO_GetDlgCode(HWND hwnd,WPARAM wParam,LPARAM lParam) 919 871 { 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; 921 883 } 922 884 … … 985 947 * Select listbox entry according to the contents of the edit control. 986 948 */ 987 static INT CBUpdateLBox( LPHEADCOMBO lphc )949 static INT CBUpdateLBox( LPHEADCOMBO lphc, BOOL bSelect ) 988 950 { 989 951 INT length, idx; … … 1007 969 } 1008 970 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 1016 979 return idx; 1017 980 } … … 1045 1008 1046 1009 SendMessageA( lphc->hWndEdit, WM_SETTEXT, 0, pText ? (LPARAM)pText : (LPARAM)"" ); 1010 1011 lphc->wState &= ~CBF_NOEDITNOTIFY; 1012 1047 1013 if( lphc->wState & CBF_FOCUSED ) 1048 1014 SendMessageA( lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1) ); … … 1062 1028 RECT rect; 1063 1029 int nItems = 0; 1064 int i;1065 int nHeight; 1066 int nDroppedHeight,nTempDroppedHeight;1067 int screenH1030 int nDroppedHeight; 1031 1032 HWND hWnd = 0; 1033 RECT DesktopRect; 1068 1034 1069 1035 //TRACE("[%04x]: drop down\n", CB_HWND(lphc)); … … 1076 1042 if( CB_GETTYPE(lphc) == CBS_DROPDOWN ) 1077 1043 { 1078 lphc->droppedIndex = CBUpdateLBox( lphc );1044 lphc->droppedIndex = CBUpdateLBox( lphc,TRUE ); 1079 1045 1080 1046 if( !(lphc->wState & CBF_CAPTURE) ) … … 1088 1054 lphc->droppedIndex = 0; 1089 1055 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 ); 1091 1058 SendMessageA( lphc->hWndLBox, LB_CARETON, 0, 0 ); 1092 1059 } … … 1108 1075 nDroppedHeight = lphc->droppedRect.bottom - lphc->droppedRect.top; 1109 1076 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(); 1120 1087 } 1121 nTempDroppedHeight = nHeight; 1088 1089 /*Now we should know screen size. */ 1090 hWnd = GetDesktopWindow(); 1091 1092 if( hWnd ) 1093 { 1094 GetClientRect( hWnd, &DesktopRect ); 1122 1095 } 1123 1096 1124 nDroppedHeight = nTempDroppedHeight;1125 1097 1126 1098 /*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 1142 1107 1143 1108 if( !(lphc->wState & CBF_NOREDRAW) ) 1144 1109 RedrawWindow( lphc->hwndself, NULL, 0, RDW_INVALIDATE | 1145 1110 RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN ); 1146 1111 1147 1112 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); 1152 1115 } 1153 1116 … … 1173 1136 1174 1137 lphc->wState &= ~CBF_DROPPED; 1138 /* By hiding the window, the capture by lphc->hWndLBox will be released too */ 1139 1175 1140 ShowWindow( lphc->hWndLBox, SW_HIDE ); 1176 if(GetCapture() == lphc->hWndLBox)1177 {1178 ReleaseCapture();1179 }1180 1141 1181 1142 if( CB_GETTYPE(lphc) == CBS_DROPDOWN ) 1182 1143 { 1183 INT index = SendMessageA( lphc->hWndLBox, LB_GETCURSEL, 0, 0 ); 1184 CBUpdateEdit( lphc, index ); 1185 rect = lphc->buttonRect; 1144 rect = lphc->buttonRect; 1186 1145 } 1187 1146 else … … 1212 1171 * Used by the ComboLBox to show/hide itself in response to VK_F4, etc... 1213 1172 */ 1214 BOOL COMBO_FlipListbox( LPHEADCOMBO lphc, BOOL bRedrawButton )1173 BOOL COMBO_FlipListbox( LPHEADCOMBO lphc, BOOL ok, BOOL bRedrawButton ) 1215 1174 { 1216 1175 if( lphc->wState & CBF_DROPPED ) 1217 1176 { 1218 CBRollUp( lphc, TRUE, bRedrawButton );1177 CBRollUp( lphc, ok, bRedrawButton ); 1219 1178 return FALSE; 1220 1179 } … … 1223 1182 return TRUE; 1224 1183 } 1225 1226 /***********************************************************************1227 * COMBO_GetLBWindow1228 *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 1238 1184 1239 1185 /*********************************************************************** … … 1379 1325 else 1380 1326 { 1381 CBUpdateLBox( lphc );1327 CBUpdateLBox( lphc, lphc->wState & CBF_DROPPED ); 1382 1328 } 1383 1329 break; … … 1428 1374 * by arrowkeys in the dropdown listbox */ 1429 1375 1430 if( ( lphc->dwStyle &CBS_SIMPLE) ||1376 if( (CB_GETTYPE(lphc) == CBS_SIMPLE) || 1431 1377 ((lphc->wState & CBF_DROPPED) && !(lphc->wState & CBF_NOROLLUP)) ) 1432 1378 { … … 1435 1381 else lphc->wState &= ~CBF_NOROLLUP; 1436 1382 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); 1445 1398 } 1446 else 1447 InvalidateRect(CB_HWND(lphc), &lphc->textRect, TRUE); 1448 1449 CB_NOTIFY( lphc, CBN_SELCHANGE ); 1399 1450 1400 /* fall through */ 1451 1401 … … 1548 1498 } 1549 1499 1500 static 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 1550 1517 static LRESULT COMBO_HandleText(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) 1551 1518 { … … 1558 1525 } 1559 1526 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 1568 1531 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; 1572 1536 } 1573 1537 … … 1728 1692 1729 1693 lphc->wState |= CBF_CAPTURE; 1694 SetCapture( hwnd ); 1730 1695 CBDropDown( lphc ); 1731 SetCapture( hwnd );1732 1696 } 1733 1697 if( bButton ) CBRepaintButton( lphc ); … … 1751 1715 if( CB_GETTYPE(lphc) == CBS_DROPDOWN ) 1752 1716 { 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; 1755 1722 } 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); 1759 1724 } 1760 1725 … … 1804 1769 lphc->wState &= ~CBF_CAPTURE; 1805 1770 ReleaseCapture(); 1806 if( CB_GETTYPE(lphc) == CBS_DROPDOWN ) CBUpdateLBox( lphc );1771 if( CB_GETTYPE(lphc) == CBS_DROPDOWN ) CBUpdateLBox( lphc,TRUE ); 1807 1772 1808 1773 /* hand over pointer tracking */ … … 1860 1825 if( KEYDATA_ALT & HIWORD(lParam) ) 1861 1826 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; 1865 1830 } 1866 1831 … … 1868 1833 { 1869 1834 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 } 1870 1841 1871 1842 if( lphc->wState & CBF_EDIT ) … … 2272 2243 return COMBO_GetText(hwnd,wParam,lParam); 2273 2244 2245 case WM_GETTEXTLENGTH: 2246 return COMBO_GetTextLength(hwnd,wParam,lParam); 2247 2274 2248 case WM_SETTEXT: 2275 case WM_GETTEXTLENGTH:2276 2249 case WM_CLEAR: 2277 2250 case WM_CUT:
Note:
See TracChangeset
for help on using the changeset viewer.