Al verschillende malen ben ik tegen het probleem aangelopen dat ik graag een undo-/redo-functie in een applicatie zou willen implementeren, maar niet zo best weet hoe ik dat moet aanpakken.
In edit controls is standaard een undo-mogelijkheid aanwezig in de vorm van de WM_CANUNDO en WM_UNDO messages. Als je een tweede keer een WM_UNDO message zendt naar een edit control, wordt de laatste undo-opdracht ongedaan gemaakt, waarmee dit hetzelfde is als redo. Nu zijn edit controls helaas de enige controls die standaard een undo-functie kennen en dan nog niet eens als een multi-level undo (dus meerdere bewerkingen ongedaan maken). Dat lijkt in de verste verte niet op de mogelijkheden in bijvoorbeeld Microsoft Excel. Nu hoeft het niet zo prachtig te zijn als Excel het doet, maar basic undo-functionaliteit lijkt me toch wel prettig.
De meest logische oplossing die ik kan verzinnen om undo/redo te implementeren is een soort stack of FIFO-buffer optuigen waar iedere bewerking die de gebruiker uitvoert in wordt bijgehouden. Voor iedere bewerking moet een inverse bewerking zijn gedefinieerd, die overeenkomt met het ongedaan maken van de bewerking. Wil de gebruiker drie keer undo doen, dan voer je de inverse bewerking uit van de laatste drie bewerkingen in de undo-buffer.
Klinkt eenvoudig, maar in de praktijk is het volgens mij heel lastig. Hoe doe je bijvoorbeeld een ‘undo’ bij een zoek-en-vervangactie in een tekstdocument? En hoe maak je een databasebewerking ongedaan als er ook nog andere gebruikers in die database actief zijn?
Hoe pakken jullie dit aan?
In edit controls is standaard een undo-mogelijkheid aanwezig in de vorm van de WM_CANUNDO en WM_UNDO messages. Als je een tweede keer een WM_UNDO message zendt naar een edit control, wordt de laatste undo-opdracht ongedaan gemaakt, waarmee dit hetzelfde is als redo. Nu zijn edit controls helaas de enige controls die standaard een undo-functie kennen en dan nog niet eens als een multi-level undo (dus meerdere bewerkingen ongedaan maken). Dat lijkt in de verste verte niet op de mogelijkheden in bijvoorbeeld Microsoft Excel. Nu hoeft het niet zo prachtig te zijn als Excel het doet, maar basic undo-functionaliteit lijkt me toch wel prettig.
De meest logische oplossing die ik kan verzinnen om undo/redo te implementeren is een soort stack of FIFO-buffer optuigen waar iedere bewerking die de gebruiker uitvoert in wordt bijgehouden. Voor iedere bewerking moet een inverse bewerking zijn gedefinieerd, die overeenkomt met het ongedaan maken van de bewerking. Wil de gebruiker drie keer undo doen, dan voer je de inverse bewerking uit van de laatste drie bewerkingen in de undo-buffer.
Klinkt eenvoudig, maar in de praktijk is het volgens mij heel lastig. Hoe doe je bijvoorbeeld een ‘undo’ bij een zoek-en-vervangactie in een tekstdocument? En hoe maak je een databasebewerking ongedaan als er ook nog andere gebruikers in die database actief zijn?
Hoe pakken jullie dit aan?
Een goede grap mag vrienden kosten.