dllを使用しSetWindowsHookEx
てdirectxアプリをフックし、そのメッセージをメインアプリのサブクラス化されたウィンドウに戻します。私はこれをC++で実行しましたが、pinvokeなどを使用してC#で実行できるはずです。C++のコードは次のとおりです。
__declspec(dllexport) int _stdcall InstallHook(DWORD dwThreadId, HWND ExtrnHandle, HWND Apphandle)
{
if (hHook==0)
hWndApp = Apphandle;
hWndHooked = ExtrnHandle;
hHook = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC) GetMsgProc, (HINSTANCE) hInstance, dwThreadId);
if (hHook==0) return GetLastError();
return 0;
}
これを使用してフックを解除します。
__declspec(dllexport) int UnInstallHook(void)
{
LRESULT result;
if (hHook != 0){
result = UnhookWindowsHookEx(hHook);
if (result == 0) return GetLastError();
hHook = 0;
}
return 0;
}
次に、dllでこのコールバックを使用して、メッセージをアプリに返します。
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
MSG *lpMsg;
if (nCode==HC_ACTION){
lpMsg = (MSG *) lParam;
//see if this is the window we are monitoring
if (lpMsg->hwnd == hWndHooked){
//forward the message to App
ChangeMessage=false;
SendMessage(hWndApp, lpMsg->message, lpMsg->wParam, lpMsg->lParam);
if (ChangeMessage==true){//Did App make changes to the data?
lpMsg->message = Shared_uMsg;
lpMsg->wParam = Shared_wParam;
lpMsg->lParam = Shared_lParam;
}//end if change message
}//end if correct hWnd
}//end if nCode==Action
return(CallNextHookEx(hHook, nCode, wParam, lParam));
}
また、fyi、これはdll .cppファイルの上部にあるコード、宣言、共有データを設定する関数などです。
#include "afxdisp.h" //this does #include <windows.h>
#include <shellapi.h>
#include "WINUSER.H"
#include <fstream>
#include <iostream>
using namespace std;
#define WM_MOUSEWHEEL 0x020A
#define COPY2CLIPBOARD 1 //for copying data from msflexgrid
#define COPY2FILE 2
/*---------------------------------------------
Shared Variables
This data is shared between both prcesses. The
VB App has access to these variables through the
function SetSharedData
---------------------------------------------*/
#pragma data_seg(".shared")
bool ChangeMessage = false;
int Shared_uMsg = 0;
int Shared_wParam = 0;
int Shared_lParam = 0;
int CopyMode = COPY2FILE;
HWND hWndApp = 0; //handle to subclassed Window
HWND hWndHooked = 0;//handle to the hooked window
HHOOK hHook = 0; // Hook handle for WH_GETMESSAGE
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
//---------------------------------------------
// Global Variables, specific to each process
//---------------------------------------------
HINSTANCE hInstance; // Global instance handle for DLL
//--------------------------------------------
// DLL entry-point
//--------------------------------------------
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
hInstance = hinstDLL;//save dll handle for each process
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);
__declspec(dllexport) void _stdcall SetSharedData(int uMsg, WPARAM wParam, LPARAM lParam)
{
Shared_uMsg = uMsg;
Shared_wParam = wParam;
Shared_lParam = lParam;
ChangeMessage = true;
}