Creating an Undo Unit that Maintains Non-Visio Data: an Example

3 4

The following example demonstrates creating an undo unit that synchronizes a drawing and a parallel model—in this case, a simple variable called m_nCount that represents the number of shapes in the drawing. This variable is incremented each time a shape is added to the drawing.

The class module called VBAUndoUnit contains the logic to increment or decrement m_nCount if the ShapeAdded event subsequently gets undone or redone. VBAUndoUnit contains a flag to maintain its own undone state. The flag is initialized to False because this object is initially placed on the undo stack. After VBAUndoUnit gets called the first time, it carries out the undo logic, changes its undone state to True, and places itself on the redo stack.

The example uses the Immediate window in the Visual Basic Editor to display how this project keeps the drawing and the data synchronized.

The first block of code is contained in the ShapeAdded event handler in the ThisDocument class module. The program increments m_nCount by 1 and then adds the undo unit to the undo stack in the Visio Undo manager. Because the Visio engine automatically creates a scope when the event handler gets called, the undo unit will get executed if the user then decides to undo the shape that was just added to the drawing.

ThisDocument also contains procedures to increment and decrement the variable.

 Private m_nCount As Long Private Sub Document_ShapeAdded(ByVal Shape As IVShape)       If Not Application.IsUndoingOrRedoing Then             'Now you can perform undoable actions             IncrementModuleVar             Debug.Print "Original Do: GetModuleVar = " & GetModuleVar             'Add an undo unit that undoes/redoes that action             Application.AddUndoUnit New VBAUndoUnit       End If End Sub Public Sub IncrementModuleVar()       m_nCount = m_nCount + 1 End Sub Public Sub DecrementModuleVar()       m_nCount = m_nCount - 1 End Sub Public Function GetModuleVar() As Long       GetModuleVar = m_nCount End Function 

Here is the code inside VBAUndoUnit:

 Implements Visio.IVBUndoUnit Private m_bUndone As Boolean       'm_bUndone is a flag that tells us whether an undo unit exists       'on the undo or redo stack. When you first call        'Application.AddUndoUnit, an instance of VBAUndoUnit is        'placed on the undo stack. Then when undo occurs, the "Do"        'method gets called and you toggle this flag and call       'IVBUndoManager.Add to get an undo unit placed on the redo stack.        'Then, the next time the Do method gets called, you toggle the        'flag back again and call IVBUndoManager.Add again to get an undo        'unit placed back on the undo stack. When an undo unit is on the        'undo stack, m_bUndone should be False because it is not yet        'undone. When your Do method gets called and the        'undo unit is transferred to the redo stack, you toggle the flag       'and m_bUndone will be True. You initialize m_bUndone as False        'because the undo unit first exists on the undo stack.       'During a rollback, (someone calls EndUndoScope(nID, *False*)),        'VBAUndoUnit's Do method will get called with IVBUndoManager set        'to Nothing. In that case, VBAUndoUnit cannot and should not        'attempt to add an undo unit to the passed in Undo manager.        'Always check for pMgr = "Is Nothing" inside of your Do method. Private Sub Class_Initialize()       Debug.Print "VBAUndoUnit created..." End Sub Private Sub Class_Terminate()       Debug.Print "VBAUndoUnit purged..." End Sub Private Property Get IVBUndoUnit_Description() As String       Debug.Print "VBAUndoUnit.Description"       IVBUndoUnit_Description = "VBAUndoUnit" End Property Private Sub IVBUndoUnit_Do(ByVal pMgr As IVBUndoManager)       'Undo or redo, according to the state flag:       If (m_bUndone) Then             'Redo the original action:             ThisDocument.IncrementModuleVar       Else             'Undo the original action:             ThisDocument.DecrementModuleVar       End If       'Toggle the state flag:       m_bUndone = Not m_bUndone       If Not (pMgr Is Nothing) Then             'Add an an instance of VBAUndoUnit back to the opposite                    stack             pMgr.Add Me             Debug.Print "VBAUndoUnit.Do called with an Undo manager"       Else             'Nothing left to do - we are in a rollback and will most              'likely soon be terminated...             Debug.Print "VBAUndoUnit.Do called WITHOUT an Undo                    manager"       End If       'Confirm results of undo by printing the value of the              GetModuleVar        'variable       Debug.Print "After VBAUndoUnit.Do - GetModuleVar = " & _             ThisDocument.GetModuleVar End Sub Private Sub IVBUndoUnit_OnNextAdd()       'OnNextAdd gets called when the next unit in the same scope gets        'added to the undo stack.       Debug.Print "VBAUndoUnit.OnNextAdd" End Sub Private Property Get IVBUndoUnit_UnitSize() As Long       'UnitSize should return an approximate in memory size (in bytes)        'of the undo unit itself plus anything it holds on to. This        'allows Visio to use a memory size measurement to decide when to        'purge undo.        Debug.Print "VBAUndoUnit.UnitSize"       IVBUndoUnit_UnitSize = 4 End Property Private Property Get IVBUndoUnit_UnitTypeCLSID() As String       'Return a CLSID string here if you think it's important to be       'able to identify your units. If you have several different types       'of units, you could return the same CLSID for all of them, but        'choose different Long IDs for each.       Debug.Print "VBAUndoUnit.UnitTypeCLSID"       IVBUndoUnit_UnitTypeCLSID = Null End Property Private Property Get IVBUndoUnit_UnitTypeLong() As Long            'Return a Long here if you want to identify your units. See        'discussion in UnitTypeCLSID.       Debug.Print "VBAUndoUnit.UnitTypeLong"       IVBUndoUnit_UnitTypeLong = 0 End Property 



Developing Microsoft Visio Solutions 2001
Developing Microsoft Visio Solutions (Pro-Documentation)
ISBN: 0735613532
EAN: 2147483647
Year: 2004
Pages: 180

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net