У меня есть приложение Win32 MFC, составленное с VS2008. Приложение имеет TreeConrtol. Существует обработчик TVN_ITEMCHANGING и внутри обработчика я принудительно перекрашиваю измененный элемент дерева.Не всегда можно поймать SEH на WoW64 на «чистой» Windows 8.1
Вот код с обработчиков SEH и прямой WinAPI вызовов вместо MFC обертками (это не влияет на вопрос):
void CMainDlg::OnTvnItemChangingMainTree(NMHDR *pNMHDR, LRESULT *pResult)
{
NMTVITEMCHANGE *pNMTVItemChange = reinterpret_cast(pNMHDR);
HWND hTreeCtrl = _ctrlTree.GetSafeHwnd();
RECT rect;
__try
{
*(HTREEITEM*) &rect = hItem;
if ((BOOL) ::SendMessage(hTreeCtrl, TVM_GETITEMRECT,
(WPARAM) FALSE, (LPARAM) &rect))
{
::InvalidateRect(hTreeCtrl, &rect, TRUE);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
::MessageBox(NULL, L"SEH exception is Here", L"__except Block", MB_OK);
}
*pResult = 0;
}
Если выбрать элемент в элементе управления Tree (программно или с помощью щелчок мышью), затем после удаления всех элементов из дерева управления (с помощью DeleteAllItems или по одному) я получаю TVN_ITEMCHANGING для элемента, который уже не существует, поэтому код сверху ведет к структурированному сбору исключений, когда вызов :: SendMessage (hTreeCtrl, TVM_GETITEMRECT, ...).
Это нормально, но ... Блок __except никогда не будет выполнен на некоторых Windows 8.1 Pro x64 (и, возможно, на других версиях Windows).
Моя рабочая машина - английский Windows 8.1 Pro x64 (сборка 9600), обновленная из Windows 8. На этой машине все работает нормально (обработчик получает исключение и отображается MessageBox). Однако на чистом английском языке Windows 8.1 Pro x64 (сборка 9600), загруженном из MSDN, блок __except не вызывается, а приложение аварийно завершает работу. Имя модуля неисправности: COMCTL32.dll
Я запускаю тот же .exe-файл на обоих компьютерах. Как вы думаете, почему это может произойти?
Вот рабочий пример. Я скомпилировал его с помощью/EHsc, а затем с/EHa (реальный проект был скомпилирован с помощью/EHa и использовал try/catch).
Код в примере отличается от функции сверху: у меня есть возможность использовать try/catch и _ try/ _except.
Использование/Пьеха Я могу поймать исключение, используя оба пытаются/улова или _ попробовать/ _except на моей рабочей машине, используя/EHsc используя _ попробовать/ _except. Но ни одна из этих комбинаций не работает для другой машины (с чистым Win8.1): она не исключает исключения.
Демо-проект (скомпилирован с Visual Studio 2008 Professional SP1 + MFC): here.
PS: Проблема была временно решена путем добавления условия для вызова SendMessage(), но здесь я хочу изучить проблему с обработкой исключений.
Заранее благодарим за ваши комментарии.
Это * ужасно * практика. Вы не можете больше рассуждать о состоянии своей программы после проглатывания первой. –