我在服务器端和客户端都放置了Image组件,客户端抓屏(为TBitmap)后与本地的Image组件相连:Image1.Picture.Assign(BitMap);通过GetOlePicture过程转换为IPictureDisp接口传递:GetOlePicture(Image1.Picture, Pic);  Monitor.Set_Picture(Pic);其中Monitor是自动化服务器的接口。当运行到这里的时候就报错:“灾难性故障”百思不得其解,望高手指教!!!
客户端程序:
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, JianShiSrv_TLB, ExtCtrls, StdCtrls, Buttons, AxCtrls, ActiveX;type
  TForm1 = class(TForm)
    Image1: TImage;
    BitBtn1: TBitBtn;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure BitBtn1Click(Sender: TObject);
  private
    { Private declarations }
    Monitor:IJianShi;
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
begin
  Monitor:=CoJianShi.Create;
end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Monitor:=nil;
end;procedure TForm1.BitBtn1Click(Sender: TObject);
var
  DeskWnd, DeskDC:LongWord;
  BitMap:TBitMap;
  Pic:IPictureDisp;
begin
  DeskWnd:=GetDesktopWindow();
  DeskDC:=GetDC(DeskWnd);
  BitMap:=TBitMap.Create;
  try
    BitMap.Width:=Screen.Width;
    BitMap.Height:=Screen.Height;
    Bitblt(BitMap.Canvas.Handle,0,0,Screen.Width,Screen.Height,
           DeskDC,0,0,SRCCOPY);
    Image1.Picture.Assign(BitMap);
    GetOlePicture(Image1.Picture, Pic);
    Monitor.Set_Picture(Pic);
  finally
    BitMap.Free;
    ReleaseDC(DeskWnd,DeskDC);
  end;
end;
end.服务器端:
unit JianShi;{$WARN SYMBOL_PLATFORM OFF}interfaceuses
  ComObj, ActiveX, JianShiSrv_TLB, StdVcl, AxCtrls, Graphics;type
  TJianShi = class(TAutoObject, IJianShi)
  protected
    procedure Set_Picture(const Picture: IPictureDisp); safecall;  end;implementationuses ComServ, MainForm;procedure TJianShi.Set_Picture(const Picture: IPictureDisp);
var
  Pic:TPicture;
begin
  Pic:=TPicture.Create;
  SetOlePicture(Pic, Picture);
  Form1.Image1.Picture.Assign(Pic);
end;initialization
  TAutoObjectFactory.Create(ComServer, TJianShi, Class_JianShi,
    ciMultiInstance, tmApartment);
end.MainForm是主窗口,上边放置了Image组件,没有其他。
请高手指点!!!!!!!!!!!!!!!!!1

解决方案 »

  1.   

    两年前也有一篇类似的文章:http://search.csdn.net/Expert/topic/768/768791.xml?temp=.6832392
      

  2.   

    在微软网站上说了这个问题,因为实现IPicture的对象不能简单的跨进程..
    解决办法是实现自定义Marshal,也就是参数传递的对象要实现IMarshal接口.
    http://support.microsoft.com/kb/150034
    SYMPTOMS
    An automation server that implements a Picture object wrapped by the CPictureHolder class in MFC fails when it attempts to pass a pointer to the picture object's IPictureDisp implementation across process boundaries. 
    CAUSE
    IPictureDisp gains access to methods of the Picture object that cannot be marshaled across process boundaries. For example, IPictureDisp supports DISPID_PICT_RENDER to gain access to the Render method of the Picture object. The Render method takes a handle to a device context as the first parameter. Device context handles cannot be marshaled.Dispatch interfaces can normally be marshalled by using the IDispatch marshaling code, but the Picture object implements IMarshal specifically to cause its marshaling to fail. 
      

  3.   

    谢谢halfdream(哈欠),总算让我明白了很多,那要怎么样通过IMarshal接口来处理呢?有处理过吗?
      

  4.   

    呵.不好意思,没仔细看,我上面说的不大对...DELPHI的SetOlePicture函数,实现是调用了
    OleCreatePictureIndirect创建对象其实微软那文档说的是这种对象它使用了自定义接口技术来防止你跨进程传递它..楼主其实可以想一想,当你跨进程传递IPicture接口指针的时候,你到底是想传递什么:)参数可以改成传递IStream,服务端使用OleLoadPicture从Stream里面取到IStream接口..
      

  5.   

    晕..敲错了...两处.....它使用了自定义Marshal来防止你跨进程传递它..
    ...服务端使用OleLoadPicture从Stream里面取到IPicture接口..
    补充一下,你可以在代码中这样判断出来..
      picAccess:=TPictureAdapter.Create(Image1.Picture);
      picAccess.GetOlePicture(picintf);
      if Supports(picIntf,IMarshal) then
        ShowMessage('oh,this Object Support IMarshal !');
      

  6.   

    恩,明白了很多,多谢halfdream(哈欠),我再结合你的解释看看微软的就明白了很多了!我再重新调试看看!谢谢啦!