通过非托管c++;来自c#net内核的dll
我尝试通过pINKEK.</P>订阅通过C++的DLL从C.NET核心到Windows消息事件/消息传递系统。 我遇到的问题 获取进程句柄或创建空窗口(甚至.net都支持这一点) 这两个参数中的任何一个对于获取句柄都是有效的 < >我如何整理C++的代码句柄> HWND < /Cord>类型?code>IntPtr似乎是显而易见的选择,但它不起作用 以下是我用来订阅活动的内容通过非托管c++;来自c#net内核的dll,c#,c++,.net-core,managed,windows-messages,C#,C++,.net Core,Managed,Windows Messages,我尝试通过pINKEK.订阅通过C++的DLL从C.NET核心到Windows消息事件/消息传递系统。 我遇到的问题 获取进程句柄或创建空窗口(甚至.net都支持这一点) 这两个参数中的任何一个对于获取句柄都是有效的 < >我如何整理C++的代码句柄> HWND < /Cord>类型?code>IntPtr似乎是显而易见的选择,但它不起作用 以下是我用来订阅活动的内容 public class MsgSubscribe : IDisposable { private readonly I
public class MsgSubscribe : IDisposable
{
private readonly Importer _importer;
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate Status DMsgSubscribe(uint msgType, uint msgQ, int hwnd, uint msgId);
private static DMsgSubscribe _dMsgSubscribe;
private IntPtr PMsgSubscribe { get; set; }
public bool Available { get; set; }
public MsgSubscribe(Importer importer)
{
_importer = importer;
if (_importer.hCurModule != IntPtr.Zero)
{
PMsgSubscribe = Importer.GetProcAddress(_importer.hCurModule, "MsgSubscribe");
Available = PUlyMsgSubscribe != IntPtr.Zero;
}
}
public Status MsgSubscribe(uint msgType, uint msgQ, int hwnd, uint msgId)
{
Status result = Status.FunctionNotAvailable;
if (Available)
{
_dMsgSubscribe = (DMsgSubscribe)Marshal.GetDelegateForFunctionPointer(PMsgSubscribe, typeof(DMsgSubscribe));
result = _dMsgSubscribe(msgType, msgQ, hwnd, msgId);
}
return result;
}
public void Dispose()
{
}
}
我尝试了IntPtr
和int
进行HWND
编组,两种方法都不起作用。
此外,我也不知道我应该如何捕捉基于窗口消息的事件,如果有什么在线的话,那就很少了
感谢您的帮助。通常,使用IntPtr是正确的
Handle()
返回这样一个IntPtr
看起来你想用你的进程HWND获取窗口消息,因为C++必须使用窗口HWND来获取与HWND相关的消息。
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Constants.Constants;
using Constants.Enums;
using Models.WindowsApiModels;
namespace Dependencies.MessagingHandling
{
public class CustomWindow : IDisposable
{
delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
private const int ErrorClassAlreadyExists = 1410;
public IntPtr Handle { get; private set; }
public List<YourType> Messages { get; set; }
public void Dispose()
{
if (Handle != IntPtr.Zero)
{
Importer.DestroyWindow(Handle);
Handle = IntPtr.Zero;
}
}
public CustomWindow()
{
Messages = new List<YourType>();
var className = "Prototype Messaging Class";
WndProc mWndProcDelegate = CustomWndProc;
// Create WNDCLASS
WNDCLASS windClass = new WNDCLASS
{
lpszClassName = className,
lpfnWndProc = Marshal.GetFunctionPointerForDelegate(mWndProcDelegate)
};
UInt16 classAtom = Importer.RegisterClassW(ref windClass);
int lastError = Marshal.GetLastWin32Error();
if (classAtom == 0 && lastError != ErrorClassAlreadyExists)
{
throw new Exception("Could not register window class");
}
// Create window
Handle = Importer.CreateWindowExW(
0,
className,
"Prototype Messaging Window",
0, 0, 0, 0, 0,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero
);
}
private IntPtr CustomWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
//handle your message here
return Importer.DefWindowProc(hWnd, msg, wParam, lParam);
}
public Task GetMessage()
{
IntPtr handle = Handle;
int bRet;
while ((bRet = Importer.GetMessage(out var msg, Handle, 0, 0)) != 0)
{
switch (bRet)
{
case -1:
Console.WriteLine("Error");
CancellationToken token = new CancellationToken(true);
return Task.FromCanceled(token);
default:
Importer.TranslateMessage(ref msg);
Importer.DispatchMessage(ref msg);
break;
}
}
return Task.FromResult(true);
}
}
}
进口商是自定义类,包含C++编组函数创建/处理窗口,按名称查找它们,因为它们是相同的。所有CAPS类/结构都是windows/c++api结构,可以在官方msdn上找到。
如何在dot net core中获取或创建窗口?@AistisTaraskevicius当您尝试订阅窗口消息时,您应该已经有了一个窗口。或者你可以自己创建一个表单。但是我如何使用.NETCore来创建表单呢。它不支持windows窗体或任何其他基于窗口的gui。@AistisTaraskevicius您需要某种窗口来获取消息。没有窗口没有消息。我意识到没有窗口我无法接收消息。介意发布我如何通过pinvoke创建一个窗口并通过NetCore订阅它的消息吗?using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Constants.Constants;
using Constants.Enums;
using Models.WindowsApiModels;
namespace Dependencies.MessagingHandling
{
public class CustomWindow : IDisposable
{
delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
private const int ErrorClassAlreadyExists = 1410;
public IntPtr Handle { get; private set; }
public List<YourType> Messages { get; set; }
public void Dispose()
{
if (Handle != IntPtr.Zero)
{
Importer.DestroyWindow(Handle);
Handle = IntPtr.Zero;
}
}
public CustomWindow()
{
Messages = new List<YourType>();
var className = "Prototype Messaging Class";
WndProc mWndProcDelegate = CustomWndProc;
// Create WNDCLASS
WNDCLASS windClass = new WNDCLASS
{
lpszClassName = className,
lpfnWndProc = Marshal.GetFunctionPointerForDelegate(mWndProcDelegate)
};
UInt16 classAtom = Importer.RegisterClassW(ref windClass);
int lastError = Marshal.GetLastWin32Error();
if (classAtom == 0 && lastError != ErrorClassAlreadyExists)
{
throw new Exception("Could not register window class");
}
// Create window
Handle = Importer.CreateWindowExW(
0,
className,
"Prototype Messaging Window",
0, 0, 0, 0, 0,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero
);
}
private IntPtr CustomWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
//handle your message here
return Importer.DefWindowProc(hWnd, msg, wParam, lParam);
}
public Task GetMessage()
{
IntPtr handle = Handle;
int bRet;
while ((bRet = Importer.GetMessage(out var msg, Handle, 0, 0)) != 0)
{
switch (bRet)
{
case -1:
Console.WriteLine("Error");
CancellationToken token = new CancellationToken(true);
return Task.FromCanceled(token);
default:
Importer.TranslateMessage(ref msg);
Importer.DispatchMessage(ref msg);
break;
}
}
return Task.FromResult(true);
}
}
}
Task.Run(ShowMenu);
_customWindow.GetMessage();