2015-07-16 3 views
0

Моя цель - уничтожить объект CListBox после того, как он потеряет фокус. Я добавил следующий код для родительского объекта:Уничтожение CListBox после LBN_KILLFOCUS приводит к исключению

BEGIN_MESSAGE_MAP(CChildView, CWnd) 
    ON_LBN_KILLFOCUS(IDC_LISTBOX, OnLBKillFocus) 
END_MESSAGE_MAP() 

void CChildView::OnLBKillFocus() 
{ 
    listBox->DestroyWindow(); 
} 

Я создал объект вроде этого:

listBox = new CListBox; 
listBox->Create(WS_VISIBLE | WS_CHILD, CRect(10, 110, 100, 200), this, 1112); 

Но после того, как функций OnLBKillFocus казнен я получаю исключение в DefWindowProc. По-видимому, уже уничтоженный ListBox пытается обработать сообщение WM_KILLFOCUS и сбой, потому что дескриптор окна - NULL.

Вот часть трассировки стека:

mfc110ud.dll!CWnd::DefWindowProcW(unsigned int nMsg, unsigned int wParam, long lParam) Line 1141 C++ 
mfc110ud.dll!CWnd::WindowProc(unsigned int message, unsigned int wParam, long lParam) Line 2138 C++ 
mfc110ud.dll!AfxCallWndProc(CWnd * pWnd, HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 290 C++ 
mfc110ud.dll!AfxWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 453 C++ 
mfc110ud.dll!AfxWndProcBase(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 304 C++ 
[email protected]() Unknown 
... 

ли кто-нибудь представление о том, что является причиной этой аварии, и как его можно избежать?

+0

Похоже на синхронизацию последовательности сообщений по мере их обработки. Вы пробовали ** публиковать ** WM_DESTROY в списке из обработчика фокуса с убийством? – rrirower

+0

Я пробовал 'PostMessage (WM_DESTROY)'. Это не имело никакого эффекта. (Нет аварии, но окно осталось). Но, похоже, это работает, если я делаю 'PostMessage (WM_CLOSE)'. Это ожидаемое поведение? – sietschie

+1

@rrirower: Нельзя публиковать WM_DESTROY самостоятельно. Единственный правильный способ уничтожить окно - это использование функции DestroyWindow. – xMRi

ответ

2

Отменить действие, которое должно привести к разрушению и разрушению.

После получения события WM_KILLFOCUS просто используйте PostMessage с личным сообщением (зарегистрированное сообщение окна или WM_APP + n), и после получения этого сообщения уничтожьте это окно.

+0

Есть ли причина не использовать 'PostMessage (WM_CLOSE)'? Софар, похоже, работает. Есть ли недостатки? – sietschie

+0

Я не уверен, что нормальный ребенок будет реагировать на это ... – xMRi

+0

Я не уверен, что вы считаете «нормальным детским контролем». Но этот список исчезает. Конечно, я не уверен, что происходит за шторами, и если это приведет к другим проблемам позже. – sietschie

Смежные вопросы