delphi 获取有输入焦点的活动窗口进行模拟输入文本

var
 wintext: array[0..MAXBYTE] of Char;
 WdChar:  array of Char;
 focuswhd: THandle;
 processId: Pointer;
 threadid: Cardinal;
 GUITHREADINFO:TGUIThreadInfo;
 cp: TPoint;
 str:string;
 i:integer;
begin
 //https://learn.microsoft.com/zh-cn/windows/win32/api/winuser/ns-winuser-guithreadinfo
 threadid := GetWindowThreadProcessId(0, nil); //0获取当前最顶级的那个窗口
 GUITHREADINFO.cbSize := SizeOf(GUITHREADINFO);
 if GetGUIThreadInfo(threadid, GUITHREADINFO) then
 begin
  if GUITHREADINFO.hwndCaret > 0 then
  begin
   if GUITHREADINFO.flags = GUI_CARETBLINKING then //当 flags == 1 时,说明当前窗口中有闪烁的插入符,也就说明当前系统具有输入焦点,处于可输入状态。
   begin
    if not AttachThreadInput(threadid,GetCurrentThreadId,True) then //共享线程,不然取不到光标输入位置处的句柄
     mmo1.Lines.Add('AttachThreadInput失败');
    mmo1.Clear;
    FillChar(wintext,SizeOf(wintext),#0);
    GetWindowText(GUITHREADINFO.hwndActive,wintext, MAXBYTE);
    mmo1.Lines.Add('线程中活动窗口的句柄:'+IntToStr(GUITHREADINFO.hwndActive)+' text:'+wintext);
    FillChar(wintext,SizeOf(wintext),#0);
    GetWindowText(GUITHREADINFO.hwndFocus,wintext, MAXBYTE);
    mmo1.Lines.Add('具有键盘焦点的窗口的句柄:'+IntToStr(GUITHREADINFO.hwndFocus)+' text:'+wintext);
    FillChar(wintext,SizeOf(wintext),#0);
    GetWindowText(GUITHREADINFO.hwndCaret,wintext, MAXBYTE);
    mmo1.Lines.Add('显示插入点的窗口的句柄:'+IntToStr(GUITHREADINFO.hwndCaret)+' text:'+wintext);
    mmo1.Lines.Add('rect:'+Format('left:%d,top:%d,right:%d,Bottom:%d, Topleft:%d,%d,BottomRight:%d,%d',
             [GUITHREADINFO.rcCaret.Left,GUITHREADINFO.rcCaret.Top,GUITHREADINFO.rcCaret.Right,GUITHREADINFO.rcCaret.Bottom,
             GUITHREADINFO.rcCaret.TopLeft.X,GUITHREADINFO.rcCaret.TopLeft.Y,
             GUITHREADINFO.rcCaret.BottomRight.X,GUITHREADINFO.rcCaret.BottomRight.Y]));
    mmo1.Lines.Add(Format('光标位置:%d,%d',[GUITHREADINFO.rcCaret.Left,GUITHREADINFO.rcCaret.Top]));

    if GetCaretPos(cp) then
     mmo1.Lines.Add(Format('GetCaretPos:光标位置:%d,%d',[cp.X,cp.Y]));
     if GetCursorPos(cp) then
     mmo1.Lines.Add(Format('GetCursorPos:光标位置:%d,%d',[cp.X,cp.Y]));
//    str := wintext+'程序插入的'; //这种方式光标位置不正确  需要处理光标位置,速度太快可能会闪烁
//    SendMessage(GUITHREADINFO.hwndCaret, WM_SETTEXT, 0, LPARAM(str));
 // 用复制的方式  最好是先保存一下当前剪切板的内容后面再还原回去
//    Clipboard.AsText := '程序插入';
//    PostMessage(GUITHREADINFO.hwndCaret,WM_PASTE,0,0);
//    Clipboard.AsText := '';
    //这种方式则不用处理光标
    str := '123中文abcd';
    SetLength(wdchar, Length(str));
    StrPCopy(PAnsiChar(WdChar), str);
    for i := Low(wdchar) to High(wdchar) do
     PostMessage(GUITHREADINFO.hwndCaret, WM_CHAR, Ord(wdchar[i]) ,0);
//    PostMessage(GUITHREADINFO.hwndCaret, WM_CHAR, Ord(wdchar[1]) ,0);
   end;
  end
  else
   mmo1.Lines.Add('没有存在输入状态的窗口');
 end
 else
  mmo1.Lines.Add(SysErrorMessage(GetLastError));

 

posted @ 2023-03-04 18:03  Tag  阅读(170)  评论(0)    收藏  举报