We help IT Professionals succeed at work.

more com programming problems.

hulken
hulken asked
on
I have a IHeader Interface

IHeader.Container is IUnknown.

on Each IHeader.Container I put an IPart or an IProduct

How Can I check the type of the container?

I tried :

if Container.QueryInterface('{763EE9CB-4C75-470E-A5D2-27C0FF4B179E}',ThisPart)=0 then
         begin

{'763EE9CB-4C75-470E-A5D2-27C0FF4B179E'} is the GUID of IPart.

How should I do?

Comment
Watch Question

Author

Commented:
My Iheader:

type
  THeader = class(TAutoObject, IHeader)
  private
    fseq_no : string;
    fheader_length : Integer;
    fMsgMainName : string;
    fFromAppl : string;
    fToAppl : string;
    fMsgName : string;
    fMsgVer : string;
    fmetod : string;
    fMetodVersion : string;
    fPriority : string;
    fDataLength : Integer;
    fDataType : string;
    fContainer : OleVariant;

  protected
    function Get_Container: OleVariant; safecall;
    function Get_DataLength: Integer; safecall;
    function Get_DataType: WideString; safecall;
    function Get_FromAppl: WideString; safecall;
    function Get_header_length: Integer; safecall;
    function Get_metod: WideString; safecall;
    function Get_MetodVersion: WideString; safecall;
    function Get_MsgMainName: WideString; safecall;
    function Get_MsgName: WideString; safecall;
    function Get_MsgVer: WideString; safecall;
    function Get_Priority: WideString; safecall;
    function Get_seq_no: WideString; safecall;
    function Get_ToAppl: WideString; safecall;
    procedure Set_Container(Value: OleVariant); safecall;
    procedure Set_DataLength(Value: Integer); safecall;
    procedure Set_DataType(const Value: WideString); safecall;
    procedure Set_FromAppl(const Value: WideString); safecall;
    procedure Set_header_length(Value: Integer); safecall;
    procedure Set_metod(const Value: WideString); safecall;
    procedure Set_MetodVersion(const Value: WideString); safecall;
    procedure Set_MsgMainName(const Value: WideString); safecall;
    procedure Set_MsgName(const Value: WideString); safecall;
    procedure Set_MsgVer(const Value: WideString); safecall;
    procedure Set_Priority(const Value: WideString); safecall;
    procedure Set_seq_no(const Value: WideString); safecall;
    procedure Set_ToAppl(const Value: WideString); safecall;
    { Protected declarations }
  end;

implementation

uses ComServ;
function THeader.Get_Container: OleVariant;
begin
  Result:= fContainer;
end;

function THeader.Get_DataLength: Integer;
begin
  Result:= fDataLength;
end;

function THeader.Get_DataType: WideString;
begin
  Result:= fDataType;
end;

function THeader.Get_FromAppl: WideString;
begin
  Result:= fFromAppl;
end;

function THeader.Get_header_length: Integer;
begin
  Result:= fheader_length;
end;

function THeader.Get_metod: WideString;
begin
  Result:= fmetod;
end;

function THeader.Get_MetodVersion: WideString;
begin
  Result:= fMetodVersion;
end;

function THeader.Get_MsgMainName: WideString;
begin
  Result:= fMsgMainName;
end;

function THeader.Get_MsgName: WideString;
begin
  Result:=  fMsgName;
end;

function THeader.Get_MsgVer: WideString;
begin
  Result:=  fMsgVer;
end;

function THeader.Get_Priority: WideString;
begin
  Result:= fPriority;
end;

function THeader.Get_seq_no: WideString;
begin
  Result:= fseq_no;
end;

function THeader.Get_ToAppl: WideString;
begin
  Result:= fToAppl;
end;

procedure THeader.Set_Container(Value: OleVariant);
begin
  fContainer:= Value;
end;

procedure THeader.Set_DataLength(Value: Integer);
begin
  fDataLength:= Value;
end;

procedure THeader.Set_DataType(const Value: WideString);
begin
  fDataType:= Value;
end;

procedure THeader.Set_FromAppl(const Value: WideString);
begin
  fFromAppl:= Value;
end;

procedure THeader.Set_header_length(Value: Integer);
begin
  fheader_length:= Value;
end;

procedure THeader.Set_metod(const Value: WideString);
begin
  fmetod:= Value;
end;

procedure THeader.Set_MetodVersion(const Value: WideString);
begin
  fMetodVersion:= Value;
end;

procedure THeader.Set_MsgMainName(const Value: WideString);
begin
  fMsgMainName:= Value;
end;

procedure THeader.Set_MsgName(const Value: WideString);
begin
  fMsgName:= Value;
end;

procedure THeader.Set_MsgVer(const Value: WideString);
begin
  fMsgVer:= Value;
end;

procedure THeader.Set_Priority(const Value: WideString);
begin
  fPriority:= Value;
end;

procedure THeader.Set_seq_no(const Value: WideString);
begin
  fseq_no:= Value;
end;

procedure THeader.Set_ToAppl(const Value: WideString);
begin
  fToAppl:= Value;
end;

const IID_IPart: TGUID = '{763EE9CB-4C75-470E-A5D2-27C0FF4B179E}';

if Suceeded(Container.QueryInterface(IID_IPart, ThisPart))then begin
  // do your stuff
  ThisPart:=nil; // free the intf.
end else begin
  // ...
end;

if you need some GUID checking then use IsEqualGUID, IsEqualIID (the same function)
why the're no repair/edit in this 'forum' ?
Suceeded is actually Succeeded :)

Author

Commented:
I can't get this to work with my IHeader and IPart abowe.

When I run this I get an OLeSysError:

"Member Not Found"

I Know that the Iheader.Container contains an IPart in this case so....

Is there something wrong with my IHeader object abowe? or what can be wrong?

Author

Commented:
if Succeeded(Container.QueryInterface(IID_IPart, ThisPart))then

gives me an compiler error:

Type not allowed in OleAutomation Call.

Commented:
You could always let the compiler do the interface querying, you just use is / as:

if header.Container is IPart then
begin
  ...
end
else if header.Container is IProduct then
begin
  ...
end;



OR you could use



try
  part := header.Container as IPart;
except
  try
    product := header.Container as IProduct;
  except
    raise;  //both failed
  end;
end;



OR you could use



try
  part := IPart(header.Container);
except
  try
    product := IProduct(header.Container);
  except
    raise;  //both failed
  end;
end;
Software Engineer, Advisory
CERTIFIED EXPERT
Top Expert 2005
Commented:

Hulken,

All looks good from what you have done. You said that the container is holding the IUnknown (for either an IPart or IProduct), which it would have to because that's what IPart and IProduct have in common. The one thing you have to remember is that the container in your delphi type is defined as OleVariant, so the query interface call would look like


var ppart: IPart;
    hret:  HRESULT;

hret:=IUnknown(Container).QueryInterface(IID_IPart, ppart);
if (hret = S_OK) then
begin
  // Do work
  ppart:=nil; // free/release the interface
end;

or

if Succeeded(IUnknown(Container).QueryInterface(IID_IPart, ppart)) then
begin


end;

The type cast should correct the "Type not allowed in blah blah error"

Russell

Author

Commented:
THenks for makeing things clearer to me.

Explore More ContentExplore courses, solutions, and other research materials related to this topic.