Commit 45e6f624 authored by Guy L. Albertelli's avatar Guy L. Albertelli Committed by Alexandre Julliard

- Implement CB_SETCURSEL, CBEM_DELETEITEM, CBEM_GETITEM,

CBEM_{GET|SET}UNICODEFORMAT, CB_FINDSTRINGEXACT, WM_COMMAND, WM_DELETEITEM. - Implement extended style CBES_EX_NOEDITIMAGE, and warn others are not yet implemented. - Restructure DrawItem code to do things more rationally.
parent 79413eda
......@@ -28,15 +28,19 @@
* 4. Dump input data for things using COMBOBOXEXITEM{A|W}.
* 5. Handle positioning EDIT control based on whether icon present.
* 6. Make InsertItemA use InsertItemW, and store all data in ..W form.
* 7. Implement CB_SETCURSEL.
* 7. Implement CBEM_DELETEITEM, CBEM_GETITEM{A|W}, CB_SETCURSEL,
* CBEM_{GET|SET}UNICODEFORMAT.
* 8. Add override for WNDPROC for the COMBO control.
* 9. Support extended style CBES_EX_NOEDITIMAGE and warn others are not
* supported.
* 10. Implement CB_FINDSTRINGEXACT in both the Combo and ComboEx window
* procs to match the items. This eliminates dup entries in the listbox.
*
* Test vehicals were the ControlSpy modules (rebar.exe and comboboxex.exe),
* and IE 4.0.
*
*/
#include <string.h>
#include "winbase.h"
#include "commctrl.h"
#include "debugtools.h"
......@@ -76,6 +80,7 @@ typedef struct
DWORD flags; /* WINE internal flags */
HFONT font;
INT nb_items; /* Number of items */
BOOL bUnicode; /* ASCII (FALSE) or Unicode (TRUE)? */
CBE_ITEMDATA *edit; /* item data for edit item */
CBE_ITEMDATA *items; /* Array of items */
} COMBOEX_INFO;
......@@ -85,11 +90,26 @@ typedef struct
* CBEN_BEGINEDIT issued
* but CBEN_ENDEDIT{A|W}
* not yet issued. */
#define WCBE_EDITCHG 0x00000002 /* Edit issued EN_CHANGE */
#define ID_CB_EDIT 1001
/*
* Special flag set in DRAWITEMSTRUCT itemState field. It is set by
* the ComboEx version of the Combo Window Proc so that when the
* WM_DRAWITEM message is then passed to ComboEx, we know that this
* particular WM_DRAWITEM message is for listbox only items. Any messasges
* without this flag is then for the Edit control field.
*
* We really cannot use the ODS_COMBOBOXEDIT flag because MSDN states that
* only version 4.0 applications will have ODS_COMBOBOXEDIT set.
*/
#define ODS_COMBOEXLBOX 0x4000
/* Height in pixels of control over the amount of the selected font */
#define CBE_EXTRA 3
......@@ -154,8 +174,6 @@ COMBOEX_Forward (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
FIXME("(0x%x 0x%x 0x%lx): stub\n", uMsg, wParam, lParam);
if (infoPtr->hwndCombo)
return SendMessageA (infoPtr->hwndCombo, uMsg, wParam, lParam);
......@@ -164,14 +182,18 @@ COMBOEX_Forward (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static INT
COMBOEX_Notify (COMBOEX_INFO *infoPtr, INT code, NMHDR *hdr)
COMBOEX_Notify (COMBOEX_INFO *infoPtr, INT code, NMHDR *hdr, BOOL doW)
{
hdr->idFrom = GetDlgCtrlID (infoPtr->hwndSelf);
hdr->hwndFrom = infoPtr->hwndSelf;
hdr->code = code;
return SendMessageA (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0,
(LPARAM)hdr);
if (doW)
return SendMessageW (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0,
(LPARAM)hdr);
else
return SendMessageA (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0,
(LPARAM)hdr);
}
......@@ -182,7 +204,7 @@ COMBOEX_GetComboFontSize (COMBOEX_INFO *infoPtr, SIZE *size)
HDC mydc;
mydc = GetDC (0); /* why the entire screen???? */
nfont = SendMessageA (infoPtr->hwndCombo, WM_GETFONT, 0, 0);
nfont = SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0);
ofont = (HFONT) SelectObject (mydc, nfont);
GetTextExtentPointA (mydc, "A", 1, size);
SelectObject (mydc, ofont);
......@@ -192,6 +214,27 @@ COMBOEX_GetComboFontSize (COMBOEX_INFO *infoPtr, SIZE *size)
static void
COMBOEX_CopyItem (COMBOEX_INFO *infoPtr, CBE_ITEMDATA *item, COMBOBOXEXITEMW *cit)
{
if (cit->mask & CBEIF_TEXT) {
cit->pszText = item->pszText;
cit->cchTextMax = item->cchTextMax;
}
if (cit->mask & CBEIF_IMAGE)
cit->iImage = item->iImage;
if (cit->mask & CBEIF_SELECTEDIMAGE)
cit->iSelectedImage = item->iSelectedImage;
if (cit->mask & CBEIF_OVERLAY)
cit->iOverlay = item->iOverlay;
if (cit->mask & CBEIF_INDENT)
cit->iIndent = item->iIndent;
if (cit->mask & CBEIF_LPARAM)
cit->lParam = item->lParam;
}
static void
COMBOEX_AdjustEditPos (COMBOEX_INFO *infoPtr)
{
SIZE mysize;
......@@ -212,8 +255,8 @@ COMBOEX_AdjustEditPos (COMBOEX_INFO *infoPtr)
/* reposition the Edit control based on whether icon exists */
COMBOEX_GetComboFontSize (infoPtr, &mysize);
TRACE("Combo font x=%ld, y=%ld\n", mysize.cx, mysize.cy);
x = xoff + CBE_STARTOFFSET;
y = CBE_EXTRA;
x = xoff + CBE_STARTOFFSET + 1;
y = CBE_EXTRA + 1;
w = rect.right-rect.left - x - GetSystemMetrics(SM_CXVSCROLL) - 1;
h = mysize.cy + 1;
......@@ -241,9 +284,9 @@ COMBOEX_ReSize (HWND hwnd, COMBOEX_INFO *infoPtr)
cy = max (iinfo.rcImage.bottom - iinfo.rcImage.top, cy);
TRACE("upgraded height due to image: height=%d\n", cy);
}
SendMessageA (hwnd, CB_SETITEMHEIGHT, (WPARAM) -1, (LPARAM) cy);
SendMessageW (hwnd, CB_SETITEMHEIGHT, (WPARAM) -1, (LPARAM) cy);
if (infoPtr->hwndCombo)
SendMessageA (infoPtr->hwndCombo, CB_SETITEMHEIGHT,
SendMessageW (infoPtr->hwndCombo, CB_SETITEMHEIGHT,
(WPARAM) 0, (LPARAM) cy);
}
......@@ -258,8 +301,8 @@ COMBOEX_SetEditText (COMBOEX_INFO *infoPtr, CBE_ITEMDATA *item)
/* EM_SETSEL32 (0,-1) */
if (item->mask & CBEIF_TEXT) {
SendMessageW (infoPtr->hwndEdit, WM_SETTEXT, 0, (LPARAM)item->pszText);
SendMessageA (infoPtr->hwndEdit, EM_SETSEL, 0, 0);
SendMessageA (infoPtr->hwndEdit, EM_SETSEL, 0, -1);
SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, 0);
SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, -1);
}
}
......@@ -293,7 +336,31 @@ COMBOEX_FindItem(COMBOEX_INFO *infoPtr, INT index)
/* *** CBEM_xxx message support *** */
/* << COMBOEX_DeleteItem >> */
static LRESULT
COMBOEX_DeleteItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
INT index = (INT) wParam;
CBE_ITEMDATA *item;
TRACE("(0x%08x 0x%08lx)\n", wParam, lParam);
/* if item number requested does not exist then return failure */
if ((index > infoPtr->nb_items) || (index < 0)) {
ERR("attempt to delete item that does not exist\n");
return CB_ERR;
}
if (!(item = COMBOEX_FindItem(infoPtr, index))) {
ERR("attempt to delete item that was not found!\n");
return CB_ERR;
}
/* doing this will result in WM_DELETEITEM being issued */
SendMessageW (infoPtr->hwndCombo, CB_DELETESTRING, (WPARAM)index, 0);
return infoPtr->nb_items;
}
inline static LRESULT
......@@ -341,22 +408,90 @@ COMBOEX_GetImageList (HWND hwnd, WPARAM wParam, LPARAM lParam)
}
/* << COMBOEX_GetItemA >> */
static LRESULT
COMBOEX_GetItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
COMBOBOXEXITEMW *cit = (COMBOBOXEXITEMW *) lParam;
INT index;
CBE_ITEMDATA *item;
TRACE("(0x%08x 0x%08lx)\n", wParam, lParam);
/* get real index of item to insert */
index = cit->iItem;
/* if item number requested does not exist then return failure */
if ((index > infoPtr->nb_items) || (index < -1)) {
ERR("attempt to get item that does not exist\n");
return 0;
}
/* if the item is the edit control and there is no edit control, skip */
if ((index == -1) &&
((GetWindowLongA (hwnd, GWL_STYLE) & CBS_DROPDOWNLIST) != CBS_DROPDOWN))
return 0;
if (!(item = COMBOEX_FindItem(infoPtr, index))) {
ERR("attempt to get item that was not found!\n");
return 0;
}
/* << COMBOEX_GetItemW >> */
COMBOEX_CopyItem (infoPtr, item, cit);
/* << COMBOEX_GetUniCodeFormat >> */
return TRUE;
}
static LRESULT
inline static LRESULT
COMBOEX_GetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
COMBOBOXEXITEMA *cit = (COMBOBOXEXITEMA *) lParam;
COMBOBOXEXITEMW tmpcit;
INT len;
TRACE("(0x%08x 0x%08lx)\n", wParam, lParam);
tmpcit.mask = cit->mask;
tmpcit.iItem = cit->iItem;
COMBOEX_GetItemW (hwnd, wParam, (LPARAM) &tmpcit);
len = WideCharToMultiByte (CP_ACP, 0, tmpcit.pszText, -1, 0, 0, NULL, NULL);
if (len > 0)
WideCharToMultiByte (CP_ACP, 0, tmpcit.pszText, -1,
cit->pszText, cit->cchTextMax, NULL, NULL);
cit->iImage = tmpcit.iImage;
cit->iSelectedImage = tmpcit.iSelectedImage;
cit->iOverlay = tmpcit.iOverlay;
cit->iIndent = tmpcit.iIndent;
cit->lParam = tmpcit.lParam;
return TRUE;
}
inline static LRESULT
COMBOEX_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
TRACE("%s hwnd=0x%x stub!\n",
infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
return infoPtr->bUnicode;
}
inline static LRESULT
COMBOEX_HasEditChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
if ((GetWindowLongA (hwnd, GWL_STYLE) & CBS_DROPDOWNLIST) != CBS_DROPDOWN)
return FALSE;
if (infoPtr->flags & WCBE_ACTEDIT)
/* FIXME: need to also test edit control */
if ((infoPtr->flags & (WCBE_ACTEDIT | WCBE_EDITCHG)) ==
(WCBE_ACTEDIT | WCBE_EDITCHG))
return TRUE;
return FALSE;
}
......@@ -369,6 +504,9 @@ COMBOEX_InsertItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
COMBOBOXEXITEMW *cit = (COMBOBOXEXITEMW *) lParam;
INT index;
CBE_ITEMDATA *item;
NMCOMBOBOXEXW nmcit;
TRACE("\n");
COMBOEX_DumpInput ((COMBOBOXEXITEMA *) cit, TRUE);
......@@ -434,9 +572,12 @@ COMBOEX_InsertItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
COMBOEX_DumpItem (item);
SendMessageA (infoPtr->hwndCombo, CB_INSERTSTRING,
SendMessageW (infoPtr->hwndCombo, CB_INSERTSTRING,
(WPARAM)cit->iItem, (LPARAM)item);
COMBOEX_CopyItem (infoPtr, item, &nmcit.ceItem);
COMBOEX_Notify (infoPtr, CBEN_INSERTITEM, (NMHDR *)&nmcit, TRUE);
return index;
}
......@@ -480,13 +621,31 @@ COMBOEX_SetExtendedStyle (HWND hwnd, WPARAM wParam, LPARAM lParam)
dwTemp = infoPtr->dwExtStyle;
if (lParam & (CBES_EX_NOEDITIMAGEINDENT |
CBES_EX_PATHWORDBREAKPROC |
CBES_EX_NOSIZELIMIT |
CBES_EX_CASESENSITIVE))
FIXME("Extended style not implemented %08lx\n", lParam);
if ((DWORD)wParam) {
infoPtr->dwExtStyle = (infoPtr->dwExtStyle & ~(DWORD)wParam) | (DWORD)lParam;
}
else
infoPtr->dwExtStyle = (DWORD)lParam;
/* FIXME: repaint?? */
/*
* native does this for CBES_EX_NOEDITIMAGE state change
*/
if ((infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGE) ^
(dwTemp & CBES_EX_NOEDITIMAGE)) {
/* if state of EX_NOEDITIMAGE changes, invalidate all */
TRACE("EX_NOEDITIMAGE state changed to %ld\n",
infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGE);
InvalidateRect (hwnd, NULL, TRUE);
COMBOEX_AdjustEditPos (infoPtr);
if (infoPtr->hwndEdit)
InvalidateRect (infoPtr->hwndEdit, NULL, TRUE);
}
return (LRESULT)dwTemp;
}
......@@ -605,30 +764,87 @@ COMBOEX_SetItemA (HWND hwnd, WPARAM wParam, LPARAM lParam)
}
/* << COMBOEX_SetUniCodeFormat >> */
inline static LRESULT
COMBOEX_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
BOOL bTemp;
TRACE("%s hwnd=0x%04x stub!\n",
((BOOL)wParam) ? "TRUE" : "FALSE", hwnd);
bTemp = infoPtr->bUnicode;
infoPtr->bUnicode = (BOOL)wParam;
return bTemp;
}
/* *** CB_xxx message support *** */
static LRESULT
COMBOEX_FindStringExact (COMBOEX_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
INT i, count;
CBE_ITEMDATA *item;
LPWSTR desired = NULL;
INT start = (INT) wParam;
i = MultiByteToWideChar (CP_ACP, 0, (LPSTR)lParam, -1, NULL, 0);
if (i > 0) {
desired = (LPWSTR)COMCTL32_Alloc ((i + 1)*sizeof(WCHAR));
MultiByteToWideChar (CP_ACP, 0, (LPSTR)lParam, -1, desired, i);
}
count = SendMessageW (infoPtr->hwndCombo, CB_GETCOUNT, 0 , 0);
/* now search from after starting loc and wrapping back to start */
for(i=start+1; i<count; i++) {
item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo,
CB_GETITEMDATA, (WPARAM)i, 0);
TRACE("desired=%s, item=%s\n",
debugstr_w(desired), debugstr_w(item->pszText));
if (lstrcmpiW(item->pszText, desired) == 0) {
COMCTL32_Free (desired);
return i;
}
}
for(i=0; i<=start; i++) {
item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo,
CB_GETITEMDATA, (WPARAM)i, 0);
TRACE("desired=%s, item=%s\n",
debugstr_w(desired), debugstr_w(item->pszText));
if (lstrcmpiW(item->pszText, desired) == 0) {
COMCTL32_Free (desired);
return i;
}
}
COMCTL32_Free(desired);
return CB_ERR;
}
static LRESULT
COMBOEX_SetCursel (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
INT index = wParam;
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
CBE_ITEMDATA *item;
LRESULT lret;
if (!(item = COMBOEX_FindItem(infoPtr, index))) {
/* FIXME: need to clear selection */
return CB_ERR;
}
TRACE("selecting item %d\n", index);
TRACE("selecting item %d text=%s\n", index, (item->pszText) ?
debugstr_w(item->pszText) : "<null>");
lret = SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL, wParam, lParam);
COMBOEX_SetEditText (infoPtr, item);
if (infoPtr->hwndCombo)
return SendMessageA (infoPtr->hwndCombo, CB_SETCURSEL, wParam, lParam);
return CB_ERR;
return lret;
}
......@@ -643,7 +859,7 @@ COMBOEX_SetItemHeight (HWND hwnd, WPARAM wParam, LPARAM lParam)
/* First, lets forward the message to the normal combo control
just like Windows. */
if (infoPtr->hwndCombo)
SendMessageA (infoPtr->hwndCombo, CB_SETITEMHEIGHT, wParam, lParam);
SendMessageW (infoPtr->hwndCombo, CB_SETITEMHEIGHT, wParam, lParam);
GetWindowRect (infoPtr->hwndCombo, &cb_wrect);
GetWindowRect (hwnd, &cbx_wrect);
......@@ -719,31 +935,9 @@ COMBOEX_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
/* was base and is necessary */
WS_CHILD | WS_VISIBLE | CBS_OWNERDRAWFIXED | dwComboStyle,
cs->y, cs->x, cs->cx, cs->cy, hwnd,
/* (HMENU) GetWindowLongA (hwnd, GWL_ID), */
/* */ (HMENU) 0, /* */
(HMENU) GetWindowLongA (hwnd, GWL_ID),
GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
#if 0
/* ***** not needed any more ***** */
LPHEADCOMBO lphc;
/*
* The following does not work (WIN98 or later) but we need
* the list box handle for later
* SendMessageA(infoPtr->hwndCombo, CB_GETCOMBOBOXINFO, 0,
* (LPARAM) &comboinfo);
* infoPtr->hwndLBox = comboinfo.hwndList;
*
* So we need to violate philosophical separation by the following
* code.
*/
lphc = (LPHEADCOMBO) GetWindowLongA(infoPtr->hwndCombo, 0);
infoPtr->hwndLBox = lphc->hWndLBox;
if (!infoPtr->hwndLBox) {
ERR("error error listbox handle zero\n");
}
#endif
/*
* native does the following at this point according to trace:
* GetWindowThreadProcessId(hwndCombo,0)
......@@ -762,7 +956,7 @@ COMBOEX_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
}
infoPtr->prevComboWndProc = (WNDPROC)SetWindowLongA(infoPtr->hwndCombo,
GWL_WNDPROC, (LONG)COMBOEX_ComboWndProc);
infoPtr->font = SendMessageA (infoPtr->hwndCombo, WM_GETFONT, 0, 0);
infoPtr->font = SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0);
/*
......@@ -795,7 +989,7 @@ COMBOEX_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
}
infoPtr->prevEditWndProc = (WNDPROC)SetWindowLongA(infoPtr->hwndEdit,
GWL_WNDPROC, (LONG)COMBOEX_EditWndProc);
infoPtr->font = SendMessageA (infoPtr->hwndCombo, WM_GETFONT, 0, 0);
infoPtr->font = SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0);
}
else {
infoPtr->hwndEdit = 0;
......@@ -811,10 +1005,10 @@ COMBOEX_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
&mylogfont, 0);
infoPtr->font = CreateFontIndirectA (&mylogfont);
}
SendMessageA (infoPtr->hwndCombo, WM_SETFONT, (WPARAM)infoPtr->font, 0);
SendMessageW (infoPtr->hwndCombo, WM_SETFONT, (WPARAM)infoPtr->font, 0);
if (infoPtr->hwndEdit) {
SendMessageA (infoPtr->hwndEdit, WM_SETFONT, (WPARAM)infoPtr->font, 0);
SendMessageA (infoPtr->hwndEdit, EM_SETMARGINS, (WPARAM)EC_USEFONTINFO, 0);
SendMessageW (infoPtr->hwndEdit, WM_SETFONT, (WPARAM)infoPtr->font, 0);
SendMessageW (infoPtr->hwndEdit, EM_SETMARGINS, (WPARAM)EC_USEFONTINFO, 0);
}
COMBOEX_ReSize (hwnd, infoPtr);
......@@ -856,6 +1050,140 @@ COMBOEX_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
inline static LRESULT
COMBOEX_Command (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
LRESULT lret;
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
INT command = HIWORD(wParam);
CBE_ITEMDATA *item = 0;
WCHAR wintext[520];
INT cursel, n;
NMCBEENDEDITA cbeend;
TRACE("for command %d\n", command);
switch (command)
{
case CBN_DROPDOWN:
SendMessageW (GetParent (hwnd), WM_COMMAND, wParam,
(LPARAM)hwnd);
/*
* from native trace of first dropdown after typing in URL in IE4
* CB_GETCURSEL(Combo)
* GetWindowText(Edit)
* CB_GETCURSEL(Combo)
* CB_GETCOUNT(Combo)
* CB_GETITEMDATA(Combo, n)
* WM_NOTIFY(parent, CBEN_ENDEDITA|W)
* CB_GETCURSEL(Combo)
* CB_SETCURSEL(COMBOEX, n)
* SetFocus(Combo)
* the rest is supposition
*/
cursel = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0);
if (cursel == -1) {
/* find match from edit against those in Combobox */
GetWindowTextW (infoPtr->hwndEdit, wintext, 520);
n = SendMessageW (infoPtr->hwndCombo, CB_GETCOUNT, 0, 0);
for (cursel = 0; cursel < n; cursel++){
item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo,
CB_GETITEMDATA,
cursel, 0);
if ((INT)item == CB_ERR) break;
if (lstrcmpiW(item->pszText, wintext) == 0) break;
}
if ((cursel == n) || ((INT)item == CB_ERR)) {
TRACE("failed to find match??? item=%p cursel=%d\n",
item, cursel);
if (infoPtr->hwndEdit)
SetFocus(infoPtr->hwndEdit);
return 0;
}
}
if (infoPtr->flags & WCBE_ACTEDIT) {
cbeend.fChanged = (infoPtr->flags & WCBE_EDITCHG);
cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
CB_GETCURSEL, 0, 0);
cbeend.iWhy = CBENF_DROPDOWN;
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
if (COMBOEX_Notify (infoPtr, CBEN_ENDEDITA,
(NMHDR *)&cbeend, FALSE)) {
/* abort the change */
TRACE("Notify requested abort of change\n");
return 0;
}
}
SendMessageW (hwnd, CB_SETCURSEL, cursel, 0);
SetFocus(infoPtr->hwndCombo);
return 0;
default:
/*
* We have to change the handle since we are the control
* issuing the message. IE4 depends on this.
* We also need to set the focus back to the Edit control
* after passing the command to the parent of the ComboEx.
*/
lret = SendMessageW (GetParent (hwnd), WM_COMMAND, wParam,
(LPARAM)hwnd);
if (infoPtr->hwndEdit)
SetFocus(infoPtr->hwndEdit);
return lret;
}
return 0;
}
inline static LRESULT
COMBOEX_WM_DeleteItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
DELETEITEMSTRUCT *dis = (DELETEITEMSTRUCT *)lParam;
CBE_ITEMDATA *item, *olditem;
INT i;
NMCOMBOBOXEXW nmcit;
TRACE("CtlType=%08x, CtlID=%08x, itemID=%08x, hwnd=%x, data=%08lx\n",
dis->CtlType, dis->CtlID, dis->itemID, dis->hwndItem, dis->itemData);
if ((dis->itemID >= infoPtr->nb_items) || (dis->itemID < 0)) return FALSE;
olditem = infoPtr->items;
i = infoPtr->nb_items - 1;
if (i == dis->itemID) {
infoPtr->items = infoPtr->items->next;
}
else {
item = olditem;
i--;
/* find the prior item in the list */
while (item->next && (i > dis->itemID)) {
item = (CBE_ITEMDATA *)item->next;
i--;
}
if (!item->next || (i != dis->itemID)) {
FIXME("COMBOBOXEX item structures broken. Please report!\n");
return FALSE;
}
olditem = item->next;
item->next = (CBE_ITEMDATA *)((CBE_ITEMDATA *)item->next)->next;
}
infoPtr->nb_items--;
COMBOEX_CopyItem (infoPtr, olditem, &nmcit.ceItem);
COMBOEX_Notify (infoPtr, CBEN_DELETEITEM, (NMHDR *)&nmcit, TRUE);
COMCTL32_Free(olditem);
return TRUE;
}
inline static LRESULT
COMBOEX_DrawItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
......@@ -885,40 +1213,14 @@ COMBOEX_DrawItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
if (dis->itemID == 0xffffffff) {
if ( ( (dis->itemAction & ODA_FOCUS) && (dis->itemState & ODS_SELECTED)) ||
( (dis->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)) && (dis->itemState & ODS_FOCUS) ) ) {
TRACE("drawing item -1 special focus, rect=(%d,%d)-(%d,%d)\n",
dis->rcItem.left, dis->rcItem.top,
dis->rcItem.right, dis->rcItem.bottom);
DrawFocusRect(dis->hDC, &dis->rcItem);
return 0;
}
else if ((dis->CtlType == ODT_COMBOBOX) &&
(dis->itemAction == ODA_DRAWENTIRE) &&
(dis->itemState == 0)) {
(dis->itemAction == ODA_DRAWENTIRE)) {
/* draw of edit control data */
CHAR str[260];
INT wlen, alen;
TRACE("drawing edit control\n");
item = infoPtr->edit;
if (item->pszText) {
COMCTL32_Free(item->pszText);
item->pszText = 0;
item->mask &= ~CBEIF_TEXT;
}
if (infoPtr->hwndEdit) {
alen = SendMessageA (infoPtr->hwndEdit, WM_GETTEXT, 260, (LPARAM)&str);
TRACE("hwndEdit=%0x, text len=%d str=<%s>\n", infoPtr->hwndEdit, alen, str);
if (alen > 0) {
item->mask |= CBEIF_TEXT;
wlen = MultiByteToWideChar (CP_ACP, 0, str, -1, NULL, 0);
if (wlen > 0) {
item->pszText = (LPWSTR)COMCTL32_Alloc ((wlen + 1)*sizeof(WCHAR));
MultiByteToWideChar (CP_ACP, 0, str, -1, item->pszText, wlen);
}
}
}
/* testing */
{
......@@ -943,14 +1245,48 @@ COMBOEX_DrawItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
}
}
if (!item)
item = (CBE_ITEMDATA *)SendMessageA (infoPtr->hwndCombo,
/* If draw item is -1 (edit control) setup the item pointer */
if (dis->itemID == 0xffffffff) {
CHAR str[260];
INT wlen, alen;
if (!infoPtr->hwndEdit) {
ERR("request to draw edit item, but no edit control exists!\n");
return 0;
}
item = infoPtr->edit;
/* free previous text of edit item */
if (item->pszText) {
COMCTL32_Free(item->pszText);
item->pszText = 0;
item->mask &= ~CBEIF_TEXT;
}
alen = SendMessageA (infoPtr->hwndEdit, WM_GETTEXT, 260, (LPARAM)&str);
TRACE("edit control hwndEdit=%0x, text len=%d str=<%s>\n",
infoPtr->hwndEdit, alen, str);
if (alen > 0) {
item->mask |= CBEIF_TEXT;
wlen = MultiByteToWideChar (CP_ACP, 0, str, -1, NULL, 0);
if (wlen > 0) {
item->pszText = (LPWSTR)COMCTL32_Alloc ((wlen + 1)*sizeof(WCHAR));
MultiByteToWideChar (CP_ACP, 0, str, -1, item->pszText, wlen);
}
}
}
/* if the item pointer is not set, then get the data and locate it */
if (!item) {
item = (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo,
CB_GETITEMDATA, (WPARAM)dis->itemID, 0);
if (item == (CBE_ITEMDATA *)CB_ERR)
{
FIXME("invalid item for id %d \n",dis->itemID);
return 0;
if (item == (CBE_ITEMDATA *)CB_ERR)
{
FIXME("invalid item for id %d \n",dis->itemID);
return 0;
}
}
/* dump the DRAWITEMSTRUCT if tracing "comboex" but not "message" */
if (!TRACE_ON(message)) {
TRACE("DRAWITEMSTRUCT: CtlType=0x%08x CtlID=0x%08x\n",
dis->CtlType, dis->CtlID);
......@@ -960,11 +1296,11 @@ COMBOEX_DrawItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
dis->hwndItem, dis->hDC, dis->rcItem.left,
dis->rcItem.top, dis->rcItem.right, dis->rcItem.bottom,
dis->itemData);
}
}
COMBOEX_DumpItem (item);
xbase = CBE_STARTOFFSET;
if (item->mask & CBEIF_INDENT)
if ((item->mask & CBEIF_INDENT) && (dis->itemState & ODS_COMBOEXLBOX))
xbase += (item->iIndent * CBE_INDENT);
if (item->mask & CBEIF_IMAGE) {
ImageList_GetImageInfo(infoPtr->himl, item->iImage, &iinfo);
......@@ -975,28 +1311,43 @@ COMBOEX_DrawItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
case ODA_FOCUS:
if (dis->itemState & ODS_SELECTED /*1*/) {
if ((item->mask & CBEIF_TEXT) && item->pszText) {
RECT rect2;
len = strlenW (item->pszText);
GetTextExtentPointW (dis->hDC, item->pszText, len, &txtsize);
rect.left = xbase + xioff - 1;
rect.top = dis->rcItem.top - 1 +
(dis->rcItem.bottom - dis->rcItem.top - txtsize.cy) / 2;
rect.right = rect.left + txtsize.cx + 2;
rect.bottom = rect.top + txtsize.cy + 2;
rect.top = dis->rcItem.top;
rect.bottom = dis->rcItem.bottom;
GetClipBox (dis->hDC, &rect2);
TRACE("drawing item %d focus, rect=(%d,%d)-(%d,%d)\n",
dis->itemID, rect.left, rect.top,
rect.right, rect.bottom);
TRACE(" clip=(%d,%d)-(%d,%d)\n",
rect2.left, rect2.top,
rect2.right, rect2.bottom);
DrawFocusRect(dis->hDC, &rect);
}
else {
FIXME("ODA_FOCUS and ODS_SELECTED but no text\n");
}
}
else {
FIXME("ODA_FOCUS but not ODS_SELECTED\n");
}
break;
case ODA_SELECT:
case ODA_DRAWENTIRE:
drawimage = -1;
if (item->mask & CBEIF_IMAGE) drawimage = item->iImage;
if ((dis->itemState & ODS_SELECTED) &&
(item->mask & CBEIF_SELECTEDIMAGE))
drawimage = item->iSelectedImage;
if (!(infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGE)) {
if (item->mask & CBEIF_IMAGE) drawimage = item->iImage;
if ((dis->itemState & ODS_SELECTED) &&
(item->mask & CBEIF_SELECTEDIMAGE))
drawimage = item->iSelectedImage;
}
if (drawimage != -1) {
TRACE("drawing image state=%d\n", dis->itemState & ODS_SELECTED);
ImageList_Draw (infoPtr->himl, drawimage, dis->hDC,
xbase, dis->rcItem.top,
(dis->itemState & ODS_SELECTED) ?
......@@ -1006,7 +1357,7 @@ COMBOEX_DrawItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
UINT x, y;
COLORREF nbkc, ntxc;
len = strlenW (item->pszText);
len = lstrlenW (item->pszText);
GetTextExtentPointW (dis->hDC, item->pszText, len, &txtsize);
nbkc = GetSysColor ((dis->itemState & ODS_SELECTED) ?
COLOR_HIGHLIGHT : COLOR_WINDOW);
......@@ -1019,8 +1370,8 @@ COMBOEX_DrawItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
(dis->rcItem.bottom - dis->rcItem.top - txtsize.cy) / 2;
rect.left = x;
rect.right = x + txtsize.cx;
rect.top = y;
rect.bottom = y + txtsize.cy;
rect.top = dis->rcItem.top + 1;
rect.bottom = dis->rcItem.bottom - 1;
TRACE("drawing item %d text, rect=(%d,%d)-(%d,%d)\n",
dis->itemID, rect.left, rect.top, rect.right, rect.bottom);
ExtTextOutW (dis->hDC, x, y, ETO_OPAQUE | ETO_CLIPPED,
......@@ -1029,8 +1380,8 @@ COMBOEX_DrawItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
rect.top -= 1;
rect.bottom += 1;
rect.left -= 1;
rect.right += 2;
TRACE("drawing item %d focus, rect=(%d,%d)-(%d,%d)\n",
rect.right += 1;
TRACE("drawing item %d focus after text, rect=(%d,%d)-(%d,%d)\n",
dis->itemID, rect.left, rect.top, rect.right, rect.bottom);
DrawFocusRect (dis->hDC, &rect);
}
......@@ -1150,7 +1501,6 @@ COMBOEX_WindowPosChanging (HWND hwnd, WPARAM wParam, LPARAM lParam)
cb_wrect.bottom-cb_wrect.top,
SWP_NOACTIVATE);
/* ****** new # 3 ******* */
COMBOEX_AdjustEditPos (infoPtr);
return 0;
......@@ -1161,6 +1511,10 @@ static LRESULT WINAPI
COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = (COMBOEX_INFO *)GetPropA (hwnd, (LPCSTR)(LONG) ComboExInfo);
NMCBEENDEDITA cbeend;
COLORREF nbkc, obkc;
HDC hDC;
RECT rect;
TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx, info_ptr=%p\n",
hwnd, uMsg, wParam, lParam, infoPtr);
......@@ -1170,10 +1524,32 @@ COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
switch (uMsg)
{
case WM_CHAR:
/* handle (ignore) the return character */
if (wParam == VK_RETURN) return 0;
/* all other characters pass into the real Edit */
return CallWindowProcA (infoPtr->prevEditWndProc,
hwnd, uMsg, wParam, lParam);
case WM_ERASEBKGND:
/*
* The following was determined by traces of the native
*/
hDC = (HDC) wParam;
nbkc = GetSysColor (COLOR_WINDOW);
obkc = SetBkColor (hDC, nbkc);
GetClientRect (hwnd, &rect);
TRACE("erasing (%d,%d)-(%d,%d)\n",
rect.left, rect.top, rect.right, rect.bottom);
ExtTextOutW (hDC, 0, 0, ETO_OPAQUE, &rect, 0, 0, 0);
SetBkColor (hDC, obkc);
return CallWindowProcA (infoPtr->prevEditWndProc,
hwnd, uMsg, wParam, lParam);
case WM_KEYDOWN: {
NMCBEENDEDITA cbeend;
INT oldItem;
INT oldItem, selected;
CBE_ITEMDATA *item;
WCHAR edit_text[260];
switch ((INT)wParam)
{
......@@ -1199,18 +1575,19 @@ COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
GetWindowTextA (infoPtr->hwndEdit, cbeend.szText, 260);
infoPtr->flags &= ~WCBE_ACTEDIT;
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
cbeend.fChanged = FALSE;
cbeend.iNewSelection = SendMessageA (infoPtr->hwndCombo,
cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
CB_GETCURSEL, 0, 0);
cbeend.iWhy = CBENF_ESCAPE;
if (COMBOEX_Notify (infoPtr, CBEN_ENDEDITA,
(NMHDR *)&cbeend)) {
(NMHDR *)&cbeend, FALSE)) {
/* abort the change */
TRACE("Notify requested abort of change\n");
return 0;
}
oldItem = SendMessageA (infoPtr->hwndCombo,CB_GETCURSEL, 0, 0);
oldItem = SendMessageW (infoPtr->hwndCombo,CB_GETCURSEL, 0, 0);
InvalidateRect (infoPtr->hwndCombo, 0, 0);
if (!(item = COMBOEX_FindItem(infoPtr, oldItem))) {
ERR("item %d not found. Problem!\n", oldItem);
......@@ -1228,13 +1605,17 @@ COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
* GetWindowTextA(Edit,&?, 0x104) x
* CB_GETCURSEL to Combo rets -1 x
* CB_GETCOUNT to Combo rets 0
* if >0 loop
* CB_GETITEMDATA to match
* *** above 3 lines simulated by FindItem x
* WM_NOTIFY to COMBOEX parent (rebar) x
* (CBEN_ENDEDIT{A|W}
* (CBEN_ENDEDIT{A|W} x
* fChanged = TRUE (-1) x
* iNewSelection = -1 x
* iNewSelection = -1 or selected x
* txt= x
* iWhy = 2 (CBENF_RETURN) x
* CB_GETCURSEL to Combo rets -1 x
* if -1 send CB_SETCURSEL to Combo -1 x
* InvalidateRect(Combo, 0, 0) x
* SetFocus(Edit) x
* CallWindowProc(406615a8, Edit, 0x100, 0xd, 0x1c0001)
......@@ -1242,20 +1623,46 @@ COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
TRACE("special code for VK_RETURN\n");
GetWindowTextA (infoPtr->hwndEdit, cbeend.szText, 260);
GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);
infoPtr->flags &= ~WCBE_ACTEDIT;
cbeend.iNewSelection = SendMessageA (infoPtr->hwndCombo,
CB_GETCURSEL, 0, 0);
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
selected = SendMessageW (infoPtr->hwndCombo,
CB_GETCURSEL, 0, 0);
if (selected != -1) {
item = COMBOEX_FindItem (infoPtr, selected);
TRACE("handling VK_RETURN, selected = %d, selected_text=%s\n",
selected, debugstr_w(item->pszText));
TRACE("handling VK_RETURN, edittext=%s\n",
debugstr_w(edit_text));
if (lstrcmpiW (item->pszText, edit_text)) {
/* strings not equal -- indicate edit has changed */
selected = -1;
}
}
cbeend.iNewSelection = selected;
cbeend.fChanged = TRUE;
cbeend.iWhy = CBENF_RETURN;
WideCharToMultiByte (CP_ACP, 0, edit_text, -1,
cbeend.szText, sizeof(cbeend.szText),
NULL, NULL);
if (COMBOEX_Notify (infoPtr, CBEN_ENDEDITA,
(NMHDR *)&cbeend)) {
/* abort the change */
(NMHDR *)&cbeend, FALSE)) {
/* abort the change, restore previous */
TRACE("Notify requested abort of change\n");
COMBOEX_SetEditText (infoPtr, infoPtr->edit);
RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE |
RDW_INVALIDATE);
return 0;
}
oldItem = SendMessageA (infoPtr->hwndCombo,CB_GETCURSEL, 0, 0);
oldItem = SendMessageW (infoPtr->hwndCombo,CB_GETCURSEL, 0, 0);
if (oldItem != -1) {
/* if something is selected, then deselect it */
SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL,
(WPARAM)-1, 0);
}
InvalidateRect (infoPtr->hwndCombo, 0, 0);
SetFocus(infoPtr->hwndEdit);
break;
......@@ -1265,17 +1672,24 @@ COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
hwnd, uMsg, wParam, lParam);
}
return 0;
}
}
case WM_KILLFOCUS:
/*
* should do NOTIFY CBEN_ENDEDIT with CBENF_KILLFOCUS
* ** fall through for now **
*/
infoPtr->flags &= ~WCBE_ACTEDIT;
if (infoPtr->flags & WCBE_ACTEDIT) {
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
cbeend.fChanged = FALSE;
cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
CB_GETCURSEL, 0, 0);
cbeend.iWhy = CBENF_KILLFOCUS;
COMBOEX_Notify (infoPtr, CBEN_ENDEDITA,
(NMHDR *)&cbeend, FALSE);
}
/* fall through */
case WM_CHAR:
case WM_ERASEBKGND:
/* The above messages need code - will be delivered later */
default:
return CallWindowProcA (infoPtr->prevEditWndProc,
hwnd, uMsg, wParam, lParam);
......@@ -1288,6 +1702,10 @@ static LRESULT WINAPI
COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
COMBOEX_INFO *infoPtr = (COMBOEX_INFO *)GetPropA (hwnd, (LPCSTR)(LONG) ComboExInfo);
NMMOUSE nmmse;
COLORREF nbkc, obkc;
HDC hDC;
RECT rect;
TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx, info_ptr=%p\n",
hwnd, uMsg, wParam, lParam, infoPtr);
......@@ -1296,6 +1714,50 @@ COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
switch (uMsg)
{
case CB_FINDSTRINGEXACT:
return COMBOEX_FindStringExact (infoPtr, wParam, lParam);
case WM_DRAWITEM:
/*
* The only way this message should come is from the
* child Listbox issuing the message. Flag this so
* that ComboEx knows this is listbox.
*/
((DRAWITEMSTRUCT *)lParam)->itemState |= ODS_COMBOEXLBOX;
return CallWindowProcA (infoPtr->prevComboWndProc,
hwnd, uMsg, wParam, lParam);
case WM_ERASEBKGND:
/*
* The following was determined by traces of the native
*/
hDC = (HDC) wParam;
nbkc = GetSysColor (COLOR_WINDOW);
obkc = SetBkColor (hDC, nbkc);
GetClientRect (hwnd, &rect);
TRACE("erasing (%d,%d)-(%d,%d)\n",
rect.left, rect.top, rect.right, rect.bottom);
ExtTextOutW (hDC, 0, 0, ETO_OPAQUE, &rect, 0, 0, 0);
SetBkColor (hDC, obkc);
return CallWindowProcA (infoPtr->prevComboWndProc,
hwnd, uMsg, wParam, lParam);
case WM_SETCURSOR:
/*
* WM_NOTIFY to comboex parent (rebar)
* with NM_SETCURSOR with extra words of 0,0,0,0,0x02010001
* CallWindowProc (previous)
*/
nmmse.dwItemSpec = 0;
nmmse.dwItemData = 0;
nmmse.pt.x = 0;
nmmse.pt.y = 0;
nmmse.dwHitInfo = lParam;
COMBOEX_Notify (infoPtr, NM_SETCURSOR, (NMHDR *)&nmmse, FALSE);
return CallWindowProcA (infoPtr->prevComboWndProc,
hwnd, uMsg, wParam, lParam);
case WM_COMMAND:
/* traces show that COMBOEX does not issue CBN_EDITUPDATE
* on the EN_UPDATE
......@@ -1306,13 +1768,25 @@ COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
/*
* For EN_SETFOCUS this issues the same calls and messages
* as the native seems to do.
*
* for some cases however native does the following:
* (noticed after SetFocus during LBUTTONDOWN on
* on dropdown arrow)
* WM_GETTEXTLENGTH (Edit);
* WM_GETTEXT (Edit, len+1, str);
* EM_SETSEL (Edit, 0, 0);
* WM_GETTEXTLENGTH (Edit);
* WM_GETTEXT (Edit, len+1, str);
* EM_SETSEL (Edit, 0, len);
* WM_NOTIFY (parent, CBEN_BEGINEDIT)
*/
NMHDR hdr;
SendMessageA (infoPtr->hwndEdit, EM_SETSEL, 0, 0);
SendMessageA (infoPtr->hwndEdit, EM_SETSEL, 0, -1);
COMBOEX_Notify (infoPtr, CBEN_BEGINEDIT, &hdr);
SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, 0);
SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, -1);
COMBOEX_Notify (infoPtr, CBEN_BEGINEDIT, &hdr, FALSE);
infoPtr->flags |= WCBE_ACTEDIT;
infoPtr->flags &= ~WCBE_EDITCHG; /* no change yet */
return 0;
}
......@@ -1321,35 +1795,41 @@ COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
* For EN_CHANGE this issues the same calls and messages
* as the native seems to do.
*/
WCHAR selected_text[260];
WCHAR edit_text[260];
WCHAR *lastwrk;
INT selected, cnt;
CBE_ITEMDATA *item;
selected = SendMessageA (infoPtr->hwndCombo,
selected = SendMessageW (infoPtr->hwndCombo,
CB_GETCURSEL, 0, 0);
/* lstrlenA( lastworkingURL ) */
if (selected == -1)
GetWindowTextW (infoPtr->hwndEdit, selected_text, 260);
GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);
if (selected == -1) {
lastwrk = infoPtr->edit->pszText;
cnt = lstrlenW (lastwrk);
if (cnt >= 259) cnt = 259;
}
else {
item = COMBOEX_FindItem (infoPtr, selected);
cnt = lstrlenW (item->pszText);
lastwrk = item->pszText;
if (cnt >= 259) cnt = 259;
lstrcpynW (selected_text, item->pszText, cnt);
selected_text[cnt+1] = 0;
}
TRACE("handling EN_CHANGE, selected = %d, text=%s\n",
selected, debugstr_w(selected_text));
TRACE("handling EN_CHANGE, selected = %d, selected_text=%s\n",
selected, debugstr_w(lastwrk));
TRACE("handling EN_CHANGE, edittext=%s\n",
debugstr_w(edit_text));
/* lstrcmpiW is between lastworkingURL and GetWindowText */
if (lstrcmpiW (infoPtr->edit->pszText, selected_text)) {
/* strings not equal -- what to do???? */
ERR("strings do not match\n");
if (lstrcmpiW (lastwrk, edit_text)) {
/* strings not equal -- indicate edit has changed */
infoPtr->flags |= WCBE_EDITCHG;
}
SendMessageA ( GetParent(infoPtr->hwndSelf), WM_COMMAND,
SendMessageW ( GetParent(infoPtr->hwndSelf), WM_COMMAND,
MAKEWPARAM(GetDlgCtrlID (infoPtr->hwndSelf),
CBN_EDITCHANGE),
infoPtr->hwndSelf);
......@@ -1358,9 +1838,6 @@ COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
/* fall through */
case WM_ERASEBKGND:
case WM_SETCURSOR:
/* The above messages need code - will be delivered later */
default:
return CallWindowProcA (infoPtr->prevComboWndProc,
hwnd, uMsg, wParam, lParam);
......@@ -1378,7 +1855,8 @@ COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
switch (uMsg)
{
/* case CBEM_DELETEITEM: */
case CBEM_DELETEITEM: /* maps to CB_DELETESTRING */
return COMBOEX_DeleteItem (hwnd, wParam, lParam);
case CBEM_GETCOMBOCONTROL:
return COMBOEX_GetComboControl (hwnd, wParam, lParam);
......@@ -1392,10 +1870,14 @@ COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case CBEM_GETIMAGELIST:
return COMBOEX_GetImageList (hwnd, wParam, lParam);
/* case CBEM_GETITEMA:
case CBEM_GETITEMA:
return COMBOEX_GetItemA (hwnd, wParam, lParam);
case CBEM_GETITEMW:
return COMBOEX_GetItemW (hwnd, wParam, lParam);
case CBEM_GETUNICODEFORMAT:
*/
return COMBOEX_GetUnicodeFormat (hwnd, wParam, lParam);
case CBEM_HASEDITCHANGED:
return COMBOEX_HasEditChanged (hwnd, wParam, lParam);
......@@ -1419,13 +1901,11 @@ COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case CBEM_SETITEMW:
return COMBOEX_SetItemW (hwnd, wParam, lParam);
/* case CBEM_SETUNICODEFORMAT:
*/
case CBEM_SETUNICODEFORMAT:
return COMBOEX_SetUnicodeFormat (hwnd, wParam, lParam);
case CB_DELETESTRING:
case CB_FINDSTRINGEXACT:
case CB_GETCOUNT:
case CB_GETCURSEL:
/* Combo messages we are not sure if we need to process or just forward */
case CB_GETDROPPEDCONTROLRECT:
case CB_GETDROPPEDSTATE:
case CB_GETITEMDATA:
......@@ -1436,14 +1916,26 @@ COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case CB_LIMITTEXT:
case CB_RESETCONTENT:
case CB_SELECTSTRING:
case CB_SETDROPPEDWIDTH: /* used by IE 4 */
case CB_SETEXTENDEDUI: /* used by IE 4 */
case CB_SETITEMDATA:
case CB_SHOWDROPDOWN: /* used by IE 4 */
case WM_SETTEXT:
case WM_GETTEXT:
FIXME("(0x%x 0x%x 0x%lx): possible missing fucntion\n",
uMsg, wParam, lParam);
return COMBOEX_Forward (hwnd, uMsg, wParam, lParam);
/* Combo messages OK to just forward to the regular COMBO */
case CB_GETCOUNT:
case CB_GETCURSEL:
case CB_SETDROPPEDWIDTH:
case CB_SETEXTENDEDUI:
case CB_SHOWDROPDOWN:
return COMBOEX_Forward (hwnd, uMsg, wParam, lParam);
/* Combo messages we need to process specially */
case CB_FINDSTRINGEXACT:
return COMBOEX_FindStringExact (COMBOEX_GetInfoPtr (hwnd),
wParam, lParam);
case CB_SETCURSEL:
return COMBOEX_SetCursel (hwnd, wParam, lParam);
......@@ -1451,15 +1943,22 @@ COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return COMBOEX_SetItemHeight (hwnd, wParam, lParam);
/* Messages passed to parent */
/* Window messages passed to parent */
case WM_COMMAND:
return COMBOEX_Command (hwnd, wParam, lParam);
case WM_NOTIFY:
return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
/* Window messages we need to process */
case WM_CREATE:
return COMBOEX_Create (hwnd, wParam, lParam);
case WM_DELETEITEM:
return COMBOEX_WM_DeleteItem (hwnd, wParam, lParam);
case WM_DRAWITEM:
return COMBOEX_DrawItem (hwnd, wParam, lParam);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment