Important: The information in this document is obsolete and should not be used for new development.
Recipes--The Clipboard
The recipes and sample code in this section demonstrate how to interact with the Macintosh Clipboard (a general outline), how to create a Clipboard view to display your private scrap types, and how to implement Cut, Copy, Clear, and Paste commands for your data types.Interacting With the Macintosh Clipboard--A General Outline
This outline describes how a MacApp application interacts with the Clipboard.
- An application defines one or more scrap type identifiers, if needed, for its private Clipboard data types. This is described in "Define a Scrap Type for Your Clipboard Data," beginning on page 509.
- When the application is first launched, it looks on the desk scrap for data of its own private desk scrap type(s). If it finds any, it extracts the data and creates a view to display it. It may or may not need to create a document object to associate with the view. To perform these actions, you override
MakeViewForAlienClipboard
in theTYourApplication
method (described in "Override the MakeViewForAlienClipboard Method," beginning on page 509).- When a user cuts or copies data to the Clipboard, the application normally creates a command to handle the operation. The command's
DoIt
method creates a view to display the cut or copied data, then callsClaimClipboard
to install the view as the command's current Clipboard view and also as the Clipboard manager's current Clipboard view. If the user chooses to undo or redo the command, MacApp takes care of switching between the current and undo Clipboard views, as appropriate. (See "Recipe--Supporting the Cut, Copy, and Clear Commands," beginning on page 514.)- Any application view that allows pasting overrides
DoSetupMenus
and, for each private or public data type it can paste, starting with its preferred type, calls the global Clipboard manager'sCanPaste
method (as described in "Override the DoSetupMenus Method in Your View Class," beginning on page 522).- When a user quits the application or switches to another application, MacApp calls the Clipboard manager's
AboutToLoseControl
method. That method calls the current Clipboard view'sWriteToDeskScrap
method. Any view you install as a Clipboard view should overrideWriteToDeskScrap
to write its private data types and possibly write some of the standard scrap types as well. Your view should also overrideGivePasteData
to provide its available data in handle format based on the requested data type. (These two steps are described in the recipe that follows.)- When the application is switched back in, MacApp calls the Clipboard manager's
RegainControl
method. If the data on the desk scrap has changed,RegainControl
generates a call toMakeViewForAlienClipboard
, which functions as described in step 2.
Recipe--Creating a Clipboard View for Your Private Data Type
When your application is first launched, and again whenever your application is switched in and there is new data on the desk scrap, MacApp calls theMakeViewForAlienClipboard
method of your application object. This method looks on the desk scrap for data in your application's private desk scrap type. If it finds any, it extracts the data and creates a view to display it. It may or may not need to create a document object to associate with the view.If
MakeViewForAlienClipboard
doesn't find your private scrap type on the desk scrap, it callsInherited
to let MacApp's default Clipboard support handle the standard data types.To create a Clipboard view for your private scrap type, you perform these steps:
The sample code shown in this recipe is from the IconEdit application.
- Define a scrap type for your Clipboard data.
- Override the
MakeViewForAlienClipboard
method in your application class.
- If the application's private scrap type is available: load the data from the desk scrap; create a view object to display the data for the Clipboard view; if necessary, create a document object to associate with the view.
- If the application's private scrap type is not available, call
Inherited
to let theMakeViewForAlienClipboard
method ofTApplication
supply a Clipboard view.
- Include the Show Clipboard command in your resource definition file.
- Override the
WriteToDeskScrap
method of your view class.- Override the
ContainsClipType
method of your view class.- Override the
GivePasteData
method of your view class.
Define a Scrap Type for Your Clipboard Data
The scrap type is a resource type specified by a four-character string. Unless you are sharing Clipboard data types with other applications, you should define a unique string for your data type. For example, the IconEdit sample program defines this constant:
const ResType kIconClipType = 'ICON'; // Your private Clipboard data type.It is a good idea to register your scrap type identifiers with Apple Computer's Developer Technical Services to avoid conflict with identifiers used by other applications (for details on how to do so, see the note on page 501).Override the MakeViewForAlienClipboard Method
MacApp calls theMakeViewForAlienClipboard
method of the application object to give your application a chance to look for its private data types on the desk scrap. If a private scrap type is available,MakeViewForAlienClipboard
loads the data from the desk scrap, creates a view object to display the data for the Clipboard view, and, if necessary, creates a document object to associate with the view.The display view is usually the same type as the view that would display similar data in the application. This makes it convenient to retrieve and display Clipboard data in your application's private format. For example, if icon data is present on the desk scrap, the
MakeViewForAlienClipboard
method of theTIconEditApplication
class, shown next, creates aTIconDocument
object to load and store the icon data and aTIconEditView
object to display the data.When there is no icon data present, the
MakeViewForAlienClipboard
method callsInherited
to let theTApplication
class supply a Clipboard view.
TView* TIconEditApplication::MakeViewForAlienClipboard() { long offset; // Does the scrap contain icon data? if (GetScrap(NULL, kIconClipType, &offset) > 0) { // Create a document object to load and store the data. TIconDocument*clipDocument = NULL; TIconEditView* clipView = NULL; clipDocument = new TIconDocument; clipDocument->IIconDocument(NULL); // Install failure handler to free the document object in // case an error occurs. FailInfo fi; Try(fi) { // Call a method of the document to get the icon data. clipDocument->ReturnBitMap()->LoadFromScrap(); // Create a view to display the icon in the Clipboard view. clipView = new TIconEditView; clipView->IIconEditView(clipDocument, NULL, gZeroVPt, 1); // No error occurred, so we're done with the error handler. fi.Success(); } else { // An error occurred, so free the document object and pass // the failure handler on for any other necessary cleanup. clipDocument = (TIconDocument*)FreeIfObject(clipDocument); fi.ReSignal(); } // If no error, return the view created to serve as // the Clipboard view. return clipView; } else { // The desk scrap didn't contain icon data, so use MacApp's // default method in the TApplication class to supply a view. return Inherited::MakeViewForAlienClipboard(); } } // TIconEditApplication::MakeViewForAlienClipboardTheTIconDocument
class ReturnBitMap method returns the document'sfIconBitMap
field. TheTIconBitMap::LoadFromScrap
method reads data from the desk scrap as follows:
void TIconBitMap::LoadFromScrap() { long offset; long err; // Load the icon data. (It's always there if this method is called.) err = GetScrap(fDataHandle, kIconClipType, &offset); // If we could not read data, cause a failure and display the error. if (err < 0) FailOSErr((short) err); }The code in the LoadFromScrap method is simple for two reasons:
- The MakeViewForAlienClipboard method has already determined that there is icon data on the desk scrap.
- Icon bitmap data is always the same length.
Include the Show Clipboard Command in Your Resource File
Since your application is supplying a view to display and manipulate Clipboard data, you might as well let the user show that view. To do so, your application needs a Show Clipboard menu item. MacApp's default Edit menu contains the Show Clipboard menu item and can be included in your resource definition file with the following line:
include "Defaults.rsrc" 'CMNU' (mEdit);MacApp defines thecShowClipboard
command constant and automatically handles this command when the user chooses it from the Edit menu.Override the WriteToDeskScrap Method of Your View Class
When the user chooses to quit your application or switches to another application, your application should convert its private scrap type to a standard data type that other applications can use. The view class you use for displaying Clipboard data should override theWriteToDeskScrap
method so that when it serves as a Clipboard view, it can write both your application's private data and whatever standard data types the application supports.In the IconEdit application, the
WriteToDeskScrap
method of theTIconEditView
class calls theWriteToScrap
method of the icon document's bitmap. It then callsInherited
to write the view as a picture (for display by other applications, which can't be expected to understand icon data).
void TIconEditView::WriteToDeskScrap() { // Write the icon data to the Clipboard, then call Inherited to // write the view in 'PICT' format. fIconDocument->ReturnBitMap()->WriteToScrap(); Inherited::WriteToDeskScrap(); }TheTIconBitMap::WriteToScrap
method writes its data as follows:
void TIconBitMap::WriteToScrap() { // Write the handle to the desk scrap, failing if an error occurs. FailOSErr(gClipboardMgr->PutDeskScrapData(kIconClipType, fDataHandle)); }ThePutDeskScrapData
method calls the Toolbox routinePutScrap
to write the passed data to the desk scrap.Override the ContainsClipType Method of Your View Class
When you supply a view to display Clipboard data, that view should override theContainsClipType
method. MacApp callsContainsClipType
to determine whether the view contains a specific type of Clipboard data. This is the ContainsClipType method from the TIconEditView class:
Boolean TIconEditView::ContainsClipType(ResType aType) { return (aType == kIconClipType); }When a TIconEditView object is used for the Clipboard view, it always contains icon data and it only contains icon data. Therefore ContainsClipType returnsTRUE
when asked if it contains icon data andFALSE
for any other data type. If your view class can contain multiple data types, your version of ContainsClipType should returnTRUE
for any currently available data type.Override the GivePasteData Method of Your View Class
Because the IconEdit application works with simple views containing a fixed-size icon bitmap, the TIconEditView class does not need to overrideGivePasteData
. In addition, theTView::GivePasteData
method will retrieve requested data types from the desk scrap, a practice that may be sufficient for some applications. However, you may wish to override theGivePasteData
method in your view class to provide the view's private data type in an efficient manner. Your version ofGivePasteData
would look something like the following:
long TYourView::GivePasteData (Handle aDataHandle, ResType dataType) { long returnErr = noErr; // If the passed data type matches one of your private types, call // a utility method to put the data in the passed handle. if (dataType == kMyPreferredClipType) returnErr = this->GetDataHandle(aDataHandle, dataType); else { // The data may be available on the desk scrap. returnErr = Inherited::GivePasteData(aDataHandle, dataType); } return returnErr; }The implementation of GetDataHandle is specific to your application. For another example of theGivePasteData
method, see MacApp'sTTEView
class.Recipe--Supporting the Cut, Copy, and Clear Commands
The Cut, Copy, and Clear commands work as follows:
A closely related command, Paste, copies the current contents of the Clipboard into a view (and its document).
- The Cut command removes the selected information from a view (and generally also from its document) and places the information in the Clipboard.
- The Copy command copies the selected information to the Clipboard but does not remove the original from the view or document.
- The Clear command removes the original but does not copy the selected information to the Clipboard.
Because there is some similarity in the operations performed by the Cut, Copy, and Clear menu commands, you may be able to handle them with a single command class. For example, the IconEdit application defines one command class to handle Cut, Copy, and Clear, and a separate class to handle the Paste command. (The Paste command is described in "Recipe--Implementing a Paste Command," beginning on page 521.)
As with other menu commands, your application handles Cut, Copy, and Clear by defining a command class and overriding the
DoIt
,RedoIt
, andUndoIt
methods. When the user chooses one of these commands, MacApp calls theDoMenuCommand
method of the current target object, passing thecCut
,cCopy
, orcClear
command constant. You override theDoMenuCommand
method in an event-handling class to respond to each of these messages by creating and initializing a command object. The command class also enables the menu items in itsDoSetupMenus
method. Recipes that show the basics of working with menus and commands are located in Chapter 12, "Working With Menus," and Chapter 13, "Working With Events and Commands."To support the Cut, Copy, and Clear menu commands for your data types, you perform these steps:
The sample code shown in this recipe is from the IconEdit application.
- Override the
DoSetupMenus
method in your view class to enable the Cut, Copy, and Clear menu items, when appropriate.- Override the
DoMenuCommand
method in your view class to create, initialize, and post a command object to handle Cut, Copy, or Clear.- Define a command class to handle Cut, Copy, and Clear.
- Implement constructor and destructor methods.
- Implement an initialization method.
- Implement a
DoIt
method.
- For Cut or Copy, create a view to display the cut or copied data in the Clipboard.
- Copy or delete the data from your view's document object.
- For Cut or Copy, call the
ClaimClipboard
method of the global Clipboard manager object to install the view in the Clipboard.
- Implement
UndoIt
andRedoIt
methods to make Clipboard operations undoable.
Override DoSetupMenus in Your View Class
The following is the DoSetupMenus method for the TIconEditView class:
void TIconEditView::DoSetupMenus() { Inherited::DoSetupMenus();// Set up inherited menus. // Enable Zoom Out if not at smallest size. Enable(cZoomOut, fMagnification > 1); Enable(cZoomIn, TRUE);// Can always zoom in. Enable(cSetColor, TRUE);// Can always set the color. Enable(cCut, TRUE); // Always enable the Cut command. Enable(cCopy, TRUE); // Always enable the Copy command. Enable(cClear, TRUE);// Always enable the Clear command. // This view can paste 'ICON' data. gClipboardMgr->CanPaste(kIconClipType); }In the IconEdit application, the current icon can always be cut, copied, or cleared. For more complicated views that may contain more than one item, you normally enable these menu items only if there is at least one selected item in the view that can be cut, copied, or cleared.Your view may also be able to paste more than one data type. If so, your DoSetupMenus method can call CanPaste more than once.
- IMPORTANT
- If your DoSetupMenus method calls CanPaste more than once, you should pass your preferred data type first, then your next most preferred type, and so on, down to your least preferred type.
Override DoMenuCommand in Your View Class
The following is theDoMenuCommand
method for the TIconEditView class:
void TIconEditView::DoMenuCommand(CommandNumber aCommandNumber) { TIconEditCommand*anIconEditCommand; TIconPasteCommand*anIconPasteCommand; // Look for command numbers we can handle. switch (aCommandNumber) { case cCut: case cCopy: case cClear: { // Use TIconEditCommand object for cut, copy, or clear. anIconEditCommand = new TIconEditCommand; anIconEditCommand->IIconEditCommand(aCommandNumber, this, fIconDocument); this->PostCommand(anIconEditCommand); break; } case cPaste: { // Post a TIconPasteCommand object to handle paste. anIconPasteCommand = new TIconPasteCommand; anIconPasteCommand->IIconPasteCommand(this, fIconDocument); this->PostCommand(anIconPasteCommand); break; } default: // If we can't handle the command, pass it on. Inherited::DoMenuCommand(aCommandNumber); break; } } // TIconEditView::DoMenuCommandThis method creates, initializes, and posts a TIconEditCommand command object to handle the command numberscCut
,cCopy
, andcClear
. When the command object is initialized, it stores the command number in itsfIdentifier
field; during execution, it usesfIdentifier
to determine which operation to perform.Define a Command Class to Handle Cut, Copy, and Clear
The IconEdit application uses a single command class,TIconEditCommand
, to handle the Cut, Copy, and Clear menu commands. TheTIconEditCommand
class is defined as follows:
class TIconEditCommand : public TCommand { MA_DECLARE_CLASS; protected: TIconDocument*fIconDocument;// Document affected by command. TIconEditView*fIconEditView;// View in which editing happens. TIconBitMap*fSavedBitMap;// Saved state for undo/redo. public: TIconEditCommand(); // Constructor. virtual ~TIconEditCommand();// Destructor. virtual void IIconEditCommand(CommandNumberitsCommandNumber, TIconEditView*itsIconEditView, TIconDocument*itsIconDocument); virtual void DoIt(); // Override. virtual void RedoIt(); // Override. virtual void UndoIt(); // Override. };If your application has more complicated data types than the IconEdit application (a likely scenario), you may require more than one command class to handle the Cut, Copy, and Clear commands.Implement Constructor and Destructor Methods
The constructor method for TIconEditCommand sets its fields to safe values:
TIconEditCommand::TIconEditCommand() { fIconDocument = NULL; fIconEditView = NULL; fSavedBitMap = NULL; }The TIconEditCommand destructor method frees the saved bitmap (used for undoing and redoing):
TIconEditCommand::~TIconEditCommand() { // Free the saved bitmap. fSavedBitMap = (TIconBitMap*)FreeIfObject(fSavedBitMap); }Implement an Initialization Method
The IIconEditCommand initialization method for the TIconEditCommand class is defined as follows:
void TIconEditCommand::IIconEditCommand ( CommandNumberitsCommandNumber, TIconEditView*itsIconEditView, TIconDocument*itsIconDocument) { // Initialize the parent command class. this->ICommand(itsCommandNumber, itsIconDocument, kCanUndo, kCausesChange, itsIconDocument); // Set other fields based on command number: // Cut or Copy (anything but Clear) changes the Clipboard. // Cut or Clear (anything but Copy) changes the document. fChangesClipboard = (itsCommandNumber != cClear); fCausesChange = (itsCommandNumber != cCopy); // Set references and save a copy of the current icon bitmap. fIconEditView = itsIconEditView; fIconDocument = itsIconDocument; fSavedBitMap = fIconDocument->ReturnBitMap()->Copy(); } // TIconEditCommand::IIconEditCommandThis method sets the fChangesClipboard and fCausesChange fields based on the command number, because only the Cut and Copy commands put something on the Clipboard, and only the Cut and Clear commands change the view and document by deleting data.Implement a DoIt Method
TheDoIt
method of the command object performs different steps, depending on the command'sfIdentifier
field. ForcCut
orcCopy
it performs these steps:
For
- It creates a view to display the cut or copied data in the Clipboard.
- It calls the
ClaimClipboard
method of the global Clipboard manager object to install the view in the Clipboard.- It copies the data to the Clipboard view.
cCut
, it performs this additional step; forcClear
, it performs only this step:
The
- It deletes the data from the view's document object. (The document object should update the view to remove the cut or copied data from its display.)
DoIt
method for the TIconEditCommand class is shown on the following page.
void TIconEditCommand::DoIt() { // Need Clipboard view only if command is Cut or Copy. if (fIdentifier != cClear) { TIconDocument*clipDocument = NULL; TIconEditView*clipView = NULL; // Create a document to store data on the Clipboard. // If IIconDocument fails, it will free the document. clipDocument = new TIconDocument; clipDocument->IIconDocument(NULL); // If IIconEditView fails, it will free the view, but you // need to install a failure handler to free the document. FailInfo fi; Try(fi) { clipView = new TIconEditView; clipView->IIconEditView(clipDocument, NULL, gZeroVPt, fIconEditView->GetMagnification()); fi.Success();// Pop the failure handler. } else // Recover. { clipDocument = (TIconDocument*)FreeIfObject(clipDocument); fi.ReSignal();// Let other failure handlers also respond. } // Copy data to document icon. fSavedBitMap->CopyDataTo(clipDocument->ReturnBitMap()); // Tell the Clipboard manager we have a new Clipboard. this->ClaimClipboard(clipView); } // For a Cut or Clear command, clear the icon. if (fIdentifier != cCopy) fIconDocument->ClearIcon(); } // TIconEditCommand::DoItImplement UndoIt and RedoIt Methods
An advantage of MacApp's Clipboard support is that when a user chooses to undo or redo a command that affects the Clipboard, MacApp automatically changes between the do and undo Clipboard views. Your application deals only with its own view and document.The following is the UndoIt method for the TIconEditCommand class:
void TIconEditCommand::UndoIt() { // If the command was Cut or Clear, undo must restore the icon. if (fIdentifier != cCopy) { fSavedBitMap->CopyDataTo(fIconDocument->ReturnBitMap()); // Make sure all views get redrawn. fIconDocument->RedrawViews(); } }This method examines thefIdentifier
field to determine whether the current command is a Cut, Copy, or Clear command. For Copy, there is no change to the document or view--only to the Clipboard, and that is handled automatically by MacApp. For Cut or Clear, the saved icon bitmap is restored.The
RedoIt
method is even simpler. For a Copy command, no change is required. For a Cut or Clear command, because the command already has a copy of the cleared icon in its fSavedBitMap field, RedoIt has only to clear the icon:
void TIconEditCommand::RedoIt() { // If the command was Cut or Clear, clear the icon. if (fIdentifier != cCopy) fIconDocument->ClearIcon(); }Recipe--Implementing a Paste Command
The Paste command pastes data from the Clipboard into a view (and typically into the view's document). The Clipboard may contain data cut or copied from your application or from another application. The data may be available in your private format or in one of the standard formats (text and picture).To implement a Paste command for your data types, you perform these steps:
The sample code shown in this recipe is from the IconEdit application.
- Override the
DoSetupMenus
method in your view class to enable the Paste command.- Override the
DoMenuCommand
method in your view class to create, initialize, and post a Paste command object.- Define a command class to handle the paste operation.
- Implement constructor and destructor methods.
- Implement an initialization method.
- Implement a
DoIt
method that
- saves the current state of the view
- pastes the Clipboard data into the view
- Implement
UndoIt
andRedoIt
methods to make the paste operation undoable.
Override the DoSetupMenus Method in Your View Class
To enable the Paste command, you override theDoSetupMenus
method in your view class. Your version ofDoSetupMenus
calls the global Clipboard manager'sCanPaste
method to specify the types of data it can accept. If the current Clipboard view (or the desk scrap) contains data matching one of the specified types,CanPaste
enables the Paste command.The
DoSetupMenus
method of theTIconEditView
class is described in the previous recipe, in the section beginning on page 515. It shows how to callCanPaste
, specifying the icon data type.Override the DoMenuCommand Method in Your View Class
You override theDoMenuCommand
method in your view class to create, initialize, and post a command object to perform the paste operation. TheDoMenuCommand
method of theTIconEditView
class is described in the previous recipe, in the section beginning on page 516. It shows how to create, initialize, and post aTIconPasteCommand
command object.Define a Command Class to Handle Paste
The IconEdit application defines the TIconPasteCommand command class to handle the Paste menu command:
class TIconPasteCommand : public TCommand { MA_DECLARE_CLASS; protected: TIconDocument*fIconDocument;// Document affected by command. TIconEditView*fIconEditView;// View in which pasting happens. TIconBitMap*fSavedIcon; // Saved state for undo/redo. public: TIconPasteCommand(); // Constructor. virtual ~TIconPasteCommand();// Destructor. virtual void IIconPasteCommand(TIconEditView* itsIconEditView, TIconDocument* itsIconDocument); virtual void DoIt(); // Override. virtual void UndoIt(); // Override. };Implement Constructor and Destructor Methods
The constructor method for TIconPasteCommand sets its fields to safe values:
TIconPasteCommand::TIconPasteCommand() { fIconDocument = NULL; fIconEditView = NULL; fSavedIcon = NULL; }The TIconPasteCommand destructor method frees the saved icon bitmap (used for undoing and redoing):
TIconPasteCommand::~TIconPasteCommand() { // Free the saved bitmap. fSavedIcon = (TIconBitMap*)FreeIfObject(fSavedIcon); }Implement an Initialization Method
The IIconPasteCommand initialization method for the TIconPasteCommand class is defined as follows:
void TIconPasteCommand::IIconPasteCommand(TIconEditView* itsIconEditView, TIconDocument* itsIconDocument) { // Initialize the parent command. this->ICommand(cPaste, itsIconDocument, kCanUndo, kCausesChange, itsIconDocument); fIconEditView = itsIconEditView; fIconDocument = itsIconDocument; TIconDocument* clipDoc = (TIconDocument*)gClipboardMgr->fClipView->fDocument; fSavedIcon = clipDoc->ReturnBitMap()->Copy(); } // TIconPasteCommand::IIconPasteCommandNote that unlike the initialization method for theTIconEditCommand
class shown in the previous recipe, the IIconPasteCommand method does not setfChangesClipboard
toTRUE
. That's because a TIconPasteCommand object extracts information from the Clipboard but doesn't change it.For a
TIconEditView
object, the Paste menu command is enabled only if there is icon data on the Clipboard. If there is icon data on the Clipboard, there must be a current Clipboard view and it must be aTIconEditView
object. Therefore the IIconPasteCommand method can access the Clipboard view, get its document, and copy the document's bitmap. This is accomplished by the following lines:
TIconDocument* clipDoc = (TIconDocument*)gClipboardMgr->fClipView->fDocument; fSavedIcon = clipDoc->ReturnBitMap()->Copy();
- Note
- A more careful programming style would suggest testing the various object references before dereferencing their fields and methods.
Implement a DoIt Method
TheDoIt
method for the TIconPasteCommand class is implemented as follows:
void TIconPasteCommand::DoIt() { TIconBitMap* tempIcon = fIconDocument->ReturnBitMap()->Copy(); fIconDocument->SetIcon(fSavedIcon); fSavedIcon = tempIcon; }This code performs three tasks:
As a result, the document's current icon bitmap is replaced by the pasted bitmap, but a copy is saved in the fSavedIcon field for undo and redo.
- It gets a copy of the current icon from the view's document.
- It sets the document's icon bitmap to the saved bitmap, which was stored by the initialization method. (In this case, the "saved" bitmap is actually the pasted bitmap from the Clipboard.) The call to
SetIcon
both sets the icon and causes the view to be redrawn.- It sets the saved icon bitmap to the one from the document.
Implement UndoIt and RedoIt Methods
TheUndoIt
method for the TIconPasteCommand command just calls theDoIt
method. As mentioned in the previous section, theDoIt
method simply switches the document's current icon bitmap with the one stored by the command, then causes the view to be redrawn.The TIconPasteCommand class doesn't override
RedoIt
, because the version ofRedoIt
defined inTCommand
already callsDoIt
, which for the TIconPasteCommand class switches the bitmaps and redraws the view.