实现插入BMP图片到RichEdit中? (100分)

  • 主题发起人 主题发起人 nest
  • 开始时间 开始时间
N

nest

Unregistered / Unconfirmed
GUEST, unregistred user!
下面的程序可以实现插入BMP图片到RichEdit中,不过要直接插入BMP文件,不知道要如何改造成直接插入TBitmap变量。
改造的关键把函数OleCreateFromFile改造成OleCreateFromData。
如果能解决,分数加倍!
unit InsRich;
interface
uses
...ActiveX;
const
REO_CP_SELECTION = ULONG(-1);
REO_BELOWBASELINE = $00000002;
REO_RESIZABLE = $00000001;
REO_STATIC = $40000000;
EM_GETOLEINTERFACE = WM_USER + 60;
IID_IUnknown: TGUID = (D1:$00000000;D2:$0000;D3:$0000;D4:($C0,$00,$00,$00,$00,$00,$00,$46));
IID_IOleObject: TGUID = (D1:$00000112;D2:$0000;D3:$0000;D4:($C0,$00,$00,$00,$00,$00,$00,$46));
type
_ReObject = record
cbStruct: DWORD; { Size of structure }
cp: ULONG; { Character position of Object }
clsid: TCLSID; { Class ID of Object }
pOleObj: IOleObject; { Ole Object interface }
pstg: IStorage; { Associated storage interface }
pOleSite: IOleClientSite; { Associated Client Site interface }
sizel: TSize; { Size of Object (may be 0,0) }
dvAspect: Longint; { Display aspect to use }
dwFlags: DWORD; { Object status flags }
dwUser: DWORD; { Dword for user's use }
end;
TReObject = _ReObject;
TCharRange = record {Copy From RichEdit.pas}
cpMin: Integer;
cpMax: Integer;
end;
TFormatRange = record
hdc: Integer;
hdcTarget: Integer;
rectRegion: TRect;
rectPage: TRect;
chrg: TCharRange;
end;
IRichEditOle = interface(System.IUnknown)
['{00020d00-0000-0000-c000-000000000046}']
function GetClientSite(out ClientSite: IOleClientSite): HResult; stdcall;
function GetObjectCount: HResult; stdcall;
function GetLinkCount: HResult; stdcall;
function GetObject(iob: Longint; out ReObject: TReObject; dwFlags: DWORD): HResult; stdcall;
function InsertObject(var ReObject: TReObject): HResult; stdcall;
function ConvertObject(iob: Longint; rclsidNew: TIID;lpstrUserTypeNew: LPCSTR): HResult; stdcall;
function ActivateAs(rclsid: TIID; rclsidAs: TIID): HResult; stdcall;
function SetHostNames(lpstrContainerApp: LPCSTR; lpstrContainerObj: LPCSTR): HResult; stdcall;
function SetLinkAvailable(iob: Longint; fAvailable: BOOL): HResult; stdcall;
function SetDvaspect(iob: Longint; dvaspect: DWORD): HResult; stdcall;
function HandsOffStorage(iob: Longint): HResult; stdcall;
function SaveCompleted(iob: Longint; const stg: IStorage): HResult; stdcall;
function InPlaceDeactivate: HResult; stdcall;
function ContextSensitiveHelp(fEnterMode: BOOL): HResult; stdcall;
function GetClipboardData(var chrg: TCharRange; reco: DWORD; out dataObj: IDataObject): HResult; stdcall;
function ImportDataObject(dataObj: IDataObject; cf: TClipFormat; hMetaPict: HGLOBAL): HResult; stdcall;
end;
function InsertBitmap(Editor: TRxRichEdit; BmpFile: String): Boolean;

implementation

function InsertBitmap(Editor: TRxRichEdit; BmpFile: String): Boolean;
var
FRTF: IRichEditOle;
FOle: IOleObject;
FormatEtc: tagFormatETC;
FStorage: ISTORAGE;
FClientSite: IOleClientSite;
FLockBytes: ILockBytes;
ReObject: TReObject;
xt: TGuid;
FTemp: IUnknown;
begin
Result:=false;
if not FileExists(BmpFile) then Exit;
try
SendMessage(Editor.Handle, em_GetOleInterFace, 0, LongInt(@FRTF));
if not Assigned(FRTF) then Exit;
if CreateILockBytesOnHGlobal(0,true,FLockBytes)<>S_OK then Exit;
if StgCreateDocfileOnILockBytes(FLockBytes,STGM_SHARE_EXCLUSIVE or STGM_CREATE or STGM_READWRITE,0,FStorage)<>S_OK then Exit;
FormatEtc.cfFormat:=0;
FormatEtc.ptd:=nil;
FormatEtc.dwAspect:=DVASPECT_CONTENT;
FormatEtc.lindex:=-1;
FormatEtc.tymed:=TYMED_NULL;
FRTF.GetClientSite(FClientSite);
//从文件中创建一个Ole对象
if OleCreateFromFile(GUID_NULL,PWideChar(WideString(BmpFile)),IID_IUnknown,0,@FormatEtc,FClientSite,FStorage,FOle)<>S_OK then Exit;
FTemp:=FOle;
FTemp.QueryInterface(IID_IOleObject, FOle);
OleSetContainedObject(FOle, true);
ReObject.cbStruct:=SizeOf(TReObject);
FOle.GetUserClassID(xt);
ReObject.clsid:=xt;
ReObject.cp:=ULong(REO_CP_SELECTION);
ReObject.dvaspect:=DVASPECT_CONTENT;
ReObject.dwFlags:=ULogn(REO_STATIC) or ULong(REO_BELOWBASELINE);
ReObject.dwUser:=0;
ReObject.pOleObj:=FOle;
ReObject.pOleSite:=FClientSite;
ReObject.pstg:=FStorage;
ReObject.sizel.cx:=0;
ReObject.sizel.cy:=0;
FRTF.InsertObject(ReObject);
finally
FRTF:=nil;
FOle:=nil;
end;
Result:=true;
end;
 
用rxRichEdit,在rxLib中
 
可能是我表达不是很清除,之所以采用这种方法是因为这样插入的图片不能被更改大小,而其他的方法(比如BmpToRtf、或粘贴到RxRichEdit)插入的图片则可以被鼠标拖动改变大小!
 
用RX,如果是做数据库用IP
 
关于如何在RichEdit中插入图片的技术,目前我掌握的3种方法,但好像只有这种方法所插入的图片不能被改变大小。
对于使用RxRichEdit的,如果能让插入的图片也不能改变大小,则同样算解决我的问题!
请参考:http://www.delphibbs.com/delphibbs/dispq.asp?lid=1421080
 
这种方法插入图片的速度很慢,有明显的停顿感觉
 
to nest
我试了你的代码,可以插入图片,而且,图片也保存到文件里了。但是,我用Delphi带的
RichEdit打开文件时,不能显示图片,但我用WORD打开时却可以。请问这是怎么回事?
如果你能帮我解决用RichEdit显示图片的问题,我愿出300分答谢你。还有,你如有武汉
来,我请你喝酒。:-)
 
