从 WPF 窗口中的托管 DLL 启动 WNDProc
Launch WNDProc from managed DLL inside WPF Window
我试图让托管 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 不运行的任何想法或建议?
干杯。
窗口过程Main_DP
与窗口类CLASS
相关联。 但是您不会使用该类创建窗口(代码被注释掉),因此不使用窗口过程。
更新
您希望处理现有主窗口的消息,但不能将新窗口类与现有窗口关联。 相反,您需要对窗口进行子类化。 (正如Ben Voigt所指出的,你不应该使用SetWindowLong
技术。
一旦你对窗口进行了子类化,你就不需要自己的消息循环了。 只需返回到 WPF 代码即可。 (请注意,可能无法可靠地将 WPF 的消息循环替换为您自己的消息循环。 它可能不仅仅是一个简单的TranslateMessage/DispatchMessage
。
您可以使用该资源来创建表单并使用 CreateDialogParam()
相关文章:
- 程序无法启动,因为缺少 libmpc-3.dll
- 启动 dll 时 C# 环境堆栈溢出
- 系统错误:程序无法启动,因为您的计算机中缺少MSVCP140D.DLL。尝试重新安装该程序以解决此问题
- 是否有其他方法将.dll文件从一个项目复制到我的启动项目中的可执行文件旁边
- VS:程序无法启动,因为缺少libfftw3-3.dll
- 如何调试在外部C#应用中旋转的C DLL(从调试器无法启动)
- 当使用“空dllmain”的dll加载链接到DLL时,应用程序无法启动(0xc0000142)
- 添加新对话框后,MFC 应用程序启动失败并"DLL Initialization Failed"
- Windows 8上的.exe文件中的MSVCR90.dll错误 - 应用程序无法正确启动(0xc000007b)
- 如何在运行时像可执行文件一样"启动"DLL?
- 无法加载dll libglorycolx2010.dll.该应用程序未能启动,因为其并排配置不正确.Hresult:0x
- 无法启动程序.pocketsphinx.dll缺少错误
- EXE 是否可以调用启动它的 DLL
- visual studio 2010无法启动程序.dll
- 程序无法启动,因为缺少opencv_core2410d.dll
- 如果你链接到一个DLL,如果该DLL丢失,是否可以启动你的可执行文件
- 在 DLL 中启动应用程序
- 从 WPF 窗口中的托管 DLL 启动 WNDProc
- 程序无法启动,因为您的计算机中缺少libgcc_s_dw2-1.dll。简单的控制台
- 本机C++程序在使用 C++/CLI 和 C# 互操作 DLL 启动时崩溃