Page 1 of 1

HowTo Manage the RichEdit "Undo" queue

Posted: Wed Sep 13, 2006 3:19 am
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 :)

Posted: Wed Sep 13, 2006 2:04 pm
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

Posted: Wed Sep 13, 2006 2:12 pm
by srod
Wow!

:shock:

Posted: Wed Sep 13, 2006 10:22 pm
by zapman*
Absolutely perfect!

Thanks a million times, Freak, you're a treasure.