gpt4 book ai didi

c# - 在 UI 线程中从 c++ 回调到 vb6

转载 作者:行者123 更新时间:2023-11-28 07:06:09 24 4
gpt4 key购买 nike

以下设置:

我有一个 .Net Dll,它有一个名为 LicenceVerifier 的异步方法方法完成时将触发一个事件。

 public class LicenceVerifier
{

private readonly ILicence _licence;
private readonly int _programkey;


public delegate void LicencedCheckedEventHandler(object sender, LicenceVerifierResultArgs args);
public event LicencedCheckedEventHandler LicencedChecked;

public LicenceVerifier(int programKey)
{
_programkey = programKey;
_licence = GetLicensing();
}


public void IsValidLicenceAsync()
{
new Task(() =>
{
LicenceVerifierResult valid = LicenceVerifierResult.NotAvailable;

if (_licence != null)
valid = _licence.IsValid(_programkey);

LicencedChecked(this, new LicenceVerifierResultArgs(valid));

}).Start();


}

在 C++ 方面它看起来是这样的:

void __stdcall CheckLicenseAsyncVb(int iPrgKey, int cbAddress)
{

LicenceVerifierCallback^ callback = gcnew LicenceVerifierCallback();
callback->lCallbackAddress = cbAddress;
callback->callbackType = VB;

//.Net object
LicenceVerifier^ licenceVerifier = gcnew LicenceVerifier(iPrgKey);
licenceVerifier->LicencedChecked += gcnew LicenceVerifier::LicencedCheckedEventHandler(callback, &LicenceVerifierCallback::handler);
licenceVerifier->IsValidLicenceAsync();

}

C++ 端的处理程序:

public ref class LicenceVerifierCallback
{

public:

CallbackType callbackType;

long lCallbackAddress;
void(*callbackFunction)(int);

void handler(System::Object^ sender, LicenceVerifierResultArgs^ e)
{

if(callbackType == VB)
ExecuteCallbackVb(convertResult(e->Result));

if(callbackType == C)
ExecuteCallbackC(callbackFunction, convertResult(e->Result));
};

int convertResult(LicenceVerifierResult verifierResult)
{
if(verifierResult == LicenceVerifierResult::Available)
return 0;

return 1;
}

void ExecuteCallbackVb(int result)
{
typedef void ( *FUNCPTR) (int iResult);

FUNCPTR callBackFunction;

callBackFunction = (FUNCPTR)lCallbackAddress;
callBackFunction(result);
};

vb6:

Private Sub LicenceCheck_Click()
Call CheckLicenseAsyncVb(20110, AddressOf ResultCallback)
End Sub

Public Declare Sub CheckLicenseAsyncVb Lib "LicensingIntfd.dll" Alias "_CheckLicenseAsyncVb@8" (ByVal prgKey As Long, ByVal address As Long)

Public Sub ResultCallback(ByVal result As Long) '
'MsgBox "I'll be never a friend of vb6: " & result
End Sub

我现在遇到了问题,回调将在工作线程而不是 UI 线程中运行,这意味着显示消息框的 vb6 调用将会失败。我可以简单地在回调方法中写入一个变量,然后轮询 UI 线程中的变量以进行更改。不过不太喜欢这个主意。任何人都有一个更简洁的解决方案的想法,可能让 C++ 端执行已经在 UI 线程中的回调(如何?)?

非常感谢任何帮助。

最佳答案

这里是如何使用隐藏的静态窗口将 WM_USER 发送到 UI 线程,将结果传递到 wParam

// VC6
LRESULT CALLBACK RedirectWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

class LicenceVerifierVbCallback
{
LPVOID m_cbAddress;
HWND m_hWnd;
WNDPROC m_pOrigWndProc;

public:
LicenceVerifierVbCallback(LPVOID cbAddress)
{
m_cbAddress = cbAddress;
m_hWnd = CreateWindow("STATIC", NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0);
SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this);
m_pOrigWndProc = (WNDPROC)SetWindowLong(m_hWnd, GWL_WNDPROC, (LONG)RedirectWndProc);
}

~LicenceVerifierVbCallback()
{
DestroyWindow(m_hWnd);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg == WM_USER)
ExecuteCallbackVb((int)wParam);
return DefWindowProc(hwnd, msg, wParam, lParam);
}

void ExecuteCallbackVb(int result)
{
// ToDo: impl
}

void handler(LPVOID sender, LPVOID e)
{
WPARAM wParam = 0; // wParam = convertResult(e->Result)
PostMessage(m_hWnd, WM_USER, wParam, 0);
}
};

LRESULT CALLBACK RedirectWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
LicenceVerifierVbCallback *pthis = (LicenceVerifierVbCallback *)GetWindowLong(hwnd, GWL_USERDATA);
if (pthis != NULL)
return pthis->WndProc(hwnd, msg, wParam, lParam);
return DefWindowProc(hwnd, msg, wParam, lParam);
}

关于c# - 在 UI 线程中从 c++ 回调到 vb6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21723670/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com