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));