У меня проблема в следующем:
Есть приложение написанное на чистом WinAPI.
В нем нужно вызвать диалог из DLL.
DLL написана с использованием MFC и сам обработчик диалога тоже в ней.
Из DLL экспортируется функция:
__declspec( dllexport ) int ShowConfigDialog(const HWND pWndParent)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HINSTANCE hOld = AfxGetResourceHandle();
AfxSetResourceHandle(theApp.m_hInstance);
CConfigDlg dlg();
int iRes = dlg.DoModal();
AfxSetResourceHandle(hOld);
return iRes;
}
Проблема в том, что при вызове функции теряется фокус и исчезает окно из списка приложений, при этом диалоговое окно показыватся, но к нему невозможно получить доступ! Если код функции заменить на:
__declspec( dllexport ) int ShowConfigDialog(const HWND pWndParent)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
AfxMessageBox("Hello word");
return 0;
}
То здесь все нормально — и фокус есть и кнопка "ОК" нажимается!
Например, для вызова диалога, реализованного в самом приложении WinAPI происходит вызовом:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
Что то я совсем запутался
Здравствуйте, Ionov, Вы писали:
I>У меня проблема в следующем:
I>Есть приложение написанное на чистом WinAPI.
I>В нем нужно вызвать диалог из DLL.
I>DLL написана с использованием MFC и сам обработчик диалога тоже в ней.
А ресурс диалога у тебя где? Если в основной проге — то не делай AFX_MANAGE_STATE. Если в DLL, то не делай
HINSTANCE hOld = AfxGetResourceHandle();
AfxSetResourceHandle(theApp.m_hInstance);
Вроде бы так. Попробуй и напиши, что получилось.
Ресурс диалога в самой DLL и обработчик тоже там.
Попробовал как ты посоветовал (двумя) способами — не помогло!
Прошелся под отладчиком в функцию CDialog::DoModal() и в ней выполняется код:
// disable parent (before creating dialog)
HWND hWndParent = PreModal();
AfxUnhookWindowCreate();
BOOL bEnableParent = FALSE;
if (hWndParent && hWndParent != ::GetDesktopWindow() && ::IsWindowEnabled(hWndParent))
{
::EnableWindow(hWndParent, FALSE);
bEnableParent = TRUE;
}
Здравствуйте, Ionov, Вы писали:
I>У меня проблема в следующем:
I>Есть приложение написанное на чистом WinAPI.
I>В нем нужно вызвать диалог из DLL.
I>DLL написана с использованием MFC и сам обработчик диалога тоже в ней.
I>Из DLL экспортируется функция:
Экспортируемая тобой функция не рассчитана на то, что ее будут вызывать из другого кода. В ней присутствуют ссылки на объекты, которые скорее всего не инициализированы, например:
AfxSetResourceHandle(theApp.m_hInstance);
theApp инициализировано? MFC код при загрузке .dll инициализирован? Вполне возможно, что в .dll лежит код, который написал с учетом работы в MFC .exe, где перед вызовом пользовательского когда работает много-много CRT и MFC
Все разобрался
Дело было в стиле окна — он просто добавился со стилем Child из шаблона DIALOGBAR.
Поставил стиль Overlapped и все заработало как надо.
Спасибо за содействие!
Все разобрался
Дело было в стиле окна — он просто добавился со стилем Child из шаблона DIALOGBAR.
Поставил стиль Overlapped и все заработало как надо.
Спасибо за содействие!
Здравствуйте, Ionov, Вы писали:
I>Ресурс диалога в самой DLL и обработчик тоже там.
I>Попробовал как ты посоветовал (двумя) способами — не помогло!
I>Прошелся под отладчиком в функцию CDialog::DoModal() и в ней выполняется код:
I>I>// disable parent (before creating dialog)
I>HWND hWndParent = PreModal();
I>AfxUnhookWindowCreate();
I>BOOL bEnableParent = FALSE;
I>if (hWndParent && hWndParent != ::GetDesktopWindow() && ::IsWindowEnabled(hWndParent))
I>{
I> ::EnableWindow(hWndParent, FALSE);
I> bEnableParent = TRUE;
I>}
I>
На этот код не обращай внимания. Это все правильно. Глупый МФЦ не использует DialogBox и DialogBoxParam для своих модальных диалогов, а эмулируют модальность вот так вот через одно место. Еще раз просмотрел твою функцию, вроде все нормуль. Попробуй не заморачиваться с ResourceHandle , потому как AFX_MANAGE_STATE именно для этого и придумали и оно все сделает как надо. Саму функцию перепиши примерно так:
__declspec( dllexport ) int ShowConfigDialog(const HWND pWndParent)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CConfigDlg dlg(); // Возможно лучше будет dlg(AfxGetMainWnd()), но не обязательно. Попробуй и так и так;
int iRes = dlg.DoModal();
return iRes;
}
А так не знаю даже в чем может быть дело. В InitInstance вызывается CWinApp::InitInstance? DLL обычная или MFC Extention (хотя если есть AFX_MANAGE_STATE, то скорее всего обычная, и это правильно). А до OnInitDialog() диалога управление доходит?
P>А так не знаю даже в чем может быть дело. В InitInstance вызывается CWinApp::InitInstance? DLL обычная или MFC Extention (хотя если есть AFX_MANAGE_STATE, то скорее всего обычная, и это правильно). А до OnInitDialog() диалога управление доходит?
В InitInstance вызывается CWinApp::InitInstance().
DLL обычная.
До OnInitDialog() диалога управление доходит.
Спасибо! Уже разобрался