user32/edit: Check for control destruction on notification return.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
Nikolay Sivov 2022-11-06 18:07:38 +03:00 committed by Alexandre Julliard
parent fed0c33fe0
commit b40ddf4237

View file

@ -141,15 +141,13 @@ typedef struct
#define SWAP_UINT32(x,y) do { UINT temp = (UINT)(x); (x) = (UINT)(y); (y) = temp; } while(0)
#define ORDER_UINT(x,y) do { if ((UINT)(y) < (UINT)(x)) SWAP_UINT32((x),(y)); } while(0)
/* used for disabled or read-only edit control */
#define EDIT_NOTIFY_PARENT(es, wNotifyCode) \
do \
{ /* Notify parent which has created this edit control */ \
TRACE("notification " #wNotifyCode " sent to hwnd=%p\n", es->hwndParent); \
SendMessageW(es->hwndParent, WM_COMMAND, \
MAKEWPARAM(GetWindowLongPtrW((es->hwndSelf),GWLP_ID), wNotifyCode), \
(LPARAM)(es->hwndSelf)); \
} while(0)
static inline BOOL notify_parent(const EDITSTATE *es, INT code)
{
HWND hwnd = es->hwndSelf;
TRACE("notification %d sent to %p.\n", code, es->hwndParent);
SendMessageW(es->hwndParent, WM_COMMAND, MAKEWPARAM(GetWindowLongPtrW(es->hwndSelf, GWLP_ID), code), (LPARAM)es->hwndSelf);
return IsWindow(hwnd);
}
static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap);
@ -1364,7 +1362,7 @@ static BOOL EDIT_MakeFit(EDITSTATE *es, UINT size)
if (es->buffer_size < size) {
WARN("FAILED ! We now have %d+1\n", es->buffer_size);
EDIT_NOTIFY_PARENT(es, EN_ERRSPACE);
notify_parent(es, EN_ERRSPACE);
return FALSE;
} else {
TRACE("We now have %d+1\n", es->buffer_size);
@ -1411,7 +1409,7 @@ static void EDIT_UpdateTextRegion(EDITSTATE *es, HRGN hrgn, BOOL bErase)
{
if (es->flags & EF_UPDATE) {
es->flags &= ~EF_UPDATE;
EDIT_NOTIFY_PARENT(es, EN_UPDATE);
if (!notify_parent(es, EN_UPDATE)) return;
}
NtUserInvalidateRgn(es->hwndSelf, hrgn, bErase);
}
@ -1426,7 +1424,7 @@ static void EDIT_UpdateText(EDITSTATE *es, const RECT *rc, BOOL bErase)
{
if (es->flags & EF_UPDATE) {
es->flags &= ~EF_UPDATE;
EDIT_NOTIFY_PARENT(es, EN_UPDATE);
if (!notify_parent(es, EN_UPDATE)) return;
}
NtUserInvalidateRect(es->hwndSelf, rc, bErase);
}
@ -1706,9 +1704,9 @@ static BOOL EDIT_EM_LineScroll_internal(EDITSTATE *es, INT dx, INT dy)
EDIT_UpdateScrollInfo(es);
}
if (dx && !(es->flags & EF_HSCROLL_TRACK))
EDIT_NOTIFY_PARENT(es, EN_HSCROLL);
notify_parent(es, EN_HSCROLL);
if (dy && !(es->flags & EF_VSCROLL_TRACK))
EDIT_NOTIFY_PARENT(es, EN_VSCROLL);
notify_parent(es, EN_VSCROLL);
return TRUE;
}
@ -2567,8 +2565,9 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_r
/* Issue the EN_MAXTEXT notification and continue with replacing text
* so that buffer limit is honored. */
if ((honor_limit) && (size > es->buffer_limit)) {
EDIT_NOTIFY_PARENT(es, EN_MAXTEXT);
if ((honor_limit) && (size > es->buffer_limit))
{
if (!notify_parent(es, EN_MAXTEXT)) return;
/* Buffer limit can be smaller than the actual length of text in combobox */
if (es->buffer_limit < (tl - (e-s)))
strl = 0;
@ -2626,7 +2625,7 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_r
strl = 0;
e = s;
SetRectRgn(hrgn, 0, 0, 0, 0);
EDIT_NOTIFY_PARENT(es, EN_MAXTEXT);
if (!notify_parent(es, EN_MAXTEXT)) return;
}
}
else {
@ -2643,7 +2642,7 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_r
EDIT_CalcLineWidth_SL(es);
}
text_buffer_changed(es);
EDIT_NOTIFY_PARENT(es, EN_MAXTEXT);
if (!notify_parent(es, EN_MAXTEXT)) return;
}
}
@ -2734,7 +2733,7 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_r
if(send_update || (es->flags & EF_UPDATE))
{
es->flags &= ~EF_UPDATE;
EDIT_NOTIFY_PARENT(es, EN_CHANGE);
if (!notify_parent(es, EN_CHANGE)) return;
}
EDIT_InvalidateUniscribeData(es);
}
@ -3044,7 +3043,7 @@ static BOOL EDIT_EM_Undo(EDITSTATE *es)
EDIT_EM_ReplaceSel(es, TRUE, utext, ulength, TRUE, TRUE);
EDIT_EM_SetSel(es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE);
/* send the notification after the selection start and end are set */
EDIT_NOTIFY_PARENT(es, EN_CHANGE);
if (!notify_parent(es, EN_CHANGE)) return TRUE;
EDIT_EM_ScrollCaret(es);
HeapFree(GetProcessHeap(), 0, utext);
@ -3565,7 +3564,7 @@ static LRESULT EDIT_WM_KillFocus(EDITSTATE *es)
DestroyCaret();
if(!(es->style & ES_NOHIDESEL))
EDIT_InvalidateText(es, es->selection_start, es->selection_end);
EDIT_NOTIFY_PARENT(es, EN_KILLFOCUS);
if (!notify_parent(es, EN_KILLFOCUS)) return 0;
/* throw away left over scroll when we lose focus */
es->wheelDeltaRemainder = 0;
return 0;
@ -3808,7 +3807,7 @@ static void EDIT_WM_SetFocus(EDITSTATE *es)
EDIT_SetCaretPos(es, es->selection_end,
es->flags & EF_AFTER_WRAP);
NtUserShowCaret( es->hwndSelf );
EDIT_NOTIFY_PARENT(es, EN_SETFOCUS);
notify_parent(es, EN_SETFOCUS);
}
static DWORD get_font_margins(HDC hdc, const TEXTMETRICW *tm, BOOL unicode)
@ -3948,8 +3947,8 @@ static void EDIT_WM_SetText(EDITSTATE *es, LPCWSTR text, BOOL unicode)
*/
if( !((es->style & ES_MULTILINE) || es->hwndListBox))
{
EDIT_NOTIFY_PARENT(es, EN_UPDATE);
EDIT_NOTIFY_PARENT(es, EN_CHANGE);
if (!notify_parent(es, EN_UPDATE)) return;
if (!notify_parent(es, EN_CHANGE)) return;
}
EDIT_EM_ScrollCaret(es);
EDIT_UpdateScrollInfo(es);
@ -4150,7 +4149,7 @@ static LRESULT EDIT_WM_HScroll(EDITSTATE *es, INT action, INT pos)
if (!dx) {
/* force scroll info update */
EDIT_UpdateScrollInfo(es);
EDIT_NOTIFY_PARENT(es, EN_HSCROLL);
notify_parent(es, EN_HSCROLL);
}
break;
case SB_ENDSCROLL:
@ -4273,7 +4272,7 @@ static LRESULT EDIT_WM_VScroll(EDITSTATE *es, INT action, INT pos)
{
/* force scroll info update */
EDIT_UpdateScrollInfo(es);
EDIT_NOTIFY_PARENT(es, EN_VSCROLL);
notify_parent(es, EN_VSCROLL);
}
break;
case SB_ENDSCROLL: