在 Delphi 中,通过使用 Skype API,我可以相当容易地向联系人发送消息。但是,我想做的是在当前关注的联系人的聊天框中输入消息,而不发送消息。
通过使用Winspector,我发现Chatbox的Classname是TChatRichEdit,它放在一个TChatEntryControl上,它放在一个TConversationForm上,最后放在tSkMainForm上。(显然 Skype 客户端是用 Delphi 编码的;))
通过使用 Win API,如何找到正确的tSkMainForm>TConversationForm>TChatEntryControl>TChatRichEdit,然后在其中输入消息?
解决此问题的最佳方法是什么?
此外,TConversationForm 还包含联系人的姓名,所以我想这会更容易一些吗?
编辑:这是 Windspector Spy 的屏幕截图,显示了 TChatRichEdit:
这是我当前的代码:
function GetConversationWindow(Wnd: HWnd; P: LParam): Bool; stdcall;
var
Param: PGetConversationParam;
ProcID: DWord;
// WndClass docs say maximum class-name length is 256.
ClassName: array[0..256] of Char;
WindowTitle: array[0..256] of Char;
begin
Result := True; // assume it doesn't match; keep searching
Param := PGetConversationParam(P);
GetWindowThreadProcessID(Wnd, @ProcID);
if ProcID <> Param.ProcID then
Exit;
if GetClassName(Wnd, ClassName, Length(ClassName)) = 0 then
Exit;
if StrComp(ClassName, 'TConversationForm') <> 0 then
Exit;
if SendMessage(Wnd, wm_GetText, Length(WindowTitle), LParam(@WindowTitle[0])) = 0 then
Exit;
if Param.ContactName = WindowTitle then begin
Param.Result := Wnd;
Result := False;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Param: TGetConversationParam;
RichEditWnd, ControlWnd : HWND;
ParentWnd : HWND;
begin
//Param.ProcID := GetSkypeProcessID;
Param.ContactName := 'xSky Admin';
ParentWnd := FindWindowEx(0,0,'tSkMainForm',nil);
if EnumChildWindows(ParentWnd,@GetConversationWindow, LParam(@Param)) then
Abort; // Didn't find it.
// Param.Result holds the conversation window's handle. Now walk its children.
ControlWnd := FindWindowEx(Param.Result, 0, 'TChatEntryControl', nil);
if ControlWnd = 0 then
Abort; // Conversation doesn't have an entry control
RichEditWnd := FindWindowEx(ControlWnd, 0, 'TChatRichEdit', nil);
if RichEditWnd = 0 then
Abort;
ShowMessage('Got it!');
end;
我从来没有到达 ShowMessage。
这是我的 IDE 在调试模式下的屏幕截图:
我在 Abort Line 添加了一个断点。
有任何想法吗?