C++Builder 窗口信息读取程序

来源:互联网 发布:知臣女装旗舰店 编辑:程序博客网 时间:2024/06/17 13:26

  1 前言 
  我们经常会遇到很多界面十分漂亮的软件,我们在惊叹其作者高超水平的同时,心中也不禁会想:自己怎样才能作出这样的界面呢?本文就从设计一个窗口信息读取程序入手,利用C++Builder适合于快速开发的特点,详细的介绍了其实现过程。有了本程序,我们可以很轻松的去读取别人程序窗口中的各种信息,从中获取我们想要的信息。 
   
  2 相关知识 
  2.1 句柄 
  要想在程序中实现对其他程序窗口信息的读取,必须先获得对该窗口的控制权,在具体编程中,我们可以通过获取目标窗口的句柄来实现对该窗口的各种操作。那么,何为句柄呢?从数据类型上看句柄是一个无符号整数,Windows用它来标识窗体或其他对象,例如字体或位图。Windows分配给每个窗口一个唯一的句柄,通过句柄操纵该窗口。通俗地说,句柄就像一把扇子的柄,一扇门的把手,只有通过柄和把手,我们才能顺利地控制扇子和门。同理,当要操纵某一个窗口时,需要先获取该窗口的句柄。获取窗口句柄的函数很多,较为常用的一个是WindowFromPoint,其用途是返回指定坐标下窗口的句柄。该函数有一个参数,原型如下: 
  HWND WindowFromPoint ( 
  POINT Point // 指定的坐标(位置) 
  );//如果成功函数返回指定坐标下窗口的句柄,否则返回NULL 
  通过以上函数,我们可以获得目标窗口的句柄,以便我们通过句柄对窗口进行操纵,从而读取目标窗口的各种信息。 
  2.2 消息 
  消息(Message)就是指Windows操作系统发给应用程序的一个通知, 告诉应用程序某个事情发生了。从数据结构的角度看,消息是一个结构体,它包含了消息的类型标识符以及其他一些附加消息。这样,接受消息的对象就能根据这个消息的标识符知道系统中发生了什么事情,并利用其附加信息作出适当的反应。在本程序中,将使用到的消息有: 
  (1)WM_GETTEXTLENGTH 
   当程序向目标窗口发送此消息后,将得到与该目标窗口有关的文本的长度(不包含空字符) 。 
  (2)WM_GETTEXT 
   应用程序发送此消息来复制对应窗口的文本到缓冲区。 
  (3)LB_GETCOUNT和LB_GETTEXT 
   发送消息LB_GETCOUNT后可以获取目标窗口中ListBox中的项目总数,而消息LB_GETTEXT的作用为从该ListBox中得到某一条记录。 
  (4)CB_GETCOUNT 和CB_GETLBTEXT 
   作用同上, 可以获取目标窗口中ComboBox中的项目总数和其中某一条记录。 
  2.3 读取窗口各类信息时用到的函数 
  (1) GetWindowRect 
  该函数可获得整个窗口的矩形范围,原型如下: 
  BOOL GetWindowRect ( 
  HWND hWnd, // 欲获得矩形范围的那个窗口的句柄 
  LPRECT lpRect // 装载窗口矩形范围的坐标值 
  ); //成功返回非零,否则返回零 
  (2)GetClassName 
  函数取得指定窗口的类名,其原型为: 
  int GetClassName( 
  HWND hWnd, // 欲获得类名的那个窗口的句柄 
  LPTSTR lpClassName, // 存放类名的缓冲区 
  int nMaxCount // 缓冲区长度 
  ); //成功返回拷贝至缓冲区的类名,失败返回零 
  (3)GetWindowLong 
  函数的作用是从指定的窗口中获取信息,原型: 
  LONG GetWindowLong( 
  HWND hWnd, // 欲获取信息的窗口的句柄 
  int nIndex// 想要取回的信息,可以是下表中任何一个常数: 
  GWL_EXSTYLE//扩展窗口样式 GWL_STYLE 窗口样式 
  GWL_WNDPROC//该窗口的窗口函数的地址GWL_HINSTANCE拥有窗口的实例的句柄 
  GWL_HWNDPARENT//该窗口的父窗口句柄GWL_ID对话框中一个子窗口的标识符 
  GWL_USERDATA//含义由应用程序规定DWL_DLGPROC窗口的对话框函数地址 
  DWL_MSGRESULT //在对话框函数中处理的一条消息返回的值 
  DWL_USER //含义由应用程序规定 
  ); //函数返回值由参数nIndex来决定要返回哪个方面的当前值,若出错则返回0 
  (4)SendMessage 
  向窗口发送某一指定消息时用到此函数,函数的原型为: 
  LRESULT SendMessage( 
  HWND hWnd, // 目标窗口的句柄 
  UINT Msg, // 将要发送的消息 
  WPARAM wParam, // 消息第一个的参数 
  LPARAM lParam //消息的第二个参数 
  ); 
  (5)GetDC 
  获取指定窗口的设备场景,函数有一个参数,原型: 
  HDC GetDC( 
  HWND hWnd//将获取其设备场景的窗口句柄,若为0,表示要获取整个屏幕DC 
  ); //返回指定窗口的设备场景句柄,出错则为NULL 
  (6)GetPixel 
  GetPixel函数可获取指定坐标下的像素点的RGB颜色值。原型如下: 
  COLORREF GetPixel( 
  HDC hdc, //设备场景的句柄 
  int nXPos, //逻辑坐标(x坐标)中要检查的点 
  int nYPos //逻辑坐标(y坐标)中要检查的点 
  ); 
  (7)GetRValue 、GetGValue 、GetBValue 
  这3个函数分别得到颜色的红、绿、蓝分量值。 
   
  3 程序的实现及关键代码分析 
  以下是用C++ Builder6编写的程序代码,实现了对其他程序窗口信息的读取探测。 
  POINT pMouse; 
  char strClassName[255], strCaption[255]; // 定义存放窗口类名和窗口标题的变量 
  int strTextLength; // 文本长度 
  if(bMouseDown) // 如果按下了鼠标 
  {Memo1->Clear(); 
  GetCursorPos(&pMouse); // 得到鼠标当前坐标 
  hWnd =WindowFromPoint(pMouse); // 获取当前坐标下窗口的句柄 
  if (hWnd != NULL && hWnd != Handle 
  && !PtInRect(BoundsRect, pMouse) ) //目标窗口不能为本程序窗口 
  {// 获取鼠标当前位置 
  LabelMouse->Caption="鼠标位置:"+String(pMouse.x)+String(",")+pMouse.y; 

  // 在Edit中显示当前窗口的句柄(分别以16进制和十进制表示) 
 EditHandle->Text=IntToHex(int(hWnd), 8)+"("+int(hWnd)+")"; 
  // 获取窗口矩形范围 
  GetWindowRect(hWnd, &tRect); 
  EditRect->Text= String("(") + String(tRect.Left) + " ," + 
  String(tRect.Top) + ")-(" + String(tRect.Right) + 
  ","+String(tRect.Bottom)+")"+" "+String(tRect.Right-tRect.Left)+"x"+String(tRect.Bottom-tRect.Top); 
  // 在Edit中显示窗口的类名 
  GetClassName(hWnd, strClassName, 255); 
  EditClassName->Text= String(strClassName); 
  // 在Edit中显示窗口的标题 
  strTextLength=SendMessage(hWnd,WM_GETTEXTLENGTH, 0, 0); //获取文本长度 
  if(strTextLength>256) 
  strTextLength = 255; 
  if(strTextLength>0) 
  {SendMessage(hWnd,WM_GETTEXT,strTextLength+1, (LPAR 
  AM)&strCaption[0]); 
  // 发送WM_GETTEXT消息,读取其中的文本内容 
  EditCaption->Text= String(strCaption);} 
  else 
  EditCaption->Text = "无";// 判断是否为密码框,先获取窗口(控件)风格,再看是否有密码属性 
  if(ES_PASSWORD&GetWindowLong(hWnd,GWL_STYLE))// 具有密码属性 
  EditIsPsw->Text="是密码框"; 
  else 
  EditIsPsw->Text="(否)不是密码框"; 
  // 取 ListBox ,Memo 的内容 
  if(EditClassName->Text.Pos("ListBox")>0) 
  // 如果对象为ListBox 
  {Memo1->Clear(); 
  int iLBCount; 
  char strLBstr[255]; 
  // 发送LB_GETCOUNT消息,获取ListBox中的项目总数 
  iLBCount = SendMessage(hWnd, LB_GETCOUNT, 0, 0); 
  LabelCount->Caption="取得记录总数:"+String(iLBCount)+"条"; 
  for(int i = 0;i<ilbcount;i++)
  {//依次读取每一条记录,并显示在Memo中 
  SendMessage(hWnd, LB_GETTEXT, i, (LPARAM)strLBstr); 
  Memo1->Lines->Add(strLBstr); }} 
  if(EditClassName->Text.Pos("Memo")>0) // 如果对象为Memo 
  { LabelCount->Caption=""; 
  Memo1->Clear(); 
  int iTextLen; 
  iTextLen = SendMessage(hWnd,WM_GETTEXTLENGTH,0,0); 
  char strCBStr[65535]; 
  SendMessage(hWnd,WM_GETTEXT,iTextLen+1, (LPARAM)strCBStr); 
  Memo1->Lines->Add(strCBStr); } // 获取颜色 
  HDC hDC = GetDC(0); 
  COLORREF cl = GetPixel(hDC,pMouse.x,pMouse.y); 
  int R,G,B; 
  R = GetRValue(cl); 
  G = GetGValue(cl); 
  B = GetBValue(cl); 
  } //目标窗口不能为本程序窗口 
  } //if(bMouseDown) 
   
  4 结束语 
  本文在实现一个窗口信息读取程序的同时,详细介绍了其相关函数的功能和应用,并给出了相应的完整C++Builder源程序, 我们还可以在此程序基础上,通过一定的修改实现更加复杂的信息探测读取功能。本程序在C++Builder6.0+Windows XP环境下编译通过。在Windows XP\2000下测试良好。