CDialog :: Create crash for dialog with ActiveX control

I have a module that creates a modeless dialog containing an ActiveX control. This module was part of the MFC EXE application, and creating the dialog worked fine. Recently, I moved the module to the ATL / COM server and copied the dialog resource from EXE to the COM server. When trying to create a dialog box without modeling using CDialog::Create() an error occurs.

I was debugging in CDialog::Create and noticed that it does not work in ::CreateDialogIndirect() , which returns NULL and GetLastError returns 0 . I changed the "No Fail Create" flag to True in the properties of the dialog resource, and I will receive more detailed information about the error. The problem occurs in the DoDataExchange() dialog box inside the DDX_Control macro. This calls CDataExchange::PrepareCtrl() with the management resource identifier as follows:

 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; } 

The function call m_pDlgWnd->GetOleControlSite() not executed for the passed resource identifier. By the way, the resource identifier is the identifier of the control.

Any suggestions on why this works inside an exe and crashes on a COM server?

+4
source share
6 answers

I had exactly the same problem. In my case, the problem was that I did not call AfxEnableControlContainer (). I added a call to it in my application's InitInstance function and fixed the problem.

+3
source

We had a similar problem just the other day. Copied the control from one dialog resource to another. As it happened, you cannot just copy an ActiveX control from one dialog to another, as you do with other MFC controls. For an ActiveX control, the rc file contains the DLGINIT section. For example, I have a form with an IE WebBrowser control:

 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 

and below in the rc file there is a DLGINIT section:

 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 

Open the source of the rc file and search for the identifier of the control. Find the DLGINIT section and copy it into a new dialog

+1
source

In my case, I put the wrong dialog id when calling

 BOOL Create(UINT nID, CWnd * pWnd); 

Failed to execute DoDataExchange() .

+1
source

Here is another situation where you can get the same warnings about debugging errors (error: without control over data exchange with identifier dlgdata: line 40):

eg. if you create an instance of the CDialogExExample dialog using the virtual function CDialogExExample :: Create (CONTROL_ID, ..), while CONTROL_ID is not constant with IDD_EXAMPLE (enum {IDD = IDD_EXAMPLE};) in the CDialogExExample header file .... then add control is not always.

Here's an inspiring link from msdn !

may be useful to someone :)

PS: this situation may be the same with @Hank Chang's answer

+1
source

In my case, I had an MFC dialog that hosted the UI.Net interface through ActiveX.

After debugging, I found DoModal failed and returned -1, and GetLastError gave 0.

After a day of debugging, this turned out to be a mismatch of the .Net Assemblies version. This causes the creation of an OLE instance to fail.

Excerpt from WinDBG:

(21b0.71cc): CLR exception - code e0434352 (first chance) CoCreateInstance OLE control {EE3C4329-83A8-4DD8-A74C-680AC01AC593} failed.

Result Code: 0x80131040

HRESULT value 0x80131040 value:

The installed assembly manifest definition does not match the assembly reference.

0
source

The solution I found after this exact error was to check the class definition in the header file. Assuming class

Then in the following code

 class CNewDlg : public CMyBaseDlg { DECLARE_DYNAMIC(CNewDlg) public: CNewDlg(CWnd* pParent = NULL); // standard constructor virtual ~CNewDlg(); // Dialog Data enum { IDD = IDD_MYNEWDIALOGID }; 

check the line:

 enum { IDD = IDD_MYNEWDIALOGID }; 

making sure you have the correct id. The error you get may be the result of copying and pasting the code from another header file of the previously created control / dialog without updating this identifier.

This should match the definition of the dialog in your .rc file. For instance:

 IDD_MYNEWDIALOGID DIALOGEX 0, 0, 445, 314 
0
source

Source: https://habr.com/ru/post/1444848/


All Articles