FromHandlePermanent всегда возвращает нуль во вставленной DLL
Я пишу программу автоматизации тестирования, которая должна взаимодействовать с элементом управления сеткой в устаревшем приложении MFC. Моя программа должна подключиться к устаревшему приложению и прочитать данные из таблицы.
Я знаю HWND окна, содержащего сетку, и теперь мне нужно найти указатель класса, производный от CWnd, связанный с этим HWND. CWnd::FromHandlePermanent
кажется, мой друг, но да, я знаю, вы не можете позвонить CWnd::FromHandlePermanent
извне приложения, как карта окна AFX (afxMapHWND()
) содержится только в целевом приложении.
Поэтому я внедряю DLL (используя CreateRemoteThread
/LoadLibrary
) в целевое приложение и заставить его звонить FromHandlePermanent
, Но даже этого недостаточно, потому что я не в теме HWND, и afxMapHWND()
смотрит на неправильное локальное хранилище потоков.
Поэтому в моей внедренной DLL я также (временно) подклассаю WndProc HWND (SetWindowLong
и т.д.), затем позвоните SendMessage
, Теперь я нахожусь в правильном потоке (основной поток целевого приложения), и я пытаюсь позвонить CWnd::FromHandlePermanent
с моим HWND, но он возвращает NULL! Если я смотрю на afxMapHWND()->m_permanentMap->m_nCount
мы видим, что это 0. Таким образом, в перманентной карте нет НИКАКИХ прикрепленных классов, что мне кажется неправильным.
Так как я могу получить производный CWnd указатель??
Некоторая другая информация:
- Целевое приложение статически связано с MFC
- Это другая версия MFC, класс окон - AfxWnd70s
- Я использую VS2010 для компиляции внедренной DLL
- Внедренная DLL также статически связывается с библиотеками (VS2010) MFC.
Вот код во вставленной DLL:
// this is how we pass the HWND to the target DLL
// (this shared segment is also loaded in calling app)
#pragma data_seg (".shared")
__declspec(dllexport) HWND g_hWnd = 0;
#pragma data_seg ()
#pragma comment(linker,"/SECTION:.shared,RWS")
BEGIN_MESSAGE_MAP(CLibSpyMFCDllApp, CWinApp)
END_MESSAGE_MAP()
CLibSpyMFCDllApp::CLibSpyMFCDllApp()
{
}
CLibSpyMFCDllApp theApp;
extern CHandleMap* PASCAL afxMapHWND(BOOL bCreate = FALSE);
UINT g_WM_GETGRIDDATA = 0;
WNDPROC wpOrigEditProc;
LRESULT CALLBACK SpySubProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (g_WM_GETGRIDDATA != 0 && message == g_WM_GETGRIDDATA) {
CWnd * target1 = CWnd::FromHandlePermanent(hWnd);
// fails - target1 is null
return 0;
}
return CallWindowProc((WNDPROC ) wpOrigEditProc, hWnd, message, wParam, lParam);
}
BOOL CLibSpyMFCDllApp::InitInstance()
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
CWinApp::InitInstance();
if (g_hWnd) {
g_WM_GETGRIDDATA = RegisterWindowMessage(L"GetGridData");
wpOrigEditProc = (WNDPROC) SetWindowLong(g_hWnd, GWL_WNDPROC, (LONG) SpySubProc);
::SendMessage(g_hWnd, g_WM_GETGRIDDATA, 0, 0);
SetWindowLong(g_hWnd, GWL_WNDPROC, (LONG) wpOrigEditProc);
}
return TRUE;
}