c#使用FindWindow函数的心得

xsl0213 2015-08-14 01:32:56
正在给一个单位写个小程序,原来的想法是把显示曲线的程序主窗体劫持到本程序下,不想Setparent函数使用起来有限制(不能捕获外部程序窗口),遂改变思路,每秒复制目标程序主界面到本程序界面显示,用到FindWindow方法,最后出了点小意外,天黑之前运行无数次都正常,回家再试就不行了,代码如下:

[DllImport("user32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string strclassName, string strWindowText);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC( IntPtr hwnd );
[DllImport("user32.dll")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern int BitBlt(
IntPtr hdcDest, // handle to destination DC目标设备的句柄
int nXDest, // x-coord of destination upper-left corner目标对象的左上角的X坐标
int nYDest, // y-coord of destination upper-left corner目标对象的左上角的Y坐标
int nWidth, // width of destination rectangle目标对象的矩形宽度
int nHeight, // height of destination rectangle目标对象的矩形长度
IntPtr hdcSrc, // handle to source DC源设备的句柄
int nXSrc, // x-coordinate of source upper-left corner源对象的左上角的X坐标
int nYSrc, // y-coordinate of source upper-left corner源对象的左上角的Y坐标
UInt32 dwRop // raster operation code光栅的操作值
);
private const uint SRCCOPY = (uint)0xCC0020;//光栅操作码:复制


hWndSrcForm = FindWindow(strWindowClassName, null);//获取待捕捉窗口句柄
IntPtr hdcSrc = Form1.GetWindowDC(hWndSrcForm);//创建待捕获窗口的设备上下文(绘图句柄)
//RECT windowRect = new Form1.RECT();
//Form1.GetWindowRect(hWndSrcForm, ref windowRect);//获取待捕获窗口大小,含非客户区
//int width = windowRect.right - windowRect.left; //此处不能这样做,应根据测试直接在BitBle函数中赋值
//int height = windowRect.bottom - windowRect.top;
IntPtr handle = this.Handle; //
IntPtr hdDesForm = this.CreateGraphics().GetHdc();
//this.lblLocHandle.Text = handle.ToString();
//this.lblLocDC.Text = hdDesForm.ToString();
//this.lblSrcHandle.Text = hWndSrcForm.ToString();
//this.lblSrcDC.Text = hdcSrc.ToString();
//this.lblClass.Text = Settings.Default.WindowClassName;
Form1.BitBlt(hdDesForm, 100, 100, 250, 65, hdcSrc, 40, 40, Form1.SRCCOPY);//将源DC中的指定位置和大小的图像复制到目标DC
Form1.ReleaseDC(handle, hdDesForm);
Form1.ReleaseDC(hWndSrcForm, hdcSrc);

结果发现FindWindow如果只是用第一个参数(WindowClass)就是窗体类名,一直获取不到正确的目标窗体句柄,后续步骤就无法开展,将下列代码:

hWndSrcForm = FindWindow(strWindowClassName, null);//获取待捕捉窗口句柄

更改为:

Process[] locAllProcess = Process.GetProcessesByName(Settings.Default.AppName);
string strMainWindowTitle = locAllProcess[0].MainWindowTitle;
hWndSrcForm = FindWindow(null, strMainWindowTitle);//获取待捕捉窗口句柄

这样做自认为操作更友好,不必使用spy++费劲看窗口类名,可以使用任务管理器开程序名称就成,但仍不能避免多实例运行问题,希望对可能用到FindWindow的朋友有所帮助
...全文
677 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
willhuo 2015-08-14
  • 打赏
  • 举报
回复
最好还是按照spy抓取后提供的窗口名或者类名,如果有异议,直接找一个没有异议的父窗口开始,依次遍历,找到你想要的窗口就行了。我记得 有更简单的办法,直接根据窗口句柄能获取到图像,忘了咋写的了

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