C# 自己动手实现Spy++(二)


  昨天已经实现了获取窗口的标题、句柄等信息,但是高亮部分还有问题,而且红色绘制框擦除也有问题,今天就又研究了下上述两个问题。

高亮部分红色框只显示左上的边框,而右下的显示不出来,如图:

代码如下:

   

   public void Highlight2(IntPtr hWnd)
        {
            const float penWidth = 3;
            Rectangle rc = new Rectangle();
            GetWindowRect(hWnd, ref rc);

            IntPtr hDC = GetWindowDC(hWnd);
            if (hDC != IntPtr.Zero)
            {
                using (Pen pen = new Pen(Color.Red, penWidth))
                {
                    using (Graphics g = Graphics.FromHdc(hDC))
                    {
                        Font font = new Font("Courer New", 9, FontStyle.Bold);
                        g.DrawRectangle(pen, 0, 0, rc.Right - rc.Left - (int)penWidth, rc.Bottom - rc.Top - (int)penWidth);  
                        // g.DrawString("BIC Tech <SPY>", font, Brushes.Red, 5, 5);
                    }
                }
            }
            ReleaseDC(hWnd, hDC);
        }

而这一句 :                     

g.DrawRectangle(pen, 0, 0, rc.Right - rc.Left - (int)penWidth, rc.Bottom - rc.Top - (int)penWidth);  

应当是控制绘制红色框大小的关键 ,它就是想从(0,0)开始绘制到rc的宽度、高度结束这个坐标,就能绘制和窗口一样的红色框,然而它却只有左上部分,我就想着我不管它窗口大小多少,我直接再绘制一个固定大小10*10的试试,于是就加了   :

                        g.DrawRectangle(pen, 0, 0, 10,10);

发现这个红色框是有右下边框的!!!我就想到肯定是大小除了问题,我再仔细查看发现昨天的代码的Size是不断变化的,按道理应当不会变化,发现它是在拖动的时候不断变化,我就把窗口移动到(0,0)坐标,这个时候才是和真实的大小一致的,我再把窗口移动(1,0)向左移动一个像素,它的Size就会增加1,rc.Right - rc.Left这个实际上就等价于rc.Width,后来我直接用rc.Width-rc.Left这个时候发现我横向移动它的大小没有改变!!

然后我就把获取窗口大小的代码改为了:
                textBox4.Text = string.Format("{0} x {1}", rc.Width - rc.Left, rc.Height - rc.Top);

这样在移动的时候窗口的大小就没有再变化。。。。。

然后同理我把

              g.DrawRectangle(pen, 0, 0, rc.Width-(int)penWidth, rc.Height- (int)penWidth);  
改为:

               g.DrawRectangle(pen, 0, 0, rc.Width -rc.Left- (int)penWidth, rc.Height -rc.Top- (int)penWidth);

结果发现红色框的右下部分出现了!!!

这个可能是某个地方的BUG,也有可能是某个代码的问题,总之解决的方法找到了,先不管它,接着搞刷新窗体绘制部分,我用

下面代码,结果发现它擦除的有问题,会存在不能及时擦除以前绘制窗口的问题:
        public void Refresh2(IntPtr hWnd)
        {
            InvalidateRect(hWnd,new COMRECT(0,0,0,0),true);
            UpdateWindow(hWnd);
            RedrawWindow(hWnd, new COMRECT(0, 0, 0, 0), IntPtr.Zero, Win32.RDW_FRAME | Win32.RDW_INVALIDATE | Win32.RDW_UPDATENOW | Win32.RDW_ALLCHILDREN);
        }

后来就搜索,终于找到一篇:http://bbs.csdn.net/topics/100106472

使用它的方法,直接一句就可以搞定:RedrawWindow(GetDesktopWindow(), null, IntPtr.Zero, 0x85);

至此,高亮绘制窗口和绘制窗口擦除部分都已经解决!

 

最后就是那个小的BUG,g.DrawRectangle(pen, 0, 0, rc.Width -rc.Left- (int)penWidth, rc.Height -rc.Top- (int)penWidth);这一句为什么宽度会多出来rc.Left还没找到原因,有哪位找到原因了告诉我一下。

程序我放在CSDN,欢迎下载:http://download.csdn.net/detail/xtfnpgy/5862401 ,最新的代码更改的部分我没有放上去,大家看着我这里的贴过去就可以了。

原文地址:https://www.cnblogs.com/xtfnpgy/p/9285442.html