我试图将另一个窗口(在另一个进程中)子类化,所以我注入了一个dll,该DLL调用SetWindowLongPtr,但失败了,GetLastError返回5。
BOOL APIENTRY DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
{
HWND hwnd = GetHwndProc();
if (!(orgWndProc = (WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)SubclassProc)))
{
char buf[40];
sprintf(buf, "Error code: %d", GetLastError());
MessageBox(hwnd, buf, "Error", MB_OK);
}
break;
}
}
return TRUE;
}
编辑:它绝对正确的PID。
编辑2:我得到了错误的HWND,但现在已得到解决(还编辑了代码)
我不再收到错误5(来自GetLastError)
HWND GetHwndProc()
{
HWND hwnd = GetTopWindow(NULL);
DWORD currentPID = GetCurrentProcessId();
do
{
char title[256];
if ((GetWindowText(hwnd, title, 256) > 0) && (IsWindowVisible(hwnd)))
{
DWORD procId;
GetWindowThreadProcessId(hwnd, &procId);
if (procId == currentPID)
{
MessageBox(hwnd, title, "", MB_OK);
return hwnd;
}
}
hwnd = GetNextWindow(hwnd, GW_HWNDNEXT);
} while (hwnd);
}
WNDPROC orgWndProc;
LRESULT APIENTRY SubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_LBUTTONDOWN:
MessageBox(0, "Subclass", "", 0);
return TRUE;
default:
return CallWindowProc(orgWndProc, hwnd, msg, wParam, lParam);
}
}
感谢您的阅读!
最佳答案
您需要从创建窗口的线程中调用SetWindowSubclass
,与该窗口关联的消息队列在该线程上运行。来自SetWindowSubclass
reference:
警告您不能使用子类化辅助函数来子类化跨线程的窗口。
反过来,必须从创建窗口的进程中调用SetWindowLongPtr
。来自SetWindowLongPtr
reference:
Windows XP / 2000:如果hWnd参数指定的窗口与调用线程不属于同一进程,则SetWindowLongPtr
函数将失败。
还有用户界面特权隔离,它进一步限制了访问。