问题
The way my application functions, is determined by Skype's view mode, due to the fact that my application is looking for windows of class TConversationWindow
, which if in Default View is a child of tSkMainForm
, and if in Compact View, it is not a child of tSkMainForm
.
Here is what I tried to do:
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;
The above function will look for top-level (unless I am mistaken - the windows with no window parent) TConversationForm
's, by checking if their parent has text or not. If Skype is in Default View, the TConversationForm
's are children of tSkMainForm
, which always has some text. It works as it is supposed to.
Now for the actual problem: Whenever the user switches between the 2 views, the top-level TConversationForm
's are not "refreshed". They disappear alright, but in order for it to appear as a child of tSkMainForm
again (so the change is visible in Winspector Spy), you have to select it in Skype, and I cannot rely on the user to do that.
In case you dont know, here is the difference between the 2 views:
Compact View
Default View
If you need more info please let me know, thanks!
回答1:
Instead of detect if Skype is in “Compact View” or “Default View” using a windows approach try reading the config.xml file which store these kind of settings and is updated in "real-time" by skype. This file is located in
%AppData%\Skype\<your-skype-user-name>
for example in windows 7 this is the location
C:\Users\<your windows user>\AppData\Roaming\Skype\<your-skype-user-name>
Inside of this file in the exist a entry called MultiWindowMode
This is the Xpath location of the MultiWindowMode
/config/UI/General/MultiWindowMode'
The value of this entry is '1' for “Compact View” and '0' for “Default View”
Check this demo which uses XPath to parse the file and read the value of the 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.
来源:https://stackoverflow.com/questions/6541629/detecting-whether-skype-is-in-compact-view-or-default-view