CDialog :: Создать не удалось для диалога с элементом управления ActiveX

У меня есть модуль, который создает немодальное диалоговое окно, содержащее элемент управления ActiveX. Этот модуль был частью приложения MFC EXE, и создание диалогового окна работало нормально. Недавно я переместил модуль на сервер ATL / COM и скопировал ресурс диалога из EXE-файла на сервер COM. При попытке создать немодальный диалог с помощьюCDialog::Create() происходит ошибка

Я отладил вCDialog::Create и заметил, что он терпит неудачу в::CreateDialogIndirect() который возвращаетсяNULL а такжеGetLastError возвращается0, Я изменилNo Fail Create " Отметьте True в свойствах ресурса диалога, и я получу более подробную информацию об ошибке. Проблема происходит в диалогеDoDataExchange() в пределахDDX_Control макро. Это вызывает вCDataExchange::PrepareCtrl() с контролемИдентификатор ресурса:

HWND CDataExchange::PrepareCtrl(int nIDC)
{
   ASSERT(nIDC != 0);
   ASSERT(nIDC != -1); // not allowed
   HWND hWndCtrl;
   COleControlSite* pSite = NULL;
   m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);
   if (hWndCtrl == NULL)
   {
      // Could be a windowless OCX
      pSite = m_pDlgWnd->GetOleControlSite(nIDC);
      if (pSite == NULL)
      {
         TRACE(traceAppMsg, 0, "Error: no data exchange control with ID 0x%04X.\n", nIDC);
         ASSERT(FALSE);
         AfxThrowNotSupportedException();
      }
   }
   m_idLastControl = nIDC;
   m_bEditLastControl = FALSE; // not an edit item by default

   return hWndCtrl;
}

Вызов функцииm_pDlgWnd->GetOleControlSite() происходит сбой для переданного идентификатора ресурса. Кстати, идентификатор ресурса является контрольнойS ID.

Любые предложения о том, почему это работает внутри EXE и не работает на COM-сервере?

Ответы на вопрос(6)

которое я нашел после этой точной ошибки, состояло в том, чтобы проверить определение класса в заголовочном файле. Предполагая, что класс

Тогда в следующем коде

class CNewDlg : public CMyBaseDlg
{
    DECLARE_DYNAMIC(CNewDlg)
public:
    CNewDlg(CWnd* pParent = NULL);   // standard constructor
    virtual ~CNewDlg();

    // Dialog Data
    enum { IDD = IDD_MYNEWDIALOGID };

проверьте строку:

enum { IDD = IDD_MYNEWDIALOGID };

убедившись, что у вас есть правильный идентификатор. Ошибка, которую вы получаете, может быть результатом копирования и вставки кода из другого заголовочного файла ранее созданного элемента управления / диалога без обновления этого идентификатора.

Это должно соответствовать определению диалога в вашем файле .rc. Например:

IDD_MYNEWDIALOGID DIALOGEX 0, 0, 445, 314
 Michael Haephrati20 апр. 2019 г., 22:39
Я не согласен, но спасибо за ваш комментарий
 IInspectable19 апр. 2019 г., 13:32
Это не может быть проблемой. Как объяснено в ОП, диалогделает создаются (предоставляя соответствующие флаги), поэтомуIDD перечисление верно. Проблема заключается в создании элемента управления ActiveX.
 Michael Haephrati21 апр. 2019 г., 14:52
Я разместил свой ответ на основе опыта. Может быть много причин для ошибки, описанной в OP, и решение, которое я разместил, сработало для меня. Я предлагаю разрешить @ user1756114 комментировать, если мое решение сработало и для него.
 IInspectable21 апр. 2019 г., 08:18
Диалоги в MFC создаются в 2 этапа. MFC сначала создает собственный диалог, передавая в диалогеID ресурса. Когда это удается, он подклассирует собственные элементы управления с экземплярами класса MFC (это 'реализовано вDDX_Control). ОП проверил, что первый шаг выполнен успешно, поэтому они, безусловно, передают правильный идентификатор диалога. Тот факт, что передача неверного идентификатора показывает ту же ошибку, несделать это ответом на вопрос. Это ответ на другой вопрос.

В моем случае при вызове я указал неправильный идентификатор диалога

BOOL Create(UINT nID, CWnd * pWnd);

так провалилсяDoDataExchange()

в котором размещается элемент управления .Net UI через ActiveX.

После отладки я обнаружил, что DoModal потерпел неудачу и вернул -1, а GetLastError дал 0.

После дня отладки это оказалось проблемой несоответствия версий .Net Assemblies. Это приводит к ошибке инстанции управления OLE.

WinDBG выдержка:

(21b0.71cc): исключительная ситуация CLR - код e0434352 (первый шанс) Ошибка CoCreateInstance элемента управления OLE {EE3C4329-83A8-4DD8-A74C-680AC01AC593}.

Код результата: 0x80131040

Значение HRESULT 0x80131040 означает:

Расположенная сборкаОпределение манифеста не соответствует ссылке на сборку.

когда можно получить те же предупреждения об отладочной оценке (ошибка: отсутствует контроль обмена данными с идентификатором dlgdata: строка 40):

например если вы создаете экземпляр диалога CDialogExExample с помощью виртуальной функции CDialogExExample :: Create (CONTROL_ID, ..), а CONTROL_ID не совпадает с IDD_EXAMPLE (enum {IDD = IDD_EXAMPLE};) в заголовочном файле CDialogExExample .... тогда можно добавить контроль не всегда.

Вотвдохновляющая ссылка от msdn!

может быть полезным для кого-то :)

PS: эта ситуация может быть такой же с @Hank Chang 'ответ

одного диалогового ресурса в другой. Как это случилось, вы можетепросто скопируйте элемент управления ActiveX из одного диалога в другой, как это делается с другими элементами управления MFC. Для элемента управления ActiveX rc-файл содержит раздел DLGINIT. Например, у меня есть форма с элементом управления IE WebBrowser:

IDD_ONLINE_REPORTVIEW_FORM DIALOGEX 0, 0, 320, 200
STYLE DS_SETFONT | DS_CONTROL | WS_CHILD
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
    CONTROL         "",IDC_EXPLORER1,"{8856F961-340A-11D0-A96B-00C04FD705A2}",WS_TABSTOP,7,61,299,77
END

и ниже в файле rc есть раздел DLGINIT:

IDD_ONLINE_REPORTVIEW_FORM DLGINIT
BEGIN
    IDC_EXPLORER1, 0x376, 160, 0
0x0000, 0x0000, 0x004c, 0x0000, 0x2e68, 0x0000, 0x0ceb, 0x0000, 0x0000, 
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
0x0000, 0x0000, 0x004c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 
0x0000, 0xd0e0, 0x0057, 0x3573, 0x11cf, 0x69ae, 0x0008, 0x2e2b, 0x6212, 
0x0008, 0x0000, 0x0000, 0x0000, 0x004c, 0x0000, 0x1401, 0x0002, 0x0000, 
0x0000, 0x00c0, 0x0000, 0x0000, 0x4600, 0x0080, 0x0000, 0x0000, 0x0000, 
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
    0
END

Откройте файл rc 's источник и поиск вашего контрольного идентификатора. Найдите раздел DLGINIT и скопируйте его в новый диалог.

ь в том, что я не имелt называется AfxEnableControlContainer (). Я добавил вызов к этому в моем приложении.Функция-член InitInstance, и это решило проблему.

Ваш ответ на вопрос