Images in Editor gadgets!

Share your advanced PureBasic knowledge/code with the community.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Images in Editor gadgets!

Post by srod »

18th Jan 2009.
Just a note to say that if you are streaming text into an editor gadget using CatchRTF() then, in the case of the text being Unicode encoded, you must add the #SF_UNICODE flag to the format parameter (use #SF_TEXT | #SF_UNICODE). In particular, if streaming in text from a string variable, then use these flags if the Unicode compiler switch is set.


Update : 29th Nov 2007.
Have adjusted the CatchRTF() and LoadRTF() functions which now add a second optional parameter in which you specify the format of the stream/file being loaded; #SF_TEXT (default) or #SF_RTF.

See topic : http://www.purebasic.fr/english/viewtop ... 733#220733

Updated code is below.


Bug fix: 30th August 2006.
Code updated 2nd July 2006.
Code updated: 27 March.
2 bugs fixed: 25 March.
Code updated: 24 March.


I've been taking a delve into COM and interfaces and thought that a good start would be to try and load and paste images into an editor gadget.

It turns out to be quite straight forward; for more so than I imagined! :D

The following include file is based on some Powerbasic code I found at
http://www.hellobasic.com/ by Edwin Knoppert which translated very painlessly to Purebasic.

I take no credit for this, but simply used Edwin's code to learn from.

I intend to add to this code somewhat when I get the time. A save as .rtf format will be first.

***Update***
Have added functions:
  • CatchRTF() - Now with optional parameter to replace selection or entire contents.
  • LoadRTF() - Now with optional parameter to replace selection or entire contents.
  • SaveRTF()


Include file

Code: Select all

;Rich edit functions.

;Include basic formatting procedures by 'Freak', 

;IRichEditOleCallback - place images into an editor gadget.
;Based on some Powerbasic code found at http://www.hellobasic.com/ by Edwin Knoppert
;and translated to Purebasic by Stephen Rodriguez.
;Coded in Purebasic 4.

;Enhanced by Nico - July 01 2007.



#STGM_SHARE_EXCLUSIVE=$00000010
#STGM_READWRITE = $00000002
#STGM_CREATE = $00001000

