From: Jacob Czekalla jczekalla@codeweavers.com
LButtonDown should return when the treeview handle is invalid (e.g. destroyed) after NM_CLICK to prevent further message processing.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58211 --- dlls/comctl32/tests/treeview.c | 2 +- dlls/comctl32/treeview.c | 33 +++++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/dlls/comctl32/tests/treeview.c b/dlls/comctl32/tests/treeview.c index 1b743a0a23c..d7591b568e9 100644 --- a/dlls/comctl32/tests/treeview.c +++ b/dlls/comctl32/tests/treeview.c @@ -3184,7 +3184,7 @@ static void test_treeview_delete_midclick(void) }
flush_events(); - ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_click_delete_seq, "treeview click and destroy sequence", TRUE); + ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_click_delete_seq, "treeview click and destroy sequence", FALSE);
flush_sequences(sequences, NUM_MSG_SEQUENCES); SetCursorPos(orig_pos.x, orig_pos.y); diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c index 073f62c66a2..11395c97046 100644 --- a/dlls/comctl32/treeview.c +++ b/dlls/comctl32/treeview.c @@ -522,6 +522,18 @@ TREEVIEW_SendRealNotify(const TREEVIEW_INFO *infoPtr, UINT code, NMHDR *hdr) return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, hdr->idFrom, (LPARAM)hdr); }
+static INT +TREEVIEW_SendSafeNotify(const TREEVIEW_INFO *infoPtr, UINT code) +{ + NMHDR hdr; + INT ret = TREEVIEW_SendRealNotify(infoPtr, code, &hdr); + if (ret != 0) + ret = 1; + if (!IsWindow(infoPtr->hwnd)) + ret = -1; + return ret; +} + static BOOL TREEVIEW_SendSimpleNotify(const TREEVIEW_INFO *infoPtr, UINT code) { @@ -4261,6 +4273,7 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam) BOOL do_track, do_select, bDoLabelEdit; HWND hwnd = infoPtr->hwnd; TVHITTESTINFO ht; + INT res;
/* If Edit control is active - kill it and return. * The best way to do it is to set focus to itself. @@ -4315,8 +4328,14 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam) (ht.flags & TVHT_ONITEMLABEL) && (infoPtr->selectedItem == ht.hItem);
/* Send NM_CLICK right away */ - if (!do_track && TREEVIEW_SendSimpleNotify(infoPtr, NM_CLICK)) - goto setfocus; + if (!do_track) + { + res = TREEVIEW_SendSafeNotify(infoPtr, NM_CLICK); + if (res == -1) + return 0; + if (res) + goto setfocus; + }
if (ht.flags & TVHT_ONITEMBUTTON) { @@ -4345,8 +4364,14 @@ TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam) } }
- if (do_track && TREEVIEW_SendSimpleNotify(infoPtr, NM_CLICK)) - goto setfocus; + if (do_track) + { + res = TREEVIEW_SendSafeNotify(infoPtr, NM_CLICK); + if (res == -1) + return 0; + if (res) + goto setfocus; + }
if (TREEVIEW_IsFullRowSelect(infoPtr)) do_select = ht.flags & (TVHT_ONITEMINDENT | TVHT_ONITEMICON | TVHT_ONITEMLABEL | TVHT_ONITEMRIGHT);