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

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

Я отладил в CDialog::Create и заметил, что он терпит неудачу в ::CreateDialogIndirect() который возвращается NULL а также GetLastError возвращается 0, Я изменил флаг "Нет создания ошибки" на "Истина" в свойствах ресурса диалога, и я получил более подробную информацию об ошибке. Проблема происходит в диалоге 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() происходит сбой для переданного идентификатора ресурса. Кстати, идентификатор ресурса - это идентификатор элемента управления.

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

5 ответов

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

Была похожая проблема только на днях. Скопировал элемент управления из одного диалогового ресурса в другой. Как это произошло, вы не можете просто скопировать элемент управления 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 и найдите свой контрольный идентификатор. Найдите раздел DLGINIT и скопируйте его в новый диалог.

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

BOOL Create(UINT nID, CWnd * pWnd);

так не удалось на DoDataExchange(),

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

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

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

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

PS: эта ситуация, возможно, такая же, как и с ответом @Hank Chang

В моем случае у меня был диалог MFC, в котором размещается элемент управления.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 означает:

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

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

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

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
Другие вопросы по тегам