sysuintf.inc 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. {
  2. *********************************************************************
  3. Copyright (C) 2002 Peter Vreman,
  4. member of the Free Pascal Development Team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. *********************************************************************
  11. }
  12. function Supports(const Instance: IInterface; const AClass: TClass; out Obj): Boolean;
  13. begin
  14. Result := (Instance<>nil) and (Instance.QueryInterface(IObjectInstance,Obj)=S_OK) and (TObject(Obj).InheritsFrom(AClass));
  15. end;
  16. function Supports(const Instance: IInterface; const IID: TGUID; out Intf): Boolean;
  17. begin
  18. Result:=(Instance<>nil) and (Instance.QueryInterface(IID,Intf)=S_OK);
  19. end;
  20. function Supports(const Instance: TObject; const IID: TGUID; out Intf): Boolean;
  21. var
  22. Temp: Pointer; // weak
  23. begin
  24. Result:=(Instance<>nil) and ((Instance.GetInterfaceWeak(IInterface,Temp) and (IInterface(Temp).QueryInterface(IID,Intf)=S_OK))
  25. or Instance.GetInterface(IID,Intf));
  26. { Some applications expect that the QueryInterface method is invoked as first priority
  27. to query for an interface and GetInterface as 2nd priority }
  28. end;
  29. function Supports(const Instance: TObject; const IID: Shortstring; out Intf): Boolean;
  30. begin
  31. Result:=(Instance<>nil) and Instance.GetInterface(IID,Intf);
  32. end;
  33. function Supports(const Instance: IInterface; const AClass: TClass): Boolean;
  34. var
  35. Temp: TObject;
  36. begin
  37. Result:=Supports(Instance,AClass,Temp);
  38. end;
  39. function Supports(const Instance: IInterface; const IID: TGUID): Boolean;
  40. var
  41. Temp: IInterface;
  42. begin
  43. Result:=Supports(Instance,IID,Temp);
  44. end;
  45. function Supports(const Instance: TObject; const IID: TGUID): Boolean;
  46. var
  47. Temp: IInterface;
  48. begin
  49. Result:=Supports(Instance,IID,Temp);
  50. end;
  51. function Supports(const Instance: TObject; const IID: Shortstring): Boolean;
  52. begin
  53. Result:=(Instance<>nil) and (Instance.GetInterfaceEntryByStr(IID)<>nil);
  54. end;
  55. function Supports(const AClass: TClass; const IID: TGUID): Boolean;
  56. begin
  57. Result:=(AClass<>nil) and (AClass.GetInterfaceEntry(IID)<>nil);
  58. end;
  59. function Supports(const AClass: TClass; const IID: Shortstring): Boolean;
  60. begin
  61. Result:=(AClass<>nil) and (AClass.GetInterfaceEntryByStr(IID)<>nil);
  62. end;
  63. function StringToGUID(const S: string): TGUID;
  64. begin
  65. if not TryStringToGUID(S, Result) then
  66. raise EConvertError.CreateFmt(SInvalidGUID, [S]);
  67. end;
  68. function TryStringToGUID(const S: string; out Guid: TGUID): Boolean;
  69. var
  70. e: Boolean;
  71. p: PChar;
  72. function rb: Byte;
  73. begin
  74. case p^ of
  75. '0'..'9': Result := Byte(p^) - Byte('0');
  76. 'a'..'f': Result := Byte(p^) - Byte('a') + 10;
  77. 'A'..'F': Result := Byte(p^) - Byte('A') + 10;
  78. else e := False;
  79. end;
  80. Inc(p);
  81. end;
  82. procedure nextChar(c: Char); inline;
  83. begin
  84. if p^ <> c then
  85. e := False;
  86. Inc(p);
  87. end;
  88. begin
  89. if Length(S)<>38 then Exit(False);
  90. e := True;
  91. p := PChar(S);
  92. nextChar('{');
  93. Guid.D1 := rb shl 28 or rb shl 24 or rb shl 20 or rb shl 16 or rb shl 12 or rb shl 8 or rb shl 4 or rb;
  94. nextChar('-');
  95. Guid.D2 := rb shl 12 or rb shl 8 or rb shl 4 or rb;
  96. nextChar('-');
  97. Guid.D3 := rb shl 12 or rb shl 8 or rb shl 4 or rb;
  98. nextChar('-');
  99. Guid.D4[0] := rb shl 4 or rb;
  100. Guid.D4[1] := rb shl 4 or rb;
  101. nextChar('-');
  102. Guid.D4[2] := rb shl 4 or rb;
  103. Guid.D4[3] := rb shl 4 or rb;
  104. Guid.D4[4] := rb shl 4 or rb;
  105. Guid.D4[5] := rb shl 4 or rb;
  106. Guid.D4[6] := rb shl 4 or rb;
  107. Guid.D4[7] := rb shl 4 or rb;
  108. nextChar('}');
  109. Result := e;
  110. end;
  111. function IsEqualGUID(const guid1, guid2: TGUID): Boolean;
  112. var
  113. a1,a2: PIntegerArray;
  114. begin
  115. a1:=PIntegerArray(@guid1);
  116. a2:=PIntegerArray(@guid2);
  117. Result:=(a1^[0]=a2^[0]) and
  118. (a1^[1]=a2^[1]) and
  119. (a1^[2]=a2^[2]) and
  120. (a1^[3]=a2^[3]);
  121. end;
  122. function GuidCase(const GUID: TGUID; const List: array of TGuid): Integer;
  123. begin
  124. for Result := High(List) downto 0 do
  125. if IsEqualGUID(GUID, List[Result]) then
  126. Exit;
  127. Result := -1;
  128. end;
  129. function GUIDToString(const GUID: TGUID): string;
  130. begin
  131. SetLength(Result, 38);
  132. StrLFmt(PChar(Result), 38,'{%.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x}',
  133. [
  134. Longint(GUID.D1), GUID.D2, GUID.D3,
  135. GUID.D4[0], GUID.D4[1], GUID.D4[2], GUID.D4[3],
  136. GUID.D4[4], GUID.D4[5], GUID.D4[6], GUID.D4[7]
  137. ]);
  138. end;