Mettre une image Bitmap dans un éditeur

Partagez votre expérience de PureBasic avec les autres utilisateurs.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Mettre une image Bitmap dans un éditeur

Message par nico »

Ce code à été réalisé à partir d'une source microsoft:
http://support.microsoft.com/default.as ... -us;220844

Vous avez la possibilité de sauvegarder le tout en rtf et surtout de le charger, voir le code sur le Forum Anglais.
http://www.purebasic.fr/english/viewtop ... mreadwrite

Si vous double cliquer sur l'image, vous éditer alors cette même image automatiquement dans Paint!

Code : Tout sélectionner

; Insérer une image Bitmap dans un éditeur à partir d'un fichier
; Version PureBasic 4.10

#CLSID_NULL=0
#STGM_SHARE_EXCLUSIVE=$00000010
#STGM_READWRITE = $00000002
#STGM_CREATE = $00001000 
#REO_CP_SELECTION=$FFFFFFFF
#REO_RESIZABLE=1
#REO_BELOWBASELINE=2
#OLERENDER_DRAW=1

Global RichEditOleObject.IRichEditOle
Global lpStorage.IStorage,lpObject.IOleObject,lpClientSite.IOleClientSite

Prototype.l CreateFromFile(a.l, FileName.p-bstr, b.l, c.l, d.l, e.l, f.l, g.l)

