5

ActiveX コントロールを含むモードレス ダイアログを作成するモジュールがあります。このモジュールは MFC EXE アプリケーションの一部であり、ダイアログの作成は正常に機能しました。最近、モジュールを ATL/COM サーバーに移動し、ダイアログ リソースを EXE から COM サーバーにコピーしました。モードレス ダイアログを使用して作成しようとするとCDialog::Create()、エラーが発生します。

デバッグして、 which returnsとreturnsCDialog::Createで失敗することに気付きました。ダイアログ リソースのプロパティで "No Fail Create" フラグを True に変更したところ、エラーの詳細が表示されました。この問題は、マクロ内のダイアログで発生します。これは、次のようにコントロールのリソース ID を使用して を呼び出します。::CreateDialogIndirect()NULLGetLastError0DoDataExchange()DDX_ControlCDataExchange::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()渡されたリソース ID に対する関数の呼び出しは失敗します。ちなみに、リソース ID はコントロールの ID です。

これがEXE内で機能し、COMサーバーで失敗する理由について何か提案はありますか?

4

6 に答える 6

4

私はまったく同じ問題を抱えていました。私の場合、AfxEnableControlContainer() を呼び出さなかったことが問題であることが判明しました。アプリの InitInstance メンバー関数にその呼び出しを追加すると、問題が修正されました。

于 2013-04-23T17:55:19.390 に答える
2

つい先日も同様の問題がありました。あるダイアログ リソースから別のダイアログ リソースにコントロールをコピーしました。たまたま、他の MFC コントロールのように ActiveX コントロールをあるダイアログから別のダイアログにコピーすることはできません。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 ファイルのソースを開き、コントロール ID を検索します。DLGINIT セクションを検索し、新しいダイアログにコピーします

于 2012-11-09T00:39:22.027 に答える
1

私の場合、呼び出し中に間違ったダイアログ ID を入力しました

BOOL Create(UINT nID, CWnd * pWnd);

に失敗しましたDoDataExchange()

于 2016-04-25T07:41:30.270 に答える