开发者

Open a dialog box from a DLL

开发者 https://www.devze.com 2022-12-16 19:53 出处:网络
I have a Visual Studio 2008 solution with two projects: a C# Windows Forms application and a C++ DLL. The DLL opens a custom CFileDialog. Here is a toy version that demonstrates the problem, where the

I have a Visual Studio 2008 solution with two projects: a C# Windows Forms application and a C++ DLL. The DLL opens a custom CFileDialog. Here is a toy version that demonstrates the problem, where the C# app is just a button to launch the dialog and a label to show its result:

DialogApp.cs:

...
public partial class Form1 : Form {
    ...
    [DllImport("DialogDll.dll")]
    static extern int OpenDialog();
    ...
    private void button1_Click(object sender, EventArgs e) {
        int r = OpenDialog();
        label1.Text = r.ToString();
    }
}

DialogDll.h:

extern "C" {
    __declspec(dllexport) int __cdecl OpenDialog();
}

DialogDll.cpp:

#include <afxdlgs.h>
#include "DialogDll.h"

extern int __cdecl OpenDialog() {
    CFileDialog d(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("All F开发者_如何学JAVAiles (*.*)|*.*||"), NULL);
    if (d.DoModal() == IFOK) {
        return 4;
    } else {
        return 9;
    }
}

When I run this, I get an error about a debug assertion failing, asking to Abort|Retry|Ignore. The assertion is afxCurrentResourceHandle != NULL. How do I get rid of this problem? If I click Ignore, I get my dialog, and everything appears to work fine.

I've already tried following the instructions here: http://msdn.microsoft.com/en-us/library/7a51wcfx.aspx

These directions say the problem is that a DLL doesn't have a CWinApp object, and I should add AFX_MANAGE_STATE(AfxGetStaticModuleState()) to the beginning of each function call. I did that, and had to resolve a linker issue by following the directions here, manually specifying the entry point for my DLL: http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/0b154e1c-141f-4567-bb24-1ac7c8ee2713/ (The parts about changing the order of the .libs didn't work for me.)

But now I'm getting another error:

LoaderLock was detected:
Attempting managed execution code inside OS Loader Lock. Do not attempt to run
managed code inside a DllMain or image initialization function since doing so
can cause the application to hang.

Good grief! Am I even going in the right direction? I've done years of programming, but I'm pretty new to the Windows platform. I think after all this work, my question is still pretty simple: How do I open a CFileDialog from my dll?


You are probably going in the right direction. I am assuming that you want/need to use MFC in your DLL.

The WinApp and MANAGE_STATE advice was good.

Are you throwing /clr or /clr:pure on any of your C++ source files? Why? Does your C++ DLL mix managed and native code together?

The fix for this trivial app is to not throw /clr. This will make all your C++ code native and ensure that you are not at risk of calling managed static initialisers from the loader lock.

Martyn


Please see comment above, but I would recommend as my answer:

Use System.Windows.Forms.OpenFileDialog instead OR

Use GetOpenFileName

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号