Changeset 9370 for trunk/src/comctl32/comboex.c
- Timestamp:
- Oct 29, 2002, 1:19:36 PM (23 years ago)
- File:
-
- 1 edited
-
trunk/src/comctl32/comboex.c (modified) (93 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/comctl32/comboex.c
r8382 r9370 20 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 21 * 22 * FIXME: 23 * 1. Implement following extended styles: 24 * CBES_EX_PATHWORDBREAKPROC 25 * CBES_EX_NOSIZELIMIT 26 * CBES_EX_CASESENSITIVE 27 * 2. Notify CBEN_DRAGBEGIN is not implemented. 28 * 22 * NOTE 23 * 24 * This code was audited for completeness against the documented features 25 * of Comctl32.dll version 6.0 on Sep. 9, 2002, by Dimitrie O. Paun. 26 * 27 * Unless otherwise noted, we belive this code to be complete, as per 28 * the specification mentioned above. 29 * If you discover missing features, or bugs, please note them below. 30 * 29 31 */ 30 32 … … 74 76 75 77 /* internal flags in the COMBOEX_INFO structure */ 76 #define WCBE_ACTEDIT 0x00000001 /* Edit active i.e.78 #define WCBE_ACTEDIT 0x00000001 /* Edit active i.e. 77 79 * CBEN_BEGINEDIT issued 78 80 * but CBEN_ENDEDIT{A|W} 79 81 * not yet issued. */ 80 #define WCBE_EDITCHG 0x00000002 /* Edit issued EN_CHANGE */82 #define WCBE_EDITCHG 0x00000002 /* Edit issued EN_CHANGE */ 81 83 #define WCBE_EDITHASCHANGED (WCBE_ACTEDIT | WCBE_EDITCHG) 82 #define WCBE_EDITFOCUSED 0x00000004 /* Edit control has focus */ 83 84 #define WCBE_EDITFOCUSED 0x00000004 /* Edit control has focus */ 85 #define WCBE_MOUSECAPTURED 0x00000008 /* Combo has captured mouse */ 86 #define WCBE_MOUSEDRAGGED 0x00000010 /* User has dragged in combo */ 84 87 85 88 #define ID_CB_EDIT 1001 … … 88 91 /* 89 92 * Special flag set in DRAWITEMSTRUCT itemState field. It is set by 90 * the ComboEx version of the Combo Window Proc so that when the 91 * WM_DRAWITEM message is then passed to ComboEx, we know that this 93 * the ComboEx version of the Combo Window Proc so that when the 94 * WM_DRAWITEM message is then passed to ComboEx, we know that this 92 95 * particular WM_DRAWITEM message is for listbox only items. Any messasges 93 96 * without this flag is then for the Edit control field. 94 97 * 95 * We really cannot use the ODS_COMBOBOXEDIT flag because MSDN states that 98 * We really cannot use the ODS_COMBOBOXEDIT flag because MSDN states that 96 99 * only version 4.0 applications will have ODS_COMBOBOXEDIT set. 97 100 */ … … 121 124 static LRESULT WINAPI 122 125 COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 126 static int CALLBACK 127 COMBOEX_PathWordBreakProc(LPWSTR lpch, int ichCurrent, int cch, int code); 123 128 static LRESULT COMBOEX_Destroy (COMBOEX_INFO *infoPtr); 129 130 #ifdef __WIN32OS2__ 131 #undef inline 132 #define inline 133 134 typedef INT (* WINAPI cmp_func_t)(LPCWSTR, LPCWSTR); 135 #else 136 typedef INT (WINAPI *cmp_func_t)(LPCWSTR, LPCWSTR); 137 #endif 124 138 125 139 inline static BOOL is_textW(LPCWSTR str) … … 164 178 inline static CBE_ITEMDATA *get_item_data(COMBOEX_INFO *infoPtr, INT index) 165 179 { 166 return (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo, CB_GETITEMDATA, 180 return (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo, CB_GETITEMDATA, 167 181 (WPARAM)index, 0); 168 182 } 169 183 184 inline static cmp_func_t get_cmp_func(COMBOEX_INFO *infoPtr) 185 { 186 return infoPtr->dwExtStyle & CBES_EX_CASESENSITIVE ? lstrcmpW : lstrcmpiW; 187 } 170 188 171 189 static INT COMBOEX_Notify (COMBOEX_INFO *infoPtr, INT code, NMHDR *hdr) … … 207 225 else if (code == CBEN_GETDISPINFOW) code = CBEN_GETDISPINFOA; 208 226 else if (code == CBEN_DRAGBEGINW) code = CBEN_DRAGBEGINA; 209 227 210 228 ret = COMBOEX_Notify (infoPtr, code, (NMHDR *)hdr); 211 229 212 230 if (astr && hdr->ceItem.pszText == (LPWSTR)astr) 213 231 hdr->ceItem.pszText = wstr; 214 232 215 233 if (astr) COMCTL32_Free(astr); 216 234 217 235 return ret; 218 236 } … … 228 246 } else { 229 247 NMCBEENDEDITA neea; 230 248 231 249 memcpy (&neea.hdr, &neew->hdr, sizeof(NMHDR)); 232 250 neea.fChanged = neew->fChanged; … … 240 258 241 259 260 static void COMBOEX_NotifyDragBegin(COMBOEX_INFO *infoPtr, LPCWSTR wstr) 261 { 262 /* Change the Text item from Unicode to ANSI if necessary for NOTIFY */ 263 if (infoPtr->NtfUnicode) { 264 NMCBEDRAGBEGINW ndbw; 265 266 ndbw.iItemid = -1; 267 lstrcpynW(ndbw.szText, wstr, CBEMAXSTRLEN); 268 COMBOEX_Notify (infoPtr, CBEN_DRAGBEGINW, &ndbw.hdr); 269 } else { 270 NMCBEDRAGBEGINA ndba; 271 272 ndba.iItemid = -1; 273 WideCharToMultiByte (CP_ACP, 0, wstr, -1, ndba.szText, CBEMAXSTRLEN, 0, 0); 274 275 COMBOEX_Notify (infoPtr, CBEN_DRAGBEGINA, &ndba.hdr); 276 } 277 } 278 279 242 280 static void COMBOEX_FreeText (CBE_ITEMDATA *item) 243 281 { … … 254 292 LPWSTR text, buf; 255 293 INT len; 256 257 if (item->pszText != LPSTR_TEXTCALLBACKW) 294 295 if (item->pszText != LPSTR_TEXTCALLBACKW) 258 296 return item->pszText; 259 297 260 298 ZeroMemory(&nmce, sizeof(nmce)); 261 299 nmce.ceItem.mask = CBEIF_TEXT; … … 277 315 } else 278 316 text = nmce.ceItem.pszText; 279 317 280 318 if (nmce.ceItem.mask & CBEIF_DI_SETITEM) 281 319 item->pszText = text; … … 290 328 291 329 mydc = GetDC (0); /* why the entire screen???? */ 292 nfont = SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0);330 nfont = (HFONT)SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0); 293 331 ofont = (HFONT) SelectObject (mydc, nfont); 294 332 GetTextExtentPointA (mydc, "A", 1, size); 295 333 SelectObject (mydc, ofont); 296 334 ReleaseDC (0, mydc); 297 TRACE("selected font hwnd=% 08x, height=%ld\n", nfont, size->cy);335 TRACE("selected font hwnd=%p, height=%ld\n", nfont, size->cy); 298 336 } 299 337 … … 376 414 } 377 415 SendMessageW (infoPtr->hwndSelf, CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)cy); 378 if (infoPtr->hwndCombo) 416 if (infoPtr->hwndCombo) { 379 417 SendMessageW (infoPtr->hwndCombo, CB_SETITEMHEIGHT, 380 418 (WPARAM) 0, (LPARAM) cy); 419 if ( !(infoPtr->flags & CBES_EX_NOSIZELIMIT)) { 420 RECT comboRect; 421 if (GetWindowRect(infoPtr->hwndCombo, &comboRect)) { 422 RECT ourRect; 423 if (GetWindowRect(infoPtr->hwndSelf, &ourRect)) { 424 if (comboRect.bottom > ourRect.bottom) { 425 POINT pt = { ourRect.left, ourRect.top }; 426 if (ScreenToClient(infoPtr->hwndSelf, &pt)) 427 MoveWindow( infoPtr->hwndSelf, pt.x, pt.y, ourRect.right - ourRect.left, 428 comboRect.bottom - comboRect.top, FALSE); 429 } 430 } 431 } 432 } 433 } 381 434 } 382 435 … … 396 449 } 397 450 398 451 399 452 static CBE_ITEMDATA * COMBOEX_FindItem(COMBOEX_INFO *infoPtr, INT index) 400 453 { … … 424 477 static inline BOOL COMBOEX_HasEdit(COMBOEX_INFO *infoPtr) 425 478 { 426 return infoPtr->hwndEdit ;427 } 428 479 return infoPtr->hwndEdit ? TRUE : FALSE; 480 } 481 429 482 430 483 /* *** CBEM_xxx message support *** */ … … 481 534 482 535 if (is_textW(tmpcit.pszText) && cit->pszText) 483 WideCharToMultiByte (CP_ACP, 0, tmpcit.pszText, -1, 536 WideCharToMultiByte (CP_ACP, 0, tmpcit.pszText, -1, 484 537 cit->pszText, cit->cchTextMax, NULL, NULL); 485 538 else if (cit->pszText) cit->pszText[0] = 0; … … 520 573 /* get zero-filled space and chain it in */ 521 574 if(!(item = (CBE_ITEMDATA *)COMCTL32_Alloc (sizeof(*item)))) return -1; 522 575 523 576 /* locate position to insert new item in */ 524 577 if (index == infoPtr->nb_items) { … … 576 629 if (TRACE_ON(comboex)) COMBOEX_DumpItem (item); 577 630 578 SendMessageW (infoPtr->hwndCombo, CB_INSERTSTRING, 631 SendMessageW (infoPtr->hwndCombo, CB_INSERTSTRING, 579 632 (WPARAM)cit->iItem, (LPARAM)item); 580 633 … … 602 655 citW.pszText = wstr; 603 656 } 604 ret = COMBOEX_InsertItemW(infoPtr, &citW); ;605 657 ret = COMBOEX_InsertItemW(infoPtr, &citW); 658 606 659 if (wstr) COMCTL32_Free(wstr); 607 660 608 661 return ret; 609 662 } 610 663 611 664 612 static DWORD 665 static DWORD 613 666 COMBOEX_SetExtendedStyle (COMBOEX_INFO *infoPtr, DWORD mask, DWORD style) 614 667 { … … 618 671 619 672 dwTemp = infoPtr->dwExtStyle; 620 621 if (style & (CBES_EX_PATHWORDBREAKPROC |622 CBES_EX_NOSIZELIMIT |623 CBES_EX_CASESENSITIVE))624 FIXME("Extended style not implemented %08lx\n", style);625 673 626 674 if (mask) … … 628 676 else 629 677 infoPtr->dwExtStyle = style; 678 679 /* see if we need to change the word break proc on the edit */ 680 if ((infoPtr->dwExtStyle ^ dwTemp) & CBES_EX_PATHWORDBREAKPROC) { 681 SendMessageW(infoPtr->hwndEdit, EM_SETWORDBREAKPROC, 0, 682 (infoPtr->dwExtStyle & CBES_EX_PATHWORDBREAKPROC) ? 683 (LPARAM)COMBOEX_PathWordBreakProc : 0); 684 } 630 685 631 686 /* test if the control's appearance has changed */ … … 676 731 if (!(item = COMBOEX_FindItem(infoPtr, index))) return FALSE; 677 732 678 /* add/change stuff to the internal item structure */ 733 /* add/change stuff to the internal item structure */ 679 734 item->mask |= cit->mask; 680 735 if (cit->mask & CBEIF_TEXT) { … … 726 781 citW.pszText = wstr; 727 782 } 728 ret = COMBOEX_SetItemW(infoPtr, &citW); ;783 ret = COMBOEX_SetItemW(infoPtr, &citW); 729 784 730 785 if (wstr) COMCTL32_Free(wstr); … … 749 804 750 805 static INT 751 COMBOEX_FindStringExact (COMBOEX_INFO *infoPtr, INT start, LPCSTR str) 752 { 753 INT i, count; 754 CBE_ITEMDATA *item; 755 LPWSTR desired = NULL; 756 757 i = MultiByteToWideChar (CP_ACP, 0, str, -1, NULL, 0); 758 if (i > 0) { 759 desired = (LPWSTR)COMCTL32_Alloc ((i + 1)*sizeof(WCHAR)); 760 if (!desired) return CB_ERR; 761 MultiByteToWideChar (CP_ACP, 0, str, -1, desired, i); 762 } 763 764 count = SendMessageW (infoPtr->hwndCombo, CB_GETCOUNT, 0, 0); 806 COMBOEX_FindStringExact (COMBOEX_INFO *infoPtr, INT start, LPCWSTR str) 807 { 808 INT i; 809 cmp_func_t cmptext = get_cmp_func(infoPtr); 810 INT count = SendMessageW (infoPtr->hwndCombo, CB_GETCOUNT, 0, 0); 765 811 766 812 /* now search from after starting loc and wrapping back to start */ 767 813 for(i=start+1; i<count; i++) { 768 item = get_item_data(infoPtr, i); 769 if (lstrcmpiW(COMBOEX_GetText(infoPtr, item), desired) == 0) { 770 COMCTL32_Free (desired); 771 return i; 772 } 814 CBE_ITEMDATA *item = get_item_data(infoPtr, i); 815 if (cmptext(COMBOEX_GetText(infoPtr, item), str) == 0) return i; 773 816 } 774 817 for(i=0; i<=start; i++) { 775 item = get_item_data(infoPtr, i); 776 if (lstrcmpiW(COMBOEX_GetText(infoPtr, item), desired) == 0) { 777 COMCTL32_Free (desired); 778 return i; 779 } 780 } 781 COMCTL32_Free(desired); 818 CBE_ITEMDATA *item = get_item_data(infoPtr, i); 819 if (cmptext(COMBOEX_GetText(infoPtr, item), str) == 0) return i; 820 } 782 821 return CB_ERR; 783 822 } … … 857 896 GetWindowRect (infoPtr->hwndSelf, &cbx_wrect); 858 897 GetClientRect (infoPtr->hwndSelf, &cbx_crect); 859 /* the height of comboex as height of the combo + comboex border */ 898 /* the height of comboex as height of the combo + comboex border */ 860 899 height = cb_wrect.bottom-cb_wrect.top 861 900 + cbx_wrect.bottom-cbx_wrect.top … … 884 923 WCHAR NIL[] = { 0 }; 885 924 COMBOEX_INFO *infoPtr; 886 DWORD dwComboStyle;887 925 LOGFONTW mylogfont; 888 926 RECT wnrc1, clrc1, cmbwrc; … … 895 933 /* initialize info structure */ 896 934 /* note that infoPtr is allocated zero-filled */ 897 935 898 936 infoPtr->hwndSelf = hwnd; 899 937 infoPtr->selected = -1; … … 901 939 infoPtr->unicode = IsWindowUnicode (hwnd); 902 940 903 i = SendMessageW(GetParent (hwnd), WM_NOTIFYFORMAT, hwnd, NF_QUERY);941 i = SendMessageW(GetParent (hwnd), WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_QUERY); 904 942 if ((i != NFR_ANSI) && (i != NFR_UNICODE)) { 905 943 WARN("wrong response to WM_NOTIFYFORMAT (%d), assuming ANSI\n", i); … … 911 949 912 950 /* create combo box */ 913 dwComboStyle = GetWindowLongW (hwnd, GWL_STYLE) &914 (CBS_SIMPLE|CBS_DROPDOWN|CBS_DROPDOWNLIST|WS_CHILD);915 916 951 GetWindowRect(hwnd, &wnrc1); 917 952 GetClientRect(hwnd, &clrc1); … … 919 954 wnrc1.left, wnrc1.top, wnrc1.right, wnrc1.bottom, 920 955 clrc1.left, clrc1.top, clrc1.right, clrc1.bottom); 921 TRACE("combo style=%08lx, adding style=%08lx\n", dwComboStyle,922 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VSCROLL |923 CBS_NOINTEGRALHEIGHT | CBS_DROPDOWNLIST |924 WS_CHILD | WS_VISIBLE | CBS_OWNERDRAWFIXED);925 956 926 957 /* Native version of ComboEx creates the ComboBox with DROPDOWNLIST */ … … 934 965 /* following line added to match native */ 935 966 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VSCROLL | 936 CBS_NOINTEGRALHEIGHT | CBS_DROPDOWNLIST | 967 CBS_NOINTEGRALHEIGHT | CBS_DROPDOWNLIST | 937 968 /* was base and is necessary */ 938 WS_CHILD | WS_VISIBLE | CBS_OWNERDRAWFIXED | dwComboStyle, 969 WS_CHILD | WS_VISIBLE | CBS_OWNERDRAWFIXED | 970 GetWindowLongW (hwnd, GWL_STYLE), 939 971 cs->y, cs->x, cs->cx, cs->cy, hwnd, 940 972 (HMENU) GetWindowLongW (hwnd, GWL_ID), 941 GetWindowLongW (hwnd, GWL_HINSTANCE), NULL);942 943 /* 973 (HINSTANCE)GetWindowLongW (hwnd, GWL_HINSTANCE), NULL); 974 975 /* 944 976 * native does the following at this point according to trace: 945 977 * GetWindowThreadProcessId(hwndCombo,0) … … 950 982 951 983 /* 952 * Setup a property to hold the pointer to the COMBOBOXEX 984 * Setup a property to hold the pointer to the COMBOBOXEX 953 985 * data structure. 954 986 */ 955 987 SetPropA(infoPtr->hwndCombo, COMBOEX_SUBCLASS_PROP, hwnd); 956 infoPtr->prevComboWndProc = (WNDPROC)SetWindowLongW(infoPtr->hwndCombo, 988 infoPtr->prevComboWndProc = (WNDPROC)SetWindowLongW(infoPtr->hwndCombo, 957 989 GWL_WNDPROC, (LONG)COMBOEX_ComboWndProc); 958 infoPtr->font = SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0);990 infoPtr->font = (HFONT)SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0); 959 991 960 992 … … 967 999 WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | ES_AUTOHSCROLL, 968 1000 0, 0, 0, 0, /* will set later */ 969 infoPtr->hwndCombo, 1001 infoPtr->hwndCombo, 970 1002 (HMENU) GetWindowLongW (hwnd, GWL_ID), 971 GetWindowLongW (hwnd, GWL_HINSTANCE), 972 NULL); 1003 (HINSTANCE)GetWindowLongW (hwnd, GWL_HINSTANCE), NULL); 973 1004 974 1005 /* native does the following at this point according to trace: … … 980 1011 981 1012 /* 982 * Setup a property to hold the pointer to the COMBOBOXEX 1013 * Setup a property to hold the pointer to the COMBOBOXEX 983 1014 * data structure. 984 1015 */ 985 1016 SetPropA(infoPtr->hwndEdit, COMBOEX_SUBCLASS_PROP, hwnd); 986 infoPtr->prevEditWndProc = (WNDPROC)SetWindowLongW(infoPtr->hwndEdit, 1017 infoPtr->prevEditWndProc = (WNDPROC)SetWindowLongW(infoPtr->hwndEdit, 987 1018 GWL_WNDPROC, (LONG)COMBOEX_EditWndProc); 988 infoPtr->font = SendMessageW(infoPtr->hwndCombo, WM_GETFONT, 0, 0);1019 infoPtr->font = (HFONT)SendMessageW(infoPtr->hwndCombo, WM_GETFONT, 0, 0); 989 1020 } 990 1021 … … 994 1025 */ 995 1026 if (!infoPtr->font) { 996 SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof(mylogfont), 1027 SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof(mylogfont), 997 1028 &mylogfont, 0); 998 1029 infoPtr->font = infoPtr->defaultFont = CreateFontIndirectW (&mylogfont); … … 1015 1046 clrc1.left, clrc1.top, clrc1.right, clrc1.bottom, 1016 1047 cmbwrc.left, cmbwrc.top, cmbwrc.right, cmbwrc.bottom); 1017 SetWindowPos(infoPtr->hwndCombo, HWND_TOP, 1048 SetWindowPos(infoPtr->hwndCombo, HWND_TOP, 1018 1049 0, 0, wnrc1.right-wnrc1.left, wnrc1.bottom-wnrc1.top, 1019 1050 SWP_NOACTIVATE | SWP_NOREDRAW); … … 1022 1053 TRACE("CB window=(%d,%d)-(%d,%d)\n", 1023 1054 cmbwrc.left, cmbwrc.top, cmbwrc.right, cmbwrc.bottom); 1024 SetWindowPos(hwnd, HWND_TOP, 1055 SetWindowPos(hwnd, HWND_TOP, 1025 1056 0, 0, cmbwrc.right-cmbwrc.left, cmbwrc.bottom-cmbwrc.top, 1026 1057 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE); … … 1029 1060 1030 1061 /* 1031 * Create an item structure to represent the data in the 1062 * Create an item structure to represent the data in the 1032 1063 * EDIT control. It is allocated zero-filled. 1033 1064 */ … … 1061 1092 ShowWindow (infoPtr->hwndEdit, SW_HIDE); 1062 1093 return SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf); 1063 1094 1064 1095 case CBN_CLOSEUP: 1065 1096 SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf); 1066 1097 /* 1067 * from native trace of first dropdown after typing in URL in IE4 1098 * from native trace of first dropdown after typing in URL in IE4 1068 1099 * CB_GETCURSEL(Combo) 1069 1100 * GetWindowText(Edit) … … 1075 1106 * CB_SETCURSEL(COMBOEX, n) 1076 1107 * SetFocus(Combo) 1077 * the rest is supposition 1108 * the rest is supposition 1078 1109 */ 1079 1110 ShowWindow (infoPtr->hwndEdit, SW_SHOW); … … 1082 1113 cursel = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0); 1083 1114 if (cursel == -1) { 1115 cmp_func_t cmptext = get_cmp_func(infoPtr); 1084 1116 /* find match from edit against those in Combobox */ 1085 1117 GetWindowTextW (infoPtr->hwndEdit, wintext, 520); … … 1088 1120 item = get_item_data(infoPtr, cursel); 1089 1121 if ((INT)item == CB_ERR) break; 1090 if (! lstrcmpiW(COMBOEX_GetText(infoPtr, item), wintext)) break;1122 if (!cmptext(COMBOEX_GetText(infoPtr, item), wintext)) break; 1091 1123 } 1092 1124 if ((cursel == n) || ((INT)item == CB_ERR)) { … … 1155 1187 1156 1188 case CBN_SELENDOK: 1157 /* 1189 /* 1158 1190 * We have to change the handle since we are the control 1159 1191 * issuing the message. IE4 depends on this. … … 1189 1221 1190 1222 default: 1191 /* 1223 /* 1192 1224 * We have to change the handle since we are the control 1193 1225 * issuing the message. IE4 depends on this. … … 1210 1242 INT i; 1211 1243 1212 TRACE("CtlType=%08x, CtlID=%08x, itemID=%08x, hwnd=% x, data=%08lx\n",1244 TRACE("CtlType=%08x, CtlID=%08x, itemID=%08x, hwnd=%p, data=%08lx\n", 1213 1245 dis->CtlType, dis->CtlID, dis->itemID, dis->hwndItem, dis->itemData); 1214 1246 … … 1264 1296 if (!IsWindowEnabled(infoPtr->hwndCombo)) return 0; 1265 1297 1266 TRACE("DRAWITEMSTRUCT: CtlType=0x%08x CtlID=0x%08x\n", 1298 TRACE("DRAWITEMSTRUCT: CtlType=0x%08x CtlID=0x%08x\n", 1267 1299 dis->CtlType, dis->CtlID); 1268 TRACE("itemID=0x%08x itemAction=0x%08x itemState=0x%08x\n", 1300 TRACE("itemID=0x%08x itemAction=0x%08x itemState=0x%08x\n", 1269 1301 dis->itemID, dis->itemAction, dis->itemState); 1270 TRACE("hWnd= 0x%04x hDC=0x%04x(%d,%d)-(%d,%d) itemData=0x%08lx\n",1271 dis->hwndItem, dis->hDC, dis->rcItem.left, 1272 dis->rcItem.top, dis->rcItem.right, dis->rcItem.bottom, 1302 TRACE("hWnd=%p hDC=%p (%d,%d)-(%d,%d) itemData=0x%08lx\n", 1303 dis->hwndItem, dis->hDC, dis->rcItem.left, 1304 dis->rcItem.top, dis->rcItem.right, dis->rcItem.bottom, 1273 1305 dis->itemData); 1274 1306 … … 1286 1318 if (dis->itemID == 0xffffffff) { 1287 1319 if ( ( (dis->itemAction & ODA_FOCUS) && (dis->itemState & ODS_SELECTED)) || 1288 ( (dis->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)) && (dis->itemState & ODS_FOCUS) ) ) { 1320 ( (dis->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)) && (dis->itemState & ODS_FOCUS) ) ) { 1289 1321 1290 1322 TRACE("drawing item -1 special focus, rect=(%d,%d)-(%d,%d)\n", … … 1292 1324 dis->rcItem.right, dis->rcItem.bottom); 1293 1325 } 1294 else if ((dis->CtlType == ODT_COMBOBOX) && 1326 else if ((dis->CtlType == ODT_COMBOBOX) && 1295 1327 (dis->itemAction == ODA_DRAWENTIRE)) { 1296 1328 /* draw of edit control data */ … … 1334 1366 if (item->pszText) 1335 1367 GetWindowTextW(infoPtr->hwndEdit, item->pszText, len+1); 1336 1337 TRACE("edit control hwndEdit=% 0x, text len=%d str=%s\n",1368 1369 TRACE("edit control hwndEdit=%p, text len=%d str=%s\n", 1338 1370 infoPtr->hwndEdit, len, debugstr_txt(item->pszText)); 1339 1371 } … … 1382 1414 /* drawing combo/edit entry */ 1383 1415 if (IsWindowVisible(infoPtr->hwndEdit)) { 1384 /* if we have an edit control, the slave the 1385 * selection state to the Edit focus state 1416 /* if we have an edit control, the slave the 1417 * selection state to the Edit focus state 1386 1418 */ 1387 1419 if (infoPtr->flags & WCBE_EDITFOCUSED) { … … 1391 1423 } 1392 1424 } else { 1393 /* if we don't have an edit control, use 1425 /* if we don't have an edit control, use 1394 1426 * the requested state. 1395 1427 */ … … 1415 1447 len = strlenW (str); 1416 1448 GetTextExtentPoint32W (dis->hDC, str, len, &txtsize); 1417 1449 1418 1450 if (dis->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)) { 1419 1451 int overlay = item->iOverlay; 1420 1452 1421 1453 if (drawimage == I_IMAGECALLBACK) { 1422 1454 NMCOMBOBOXEXW nmce; … … 1442 1474 overlay = nmce.ceItem.iOverlay; 1443 1475 } 1444 1445 if (drawimage >= 0 && 1476 1477 if (drawimage >= 0 && 1446 1478 !(infoPtr->dwExtStyle & (CBES_EX_NOEDITIMAGE | CBES_EX_NOEDITIMAGEINDENT))) { 1447 1479 if (overlay > 0) ImageList_SetOverlayImage (infoPtr->himl, overlay, 1); 1448 ImageList_Draw (infoPtr->himl, drawimage, dis->hDC, xbase, dis->rcItem.top, 1480 ImageList_Draw (infoPtr->himl, drawimage, dis->hDC, xbase, dis->rcItem.top, 1449 1481 drawstate | (overlay > 0 ? INDEXTOOVERLAYMASK(1) : 0)); 1450 1482 } … … 1473 1505 } 1474 1506 } 1475 1507 1476 1508 if (dis->itemAction & ODA_FOCUS) { 1477 1509 rect.left = xbase + xioff - 1; … … 1509 1541 } 1510 1542 1511 if (infoPtr->defaultFont) 1543 if (infoPtr->defaultFont) 1512 1544 DeleteObject (infoPtr->defaultFont); 1513 1545 … … 1529 1561 mis->itemHeight = mysize.cy + CBE_EXTRA; 1530 1562 1531 TRACE("adjusted height hwnd=% 08x, height=%d\n",1563 TRACE("adjusted height hwnd=%p, height=%d\n", 1532 1564 infoPtr->hwndSelf, mis->itemHeight); 1533 1565 … … 1556 1588 if (lParam == NF_REQUERY) { 1557 1589 INT i = SendMessageW(GetParent (infoPtr->hwndSelf), 1558 WM_NOTIFYFORMAT, infoPtr->hwndSelf, NF_QUERY);1590 WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwndSelf, NF_QUERY); 1559 1591 infoPtr->NtfUnicode = (i == NFR_UNICODE) ? 1 : 0; 1560 1592 } … … 1565 1597 static LRESULT COMBOEX_Size (COMBOEX_INFO *infoPtr, INT width, INT height) 1566 1598 { 1567 TRACE("(width=%d, height=%d)\n", width, height); 1599 TRACE("(width=%d, height=%d)\n", width, height); 1568 1600 1569 1601 MoveWindow (infoPtr->hwndCombo, 0, 0, width, height, TRUE); … … 1586 1618 /* width is winpos value + border width of comboex */ 1587 1619 width = wp->cx 1588 + (cbx_wrect.right-cbx_wrect.left) 1589 - (cbx_crect.right-cbx_crect.left); 1620 + (cbx_wrect.right-cbx_wrect.left) 1621 - (cbx_crect.right-cbx_crect.left); 1590 1622 1591 1623 TRACE("winpos=(%d,%d %dx%d) flags=0x%08x\n", … … 1618 1650 } 1619 1651 1652 static inline int is_delimiter(WCHAR c) 1653 { 1654 switch(c) { 1655 case '/': 1656 case '\\': 1657 case '.': 1658 return TRUE; 1659 } 1660 return FALSE; 1661 } 1662 1663 static int CALLBACK 1664 COMBOEX_PathWordBreakProc(LPWSTR lpch, int ichCurrent, int cch, int code) 1665 { 1666 if (code == WB_ISDELIMITER) { 1667 return is_delimiter(lpch[ichCurrent]); 1668 } else { 1669 int dir = (code == WB_LEFT) ? -1 : 1; 1670 for(; 0 <= ichCurrent && ichCurrent < cch; ichCurrent += dir) 1671 if (is_delimiter(lpch[ichCurrent])) return ichCurrent; 1672 } 1673 return ichCurrent; 1674 } 1620 1675 1621 1676 static LRESULT WINAPI … … 1631 1686 LRESULT lret; 1632 1687 1633 TRACE("hwnd=% x msg=%x wparam=%x lParam=%lx, info_ptr=%p\n",1688 TRACE("hwnd=%p msg=%x wparam=%x lParam=%lx, info_ptr=%p\n", 1634 1689 hwnd, uMsg, wParam, lParam, infoPtr); 1635 1690 … … 1643 1698 if (wParam == VK_RETURN) return 0; 1644 1699 /* all other characters pass into the real Edit */ 1645 return CallWindowProcW (infoPtr->prevEditWndProc, 1700 return CallWindowProcW (infoPtr->prevEditWndProc, 1646 1701 hwnd, uMsg, wParam, lParam); 1647 1702 1648 1703 case WM_ERASEBKGND: 1649 1704 /* 1650 * The following was determined by traces of the native 1705 * The following was determined by traces of the native 1651 1706 */ 1652 1707 hDC = (HDC) wParam; … … 1657 1712 ExtTextOutW (hDC, 0, 0, ETO_OPAQUE, &rect, 0, 0, 0); 1658 1713 SetBkColor (hDC, obkc); 1659 return CallWindowProcW (infoPtr->prevEditWndProc, 1714 return CallWindowProcW (infoPtr->prevEditWndProc, 1660 1715 hwnd, uMsg, wParam, lParam); 1661 1716 … … 1672 1727 * CB_GETCURSEL to Combo rets -1 x 1673 1728 * WM_NOTIFY to COMBOEX parent (rebar) x 1674 * (CBEN_ENDEDIT{A|W} 1729 * (CBEN_ENDEDIT{A|W} 1675 1730 * fChanged = FALSE x 1676 1731 * inewSelection = -1 x … … 1701 1756 break; 1702 1757 } 1703 infoPtr->selected = oldItem; 1758 infoPtr->selected = oldItem; 1704 1759 COMBOEX_SetEditText (infoPtr, item); 1705 RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE | 1760 RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE | 1706 1761 RDW_INVALIDATE); 1707 1762 break; … … 1713 1768 * CB_GETCURSEL to Combo rets -1 x 1714 1769 * CB_GETCOUNT to Combo rets 0 1715 * if >0 loop 1770 * if >0 loop 1716 1771 * CB_GETITEMDATA to match 1717 * *** above 3 lines simulated by FindItem x 1772 * *** above 3 lines simulated by FindItem x 1718 1773 * WM_NOTIFY to COMBOEX parent (rebar) x 1719 1774 * (CBEN_ENDEDIT{A|W} x … … 1738 1793 1739 1794 if (selected != -1) { 1795 cmp_func_t cmptext = get_cmp_func(infoPtr); 1740 1796 item = COMBOEX_FindItem (infoPtr, selected); 1741 1797 TRACE("handling VK_RETURN, selected = %d, selected_text=%s\n", … … 1743 1799 TRACE("handling VK_RETURN, edittext=%s\n", 1744 1800 debugstr_w(edit_text)); 1745 if ( lstrcmpiW(COMBOEX_GetText(infoPtr, item), edit_text)) {1801 if (cmptext (COMBOEX_GetText(infoPtr, item), edit_text)) { 1746 1802 /* strings not equal -- indicate edit has changed */ 1747 1803 selected = -1; … … 1750 1806 1751 1807 cbeend.iNewSelection = selected; 1752 cbeend.fChanged = TRUE; 1808 cbeend.fChanged = TRUE; 1753 1809 cbeend.iWhy = CBENF_RETURN; 1754 1810 if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) { … … 1756 1812 TRACE("Notify requested abort of change\n"); 1757 1813 COMBOEX_SetEditText (infoPtr, infoPtr->edit); 1758 RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE | 1814 RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE | 1759 1815 RDW_INVALIDATE); 1760 1816 return 0; … … 1763 1819 if (oldItem != -1) { 1764 1820 /* if something is selected, then deselect it */ 1765 SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL, 1821 SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL, 1766 1822 (WPARAM)-1, 0); 1767 1823 } … … 1787 1843 case WM_SETFOCUS: 1788 1844 /* remember the focus to set state of icon */ 1789 lret = CallWindowProcW (infoPtr->prevEditWndProc, 1845 lret = CallWindowProcW (infoPtr->prevEditWndProc, 1790 1846 hwnd, uMsg, wParam, lParam); 1791 1847 infoPtr->flags |= WCBE_EDITFOCUSED; … … 1793 1849 1794 1850 case WM_KILLFOCUS: 1795 /* 1851 /* 1796 1852 * do NOTIFY CBEN_ENDEDIT with CBENF_KILLFOCUS 1797 1853 */ … … 1811 1867 1812 1868 default: 1813 return CallWindowProcW (infoPtr->prevEditWndProc, 1869 return CallWindowProcW (infoPtr->prevEditWndProc, 1814 1870 hwnd, uMsg, wParam, lParam); 1815 1871 } … … 1829 1885 HWND focusedhwnd; 1830 1886 RECT rect; 1887 POINT pt; 1831 1888 WCHAR edit_text[260]; 1832 1889 1833 TRACE("hwnd=% x msg=%x wparam=%x lParam=%lx, info_ptr=%p\n",1890 TRACE("hwnd=%p msg=%x wparam=%x lParam=%lx, info_ptr=%p\n", 1834 1891 hwnd, uMsg, wParam, lParam, infoPtr); 1835 1892 … … 1838 1895 switch (uMsg) 1839 1896 { 1840 1841 case CB_FINDSTRINGEXACT:1842 return COMBOEX_FindStringExact (infoPtr, (INT)wParam, (LPCSTR)lParam);1843 1897 1844 1898 case WM_DRAWITEM: … … 1849 1903 */ 1850 1904 ((DRAWITEMSTRUCT *)lParam)->itemState |= ODS_COMBOEXLBOX; 1851 return CallWindowProcW (infoPtr->prevComboWndProc, 1905 return CallWindowProcW (infoPtr->prevComboWndProc, 1852 1906 hwnd, uMsg, wParam, lParam); 1853 1907 1854 1908 case WM_ERASEBKGND: 1855 1909 /* 1856 * The following was determined by traces of the native 1910 * The following was determined by traces of the native 1857 1911 */ 1858 1912 hDC = (HDC) wParam; … … 1863 1917 ExtTextOutW (hDC, 0, 0, ETO_OPAQUE, &rect, 0, 0, 0); 1864 1918 SetBkColor (hDC, obkc); 1865 return CallWindowProcW (infoPtr->prevComboWndProc, 1919 return CallWindowProcW (infoPtr->prevComboWndProc, 1866 1920 hwnd, uMsg, wParam, lParam); 1867 1921 … … 1878 1932 nmmse.dwHitInfo = lParam; 1879 1933 COMBOEX_Notify (infoPtr, NM_SETCURSOR, (NMHDR *)&nmmse); 1880 return CallWindowProcW (infoPtr->prevComboWndProc, 1934 return CallWindowProcW (infoPtr->prevComboWndProc, 1881 1935 hwnd, uMsg, wParam, lParam); 1936 1937 case WM_LBUTTONDOWN: 1938 GetClientRect (hwnd, &rect); 1939 rect.bottom = rect.top + SendMessageW(infoPtr->hwndSelf, 1940 CB_GETITEMHEIGHT, -1, 0); 1941 rect.left = rect.right - GetSystemMetrics(SM_CXVSCROLL); 1942 POINTSTOPOINT(pt, MAKEPOINTS(lParam)); 1943 if (PtInRect(&rect, pt)) 1944 return CallWindowProcW (infoPtr->prevComboWndProc, 1945 hwnd, uMsg, wParam, lParam); 1946 infoPtr->flags |= WCBE_MOUSECAPTURED; 1947 SetCapture(hwnd); 1948 break; 1949 1950 case WM_LBUTTONUP: 1951 if (!(infoPtr->flags & WCBE_MOUSECAPTURED)) 1952 return CallWindowProcW (infoPtr->prevComboWndProc, 1953 hwnd, uMsg, wParam, lParam); 1954 ReleaseCapture(); 1955 infoPtr->flags &= ~WCBE_MOUSECAPTURED; 1956 if (infoPtr->flags & WCBE_MOUSEDRAGGED) { 1957 infoPtr->flags &= ~WCBE_MOUSEDRAGGED; 1958 } else { 1959 SendMessageW(hwnd, CB_SHOWDROPDOWN, TRUE, 0); 1960 } 1961 break; 1962 1963 case WM_MOUSEMOVE: 1964 if ( (infoPtr->flags & WCBE_MOUSECAPTURED) && 1965 !(infoPtr->flags & WCBE_MOUSEDRAGGED)) { 1966 GetWindowTextW (infoPtr->hwndEdit, edit_text, 260); 1967 COMBOEX_NotifyDragBegin(infoPtr, edit_text); 1968 infoPtr->flags |= WCBE_MOUSEDRAGGED; 1969 } 1970 return CallWindowProcW (infoPtr->prevComboWndProc, 1971 hwnd, uMsg, wParam, lParam); 1882 1972 1883 1973 case WM_COMMAND: … … 1918 2008 if (focusedhwnd) 1919 2009 SendMessageW (infoPtr->hwndCombo, WM_KILLFOCUS, 1920 (WPARAM)focusedhwnd, 0); 2010 (WPARAM)focusedhwnd, 0); 1921 2011 return 0; 1922 2012 1923 2013 case EN_SETFOCUS: { 1924 /* 2014 /* 1925 2015 * For EN_SETFOCUS this issues the same calls and messages 1926 2016 * as the native seems to do. … … 1948 2038 1949 2039 case EN_CHANGE: { 1950 /* 2040 /* 1951 2041 * For EN_CHANGE this issues the same calls and messages 1952 2042 * as the native seems to do. … … 1954 2044 WCHAR edit_text[260]; 1955 2045 LPCWSTR lastwrk; 1956 INT selected; 1957 CBE_ITEMDATA *item; 1958 1959 selected = SendMessageW (infoPtr->hwndCombo, 1960 CB_GETCURSEL, 0, 0); 2046 cmp_func_t cmptext = get_cmp_func(infoPtr); 2047 2048 INT selected = SendMessageW (infoPtr->hwndCombo, 2049 CB_GETCURSEL, 0, 0); 1961 2050 1962 2051 /* lstrlenA( lastworkingURL ) */ … … 1967 2056 } 1968 2057 else { 1969 item = COMBOEX_FindItem (infoPtr, selected);2058 CBE_ITEMDATA *item = COMBOEX_FindItem (infoPtr, selected); 1970 2059 lastwrk = COMBOEX_GetText(infoPtr, item); 1971 2060 } … … 1976 2065 debugstr_w(edit_text)); 1977 2066 1978 /* lstrcmpiWis between lastworkingURL and GetWindowText */1979 if ( lstrcmpiW(lastwrk, edit_text)) {2067 /* cmptext is between lastworkingURL and GetWindowText */ 2068 if (cmptext (lastwrk, edit_text)) { 1980 2069 /* strings not equal -- indicate edit has changed */ 1981 2070 infoPtr->flags |= WCBE_EDITCHG; … … 1984 2073 MAKEWPARAM(GetDlgCtrlID (infoPtr->hwndSelf), 1985 2074 CBN_EDITCHANGE), 1986 infoPtr->hwndSelf);2075 (LPARAM)infoPtr->hwndSelf); 1987 2076 return 0; 1988 2077 } … … 2024 2113 }/* fall through */ 2025 2114 default: 2026 return CallWindowProcW (infoPtr->prevComboWndProc, 2115 return CallWindowProcW (infoPtr->prevComboWndProc, 2027 2116 hwnd, uMsg, wParam, lParam); 2028 2117 } … … 2036 2125 COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd); 2037 2126 2038 TRACE("hwnd=% xmsg=%x wparam=%x lParam=%lx\n", hwnd, uMsg, wParam, lParam);2127 TRACE("hwnd=%p msg=%x wparam=%x lParam=%lx\n", hwnd, uMsg, wParam, lParam); 2039 2128 2040 2129 if (!infoPtr) { … … 2052 2141 2053 2142 case CBEM_GETCOMBOCONTROL: 2054 return infoPtr->hwndCombo;2143 return (LRESULT)infoPtr->hwndCombo; 2055 2144 2056 2145 case CBEM_GETEDITCONTROL: 2057 return infoPtr->hwndEdit;2146 return (LRESULT)infoPtr->hwndEdit; 2058 2147 2059 2148 case CBEM_GETEXTENDEDSTYLE: … … 2099 2188 /*case CBEM_SETWINDOWTHEME: 2100 2189 FIXME("CBEM_SETWINDOWTHEME: stub\n");*/ 2190 2191 case WM_SETTEXT: 2192 case WM_GETTEXT: 2193 return SendMessageW(infoPtr->hwndEdit, uMsg, wParam, lParam); 2101 2194 2102 2195 /* Combo messages we are not sure if we need to process or just forward */ … … 2109 2202 case CB_RESETCONTENT: 2110 2203 case CB_SELECTSTRING: 2111 case WM_SETTEXT:2112 case WM_GETTEXT:2113 FIXME("(0x%x 0x%x 0x%lx): possibly missing function\n",2114 uMsg, wParam, lParam);2115 2204 2116 2205 /* Combo messages OK to just forward to the regular COMBO */ 2117 case CB_GETCOUNT: 2206 case CB_GETCOUNT: 2118 2207 case CB_GETCURSEL: 2119 2208 case CB_GETDROPPEDSTATE: … … 2125 2214 /* Combo messages we need to process specially */ 2126 2215 case CB_FINDSTRINGEXACT: 2127 return COMBOEX_FindStringExact (infoPtr, (INT)wParam, (LPC STR)lParam);2216 return COMBOEX_FindStringExact (infoPtr, (INT)wParam, (LPCWSTR)lParam); 2128 2217 2129 2218 case CB_GETITEMDATA: … … 2175 2264 2176 2265 default: 2177 if ( uMsg >= WM_USER)2266 if ((uMsg >= WM_USER) && (uMsg < WM_APP)) 2178 2267 ERR("unknown msg %04x wp=%08x lp=%08lx\n",uMsg,wParam,lParam); 2179 2268 return DefWindowProcW (hwnd, uMsg, wParam, lParam); … … 2195 2284 wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 2196 2285 wndClass.lpszClassName = WC_COMBOBOXEXW; 2197 2286 2198 2287 RegisterClassW (&wndClass); 2199 2288 } … … 2204 2293 UnregisterClassW (WC_COMBOBOXEXW, (HINSTANCE)NULL); 2205 2294 } 2206
Note:
See TracChangeset
for help on using the changeset viewer.
