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

本文关键字:运行 对话框 dll win32 | 更新日期: 2023-09-27 18:18:43

我制作了一个使用对话框录制和播放的 win32 DLL。我正在尝试通过一个函数传递指针来在我的 C# 代码中使用它,这样我就可以保留数据并实际让对话框与另一个函数一起打开,调用 CreateDialog 并为其提供我的 DLGPROC。我希望让 dll 尽可能独立地运行,只保留对数据的引用并告诉它何时打开和关闭。

标题.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*);

记录:

#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#:

    [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();

我很有信心 StartDiag 被正确调用,因为它总是返回 false,这意味着输入函数的主体并且正确计算 if 语句。明显的问题是,这意味着DLL没有像我希望的那样创建对话框。对话框显然在 rc 文件中,应该包含在 dll 中,那么它是如何工作的呢?如何让我的 DLL 实际运行对话框资源?

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

if (CreateDialog(NULL, ...)

你不能在这里通过空并希望成功。 这仅适用于简单的单模块程序,即只有一个包含所有内容的 EXE 文件的程序。 在您的方案中,Windows 将在托管程序集中搜索资源。 那是一头失败的鲸鱼。 它必须是包含对话框资源的模块的句柄。 当然是DLL。

你需要 DllMain(( 而不是 WinMain((。 存放您获得的手柄,以便以后使用。 样板:

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