Kaynağa Gözat

Fix Mantis #11783:
* Dispinterfaces can be assigned/typecasted to Variants and vice-versa.
* At the same time, disabled corbainterface assignment compatibility with Variants. Simply intermixing COM and CORBA interfaces is wrong since it causes reference counting calls on CORBA interfaces.
* Dispinterfaces are returned in parameter, similar to regular interfaces.
* Fixed crash in comobj.pp due to incorrect typecast.
* Fixed incorrect dispinterface declarations in the test itself. Now it compiles and works (if MS Excel is installed).

git-svn-id: trunk@16835 -

sergei 14 yıl önce
ebeveyn
işleme
4780278e7b

+ 8 - 4
compiler/defcmp.pas

@@ -156,8 +156,8 @@ implementation
            uvoid,
            u8bit,u16bit,u32bit,u64bit,
            s8bit,s16bit,s32bit,s64bit,
-           bool8bit,bool16bit,bool32bit,bool64bit,
-           uchar,uwidechar }
+           pasbool, bool8bit,bool16bit,bool32bit,bool64bit,
+           uchar,uwidechar,scurrency }
 
       type
         tbasedef=(bvoid,bchar,bint,bbool);
@@ -886,7 +886,9 @@ implementation
                        end;
                      objectdef :
                        begin
-                          if is_interface(def_from) then
+                         { corbainterfaces not accepted, until we have
+                           runtime support for them in Variants (sergei) }
+                          if is_interfacecom_or_dispinterface(def_from) then
                             begin
                                doconv:=tc_interface_2_variant;
                                eq:=te_convert_l1;
@@ -1328,8 +1330,10 @@ implementation
                        eq:=te_convert_l1;
                        doconv:=tc_equal;
                      end
-                   else if (def_from.typ=variantdef) and is_interface(def_to) then
+                   else if (def_from.typ=variantdef) and is_interfacecom_or_dispinterface(def_to) then
                      begin
+                     { corbainterfaces not accepted, until we have
+                       runtime support for them in Variants (sergei) }
                        doconv:=tc_variant_2_interface;
                        eq:=te_convert_l2;
                      end

+ 1 - 1
compiler/paramgr.pas

@@ -163,7 +163,7 @@ implementation
            (def.typ=stringdef) or
            ((def.typ=procvardef) and not tprocvardef(def).is_addressonly) or
            { interfaces are also passed by reference to be compatible with delphi and COM }
-           ((def.typ=objectdef) and (is_object(def) or is_interface(def))) or
+           ((def.typ=objectdef) and (is_object(def) or is_interface(def) or is_dispinterface(def))) or
            (def.typ=variantdef) or
            ((def.typ=setdef) and not is_smallset(def));
       end;

+ 1 - 1
packages/winunits-base/src/comobj.pp

@@ -1385,7 +1385,7 @@ HKCR
                        { Codegen always passes a pointer to variant,
                          *unlike* Delphi which pushes the entire TVarData }
                         Arguments[i]:=PVarData(PPointer(Params)^)^;
-                        inc(PVarData(Params));
+                        inc(PPointer(Params));
                       end;
                     varCurrency,
                     varDouble,

+ 8 - 7
packages/winunits-base/tests/testcom2.pp

@@ -3,7 +3,7 @@
 {$endif FPC}
 program excel;
 
-uses variants,Windows,activeX;
+uses variants,Windows,activeX,comobj;
 
 Const
   IID_IDISPATCH : TGUID = '{00020400-0000-0000-C000-000000000046}';
@@ -13,6 +13,7 @@ Type
   tArguments = array[0..63] of variant;
 
   ExcelRange = dispinterface ['{00020846-0000-0000-C000-000000000046}']
+    property _Default[{optional}RowIndex: OleVariant; {optional} ColumnIndex: OleVariant]: OleVariant dispid 0; default;
     property Value: OleVariant dispid 6;
   end;
 
@@ -24,13 +25,13 @@ Type
   end;
 
   WorkbooksDisp = dispinterface ['{000208DB-0000-0000-C000-000000000046}']
-    function Add(Template: OleVariant; lcid: Integer): ExcelWorkbook; dispid 181;
+    function Add({optional} Template: OleVariant): ExcelWorkbook; dispid 181;
   end;
 
   ExcelApplicationDisp = dispinterface ['{000208D5-0000-0000-C000-000000000046}']
     property ActiveSheet: IDispatch readonly dispid 307;
     property Workbooks: IDispatch readonly dispid 572;
-    property Visible[lcid: Integer]: WordBool dispid 558;
+    property Visible: WordBool dispid 558;
   end;
 
 Function CheckOle(Msg : string;hres : HResult) : HResult;
@@ -64,10 +65,10 @@ begin
   hres := CheckOle('CLSIDFromProgID',CLSIDFromProgID('Excel.Application', aclsid));
   hres := CheckOle('CoCreate',CoCreateInstance(aclsid, Nil, {CLSCTX_INPROC_SERVER or }CLSCTX_LOCAL_SERVER, IID_IDispatch, excelApp));
 
-  ExcelApp.Visible[0] := true;
+  ExcelApp.Visible := true;
   { Following should also be possible as ExcelApp.Workbooks.Add !!}
   WorkBooks := ExcelApp.WorkBooks as WorkBooksDisp;
-  WorkBooks.Add(Null,0);
+  WorkBooks.Add(EmptyParam);
   {
     The following should also work as
       For I:=1 to 5 do
@@ -78,8 +79,8 @@ begin
   For I:=1 to 5 do
     for j:=1 to 5 do
       begin
-//      Cells:=ActiveSheet.Cells[I,J];
-//      Cells.Value:=I+J;
+      Cells:=ActiveSheet.Cells[I,J];
+      Cells.Value:=I+J;
       end;
   // Free everything.
   Cells:=Nil;