Listview Unicodification (part 2)

Dimitrie O. Paun dimi at cs.toronto.edu
Mon Feb 4 00:28:51 CST 2002


(I was away most weekend, I finally managed to test the bits left in my
tree, before I start merging the CW changes)

ChangeLog:
  Complete Listview Unicodification;
  Simplify the setting of (sub)item text by using common code.

Alexandre, let me know if you like the patch better in this format.
For people using Pine with Pico as the editor, I simply did a ^R to read
the fine in. I hope it didn't got mangled in the process, I would
appreciate to hear if it did.

--
Dimi.

Index: dlls/comctl32/listview.c
===================================================================
RCS file: /var/cvs/wine/dlls/comctl32/listview.c,v
retrieving revision 1.113
diff -u -r1.113 listview.c
--- dlls/comctl32/listview.c	2 Feb 2002 17:57:00 -0000	1.113
+++ dlls/comctl32/listview.c	4 Feb 2002 05:11:36 -0000
@@ -48,6 +48,7 @@
 
 /* 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 @@
  */
 /* 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 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 @@
   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 @@
         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 @@
           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 @@
  * [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 @@
   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 @@
   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 @@
   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 @@
   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 @@
  *
  * 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 @@
 	    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 @@
 		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 @@
         
 	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 @@
     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 @@
  *
  * 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 @@
     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 @@
         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 @@
 
     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);
 






More information about the wine-patches mailing list