设置如下:

我有一个.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


我现在遇到了问题,回调将在workerthread中而不是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/

10-09 05:25