Nikolay Sivov : comctl32/listview: Handle EN_KILLFOCUS in WM_COMMAND message handler.
Alexandre Julliard
julliard at winehq.org
Wed Jun 3 09:31:16 CDT 2009
Module: wine
Branch: master
Commit: b13cd52b049cacbb1f1176396049c65fd461c079
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b13cd52b049cacbb1f1176396049c65fd461c079
Author: Nikolay Sivov <bunglehead at gmail.com>
Date: Tue Jun 2 23:47:33 2009 +0400
comctl32/listview: Handle EN_KILLFOCUS in WM_COMMAND message handler.
---
dlls/comctl32/listview.c | 96 ++++++++++++++++++++++++---------------
dlls/comctl32/tests/listview.c | 4 +-
2 files changed, 61 insertions(+), 39 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index 09d8dae..3fe41bd 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -33,7 +33,6 @@
* TODO:
*
* Default Message Processing
- * -- EN_KILLFOCUS should be handled in WM_COMMAND
* -- WM_CREATE: create the icon and small icon image lists at this point only if
* the LVS_SHAREIMAGELISTS style is not specified.
* -- WM_WINDOWPOSCHANGED: arrange the list items if the current view is icon
@@ -412,7 +411,7 @@ static INT LISTVIEW_GetLabelWidth(const LISTVIEW_INFO *, INT);
static void LISTVIEW_GetOrigin(const LISTVIEW_INFO *, LPPOINT);
static BOOL LISTVIEW_GetViewRect(const LISTVIEW_INFO *, LPRECT);
static void LISTVIEW_UpdateSize(LISTVIEW_INFO *);
-static LRESULT LISTVIEW_Command(const LISTVIEW_INFO *, WPARAM, LPARAM);
+static LRESULT LISTVIEW_Command(LISTVIEW_INFO *, WPARAM, LPARAM);
static INT LISTVIEW_GetStringWidthT(const LISTVIEW_INFO *, LPCWSTR, BOOL);
static BOOL LISTVIEW_KeySelection(LISTVIEW_INFO *, INT, BOOL);
static UINT LISTVIEW_GetItemState(const LISTVIEW_INFO *, INT, UINT);
@@ -4920,30 +4919,51 @@ static BOOL LISTVIEW_DeleteItem(LISTVIEW_INFO *infoPtr, INT nItem)
*
* PARAMETER(S):
* [I] infoPtr : valid pointer to the listview structure
- * [I] pszText : modified text
+ * [I] storeText : store edit box text as item text
* [I] isW : TRUE if psxText is Unicode, FALSE if it's ANSI
*
* RETURN:
* SUCCESS : TRUE
* FAILURE : FALSE
*/
-static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, LPWSTR pszText, BOOL isW)
+static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL isW)
{
HWND hwndSelf = infoPtr->hwndSelf;
NMLVDISPINFOW dispInfo;
INT editedItem = infoPtr->nEditLabelItem;
BOOL bSame;
+ WCHAR *pszText = NULL;
+ BOOL res;
+
+ if (storeText)
+ {
+ DWORD len = isW ? GetWindowTextLengthW(infoPtr->hwndEdit) : GetWindowTextLengthA(infoPtr->hwndEdit);
+
+ if (len)
+ {
+ if ((pszText = Alloc((len+1) * (isW ? sizeof(WCHAR) : sizeof(CHAR)))))
+ {
+ if (isW) GetWindowTextW(infoPtr->hwndEdit, pszText, len+1);
+ else GetWindowTextA(infoPtr->hwndEdit, (CHAR*)pszText, len+1);
+ }
+ }
+ }
TRACE("(pszText=%s, isW=%d)\n", debugtext_t(pszText, isW), isW);
infoPtr->nEditLabelItem = -1;
+ infoPtr->hwndEdit = 0;
ZeroMemory(&dispInfo, sizeof(dispInfo));
dispInfo.item.mask = LVIF_PARAM | LVIF_STATE | LVIF_TEXT;
dispInfo.item.iItem = editedItem;
dispInfo.item.iSubItem = 0;
dispInfo.item.stateMask = ~0;
- if (!LISTVIEW_GetItemW(infoPtr, &dispInfo.item)) return FALSE;
+ if (!LISTVIEW_GetItemW(infoPtr, &dispInfo.item))
+ {
+ res = FALSE;
+ goto cleanup;
+ }
if (isW)
bSame = (lstrcmpW(dispInfo.item.pszText, pszText) == 0);
@@ -4953,7 +4973,11 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, LPWSTR pszText, BOOL
bSame = (lstrcmpW(dispInfo.item.pszText, tmp) == 0);
textfreeT(tmp, FALSE);
}
- if (bSame) return TRUE;
+ if (bSame)
+ {
+ res = TRUE;
+ goto cleanup;
+ }
/* add the text from the edit in */
dispInfo.item.mask |= LVIF_TEXT;
@@ -4961,9 +4985,16 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, LPWSTR pszText, BOOL
dispInfo.item.cchTextMax = textlenT(pszText, isW);
/* Do we need to update the Item Text */
- if (!notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW)) return FALSE;
+ if (!notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW))
+ {
+ res = FALSE;
+ goto cleanup;
+ }
if (!IsWindow(hwndSelf))
- return FALSE;
+ {
+ res = FALSE;
+ goto cleanup;
+ }
if (!pszText) return TRUE;
if (!(infoPtr->dwStyle & LVS_OWNERDATA))
@@ -4973,7 +5004,8 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, LPWSTR pszText, BOOL
if (lpItem && lpItem->hdr.pszText == LPSTR_TEXTCALLBACKW)
{
LISTVIEW_InvalidateItem(infoPtr, editedItem);
- return TRUE;
+ res = TRUE;
+ goto cleanup;
}
}
@@ -4983,7 +5015,12 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, LPWSTR pszText, BOOL
dispInfo.item.iSubItem = 0;
dispInfo.item.pszText = pszText;
dispInfo.item.cchTextMax = textlenT(pszText, isW);
- return LISTVIEW_SetItemT(infoPtr, &dispInfo.item, isW);
+ res = LISTVIEW_SetItemT(infoPtr, &dispInfo.item, isW);
+
+cleanup:
+ Free(pszText);
+
+ return res;
}
/***
@@ -10454,7 +10491,7 @@ void LISTVIEW_Unregister(void)
* RETURN:
* Zero.
*/
-static LRESULT LISTVIEW_Command(const LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
{
switch (HIWORD(wParam))
{
@@ -10504,6 +10541,14 @@ static LRESULT LISTVIEW_Command(const LISTVIEW_INFO *infoPtr, WPARAM wParam, LPA
break;
}
+ case EN_KILLFOCUS:
+ {
+ /* handle value will be lost after LISTVIEW_EndEditLabelT */
+ HWND edit = infoPtr->hwndEdit;
+
+ LISTVIEW_EndEditLabelT(infoPtr, TRUE, IsWindowUnicode(infoPtr->hwndEdit));
+ SendMessageW(edit, WM_CLOSE, 0, 0);
+ }
default:
return SendMessageW (infoPtr->hwndNotify, WM_COMMAND, wParam, lParam);
@@ -10530,7 +10575,7 @@ static LRESULT LISTVIEW_Command(const LISTVIEW_INFO *infoPtr, WPARAM wParam, LPA
static LRESULT EditLblWndProcT(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL isW)
{
LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongPtrW(GetParent(hwnd), 0);
- BOOL cancel = FALSE;
+ BOOL save = TRUE;
TRACE("(hwnd=%p, uMsg=%x, wParam=%lx, lParam=%lx, isW=%d)\n",
hwnd, uMsg, wParam, lParam, isW);
@@ -10540,9 +10585,6 @@ static LRESULT EditLblWndProcT(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPara
case WM_GETDLGCODE:
return DLGC_WANTARROWS | DLGC_WANTALLKEYS;
- case WM_KILLFOCUS:
- break;
-
case WM_DESTROY:
{
WNDPROC editProc = infoPtr->EditWndProc;
@@ -10554,7 +10596,7 @@ static LRESULT EditLblWndProcT(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPara
case WM_KEYDOWN:
if (VK_ESCAPE == (INT)wParam)
{
- cancel = TRUE;
+ save = FALSE;
break;
}
else if (VK_RETURN == (INT)wParam)
@@ -10566,27 +10608,7 @@ static LRESULT EditLblWndProcT(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPara
/* kill the edit */
if (infoPtr->hwndEdit)
- {
- LPWSTR buffer = NULL;
-
- infoPtr->hwndEdit = 0;
- if (!cancel)
- {
- DWORD len = isW ? GetWindowTextLengthW(hwnd) : GetWindowTextLengthA(hwnd);
-
- if (len)
- {
- if ( (buffer = Alloc((len+1) * (isW ? sizeof(WCHAR) : sizeof(CHAR)))) )
- {
- if (isW) GetWindowTextW(hwnd, buffer, len+1);
- else GetWindowTextA(hwnd, (CHAR*)buffer, len+1);
- }
- }
- }
- LISTVIEW_EndEditLabelT(infoPtr, buffer, isW);
-
- Free(buffer);
- }
+ LISTVIEW_EndEditLabelT(infoPtr, save, isW);
SendMessageW(hwnd, WM_CLOSE, 0, 0);
return 0;
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c
index 21697c6..d0aa1f3 100644
--- a/dlls/comctl32/tests/listview.c
+++ b/dlls/comctl32/tests/listview.c
@@ -2915,7 +2915,7 @@ static void test_editbox(void)
item.iSubItem = 0;
r = SendMessage(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&item);
expect(strlen(item.pszText), r);
- todo_wine ok(strcmp(buffer, testitem1A) == 0, "Expected item text to change\n");
+ ok(strcmp(buffer, testitem1A) == 0, "Expected item text to change\n");
/* end edit without saving */
r = SendMessage(hwndedit, WM_KEYDOWN, VK_ESCAPE, 0);
expect(0, r);
@@ -2926,7 +2926,7 @@ static void test_editbox(void)
item.iSubItem = 0;
r = SendMessage(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&item);
expect(strlen(item.pszText), r);
- todo_wine ok(strcmp(buffer, testitem1A) == 0, "Expected item text to change\n");
+ ok(strcmp(buffer, testitem1A) == 0, "Expected item text to change\n");
DestroyWindow(hwnd);
}
More information about the wine-cvs
mailing list