delphi - How to create Picture and HTML formats all together on the clipboard? -
i need create following formats on clipboard:
cf_bitmap
cf_dib
cf_dib5
html format
this console program can create either picture formats or html format, not on clipboard:
program copyimagefromfile; {$apptype console} {$r *.res} uses winapi.windows, vcl.clipbrd, vcl.extctrls, vcl.imaging.pngimage, system.sysutils; function formathtmlclipboardheader(htmltext: string): string; const crlf = #13#10; begin result := 'version:0.9' + crlf; result := result + 'starthtml:-1' + crlf; result := result + 'endhtml:-1' + crlf; result := result + 'startfragment:000081' + crlf; result := result + 'endfragment:°°°°°°' + crlf; result := result + htmltext + crlf; result := stringreplace(result, '°°°°°°', format('%.6d', [length(result)]), []); end; procedure copyhtmlandimagetoclipboard(const str, apngfile: ansistring; const htmlstr: ansistring = ''); var gmem: hglobal; lp: pchar; strings: array[0..1] of ansistring; formats: array[0..1] of uint; i: integer; thisimage: timage; myformat: word; bitmap: tbitmap; adata: thandle; apalette: hpalette; begin gmem := 0; //{$ifndef usevclclipboard} //win32check(openclipboard(0)); //{$endif} clipboard.open; try //most descriptive first per api docs strings[0] := formathtmlclipboardheader(htmlstr); strings[1] := str; formats[0] := registerclipboardformat('html format'); formats[1] := cf_text; {$ifndef usevclclipboard} win32check(emptyclipboard); {$endif} := 0 high(strings) begin if strings[i] = '' continue; //an "1" null terminator gmem := globalalloc(gmem_ddeshare + gmem_moveable, length(strings[i]) + 1); {succeeded, read stream contents memory pointer points at} try win32check(gmem <> 0); lp := globallock(gmem); win32check(lp <> nil); copymemory(lp, pchar(strings[i]), length(strings[i]) + 1); globalunlock(gmem); end; win32check(gmem <> 0); setclipboarddata(formats[i], gmem); win32check(gmem <> 0); gmem := 0; end; thisimage := timage.create(nil); try thisimage.picture.loadfromfile(apngfile); // comment out copy html format: clipboard.assign(thisimage.picture); {myformat := cf_picture; thisimage.picture.savetoclipboardformat(myformat, adata, apalette); clipboard.setashandle(myformat, adata);} thisimage.free; end; //{$ifndef usevclclipboard} //win32check(closeclipboard); //{$endif} clipboard.close; end; end; var html: string; begin try // usage: copyimagefromfile.exe test.png // test.png 32 bit alpha channel if paramcount = 1 begin if fileexists(paramstr(1)) begin if lowercase(extractfileext(paramstr(1))) = '.png' begin html := '<img border="0" src="file:///' + paramstr(1) + '">'; copyhtmlandimagetoclipboard('test', paramstr(1), html); end; end; end; except on e: exception begin writeln(e.classname, ': ', e.message); readln; end; end; end.
so how can create these formats on clipboard?
tclipboard
empties clipboard first time use tclipboard
method put data on clipboard (tclipboard.assign()
, tclipboard.setbuffer()
, tclipboard.setashandle()
, etc) after calling open()
. tclipboard
expects use methods accessing clipboard, use of setclpboarddata()
directly store string data bypassing tclipboard
's internal logic, call assign()
seen first clipboard write , tclipboard
wipes out data stored setclipboarddata()
.
to avoid that, have few choices:
assign()
image clipboard first, save string itemssetclipboarddata()
afterwards.don't use
assign()
@ all. usetpicture.savetoclipboardformat()
directly , callsetclipboarddata()
.don't use
setclipboarddata()
directly unlessusevclclipboard
not defined. usetclipboard.setashandle()
instead.
i suggest #3. let tclipboard
of work:
var cf_html: uint = 0; // tclipboard.setbuffer() allows format , arbitrary buffer // specified , handles global memory allocation. // however, protected, using accessor class reach it. // // tclipboard.astext , tclipboard.settextbuf() use // cf_(unicode)text, , tclipboard.setashandle() requires manual // allocation... // type tclipboardaccess = class(tclipboard) end; procedure copyhtmlandimagetoclipboard(const str, apngfile: ansistring; const htmlstr: ansistring = ''); var tmphtmlstr: ansistring; thisimage: tpicture; begin clipboard.open; try //most descriptive first per api docs tmphtmlstr := formathtmlclipboardheader(htmlstr); tclipboardaccess(clipboard).setbuffer(cf_html, pansichar(tmphtmlstr)^, length(tmphtmlstr) + 1); tclipboardaccess(clipboard).setbuffer(cf_text, pansichar(str)^, length(str) + 1); thisimage := tpicture.create; try thisimage.loadfromfile(apngfile); clipboard.assign(thisimage); thisimage.free; end; clipboard.close; end; end; initialization cf_html := registerclipboardformat('html format');
if need support {$ifndef usevclclipboard}
cannot use tclipboard
@ all, eg:
var cf_html: uint = 0; {$ifdef usevclclipboard} // tclipboard.setbuffer() allows format , arbitrary buffer // specified , handles global memory allocation. // however, protected, using accessor class reach it. // // tclipboard.astext , tclipboard.settextbuf() use // cf_(unicode)text, , tclipboard.setashandle() requires manual // allocation... // type tclipboardaccess = class(tclipboard) end; {$endif} procedure copyhtmlandimagetoclipboard(const str, apngfile: ansistring; const htmlstr: ansistring = ''); var thisimage: tpicture; {$ifndef usevclclipboard} imgdata: thandle; imgformat: word; imgpalette: hpalette; {$endif} procedure setastext(format: uint; const s: ansistring); {$ifndef usevclclipboard} var gmem: hglobal; lp: pansichar; {$endif} begin {$ifdef usevclclipboard} tclipboardaccess(clipboard).setbuffer(format, pansichar(s)^, length(s) + 1); {$else} //an "1" null terminator gmem := globalalloc(gmem_ddeshare + gmem_moveable, length(s) + 1); win32check(gmem <> 0); try {succeeded, read stream contents memory pointer points at} lp := globallock(gmem); win32check(lp <> nil); try copymemory(lp, pansichar(s), length(s) + 1); globalunlock(gmem); end; except globalfree(gmem); raise; end; setclipboarddata(format, gmem); {$endif} end; begin {$ifdef usevclclipboard} clipboard.open; {$else} win32check(openclipboard(0)); {$endif} try //most descriptive first per api docs setastext(cf_html, formathtmlclipboardheader(htmlstr)); setastext(cf_text, str); thisimage := tpicture.create; try thisimage.loadfromfile(apngfile); {$ifdef usevclclipboard} clipboard.assign(thisimage); {$else} imgpalette := 0; thisimage.savetoclipboardformat(imgformat, imgdata, imgpalette); setclipboarddata(imgformat, imgdata); if imgpalette <> 0 setclipboarddata(cf_palette, imgpalette); {$endif} thisimage.free; end; {$ifdef usevclclipboard} clipboard.close; {$else} win32check(closeclipboard); {$endif} end; end; initialization cf_html := registerclipboardformat('html format');
Comments
Post a Comment