简体   繁体   English

来自非托管 win32 dll 的 C# 运行对话框

[英]C# run dialog from unmanaged win32 dll

I've made a win32 DLL that records and plays using a dialog box.我制作了一个使用对话框进行记录和播放的 win32 DLL。 I'm trying to use it in my C# code by passing a pointer in through one function so I can keep the data and actually getting the dialog to open with another function the calls CreateDialog and gives it my DLGPROC.我试图在我的 C# 代码中使用它,方法是通过一个函数传递一个指针,这样我就可以保留数据并实际使用另一个函数打开对话框,调用 CreateDialog 并给它我的 DLGPROC。 I'd like to have the dll run as independently as possible, only keeping a reference to the data and telling it when to open and close.我想让 dll 尽可能独立运行,只保留对数据的引用并告诉它何时打开和关闭。

Header.h:标题.h:

#pragma once
#pragma comment(lib, "winmm.lib")

#include <Windows.h>

#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif

EXPORT BOOLEAN StartDiag();
EXPORT BOOLEAN SetData(DOUBLE*);

Record.c:记录.c:

#include <windows.h>
#include "resource.h"
#include "Header.h"

#define INP_BUFFER_SIZE 16384

BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);

TCHAR szAppName[] = TEXT("Record1");
double* pData;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR szCmdLine, int iCmdShow)
{
    return 0;
}

BOOLEAN StartDiag()
{
    if (CreateDialog(NULL, MAKEINTRESOURCE(DLG_RECORD), NULL, DlgProc) == 
        NULL)
    {
        return FALSE;
    }
    return TRUE;
}

BOOLEAN SetData(double* p)
{
    p = pData;
    return TRUE;
}

BOOL CALLBACK DlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   ...
}

C#: C#:

    [DllImport("RecordLib.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
    public static extern Boolean SetData(ref double[] d);
    [DllImport("RecordLib.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
    public static extern Boolean StartDiag();

I am pretty confident StartDiag is getting called correctly because It always returns false, meaning the body of the function is entered and the if statement is evaluated properly.我非常有信心 StartDiag 被正确调用,因为它总是返回 false,这意味着输入了函数体并且正确评估了 if 语句。 The obvious problem is this means the DLL isn't creating a dialog like I want it to.明显的问题是这意味着 DLL 没有像我想要的那样创建对话框。 The Dialog is obviously in an rc file and should be included with the dll, so how does this work? Dialog 显然在一个 rc 文件中,应该包含在 dll 中,那么这是如何工作的呢? How would I get my DLL to actually run the dialog resource?如何让我的 DLL 实际运行对话框资源?

if (CreateDialog(NULL, ...)

You cannot pass NULL here and hope for success.你不能在这里传递 NULL 并希望成功。 That only works in simple single module programs, the kind that has just a single EXE file that contains everything.这只适用于简单的单模块程序,这种程序只有一个包含所有内容的 EXE 文件。 In your scenario, Windows is going to search the managed assembly for the resource.在您的方案中,Windows 将在托管程序集中搜索资源。 That's a fail whale.那是一只失败的鲸鱼。 It has to be the handle of the module that contains the dialog resource.它必须是包含对话框资源的模块的句柄。 Surely the DLL.当然是DLL。

You need DllMain() instead of WinMain().您需要 DllMain() 而不是 WinMain()。 Store the handle you get so you can use it later.存放您获得的手柄,以便以后使用。 Boilerplate:样板:

HMODULE ThisDllHandle;

BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID)
{
    if (reason == DLL_PROCESS_ATTACH) {
        ThisDllHandle = hModule;
        DisableThreadLibraryCalls(hModule);
    }
    return TRUE;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM