- Fix memory leaks.
- Add support for WM_NOTIFYFORMAT and support both ANSI and UNICODE notify formats. - Fix some drawing issues with COMBOEX_DrawItem.
This commit is contained in:
parent
0d0cc390c3
commit
b2207c7f36
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ComboBoxEx control v2 (mod5)
|
* ComboBoxEx control v2 (mod6)
|
||||||
*
|
*
|
||||||
* Copyright 1998, 1999 Eric Kohl
|
* Copyright 1998, 1999 Eric Kohl
|
||||||
*
|
*
|
||||||
|
@ -68,6 +68,14 @@
|
||||||
* 4. Improve some traces.
|
* 4. Improve some traces.
|
||||||
* 5. Add support for CB_SETITEMDATA sets LPARAM value from item.
|
* 5. Add support for CB_SETITEMDATA sets LPARAM value from item.
|
||||||
*
|
*
|
||||||
|
* mod 6
|
||||||
|
* 1. Add support for WM_NOTIFYFORMAT (both incoming and outgoing) and do
|
||||||
|
* WM_NOTIFY correctly based on results.
|
||||||
|
* 2. Fix memory leaks of text strings in COMBOEX_WM_DELETEITEM.
|
||||||
|
* 3. Add routines to handle special cases of NMCBEENDEDIT and NMCOMBOXEX
|
||||||
|
* so translation to ANSI is done correctly.
|
||||||
|
* 4. Fix some issues with COMBOEX_DrawItem.
|
||||||
|
*
|
||||||
* Test vehicals were the ControlSpy modules (rebar.exe and comboboxex.exe),
|
* Test vehicals were the ControlSpy modules (rebar.exe and comboboxex.exe),
|
||||||
* WinRAR, and IE 4.0.
|
* WinRAR, and IE 4.0.
|
||||||
*
|
*
|
||||||
|
@ -114,7 +122,8 @@ typedef struct
|
||||||
DWORD flags; /* WINE internal flags */
|
DWORD flags; /* WINE internal flags */
|
||||||
HFONT font;
|
HFONT font;
|
||||||
INT nb_items; /* Number of items */
|
INT nb_items; /* Number of items */
|
||||||
BOOL bUnicode; /* ASCII (FALSE) or Unicode (TRUE)? */
|
BOOL bUnicode; /* TRUE if this window is Unicode */
|
||||||
|
BOOL NtfUnicode; /* TRUE if parent wants notify in Unicode */
|
||||||
CBE_ITEMDATA *edit; /* item data for edit item */
|
CBE_ITEMDATA *edit; /* item data for edit item */
|
||||||
CBE_ITEMDATA *items; /* Array of items */
|
CBE_ITEMDATA *items; /* Array of items */
|
||||||
} COMBOEX_INFO;
|
} COMBOEX_INFO;
|
||||||
|
@ -217,13 +226,13 @@ COMBOEX_Forward (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
|
|
||||||
static INT
|
static INT
|
||||||
COMBOEX_Notify (COMBOEX_INFO *infoPtr, INT code, NMHDR *hdr, BOOL doW)
|
COMBOEX_Notify (COMBOEX_INFO *infoPtr, INT code, NMHDR *hdr)
|
||||||
{
|
{
|
||||||
|
|
||||||
hdr->idFrom = GetDlgCtrlID (infoPtr->hwndSelf);
|
hdr->idFrom = GetDlgCtrlID (infoPtr->hwndSelf);
|
||||||
hdr->hwndFrom = infoPtr->hwndSelf;
|
hdr->hwndFrom = infoPtr->hwndSelf;
|
||||||
hdr->code = code;
|
hdr->code = code;
|
||||||
if (doW)
|
if (infoPtr->NtfUnicode)
|
||||||
return SendMessageW (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0,
|
return SendMessageW (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0,
|
||||||
(LPARAM)hdr);
|
(LPARAM)hdr);
|
||||||
else
|
else
|
||||||
|
@ -232,6 +241,67 @@ COMBOEX_Notify (COMBOEX_INFO *infoPtr, INT code, NMHDR *hdr, BOOL doW)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static INT
|
||||||
|
COMBOEX_NotifyItem (COMBOEX_INFO *infoPtr, INT code, NMCOMBOBOXEXW *hdr)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Change the Text item from Unicode to ANSI if necessary for NOTIFY */
|
||||||
|
|
||||||
|
hdr->hdr.idFrom = GetDlgCtrlID (infoPtr->hwndSelf);
|
||||||
|
hdr->hdr.hwndFrom = infoPtr->hwndSelf;
|
||||||
|
hdr->hdr.code = code;
|
||||||
|
if (infoPtr->NtfUnicode)
|
||||||
|
return SendMessageW (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0,
|
||||||
|
(LPARAM)hdr);
|
||||||
|
else {
|
||||||
|
LPWSTR str, ostr = NULL;
|
||||||
|
INT ret, len = 0;
|
||||||
|
|
||||||
|
if (hdr->ceItem.mask & CBEIF_TEXT) {
|
||||||
|
ostr = hdr->ceItem.pszText;
|
||||||
|
str = ostr;
|
||||||
|
if (!str) str = (LPWSTR)L"";
|
||||||
|
len = WideCharToMultiByte (CP_ACP, 0, str, -1, 0, 0, NULL, NULL);
|
||||||
|
if (len > 0) {
|
||||||
|
hdr->ceItem.pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(CHAR));
|
||||||
|
WideCharToMultiByte (CP_ACP, 0, str, -1, (LPSTR)hdr->ceItem.pszText,
|
||||||
|
len, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = SendMessageA (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0,
|
||||||
|
(LPARAM)hdr);
|
||||||
|
if (hdr->ceItem.mask & CBEIF_TEXT) {
|
||||||
|
if (len > 0)
|
||||||
|
COMCTL32_Free (hdr->ceItem.pszText);
|
||||||
|
hdr->ceItem.pszText = ostr;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static INT
|
||||||
|
COMBOEX_NotifyEndEdit (COMBOEX_INFO *infoPtr, NMCBEENDEDITW *hdr, LPWSTR itemText)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Change the Text item from Unicode to ANSI if necessary for NOTIFY */
|
||||||
|
|
||||||
|
hdr->hdr.idFrom = GetDlgCtrlID (infoPtr->hwndSelf);
|
||||||
|
hdr->hdr.hwndFrom = infoPtr->hwndSelf;
|
||||||
|
hdr->hdr.code = (infoPtr->NtfUnicode) ? CBEN_ENDEDITW : CBEN_ENDEDITA;
|
||||||
|
if (infoPtr->NtfUnicode)
|
||||||
|
return SendMessageW (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0,
|
||||||
|
(LPARAM)hdr);
|
||||||
|
else {
|
||||||
|
WideCharToMultiByte (CP_ACP, 0, itemText, -1,
|
||||||
|
(LPSTR)hdr->szText, CBEMAXSTRLEN, NULL, NULL);
|
||||||
|
return SendMessageA (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0,
|
||||||
|
(LPARAM)hdr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
COMBOEX_GetComboFontSize (COMBOEX_INFO *infoPtr, SIZE *size)
|
COMBOEX_GetComboFontSize (COMBOEX_INFO *infoPtr, SIZE *size)
|
||||||
{
|
{
|
||||||
|
@ -529,7 +599,7 @@ COMBOEX_GetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
|
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
|
||||||
|
|
||||||
TRACE("%s hwnd=0x%x stub!\n",
|
TRACE("%s hwnd=0x%x\n",
|
||||||
infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
|
infoPtr->bUnicode ? "TRUE" : "FALSE", hwnd);
|
||||||
|
|
||||||
return infoPtr->bUnicode;
|
return infoPtr->bUnicode;
|
||||||
|
@ -609,6 +679,8 @@ COMBOEX_InsertItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
item->pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
|
item->pszText = (LPWSTR)COMCTL32_Alloc ((len + 1)*sizeof(WCHAR));
|
||||||
strcpyW (item->pszText, str);
|
strcpyW (item->pszText, str);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
item->pszText = NULL;
|
||||||
item->cchTextMax = cit->cchTextMax;
|
item->cchTextMax = cit->cchTextMax;
|
||||||
}
|
}
|
||||||
if (item->mask & CBEIF_IMAGE)
|
if (item->mask & CBEIF_IMAGE)
|
||||||
|
@ -631,7 +703,7 @@ COMBOEX_InsertItemW (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
(WPARAM)cit->iItem, (LPARAM)item);
|
(WPARAM)cit->iItem, (LPARAM)item);
|
||||||
|
|
||||||
COMBOEX_CopyItem (infoPtr, item, &nmcit.ceItem);
|
COMBOEX_CopyItem (infoPtr, item, &nmcit.ceItem);
|
||||||
COMBOEX_Notify (infoPtr, CBEN_INSERTITEM, (NMHDR *)&nmcit, TRUE);
|
COMBOEX_NotifyItem (infoPtr, CBEN_INSERTITEM, &nmcit);
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
|
|
||||||
|
@ -825,12 +897,12 @@ inline static LRESULT
|
||||||
COMBOEX_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
COMBOEX_SetUnicodeFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
|
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
|
||||||
BOOL bTemp;
|
BOOL bTemp = infoPtr->bUnicode;
|
||||||
|
|
||||||
TRACE("%s hwnd=0x%04x stub!\n",
|
TRACE("to %s hwnd=0x%04x, was %s\n",
|
||||||
((BOOL)wParam) ? "TRUE" : "FALSE", hwnd);
|
((BOOL)wParam) ? "TRUE" : "FALSE", hwnd,
|
||||||
|
(bTemp) ? "TRUE" : "FALSE");
|
||||||
|
|
||||||
bTemp = infoPtr->bUnicode;
|
|
||||||
infoPtr->bUnicode = (BOOL)wParam;
|
infoPtr->bUnicode = (BOOL)wParam;
|
||||||
|
|
||||||
return bTemp;
|
return bTemp;
|
||||||
|
@ -1006,6 +1078,7 @@ COMBOEX_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
CBE_ITEMDATA *item;
|
CBE_ITEMDATA *item;
|
||||||
RECT wnrc1, clrc1, cmbwrc;
|
RECT wnrc1, clrc1, cmbwrc;
|
||||||
LONG test;
|
LONG test;
|
||||||
|
INT i;
|
||||||
|
|
||||||
/* allocate memory for info structure */
|
/* allocate memory for info structure */
|
||||||
infoPtr = (COMBOEX_INFO *)COMCTL32_Alloc (sizeof(COMBOEX_INFO));
|
infoPtr = (COMBOEX_INFO *)COMCTL32_Alloc (sizeof(COMBOEX_INFO));
|
||||||
|
@ -1021,6 +1094,17 @@ COMBOEX_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
infoPtr->hwndSelf = hwnd;
|
infoPtr->hwndSelf = hwnd;
|
||||||
infoPtr->selected = -1;
|
infoPtr->selected = -1;
|
||||||
|
|
||||||
|
infoPtr->bUnicode = IsWindowUnicode (hwnd);
|
||||||
|
|
||||||
|
i = SendMessageA(GetParent (hwnd),
|
||||||
|
WM_NOTIFYFORMAT, hwnd, NF_QUERY);
|
||||||
|
if ((i < NFR_ANSI) || (i > NFR_UNICODE)) {
|
||||||
|
ERR("wrong response to WM_NOTIFYFORMAT (%d), assuming ANSI\n",
|
||||||
|
i);
|
||||||
|
i = NFR_ANSI;
|
||||||
|
}
|
||||||
|
infoPtr->NtfUnicode = (i == NFR_UNICODE) ? 1 : 0;
|
||||||
|
|
||||||
SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
|
SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
|
||||||
|
|
||||||
/* create combo box */
|
/* create combo box */
|
||||||
|
@ -1174,7 +1258,7 @@ COMBOEX_Command (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
CBE_ITEMDATA *item = 0;
|
CBE_ITEMDATA *item = 0;
|
||||||
WCHAR wintext[520];
|
WCHAR wintext[520];
|
||||||
INT cursel, n, oldItem;
|
INT cursel, n, oldItem;
|
||||||
NMCBEENDEDITA cbeend;
|
NMCBEENDEDITW cbeend;
|
||||||
DWORD oldflags;
|
DWORD oldflags;
|
||||||
|
|
||||||
TRACE("for command %d\n", command);
|
TRACE("for command %d\n", command);
|
||||||
|
@ -1235,16 +1319,12 @@ COMBOEX_Command (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
|
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
|
||||||
|
|
||||||
if (oldflags & WCBE_ACTEDIT) {
|
if (oldflags & WCBE_ACTEDIT) {
|
||||||
WideCharToMultiByte (CP_ACP, 0, item->pszText, -1,
|
|
||||||
cbeend.szText, sizeof(cbeend.szText),
|
|
||||||
NULL, NULL);
|
|
||||||
cbeend.fChanged = (oldflags & WCBE_EDITCHG);
|
cbeend.fChanged = (oldflags & WCBE_EDITCHG);
|
||||||
cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
|
cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
|
||||||
CB_GETCURSEL, 0, 0);
|
CB_GETCURSEL, 0, 0);
|
||||||
cbeend.iWhy = CBENF_DROPDOWN;
|
cbeend.iWhy = CBENF_DROPDOWN;
|
||||||
|
|
||||||
if (COMBOEX_Notify (infoPtr, CBEN_ENDEDITA,
|
if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, item->pszText)) {
|
||||||
(NMHDR *)&cbeend, FALSE)) {
|
|
||||||
/* abort the change */
|
/* abort the change */
|
||||||
TRACE("Notify requested abort of change\n");
|
TRACE("Notify requested abort of change\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1307,15 +1387,14 @@ COMBOEX_Command (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
SendMessageW (GetParent (hwnd), WM_COMMAND, wParam,
|
SendMessageW (GetParent (hwnd), WM_COMMAND, wParam,
|
||||||
(LPARAM)hwnd);
|
(LPARAM)hwnd);
|
||||||
if (infoPtr->flags & WCBE_ACTEDIT) {
|
if (infoPtr->flags & WCBE_ACTEDIT) {
|
||||||
GetWindowTextA (infoPtr->hwndEdit, cbeend.szText, 260);
|
GetWindowTextW (infoPtr->hwndEdit, wintext, 260);
|
||||||
cbeend.fChanged = (infoPtr->flags & WCBE_EDITCHG);
|
cbeend.fChanged = (infoPtr->flags & WCBE_EDITCHG);
|
||||||
cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
|
cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
|
||||||
CB_GETCURSEL, 0, 0);
|
CB_GETCURSEL, 0, 0);
|
||||||
cbeend.iWhy = CBENF_KILLFOCUS;
|
cbeend.iWhy = CBENF_KILLFOCUS;
|
||||||
|
|
||||||
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
|
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
|
||||||
if (COMBOEX_Notify (infoPtr, CBEN_ENDEDITA,
|
if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, wintext)) {
|
||||||
(NMHDR *)&cbeend, FALSE)) {
|
|
||||||
/* abort the change */
|
/* abort the change */
|
||||||
TRACE("Notify requested abort of change\n");
|
TRACE("Notify requested abort of change\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1382,8 +1461,10 @@ COMBOEX_WM_DeleteItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
infoPtr->nb_items--;
|
infoPtr->nb_items--;
|
||||||
|
|
||||||
COMBOEX_CopyItem (infoPtr, olditem, &nmcit.ceItem);
|
COMBOEX_CopyItem (infoPtr, olditem, &nmcit.ceItem);
|
||||||
COMBOEX_Notify (infoPtr, CBEN_DELETEITEM, (NMHDR *)&nmcit, TRUE);
|
COMBOEX_NotifyItem (infoPtr, CBEN_DELETEITEM, &nmcit);
|
||||||
|
|
||||||
|
if (olditem->pszText)
|
||||||
|
COMCTL32_Free(olditem->pszText);
|
||||||
COMCTL32_Free(olditem);
|
COMCTL32_Free(olditem);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1399,14 +1480,28 @@ COMBOEX_DrawItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
CBE_ITEMDATA *item = 0;
|
CBE_ITEMDATA *item = 0;
|
||||||
SIZE txtsize;
|
SIZE txtsize;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
|
LPWSTR str;
|
||||||
int drawimage, drawstate;
|
int drawimage, drawstate;
|
||||||
UINT xbase;
|
UINT xbase, x, y;
|
||||||
UINT xioff = 0; /* size and spacer of image if any */
|
UINT xioff = 0; /* size and spacer of image if any */
|
||||||
IMAGEINFO iinfo;
|
IMAGEINFO iinfo;
|
||||||
INT len;
|
INT len;
|
||||||
|
COLORREF nbkc, ntxc;
|
||||||
|
|
||||||
if (!IsWindowEnabled(infoPtr->hwndCombo)) return 0;
|
if (!IsWindowEnabled(infoPtr->hwndCombo)) 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);
|
||||||
|
TRACE("itemID=0x%08x itemAction=0x%08x itemState=0x%08x\n",
|
||||||
|
dis->itemID, dis->itemAction, dis->itemState);
|
||||||
|
TRACE("hWnd=0x%04x hDC=0x%04x (%d,%d)-(%d,%d) itemData=0x%08lx\n",
|
||||||
|
dis->hwndItem, dis->hDC, dis->rcItem.left,
|
||||||
|
dis->rcItem.top, dis->rcItem.right, dis->rcItem.bottom,
|
||||||
|
dis->itemData);
|
||||||
|
}
|
||||||
|
|
||||||
/* MSDN says: */
|
/* MSDN says: */
|
||||||
/* "itemID - Specifies the menu item identifier for a menu */
|
/* "itemID - Specifies the menu item identifier for a menu */
|
||||||
/* item or the index of the item in a list box or combo box. */
|
/* item or the index of the item in a list box or combo box. */
|
||||||
|
@ -1458,27 +1553,26 @@ COMBOEX_DrawItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
CHAR str[260];
|
CHAR str[260];
|
||||||
INT wlen, alen;
|
INT wlen, alen;
|
||||||
|
|
||||||
if (!infoPtr->hwndEdit) {
|
|
||||||
ERR("request to draw edit item, but no edit control exists!\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
item = infoPtr->edit;
|
item = infoPtr->edit;
|
||||||
/* free previous text of edit item */
|
|
||||||
if (item->pszText) {
|
if (infoPtr->hwndEdit) {
|
||||||
COMCTL32_Free(item->pszText);
|
|
||||||
item->pszText = 0;
|
/* free previous text of edit item */
|
||||||
item->mask &= ~CBEIF_TEXT;
|
if (item->pszText) {
|
||||||
}
|
COMCTL32_Free(item->pszText);
|
||||||
alen = SendMessageA (infoPtr->hwndEdit, WM_GETTEXT, 260, (LPARAM)&str);
|
item->pszText = 0;
|
||||||
TRACE("edit control hwndEdit=%0x, text len=%d str=<%s>\n",
|
item->mask &= ~CBEIF_TEXT;
|
||||||
infoPtr->hwndEdit, alen, str);
|
}
|
||||||
if (alen > 0) {
|
alen = SendMessageA (infoPtr->hwndEdit, WM_GETTEXT, 260, (LPARAM)&str);
|
||||||
item->mask |= CBEIF_TEXT;
|
TRACE("edit control hwndEdit=%0x, text len=%d str=<%s>\n",
|
||||||
wlen = MultiByteToWideChar (CP_ACP, 0, str, -1, NULL, 0);
|
infoPtr->hwndEdit, alen, str);
|
||||||
if (wlen > 0) {
|
if (alen > 0) {
|
||||||
item->pszText = (LPWSTR)COMCTL32_Alloc ((wlen + 1)*sizeof(WCHAR));
|
item->mask |= CBEIF_TEXT;
|
||||||
MultiByteToWideChar (CP_ACP, 0, str, -1, item->pszText, wlen);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1494,17 +1588,6 @@ COMBOEX_DrawItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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);
|
|
||||||
TRACE("itemID=0x%08x itemAction=0x%08x itemState=0x%08x\n",
|
|
||||||
dis->itemID, dis->itemAction, dis->itemState);
|
|
||||||
TRACE("hWnd=0x%04x hDC=0x%04x (%d,%d)-(%d,%d) itemData=0x%08lx\n",
|
|
||||||
dis->hwndItem, dis->hDC, dis->rcItem.left,
|
|
||||||
dis->rcItem.top, dis->rcItem.right, dis->rcItem.bottom,
|
|
||||||
dis->itemData);
|
|
||||||
}
|
|
||||||
COMBOEX_DumpItem (item);
|
COMBOEX_DumpItem (item);
|
||||||
|
|
||||||
xbase = CBE_STARTOFFSET;
|
xbase = CBE_STARTOFFSET;
|
||||||
|
@ -1589,38 +1672,41 @@ COMBOEX_DrawItem (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
ImageList_Draw (infoPtr->himl, drawimage, dis->hDC,
|
ImageList_Draw (infoPtr->himl, drawimage, dis->hDC,
|
||||||
xbase, dis->rcItem.top, drawstate);
|
xbase, dis->rcItem.top, drawstate);
|
||||||
}
|
}
|
||||||
if ((item->mask & CBEIF_TEXT) && item->pszText) {
|
|
||||||
UINT x, y;
|
|
||||||
COLORREF nbkc, ntxc;
|
|
||||||
|
|
||||||
len = lstrlenW (item->pszText);
|
/* setup pointer to text to be drawn */
|
||||||
GetTextExtentPointW (dis->hDC, item->pszText, len, &txtsize);
|
if ((item->mask & CBEIF_TEXT) && item->pszText)
|
||||||
nbkc = GetSysColor ((dis->itemState & ODS_SELECTED) ?
|
str = item->pszText;
|
||||||
COLOR_HIGHLIGHT : COLOR_WINDOW);
|
else
|
||||||
SetBkColor (dis->hDC, nbkc);
|
str = (LPWSTR) L"";
|
||||||
ntxc = GetSysColor ((dis->itemState & ODS_SELECTED) ?
|
|
||||||
COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT);
|
/* now draw the text */
|
||||||
SetTextColor (dis->hDC, ntxc);
|
len = lstrlenW (str);
|
||||||
x = xbase + xioff;
|
GetTextExtentPointW (dis->hDC, str, len, &txtsize);
|
||||||
y = dis->rcItem.top +
|
nbkc = GetSysColor ((dis->itemState & ODS_SELECTED) ?
|
||||||
(dis->rcItem.bottom - dis->rcItem.top - txtsize.cy) / 2;
|
COLOR_HIGHLIGHT : COLOR_WINDOW);
|
||||||
rect.left = x;
|
SetBkColor (dis->hDC, nbkc);
|
||||||
rect.right = x + txtsize.cx;
|
ntxc = GetSysColor ((dis->itemState & ODS_SELECTED) ?
|
||||||
rect.top = dis->rcItem.top + 1;
|
COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT);
|
||||||
rect.bottom = dis->rcItem.bottom - 1;
|
SetTextColor (dis->hDC, ntxc);
|
||||||
TRACE("drawing item %d text, rect=(%d,%d)-(%d,%d)\n",
|
x = xbase + xioff;
|
||||||
|
y = dis->rcItem.top +
|
||||||
|
(dis->rcItem.bottom - dis->rcItem.top - txtsize.cy) / 2;
|
||||||
|
rect.left = x;
|
||||||
|
rect.right = x + txtsize.cx;
|
||||||
|
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,
|
||||||
|
&rect, str, len, 0);
|
||||||
|
if (dis->itemState & ODS_FOCUS) {
|
||||||
|
rect.top -= 1;
|
||||||
|
rect.bottom += 1;
|
||||||
|
rect.left -= 1;
|
||||||
|
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);
|
dis->itemID, rect.left, rect.top, rect.right, rect.bottom);
|
||||||
ExtTextOutW (dis->hDC, x, y, ETO_OPAQUE | ETO_CLIPPED,
|
DrawFocusRect (dis->hDC, &rect);
|
||||||
&rect, item->pszText, len, 0);
|
|
||||||
if (dis->itemState & ODS_FOCUS) {
|
|
||||||
rect.top -= 1;
|
|
||||||
rect.bottom += 1;
|
|
||||||
rect.left -= 1;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1704,6 +1790,27 @@ COMBOEX_NCCreate (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static LRESULT
|
||||||
|
COMBOEX_NotifyFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
|
||||||
|
INT i;
|
||||||
|
|
||||||
|
if (lParam == NF_REQUERY) {
|
||||||
|
i = SendMessageA(GetParent (hwnd),
|
||||||
|
WM_NOTIFYFORMAT, infoPtr->hwndSelf, NF_QUERY);
|
||||||
|
if ((i < NFR_ANSI) || (i > NFR_UNICODE)) {
|
||||||
|
ERR("wrong response to WM_NOTIFYFORMAT (%d), assuming ANSI\n",
|
||||||
|
i);
|
||||||
|
i = NFR_ANSI;
|
||||||
|
}
|
||||||
|
infoPtr->NtfUnicode = (i == NFR_UNICODE) ? 1 : 0;
|
||||||
|
return (LRESULT)i;
|
||||||
|
}
|
||||||
|
return (LRESULT)((infoPtr->bUnicode) ? NFR_UNICODE : NFR_ANSI);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static LRESULT
|
static LRESULT
|
||||||
COMBOEX_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
COMBOEX_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
@ -1727,12 +1834,10 @@ static LRESULT
|
||||||
COMBOEX_WindowPosChanging (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
COMBOEX_WindowPosChanging (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
|
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
|
||||||
LRESULT ret;
|
|
||||||
RECT cbx_wrect, cbx_crect, cb_wrect;
|
RECT cbx_wrect, cbx_crect, cb_wrect;
|
||||||
UINT width, height;
|
UINT width, height;
|
||||||
WINDOWPOS *wp = (WINDOWPOS *)lParam;
|
WINDOWPOS *wp = (WINDOWPOS *)lParam;
|
||||||
|
|
||||||
ret = DefWindowProcA (hwnd, WM_WINDOWPOSCHANGING, wParam, lParam);
|
|
||||||
GetWindowRect (hwnd, &cbx_wrect);
|
GetWindowRect (hwnd, &cbx_wrect);
|
||||||
GetClientRect (hwnd, &cbx_crect);
|
GetClientRect (hwnd, &cbx_crect);
|
||||||
GetWindowRect (infoPtr->hwndCombo, &cb_wrect);
|
GetWindowRect (infoPtr->hwndCombo, &cb_wrect);
|
||||||
|
@ -1776,7 +1881,8 @@ static LRESULT WINAPI
|
||||||
COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
COMBOEX_INFO *infoPtr = (COMBOEX_INFO *)GetPropA (hwnd, (LPCSTR)(LONG) ComboExInfo);
|
COMBOEX_INFO *infoPtr = (COMBOEX_INFO *)GetPropA (hwnd, (LPCSTR)(LONG) ComboExInfo);
|
||||||
NMCBEENDEDITA cbeend;
|
NMCBEENDEDITW cbeend;
|
||||||
|
WCHAR edit_text[260];
|
||||||
COLORREF nbkc, obkc;
|
COLORREF nbkc, obkc;
|
||||||
HDC hDC;
|
HDC hDC;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
|
@ -1815,7 +1921,6 @@ COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_KEYDOWN: {
|
case WM_KEYDOWN: {
|
||||||
INT oldItem, selected;
|
INT oldItem, selected;
|
||||||
CBE_ITEMDATA *item;
|
CBE_ITEMDATA *item;
|
||||||
WCHAR edit_text[260];
|
|
||||||
|
|
||||||
switch ((INT)wParam)
|
switch ((INT)wParam)
|
||||||
{
|
{
|
||||||
|
@ -1839,7 +1944,7 @@ COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
*/
|
*/
|
||||||
TRACE("special code for VK_ESCAPE\n");
|
TRACE("special code for VK_ESCAPE\n");
|
||||||
|
|
||||||
GetWindowTextA (infoPtr->hwndEdit, cbeend.szText, 260);
|
GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);
|
||||||
|
|
||||||
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
|
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
|
||||||
cbeend.fChanged = FALSE;
|
cbeend.fChanged = FALSE;
|
||||||
|
@ -1847,8 +1952,7 @@ COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
CB_GETCURSEL, 0, 0);
|
CB_GETCURSEL, 0, 0);
|
||||||
cbeend.iWhy = CBENF_ESCAPE;
|
cbeend.iWhy = CBENF_ESCAPE;
|
||||||
|
|
||||||
if (COMBOEX_Notify (infoPtr, CBEN_ENDEDITA,
|
if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) {
|
||||||
(NMHDR *)&cbeend, FALSE)) {
|
|
||||||
/* abort the change */
|
/* abort the change */
|
||||||
TRACE("Notify requested abort of change\n");
|
TRACE("Notify requested abort of change\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1910,12 +2014,7 @@ COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
cbeend.iNewSelection = selected;
|
cbeend.iNewSelection = selected;
|
||||||
cbeend.fChanged = TRUE;
|
cbeend.fChanged = TRUE;
|
||||||
cbeend.iWhy = CBENF_RETURN;
|
cbeend.iWhy = CBENF_RETURN;
|
||||||
WideCharToMultiByte (CP_ACP, 0, edit_text, -1,
|
if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) {
|
||||||
cbeend.szText, sizeof(cbeend.szText),
|
|
||||||
NULL, NULL);
|
|
||||||
|
|
||||||
if (COMBOEX_Notify (infoPtr, CBEN_ENDEDITA,
|
|
||||||
(NMHDR *)&cbeend, FALSE)) {
|
|
||||||
/* abort the change, restore previous */
|
/* abort the change, restore previous */
|
||||||
TRACE("Notify requested abort of change\n");
|
TRACE("Notify requested abort of change\n");
|
||||||
COMBOEX_SetEditText (infoPtr, infoPtr->edit);
|
COMBOEX_SetEditText (infoPtr, infoPtr->edit);
|
||||||
|
@ -1954,13 +2053,14 @@ COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
infoPtr->flags &= ~WCBE_EDITFOCUSED;
|
infoPtr->flags &= ~WCBE_EDITFOCUSED;
|
||||||
if (infoPtr->flags & WCBE_ACTEDIT) {
|
if (infoPtr->flags & WCBE_ACTEDIT) {
|
||||||
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
|
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
|
||||||
|
|
||||||
|
GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);
|
||||||
cbeend.fChanged = FALSE;
|
cbeend.fChanged = FALSE;
|
||||||
cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
|
cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
|
||||||
CB_GETCURSEL, 0, 0);
|
CB_GETCURSEL, 0, 0);
|
||||||
cbeend.iWhy = CBENF_KILLFOCUS;
|
cbeend.iWhy = CBENF_KILLFOCUS;
|
||||||
|
|
||||||
COMBOEX_Notify (infoPtr, CBEN_ENDEDITA,
|
COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text);
|
||||||
(NMHDR *)&cbeend, FALSE);
|
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
|
@ -1976,12 +2076,13 @@ static LRESULT WINAPI
|
||||||
COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
COMBOEX_INFO *infoPtr = (COMBOEX_INFO *)GetPropA (hwnd, (LPCSTR)(LONG) ComboExInfo);
|
COMBOEX_INFO *infoPtr = (COMBOEX_INFO *)GetPropA (hwnd, (LPCSTR)(LONG) ComboExInfo);
|
||||||
NMCBEENDEDITA cbeend;
|
NMCBEENDEDITW cbeend;
|
||||||
NMMOUSE nmmse;
|
NMMOUSE nmmse;
|
||||||
COLORREF nbkc, obkc;
|
COLORREF nbkc, obkc;
|
||||||
HDC hDC;
|
HDC hDC;
|
||||||
HWND focusedhwnd;
|
HWND focusedhwnd;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
|
WCHAR edit_text[260];
|
||||||
|
|
||||||
TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx, info_ptr=%p\n",
|
TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx, info_ptr=%p\n",
|
||||||
hwnd, uMsg, wParam, lParam, infoPtr);
|
hwnd, uMsg, wParam, lParam, infoPtr);
|
||||||
|
@ -2030,7 +2131,7 @@ COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
nmmse.pt.x = 0;
|
nmmse.pt.x = 0;
|
||||||
nmmse.pt.y = 0;
|
nmmse.pt.y = 0;
|
||||||
nmmse.dwHitInfo = lParam;
|
nmmse.dwHitInfo = lParam;
|
||||||
COMBOEX_Notify (infoPtr, NM_SETCURSOR, (NMHDR *)&nmmse, FALSE);
|
COMBOEX_Notify (infoPtr, NM_SETCURSOR, (NMHDR *)&nmmse);
|
||||||
return CallWindowProcA (infoPtr->prevComboWndProc,
|
return CallWindowProcA (infoPtr->prevComboWndProc,
|
||||||
hwnd, uMsg, wParam, lParam);
|
hwnd, uMsg, wParam, lParam);
|
||||||
|
|
||||||
|
@ -2058,15 +2159,14 @@ COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
*/
|
*/
|
||||||
focusedhwnd = GetFocus();
|
focusedhwnd = GetFocus();
|
||||||
if (infoPtr->flags & WCBE_ACTEDIT) {
|
if (infoPtr->flags & WCBE_ACTEDIT) {
|
||||||
GetWindowTextA (infoPtr->hwndEdit, cbeend.szText, 260);
|
GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);
|
||||||
cbeend.fChanged = (infoPtr->flags & WCBE_EDITCHG);
|
cbeend.fChanged = (infoPtr->flags & WCBE_EDITCHG);
|
||||||
cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
|
cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
|
||||||
CB_GETCURSEL, 0, 0);
|
CB_GETCURSEL, 0, 0);
|
||||||
cbeend.iWhy = CBENF_KILLFOCUS;
|
cbeend.iWhy = CBENF_KILLFOCUS;
|
||||||
|
|
||||||
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
|
infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
|
||||||
if (COMBOEX_Notify (infoPtr, CBEN_ENDEDITA,
|
if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) {
|
||||||
(NMHDR *)&cbeend, FALSE)) {
|
|
||||||
/* abort the change */
|
/* abort the change */
|
||||||
TRACE("Notify requested abort of change\n");
|
TRACE("Notify requested abort of change\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2099,7 +2199,7 @@ COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, 0);
|
SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, 0);
|
||||||
SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, -1);
|
SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, -1);
|
||||||
COMBOEX_Notify (infoPtr, CBEN_BEGINEDIT, &hdr, FALSE);
|
COMBOEX_Notify (infoPtr, CBEN_BEGINEDIT, &hdr);
|
||||||
infoPtr->flags |= WCBE_ACTEDIT;
|
infoPtr->flags |= WCBE_ACTEDIT;
|
||||||
infoPtr->flags &= ~WCBE_EDITCHG; /* no change yet */
|
infoPtr->flags &= ~WCBE_EDITCHG; /* no change yet */
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2197,6 +2297,8 @@ COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
static LRESULT WINAPI
|
static LRESULT WINAPI
|
||||||
COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
|
||||||
|
|
||||||
TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx\n", hwnd, uMsg, wParam, lParam);
|
TRACE("hwnd=%x msg=%x wparam=%x lParam=%lx\n", hwnd, uMsg, wParam, lParam);
|
||||||
|
|
||||||
if (!COMBOEX_GetInfoPtr (hwnd)) {
|
if (!COMBOEX_GetInfoPtr (hwnd)) {
|
||||||
|
@ -2307,7 +2409,12 @@ COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
return COMBOEX_Command (hwnd, wParam, lParam);
|
return COMBOEX_Command (hwnd, wParam, lParam);
|
||||||
|
|
||||||
case WM_NOTIFY:
|
case WM_NOTIFY:
|
||||||
return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
|
if (infoPtr->NtfUnicode)
|
||||||
|
return SendMessageW (GetParent (hwnd),
|
||||||
|
uMsg, wParam, lParam);
|
||||||
|
else
|
||||||
|
return SendMessageA (GetParent (hwnd),
|
||||||
|
uMsg, wParam, lParam);
|
||||||
|
|
||||||
|
|
||||||
/* Window messages we need to process */
|
/* Window messages we need to process */
|
||||||
|
@ -2323,6 +2430,9 @@ COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
case WM_MEASUREITEM:
|
case WM_MEASUREITEM:
|
||||||
return COMBOEX_MeasureItem (hwnd, wParam, lParam);
|
return COMBOEX_MeasureItem (hwnd, wParam, lParam);
|
||||||
|
|
||||||
|
case WM_NOTIFYFORMAT:
|
||||||
|
return COMBOEX_NotifyFormat (hwnd, wParam, lParam);
|
||||||
|
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
return COMBOEX_Size (hwnd, wParam, lParam);
|
return COMBOEX_Size (hwnd, wParam, lParam);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue