C#操作窗口类句柄操作 2.docx
《C#操作窗口类句柄操作 2.docx》由会员分享,可在线阅读,更多相关《C#操作窗口类句柄操作 2.docx(20页珍藏版)》请在冰豆网上搜索。
C#操作窗口类句柄操作2
C#
实现过程:
过程一:
找到当前鼠标位置的句柄
您的使用2个WinAPI(俺喜欢自己封装下来用):
ViewCode
[DllImport("user32.dll",EntryPoint="GetCursorPos")]
publicstaticexternboolGetCursorPos(outPointpt);
[DllImport("user32.dll",EntryPoint="WindowFromPoint")]
publicstaticexternIntPtrWindowFromPoint(Pointpt);
//鼠标位置的坐标
publicstaticPointGetCursorPosPoint()
{
Pointp=newPoint();
if(GetCursorPos(outp))
{
returnp;
}
returndefault(Point);
}
///
///找到句柄
///
///坐标
///
publicstaticIntPtrGetHandle(Pointp)
{
returnWindowFromPoint(p);
}
过程二:
改变窗口的Text
您的使用1个WinAPI:
ViewCode
[DllImport("user32.dll",EntryPoint="SendMessage")]
privatestaticexternintSendMessage(IntPtrhWnd,intMsg,IntPtrwParam,stringlParam);
///
///给窗口发送内容
///
///句柄
///要发送的内容
publicstaticvoidSetText(IntPtrhWnd,stringlParam)
{
SendMessage(hWnd,WM_SETTEXT,IntPtr.Zero,lParam);
}
privateconstintWM_SETTEXT=0x000C;
通过这个方法就能改变Text的值了。
思考:
如果俺把这个窗口的句柄记录下来,下次不用鼠标获取,直接就能改变值不蛮好的嘛。
例如:
我有个桌面系统老叫我输入用户名,密码。
我记录用户名和密码的窗口句柄,然后改变他们的输入值,这样多省事。
(只是举例,不考虑安全性)
问题:
你会告诉我,窗口句柄的每次重建会变的呀,咋办。
回答:
类名不变呀。
过程三:
您的准备一些工具吧,例如:
句柄找类名呀,类名找句柄什么的等等,下面会用到一些WinAPI
ViewCode
[DllImport("user32.dll",EntryPoint="FindWindow")]
privatestaticexternIntPtrFindWindow(stringIpClassName,stringIpWindowName);
[DllImport("user32.dll",EntryPoint="FindWindowEx")]
privatestaticexternIntPtrFindWindowEx(IntPtrhwndParent,IntPtrhwndChildAfter,stringlpszClass,stringlpszWindow);
[DllImport("user32.dll",EntryPoint="GetParent")]
publicstaticexternIntPtrGetParent(IntPtrhWnd);
[DllImport("user32.dll",CharSet=CharSet.Auto)]
publicstaticexternintGetClassName(IntPtrhWnd,StringBuilderlpClassName,intnMaxCount);
///
///找到句柄
///
///类名
///
publicstaticIntPtrGetHandle(stringIpClassName)
{
returnFindWindow(IpClassName,null);
}
///
///子窗口句柄
///
///父窗口句柄
///前一个同目录级同名窗口句柄
///类名
///
publicstaticIntPtrGetChildHandle(IntPtrhwndParent,IntPtrhwndChildAfter,stringlpszClass)
{
returnFindWindowEx(hwndParent,hwndChildAfter,lpszClass,null);
}
///
///全部子窗口句柄
///
///父窗口句柄
///类名
///
publicstaticListGetChildHandles(IntPtrhwndParent,stringclassName)
{
ListresultList=newList();
for(IntPtrhwndClient=GetChildHandle(hwndParent,IntPtr.Zero,className);hwndClient!
=IntPtr.Zero;hwndClient=GetChildHandle(hwndParent,hwndClient,className))
{
resultList.Add(hwndClient);
}
returnresultList;
}
///
///找类名
///
///句柄
///
publicstaticstringGetClassName(IntPtrhWnd)
{
StringBuilderlpClassName=newStringBuilder(128);
if(GetClassName(hWnd,lpClassName,lpClassName.Capacity)==0)
{
thrownewException("notfoundIntPtr!
");
}
returnlpClassName.ToString();
}
思考:
遍历桌面上所有的窗口,然后找类名,然后改他的Text,扯淡嘛,相同的类名太多了,找毛呀。
实现:
不仅记录类名,而且记录类名在父窗口出现的位置,然后通过桌面一层层找下来,最后找到这个句柄。
(虽然不是太准,但是一般的还是能解决了,如果你有什么好方式一起研究)。
过程四:
实现一个WinHWND的类,可以把他的规则,他的父窗口类名,以及在父窗口中同类名出现的顺序记录下来,然后通过这些记录的信息还原句柄。
ViewCode
publicclassWinHWND
{
publicIntPtrHWND{get;set;}
publicstringClassName{get;set;}
publicWinHWNDParent{get;set;}
publicintInParentSequence{get;set;}
privateWinHWND(){}
publicWinHWND(IntPtrhWnd)
{
this.HWND=hWnd;
this.ClassName=GetClassName();
this.Parent=GetParent();
this.InParentSequence=GetInParentSequence();
}
privatestringGetClassName()
{
returnWinAPI.GetClassName(this.HWND);
}
privateWinHWNDGetParent()
{
if(WinAPI.GetParent(this.HWND)==null)
{
thrownewException("notfoundIntPtr!
");
}
if(WinAPI.GetParent(this.HWND)==IntPtr.Zero)
{
returnnull;
}
returnnewWinHWND(WinAPI.GetParent(this.HWND));
}
privateintGetInParentSequence()
{
IntPtrIntprtParent=this.Parent==nullIntPtr.Zero:
this.Parent.HWND;
returnWinAPI.GetChildHandles(IntprtParent,this.ClassName).IndexOf(this.HWND);
}
publicoverridestringToString()
{
StringBuilderresult=newStringBuilder();
for(WinHWNDwinHandle=this;winHandle!
=null;winHandle=winHandle.Parent)
{
result.Append(string.Format("{0}:
{1};",Escape(winHandle.ClassName),
if(winHandle.InParentSequence==-1)break;
}
returnresult.ToString().TrimEnd(';');
}
privatestaticstringGetBaseMark(stringsMark)
{
string[]sMarks=sMark.Split(';');
returnsMarks[sMarks.Length-1].Split(':
')[0];
}
privatestaticstring[]GetChildMarks(stringsMark)
{
string[]sMarks=sMark.Split(';');
string[]sChildMarks=newstring[sMarks.Length-1];
for(inti=0;i{
sChildMarks[i]=sMarks[i];
}
returnsChildMarks;
}
//我一直觉得这段写很丑陋,谁能帮帮我改改
publicstaticWinHWNDGetWinHWND(stringsMark)
{
ListbaseHwnds=WinAPI.GetChildHandles(IntPtr.Zero,GetBaseMark(sMark));
string[]sChildMarks=GetChildMarks(sMark);
//由于主窗口在桌面出现所以很可能同名,所以要看看他的儿子和孙子...是不是都匹配
foreach(IntPtrbaseHwndinbaseHwnds)
{
IntPtrhandle=baseHwnd;
for(inti=sChildMarks.Length-1;i>=0;i--)
{
string[]sChildMark=sChildMarks[i].Split(':
');
try
{
handle=WinAPI.GetChildHandles(handle,UnEscape(sChildMark[0]))[int.Parse(sChildMark[1])];
}
catch
{
break;
}
if(i==0)returnnewWinHWND(handle);
}
continue;
}
returnnull;
}
#region转义
privatestaticstringEscape(stringarg)
{
returnarg.Replace(":
","\\:
").Replace(";","\\;");
}
privatestaticstringUnEscape(stringarg)
{
returnarg.Replace("\\:
",":
").Replace("\\;",";");
}
#endregion
publicstaticWinHWNDGetWinHWND()
{
returnnewWinHWND(WinAPI.GetHandle(WinAPI.GetCursorPosPoint()));
}
}
上全部代码,里面加了窗口的部分属性,扩展其他的属性,自己发挥吧,就是搞WinAPI
ViewCode
usingSystem;
using
usingSystem.Linq;
usingSystem.Text;
using
usingSystem.Drawing;
usingSystem.Collections;
namespaceInformationCollectionDataFill
{
publicclassWinAPI
{
#regionWinodwsAPI
[DllImport("user32.dll",EntryPoint="FindWindow")]
privatestaticexternIntPtrFindWindow(stringIpClassName,stringIpWindowName);
[DllImport("user32.dll",EntryPoint="FindWindowEx")]
privatestaticexternIntPtrFindWindowEx(IntPtrhwndParent,IntPtrhwndChildAfter,stringlpszClass,stringlpszWindow);
[DllImport("user32.dll",EntryPoint="SendMessage")]
privatestaticexternintSendMessage(IntPtrhWnd,intMsg,IntPtrwParam,stringlParam);
[DllImport("user32.dll",EntryPoint="GetParent")]
publicstaticexternIntPtrGetParent(IntPtrhWnd);
[DllImport("user32.dll",EntryPoint="GetCursorPos")]
publicstaticexternboolGetCursorPos(outPointpt);
[DllImport("user32.dll",EntryPoint="WindowFromPoint",CharSet=CharSet.Auto,ExactSpelling=true)]
publicstaticexternIntPtrWindowFromPoint(Pointpt);
[DllImport("user32.dll",CharSet=CharSet.Auto)]
publicstaticexternintGetClassName(IntPtrhWnd,StringBuilderlpClassName,intnMaxCount);
[DllImport("user32.dll",CharSet=CharSet.Auto)]
publicstaticexternintGetWindowText(IntPtrhWnd,[Out,MarshalAs(UnmanagedType.LPTStr)]StringBuilderlpString,intnMaxCount);
[DllImport("user32.dll",CharSet=CharSet.Auto)]
publicstaticexternintGetWindowRect(IntPtrhwnd,refRectanglerc);
[DllImport("user32.dll",CharSet=CharSet.Auto)]
publicstaticexternintGetClientRect(IntPtrhwnd,refRectanglerc);
[DllImport("user32.dll",CharSet=CharSet.Auto)]
publicstaticexternintMoveWindow(IntPtrhwnd,intx,inty,intnWidth,intnHeight,boolbRepaint);
[DllImport("user32.dll",CharSet=CharSet.Auto,SetLastError=true,ExactSpelling=true)]
publicstaticexternintScreenToClient(IntPtrhWnd,refRectanglerect);
#endregion
#region封装API方法
///
///找到句柄
///
///类名
///
publicstaticIntPtrGetHandle(stringIpClassName)
{
returnFindWindow(IpClassName,null);
}
///
///找到句柄
///
///坐标
///
publicstaticIntPtrGetHandle(Pointp)
{
returnWindowFromPoint(p);
}
//鼠标位置的坐标
publicstaticPointGetCursorPosPoint()
{
Pointp=newPoint();
if(GetCursorPos(outp))
{
returnp;
}
returndefault(Point);
}
///
///子窗口句柄
///
///父窗口句柄
///前一个同目录级同名窗口句柄
///类名
///
publicstaticIntPtrGetChildHandle(IntPtrhwndParent,IntPtrhwndChildAfter,stringlpszClass)
{
returnFindWindowEx(hwndParent,hwndChildAfter,lpszClass,null);
}
///
///全部子窗口句柄
///
///父窗口句柄
///类名
///
publicstaticListGetChildHandles(IntPtrhwndParent,stringclassName)
{
ListresultList=newList();
for(IntPtrhwndClient=GetChildHandle(hwndParent,IntPtr.Zero,className);hwndClient!
=IntPtr.Zero;hwndClient=GetChildHandle(hwndParent,hwndClient,className))
{
resultList.Add(hwndClient);
}
returnresultList;
}
///
///给窗口发送内容
///
///句柄
///要发送的内容
publicstaticvoidSetText(IntPtrhWnd,stringlParam)
{
SendMessage(hWnd,WM_SETTEXT,IntPtr.Zero,lParam);
}
privateconstintWM_SETTEXT=0x000C;
///
///获得窗口内容或标题
///
///句柄
///
publicstaticstringGetText(IntPtrhWnd)
{
StringBuilderresult=newStringBuilder(128);
GetWindowText(hWnd,result,result.Capacity);
returnresult.ToString();
}
///
///找类名
///
///句柄
///
publicstaticstringGetClassName(IntPtrhWnd)
{
StringBuilderlpClassName=newStringBuilder(128);
if(GetClassName(hWnd,lpClassName,lpClassName.Capacity)==0)
{
thrownewException("notfoundIntPtr!
");
}
returnlpClassName.ToString();
}
///
///窗口在屏幕位置
///
///句柄
///
publicstaticRectangleGetWindowRect(IntPtrhWnd)
{
Rectangleresult=default(Rectangle);
GetWindowRect(hWnd,refresult);
ret