[3/3] comctl32/listview: Convert forwarded header notifications to ANSI if NFR_ANSI is current format
Nikolay Sivov
bunglehead at gmail.com
Mon Jun 15 17:02:30 CDT 2009
If application expects ansi header notifications it won't recieve them
in current design. Test show that header notify format is always unicode,
so additional internal conversion needed.
http://bugs.winehq.org/show_bug.cgi?id=18949 has a test application shows
this behaviour - expecting 'A' notify code it doesn't block header item resizing.
Bug is closed as malformed, expected to be splitted in separate reports.
Changelog:
- Convert forwarded header notifications to ANSI if NFR_ANSI is current format
>From de14bcdc01f6ed88879b1033a5cd971204cecf6f Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <bunglehead at gmail.com>
Date: Tue, 16 Jun 2009 01:46:11 +0400
Subject: Convert forwarded header notifications to ANSI if NFR_ANSI is current format.
Internally only unicode notifications used.
---
dlls/comctl32/listview.c | 88 +++++++++++++++++++++++++++++++--------
dlls/comctl32/tests/listview.c | 30 +++++++++++++-
2 files changed, 99 insertions(+), 19 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index de98e38..d1d9cde 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -701,10 +701,78 @@ static inline LPCSTR debugscrollcode(int nScrollCode)
/******** Notification functions ************************************/
+static int get_ansi_notification(UINT unicodeNotificationCode)
+{
+ switch (unicodeNotificationCode)
+ {
+ case LVN_BEGINLABELEDITW: return LVN_BEGINLABELEDITA;
+ case LVN_ENDLABELEDITW: return LVN_ENDLABELEDITA;
+ case LVN_GETDISPINFOW: return LVN_GETDISPINFOA;
+ case LVN_SETDISPINFOW: return LVN_SETDISPINFOA;
+ case LVN_ODFINDITEMW: return LVN_ODFINDITEMA;
+ case LVN_GETINFOTIPW: return LVN_GETINFOTIPA;
+ /* header forwards */
+ case HDN_TRACKW: return HDN_TRACKA;
+ case HDN_ENDTRACKW: return HDN_ENDTRACKA;
+ case HDN_BEGINDRAG: return HDN_BEGINDRAG;
+ case HDN_ENDDRAG: return HDN_ENDDRAG;
+ case HDN_ITEMCHANGINGW: return HDN_ITEMCHANGINGA;
+ case HDN_ITEMCHANGEDW: return HDN_ITEMCHANGEDA;
+ case HDN_ITEMCLICKW: return HDN_ITEMCLICKA;
+ case HDN_DIVIDERDBLCLICKW: return HDN_DIVIDERDBLCLICKA;
+ }
+ ERR("unknown notification %x\n", unicodeNotificationCode);
+ assert(FALSE);
+ return 0;
+}
+
+/* forwards header notifications to listview parent */
static LRESULT notify_forward_header(const LISTVIEW_INFO *infoPtr, const NMHEADERW *lpnmh)
{
- return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY,
- (WPARAM)lpnmh->hdr.idFrom, (LPARAM)lpnmh);
+ NMHEADERA nmhA;
+ HDITEMA hditema;
+ HD_TEXTFILTERA textfilter;
+ LPSTR text = NULL, filter = NULL;
+ LRESULT ret;
+
+ /* on unicode format exit earlier */
+ if (infoPtr->notifyFormat == NFR_UNICODE)
+ return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY,
+ (WPARAM)lpnmh->hdr.idFrom, (LPARAM)lpnmh);
+
+ /* header always supplies unicode notifications,
+ all we have to do is to convert strings to ANSI */
+ nmhA = *(NMHEADERA*)lpnmh;
+ if (lpnmh->pitem)
+ {
+ hditema = *(HDITEMA*)lpnmh->pitem;
+ nmhA.pitem = &hditema;
+ /* convert item text */
+ if (lpnmh->pitem->mask & HDI_TEXT)
+ {
+ Str_SetPtrWtoA(&hditema.pszText, lpnmh->pitem->pszText);
+ text = hditema.pszText;
+ }
+ /* convert filter text */
+ if ((lpnmh->pitem->mask & HDI_FILTER) && (lpnmh->pitem->type == HDFT_ISSTRING) &&
+ lpnmh->pitem->pvFilter)
+ {
+ hditema.pvFilter = &textfilter;
+ textfilter = *(HD_TEXTFILTERA*)(lpnmh->pitem->pvFilter);
+ Str_SetPtrWtoA(&textfilter.pszText, ((HD_TEXTFILTERW*)lpnmh->pitem->pvFilter)->pszText);
+ filter = textfilter.pszText;
+ }
+ }
+ nmhA.hdr.code = get_ansi_notification(lpnmh->hdr.code);
+
+ ret = SendMessageW(infoPtr->hwndNotify, WM_NOTIFY,
+ (WPARAM)nmhA.hdr.idFrom, (LPARAM)&nmhA);
+
+ /* cleanup */
+ Free(text);
+ Free(filter);
+
+ return ret;
}
static LRESULT notify_hdr(const LISTVIEW_INFO *infoPtr, INT code, LPNMHDR pnmh)
@@ -804,22 +872,6 @@ static BOOL notify_deleteitem(const LISTVIEW_INFO *infoPtr, INT nItem)
return IsWindow(hwnd);
}
-static int get_ansi_notification(UINT unicodeNotificationCode)
-{
- switch (unicodeNotificationCode)
- {
- case LVN_BEGINLABELEDITW: return LVN_BEGINLABELEDITA;
- case LVN_ENDLABELEDITW: return LVN_ENDLABELEDITA;
- case LVN_GETDISPINFOW: return LVN_GETDISPINFOA;
- case LVN_SETDISPINFOW: return LVN_SETDISPINFOA;
- case LVN_ODFINDITEMW: return LVN_ODFINDITEMA;
- case LVN_GETINFOTIPW: return LVN_GETINFOTIPA;
- }
- ERR("unknown notification %x\n", unicodeNotificationCode);
- assert(FALSE);
- return 0;
-}
-
/*
Send notification. depends on dispinfoW having same
structure as dispinfoA.
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c
index d28fc1b..575d1ab 100644
--- a/dlls/comctl32/tests/listview.c
+++ b/dlls/comctl32/tests/listview.c
@@ -3177,7 +3177,7 @@ static void test_editbox(void)
static void test_notifyformat(void)
{
- HWND hwnd;
+ HWND hwnd, header;
DWORD r;
hwnd = create_listview_control(0);
@@ -3212,8 +3212,12 @@ static void test_notifyformat(void)
notifyFormat = 0;
hwnd = create_listview_control(0);
ok(hwnd != NULL, "failed to create a listview window\n");
+ header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0);
+ ok(IsWindow(header), "expected header to be created\n");
r = SendMessage(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
expect(0, r);
+ r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0);
+ expect(1, r);
r = SendMessage(hwnd, WM_NOTIFYFORMAT, 0, NF_QUERY);
ok(r != 0, "Expected valid format\n");
@@ -3222,12 +3226,16 @@ static void test_notifyformat(void)
expect(NFR_UNICODE, r);
r = SendMessage(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
expect(1, r);
+ r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0);
+ expect(1, r);
notifyFormat = NFR_ANSI;
r = SendMessage(hwnd, WM_NOTIFYFORMAT, 0, NF_REQUERY);
expect(NFR_ANSI, r);
r = SendMessage(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
expect(0, r);
+ r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0);
+ expect(1, r);
DestroyWindow(hwnd);
@@ -3245,36 +3253,56 @@ static void test_notifyformat(void)
notifyFormat = -1;
hwnd = create_listview_controlW(0, hwndparentW);
ok(hwnd != NULL, "failed to create a listview window\n");
+ header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0);
+ ok(IsWindow(header), "expected header to be created\n");
r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
expect(1, r);
+ r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0);
+ expect(1, r);
DestroyWindow(hwnd);
/* recieving error code defaulting to ansi */
notifyFormat = 0;
hwnd = create_listview_controlW(0, hwndparentW);
ok(hwnd != NULL, "failed to create a listview window\n");
+ header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0);
+ ok(IsWindow(header), "expected header to be created\n");
r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
expect(0, r);
+ r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0);
+ expect(1, r);
DestroyWindow(hwnd);
/* recieving ansi code from unicode window, use it */
notifyFormat = NFR_ANSI;
hwnd = create_listview_controlW(0, hwndparentW);
ok(hwnd != NULL, "failed to create a listview window\n");
+ header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0);
+ ok(IsWindow(header), "expected header to be created\n");
r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
expect(0, r);
+ r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0);
+ expect(1, r);
DestroyWindow(hwnd);
/* unicode listview with ansi parent window */
notifyFormat = -1;
hwnd = create_listview_controlW(0, hwndparent);
ok(hwnd != NULL, "failed to create a listview window\n");
+ header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0);
+ ok(IsWindow(header), "expected header to be created\n");
r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
expect(0, r);
+ r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0);
+ expect(1, r);
DestroyWindow(hwnd);
/* unicode listview with ansi parent window, return error code */
notifyFormat = 0;
hwnd = create_listview_controlW(0, hwndparent);
ok(hwnd != NULL, "failed to create a listview window\n");
+ header = (HWND)SendMessage(hwnd, LVM_GETHEADER, 0, 0);
+ ok(IsWindow(header), "expected header to be created\n");
r = SendMessageW(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
expect(0, r);
+ r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0);
+ expect(1, r);
DestroyWindow(hwnd);
DestroyWindow(hwndparentW);
--
1.5.6.5
More information about the wine-patches
mailing list