
function GetFocusHandle: HWND;
var
h: HWND;
c: array[0102432] of Char;
idAttach: Cardinal;
begin
H := GetForegroundWindow;
idAttach := GetWindowThreadProcessId(h, nil);
if not AttachThreadInput(idAttach , GetCurrentThreadId(), True) then Exit;
Result := GetFocus;
AttachThreadInput(idAttach, GetCurrentThreadId(), false );
end;
这是因为:一旦程序启动后,系统只分配给它一个PID,而一个程序往往有多个窗口。所以,要想从PID反向查找对应的窗口不具有唯一性,并已经过实践证明,往这方面研究只能走入死胡同。
解决此问题办法是:先枚举所有窗口句柄,然后取得对应的进程名称或PID,如果该进程或PID满足你的条件,则可以进行相应处理。
using System;
using SystemRuntimeInteropServices;
namespace FrmZhidao
{
public struct POINT {
int x;
int y;
}
public static class APIMethod
{
[DllImport("user32dll")]
static extern IntPtr WindowFromPoint(POINT Point);
[DllImport("user32dll")]
static extern IntPtr WindowFromPoint(int xPoint, int yPoint);
[DllImport("user32dll")]
static extern bool GetCursorPos(out POINT lpPoint);
[DllImport("user32dll")]
static extern bool SetWindowText(IntPtr hWnd, string lpString);
public static POINT GetCursorPos(){
POINT p;
if (GetCursorPos(out p)){
return p;
}
throw new Exception();
}
public static IntPtr WindowFromPoint(){
POINT p=GetCursorPos();
return WindowFromPoint(p);
}
}
}
下面是我去获取Clicker Hero这个游戏的句柄,用print Screen键截的图,所以没鼠标指针。Spy++也在图上,指针是对上的。
main函数,和我的系统信息。 我64位的win10都能做到,就更别说win7了
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetForegroundWindow Lib "user32" () As Long
'可以通过查看前景窗口是否为指定窗口判断
hwd1 = FindWindow("#32770", "QQ用户登录")
'获得指定窗口句柄
hwd2 = GetForegroundWindow
'获得前景窗口句柄
If hwd1 = hwd2 Then MsgBox "指定窗口为活动状态!"
'判断是否相同
'可以通过ModifyMenu修改系统菜单来禁止移动,但并不适用所有窗体,有的窗体不具有系统菜单(BorderStyle=0)
'但通过子类化仍可以实现系统菜单具有的功能,新建窗体,添加command1,复制粘贴下段代码
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As Long) As Long
Private Declare Function ModifyMenu Lib "user32" Alias "ModifyMenuA" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpString As Any) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const SC_MOVE = &HF010&
Private Const MF_BYCOMMAND = &H0&
Private Const MF_ENABLED = &H0&
Private Const MF_GRAYED = &H1&
Private Sub Command1_Click()
hwind = FindWindow("#32770", "QQ用户登录")
'获取窗体句柄
hMenu = GetSystemMenu(hwind, False)
'获取该窗体系统菜单句柄
ModifyMenu hMenu, SC_MOVE, MF_BYCOMMAND Or MF_GRAYED, -10, "禁止移动"
'设置移动菜单项不可用,并指定新ID为小于0的-10以防止系统重新加载该菜单,新标题为“禁止移动”,成功返回非0,失败0
'ModifyMenu hMenu, -10, MF_BYCOMMAND + MF_ENABLED, SC_MOVE, "移动(&M)" '恢复移动菜单
SendMessage hwind, WM_NCACTIVATE, True, 0
'发送WM_NCACTIVE消息到指定窗体刷新非客户区(标题栏)
End Sub
一个网上的例子
c# 获取鼠标处窗口句柄,程序嵌入桌面
using System;
using SystemCollectionsGeneric;
using SystemComponentModel;
using SystemData;
using SystemDrawing;
using SystemText;
using SystemWindowsForms;
using SystemRuntimeInteropServices;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("user32dll", EntryPoint = "FindWindow")]
public static extern int FindWindow(
string lpClassName,
string lpWindowName
);
[DllImport("user32dll", EntryPoint = "GetWindow")]//获取窗体句柄,hwnd为源窗口句柄
/wCmd指定结果窗口与源窗口的关系,它们建立在下述常数基础上:
GW_CHILD
寻找源窗口的第一个子窗口
GW_HWNDFIRST
为一个源子窗口寻找第一个兄弟(同级)窗口,或寻找第一个顶级窗口
GW_HWNDLAST
为一个源子窗口寻找最后一个兄弟(同级)窗口,或寻找最后一个顶级窗口
GW_HWNDNEXT
为源窗口寻找下一个兄弟窗口
GW_HWNDPREV
为源窗口寻找前一个兄弟窗口
GW_OWNER
寻找窗口的所有者
/
public static extern int GetWindow(
int hwnd,
int wCmd
);
[DllImport("user32dll", EntryPoint = "SetParent")]//设置父窗体
public static extern int SetParent(
int hWndChild,
int hWndNewParent
);
[DllImport("user32dll", EntryPoint = "GetCursorPos")]//获取鼠标坐标
public static extern int GetCursorPos(
ref POINTAPI lpPoint
);
[StructLayout(LayoutKindSequential)]//定义与API相兼容结构体,实际上是一种内存转换
public struct POINTAPI
{
public int X;
public int Y;
}
[DllImport("user32dll", EntryPoint = "WindowFromPoint")]//指定坐标处窗体句柄
public static extern int WindowFromPoint(
int xPoint,
int yPoint
);
private void timer1_Tick(object sender, EventArgs e)
{
POINTAPI point = new POINTAPI();//必须用与之相兼容的结构体,类也可以
GetCursorPos(ref point);//获取当前鼠标坐标
int hwnd = WindowFromPoint(pointX, pointY);//获取指定坐标处窗口的句柄
thislabel1Text =pointXToString() + ":" + pointYToString() + "-" + hwndToString();//显示效果,此时窗口已经嵌入桌面了
}
const int GW_CHILD = 5;//定义窗体关系
private void Form1_Load(object sender, EventArgs e)
{
int hDesktop = FindWindow("Progman", null);//获取系统句柄
hDesktop = GetWindow(hDesktop, GW_CHILD);//获取其子窗口句柄,就是桌面的句柄
SetParent((int)thisHandle, hDesktop);//设置父窗体,第一个为要被设置的窗口,第二个参数为指定其父窗口句柄
}
}
}
以上就是关于Delphi中如何获取外部程序焦点所在控件的句柄全部的内容,包括:Delphi中如何获取外部程序焦点所在控件的句柄、vB 通过进程名称获取窗体句柄、c# 通过鼠标获取窗口句柄等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)