MFC 创建带窗口的dll链接库.窗口为非模态窗口

语言:VS2008

代码实现功能:创建一个MFC Regular Dll链接库。要求链接库注入到目标进城后能调出Dll内部的MFC窗口.目标进程为第三方进程程序


步骤:

1,创建项目->MFC Dll;

2,在自动生成的项目代码中添加 Dialog对话框资源.

3,为对话框资源添加 窗口类

4,声明一个呼出窗口函数.startmythread.此函数可以导出也可以不导出  导出需要前缀:。此函数用于自己的程序 CreateRemoteThread 中远程线程调用.使用 extern "C" __declspec(dllexpot) ;

5,在startmythread 调用::CreateThread()函数创建线程.此线程实现函数thr内部为创建窗口和消息循环的代码.

6.创建非模态窗口   void ShowTreeDlg()
{
//=(HWND)329282;
//HWND hMainWnd=FindWindowA("#32770","CheckMyDriver");//通过遍历窗口方式获取目标进程主窗口句柄
HWND hMainWnd=GetHwndByProcessId(GetCurrentProcessId());//通过进程获取目标主窗口进程.注意:GetCurrentProcessId为目标进程Pid
if(hMainWnd!=0)
{
char a[10]={0};

itoa((ULONG)hMainWnd,a,10);

// MessageBoxA(NULL,(LPSTR)a,"",0);

}
else
{
//MessageBoxA(NULL,"调用失败","",0);
return;
}

AFX_MANAGE_STATE(AfxGetStaticModuleState());//这句必不可少

cDlg=new CMDlg;
CWnd *pMainWnd=CWnd::FromHandle(hMainWnd);
ASSERT(pMainWnd);
BOOL retValue=cDlg->Create(IDD_DIALOG1,pMainWnd);
if (!retValue)
{
//MessageBoxA(NULL,"error","1",MB_OKCANCEL);
}
cDlg->ShowWindow(SW_SHOW);



}

7,线程函数thr实现

thr()

{

ShowTreeDlg();

MSG msg;//消息循环  如果dll宿主程序为自己调用的程序 消息循环可以不需要 如果宿主程序为第三方进程 如果没有消息循环 调用后窗口会闪退.
while (GetMessage(&msg, NULL, 0, 0))

TranslateMessage(&msg); 
DispatchMessage(&msg); 
}

}

8,当自己的程序远程注入dll后 需要通过startmythread远程call此函数加载窗口.所以需要把startmythread函数地址传给自己的程序

传入方法:使用::PostMeaage(hwnd,message,w,l).hwnd可以通过Findwindow获取 ..message消息类型需要自己定义.WM_USER 以上的消息值.

为什么不使用SendMessage?本人exe程序和dll程序会卡死.

9 把8里面的实现代码放到CMyApp::InitInstance()内部.自己exe程序就会接收到startmythread函数地址.然后通过CreateReMoteThread调用之.


注意的问题:

1,为什么创建窗口要放在线程里.因不放在线程里后面的消息循环会把dll卡死.从而整个进程无响应.

2,为什么不把startmythead直接放在InitInstatce调用.因为在其内部创建线程dll同样会卡死.


看似一个简单的dll窗口调用 花了两天时间才搞定.新手伤不起.



你可能感兴趣的:(VS设置那些事)