HowTo Manage the RichEdit "Undo" queue

Just starting out? Need help? Post your questions and find answers here.
zapman*
Enthusiast
Enthusiast
Posts: 115
Joined: Wed Jun 02, 2004 10:17 pm
Location: New Caledonia (South Pacific)
Contact:

HowTo Manage the RichEdit "Undo" queue

Post by zapman* »

I'm making an editor with a RichEdit Gadget.
I would like to be able to do some operations (i.e. coloring parts of the text) without adding those operations in the "Undo" queue automatically managed by Windows. In other words, I don't want that the user can "undo" the operations made on the RE Gadget by my program.

Is there any way to access to this undo list and to modify it?

Must I use the "IOleUndoManager" interface and does anybody have an experience or example code using this interface?

I have exactly the same question for Web gadget in editable mode, but let's go step by step :)
Don't try - DO it !
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

Try this code:

Code: Select all

; richedit 3.0 text object model constants 
;
#tomSuspend = -9999995 
#tomResume  = -9999994

DataSection

  IID_ITextDocument:  ; {8CC497C0-A1DF-11ce-8098-00AA0047BE5D}
    Data.l $8CC497C0
    Data.w $A1DF, $11ce
    Data.b $80, $98, $00, $AA, $00, $47, $BE, $5D
    
EndDataSection

Enumeration
  #GADGET_Editor  
  #GADGET_Suspend
  #GADGET_Resume
  #GADGET_Clear
  #GADGET_Undo
EndEnumeration

If OpenWindow(0, 0, 0, 500, 400, "RichEdit", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  CreateGadgetList(WindowID(0))
  
  EditorGadget(#GADGET_Editor, 10, 10, 480, 345)
  ButtonGadget(#GADGET_Suspend, 10, 365, 100, 25, "Suspend")
  ButtonGadget(#GADGET_Resume, 120, 365, 100, 25, "Resume")
  ButtonGadget(#GADGET_Clear, 230, 365, 100, 25, "Clear")
  ButtonGadget(#GADGET_Undo, 390, 365, 100, 25, "Undo")
  
  ; Get the ITextDocument interface. This message is Richedit 3.0+ only.
  ; Older versions just ignore it, so make sure you are prepared for a 0 result!
  ;
  SendMessage_(GadgetID(#GADGET_Editor), #EM_GETOLEINTERFACE, 0, @RichEditOleObject.IRichEditOle)
  If RichEditOleObject
    RichEditOleObject\QueryInterface(?IID_ITextDocument, @TextInterface.ITextDocument)
    RichEditOleObject\Release()
  EndIf  
  
  If TextInterface = 0    
    DisableGadget(#GADGET_Suspend, 1)
  EndIf
  
  DisableGadget(#GADGET_Resume, 1)
  DisableGadget(#GADGET_Clear, 1)
  DisableGadget(#GADGET_Undo, 1)
  
  ; Somehow the undo buffer is non-empty after creation.. this is weird
  SendMessage_(GadgetID(#GADGET_Editor), #EM_EMPTYUNDOBUFFER, 0, 0)  
  IsSuspended = 0
  
  Repeat
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_Gadget

      Select EventGadget()
       
        Case #GADGET_Suspend
          If TextInterface ; make sure to check this as old systens don't have it!
            TextInterface\Undo(#tomSuspend, 0) ; this suspends undo recording
            IsSuspended = 1
            DisableGadget(#GADGET_Resume, 0)
            DisableGadget(#GADGET_Suspend, 1)
          EndIf
          
        Case #GADGET_Resume
          If TextInterface
            TextInterface\Undo(#tomResume, 0) ; this resumes undo recording
            IsSuspended = 0
            DisableGadget(#GADGET_Resume, 1)
            DisableGadget(#GADGET_Suspend, 0)
          EndIf       
          
        Case #GADGET_Clear
          SendMessage_(GadgetID(#GADGET_Editor), #EM_EMPTYUNDOBUFFER, 0, 0) ; clear all the buffer
        
        Case #GADGET_Undo
          SendMessage_(GadgetID(#GADGET_Editor), #EM_UNDO, 0, 0) ; undo
      
      EndSelect
      
      ; update the gadgets by checking if there is something to undo
      If SendMessage_(GadgetID(#GADGET_Editor), #EM_CANUNDO, 0, 0)
        DisableGadget(#GADGET_Clear, 0)
        
        If IsSuspended
          DisableGadget(#GADGET_Undo, 1)  ; cannot undo while the operation is suspended!
        Else
          DisableGadget(#GADGET_Undo, 0) 
        EndIf        
      Else
        DisableGadget(#GADGET_Clear, 1)
        DisableGadget(#GADGET_Undo, 1) 
      EndIf
    EndIf
    
  Until Event = #PB_Event_CloseWindow
  
  ; important to release this when you free the gadget to avoid memory leaks.
  ; (especially when you free the gadget but don't end the program after)  
  If TextInterface
    TextInterface\Release()
  EndIf
EndIf
End
quidquid Latine dictum sit altum videtur
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Wow!

:shock:
I may look like a mule, but I'm not a complete ass.
zapman*
Enthusiast
Enthusiast
Posts: 115
Joined: Wed Jun 02, 2004 10:17 pm
Location: New Caledonia (South Pacific)
Contact:

Post by zapman* »

Absolutely perfect!

Thanks a million times, Freak, you're a treasure.
Don't try - DO it !
Post Reply