• 句柄2


    没有WM_CLICK,我想你说的应该是WM_LBUTTONDOWN,这个就是当被鼠标左键点击时引发的消息;
    BM_CLICK是其他窗口发送给按钮控件的消息,让按钮执行点击操作,可以模拟按钮点击;
    BN_CLICK是当按钮被点击时,按钮控件发送给按钮控件的父窗口的,告诉父窗口我被点击了
     
    ///////////////////////
    如果BUTTON太多的话,再把GetWindowText也加上,来判断哪一个是你想要的!!
     
     
     
    先用FindWindow找主窗口,再用GetDlgItem一级一级往下找子窗口,直到找到你想要的Button
     
    假设你的窗口的句柄是:hw   程序如下: 
    var
        h1,h2,h3:Thandle;
    begin
        h1:=findwindowex(hw,0, 'TButton ',nil);
        h2:=GetNextWindow(h1,GW_HWNDNEXT);
        h3:=GetNextWindow(h2,GW_HWNDNEXT);
        sendmessage(hw,wm_command,BN_CLICKED,h1);//点击第一个按钮
        ...
       
    end;
     
    ////////////////////////////////////////////////////
     
    //如果只打开一个记事本的话用下面的代码,如果是有多个的话,需要修改一下枚举窗口时的窗口名
    //if pos(sample.txt - 记事本',StrPas(WinText))>0 then
     
    unit Unit1;
     
    interface
     
    uses
     Windows, Messages, SysUtils, Classes, Controls, Forms, StdCtrls;
     
    type
     TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        Edit1: TEdit;
        procedure Button1Click(Sender: TObject);
     private
     public
     end;
     
    var
     Form1: TForm1;
     HEdit: THandle;
     
    implementation
     
    {$R *.dfm}
     
    //向控件发送字符
    procedure SendDBCSString(hFocus: HWND; const sSend: string);
    var
     k : integer;
     ch : byte;
    begin
     k := 1;
     while k <= Length(sSend) do begin
        ch := byte(sSend[k]);
        if Windows.IsDBCSLeadByte(ch) then
        begin
          Inc(k);
          SendMessage(hFocus, WM_IME_CHAR, MakeWord(byte(sSend[k]), ch), 0);
        end
        else
          SendMessage(hFocus, WM_IME_CHAR, word(ch), 0);
        Inc(k);
     end;
    end;
     
    //枚举记事本窗口,获取记事本的内容输入框句柄
    Function EnumWinProc(Wnd: HWND; Form1: TForm1): Boolean; Export;StdCall;
    var
     WinText : Array[0..255] of Char;
    begin
     GetWindowText(Wnd, WinText, 255);
     Result := True;
     if pos('记事本',StrPas(WinText))>0 then
     HEdit:=FindWindowEx(WND,0,'Edit','');
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
     EnumWindows(@EnumWinProc, LongInt(Self));
     SendDBCSString(HEdit,'预先设定的文字');
    end;
     

    end.

    ///////////////////////////////////////////////////

    基本上句柄是标志窗口,我可以根据句柄又可引申其中更多如类名,windowtitle等属性所以基于这点,一般开发工具会提供查句柄,查类名等工具,vs提供的spy++就是一个很好例子。现在教你们一查句柄知多少。其实也简单,下面贴出源代码。

    procedure Tform1.TimerTimer(Sender: TObject);
      var
      Pos: TPoint;
      Handle: HWND;
      ScreenDC: HDC;
      Buf: array[0..1024] of Char;
      ScreenColor: COLORREF;
      begin
      GetCursorPos(Pos); // 得到当前光标位置
      Handle := WindowFromPoint(Pos); // 返回当前位置的句柄
      HandleText.Caption := IntToStr(Handle);
      GetClassName(Handle, Buf, 1024); // 得到类名
      ClassNameText.Caption := Buf;
      SendMessage(Handle, WM_GETTEXT, 33, Integer(@Buf)); // 得到标题
      TitleText.Caption := Buf;
      { 得到光标处点的颜色 }
      ScreenDC := GetDC(0);
      ScreenColor := GetPixel(ScreenDC, Pos.X, Pos.Y);
      Shape.Brush.Color := TColor(ScreenColor);
      RGBColorText.Caption := ': ' + IntToStr(GetRValue(ScreenColor)) +
      绿: ' + IntToStr(GetGValue(ScreenColor)) + '  : ' +
      IntToStr(GetBValue(ScreenColor));
      ReleaseDC(0, ScreenDC);
      DelphiColorText.Caption := Format('Delphi中颜色值:$00%2.2x%2.2x%2.2x', [GetBValue(ScreenColor),
      GetGValue(ScreenColor), GetRValue(ScreenColor)]);
      HTMLColorText.Caption := Format('HTML颜色值:#%2.2x%2.2x%2.2x', [GetRValue(ScreenColor),
      GetGValue(ScreenColor), GetBValue(ScreenColor)]);
      end; 

    /////////////////////////////////////////////////////////////////////////////////////////////

    SendMessage(TreeView.Handle,TVM_SETBKCOLOR,0,RGB(255,0,0)); 设置TV背景颜色

    SendMessage(Button.Handle,WM_LBUTTONDOWN,0,0);
      鼠标左键按下
    SendMessage(Button.Handle,WM_LBUTTONUP,0,0);
       鼠标左键抬起
    SendMessage(Edit.Handle,WM_SETTEXT,255,Integer(PChar('abc')));
     传递文本
    SendMessage(Edit.Handle,WM_Char,Wparam('Q'),2);
      传递字符
    SendMessage(Button.Handle,BM_SETSTYLE,BS_RADIOBUTTON,1);
      改变Button风格
    SendMessage(ComboBox.Handle,CB_SETDROPPEDWIDTH,300,0);
      改变CBDownWidth
    WM_CUT
    WM_COPYWM_PASTE  剪切,复制,粘帖

    实现任意组合键
    keybd_event(VK_Control, MapVirtualKey(VK_Control, 0), 0, 0);
    keybd_event(ord('V'), MapVirtualKey(ord('V'), 0), 0, 0);
    keybd_event(ord('V'), MapVirtualKey(ord('V'), 0), KEYEVENTF_KEYUP, 0);
    keybd_event(VK_Control, MapVirtualKey(VK_Control, 0), KEYEVENTF_KEYUP, 0);

    SendMessageA
    说明:       调用一个窗口的窗口函数,将一条消息发给那个窗口。除非消息处理完毕,否则该函数不会返回SendMessage所包含4个参数:    
    1.       hwnd       32
    位的窗口句柄窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可视对象的句柄
    2.       wMsg      
    用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量
    3.       wParam      
    通常是一个与消息有关的常量值,也可能是窗口或控件的句柄
    4.       lParam      
    通常是一个指向内存中数据的指针。由于WParmlParamPointer都是32位的,因此,它们之间可以相互转换
    wMsg
    函数    
    WM_CREATE       创建一个窗口
    WM_DESTROY       当一个窗口被破坏时发送
    WM_MOVE       移动一个窗口
    WM_SIZE       改变一个窗口的大小
    WM_ACTIVATE       一个窗口被激活或失去激活状态
    WM_SETFOCUS       一个窗口获得焦点
    WM_KILLFOCUS       一个窗口失去焦点
    WM_ENABLE       一个窗口改变成Enable状态
    WM_SETREDRAW       设置窗口是否能重画
    WM_SETTEXT       应用程序发送此消息来设置一个窗口的文本
    WM_GETTEXT       应用程序发送此消息来复制对应窗口的文本到缓冲区
    WM_GETTEXTLENGTH       得到与一个窗口有关的文本的长度(不包含空字符)
    WM_PAINT       要求一个窗口重画自己
    WM_CLOSE       当一个窗口或应用程序要关闭时发送一个信号
    WM_QUERYENDSESSION       用户选择结束对话框或程序自己调用ExitWindows函数
    WM_QUIT       用来结束程序运行
    WM_QUERYOPEN       用户窗口恢复以前的大小位置时,把此消息发送给某个图标
    WM_ERASEBKGND       当窗口背景必须被擦除时(例在窗口改变大小时)
    WM_SYSCOLORCHANGE       当系统颜色改变时,发送此消息给所有顶级窗口
    WM_QUERYENDSESSION       消息后,此消息发送给应用程序,通知它对话是否结束
    WM_SHOWWINDOW       当隐藏或显示窗口是发送此消息给这个窗口
    WM_ACTIVATEAPP       发此消息给应用程序哪个窗口是激活的,哪个是非激活的    
    WM_FONTCHANGE       当系统的字体资源库变化时发送此消息给所有顶级窗口
    WM_TIMECHANGE       当系统的时间变化时发送此消息给所有顶级窗口
    WM_CANCELMODE       发送此消息来取消某种正在进行的摸态(操作)
    WM_SETCURSOR       如果鼠标引起光标在某个窗口中移动
    WM_ENDSESSION       当系统进程发出且鼠标输入没有被捕获时,就发消息给某个窗口
    WM_MOUSEACTIVATE       当光标在某个非激活的窗口中而用户正按着鼠标的某个键发送此消息给当前窗口
    WM_CHILDACTIVATE       送此消息给MDI子窗口当用户点击此窗口的标题栏,或当窗口被激活,移动,改变大小
    WM_QUEUESYNC     此消息由基于计算机的训练程序发送,通过       WH_JOURNALPALYBACKhook程序分离出用户输入消息
    WM_GETMINMAXINFO       此消息发送给窗口当它将要改变大小或位置    
    WM_PAINTICON       发送给最小化窗口当它图标将要被重画
    WM_ICONERASEBKGND       此消息发送给某个最小化窗口,仅当它在画图标前它的背景必须被重画
    WM_NEXTDLGCT发送此消息给一个对话框程序去更改焦点位置
    WM_SPOOLERSTATUS       每当打印管理列队增加或减少一条作业时发出此消息    
    WM_DRAWITEM       buttoncomboboxlistboxmenu的可视外观改变时发送
    WM_MEASUREITEM       button,       combobox,       listbox,       listview       control,       or       menuitem       被创建时
    WM_VKEYTOITEM       此消息有一个LBS_WANTKEYBOARDINPUT风格的发出给它的所有者来响应WM_KEYDOWN消息    
    WM_CHARTOITEM       此消息由一个LBS_WANTKEYBOARDINPUT风格的列表框发送给他的所有者来响应WM_CHAR消息    
    WM_SETFONT       当绘制文本时程序发送此消息得到控件要用的颜色
    WM_GETFONT       应用程序发送此消息得到当前控件绘制文本的字体
    WM_SETHOTKEY       应用程序发送此消息让一个窗口与一个热键相关连
    WM_GETHOTKEY       应用程序发送此消息来判断热键与某个窗口是否有关联
    WM_QUERYDRAGICON       此消息发送给最小化窗口,当此窗口将要被拖放而它的类中没有定义图标,应用程序能返回一个图标或光标的句柄,当用户拖放图标时系统显示这个图标或光标
    WM_COMPAREITEM       发送此消息来判定comboboxlistbox新增加的项的相对位置
    WM_COMPACTING       显示内存已经很少了
    WM_WINDOWPOSCHANGING       发送此消息给那个窗口的大小和位置将要被改变时,来调用setwindowpos函数或其它窗口管理函数
    WM_WINDOWPOSCHANGED       发送此消息给那个窗口的大小和位置已经被改变时,来调用setwindowpos函数或其它窗口管理函数
    WM_POWER       当系统将要进入暂停状态时发送此消息
    WM_COPYDATA       当一个应用程序传递数据给另一个应用程序时发送此消息
    WM_CANCELJOURNA       当某个用户取消程序日志激活状态,提交此消息给程序
    WM_NOTIFY       当某个控件的某个事件已经发生或这个控件需要得到一些信息时,发送此消息给它的父窗口    
    WM_INPUTLANGCHANGEREQUEST       当用户选择某种输入语言,或输入语言的热键改变
    WM_INPUTLANGCHANGE       当平台现场已经被改变后发送此消息给受影响的最顶级窗口
    WM_TCARD       当程序已经初始化windows帮助例程时发送此消息给应用程序
    WM_HELP       此消息显示用户按下了F1,如果某个菜单是激活的,就发送此消息个此窗口关联的菜单,否则就发送给有焦点的窗口,如果当前都没有焦点,就把此消息发送给当前激活的窗口
    WM_USERCHANGED       当用户已经登入或退出后发送此消息给所有的窗口,当用户登入或退出时系统更新用户的具体设置信息,在用户更新设置时系统马上发送此消息
    WM_NOTIFYFORMAT       公用控件,自定义控件和他们的父窗口通过此消息来判断控件是使用ANSI还是UNICODE结构

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Delphi获取其它进程窗口句柄的3种方法

    Delphi获取其它进程窗口句柄的3种方法
    ━━━━━━━━━━━━━━━━━━━━━━━━━━

    作者:张国斌

        本文主要跟大家介绍Delphi中获取其它进程的窗口句柄,在Delphi中获取其它进程的窗口句柄,绝大部分人首先想到的会使用:FindWindow或者用GetWindow来遍历查找,如:

    handle := FindWindow(nil,PChar('窗口的标题'));
    或者:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      hCurrentWindow: HWnd;
      WndText:String;
    begin
      hCurrentWindow := GetWindow(Handle, GW_HWNDFIRST);
      while hCurrentWindow <> 0 do
      begin
        WndText:=GetWndText(hCurrentWindow);
        if UpperCase(WndText)='窗口的标题' then begin
          ...
          ...
        end;
        hCurrentWindow:=GetWindow(hCurrentWindow, GW_HWNDNEXT);
      end;
    end;

        因为目前网络上绝大部分的代码都是介绍用这两种方法取得其它进程的窗口句柄。虽这两种方法都可以达到查找其它进程的窗口句柄的目的,但本人认为这两都方法存在较大的弊端。因为这两种方法都是根据其它进程的标题来查找的,如果其它进程的标题在运行时不断的发生变化,那么这两种方法就无法没办法用了。


       
    今天给大家介绍第三种通过进程的文件名来查找窗口句柄。首先通过进程快照得到要查找的进程ID(ProcessId),其次,再跟据ProcessId获取进程的窗口句柄。以下为本文章的代码:


    uses TLHelp32;

    procedure TForm1.Button1Click(Sender: TObject);
    var
    ProcessName : string; //
    进程名
    FSnapshotHandle:THandle; //
    进程快照句柄
    FProcessEntry32:TProcessEntry32; //
    进程入口的结构体信息
    ContinueLoop:BOOL;
    MyHwnd:THandle;
    begin
    FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); //
    创建一个进程快照
    FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
    ContinueLoop:=Process32First(FSnapshotHandle,FProcessEntry32); //
    得到系统中第一个进程
    //
    循环例举   
    while ContinueLoop do  
    begin
        ProcessName := FProcessEntry32.szExeFile;

        if(ProcessName = '要找的应用程序名.exe') then begin
          MyHwnd := GetHWndByPID(FProcessEntry32.th32ProcessID);
          ...

          ...
        end;
        ContinueLoop:=Process32Next(FSnapshotHandle,FProcessEntry32);
    end;
    CloseHandle(FSnapshotHandle);   //  
    释放快照句柄
    end;


    //
    跟据ProcessId获取进程的窗口句柄

    function TForm1.GetHWndByPID(const hPID: THandle): THandle;
    type
        PEnumInfo = ^TEnumInfo;
        TEnumInfo = record
        ProcessID: DWORD;
        HWND: THandle;
        end;

        function EnumWindowsProc(Wnd: DWORD; var EI: TEnumInfo): Bool; stdcall;
        var
        PID: DWORD;
        begin
        GetWindowThreadProcessID(Wnd, @PID);
        Result := (PID <> EI.ProcessID) or
            (not IsWindowVisible(WND)) or
            (not IsWindowEnabled(WND));

        if not Result then EI.HWND := WND;
        end;

        function FindMainWindow(PID: DWORD): DWORD;
        var
        EI: TEnumInfo;
        begin
        EI.ProcessID := PID;
        EI.HWND := 0;
        EnumWindows(@EnumWindowsProc, Integer(@EI));
        Result := EI.HWND;
        end;
    begin
        if hPID<>0 then
        Result:=FindMainWindow(hPID)
        else
        Result:=0;
    end;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    当光标被另外一个线程掌握时,就无法用GetCursor()应用接口获得光标句柄。本文阐述如何在任何线程掌握光标时都能够获取光标句柄。

     

    =========================================================

     

    {

     当光标被另外一个线程掌握时,就无法用GetCursor()应用接口获得光标句柄。

     本文阐述如何在任何线程掌握光标时都能够获取光标句柄。

     例如,想在屏幕截取程序中放置光标时该如何做。

    }

     

    function GetCursorHandle: HCURSOR;

    var

     hWindow: HWND;

     pt: TPoint;

     pIconInfo: TIconInfo;

     dwThreadID, dwCurrentThreadID: DWord;

    begin

     // 检查哪个窗体掌握光标

     GetCursorPos(pt);

     hWindow := WindowFromPoint(pt);

     

     // 获得光标所有者的线程ID

     dwThreadID := GetWindowThreadPRocessId(hWindow, nil);

     

     // 获得当前线程的ID

     dwCurrentThreadID := GetCurrentThreadId;

     

     // 如果光标所有者的线程不是当前线程,就要把光标所有者的线程配属到当前线程。

     //然后调用GetCursor()来获得正确的光标句柄(hCursor)

     

     if (dwCurrentThreadID <> dwThreadID) then

     begin

        if AttachThreadInput(dwCurrentThreadID, dwThreadID, True) then

        begin

          // 获得光标句柄

          Result := GetCursor;

          AttachThreadInput(dwCurrentThreadID, dwThreadID, False);

        end;

     end else

     begin

        Result := GetCursor;

     end;

    end;

     

    procedure TForm1.Button1Click(Sender: TObject);

    var

     CurPosX, CurPoxY: Integer;

     MyCursor: TIcon;

     pIconInfo: TIconInfo;

    begin

     MyCursor := TIcon.Create;

     try

        MyCursor.Handle := GetCursorHandle;

        // 获得光标位置

        GetIconInfo(MyCursor.Handle, pIconInfo);

        CurPosX := pIconInfo.xHotspot;

        CurPoxY := pIconInfo.yHotspot;

        // 在窗体上画出光标

        Canvas.Draw(CurPoxY, CurPoxY, MyCursor);

     finally

     

    当光标被另外一个线程掌握时,就无法用GetCursor()应用接口获得光标句柄。本文阐述如何在任何线程掌握光标时都能够获取光标句柄。

     

    =========================================================

     

    {

     当光标被另外一个线程掌握时,就无法用GetCursor()应用接口获得光标句柄。

     本文阐述如何在任何线程掌握光标时都能够获取光标句柄。

     例如,想在屏幕截取程序中放置光标时该如何做。

    }

     

    function GetCursorHandle: HCURSOR;

    var

     hWindow: HWND;

     pt: TPoint;

     pIconInfo: TIconInfo;

     dwThreadID, dwCurrentThreadID: DWORD;

    begin

     // 检查哪个窗体掌握光标

     GetCursorPos(pt);

     hWindow := WindowFromPoint(pt);

     

     // 获得光标所有者的线程ID

     dwThreadID := GetWindowThreadProcessId(hWindow, nil);

     

     // 获得当前线程的ID

     dwCurrentThreadID := GetCurrentThreadId;

     

     // 如果光标所有者的线程不是当前线程,就要把光标所有者的线程配属到当前线程。

     //然后调用GetCursor()来获得正确的光标句柄(hCursor)

     

     if (dwCurrentThreadID <> dwThreadID) then

     begin

        if AttachThreadInput(dwCurrentThreadID, dwThreadID, True) then

        begin

          // 获得光标句柄

          Result := GetCursor;

          AttachThreadInput(dwCurrentThreadID, dwThreadID, False);

        end;

     end else

     begin

        Result := GetCursor;

     end;

    end;

     

    procedure TForm1.Button1Click(Sender: TObject);

    var

     CurPosX, CurPoxY: Integer;

     MyCursor: TIcon;

     pIconInfo: TIconInfo;

    begin

     MyCursor := TIcon.Create;

     try

        MyCursor.Handle := GetCursorHandle;

        // 获得光标位置

        GetIconInfo(MyCursor.Handle, pIconInfo);

        CurPosX := pIconInfo.xHotspot;

        CurPoxY := pIconInfo.yHotspot;

        // 在窗体上画出光标

        Canvas.Draw(CurPoxY, CurPoxY, MyCursor);

     finally

        MyCursor.ReleaseHandle;

        MyCursor.Free;

     end;

    end;

     

    // 另外一种解决办法:

     

    procedure TForm1.Timer1Timer(Sender: TObject);

    var

     CI: TCursorInfo;

    begin

     CI.cbSize := SizeOf(CI);

     GetCursorInfo(CI);

     Image1.Picture.Icon.Handle := CI.hCursor;

    end;

     

        MyCursor.ReleaseHandle;

        MyCursor.Free;

     end;

    end;

     

    // 另外一种解决办法:

     

    procedure TForm1.Timer1Timer(Sender: TObject);

    var

     CI: TCursorInfo;

    begin

     CI.cbSize := SizeOf(CI);

     GetCursorInfo(CI);

     Image1.Picture.Icon.Handle := CI.hCursor;

    end;

     

     

     

    资料引用:http://www.knowsky.com/335397.html

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Delphi~通过程序窗体句柄获取程序路径

    引用PsAPI

    var
      h:HWND;
      pid: Cardinal;
      pHandle: THandle;
      buf: array[0..MAX_PATH] of Char;
    begin
      h:=GetForegroundWindow; //
    获取当前激活的窗体句柄
      GetWindowThreadProcessId(h, @pid); //
    通过句柄获取其进程ID
      pHandle := OpenProcess(PROCESS_ALL_ACCESS, False, pid);//
    通过进程ID获取进程句柄
      GetModuleFileNameEx(pHandle, 0, buf, Length(buf));//
    通过进程句柄获取其模块路径
      CloseHandle(pHandle);
      Edit1.Text:= buf;
    end;//
    把它放进一个Timer里,半秒获取一次。。。

     

    //////////////////////////////////////////////////////////////////////////////////////////////////////////

    delphi实现句柄关闭迅雷

    dos命令:
    TASKKILL /F /IM thunder5.exe
    delphi命令:
    var
      H: THandle;
      Process, ProcessId: Cardinal;
    begin
      H := FindWindow('Afx:400000:0:0:0:807b3', nil);
      GetWindowThreadProcessId(H, ProcessId);
      Process := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessId);
      TerminateProcess(Process, 0);
    end;

    方法:
    apy++查找类名 或者用进程快照定位都可以!
    窗口类名:
    Afx:400000:0:0:0:807b3

    效果如图:

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Delphi 关于QQ输入控件无法Spy到句柄的实现方案可行性研究

    2010619日联系商易上海电子商务网站建设,了解更多

     

     


    Delphi
    关于QQ输入控件无法Spy到句柄的实现方案可行性研究

     

     

     

        QQ2009版本的界面,和以前的版本有个显著的不同,就是无法通过Spy++抓到界面上某些元素的句柄了,对于这个技术的实现方案,相信好多人都有一些揣度,实现方法怎样,有人说是应用的DirectUI技术,也有人说是用反Hook,等等一些列的说道!在这,我也说说我的一点看法!我说的一种方法不属于以上的任何一种方法。至于如何,且听我慢慢道来!此思路,来源于一个偶然,在聊天窗口失去焦点与获得焦点时的一个偶然。

     

     聊天的时候,我们要输入信息,首先要让窗口获得焦点!然后输入框也要获得焦点,才能输入。那么我们可以想象一下,在Delphi中什么情况下的控件时没有句柄的,用Delphi的同僚都知道,TGraphicControl继承下来的控件都没有焦点,既然如此,那么咱们就可以有一个混淆视听的方式,写的控件都从TGraphicControl继承来写,那么肯定就没句柄的,这个Button,ScrollBar等不必体现输入的,我相信没有争议,那么我实现一个编辑框Edit,也从TGraphicControl继承来写!这样,别人不就无法找到这个编辑框的句柄了么?嘿嘿,此时一定会有很多人大惑不解,那么输入呢,从TGraphicControl继承的Edit,如何实现输入?难道全部自己模拟消息来实现输入?当然不是,如果这样,那将让工作量增大N倍而不尽然能成功!重点就在这里,这是,我们可以在内部放一个TEdit,本Edit是活动的,在鼠标点下,或者模拟获得焦点的时候,我们将内置的EditParent设置成我们从TGraphicControl继承的EditParent,也就是Edt.parent := self.parent;并且设置内置Edit的区域,然后在内置Edit.setFocus,这样就能够输入了,然后当这个内置Edit失去焦点的时候,我们将内置Edit的显示文字抓成图片,之后,将内置editparent设置为nil,然后在在这个GrphicControlEdit的对应区域绘制上我们抓取出来的那个真实Edit的图片,这样,内置的Edit已经不再本界面上了,从而当外部Spy++Spy的时候,就无法找到那个Edit进而进行信息的获取等操作了!这便是我的实现思路。那么就可以想象,QQ聊天窗口在我们要输入信息的时候,获得焦点了,RichEditparentQQ聊天窗口,然后我们输入信息,当信息输入完成,我们离开了之后,将内部的RichEditparent设置为nil,然后再将RichEdit的画面获得到绘制到原来的位置上去。这样 ,我们就无法SpyRichEdit的句柄了。

     

    下面给出俺的模拟代码:

     

    这个代码中的DxEdit就是了,大家可用Spy查一下,肯定是查不到句柄的说!呵呵!

     

    不过这个只是实现了一个简单的模拟而已,如果要完全达到QQ的那个效果,还有许多其他工作要做,这里仅提供一个实现的思路参考

     

    下载

     

     

     

     

    {不得闲2010-2-25}
    unit
    Unit4;

    interface

    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, StdCtrls;

    type
     TDxEdit =
    class(TGraphicControl)
     
    private
        edt: TEdit;
        edtbndrect: TRect;
        bmp: TBitmap;
        OldEdtwndproc: TWndMethod;
     
    protected
       
    procedure Paint;override;
       
    procedure HookedtWndProc(var msg: TMessage);
       
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
          X, Y: Integer);
    override;
       
    procedure SetParent(AParent: TWinControl);override;
     
    public
       
    constructor Create(AOwner: TComponent);
       
    procedure BeforeDestruction;override;
       
    destructor Destroy;override;
     
    end;
     TForm4 =
    class(TForm)
       
    procedure FormCreate(Sender: TObject);
     
    private
       
    { Private declarations }
     
    public
       
    { Public declarations }
        medt,edt2: TDxEdit;
     
    end;

    var
     Form4: TForm4;
    implementation

    var
     edt: TEdit;
    type
     TWControl =
    class(TWinControl) end;

    procedure GetControlBitmap(Control: TWinControl;bmp: TBitmap);
    var
     ControlWidth,ControlHeight: integer;
     ControlDc,hCaptureDC: HDC;
    begin
     ControlWidth := Control.ClientWidth;
     ControlHeight := Control.ClientHeight;
     ControlDc := GetDC(Control.Handle);
     hCaptureDC := CreateCompatibleDC(ControlDc);
     bmp.Handle :=CreateCompatibleBitmap(ControlDc,ControlWidth,ControlHeight);
     SelectObject(hCaptureDC,bmp.Handle);

     BitBlt(hCaptureDC,
    0,0,ControlWidth,ControlHeight,ControlDc,0,0,SRCCOPY);
     ReleaseDC(GetDesktopWindow,ControlDc);
     DeleteDC(hCaptureDC);
    end;
    {$R *.dfm}

    procedure TForm4.FormCreate(Sender: TObject);
    begin
     medt := TDxEdit.Create(self);
     medt.Parent := self;

     edt2 := TDxEdit.Create(self);
     edt2.Parent := self;
     edt2.Left :=
    150;
     edt2.Top :=
    10;
    end;

    { TDxEdit }

    procedure TDxEdit.BeforeDestruction;
    begin

     
    inherited;
    end;

    constructor TDxEdit.Create(AOwner: TComponent);
    begin
     
    inherited;
     edtbndrect := Rect(
    0,0,0,0);
     bmp := TBitmap.Create;
     Cursor := crIBeam;
     Height :=
    21;
     Width :=
    121;
    end;

    destructor TDxEdit.Destroy;
    begin
     
    inherited;
     bmp.Free;
    end;

    procedure TDxEdit.HookedtWndProc(var msg: TMessage);
    begin
     OldEdtwndproc(msg);
     
    case msg.Msg of
     WM_KILLFOCUS:
       
    begin
          GetControlBitmap(edt,bmp);
          //bmp.SaveToFile(
    "C:\1.bmp");
          edtbndrect.Left :=
    2;
          edtbndrect.Top := (Height - edt.Height)
    div 2;
          edtbndrect.Right := edtbndrect.Left + edt.Width;
          edtbndrect.Bottom := edtbndrect.Top + edt.Height;
          edt.Parent :=
    nil;
       
    end;
     
    end;

    end;

    procedure TDxEdit.MouseDown(Button: TMouseButton; Shift: TShiftState;
          X, Y: Integer);
    begin
     
    inherited;
     
    if Button = mbLeft then
     
    begin
       
    if edt = nil then
       
    begin
          edt := TEdit.Create(
    nil);
          OldEdtwndproc := edt.WindowProc;
          edt.WindowProc := HookedtWndProc;
          edt.BorderStyle := bsNone;
          edt.Height :=
    14;
       
    end;
        edt.Left := Left +
    2;
        edt.Top := top + (Height - edt.Height)
    div 2;
        edt.Width := Width -
    4;
        edt.Parent := self.Parent;
        edt.SetFocus;
        //edt.SelLength :=
    0;
     
    end;
    end;

    procedure TDxEdit.Paint;
    begin
     Canvas.Brush.Color := clWhite;
     Canvas.FillRect(ClientRect);
     Canvas.Brush.Color := clBlue;
     Canvas.FrameRect(ClientRect);
     //然后开始绘制文字
     
    if (edt <> nil) and (edt.Parent = nil) then
     
    begin
        //bmp := TBitmap.Create;
        //GetControlBitmap(edt);
       
    if edtbndrect.Left <> edtbndrect.Right then

        Canvas.CopyRect(edtbndrect,bmp.Canvas,bmp.Canvas.ClipRect);
     
    end;
    end;


    procedure TDxEdit.SetParent(AParent: TWinControl);
    begin
     
    inherited;

    end;

    initialization

    finalization

    end.

     

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    delphi 多种方法查找窗口句柄

    第一种:使用API函数FindWindow
    hw:=FindWindow(nil,PChar('窗口的标题名称'));

    第二种:通过枚举所有窗口,查询特定条件的窗口
    function EnumWindowsProc(Wnd: HWND; Param: Integer): Boolean; stdcall;
    var
    cn : Array[0..255] of char;
    tab : HWND;
    tId : DWORD;
    begin
    Result := TRUE;
    if GetClassName(wnd, cn, 255) > 0 then
    if cn = '#32770' then
    begin
    if (FindWindowEx(wnd, 0, 'Button','新建窗口') <> 0) and
    (FindWindowEx(wnd, 0, 'Button','拨打电话') <> 0) and
    (FindWindowEx(wnd, 0, 'Button','发送(Enter)') <> 0) then
    begin
    tID := GetWindowThreadProcessID(wnd, nil);
    Form1.Memo1.Lines.Add('对话框句柄:'+IntToStr(Wnd));
    Form1.Memo1.Lines.Add('对话框线程ID' + IntToSTr(tID));
    end;
    end;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    EnumWindows(@EnumWindowsProc,0);
    end;

    第三种: 查找字窗口内元素的句柄
    FindWindowEx(wnd, 0, 'Button','拨打电话')

    第四种: 直接使用类似spy++工具软件查询

    //////////////////////////////////////////////////////////////////////////////////////////////////////////

  • 相关阅读:
    数据库范式
    将DBF,XLS,XML,MDB文件导入C#DataGrid的方法
    在类文件中引用Server对象
    在使用了母版页的页面里加载css和js文件
    IIS 7.5 URL重写参数
    hdu Can you solve this equation?
    hdu Dome of Circus
    hdu Bone Collector
    hdu Turn the corner
    hdu 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
  • 原文地址:https://www.cnblogs.com/hssbsw/p/1963940.html
Copyright © 2020-2023  润新知