sysuintf.inc 4.4 KB

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