我正在尝试在C#中子类化外部窗口。 我之前在VB6中使用过类似的东西没有任何问题,但下面的代码不起作用。有人可以帮帮我吗?
//API
[DllImport("user32")]
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr newProc);
[DllImport("user32")]
private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, WinProc newProc);
[DllImport("user32.dll")]
private static extern IntPtr DefWindowProc(IntPtr hWnd, int uMsg, int wParam, int lParam);
[DllImport("user32")]
private static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, int Msg, int wParam, int lParam);
private delegate IntPtr WinProc(IntPtr hWnd, int Msg, int wParam, int lParam);
private const int GWL_WNDPROC = -4;
private enum winMessage : int
{
WM_GETMINMAXINFO = 0x024,
WM_ENTERSIZEMOVE = 0x231,
WM_EXITSIZEMOVE = 0x232
}
private WinProc newWndProc = null;
private IntPtr oldWndProc = IntPtr.Zero;
private IntPtr winHook = IntPtr.Zero;
//Implementation
public void hookWindow(IntPtr winHandle)
{
if (winHandle != IntPtr.Zero)
{
winHook = winHandle;
newWndProc = new WinProc(newWindowProc);
oldWndProc = SetWindowLong(winHook, GWL_WNDPROC,newWndProc);
}
}
public void unHookWindow()
{
if (winHook != IntPtr.Zero)
{
SetWindowLong(winHook, GWL_WNDPROC, oldWndProc);
winHook = IntPtr.Zero;
}
}
private IntPtr newWindowProc(IntPtr hWnd, int Msg, int wParam, int lParam)
{
switch (Msg)
{
case (int)winMessage.WM_GETMINMAXINFO:
MessageBox.Show("Moving");
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
答案 0 :(得分:3)
确定即时完成编码,但在您的解决方案中,您必须拥有表单解决方案和dll解决方案并且它可以工作,如果您希望该代码让我知道。但是你不能在同一个exe中进行子类化。所以它可以在c#中完成,但是当我开始转换我的c ++项目时,你确实需要那个dll
所有因为
BOOL WINAPI DllMain(HANDLE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
{
hInstance=(HINSTANCE)hinstDLL;
}
break;
case DLL_PROCESS_DETACH:
{
if((int)hndll>1)
{
SetWindowLong(hndll,GWL_WNDPROC,OldWndHndl); //Set back the old window procedure
return 1;
}
}
}
}
答案 1 :(得分:0)
使用C#是不可能的。只有非托管C / C ++才能做到这一点..
如果winHook来自另一个进程, oldWndProc = SetWindowLong(winHook, GWL_WNDPROC,newWndProc);
将始终返回0(表示失败)。