Procedure.l FileToOLE(FileName.s,Rich_Edit_ID.l)
  
  SendMessage_(GadgetID(Rich_Edit_ID), #EM_GETOLEINTERFACE, 0, @RichEditOleObject.IRichEditOle)
  
  If RichEditOleObject
    
    lpLockBytes.ILockBytes
    cfFormat = 0
    lpFormatEtc.FORMATETC
    clsid.CLSID
    
    CopyMemory(?IID_NULL,@clsid,16)
    
    sc = CreateILockBytesOnHGlobal_(#Null, #True, @lpLockBytes)
    If sc = #S_OK
      sc =StgCreateDocfileOnILockBytes_(lpLockBytes,#STGM_SHARE_EXCLUSIVE|#STGM_CREATE|#STGM_READWRITE, 0, @lpStorage)
      
      If sc = #S_OK
        lpLockBytes\Release()
      Else
        ProcedureReturn #False 
      EndIf 
    Else
      ProcedureReturn #False 
    EndIf 
    
    ;// fill in FORMATETC struct
    lpFormatEtc\cfFormat = 0
    lpFormatEtc\ptd = #Null
    lpFormatEtc\dwAspect = #DVASPECT_CONTENT
    lpFormatEtc\lindex = -1
    lpFormatEtc\tymed = #TYMED_NULL
    
    ;// attempt To create the object
    RichEditOleObject\GetClientSite(@lpClientSite)
    
    If OpenLibrary(0, "ole32.dll")
      CreateFromFile.CreateFromFile = GetFunction(0, "OleCreateFromFile")   
      sc = CreateFromFile( clsid, FileName, ?IID_IUnknown, #OLERENDER_DRAW, lpFormatEtc, lpClientSite, lpStorage, @lpObject)
      CloseLibrary(0)
    EndIf 
    
    Debug sc
    ; je devrais avoir 0 mais on a 48 ?
    
    
    ;// lpObject is currently an IUnknown, convert To IOleObject
    If lpObject<> #Null
      lpUnk.IUnknown = lpObject
      lpUnk\QueryInterface(?IID_IOleObject, @lpObject)
      lpUnk\Release()
    	EndIf 
      
    	;// all items are "contained" -- this makes our reference To this object
    	;//  weak -- which is needed For links To embedding silent update.
    	OleSetContainedObject_(lpObject, #True)
      
	    reobject.REOBJECT
    	ZeroMemory_(@reobject, SizeOf(REOBJECT))
    	reobject\cbStruct = SizeOf(REOBJECT)
      
    	sc = lpObject\GetUserClassID(clsid.CLSID)
    	Debug sc
      
    	CopyMemory(@clsid,@reobject\clsid,16)
      
    	reobject\cp = #REO_CP_SELECTION
    	reobject\dvaspect = #DVASPECT_CONTENT
    	reobject\dwFlags = #REO_RESIZABLE | #REO_BELOWBASELINE
    	reobject\dwUser = 0
    	reobject\poleobj = lpObject
      
    	reobject\polesite = lpClientSite
      
    	reobject\pstg = lpStorage
      
    	reobject\sizel\cx=0
    	reobject\sizel\cy=0
    	
    	RichEditOleObject\InsertObject(reobject)
    	
    	If lpObject
      lpObject\Release()
      lpObject = #Null
    	EndIf 
    	
    	If lpStorage
      lpStorage\Release()
      lpStorage = #Null
    	EndIf 
    	
    	If lpClientSite
      lpClientSite\Release()
      lpClientSite = #Null
    EndIf 
    
    If RichEditOleObject
      RichEditOleObject\Release()
      RichEditOleObject = #Null
    EndIf
    
    ProcedureReturn #True 
  EndIf 
EndProcedure 

Enumeration
  #GADGET_Editor 
EndEnumeration

If OpenWindow(0, 0, 0, 500, 440, "RichEdit", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  CreateGadgetList(WindowID(0))
  
  EditorGadget(#GADGET_Editor, 10, 10, 480, 380)
  ButtonGadget(1, 10, 400, 200, 20, "Ouvrir un fichier Image")
  
  Repeat
    Event = WaitWindowEvent()
    Select Event   
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 1
            Select EventType()
              Case #PB_EventType_LeftClick
                FichierParDefaut$ = "C:\" 
                Filtre$ = "Bitmap(*.bmp)|*.bmp"
                Filtre  = 0  
                Fichier$ = OpenFileRequester("Choisissez un fichier à charger", FichierParDefaut$, Filtre$, Filtre)
                If Fichier$
                  Ret=FileToOLE(Fichier$,0)
                  If Ret=0
                    MessageRequester("Information", "Le chargement de l'image dans l'éditeur à échoué", 0)
                  EndIf 
                Else
                  MessageRequester("Information", "La sélection a été annulée.", 0)
                EndIf 
            EndSelect  
            
        EndSelect
    EndSelect 
  Until Event = #PB_Event_CloseWindow
  
EndIf
End

DataSection
IID_IOleObject: ;"{00000112-0000-0000-C000-000000000046}"
Data.l $00000112
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  
    
IID_NULL:   ;"{00000000-0000-0000-0000-000000000000}"
Data.l $00000000
Data.w $0000,$0000
Data.b $00,$00,$00,$00,$00,$00,$00,$09  
EndDataSection
:o :o :o :o
Dernière modification par nico le mar. 19/juin/2007 3:34, modifié 5 fois.
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Message par Jacobus »

Excellent nico! Tu nous offre une belle avancée dans l'édition. :D
C'est le genre de possibilité qu'on aimerait trouver en natif dans PB.

Merci!

Testé avec PB 4.02
nico a écrit :
Debug sc
; je devrais avoir 0 mais on a 48 ?
J'obtiens 176 ...
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Nico va nous pondre une lib Richtext... peut etre 8O :D
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

; La même chose mais avec le presse papier
; On crée une image que l'on envoie au presse papier et que l'on colle ensuite dans l'éditeur

; On remarquera que le double click ne lance plus Paint!

Code : Tout sélectionner

; Insérer une image Bitmap dans un éditeur à partir du Clipboard
; Version PureBasic 4.10

#STGM_SHARE_EXCLUSIVE=$00000010
#STGM_READWRITE = $00000002
#STGM_CREATE = $00001000 
#REO_CP_SELECTION=$FFFFFFFF
#REO_RESIZABLE=1
#REO_BELOWBASELINE=2
#OLERENDER_FORMAT=2

Global RichEditOleObject.IRichEditOle
Global lpStorage.IStorage,lpObject.IOleObject,lpClientSite.IOleClientSite,lpDataObject.IDataobject


Procedure.l Paste_Image(Rich_Edit_ID.l)
  
  SendMessage_(GadgetID(Rich_Edit_ID), #EM_GETOLEINTERFACE, 0, @RichEditOleObject.IRichEditOle)
  
  If RichEditOleObject
    
    lpLockBytes.ILockBytes
    cfFormat = 0
    lpFormatEtc.FORMATETC
    clsid.CLSID
    
    *pointeur.CLSID=@clsid
    *pointeur=?IID_NULL
    
    sc = CreateILockBytesOnHGlobal_(#Null, #True, @lpLockBytes)
    If sc = #S_OK
      sc =StgCreateDocfileOnILockBytes_(lpLockBytes,#STGM_SHARE_EXCLUSIVE|#STGM_CREATE|#STGM_READWRITE, 0, @lpStorage)
      
      If sc = #S_OK
        lpLockBytes\Release()
      Else
        ProcedureReturn #False 
      EndIf 
    Else
      ProcedureReturn #False 
    EndIf 
    
    ; On récupère un Handle Bitmap OLE
    OleGetClipboard_(@lpDataObject)  
    lpFormatEtc\cfFormat = #CF_BITMAP
    lpFormatEtc\ptd = #Null
    lpFormatEtc\dwAspect = #DVASPECT_CONTENT
    lpFormatEtc\lindex = -1
    lpFormatEtc\tymed = #TYMED_GDI
    
    ;// attempt To create the object
    RichEditOleObject\GetClientSite(@lpClientSite)
    
    sc = OleCreateStaticFromData_(lpDataObject, ?IID_IOleObject, #OLERENDER_FORMAT, lpFormatEtc, lpClientSite, lpStorage, @lpObject)
    
    If sc = #S_OK
      
      ;// all items are "contained" -- this makes our reference To this object
      ;//  weak -- which is needed For links To embedding silent update.
      OleSetContainedObject_(lpObject, #True)
      
      reobject.REOBJECT
      ZeroMemory_(@reobject, SizeOf(REOBJECT))
      reobject\cbStruct = SizeOf(REOBJECT)
      
      sc = lpObject\GetUserClassID(clsid.CLSID)
      Debug sc
      
      CopyMemory(@clsid,@reobject\clsid,16)
    	
      reobject\cp = #REO_CP_SELECTION
      reobject\dvaspect = #DVASPECT_CONTENT
      reobject\dwFlags = #REO_RESIZABLE | #REO_BELOWBASELINE
      reobject\dwUser = 0
      reobject\poleobj = lpObject
      reobject\polesite = lpClientSite
      reobject\pstg = lpStorage
      reobject\sizel\cx=0
      reobject\sizel\cy=0
      
      RichEditOleObject\InsertObject(reobject)
      
      If lpDataObject
        lpDataObject\Release()
        lpDataObject = #Null
      EndIf 
      
      If lpObject
        lpObject\Release()
        lpObject = #Null
      EndIf 
      
      If lpStorage
        lpStorage\Release()
        lpStorage = #Null
      EndIf 
      
      If lpClientSite
        lpClientSite\Release()
        lpClientSite = #Null
      EndIf 
      
      If RichEditOleObject
        RichEditOleObject\Release()
        RichEditOleObject = #Null
      EndIf
      
      ProcedureReturn #True 
    EndIf 
    
    ProcedureReturn #False
  EndIf 
EndProcedure 

Enumeration
  #GADGET_Editor 
EndEnumeration

If OpenWindow(0, 0, 0, 500, 440, "RichEdit", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  CreateGadgetList(WindowID(0))
  
  EditorGadget(#GADGET_Editor, 10, 10, 480, 380)
  ButtonGadget(1, 10, 400, 200, 20, "Coller mon image")
  
  Repeat
    Event = WaitWindowEvent()
    Select Event   
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 1
            Select EventType()
              Case #PB_EventType_LeftClick
                If CreateImage(0,100,100)
                  StartDrawing(ImageOutput(0))
                  Box(0,0,100,100,RGB(0,0,255))
                  Circle(50,50,20,RGB(255,0,0))
                  StopDrawing()
                EndIf
                SetClipboardImage(0)
                
                Ret=Paste_Image(0)
                
            EndSelect  
            
        EndSelect
    EndSelect 
  Until Event = #PB_Event_CloseWindow
  
EndIf
End

DataSection
IID_IOleObject: ;"{00000112-0000-0000-C000-000000000046}"
Data.l $00000112
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  
    
IID_NULL:   ;"{00000000-0000-0000-0000-000000000000}"
Data.l $00000000
Data.w $0000,$0000
Data.b $00,$00,$00,$00,$00,$00,$00,$00  
EndDataSection
Dernière modification par nico le mar. 19/juin/2007 3:35, modifié 1 fois.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Je viens d'éditer les deux codes pour corriger quelques erreurs!
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Bonjour NICO

Cool ce code 8)

Le premier marche nickel, par contre chez moi je met bien une image dans le presse-papier, mais a la place j'ai un carré bleu dans ton prg 8O

Qu'est ce qui ne va pas chez moi (Hors mis ma tete bien sur :lol: )
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Avant de lancer la procédure, le prog crée lui-même une image et la place ensuite dans le pressse papier.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Un exemple avec le source du chargement d'un fichier Bitmap avec le code source de Srod qui permet de sauvegarder et charger un fichier rtf avec des images et de déplacer une image à l'intérieur de l'éditeur.

Code : Tout sélectionner

; Insérer une image Bitmap dans un éditeur à partir d'un fichier
; Version PureBasic 4.10

#STGM_SHARE_EXCLUSIVE=$00000010
#STGM_READWRITE = $00000002
#STGM_CREATE = $00001000 
#REO_CP_SELECTION=$FFFFFFFF
#REO_RESIZABLE=1
#REO_BELOWBASELINE=2
#OLERENDER_DRAW=1

Global RichEditOleObject.IRichEditOle
Global lpStorage.IStorage,lpObject.IOleObject,lpClientSite.IOleClientSite

Prototype.l CreateFromFile(a.l, FileName.p-bstr, b.l, c.l, d.l, e.l, f.l, g.l)

Declare.l StreamDataCallback(dwCookie, pbBuff, cb, pcb)
Declare.l StreamFileInCallback(dwCookie, pbBuff, cb, pcb)
Declare.l StreamFileOutCallback(dwCookie, pbBuff, cb, pcb)

Structure RichEditOle
  *pIntf.l
  Refcount.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 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, replaceall=0)
  Protected edstr.EDITSTREAM
  prtf = datastart
  edstr\dwCookie = dataend
  edstr\dwError = 0
  edstr\pfnCallback = @StreamDataCallback()
  SendMessage_(GadgetID(gadget), #EM_STREAMIN, #SF_RTF|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 an rtf file into an editor gadget.
;Returns zero if no error encountered.
;***********************************************************************************************
Procedure.l LoadRTF(gadget, FileName.s, 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, #SF_RTF|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


;***********************************************************************************************
;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)
Debug 1
  ;  If RichComObject\Refcount=0
  AddElement(RichComObject())
  RichComObject()\pIntf = ?VTable
  SendMessage_(hwnd, #EM_SETOLECALLBACK, 0, RichComObject())
  ;  EndIf
EndProcedure

Procedure.l RichEdit_QueryInterface(*pObject.RichEditOle, REFIID, ppvObj)
Debug 2
  ppvObj=0
  If CompareMemory(REFIID,?IID_IRichEditOleCallback,16)
    ppvObj=*pObject\pIntf
    ProcedureReturn #S_OK
  Else
    ProcedureReturn #E_NOINTERFACE
  EndIf 
  
EndProcedure

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

Procedure.l RichEdit_Release(*pObject.RichEditOle)
Debug 4
  *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 5
  Debug 1
  ProcedureReturn #S_OK
EndProcedure

Procedure.l RichEdit_ShowContainerUI(*pObject.RichEditOle, fShow)
Debug 6
  ProcedureReturn #S_OK
EndProcedure

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

Procedure.l RichEdit_DeleteObject(*pObject.RichEditOle, lpoleobj)
Debug 8
  ProcedureReturn #S_OK
EndProcedure

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

Procedure.l RichEdit_ContextSensitiveHelp(*pObject.RichEditOle, fEnterMode)
Debug 10
  ProcedureReturn #S_OK
EndProcedure

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

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

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


;The following function does the main work!
Procedure.l RichEdit_GetNewStorage(*pObject.RichEditOle, lplpstg)
Debug 14
  Protected sc, lpLockBytes.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)
  If sc ;This means that the allocation failed.
    lpLockBytes\Release() 
    ProcedureReturn sc
  EndIf
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_IRichEditOle: ;"0x00020D00, 0, 0, 0xC0,0,0,0,0,0,0,0x46)"
Data.l $00020D00
Data.w $0000,$0000
Data.b $C0,$00,$00,$00,$00,$00,$00,$46  

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  
EndDataSection 




Procedure.l FileToOLE(FileName.s,Rich_Edit_ID.l)
  
  SendMessage_(GadgetID(Rich_Edit_ID), #EM_GETOLEINTERFACE, 0, @RichEditOleObject.IRichEditOle)
  
  If RichEditOleObject
    
    lpLockBytes.ILockBytes
    cfFormat = 0
    lpFormatEtc.FORMATETC
    clsid.CLSID
    
    CopyMemory(?IID_NULL,@clsid,16)
    
    sc = CreateILockBytesOnHGlobal_(#Null, #True, @lpLockBytes)
    If sc = #S_OK
      sc =StgCreateDocfileOnILockBytes_(lpLockBytes,#STGM_SHARE_EXCLUSIVE|#STGM_CREATE|#STGM_READWRITE, 0, @lpStorage)
      
      If sc = #S_OK
        lpLockBytes\Release()
      Else
        ProcedureReturn #False 
      EndIf 
    Else
      ProcedureReturn #False 
    EndIf 
    
    ;// fill in FORMATETC struct
    lpFormatEtc\cfFormat = 0
    lpFormatEtc\ptd = #Null
    lpFormatEtc\dwAspect = #DVASPECT_CONTENT
    lpFormatEtc\lindex = -1
    lpFormatEtc\tymed = #TYMED_NULL
    
    ;// attempt To create the object
    RichEditOleObject\GetClientSite(@lpClientSite)
    
    If OpenLibrary(0, "ole32.dll")
      CreateFromFile.CreateFromFile = GetFunction(0, "OleCreateFromFile")   
      sc = CreateFromFile( clsid, FileName, ?IID_IUnknown, #OLERENDER_DRAW, lpFormatEtc, lpClientSite, lpStorage, @lpObject)
      CloseLibrary(0)
    EndIf 
    
    Debug sc
    ; je devrais avoir 0 mais on a 48 ?
    
    
    ;// lpObject is currently an IUnknown, convert To IOleObject
    If lpObject<> #Null
      lpUnk.IUnknown = lpObject
      lpUnk\QueryInterface(?IID_IOleObject, @lpObject)
      lpUnk\Release()
    EndIf 
    
    ;// all items are "contained" -- this makes our reference To this object
    ;//  weak -- which is needed For links To embedding silent update.
    OleSetContainedObject_(lpObject, #True)
    
    reobject.REOBJECT
    ZeroMemory_(@reobject, SizeOf(REOBJECT))
    reobject\cbStruct = SizeOf(REOBJECT)
    
    sc = lpObject\GetUserClassID(clsid.CLSID)
    Debug sc
    
    CopyMemory(@clsid,@reobject\clsid,16)
    
    reobject\cp = #REO_CP_SELECTION
    reobject\dvaspect = #DVASPECT_CONTENT
    reobject\dwFlags = #REO_RESIZABLE | #REO_BELOWBASELINE
    reobject\dwUser = 0
    reobject\poleobj = lpObject
    
    reobject\polesite = lpClientSite
    
    reobject\pstg = lpStorage
    
    reobject\sizel\cx=0
    reobject\sizel\cy=0
    
    RichEditOleObject\InsertObject(reobject)
    
    If lpObject
      lpObject\Release()
      lpObject = #Null
    EndIf 
    	
    If lpStorage
      lpStorage\Release()
      lpStorage = #Null
    EndIf 
    	
    If lpClientSite
      lpClientSite\Release()
      lpClientSite = #Null
    EndIf 
    
    If RichEditOleObject
      RichEditOleObject\Release()
      RichEditOleObject = #Null
    EndIf
    
    ProcedureReturn #True 
  EndIf 
EndProcedure 

Enumeration
  #GADGET_Editor 
EndEnumeration


If OpenWindow(0, 0, 0, 500, 440, "RichEdit", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  CreateGadgetList(WindowID(0))
  
  EditorGadget(#GADGET_Editor, 10, 10, 480, 380)
  RichEdit_SetInterface(GadgetID(#GADGET_Editor))
  
  ButtonGadget(1, 10, 400, 120, 20, "Ouvrir un fichier Image")
  ButtonGadget(2, 140, 400, 120, 20, "Sauver le Fichier")
  ButtonGadget(3, 280, 400, 120, 20, "Ouvrir un Fichier")

  
  Repeat
    Event = WaitWindowEvent()
    Select Event   
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 1
            Select EventType()
              Case #PB_EventType_LeftClick
                  FichierParDefaut$ = "C:\" 
                  Filtre$ = "Bitmap(*.bmp)|*.bmp"
                  Filtre  = 0  
                  Fichier$ = OpenFileRequester("Choisissez un fichier à charger", FichierParDefaut$, Filtre$, Filtre)
                  If Fichier$
                    Ret=FileToOLE(Fichier$,#GADGET_Editor)
                    If Ret=0
                      MessageRequester("Information", "Le chargement de l'image dans l'éditeur à échoué", 0)
                    EndIf 
                  Else
                    MessageRequester("Information", "La sélection a été annulée.", 0)
                  EndIf 
            EndSelect
              
         Case 2
            Select EventType()
              Case #PB_EventType_LeftClick
                  FichierParDefaut$ = "C:\" 
                  Filtre$ = "Fichier texte(*.rtf)|*.rtf"
                  Filtre  = 0  
                  Fichier$ = SaveFileRequester("Choisissez un fichier à sauvegarder", FichierParDefaut$, Filtre$, Filtre)
                  If Fichier$
                      SaveRTF(#GADGET_Editor,Fichier$)
                  Else
                    MessageRequester("Information", "La sélection a été annulée.", 0)
                  EndIf
            EndSelect 
            
         Case 3
            Select EventType()
              Case #PB_EventType_LeftClick
                  FichierParDefaut$ = "C:\" 
                  Filtre$ = "Fichier texte(*.rtf)|*.rtf"
                  Filtre  = 0  
                  Fichier$ = OpenFileRequester("Choisissez un fichier à charger", FichierParDefaut$, Filtre$, Filtre)
                  If Fichier$
                    LoadRTF(#GADGET_Editor, "c:\essai.rtf") 
                  Else
                    MessageRequester("Information", "La sélection a été annulée.", 0)
                  EndIf 

            EndSelect 
        EndSelect
  
    EndSelect 
  Until Event = #PB_Event_CloseWindow
  
EndIf
End

DataSection
IID_IOleObject: ;"{00000112-0000-0000-C000-000000000046}"
Data.l $00000112
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  
    
IID_NULL:   ;"{00000000-0000-0000-0000-000000000000}"
Data.l $00000000
Data.w $0000,$0000
Data.b $00,$00,$00,$00,$00,$00,$00,$00  
EndDataSection
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

Impecable !!!!

J'avais encore rien compris comme dab :oops:

Je te remercie beaucoup de ta reponse

Passe une bonne journée
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Je viens de m'apercevoir que le code de Srod suffit à lui-même, il permet déjà de coller une image dans l'éditeur depuis le presse papier en envoyant un sendmessage_(gadgetid(...),#WM_PASTE,0,0).

Il n'est jamais trop tard pour le découvrir. :lol:
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Je trouve extraordinaire que je puisse arriver à traduire des trucs pareils alors que je n'y comprend pas grand chose moi-même. :lol:

Avec ce nouveau code, je crois qu'on a fait le tour de la question sur la façon de copier un Bitmap dans l'éditeur.

Code : Tout sélectionner

Structure iData
  *pIntf.IDataobject
  Refcount.l
  m_stgmed.STGMEDIUM
  m_fromat.FORMATETC
EndStructure

Global NewList IDataObject.iData()

#STGM_SHARE_EXCLUSIVE=$00000010
#STGM_READWRITE = $00000002
#STGM_CREATE = $00001000
#REO_CP_SELECTION=$FFFFFFFF
#REO_RESIZABLE=1
#REO_BELOWBASELINE=2
#OLERENDER_FORMAT=2

Procedure dataobject_AddRef(*dataobject.iData)
  Debug "AddRef"
  *dataobject\Refcount=*dataobject\Refcount+1
  Debug "*dataobject\Refcount= "+Str(*dataobject\Refcount)
  ProcedureReturn *dataobject\Refcount
EndProcedure

Procedure dataobject_Release(*dataobject.iData)
  Debug "Release"
  *dataobject\Refcount=*dataobject\Refcount-1
  Debug "*dataobject\Refcount= "+Str(*dataobject\Refcount)
  If *dataobjectRefcount > 0
    ProcedureReturn *dataobject\Refcount
  Else
    ForEach IDataObject()
      If IDataObject()=*dataobject
        Debug "Destruction de l'objet"
        DeleteElement(IDataObject()) : Break
      EndIf
    Next
    *dataobject\pIntf=0
    ProcedureReturn 0
  EndIf
EndProcedure

Procedure dataobject_QueryInterface(*dataobject.IDataobject, iid, *ppvObject.Long)
  If CompareMemory(iid, ?IID_IUnknown, 16)=1 Or CompareMemory(iid, ?IID_IDataObject, 16)=1
    Debug "QueryInterface"
    *ppvObject\l = *dataobject
    *dataobject\AddRef()
    ProcedureReturn #S_OK
  Else
    *ppvObject\l=0
    ProcedureReturn #E_NOINTERFACE
  EndIf
EndProcedure
   
Procedure dataobject_GetData(*dataobject.iData,*pformatetcIn.FORMATETC, *pmedium.STGMEDIUM)
  If *pformatetcIn\tymed=*dataobject\m_fromat\tymed
    If *pformatetcIn\cfFormat=*dataobject\m_fromat\cfFormat
      Debug "GetData"
      *pmedium\tymed = *dataobject\m_stgmed\tymed
      *pmedium\hBitmap = *dataobject\m_stgmed\hBitmap
      *pmedium\pUnkForRelease = *dataobject\m_stgmed\pUnkForRelease
    EndIf
  EndIf
  ProcedureReturn #S_OK
EndProcedure

Procedure dataobject_GetDataHere(*dataobject, *pformatetc, *pmedium )
  Debug "GetDataHere"
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure dataobject_QueryGetData(*dataobject, *pformatetc )
  Debug "QueryGetData"
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure dataobject_GetCanonicalFormatEtc(*dataobject, *pformatectIn ,*pformatetcOut )
  Debug "GetCanonicalFormatEtc"
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure dataobject_SetData(*dataobject.iData, *pformatetc.FORMATETC , *pmedium.STGMEDIUM , fRelease )
  Debug "SetData"
  CopyMemory(*pformatetc,*dataobject\m_fromat,SizeOf(FORMATETC))
  CopyMemory(*pmedium,*dataobject\m_stgmed,SizeOf(STGMEDIUM))
 
  ProcedureReturn #S_OK
EndProcedure

Procedure dataobject_EnumFormatEtc(*dataobject, dwDirection , *ppenumFormatEtc )
  Debug "EnumFormatEtc"
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure dataobject_DAdvise(*dataobject,*pformatetc, advf, *pAdvSink, *pdwConnection)
  Debug "DAdvise"
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure dataobject_DUnadvise(*dataobject, dwConnection)
  Debug "DUnadvise"
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure dataobject_EnumDAdvise(*dataobject, *ppenumAdvise)
  Debug "EnumDAdvise"
  ProcedureReturn #E_NOTIMPL
EndProcedure
   
Procedure.l Paste_Image(hBitmap.l,Rich_Edit_ID.l)
  Protected Ret.l,sc.l,pods.IDataobject,stgm.STGMEDIUM ,fm.FORMATETC
 
  SendMessage_(GadgetID(Rich_Edit_ID), #EM_GETOLEINTERFACE, 0, @RichEditOleObject.IRichEditOle)
 
  If RichEditOleObject
    AddElement(IDataObject())
    IDataObject()\pIntf=?VTable
    pods.IDataobject=IDataObject()
   
    ;       Normalement on devrait dupliquer le bitmap avec cette fonction,
    ;       mais bien que la fonction return un handle; ça ne fonctionne pas pour autant!
    ;       hbitmap = OleDuplicateData_(hBitmap, #CF_BITMAP, #Null)
   
    hBitmap=CopyImage_(hBitmap,#IMAGE_BITMAP,0,0,#LR_COPYRETURNORG)

    stgm\tymed = #TYMED_GDI            ;         // Storage medium = HBITMAP handle     
    stgm\hBitmap = hBitmap             ;         // HBITMAP handle
    stgm\pUnkForRelease = #Null        ;         // Use ReleaseStgMedium
   

    fm\cfFormat = #CF_BITMAP           ;         // Clipboard format = CF_BITMAP
    fm\ptd = #Null                     ;         // Target Device = Screen
    fm\dwAspect = #DVASPECT_CONTENT    ;         // Level of detail = Full content
    fm\lindex = -1                     ;         // Index = Not applicaple
    fm\tymed = #TYMED_GDI              ;         // Storage medium = HBITMAP handle
   
   
    CopyMemory(?IID_IUnknown,@iid.IID,16)
    sc=pods\QueryInterface(iid.IID, @lpDataObject.IDataobject)
   
    sc=pods\SetData(@fm, @stgm, #True)
   
    sc = CreateILockBytesOnHGlobal_(#Null, #True, @lpLockBytes.ILockBytes)
    If sc = #S_OK
     
      sc =StgCreateDocfileOnILockBytes_(lpLockBytes,#STGM_SHARE_EXCLUSIVE|#STGM_CREATE|#STGM_READWRITE, 0, @lpStorage.IStorage)
      If sc = #S_OK
       
        sc =RichEditOleObject\GetClientSite(@lpClientSite.IOleClientSite)
        If sc = #S_OK
         
          sc = OleCreateStaticFromData_(lpDataObject, ?IID_IOleObject, #OLERENDER_FORMAT, IDataObject()\m_fromat, lpClientSite, lpStorage, @lpOleObject.IOleObject)
          If sc = #S_OK
           
            OleSetContainedObject_(lpOleObject, #True)
           
            reobject.REOBJECT
            ZeroMemory_(@reobject, SizeOf(REOBJECT))
            reobject\cbStruct = SizeOf(REOBJECT)
           
            sc = lpOleObject\GetUserClassID(@clsid.CLSID)
           
            CopyMemory(@clsid.CLSID,@reobject\clsid,16)
           
            reobject\cp = #REO_CP_SELECTION
            reobject\dvaspect = #DVASPECT_CONTENT
            reobject\dwFlags = #REO_RESIZABLE
            reobject\dwUser = 0
            reobject\poleobj = lpOleObject
            reobject\polesite = lpClientSite
            reobject\pstg = lpStorage
            reobject\sizel\cx=0
            reobject\sizel\cy=0
           
            Ret= RichEditOleObject\InsertObject(reobject)
           
          EndIf
        EndIf
      EndIf
    EndIf
   
    If lpLockBytes
      lpLockBytes\Release()
      lpLockBytes=0
    EndIf
   
    If lpDataObject
      lpDataObject\Release()
      lpDataObject = #Null
    EndIf
   
    If lpOleObject
      lpOleObject\Release()
      lpOleObject = #Null
    EndIf
   
    If lpStorage
      lpStorage\Release()
      lpStorage = #Null
    EndIf
   
    If lpClientSite
      lpClientSite\Release()
      lpClientSite = #Null
    EndIf
   
    If RichEditOleObject
      RichEditOleObject\Release()
      RichEditOleObject = #Null
    EndIf
  EndIf
  ProcedureReturn Ret
EndProcedure


LoadImage(1,"c:\carre_rouge.bmp")

If OpenWindow(0, 0, 0, 600, 600, "RichEdit", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  SetWindowLong_(WindowID(0),#GWL_STYLE,GetWindowLong_(WindowID(0),#GWL_STYLE)|#WS_CLIPCHILDREN)
  CreateGadgetList(WindowID(0))
 
  EditorGadget(0, 10, 10, 580, 360)
 
  ButtonImageGadget(2, 10, 380, 200, 200, ImageID(1))
 
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
         
          Case 2
            Select EventType()
              Case #PB_EventType_LeftClick
                Paste_Image(ImageID(1),0)
            EndSelect
           
        EndSelect
       
    EndSelect
  Until Event = #PB_Event_CloseWindow
EndIf

DataSection
VTable:
Data.l @dataobject_QueryInterface(), @dataobject_AddRef(), @dataobject_Release()
Data.l @dataobject_GetData(),@dataobject_GetDataHere(),@dataobject_QueryGetData()
Data.l @dataobject_GetCanonicalFormatEtc(),@dataobject_SetData(),@dataobject_EnumFormatEtc()
Data.l @dataobject_DAdvise(),@dataobject_DUnadvise(),@dataobject_EnumDAdvise()

IID_IDataObject:  ;{0000010e-0000-0000-C000-000000000046"}
Data.l $0000010E
Data.w $0000,$0000
Data.b $C0,$00,$00,$00,$00,$00,$00,$46

IID_IOleObject:   ;"{00000112-0000-0000-C000-000000000046}"
Data.l $00000112
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  
Dernière modification par nico le sam. 30/juin/2007 13:17, modifié 4 fois.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

nico a écrit :Je trouve extraordinaire que je puisse arriver à traduire des trusc pareils alors que je n'y comprend pas grand chose moi-même. :lol:
En tout cas c'est sympa de partager :)
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Voici tous les fichiers nécessaires pour implémenter la gestion des images dans l'éditeur:

Le fichier Ole.pbi

Code : Tout sélectionner

;Rich edit functions.

;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.



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

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 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, replaceall=0)
  Protected edstr.EDITSTREAM
  prtf = datastart
  edstr\dwCookie = dataend
  edstr\dwError = 0
  edstr\pfnCallback = @StreamDataCallback()
  SendMessage_(GadgetID(gadget), #EM_STREAMIN, #SF_RTF|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 an rtf file into an editor gadget.
;Returns zero if no error encountered.
;***********************************************************************************************
Procedure.l LoadRTF(gadget, filename.s, 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, #SF_RTF|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


;***********************************************************************************************
;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_IRicheditOle
   RichComObject()\hwnd=hwnd
   Debug "--------------"+Str(RichComObject())
   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
  Debug "------*pObject\Refcount-------"+Str(*pObject\Refcount)
  ProcedureReturn *pObject\Refcount
EndProcedure

Procedure.l RichEdit_Release(*pObject.RichEditOle)
  *pObject\Refcount-1
  Debug "------*pObject\Refcount-------"+Str(*pObject\Refcount)
  If *pObject\Refcount > 0
    ProcedureReturn *pObject\Refcount
  Else
    ForEach RichComObject()
      If RichComObject()=*pObject
        DeleteElement(RichComObject()) : Break
      EndIf
    Next
      *pObject=0
      ProcedureReturn 0
  EndIf
EndProcedure

Procedure.l RichEdit_GetInPlaceContext(*pObject.RichEditOle, lplpFrame, lplpDoc, lpFrameInfo)
  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)
  If sc ;This means that the allocation failed.
    t = lpLockBytes
    t\Release() 
    ProcedureReturn sc
  EndIf
EndProcedure
;***********************************************************************************************

DataSection

VTable_IRicheditOle:
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

Le fichier Paste_Image_Editor.pbi

Code : Tout sélectionner

Structure iData
  *pIntf.IDataobject
  Refcount.l
  m_stgmed.STGMEDIUM
  m_fromat.FORMATETC
EndStructure

Global NewList IDataObject.iData()

#STGM_SHARE_EXCLUSIVE=$00000010
#STGM_READWRITE = $00000002
#STGM_CREATE = $00001000
#REO_CP_SELECTION=$FFFFFFFF
#REO_RESIZABLE=1
#REO_BELOWBASELINE=2
#OLERENDER_FORMAT=2

Procedure dataobject_AddRef(*dataobject.iData)
  Debug "AddRef"
  *dataobject\Refcount=*dataobject\Refcount+1
  ProcedureReturn *dataobject\Refcount
EndProcedure

Procedure dataobject_Release(*dataobject.iData)
  *dataobject\Refcount=*dataobject\Refcount-1
  If *dataobjectRefcount > 0
    ProcedureReturn *dataobject\Refcount
  Else
    ForEach IDataObject()
      If IDataObject()=*dataobject
        Debug "Release"
        DeleteElement(IDataObject()) : Break
      EndIf
    Next
    *dataobject=0
    ProcedureReturn 0
  EndIf
EndProcedure

Procedure dataobject_QueryInterface(*dataobject.IDataobject, iid, *ppvObject.Long)
  If CompareMemory(iid, ?IID_IUnknown, 16)=1 Or CompareMemory(iid, ?IID_IDataObject, 16)=1
    Debug "QueryInterface"
    *ppvObject\l = *dataobject
    *dataobject\AddRef()
    ProcedureReturn #S_OK
  Else
    *ppvObject=0
    ProcedureReturn #E_NOINTERFACE
  EndIf
EndProcedure
   
Procedure dataobject_GetData(*dataobject.iData,*pformatetcIn.FORMATETC, *pmedium.STGMEDIUM)
  Protected hbitmap.l
  If *pformatetcIn\tymed=*dataobject\m_fromat\tymed
    If *pformatetcIn\cfFormat=*dataobject\m_fromat\cfFormat
      Debug "GetData"
      hbitmap = OleDuplicateData_(*dataobject\m_stgmed\hBitmap, #CF_BITMAP, #Null)
      *pmedium\tymed = *dataobject\m_stgmed\tymed
      *pmedium\hBitmap = hbitmap
      *pmedium\pUnkForRelease = *dataobject\m_stgmed\pUnkForRelease
    EndIf
  EndIf
  ProcedureReturn #S_OK
EndProcedure

Procedure dataobject_GetDataHere(*dataobject, *pformatetc, *pmedium )
  Debug "GetDataHere"
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure dataobject_QueryGetData(*dataobject, *pformatetc )
  Debug "QueryGetData"
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure dataobject_GetCanonicalFormatEtc(*dataobject, *pformatectIn ,*pformatetcOut )
  Debug "GetCanonicalFormatEtc"
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure dataobject_SetData(*dataobject.iData, *pformatetc.FORMATETC , *pmedium.STGMEDIUM , fRelease )
  Debug "SetData"
  CopyMemory(*pformatetc,*dataobject\m_fromat,SizeOf(FORMATETC))
  CopyMemory(*pmedium,*dataobject\m_stgmed,SizeOf(STGMEDIUM))
 
  ProcedureReturn #S_OK
EndProcedure

Procedure dataobject_EnumFormatEtc(*dataobject, dwDirection , *ppenumFormatEtc )
  Debug "EnumFormatEtc"
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure dataobject_DAdvise(*dataobject,*pformatetc, advf, *pAdvSink, *pdwConnection)
  Debug "DAdvise"
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure dataobject_DUnadvise(*dataobject, dwConnection)
  Debug "DUnadvise"
  ProcedureReturn #E_NOTIMPL
EndProcedure

Procedure dataobject_EnumDAdvise(*dataobject, *ppenumAdvise)
  Debug "EnumDAdvise"
  ProcedureReturn #E_NOTIMPL
EndProcedure
   
Procedure.l Paste_Image(hBitmap.l,Rich_Edit_ID.l)
  Protected Ret.l,sc.l,pods.IDataobject,stgm.STGMEDIUM ,fm.FORMATETC
 
  hBitmap=CopyImage_(hBitmap,#IMAGE_BITMAP,0,0,#LR_COPYRETURNORG)
  If hBitmap
  
    SendMessage_(GadgetID(Rich_Edit_ID), #EM_GETOLEINTERFACE, 0, @RichEditOleObject.IRichEditOle)
   
    If RichEditOleObject
      AddElement(IDataObject())
      IDataObject()\pIntf=?VTable_IDataObject
      pods.IDataobject=IDataObject()
  
  
      stgm\tymed = #TYMED_GDI            ;         // Storage medium = HBITMAP handle     
      stgm\hBitmap = hBitmap             ;         // HBITMAP handle
      stgm\pUnkForRelease = #Null        ;         // Use ReleaseStgMedium
     
  
      fm\cfFormat = #CF_BITMAP           ;         // Clipboard format = CF_BITMAP
      fm\ptd = #Null                     ;         // Target Device = Screen
      fm\dwAspect = #DVASPECT_CONTENT    ;         // Level of detail = Full content
      fm\lindex = -1                     ;         // Index = Not applicaple
      fm\tymed = #TYMED_GDI              ;         // Storage medium = HBITMAP handle
     
     
      CopyMemory(?IID_IUnknown,@iid.IID,16)
      sc=pods\QueryInterface(iid.IID, @lpDataObject.IDataobject)
     
      sc=pods\SetData(@fm, @stgm, #True)
     
      sc = CreateILockBytesOnHGlobal_(#Null, #True, @lpLockBytes.ILockBytes)
      If sc = #S_OK
       
        sc =StgCreateDocfileOnILockBytes_(lpLockBytes,#STGM_SHARE_EXCLUSIVE|#STGM_CREATE|#STGM_READWRITE, 0, @lpStorage.IStorage)
        If sc = #S_OK
         
          sc =RichEditOleObject\GetClientSite(@lpClientSite.IOleClientSite)
          If sc = #S_OK
           
            sc = OleCreateStaticFromData_(lpDataObject, ?IID_IOleObject, #OLERENDER_FORMAT, IDataObject()\m_fromat, lpClientSite, lpStorage, @lpOleObject.IOleObject)
            If sc = #S_OK
             
              OleSetContainedObject_(lpOleObject, #True)
             
              reobject.REOBJECT
              ZeroMemory_(@reobject, SizeOf(REOBJECT))
              reobject\cbStruct = SizeOf(REOBJECT)
             
              sc = lpOleObject\GetUserClassID(@clsid.CLSID)
             
              CopyMemory(@clsid.CLSID,@reobject\clsid,16)
             
              reobject\cp = #REO_CP_SELECTION
              reobject\dvaspect = #DVASPECT_CONTENT
              reobject\dwFlags = #REO_RESIZABLE
              reobject\dwUser = 0
              reobject\poleobj = lpOleObject
              reobject\polesite = lpClientSite
              reobject\pstg = lpStorage
              reobject\sizel\cx=0
              reobject\sizel\cy=0
             
              Ret= RichEditOleObject\InsertObject(reobject)
            EndIf
          EndIf
        EndIf
      EndIf
     
      If lpLockBytes
        lpLockBytes\Release()
        lpLockBytes=0
      EndIf
     
      If lpDataObject
        lpDataObject\Release()
        lpDataObject = #Null
      EndIf
     
      If lpOleObject
        lpOleObject\Release()
        lpOleObject = #Null
      EndIf
     
      If lpStorage
        lpStorage\Release()
        lpStorage = #Null
      EndIf
     
      If lpClientSite
        lpClientSite\Release()
        lpClientSite = #Null
      EndIf
     
      If RichEditOleObject
        RichEditOleObject\Release()
        RichEditOleObject = #Null
      EndIf
    EndIf
    DeleteObject_(hBitmap)
  EndIf 
  ProcedureReturn Ret
EndProcedure

DataSection
VTable_IDataObject:
Data.l @dataobject_QueryInterface(), @dataobject_AddRef(), @dataobject_Release()
Data.l @dataobject_GetData(),@dataobject_GetDataHere(),@dataobject_QueryGetData()
Data.l @dataobject_GetCanonicalFormatEtc(),@dataobject_SetData(),@dataobject_EnumFormatEtc()
Data.l @dataobject_DAdvise(),@dataobject_DUnadvise(),@dataobject_EnumDAdvise()

IID_IDataObject:  ;{0000010e-0000-0000-C000-000000000046"}
Data.l $0000010E
Data.w $0000,$0000
Data.b $C0,$00,$00,$00,$00,$00,$00,$46

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

EndDataSection   
Et pour finir un exemple:

Code : Tout sélectionner

; L'ordre des IncludeFile est important
IncludeFile "Ole.pbi"
IncludeFile "Paste_Image_Editor.pbi"

If OpenWindow(0, 0, 0, 600, 320, "RichEdit", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  SetWindowLong_(WindowID(0),#GWL_STYLE,GetWindowLong_(WindowID(0),#GWL_STYLE)|#WS_CLIPCHILDREN)
  CreateGadgetList(WindowID(0))
  
  EditorGadget(0, 10, 10, 260, 260)
  EditorGadget(4, 300, 10, 260, 260)

  RichEdit_SetInterface(GadgetID(0))
  RichEdit_SetInterface(GadgetID(4))
  
  ButtonGadget(1, 10, 280, 120, 20, "Ouvrir un Fichier")
  ButtonGadget(2, 140, 280, 120, 20, "Sauver le Fichier")
  ButtonGadget(3, 280, 280, 220, 20, "Choisir une image et la coller")
  
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()
        
         Case 1
            Select EventType()
              Case #PB_EventType_LeftClick
                  FichierParDefaut$ = "C:\" 
                  Filtre$ = "Fichier texte(*.rtf)|*.rtf"
                  Filtre  = 0  
                  Fichier$ = OpenFileRequester("Choisissez un fichier à charger", FichierParDefaut$, Filtre$, Filtre)
                  If Fichier$
                    LoadRTF(0, "c:\essai.rtf") 
                  Else
                    MessageRequester("Information", "La sélection a été annulée.", 0)
                  EndIf 
            EndSelect 
            
         Case 2
            Select EventType()
              Case #PB_EventType_LeftClick
                  FichierParDefaut$ = "C:\" 
                  Filtre$ = "Fichier texte(*.rtf)|*.rtf"
                  Filtre  = 0  
                  Fichier$ = SaveFileRequester("Choisissez un fichier à sauvegarder", FichierParDefaut$, Filtre$, Filtre)
                  If Fichier$
                      SaveRTF(0,Fichier$)
                  Else
                    MessageRequester("Information", "La sélection a été annulée.", 0)
                  EndIf
            EndSelect
            
         Case 3
            Select EventType()
              Case #PB_EventType_LeftClick
                FichierParDefaut$ = "C:\"
                Filtre$ = "Bitmap(*.bmp)|*.bmp"
                Filtre  = 0 
                Fichier$ = OpenFileRequester("Choisissez un fichier à charger", FichierParDefaut$, Filtre$, Filtre)
                If Fichier$
                  id=LoadImage(#PB_Any,Fichier$)
                  Paste_Image(ImageID(id),0)
                  FreeImage(id)
                Else
                  MessageRequester("Information", "La sélection a été annulée.", 0)
                EndIf 
                
            EndSelect
        EndSelect
  
    EndSelect 
  Until Event = #PB_Event_CloseWindow
EndIf 
Dernière modification par nico le dim. 01/juil./2007 9:45, modifié 7 fois.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Le fichier Ole.pbi est celui de Srod que j'ai complété.
La fonction CatchRtf me semble pas nécessaire puisqu'on peut faire un SetGadgetText!
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Le code Paste_Image_Editor à été mis à jour, j'ai enfin pu mettre en place l'API OleDuplicateData, suffisait de le mettre en place après la copie de l'image.

Si pour unr raison ou une autre, les codes postés ici ne fonctionnaient pas, merci d'en faire part!
Répondre