;Future proof!
CompilerIf Defined(ENM_LINK, #PB_Constant)
CompilerElse
  #ENM_LINK = $04000000
CompilerEndIf
CompilerIf Defined(CFM_LINK, #PB_Constant)
CompilerElse
  #CFM_LINK = $00000020
CompilerEndIf
CompilerIf Defined(CFE_LINK, #PB_Constant)
CompilerElse
  #CFE_LINK = $0020
CompilerEndIf
CompilerIf Defined(CFE_SUBSCRIPT, #PB_Constant)
CompilerElse
  #CFE_SUBSCRIPT = $00010000
CompilerEndIf
CompilerIf Defined(CFE_SUPERSCRIPT, #PB_Constant)
CompilerElse
  #CFE_SUPERSCRIPT = $00020000
CompilerEndIf
CompilerIf Defined(CFM_SUBSCRIPT, #PB_Constant)
CompilerElse
  #CFM_SUBSCRIPT = #CFE_SUBSCRIPT | #CFE_SUPERSCRIPT
  #CFM_SUPERSCRIPT=#CFM_SUBSCRIPT
CompilerEndIf
CompilerIf Defined(CFM_BACKCOLOR, #PB_Constant)
CompilerElse
  #CFM_BACKCOLOR =$4000000
CompilerEndIf


;-Declares.
Declare Editor_BackColor(Gadget, Color.l) 
Declare Editor_Color(Gadget, Color.l) 
Declare Editor_Font(Gadget, FontName.s) 
Declare Editor_FontSize(Gadget, Fontsize.l) 
Declare Editor_Format(Gadget, flags, alternate=0)
Declare Editor_Select(Gadget, LineStart.l, CharStart.l, LineEnd.l, CharEnd.l)    
Declare Editor_Bulleted(Gadget)
Declare Editor_JustifyParagraph(Gadget, justify)
Declare Editor_CopyText(gadget) 
Declare Editor_CutText(gadget) 
Declare Editor_InsertText(gadget,Text$) 
Declare Editor_PasteText(gadget) 
Declare.l StreamDataCallback(dwCookie, pbBuff, cb, pcb)
Declare.l StreamFileInCallback(dwCookie, pbBuff, cb, pcb)
Declare.l StreamFileOutCallback(dwCookie, pbBuff, cb, pcb) 

Structure RichEditOle 
   *pIntf.IRicheditOle 
   Refcount.l 
   hwnd.l 
EndStructure 


;The following variable forms the IRichEditOleCallback interface for a rich edit control.
Global NewList RichComObject.RichEditOle()
;The following variable points to the rtf stream when including rtf files.
Global prtf


;-*****USER FUNCTIONS***************************************************************************


;***********************************************************************************************
;The following procedure includes a text or an rtf file from a memory stream.
;Include the file using Include Binary etc.
;Returns zero if no error encountered.
;***********************************************************************************************
Procedure.l CatchRTF(gadget, datastart, dataend, format=#SF_TEXT, replaceall=0) 
  Protected edstr.EDITSTREAM
  prtf = datastart
  edstr\dwCookie = dataend
  edstr\dwError = 0 
  edstr\pfnCallback = @StreamDataCallback() 
  SendMessage_(GadgetID(gadget), #EM_STREAMIN, format|replaceall, edstr) 
  ProcedureReturn edstr\dwError
EndProcedure 
;The following is called repeatedly by Windows to stream data into an editor gadget.
Procedure.l StreamDataCallback(dwCookie, pbBuff, cb, pcb) 
  Protected result
  result = 0 
  If prtf>=dwCookie
    cb = 0 
    result = 1 
  ElseIf prtf+cb>=dwCookie 
    cb = dwCookie-prtf
  EndIf 
  CopyMemory(prtf, pbBuff, cb) 
  prtf+cb 
  PokeL(pcb, cb) 
  ProcedureReturn result 
EndProcedure 


;***********************************************************************************************
;The following procedure loads text or an rtf file into an editor gadget.
;Returns zero if no error encountered.
;***********************************************************************************************
Procedure.l LoadRTF(gadget, filename.s, format=#SF_TEXT, replaceall=0)
  Protected edstr.EDITSTREAM
  edstr\dwCookie = ReadFile(#PB_Any, filename)
  If edstr\dwCookie
    edstr\dwError = 0 
    edstr\pfnCallback = @StreamFileInCallback() 
    SendMessage_(GadgetID(gadget), #EM_STREAMIN, format|replaceall, edstr) 
    CloseFile(edstr\dwCookie)
    ProcedureReturn edstr\dwError
  Else
    ProcedureReturn 1
  EndIf
EndProcedure 
;The following is called repeatedly by Windows to stream data into an editor gadget from an external file.
Procedure.l StreamFileInCallback(dwCookie, pbBuff, cb, pcb) 
  Protected result, length
  result=0
  length=ReadData(dwCookie, pbBuff, cb)
  PokeL(pcb, length) 
  If length = 0
    result = 1
  EndIf
  ProcedureReturn result 
EndProcedure 


;***********************************************************************************************
;The following procedure saves the rtf content of an editor gadget to an external file.
;Returns zero if no error encountered.
;***********************************************************************************************
Procedure.l SaveRTF(gadget, filename.s)
  Protected edstr.EDITSTREAM
  edstr\dwCookie = CreateFile(#PB_Any, filename)
  If edstr\dwCookie
    edstr\dwError = 0 
    edstr\pfnCallback = @StreamFileOutCallback() 
    SendMessage_(GadgetID(gadget), #EM_STREAMOUT, #SF_RTF, edstr) 
    CloseFile(edstr\dwCookie)
    ProcedureReturn edstr\dwError
  Else
    ProcedureReturn 1
  EndIf
EndProcedure
;The following is called repeatedly by Windows to stream data from an editor gadget to an external file.
Procedure.l StreamFileOutCallback(dwCookie, pbBuff, cb, pcb) 
  Protected result, length
  result=0
  WriteData(dwCookie, pbBuff, cb)
  PokeL(pcb, cb) 
  If cb = 0
    result = 1
  EndIf
  ProcedureReturn result 
EndProcedure 

;-----------------------------------------------Character formatting.
Procedure Editor_BackColor(Gadget, Color.l) 
  format.CHARFORMAT2 
  format\cbSize = SizeOf(CHARFORMAT2) 
  format\dwMask = #CFM_BACKCOLOR
  format\crBackColor = Color 
  SendMessage_(GadgetID(Gadget), #EM_SETCHARFORMAT, #SCF_SELECTION, @format) 
EndProcedure

; Set the Text color for the Selection 
; in RGB format 
Procedure Editor_Color(Gadget, Color.l) 
  format.CHARFORMAT2 
  format\cbSize = SizeOf(CHARFORMAT2) 
  format\dwMask = #CFM_COLOR 
  format\crTextColor = Color 
  SendMessage_(GadgetID(Gadget), #EM_SETCHARFORMAT, #SCF_SELECTION, @format) 
EndProcedure 

; Set Font for the Selection 
; You must specify a font name, the font doesn't need 
; to be loaded 
Procedure Editor_Font(Gadget, FontName.s) 
  format.CHARFORMAT2 
  format\cbSize = SizeOf(CHARFORMAT2) 
  format\dwMask = #CFM_FACE 
  PokeS(@format\szFaceName, FontName) 
  SendMessage_(GadgetID(Gadget), #EM_SETCHARFORMAT, #SCF_SELECTION, @format) 
EndProcedure 

; Set Font Size for the Selection 
; in pt 
Procedure Editor_FontSize(Gadget, Fontsize.l) 
  format.CHARFORMAT2 
  format\cbSize = SizeOf(CHARFORMAT2) 
  format\dwMask = #CFM_SIZE 
  format\yHeight = FontSize*20 
  SendMessage_(GadgetID(Gadget), #EM_SETCHARFORMAT, #SCF_SELECTION, @format) 
EndProcedure 

; Set Format of the Selection. This can be a combination of 
; the following values: 
; #CFE_BOLD 
; #CFE_ITALIC 
; #CFE_UNDERLINE 
; #CFE_STRIKEOUT 
; #CFE_LINK
; #CFE_SUBSCRIPT
; #CFE_SUPERSCRIPT
;If the optional parameter 'alternate' is non-zero then the formatting attributes specified in
;'flags' will be xored with those already present within the first character of the selection.
;This has the effect of removing individual attributes if already present.
;E.g. specifying #CFE_BOLD on an already bold selection, will remove the bold formatting etc.
Procedure Editor_Format(Gadget, flags, alternate=0) 
  format.CHARFORMAT2 
  format\cbSize = SizeOf(CHARFORMAT2) 
  If alternate
    SendMessage_(GadgetID(Gadget), #EM_GETCHARFORMAT, 1, @format) 
    flags=format\dwEffects!flags
  EndIf
  format\dwMask = #CFM_ITALIC|#CFM_BOLD|#CFM_STRIKEOUT|#CFM_UNDERLINE|#CFM_LINK|#CFM_SUBSCRIPT|#CFM_SUPERSCRIPT
  format\dwEffects = flags 
  SendMessage_(GadgetID(Gadget), #EM_SETCHARFORMAT, #SCF_SELECTION, @format) 
EndProcedure 

; Selects Text inside an EditorGadget 
; Line numbers range from 0 to CountGadgetItems(#Gadget)-1 
; Char numbers range from 0 to the length of a line 
; Set Line numbers to -1 to indicate the last line, and Char 
; numbers to -1 to indicate the end of a line 
; selecting from 0,1 to -1, -1 selects all. 
Procedure Editor_Select(Gadget, LineStart.l, CharStart.l, LineEnd.l, CharEnd.l)    
  sel.CHARRANGE 
  sel\cpMin = SendMessage_(GadgetID(Gadget), #EM_LINEINDEX, LineStart, 0) + CharStart
  
  If LineEnd = -1 
    LineEnd = SendMessage_(GadgetID(Gadget), #EM_GETLINECOUNT, 0, 0)-1 
  EndIf 
  sel\cpMax = SendMessage_(GadgetID(Gadget), #EM_LINEINDEX, LineEnd, 0) 
  
  If CharEnd = -1 
    sel\cpMax + SendMessage_(GadgetID(Gadget), #EM_LINELENGTH, sel\cpMax, 0) 
  Else 
    sel\cpMax + CharEnd
  EndIf 
  SendMessage_(GadgetID(Gadget), #EM_EXSETSEL, 0, @sel) 
EndProcedure 


;-----------------------------------------------Paragraph formatting.
Procedure Editor_Bulleted(Gadget)
  format.PARAFORMAT
  format\cbSize = SizeOf(PARAFORMAT) 
  format\dwMask = #PFM_NUMBERING	
  format\wnumbering = #PFN_BULLET
  SendMessage_(GadgetID(Gadget), #EM_SETPARAFORMAT, 0, @format) 
EndProcedure

;Set paragraph justification.
;Can be one of the following values:
; #PFA_LEFT	
; #PFA_RIGHT	
; #PFA_CENTER	
Procedure Editor_JustifyParagraph(Gadget, justify)
  format.PARAFORMAT
  format\cbSize = SizeOf(PARAFORMAT) 
  format\dwMask = #PFM_ALIGNMENT
  format\wAlignment = justify
  SendMessage_(GadgetID(Gadget), #EM_SETPARAFORMAT, 0, @format) 
EndProcedure


;-----------------------------------------------Clipboard.
Procedure  Editor_CopyText(gadget) 
 SendMessage_(GadgetID(gadget), #WM_COPY,0,0)    
EndProcedure 

Procedure  Editor_CutText(gadget) 
  SendMessage_(GadgetID(gadget), #WM_CUT,0,0)    
EndProcedure 

Procedure Editor_InsertText(gadget,Text$) 
  ProcedureReturn SendMessage_(GadgetID(gadget),#EM_REPLACESEL,0,Text$) 
EndProcedure 

Procedure  Editor_PasteText(gadget) 
  SendMessage_(GadgetID(gadget), #WM_PASTE,0,0)    
EndProcedure 
;-*****END USER FUNCTIONS***********************************************************************


;***********************************************************************************************
;Implementation procedures for OLE. Most are not actually used but are still needed.
;***********************************************************************************************
;***********************************************************************************************
;Set up the com interface for our rich edit control.
;***********************************************************************************************
Procedure.l RichEdit_SetInterface(hWnd) 
  Protected No_Com.l 

  ForEach RichComObject() 
      If RichComObject()\hwnd=hwnd 
          No_Com=1 
          Break 
      EndIf 
  Next 
    
  If No_Com=0 
   AddElement(RichComObject()) 
   RichComObject()\pIntf = ?VTable 
   RichComObject()\hwnd=hwnd 
   SendMessage_(hWnd, #EM_SETOLECALLBACK, 0, RichComObject()) 
   ProcedureReturn RichComObject() 
  EndIf 
EndProcedure 

Procedure.l RichEdit_QueryInterface(*pObject.RichEditOle, REFIID, *ppvObj.LONG) 
  Protected *pointeur.IRicheditOle 
  *pointeur=*pObject 
  If CompareMemory(REFIID, ?IID_IUnknown, 16)=1 Or CompareMemory(REFIID, ?IID_IRichEditOleCallback, 16)=1 
    Debug "QueryInterface" 
    *ppvObj\l = *pObject 
    *pointeur\AddRef() 
    ProcedureReturn #S_OK 
  Else 
    *ppvObject=0 
    ProcedureReturn #E_NOINTERFACE 
  EndIf 
EndProcedure 

Procedure.l RichEdit_AddRef(*pObject.RichEditOle)
  *pObject\Refcount+1
  ProcedureReturn *pObject\Refcount
EndProcedure

Procedure.l RichEdit_Release(*pObject.RichEditOle)
  *pObject\Refcount-1
  If *pObject\Refcount > 0
    ProcedureReturn *pObject\Refcount
  Else
;Remove entry in the linked list.
    ForEach RichComObject()
      If RichComObject()=*pObject
        DeleteElement(RichComObject()) : Break
      EndIf
    Next
      *pObject=0
  EndIf
EndProcedure

Procedure.l RichEdit_GetInPlaceContext(*pObject.RichEditOle, lplpFrame, lplpDoc, lpFrameInfo)
Debug 1
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure.l RichEdit_ShowContainerUI(*pObject.RichEditOle, fShow)
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure.l RichEdit_QueryInsertObject(*pObject.RichEditOle, lpclsid, lpstg, cp)
    ProcedureReturn #S_OK
EndProcedure

Procedure.l RichEdit_DeleteObject(*pObject.RichEditOle, lpoleobj)
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure.l RichEdit_QueryAcceptData(*pObject.RichEditOle, lpdataobj, lpcfFormat, reco, fReally, hMetaPict)
    ProcedureReturn #S_OK
EndProcedure

Procedure.l RichEdit_ContextSensitiveHelp(*pObject.RichEditOle, fEnterMode)
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure.l RichEdit_GetClipboardData(*pObject.RichEditOle, lpchrg, reco, lplpdataobj)
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure.l RichEdit_GetDragDropEffect(*pObject.RichEditOle, fDrag, grfKeyState, pdwEffect)
;PokeL(pdwEffect,0) ;Uncomment this to prevent dropping to the editor gadget.
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure.l RichEdit_GetContextMenu(*pObject.RichEditOle, seltype.w, lpoleobj, lpchrg, lphmenu)
  ProcedureReturn #E_NOTIMPL
EndProcedure


;The following function does the main work!
Procedure.l RichEdit_GetNewStorage(*pObject.RichEditOle, lplpstg)
  Protected sc, lpLockBytes, t.ILockBytes
;Attempt to create a byte array object which acts as the 'foundation' for the upcoming compound file.
  sc=CreateILockBytesOnHGlobal_(#Null, #True, @lpLockBytes) 
  If sc ;This means that the allocation failed.
    ProcedureReturn sc
  EndIf
;Allocation succeeded so we now attempt to create a compound file storage object.
  sc=StgCreateDocfileOnILockBytes_(lpLockBytes, #STGM_SHARE_EXCLUSIVE|#STGM_READWRITE|#STGM_CREATE, 0, lplpstg)
  t = lpLockBytes
  t\Release()  
EndProcedure
;***********************************************************************************************

 

DataSection
VTable: 
      Data.l @RichEdit_QueryInterface(), @RichEdit_AddRef(), @RichEdit_Release(), @RichEdit_GetNewStorage()
      Data.l @RichEdit_GetInPlaceContext(), @RichEdit_ShowContainerUI(), @RichEdit_QueryInsertObject()
      Data.l @RichEdit_DeleteObject(), @RichEdit_QueryAcceptData(), @RichEdit_ContextSensitiveHelp(), @RichEdit_GetClipboardData()
      Data.l @RichEdit_GetDragDropEffect(), @RichEdit_GetContextMenu()

IID_IRichEditOleCallback: ;" 0x00020D03, 0, 0, 0xC0,0,0,0,0,0,0,0x46" 
Data.l $00020D03 
Data.w $0000,$0000 
Data.b $C0,$00,$00,$00,$00,$00,$00,$46  

IID_IUnknown:   ;"{00000000-0000-0000-C000-000000000046}" 
Data.l $00000000 
Data.w $0000,$0000 
Data.b $C0,$00,$00,$00,$00,$00,$00,$46  

EndDataSection
Regards.
Last edited by srod on Sun Jan 18, 2009 1:38 pm, edited 14 times in total.
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Updated examples to include the new functions added:

Example 1.
The following loads an image directly into multiple editor gadgets.

You can also paste further images etc.

Code: Select all

;**************MUST INCLUDE*****************************************************************
XIncludeFile "OLEedit.pbi"
;*******************************************************************************************

If OpenWindow(0, 0, 0, 600, 400, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) 
    EditorGadget(0, 8, 8, 500, 150) 
    EditorGadget(1, 8, 180, 500, 150) 

;Set up the com interface for the editor gadget.
    RichEdit_SetInterface(GadgetID(0))
    RichEdit_SetInterface(GadgetID(1))

;Load some .rtf content with a simple metafile.
a$ = "{\rtf1\ansi\ansicpg1252\deff0\deflang2057{\fonttbl{\f0\fswiss\fcharset0 Arial;}}"
a$+"{\*\generator Msftedit 5.41.15.1503;}\viewkind4\uc1\pard\f0\fs20{\pict\wmetafile8\picwgoal903\pichgoal825 "
a$+"010009000003e402000008000601000000000400000003010800050000000b0200000000050000"
a$+"000c025e017d01040000002e0118001c000000fb021000070000000000bc020000000001020222"
a$+"53797374656d00017d010000f7a9724500ea120004ee8339706e22000c020000040000002d0100"
a$+"0004000000020101001c000000fb029cff0000000000009001000000000440001254696d657320"
a$+"4e657720526f6d616e0000000000000000000000000000000000040000002d0101000500000009"
a$+"02000000020d000000320a5700fdff01000400fdfffdff7a015b0120d92d00030000001e000700"
a$+"0000fc020000ff0000000000040000002d010200040000000601010008000000fa020500000000"
a$+"00ffffff00040000002d0103000601000024038100bb000300b1000300a80004009f0005009600"
a$+"06008d00080084000a007b000d00730010006b001300630017005b001b00540020004c00240045"
a$+"0029003f002f003800340032003a002c0040002700470022004d001d00540019005b0015006200"
a$+"11006a000e0072000b0079000800810006008a000500920003009a000300a3000200ac000300b4"
a$+"000300bd000500c5000600ce000800d6000b00de000e00e6001100ed001500f5001900fc001d00"
a$+"030122000a01270011012c00170132001d01380023013f00280145002e014c003301540037015b"
a$+"003c01630040016b004401730047017b004a0184004d018d004f01960051019f005201a8005301"
a$+"b1005401bb005401c4005401ce005301d7005201e0005101e9004f01f2004d01fa004a01030147"
a$+"010b014401130140011a013c01220137012901330130012e01370128013d01230143011d014901"
a$+"17014f01110154010a01580103015d01fc006101f5006501ed006801e6006b01de006d01d6006f"
a$+"01ce007101c5007201bd007301b4007301ac007301a30072019a00710192006f018a006d018100"
a$+"6b0179006801720065016a00610162005d015b005801540054014d004f0147004901400043013a"
a$+"003d01340037012f003001290029012400220120001a011b00130117000b01130003011000fa00"
a$+"0d00f2000a00e9000800e0000600d7000500ce000400c4000300bb00030008000000fa02000000"
a$+"00000000000000040000002d010400040000000601010007000000fc020000ffffff0000000400"
a$+"00002d01050008000000fa0200000600000000000000040000002d01060007000000fc02010000"
a$+"0000000000040000002d0107000601000025038100bb000300b1000300a80004009f0005009600"
a$+"06008d00080084000a007b000d00730010006b001300630017005b001b00540020004c00240045"
a$+"0029003f002f003800340032003a002c0040002700470022004d001d00540019005b0015006200"
a$+"11006a000e0072000b0079000800810006008a000500920003009a000300a3000200ac000300b4"
a$+"000300bd000500c5000600ce000800d6000b00de000e00e6001100ed001500f5001900fc001d00"
a$+"030122000a01270011012c00170132001d01380023013f00280145002e014c003301540037015b"
a$+"003c01630040016b004401730047017b004a0184004d018d004f01960051019f005201a8005301"
a$+"b1005401bb005401c4005401ce005301d7005201e0005101e9004f01f2004d01fa004a01030147"
a$+"010b014401130140011a013c01220137012901330130012e01370128013d01230143011d014901"
a$+"17014f01110154010a01580103015d01fc006101f5006501ed006801e6006b01de006d01d6006f"
a$+"01ce007101c5007201bd007301b4007301ac007301a30072019a00710192006f018a006d018100"
a$+"6b0179006801720065016a00610162005d015b005801540054014d004f0147004901400043013a"
a$+"003d01340037012f003001290029012400220120001a011b00130117000b01130003011000fa00"
a$+"0d00f2000a00e9000800e0000600d7000500ce000400c4000300bb000300040000002d01040004"
a$+"0000002d01050004000000f0010600040000002701ffff040000002d010000030000000000"
a$+"}\par"
a$+"}"

SetGadgetText(0,a$)
SetGadgetText(1,a$)
;CatchRTF(GadgetID(0), @a$, @a$+Len(a$),#SFF_SELECTION) 

    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 
EndIf 
End

Last edited by srod on Sun Jul 02, 2006 2:09 pm, edited 4 times in total.
I may look like a mule, but I'm not a complete ass.
jack
Addict
Addict
Posts: 1358
Joined: Fri Apr 25, 2003 11:10 pm

Post by jack »

very interesting, how do you get the image data as in your example?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I drew a circle in MS Word; pasted it into Wordpad (as it seems to streamline the .rtf file somewhat) saved as an rtf file and then loaded as a straight text file.

A bit of a roundabout way I know!
I may look like a mule, but I'm not a complete ass.
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

You genius! :D

I was struggling with this again last night, with no success. Was trying to get a handle on things from some info here:
http://www.vbforums.com/showthread.php? ... ost2131039

I am going to try your code in a couple of hours. But I know you wouldn't post unless you had something going, so .. genius!
@}--`--,-- A rose by any other name ..
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

I couldn't wait. I put some things on hold and tried. It worked! LOL! Happy chappy.

Ack. Now I have to get back to other things when all I really want to do is play with this. :)
@}--`--,-- A rose by any other name ..
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

The thing with the VB code that you've looked at there is that the VB rich text control is already set up to accept images; i.e. the OLE stuff has already been taken care of behind the scenes.

What they're doing is inserting a bitmap from memory into a rich edit control without going via the clipboard. Interesting. I didn't realise it was that easy to convert a bitmap into a Windows metafile.

Think I'll bookmark that. Thanks.
I may look like a mule, but I'm not a complete ass.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

This is nice :) The only possible problem I see concerning the clipboard method is that images and stuff in the clipboard can be erased very fast, before the program could grab it.

Any chance for a link to the VB version that does this from memory?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

My code doesn't use the clipboard. You can simply stream images direct from an rtf source, or indeed from memory as I have with the little example.

What the VB code was getting at (the link is in Dare2's post) was one way of converting a memory bitmap into an rtf stream by first copying to the clipboard etc. It then went on to show another method by first converting to a metafile.
I may look like a mule, but I'm not a complete ass.
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

Sorry about that, his was the one I meant.

The other thing is ... do you have a sample of an Image being placed into the rtf at a certian point?

For example ..

(Psudo code...)

Code: Select all

Temp.l = CreateImage(#PB_ANY, 32, 32)
AddImage(RichTextBox, Temp)
dagcrack
Addict
Addict
Posts: 1868
Joined: Sun Mar 07, 2004 8:47 am
Location: Argentina
Contact:

Post by dagcrack »

Nice!
Any ideal uses for this though? Can't think of anything "cool" right now. But its certainly nice.
! Black holes are where God divided by zero !
My little blog!
(Not for the faint hearted!)
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

Hi Shannara,

Now that srod has cracked this - blows platonic kisses - it appears we can use it much as you use a normal gadget. So to insert an image at the current cursor position (in this case via clipboard):

Code: Select all

#img = 0
#DVASPECT_CONTENT = 1

Define.REPASTESPECIAL clip
LoadImage(#img,pathToYourBmp)
SetClipboardImage (#img)
clip\dwAspect = #DVASPECT_CONTENT
SendMessage_(GadgetID(0),#EM_PASTESPECIAL,#CF_BITMAP,@clip)
Beauty man. Now to look at alignments, etc.
@}--`--,-- A rose by any other name ..
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

dagcrack wrote:Nice!
Any ideal uses for this though? Can't think of anything "cool" right now. But its certainly nice.
I've been needing this for quite some time for an app that I am to write. It will allow for teachers to select maths questions from a large database and create a worksheet. Questions will of course mix text with diagrams etc.
dare2 wrote:Beauty man. Now to look at alignments, etc.
Hey, please post if you crack that one! Alignment is a pain in the arse where rtf is concerned! :D
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

**Update:

Have rewritten the include file so that it makes use of PB4's revamped datasection capabilities. The code is now far more compact and efficient.

Code: Select all

Removed.  Code now in post 1 above.
Last edited by srod on Sat Mar 25, 2006 12:39 am, edited 2 times in total.
I may look like a mule, but I'm not a complete ass.
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

If I do, I sure will, but don't hold your breath. :)

Looking at this: http://support.microsoft.com/kb/146022/EN-US/#kb1 which is VB stuff but says it can make a rich edit control "wysiwyg" by deluding it into thinking it is the printer it prints to.

Or something.

Just started reading it so this might be a bum steer.

Edit: Whup, posted as you did. This was in response to your previous post.
@}--`--,-- A rose by any other name ..
Post Reply