【问题标题】:Detecting whether Skype is in "Compact View" or "Default View"检测 Skype 是处于“紧凑视图”还是“默认视图”
【发布时间】:2011-09-26 08:45:16
【问题描述】:

我的应用程序的运行方式由 Skype 的视图模式决定,因为我的应用程序正在寻找 TConversationWindow 类的窗口,如果在默认视图中是 tSkMainForm 的子窗口,如果在紧凑视图中看,它不是tSkMainForm的孩子。

这是我尝试做的:

Function IsCompactView:Boolean;
Var
 Wnd : Hwnd;
Begin
  Result := True;
  Wnd := FindWindow('TConversationForm',nil);

  if Wnd <> 0 then
  begin
   Wnd := GetParent(Wnd);
   // Custom function that grabs the Window Text
   if GetHandleText(Wnd) <> '' then
   Result := False;

  end;

End;

上述函数将通过检查其父级是否有文本来查找顶级(除非我弄错了 - 没有窗口父级的窗口)TConversationForm。如果 Skype 在默认视图中,TConversationFormtSkMainForm 的子代,tSkMainForm 总是有一些文本。它按预期工作。

现在解决实际问题:每当用户在两个视图之间切换时,顶级TConversationForm 不会“刷新”。它们消失得很好,但为了让它再次显示为 tSkMainForm 的子项(因此更改在 Winspector Spy 中可见),您必须在 Skype 中选择它,我不能依赖用户这样做。

如果你不知道,这里是 2 个视图之间的区别:

精简视图

默认视图

如果您需要更多信息,请告诉我,谢谢!

【问题讨论】:

  • +1 因为这可能是您问过的最明确的问题。不错的工作! (不过有一个小小的抱怨:可能应该包含“抓取窗口文本的自定义函数”代码,因为它可能会有所作为。不过,改进了很多。)
  • 我只是好奇,它是什么组件(tskmainform)?你能告诉我吗?
  • @ArionaRian - 我相信这是 Skype 开发的自定义组件。它是 Skype 的主要形式。

标签: delphi hierarchy skype window-handles


【解决方案1】:

不要使用 Windows 方法检测 Skype 是处于“紧凑视图”还是“默认视图”,而是尝试读取 config.xml 文件,该文件存储了这些设置并以“真实-时间”通过Skype。该文件位于

%AppData%\Skype\<your-skype-user-name>

例如在 Windows 7 中,这是位置

C:\Users\<your windows user>\AppData\Roaming\Skype\<your-skype-user-name>

在这个文件中存在一个名为MultiWindowMode的条目

这是MultiWindowMode 的 Xpath 位置

/config/UI/General/MultiWindowMode'

此条目的值为“紧凑视图”的“1”和“默认视图”的“0”

查看这个使用 XPath 解析文件并读取 MultiWindowMode 的值的演示。

{$APPTYPE CONSOLE}

uses
  ComObj,
  ActiveX,
  Variants,
  SysUtils;


function SkypeISCompactView(const SettingsFile : string) : Boolean;
var
   XmlDoc      : OleVariant;
   Node        : OleVariant;
begin
  Result:=False;
   if FileExists(SettingsFile) then
   begin
     XmlDoc       := CreateOleObject('Msxml2.DOMDocument.6.0');
     try
       XmlDoc.Async := False;
       XmlDoc.Load(SettingsFile);
       XmlDoc.SetProperty('SelectionLanguage','XPath');

        if (XmlDoc.parseError.errorCode <> 0) then
         raise Exception.CreateFmt('Error in Xml Data %s',[XmlDoc.parseError]);

       Node  :=XmlDoc.selectSingleNode('/config/UI/General/MultiWindowMode');
       if not VarIsClear(Node) then
        Result:=Node.text='1';
     finally
       XmlDoc:=Unassigned;
     end;
   end;
end;


begin
 try
    CoInitialize(nil);
    try
      Writeln(BoolToStr(SkypeISCompactView('C:\Users\<your windows user>\AppData\Roaming\Skype\<skype user>\config.xml'),True));
    except
      on E:Exception do
      begin
          Writeln(E.Classname, ':', E.Message);
      end;
    end;
 finally
      CoUninitialize;
 end;
 Readln;
end.

【讨论】:

  • +1。有没有你没有答案的任何事情? :) 你甚至包括了 XML 的错误处理。
  • 哇!这更好!我不知道它存放在哪里!太棒了!
  • 然而更正:MultiWindowMode 必须为 1 用于紧凑视图,而不是 0。(因此名称为 MultiWindowMode,哈哈:P)
猜你喜欢
  • 1970-01-01
  • 2017-07-13
  • 1970-01-01
  • 2017-09-12
  • 2021-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-11
相关资源
最近更新 更多