做一个能够放图像的RichEdit并不难, 只需要继承一个TRichEdit, 将csAcceptsControls
加入到它的ControlStyle中即可作为Parent容纳其他控件了.

难的是处理文字环绕及滚动时候控件的的位置.

 
以下是我把一幅位图和一些文字都有放在一起的一些语句

var
pic:Trect;
map:Tbitmap;
...
implementation

......
image1.canvas.textout(50,x-50,'字幕标题'); { 列,行,‘内容’}
image1.canvas.font.size:=20;
image1.canvas.font.color:=$120000ff;
pic.topleft.x:=150; //位图的横坐标点
pic.topleft.Y:=tt; //位图的纵坐标点
pic.bottoMright.x:=pic.topleft.x+200; {位图宽}
pic.bottoMright.y:=pic.topleft.y+130; {位图高}
image1.canvas.strEtchdraw(pic,map);
....
image1.Canvas.Brush.Style := bsClear;
//使后背景不受文字破坏(无白色)

pic:=rect(0,0,image1.width,image1.height);
image1.canvas.fillRect(pic);
pic:=rect(-1,-1,1,1);
map:=Tbitmap.create;
map.loadfromFile('c:/windows/Clouds.bmp');
image1.canvas.stretchdraw(pic,map);

 
请问nest找出了不能改变大小的好方法没?

我试过你的方法,虽然不可以该大小,但是双击图片时会打开画板,可以编辑图片。
 
后退
顶部