1

マネージ DLL を WPF アプリケーションで動作させるのに苦労しました。アイデアは、WPF MainWindow のコード ビハインド内から関数を呼び出して (ウィンドウ ハンドルを取得できるようにするため)、それと、wchar_t 型のポインターになる別のポインターを渡すことです。

dll を呼び出すことはできますが、WNDProc は起動しません。アプリケーションのインスタンスまたはハンドルと関係があると思いますが、指を置くことはできません。プロジェクトは正常にビルドされますが、WNDProc は実行されません。

このアプリケーションの考え方は、WPF を使用して c++ を呼び出し、Windows に組み込まれているリモート アシスタンス API を呼び出すサーバー インスタンスを起動することです。

私が持っているものは次のとおりです。

#pragma once

#include "stdafx.h"
#include <winsock2.h>
#include <tchar.h>
#include "RDP.h"

#pragma warning(disable : 4996)
#pragma warning(disable : 4267)
#pragma comment(lib,"ws2_32.lib")

namespace RDPServerSession
{
RAS::SERVER* s = 0;
HWND MainWindow = 0;
HWND hL = 0;
HINSTANCE hAppInstance = 0;
wchar_t* password;

enum
{
    MESSAGE_NOTIFY = WM_USER + 2,
};

public ref class Server
{
public:
    void StartServer(System::IntPtr id, System::IntPtr handle)
    {
        password = reinterpret_cast<wchar_t*>(id.ToPointer());

        WSADATA wData;
        WSAStartup(MAKEWORD(2, 2), &wData);
        CoInitializeEx(0,COINIT_APARTMENTTHREADED);
        /*INITCOMMONCONTROLSEX icex = {0};
        icex.dwICC = ICC_LISTVIEW_CLASSES | ICC_DATE_CLASSES | ICC_WIN95_CLASSES;
        icex.dwSize = sizeof(icex);
        InitCommonControlsEx(&icex);*/
        //InitCommonControls();
        //PrepareDoMatchTable();

        hAppInstance = GetModuleHandle(NULL);

        WNDCLASSEX wClass = {0};
        wClass.cbSize = sizeof(wClass);

        wClass.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_PARENTDC;
        wClass.lpfnWndProc = (WNDPROC)Main_DP;
        wClass.hInstance = hAppInstance;
        wClass.hCursor = LoadCursor(0, IDC_ARROW);
        wClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
        wClass.lpszClassName = _T("CLASS");
        RegisterClassEx(&wClass);

        /*MainWindow = CreateWindowEx(0,
            _T("CLASS"),
            ttitle,
            WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |
            WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT,
            500, 600, 0,LoadMenu(h,_T("MENU_1")), h, 0);*/

        ShowWindow(MainWindow,SW_SHOW);

        MSG msg;

        while(GetMessage(&msg,0,0,0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return;
    }



    static void StartS(HWND hh)
{
if (!s)
    {
    s = new RAS::SERVER;
    int ty = 0,po = 0,col = 16;
    bool dy = 0;

    bool Rev = false;
    if (GetKeyState(VK_CONTROL) >> 15)
        Rev = true;



    s->CreateVirtualChannel(L"test",true,CHANNEL_PRIORITY_MED);
    s->Open();
    s->SetWindowNotification(hh,MESSAGE_NOTIFY);

    vector<int> pids;
    vector<wstring> names;
    vector<int> ST;
    s->GetShareableApplications(pids,names,ST);

    RAS::S_INVITATION* inv = s->Invite(0,password,L"group",3);
    if (inv)
        {
        const wchar_t* password = inv->GetTicket().c_str();
        }

    return;
    }
else
    {
    delete s;
    s = 0;
    }
}

static LRESULT CALLBACK Main_DP(HWND hh,UINT mm,WPARAM ww,LPARAM ll)
{
switch(mm)
    {
    case WM_COMMAND:
        {
        int LW = LOWORD(ww);
        if (LW == 100)
            StartS(hh);
        return 0;
        }

    case WM_CLOSE:
        {
        if (s)
            StartS(hh);
        DestroyWindow(hh);
        return 0;
        }

    case WM_DESTROY:
        {
        PostQuitMessage(0);
        return 0;
        }
    }
return DefWindowProc(hh,mm,ww,ll);
}




    void StopServer() { delete s; }
    ~Server() { }
};

}

Wndproc が実行されない理由について何か考えや提案はありますか?

乾杯。

4

2 に答える 2

1

ウィンドウ プロシージャMain_DPは、ウィンドウ クラスに関連付けられていますCLASS。ただし、そのクラスでウィンドウを作成しない (コードはコメント アウトされている) ため、ウィンドウ プロシージャは使用されません。

アップデート

既存のメイン ウィンドウのメッセージを処理したいが、新しいウィンドウ クラスを既存のウィンドウに関連付けることができない。代わりに、 window をサブクラス化する必要があります。(Ben Voigt が指摘したように、このSetWindowLong手法は使用しないでください。)

ウィンドウをサブクラス化したら、独自のメッセージ ループは必要ありません。WPF コードに戻るだけです。(また、WPF のメッセージ ループを独自のメッセージ ループに確実に置き換えることができない場合があることに注意してください。単純な処理以上のことを行っている可能性がありますTranslateMessage/DispatchMessage。)

于 2012-05-31T19:21:41.730 に答える
0

リソースを使用してフォームを作成し、CreateDialogParam()を使用できます

于 2012-05-31T22:25:36.190 に答える