What do I need to show images in a richtext control? I need some API calls, but I can't find a concise, task-oriented list of those. Something OLE, right? I don't know, yet, if I want to embed the graphics in the RTF file -- filesize balloons up in a hurry that way -- but I should be able to place and show the image, kind of HTML-like, with some magic API RTF OLE call.... ::)
Hi Jerry!
Maybe this Cbasic code can help.
Can be quickly converted ;)
Cbasic code :
'Insert a bitmap image via the clipboard to a richedit control
'ibasic std code
'by jos de jong, 2007
'code used from Fletchie on how to copy an image to clipboard
'API declarations
DECLARE "user32",GetSysColor(what:INT),INT
DECLARE "user32",OpenClipboard(hwnd:dialog),INT
DECLARE "user32",CloseClipboard(),INT
DECLARE "user32",SetClipboardData(format:INT,handle:INT),INT
DECLARE "user32",EmptyClipboard(),INT
' Predefined Clipboard Formats
CONST CF_TEXT = 1
CONST CF_BITMAP = 2
CONST CF_METAFILEPICT = 3
CONST CF_SYLK = 4
CONST CF_DIF = 5
CONST CF_TIFF = 6
CONST CF_OEMTEXT = 7
CONST CF_DIB = 8
CONST CF_PALETTE = 9
CONST CF_PENDATA = 10
CONST CF_RIFF = 11
CONST CF_WAVE = 12
CONST CF_UNICODETEXT = 13
CONST CF_ENHMETAFILE = 14
CONST CF_OWNERDISPLAY = 0x80
CONST CF_DSPTEXT = 0x81
CONST CF_DSPBITMAP = 0x82
CONST CF_DSPMETAFILEPICT = 0x83
CONST CF_DSPENHMETAFILE = 0x8E
'open a window with a richedit control and a button
DEF w1:DIALOG
DIALOG w1,100,100,700,530,@NOAUTODRAW,0,"Insert bitmap in richedit control",whnd
CONTROL w1,"re,,5,40,680,460,@hscroll | @vscroll | @CTEDITMULTI | @CTEDITAUTOH | @CTEDITAUTOV | @BORDER, 1"
CONTROL w1,"b,Insert image in RichEdit,5,5,180,25,0,2"
DOMODAL w1
'close the program after the window is closed
WAITUNTIL w1=0
END
'___________________________________________________________________________
SUB whnd
'handler for the window w1
SELECT @CLASS
CASE @IDCLOSEWINDOW
'when the user pressed the X button, close the window
CLOSEWINDOW w1
CASE @IDCONTROL
IF @CONTROLID=2
'the button is pressed. insert an image
insertImage()
ENDIF
ENDSELECT
RETURN
'___________________________________________________________________________
SUB insertImage()
'insert a bitmap image in the richedit control
DEF fileName:STRING
DEF img:INT
'ask for an image
fileName = FILEREQUEST("Insert image", w1, 1, "Bitmap images (*.bmp)|*.bmp|All Files|*.*||")
IF fileName<>""
'load the image
img = LOADIMAGE(fileName, @IMGBITMAP)
'open and empty the clipboard
OpenClipBoard(w1)
EmptyClipboard()
'copy the image to the clipboard
SetClipBoardData(CF_BITMAP, img)
CloseClipboard()
'paste the content from the clipboard in the richeditbox
CONTROLCMD w1, 1, @RTPASTE
DELETEIMAGE img, @IMGBITMAP
ENDIF
RETURN
Thanks much, Peter! I'm going to sit down and study this. I can see that it gets an image into the file and the control's display. Next problem is how to handle saving it all. Embedding a graphic in RTF results in a huge file, and reused graphics have to be repeated in full if they are embedded. Maybe I'll just go with the clipboard function for display, and leave the graphics live as separate files, much like an HTML page.
This is as far as I get with the conversion:
'Insert a bitmap image via the clipboard to a richedit control
'ibasic std code
'by jos de jong, 2007
'code used from Fletchie on how to copy an image to clipboard
'API declarations
DECLARE "user32",GetSysColor(what:INT),INT
DECLARE "user32",OpenClipboard(hwnd:dialog),INT
DECLARE "user32",CloseClipboard(),INT
DECLARE "user32",SetClipboardData(format:INT,handle:INT),INT
DECLARE "user32",EmptyClipboard(),INT
' Predefined Clipboard Formats
CONST CF_TEXT = 1
CONST CF_BITMAP = 2
CONST CF_METAFILEPICT = 3
CONST CF_SYLK = 4
CONST CF_DIF = 5
CONST CF_TIFF = 6
CONST CF_OEMTEXT = 7
CONST CF_DIB = 8
CONST CF_PALETTE = 9
CONST CF_PENDATA = 10
CONST CF_RIFF = 11
CONST CF_WAVE = 12
CONST CF_UNICODETEXT = 13
CONST CF_ENHMETAFILE = 14
CONST CF_OWNERDISPLAY = 0x80
CONST CF_DSPTEXT = 0x81
CONST CF_DSPBITMAP = 0x82
CONST CF_DSPMETAFILEPICT = 0x83
CONST CF_DSPENHMETAFILE = 0x8E
'open a window with a richedit control and a button
DEF w1:window
OPENWINDOW w1,100,100,700,530,@NOAUTODRAW,0,"Insert bitmap in richedit control",&whnd
'CONTROL w1,"re,,5,40,680,460,@hscroll | @vscroll | @CTEDITMULTI | @CTEDITAUTOH | @CTEDITAUTOV | @BORDER, 1"
CONTROL w1,@RICHEDIT,"",5,40,680,460,@CTEDITMULTI|@VSCROLL|@CTEDITRETURN,1
CONTROL w1,@SYSBUTTON,"Insert Image",5,5,90,25,0x50000000,2
CONTROL w1,@SYSBUTTON,"Quit",95,5,90,25,0x50000000,3
'CONTROL w1,"b,Insert image in RichEdit,5,5,180,25,0,2"
'close the program after the window is closed
WAITUNTIL w1=0
END
'___________________________________________________________________________
SUB whnd
'handler for the window w1
SELECT @CLASS
CASE @IDCLOSEWINDOW
'when the user pressed the X button, close the window
CLOSEWINDOW w1
CASE @IDCONTROL
SELECT @CONTROLID
CASE 2:'the button is pressed. insert an image
GOSUB insertImage
CASE 3:' Quit
CLOSEWINDOW w1
ENDSELECT
ENDSELECT
RETURN
ENDSUB
'___________________________________________________________________________
SUB insertImage
'insert a bitmap image in the richedit control
DEF fileName:STRING
SUB insertImage
'insert a bitmap image in the richedit control
DEF fileName:STRING
DEF img,clipresult:INT
'ask for an image
fileName = FILEREQUEST("Insert image", w1, 1, "Bitmap images (*.bmp)|*.bmp|All Files|*.*||")
IF fileName<>""
'load the image
img = LOADIMAGE(fileName, @IMGBITMAP)
'open and empty the clipboard
clipresult=OpenClipBoard(w1)
if clipresult=0
messagebox w1, "Unable to open clipboard.","Error"
RETURN
endif
EmptyClipboard()
'copy the image to the clipboard
SetClipBoardData(CF_BITMAP, img)
CloseClipboard()
'paste the content from the clipboard in the richeditbox
CONTROLCMD w1, 1, @RTPASTE
DELETEIMAGE img, @IMGBITMAP
ENDIF
RETURN
ENDSUB
The insertion is not the selected image, but whatever text I most recently put on the clipboard. Am I mishandling the "user32" stuff?
(Edit - added test for opening clipboard) - I'm not opening the clipboard, for some reason related to my lack of experience using API calls.
OpenClipBoard(w1) - you're passing pointer to structure instead window handle, use w1.hwnd instead w1, and change the type to int in the import declaration.
There is no api that will accept a dialog/window structure as a parameter.
Quote from: sapero on February 23, 2008, 07:24:02 AM
OpenClipBoard(w1) - you're passing pointer to structure instead window handle, use w1.hwnd instead w1, and change the type to int in the import declaration.
There is no api that will accept a dialog/window structure as a parameter.
Most of us have to store that somewhere in our head as this is a recurrent mistake we often do. :)
Thank you, Sapero! Lesson #1 in my Assault on API... ::)
(Note to self: A pointer is not the object itself. And an object cannot stand in for a pointer. Data types have meaning!)
Sadly, still not working. I'm running Win XP Pro, if that makes a difference:
'Insert a bitmap image via the clipboard to a richedit control
'ibasic std code
'by jos de jong, 2007
'code used from Fletchie on how to copy an image to clipboard
'API declarations
DECLARE "user32",GetSysColor(what:INT),INT
DECLARE "user32",OpenClipboard(hwnd:INT),INT
DECLARE "user32",CloseClipboard(),INT
DECLARE "user32",SetClipboardData(format:INT,handle:INT),INT
DECLARE "user32",EmptyClipboard(),INT
' Predefined Clipboard Formats
CONST CF_TEXT = 1
CONST CF_BITMAP = 2
CONST CF_METAFILEPICT = 3
CONST CF_SYLK = 4
CONST CF_DIF = 5
CONST CF_TIFF = 6
CONST CF_OEMTEXT = 7
CONST CF_DIB = 8
CONST CF_PALETTE = 9
CONST CF_PENDATA = 10
CONST CF_RIFF = 11
CONST CF_WAVE = 12
CONST CF_UNICODETEXT = 13
CONST CF_ENHMETAFILE = 14
CONST CF_OWNERDISPLAY = 0x80
CONST CF_DSPTEXT = 0x81
CONST CF_DSPBITMAP = 0x82
CONST CF_DSPMETAFILEPICT = 0x83
CONST CF_DSPENHMETAFILE = 0x8E
'open a window with a richedit control and a button
DEF w1:window
OPENWINDOW w1,100,100,700,530,@NOAUTODRAW,0,"Insert bitmap in richedit control",&whnd
'CONTROL w1,"re,,5,40,680,460,@hscroll | @vscroll | @CTEDITMULTI | @CTEDITAUTOH | @CTEDITAUTOV | @BORDER, 1"
CONTROL w1,@RICHEDIT,"",5,40,680,460,@CTEDITMULTI|@VSCROLL|@CTEDITRETURN,1
CONTROL w1,@SYSBUTTON,"Insert Image",5,5,90,25,0x50000000,2
CONTROL w1,@SYSBUTTON,"Quit",95,5,90,25,0x50000000,3
'CONTROL w1,"b,Insert image in RichEdit,5,5,180,25,0,2"
'close the program after the window is closed
WAITUNTIL w1=0
END
'___________________________________________________________________________
SUB whnd
'handler for the window w1
SELECT @CLASS
CASE @IDCLOSEWINDOW
'when the user pressed the X button, close the window
CLOSEWINDOW w1
CASE @IDCONTROL
SELECT @CONTROLID
CASE 2:'the button is pressed. insert an image
GOSUB insertImage
CASE 3:' Quit
CLOSEWINDOW w1
ENDSELECT
ENDSELECT
RETURN
ENDSUB
'___________________________________________________________________________
SUB insertImage
'insert a bitmap image in the richedit control
DEF fileName:STRING
DEF img,clipresult:INT
'ask for an image
fileName = FILEREQUEST("Insert image", w1, 1, "Bitmap images (*.bmp)|*.bmp|All Files|*.*||")
IF fileName<>""
'load the image
img = LOADIMAGE(fileName, @IMGBITMAP)
'open and empty the clipboard
clipresult=OpenClipBoard(w1.hwnd)
if clipresult=0
messagebox w1, "Unable to open clipboard.","Error"
RETURN
endif
EmptyClipboard()
'copy the image to the clipboard
SetClipBoardData(CF_BITMAP, img)
CloseClipboard()
'paste the content from the clipboard in the richeditbox
CONTROLCMD w1, 1, @RTPASTE
DELETEIMAGE img, @IMGBITMAP
ENDIF
RETURN
ENDSUB
I can run IMGVIEW.EBA from the demo files all right. And I do have an "img" handle going into SetClipBoardData, but nothing happens in the richtext control.
The Help file for richtext control says I can "embed OLE objects", presumable like graphics containers or somesuch. However, I don't see anything on what objects are available, or how to embed them in RTF. Can anyone point me to a useful reference?
If I copy a paragraph with an embedded image from a third-party RTF editor, like Angel Writer, and paste it into my EBasic richtext editor, the font-formatted text comes in formatted all right, but the image doesn't come through the Paste operation. Must need something activated in the richtext control that I can't find. ::)
Yes. It needs me to write code to support inlining of images and allocation of the object. Unless you want to try your hand at the COM interfaces ;)
Oh! Um.... Er.... Well.... You're talking to the guy who couldn't figure out how set focus in a dialog, remember.... I'll take the coward's way out, for the moment, and just use a tagged filename in the RTF file, then parse it into HTML for presentation in an embedded browser... or overlay a regular window and draw directly on it like a canvas for presentation... or something else non-COM-ish. ::)
Does Aurora handle images in richtext? I could always learn another language.....
Yes it does. And porting to Emergence will be easy for me to do now that I can use a class to do it.
I see! Well, then, looks like my usually impeccable timing is perfect! I will push ahead on the non-graphic parts of my wondrous project, and see what develops down the road!
Was image handling in richtext ported to EBasic in the recent builds? I may not be poking around in the Help docs in quite the right place.... ::)
No. But thanks for the reminder, I was sidetracked back in Feb and neglected to add it to my todo list. Expect it in 1.7, that part of the library needs a rewrite anyway.
Paul.
Thanks, Paul. I'm revving up my programming imagination, again. ;D