1. REUndo stack in RichEdit
- Posted by Cuvier Christian <christian.cuvier at insee.fr> Apr 12, 2006
- 512 views
> Subject: Undo stack in RichEdit > > > posted by: Antonio Alessi <a.admin at myway.it> > > > When text is changed into a RichEdit window, the Undo feature > become active > and at every change it is increased one step. > Note that this does not occurr on every single character > change, but after > a string, or some text is changed. > > I need to know the current number of these steps, or the > stack length( ) > of the Undo feature. Is there a way to get this info? > > Thanks to everybody for an answer. > > Antonio Alessi > Not directly. You have to intercept the following messages which your RichEdit receives so as to keep track of the undo count, starting at 0: * EM_UNDO: substract 1 to length if nonzero * WM_UNDO: same * EM_REDO: add 1 to length * EM_STOPGROUPTYPING: add 1 to length (this splits a typing action the control would otherwise undo/redo atomically) * EM_EMPTYUNDOBUFFER: set length to 0 * EM_SETUNDOLIMIT: set length to returned value if it was greater (see note below) * EM_SETHANDLE: set length to zero. Also note that: * the default value for the max number of undoable actions is 100 on RichEdits 2.0+; * setting this to 0 disables the undo feature, which is enabled back by setting this parameter to some nonzero value. Now how to keep track of events occurring to the control? You have to listen to the EN_UPDATE notifications it sends. Also listen to the WM_CHAR its parent gets. If a notification occurs between two WM_CHARs, ignore it; else add 1 to length. If you are subclassing a control that had its own life before you interact with it, you can undo every action in the current buffer (by sending EM_UNDO) preceded by EM_CANUNDO. Count the number of EM_CANUNDO that returned TRUE. This is the current buffer length. When EM_CANUNDO returns FALSE, redo everything by sebding EM_REDO this same number of times. Slow and ugly, but it works. RichEdits are not supposed to get EM_SETHANDLE and WM_UNDO as deprecated features that are/were intended for single edit controls, but who knows? RichEdit 1.0 only store 1 operation. For these older controls, the whole thing above boils down to sending EM_CANUNDO: if it returns true, length is 1, and 0 else. M$, in his infinite "wisdom", did not provide any direct notification of undoable change. CChris
2. Re: REUndo stack in RichEdit
- Posted by Antonio Alessi <a.admin at myway.it> Apr 12, 2006
- 482 views
Cuvier Christian wrote: > > > Subject: Undo stack in RichEdit > > > > > > posted by: Antonio Alessi <a.admin at myway.it> > > > > > > When text is changed into a RichEdit window, the Undo feature > > become active > > and at every change it is increased one step. > > Note that this does not occurr on every single character > > change, but after > > a string, or some text is changed. > > > > I need to know the current number of these steps, or the > > stack length( ) > > of the Undo feature. Is there a way to get this info? > > > > Thanks to everybody for an answer. > > > > Antonio Alessi > > > > Not directly. > You have to intercept the following messages which your RichEdit receives so > as to keep track of the undo count, starting at 0: > > * EM_UNDO: substract 1 to length if nonzero > * WM_UNDO: same > * EM_REDO: add 1 to length > * EM_STOPGROUPTYPING: add 1 to length (this splits a typing action the > control would otherwise undo/redo atomically) > * EM_EMPTYUNDOBUFFER: set length to 0 > * EM_SETUNDOLIMIT: set length to returned value if it was greater (see note > below) > * EM_SETHANDLE: set length to zero. > > Also note that: > * the default value for the max number of undoable actions is 100 on > RichEdits 2.0+; > * setting this to 0 disables the undo feature, which is enabled back by > setting this parameter to some nonzero value. > > Now how to keep track of events occurring to the control? You have to listen > to the EN_UPDATE notifications it sends. Also listen to the WM_CHAR its > parent gets. If a notification occurs between two WM_CHARs, ignore it; else > add 1 to length. > > If you are subclassing a control that had its own > life before you interact with it, you can undo every action in the current > buffer (by sending EM_UNDO) preceded by EM_CANUNDO. Count the number of > EM_CANUNDO that returned TRUE. This is the current buffer length. When > EM_CANUNDO returns FALSE, redo everything by sebding EM_REDO this same > number of times. Slow and ugly, but it works. > > RichEdits are not supposed to get EM_SETHANDLE and WM_UNDO as deprecated > features that are/were intended for single edit controls, but who knows? > > RichEdit 1.0 only store 1 operation. For these older controls, the whole > thing above boils down to sending EM_CANUNDO: if it returns true, length is > 1, and 0 else. > > M$, in his infinite "wisdom", did not provide any direct notification of > undoable change. > > CChris > > Thank you Chris, I'll keep precious all this explanation. The above was probably the only way to take us into an 'infinite' loop.. «The Devil makes the pots but not the covers», goes a famous Italian proverb; it means that even the "cleverest" can fail to attend to essential details (and because of this they can be beaten). However, I find this quote PERFECT for M$. Since I'm handling the options of both single and grouping undo/redo steps, with a real time counter, in such case I guess it will be more immediate to keep track of changes through the keyboard and update a counter of mine. If not, I'll try to apply what you describe. Antonio