From d15ed230a82c63e294e73c94e04ef33846c375aa Mon Sep 17 00:00:00 2001 From: "Dimitrie O. Paun" Date: Mon, 4 Feb 2002 18:44:16 +0000 Subject: [PATCH] Complete Listview Unicodification. Simplify the setting of (sub)item text by using common code. --- dlls/comctl32/listview.c | 183 ++++++++++++++++++++++++++++----------- 1 file changed, 134 insertions(+), 49 deletions(-) diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c index d1eaaee570a..d5508ae27b4 100644 --- a/dlls/comctl32/listview.c +++ b/dlls/comctl32/listview.c @@ -48,6 +48,7 @@ DEFAULT_DEBUG_CHANNEL(listview); /* Some definitions for inline edit control */ typedef BOOL (*EditlblCallbackW)(HWND, LPWSTR, DWORD); +typedef BOOL (*EditlblCallbackA)(HWND, LPWSTR, DWORD); typedef struct tagEDITLABEL_ITEM { @@ -167,12 +168,11 @@ typedef struct tagLISTVIEW_INFO */ /* retrieve the number of items in the listview */ #define GETITEMCOUNT(infoPtr) ((infoPtr)->hdpaItems->nItemCount) -#define LVN_GETDISPINFOT(isW) ( (isW) ? LVN_GETDISPINFOW : LVN_GETDISPINFOA ) #define HDM_INSERTITEMT(isW) ( (isW) ? HDM_INSERTITEMW : HDM_INSERTITEMA ) -HWND CreateEditLabelW(LPCWSTR text, DWORD style, INT x, INT y, +HWND CreateEditLabelT(LPCWSTR text, DWORD style, INT x, INT y, INT width, INT height, HWND parent, HINSTANCE hinst, - EditlblCallbackW EditLblCb, DWORD param); + EditlblCallbackW EditLblCb, DWORD param, BOOL isW); /* * forward declarations @@ -214,6 +214,7 @@ static BOOL LISTVIEW_ToggleSelection(HWND, INT); static VOID LISTVIEW_UnsupportedStyles(LONG lStyle); static HWND LISTVIEW_EditLabelT(HWND hwnd, INT nItem, BOOL isW); static BOOL LISTVIEW_EndEditLabelW(HWND hwnd, LPWSTR pszText, DWORD nItem); +static BOOL LISTVIEW_EndEditLabelA(HWND hwnd, LPSTR pszText, DWORD nItem); static LRESULT LISTVIEW_Command(HWND hwnd, WPARAM wParam, LPARAM lParam); static LRESULT LISTVIEW_SortItems(HWND hwnd, PFNLVCOMPARE pfnCompare, LPARAM lParamSort); static LRESULT LISTVIEW_GetStringWidthT(HWND hwnd, LPCWSTR lpszText, BOOL isW); @@ -286,6 +287,29 @@ static inline void textfreeT(LPWSTR wstr, BOOL isW) if (!isW && wstr) HeapFree(GetProcessHeap(), 0, wstr); } +/* + * dest is a pointer to a Unicode string + * src is a pointer to a string (Unicode if isW, ANSI if !isW) + */ +static inline BOOL textsetptrT(LPWSTR *dest, LPWSTR src, BOOL isW) +{ + LPWSTR pszText = textdupTtoW(src, isW); + BOOL bResult = TRUE; + if (*dest == LPSTR_TEXTCALLBACKW) *dest = NULL; + bResult = Str_SetPtrW(dest, pszText); + textfreeT(pszText, isW); + return bResult; +} + +static inline LRESULT CallWindowProcT(WNDPROC proc, HWND hwnd, UINT uMsg, + WPARAM wParam, LPARAM lParam, BOOL isW) +{ + if (isW) + return CallWindowProcW(proc, hwnd, uMsg, wParam, lParam); + else + return CallWindowProcA(proc, hwnd, uMsg, wParam, lParam); +} + static inline BOOL notify(HWND self, INT code, LPNMHDR pnmh) { pnmh->hwndFrom = self; @@ -2374,12 +2398,7 @@ static BOOL LISTVIEW_InitItemT(HWND hwnd, LISTVIEW_ITEM *lpItem, lpItem->pszText = LPSTR_TEXTCALLBACKW; } else - { - LPWSTR pszText = textdupTtoW(lpLVItem->pszText, isW); - if (lpItem->pszText == LPSTR_TEXTCALLBACKW) lpItem->pszText = NULL; - bResult = Str_SetPtrW(&lpItem->pszText, pszText); - textfreeT(pszText, isW); - } + bResult = textsetptrT(&lpItem->pszText, lpLVItem->pszText, isW); } } @@ -2436,12 +2455,7 @@ static BOOL LISTVIEW_InitSubItemT(HWND hwnd, LISTVIEW_SUBITEM *lpSubItem, lpSubItem->pszText = LPSTR_TEXTCALLBACKW; } else - { - LPWSTR pszText = textdupTtoW(lpLVItem->pszText, isW); - if(lpSubItem->pszText == LPSTR_TEXTCALLBACKW) lpSubItem->pszText=NULL; - bResult = Str_SetPtrW(&lpSubItem->pszText, pszText); - textfreeT(pszText, isW); - } + bResult = textsetptrT(&lpSubItem->pszText, lpLVItem->pszText, isW); } } } @@ -4144,12 +4158,13 @@ static LRESULT LISTVIEW_GetEditControl(HWND hwnd) * [I] HWND : window handle * [I] LPSTR : modified text * [I] DWORD : item index + * [I] isW : TRUE if psxText is Unicode, FALSE if it's ANSI * * RETURN: * SUCCESS : TRUE * FAILURE : FALSE */ -static BOOL LISTVIEW_EndEditLabelW(HWND hwnd, LPWSTR pszText, DWORD nItem) +static BOOL LISTVIEW_EndEditLabelT(HWND hwnd, LPWSTR pszText, DWORD nItem, BOOL isW) { LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongW(hwnd, 0); LONG lStyle = GetWindowLongW(hwnd, GWL_STYLE); @@ -4158,13 +4173,16 @@ static BOOL LISTVIEW_EndEditLabelW(HWND hwnd, LPWSTR pszText, DWORD nItem) HDPA hdpaSubItems; LISTVIEW_ITEM lvItemRef; LVITEMW item; - + BOOL bResult = TRUE; + + TRACE("(hwnd=%x, pszText=%s, nItem=%ld, isW=%d)\n", hwnd, debugstr_t(pszText, isW), nItem, isW); + if (!(lStyle & LVS_OWNERDATA)) { - if (NULL == (hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem))) + if (!(hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem))) return FALSE; - if (NULL == (lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0))) + if (!(lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0))) return FALSE; } else @@ -4187,17 +4205,53 @@ static BOOL LISTVIEW_EndEditLabelW(HWND hwnd, LPWSTR pszText, DWORD nItem) dispInfo.item.state = lpItem->state; dispInfo.item.stateMask = 0; dispInfo.item.pszText = pszText; - dispInfo.item.cchTextMax = pszText ? lstrlenW(pszText) : 0; + dispInfo.item.cchTextMax = textlenT(pszText, isW); dispInfo.item.iImage = lpItem->iImage; dispInfo.item.lParam = lpItem->lParam; infoPtr->hwndEdit = 0; /* Do we need to update the Item Text */ - if(dispinfo_notifyT(hwnd, LVN_ENDLABELEDITW, &dispInfo, TRUE)) - if ((lpItem->pszText != LPSTR_TEXTCALLBACKW)&&(!(lStyle & LVS_OWNERDATA))) - Str_SetPtrW(&lpItem->pszText, pszText); + if(dispinfo_notifyT(hwnd, LVN_ENDLABELEDITW, &dispInfo, isW)) + if (lpItem->pszText != LPSTR_TEXTCALLBACKW && !(lStyle & LVS_OWNERDATA)) + bResult = textsetptrT(&lpItem->pszText, pszText, isW); + + return bResult; +} - return TRUE; +/*** + * DESCRIPTION: + * Callback implementation for editlabel control + * + * PARAMETER(S): + * [I] HWND : window handle + * [I] LPSTR : modified text + * [I] DWORD : item index + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static BOOL LISTVIEW_EndEditLabelW(HWND hwnd, LPWSTR pszText, DWORD nItem) +{ + return LISTVIEW_EndEditLabelT(hwnd, pszText, nItem, TRUE); +} + +/*** + * DESCRIPTION: + * Callback implementation for editlabel control + * + * PARAMETER(S): + * [I] HWND : window handle + * [I] LPSTR : modified text + * [I] DWORD : item index + * + * RETURN: + * SUCCESS : TRUE + * FAILURE : FALSE + */ +static BOOL LISTVIEW_EndEditLabelA(HWND hwnd, LPSTR pszText, DWORD nItem) +{ + return LISTVIEW_EndEditLabelT(hwnd, (LPWSTR)pszText, nItem, FALSE); } /*** @@ -4287,13 +4341,10 @@ static HWND LISTVIEW_EditLabelT(HWND hwnd, INT nItem, BOOL isW) if (!LISTVIEW_GetItemRect(hwnd, nItem, &rect)) return 0; - /* FIXME: if !isW, should we create a ASCII edit label instead - * with a ASCII callback which should send ASCII notification msgs??? - */ - if (!(hedit = CreateEditLabelW(szDispText , WS_VISIBLE, - rect.left-2, rect.top-1, 0, - rect.bottom - rect.top+2, - hwnd, hinst, LISTVIEW_EndEditLabelW, nItem))) + if (!(hedit = CreateEditLabelT(szDispText , WS_VISIBLE, + rect.left-2, rect.top-1, 0, rect.bottom - rect.top+2, hwnd, hinst, + isW ? LISTVIEW_EndEditLabelW : (EditlblCallbackW)LISTVIEW_EndEditLabelA, + nItem, isW))) return 0; infoPtr->hwndEdit = hedit; @@ -5117,10 +5168,7 @@ static LRESULT LISTVIEW_GetItemT(HWND hwnd, LPLVITEMW lpLVItem, BOOL internal, B if (dispInfo.item.mask & LVIF_TEXT) { if ((dispInfo.item.mask & LVIF_DI_SETITEM) && *ppszText) - { - if (isW) Str_SetPtrW(ppszText, dispInfo.item.pszText); - else Str_SetPtrA((LPSTR *)ppszText, (LPCSTR)dispInfo.item.pszText); - } + textsetptrT(ppszText, dispInfo.item.pszText, isW); /* If lpLVItem->pszText==dispInfo.item.pszText a copy is unnecessary, but */ /* some apps give a new pointer in ListView_Notify so we can't be sure. */ @@ -9153,14 +9201,17 @@ static LRESULT LISTVIEW_Command(HWND hwnd, WPARAM wParam, LPARAM lParam) * * RETURN: */ -LRESULT CALLBACK EditLblWndProcW(HWND hwnd, UINT uMsg, - WPARAM wParam, LPARAM lParam) +static LRESULT EditLblWndProcT(HWND hwnd, UINT uMsg, + WPARAM wParam, LPARAM lParam, BOOL isW) { LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongW(GetParent(hwnd), 0); EDITLABEL_ITEM *einfo = infoPtr->pedititem; static BOOL bIgnoreKillFocus = FALSE; BOOL cancel = FALSE; + TRACE("(hwnd=%x, uMsg=%x, wParam=%x, lParam=%lx, isW=%d)\n", + hwnd, uMsg, wParam, lParam, isW); + switch (uMsg) { case WM_GETDLGCODE: @@ -9176,7 +9227,7 @@ LRESULT CALLBACK EditLblWndProcW(HWND hwnd, UINT uMsg, SetWindowLongW(hwnd, GWL_WNDPROC, (LONG)editProc); COMCTL32_Free(einfo); infoPtr->pedititem = NULL; - return CallWindowProcW(editProc, hwnd, uMsg, wParam, lParam); + return CallWindowProcT(editProc, hwnd, uMsg, wParam, lParam, isW); } case WM_KEYDOWN: @@ -9189,8 +9240,7 @@ LRESULT CALLBACK EditLblWndProcW(HWND hwnd, UINT uMsg, break; default: - return CallWindowProcW(einfo->EditWndProc, hwnd, - uMsg, wParam, lParam); + return CallWindowProcT(einfo->EditWndProc, hwnd, uMsg, wParam, lParam, isW); } if (einfo->EditLblCb) @@ -9199,12 +9249,15 @@ LRESULT CALLBACK EditLblWndProcW(HWND hwnd, UINT uMsg, if (!cancel) { - int len = 1 + GetWindowTextLengthW(hwnd); + int len = 1 + isW ? GetWindowTextLengthW(hwnd) : GetWindowTextLengthA(hwnd); if (len > 1) { - if ( (buffer = COMCTL32_Alloc(len*sizeof(WCHAR))) ) - GetWindowTextW(hwnd, buffer, len); + if ( (buffer = COMCTL32_Alloc(len*(isW ? sizeof(WCHAR) : sizeof(CHAR)))) ) + { + if (isW) GetWindowTextW(hwnd, buffer, len); + else GetWindowTextA(hwnd, (CHAR*)buffer, len); + } } } /* Processing LVN_ENDLABELEDIT message could kill the focus */ @@ -9222,6 +9275,31 @@ LRESULT CALLBACK EditLblWndProcW(HWND hwnd, UINT uMsg, return TRUE; } +/*** + * DESCRIPTION: + * Subclassed edit control windproc function + * + * PARAMETER(S): + * + * RETURN: + */ +LRESULT CALLBACK EditLblWndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return EditLblWndProcT(hwnd, uMsg, wParam, lParam, TRUE); +} + +/*** + * DESCRIPTION: + * Subclassed edit control windproc function + * + * PARAMETER(S): + * + * RETURN: + */ +LRESULT CALLBACK EditLblWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + return EditLblWndProcT(hwnd, uMsg, wParam, lParam, FALSE); +} /*** * DESCRIPTION: @@ -9231,9 +9309,9 @@ LRESULT CALLBACK EditLblWndProcW(HWND hwnd, UINT uMsg, * * RETURN: */ -HWND CreateEditLabelW(LPCWSTR text, DWORD style, INT x, INT y, +HWND CreateEditLabelT(LPCWSTR text, DWORD style, INT x, INT y, INT width, INT height, HWND parent, HINSTANCE hinst, - EditlblCallbackW EditLblCb, DWORD param) + EditlblCallbackW EditLblCb, DWORD param, BOOL isW) { LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongW(parent, 0); WCHAR editName[5] = { 'E', 'd', 'i', 't', '\0' }; @@ -9243,6 +9321,8 @@ HWND CreateEditLabelW(LPCWSTR text, DWORD style, INT x, INT y, HDC hOldFont=0; TEXTMETRICW textMetric; + TRACE("(text=%s, ..., isW=%d)\n", debugstr_t(text, isW), isW); + if (NULL == (infoPtr->pedititem = COMCTL32_Alloc(sizeof(EDITLABEL_ITEM)))) return 0; @@ -9264,8 +9344,12 @@ HWND CreateEditLabelW(LPCWSTR text, DWORD style, INT x, INT y, SelectObject(hdc, hOldFont); ReleaseDC(parent, hdc); - if (!(hedit = CreateWindowW(editName, text, style, x, y, sz.cx, height, - parent, 0, hinst, 0))) + if (isW) + hedit = CreateWindowW(editName, text, style, x, y, sz.cx, height, parent, 0, hinst, 0); + else + hedit = CreateWindowA("Edit", (LPCSTR)text, style, x, y, sz.cx, height, parent, 0, hinst, 0); + + if (!hedit) { COMCTL32_Free(infoPtr->pedititem); return 0; @@ -9273,8 +9357,9 @@ HWND CreateEditLabelW(LPCWSTR text, DWORD style, INT x, INT y, infoPtr->pedititem->param = param; infoPtr->pedititem->EditLblCb = EditLblCb; - infoPtr->pedititem->EditWndProc = (WNDPROC)SetWindowLongW(hedit, - GWL_WNDPROC, (LONG) EditLblWndProcW); + infoPtr->pedititem->EditWndProc = (WNDPROC) + (isW ? SetWindowLongW(hedit, GWL_WNDPROC, (LONG)EditLblWndProcW) : + SetWindowLongA(hedit, GWL_WNDPROC, (LONG)EditLblWndProcA) ); SendMessageW(hedit, WM_SETFONT, infoPtr->hFont, FALSE);