
Bill likes to play with software. This drives other people nuts.
Everyone knows this.
have you wondered where that "Edit" button comes from?
let's go to some code
//***************************************************************************
//
// Copyright (c) 2006 Microsoft Corporation. All rights reserved.
// This code is licensed under the Visual Studio SDK license terms.
// THIS CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//***************************************************************************
using System;
using System.Collections.Generic;
using System.Text;
using System.CodeDom;
namespace Microsoft.VisualStudio.Tools.Applications.Samples.ShapeApp
{
#region Command Base Class
internal abstract class Command
{
internal abstract void Save(ICommandWriter w);
}
#endregion
#region Menu Based Commands
#region Main Menu Commands
#region File Menu Commands
internal class FileNewCommand : Command
{
/// <summary>
/// Generates code for the FileNewCommand object.
/// This method will generate code of the form:
/// this.NewDrawing();
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
CodeMethodInvokeExpression newMethodStatement =
new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "NewDrawing");
w.Write(newMethodStatement);
}
}
internal class FileOpenCommand : Command
{
private String fileName;
internal FileOpenCommand(String fileName)
{
this.fileName = fileName;
}
/// <summary>
/// Generates code for the FileOpenCommand object.
/// This method will generate code of the form:
/// this.LoadDrawing("fileName");
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
CodeMethodInvokeExpression loadMethodStatement =
new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "LoadDrawing", new CodePrimitiveExpression(this.fileName));
w.Write(loadMethodStatement);
}
}
internal class FileCloseCommand : Command
{
/// <summary>
/// Generates code for the FileCloseCommand object.
/// This method will generate code of the form:
/// this.ActiveDrawing.Close();
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
CodePropertyReferenceExpression drawingRef =
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "ActiveDrawing");
CodeMethodInvokeExpression closeMethodStatement =
new CodeMethodInvokeExpression(drawingRef, "Close");
w.Write(closeMethodStatement);
}
}
internal class FileCloseAllCommand : Command
{
/// <summary>
/// Generates code for the FileCloseAll object.
/// This method will generate code of the form:
/// for (;this.Drawings.Count > 0;)
/// {
/// this.Drawings[0].Close();
/// }
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
// Create references to Drawings, Drawings.Count and Drawings[0]
CodePropertyReferenceExpression drawingsRef =
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Drawings");
CodePropertyReferenceExpression countRef =
new CodePropertyReferenceExpression(drawingsRef, "Count");
CodeIndexerExpression drawingRef =
new CodeIndexerExpression(drawingsRef, new CodePrimitiveExpression(0));
// Create Initializer, Test Expression, and Increment Statement for iterator
CodeExpressionStatement initStatement =
new CodeExpressionStatement(new CodeSnippetExpression(String.Empty));
CodeBinaryOperatorExpression testExpression =
new CodeBinaryOperatorExpression(countRef, CodeBinaryOperatorType.GreaterThan, new CodePrimitiveExpression(0));
CodeExpressionStatement incrementStatement =
new CodeExpressionStatement(new CodeSnippetExpression(String.Empty));
// Create the statement to execute in the for loop.
CodeMethodInvokeExpression closeMethodStatement =
new CodeMethodInvokeExpression(drawingRef, "Close");
// Create the for loop.
CodeIterationStatement iteratorStatement =
new CodeIterationStatement(initStatement, testExpression, incrementStatement, new CodeExpressionStatement(closeMethodStatement));
w.Write(iteratorStatement);
}
}
internal class FileSaveCommand : Command
{
/// <summary>
/// Generates code for the FileSaveCommand object.
/// This method will generate code of the form:
/// this.ActiveDrawing.Save();
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
CodePropertyReferenceExpression drawingRef =
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "ActiveDrawing");
CodeMethodInvokeExpression saveMethodStatement =
new CodeMethodInvokeExpression(drawingRef, "Save");
w.Write(saveMethodStatement);
}
}
internal class FileSaveAllCommand : Command
{
/// <summary>
/// Generates code for the FileSaveAll object.
/// This method will generate code of the form:
/// int drawingIndex;
/// for (drawingIndex = 0; drawingIndex < this.Drawings.Count; drawingIndex = drawingIndex + 1)
/// {
/// this.Drawings[drawingIndex].Save();
/// }
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
// Declare and create a reference to drawingIndex
w.Declare(typeof(int), "drawingIndex");
CodeVariableReferenceExpression drawingIndexRef =
new CodeVariableReferenceExpression("drawingIndex");
// Create references to Drawings, Drawings.Count, and indexed drawings
CodePropertyReferenceExpression drawingsRef =
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Drawings");
CodePropertyReferenceExpression countRef =
new CodePropertyReferenceExpression(drawingsRef, "Count");
CodeIndexerExpression drawingRef =
new CodeIndexerExpression(drawingsRef, drawingIndexRef);
// Create Initializer, Test Expression, and Increment Statement for iterator
CodeAssignStatement initStatement =
new CodeAssignStatement(drawingIndexRef, new CodePrimitiveExpression(0));
CodeBinaryOperatorExpression testExpression =
new CodeBinaryOperatorExpression(drawingIndexRef, CodeBinaryOperatorType.LessThan, countRef);
CodeAssignStatement incrementStatement =
new CodeAssignStatement(drawingIndexRef,
new CodeBinaryOperatorExpression(drawingIndexRef, CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1)));
// Create the statement to run in the for loop
CodeMethodInvokeExpression saveStatement =
new CodeMethodInvokeExpression(drawingRef, "Save");
// Create the for loop
CodeIterationStatement iteratorStatement =
new CodeIterationStatement(initStatement, testExpression, incrementStatement, new CodeExpressionStatement(saveStatement));
// Write out the code
w.Write(iteratorStatement);
}
}
internal class FileExitCommand : Command
{
/// <summary>
/// Generates code for the FileExitCommand object.
/// This method will generate code of the form:
/// this.Quit();
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
CodeMethodInvokeExpression quitMethodStatement =
new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "Quit");
w.Write(quitMethodStatement);
}
}
#endregion
#region Windows Menu Commands
internal class WindowActivateCommand : Command
{
private int index;
internal WindowActivateCommand(int index)
{
this.index = index;
}
/// <summary>
/// Generates code for the WindowActivateCommand object.
/// This method will generate code of the form:
/// this.Drawings[index].Activate();
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
CodePropertyReferenceExpression drawingsRef =
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "Drawings");
CodeIndexerExpression drawingRef =
new CodeIndexerExpression(drawingsRef, new CodePrimitiveExpression(index));
CodeMethodInvokeExpression activateMethodStatement =
new CodeMethodInvokeExpression(drawingRef, "Activate");
w.Write(activateMethodStatement);
}
}
#endregion
#endregion
#region Object Based Commands
#region Drawing Commands
internal class DrawingShapeAddedCommand : Command
{
private IShape shape;
internal DrawingShapeAddedCommand(IShape shape)
{
this.shape = shape;
}
/// <summary>
/// Generates code for the DrawingShapeAddedCommand object.
/// This method will generate code of the form:
/// IShape newShape;
/// newShape = this.AvailableShapes["shapeName"].Clone()
/// newShape.Location = this.CreatePoint(x, y);
/// this.ActiveDrawing.Shapes.Add(newShape);
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
w.Declare(typeof(IShape), "newShape");
CodePropertyReferenceExpression drawingRef =
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "ActiveDrawing");
CodePropertyReferenceExpression shapesRef =
new CodePropertyReferenceExpression(drawingRef, "Shapes");
CodePropertyReferenceExpression availRef =
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "AvailableShapes");
CodeIndexerExpression shapesIndexer =
new CodeIndexerExpression(availRef, new CodePrimitiveExpression(shape.Name));
CodeMethodInvokeExpression cloneRef =
new CodeMethodInvokeExpression(shapesIndexer, "Clone");
CodeVariableReferenceExpression newShapeRef =
new CodeVariableReferenceExpression("newShape");
CodeAssignStatement shapeAssignStatement =
new CodeAssignStatement(newShapeRef, cloneRef);
w.Write(shapeAssignStatement);
CodeMethodInvokeExpression createPointStatement =
new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "CreatePoint",
new CodePrimitiveExpression(shape.Location.X),
new CodePrimitiveExpression(shape.Location.Y));
CodePropertyReferenceExpression shapeLocationRef =
new CodePropertyReferenceExpression(newShapeRef, "Location");
CodeAssignStatement locationAssignStatement =
new CodeAssignStatement(shapeLocationRef, createPointStatement);
w.Write(locationAssignStatement);
CodeMethodInvokeExpression addShape =
new CodeMethodInvokeExpression(shapesRef, "Add", newShapeRef);
w.Write(addShape);
}
}
internal class DrawingColorChangeCommand : Command
{
private Color color;
internal DrawingColorChangeCommand(Color color)
{
this.color = color;
}
/// <summary>
/// Generates code for the DrawingColorChangeCommand object.
/// This method will generate code of the form:
/// this.ActiveDrawing.BackgroundColor = this.CreateColor(argb);
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
CodePropertyReferenceExpression drawingRef =
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "ActiveDrawing");
CodePropertyReferenceExpression backgroundColorRef =
new CodePropertyReferenceExpression(drawingRef, "BackgroundColor");
CodeMethodInvokeExpression createColorStatement =
new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "CreateColor",
new CodePrimitiveExpression(System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B).ToArgb()));
CodeAssignStatement assignStatement =
new CodeAssignStatement(backgroundColorRef, createColorStatement);
w.Write(assignStatement);
}
}
internal class DrawingClearCommand : Command
{
/// <summary>
/// Generates code for the DrawingClearCommand object.
/// This method will generate code of the form:
/// this.ActiveDrawing.Shapes.Clear();
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
CodePropertyReferenceExpression drawingRef =
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "ActiveDrawing");
CodePropertyReferenceExpression shapesRef =
new CodePropertyReferenceExpression(drawingRef, "Shapes");
CodeMethodInvokeExpression clearMethodStatement =
new CodeMethodInvokeExpression(shapesRef, "Clear");
w.Write(clearMethodStatement);
}
}
#endregion
#region Shape Context Menu Commands
internal static class CommandHelper
{
public static CodeExpression SelectedShapeExpression(CodeExpression preFixExpression, int shapeIndex)
{
CodePropertyReferenceExpression drawingRef =
new CodePropertyReferenceExpression(preFixExpression == null ?
new CodeThisReferenceExpression() : preFixExpression, "ActiveDrawing");
CodePropertyReferenceExpression shapesRef =
new CodePropertyReferenceExpression(drawingRef, "Shapes");
CodeIndexerExpression shapeRef =
new CodeIndexerExpression(shapesRef, new CodePrimitiveExpression(shapeIndex));
return shapeRef;
}
public static CodeAssignStatement AssignColor(CodeExpression preFixExpression, Color color)
{
CodePropertyReferenceExpression colorRef =
new CodePropertyReferenceExpression(preFixExpression == null ?
new CodeThisReferenceExpression() : preFixExpression, "Color");
CodeMethodInvokeExpression createColorStatement =
new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "CreateColor",
new CodePrimitiveExpression(
System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B).ToArgb()));
CodeAssignStatement assignStatement =
new CodeAssignStatement(colorRef, createColorStatement);
return assignStatement;
}
}
internal class ShapeColorChangeCommand : Command
{
private int index;
private Color color;
internal ShapeColorChangeCommand(int index, Color color)
{
this.index = index;
this.color = color;
}
/// <summary>
/// Generates code for the ShapeColorChangeCommand object.
/// This method will generate code of the form:
/// this.ActiveDrawing.Shapes[index].Color = this.CreateColor(argb);
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
////refactored to one line
//CodePropertyReferenceExpression drawingRef =
// new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "ActiveDrawing");
//CodePropertyReferenceExpression shapesRef =
// new CodePropertyReferenceExpression(drawingRef, "Shapes");
//CodeIndexerExpression shapeRef =
// new CodeIndexerExpression(shapesRef, new CodePrimitiveExpression(index));
//CodePropertyReferenceExpression colorRef =
// new CodePropertyReferenceExpression(shapeRef, "Color");
////CodePropertyReferenceExpression colorRef =
//// new CodePropertyReferenceExpression(CommandHelper.SelectedShapeExpression(index), "Color");
//CodeMethodInvokeExpression createColorStatement =
// new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "CreateColor",
// new CodePrimitiveExpression(System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B).ToArgb()));
//CodeAssignStatement assignStatement =
// new CodeAssignStatement(colorRef, createColorStatement);
//w.Write(assignStatement);
w.Write(CommandHelper.AssignColor(
CommandHelper.SelectedShapeExpression(null,index),color));
}
}
internal class ShapeLocationChangeCommand : Command
{
private int index;
private Point location;
internal ShapeLocationChangeCommand(int index, Point location)
{
this.index = index;
this.location = location;
}
/// <summary>
/// Generates code for the ShapeLocationChangeCommand object.
/// This method will generate code of the form:
/// this.ActiveDrawing.Shapes[index].Location = this.CreatePoint(x, y);
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
CodePropertyReferenceExpression drawingRef =
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "ActiveDrawing");
CodePropertyReferenceExpression shapesRef =
new CodePropertyReferenceExpression(drawingRef, "Shapes");
CodeIndexerExpression shapeRef =
new CodeIndexerExpression(shapesRef, new CodePrimitiveExpression(index));
CodePropertyReferenceExpression locationRef =
new CodePropertyReferenceExpression(shapeRef, "Location");
CodeMethodInvokeExpression createPointStatement =
new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "CreatePoint",
new CodePrimitiveExpression(location.X),
new CodePrimitiveExpression(location.Y));
CodeAssignStatement assignStatement =
new CodeAssignStatement(locationRef, createPointStatement);
w.Write(assignStatement);
}
}
internal class ShapeSizeChangeCommand : Command
{
private int index;
private Size size;
internal ShapeSizeChangeCommand(int index, Size size)
{
this.index = index;
this.size = size;
}
/// <summary>
/// Generates code for the ShapeSizeChangeCommand object.
/// This method will generate code of the form:
/// this.ActiveDrawing.Shapes[index].Size = this.CreateSize(w, h);
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
CodePropertyReferenceExpression drawingRef =
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "ActiveDrawing");
CodePropertyReferenceExpression shapesRef =
new CodePropertyReferenceExpression(drawingRef, "Shapes");
CodeIndexerExpression shapeRef =
new CodeIndexerExpression(shapesRef, new CodePrimitiveExpression(index));
CodePropertyReferenceExpression sizeRef =
new CodePropertyReferenceExpression(shapeRef, "Size");
CodeMethodInvokeExpression createSizeStatement =
new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "CreateSize",
new CodePrimitiveExpression(size.Width),
new CodePrimitiveExpression(size.Height));
CodeAssignStatement assignStatement =
new CodeAssignStatement(sizeRef, createSizeStatement);
w.Write(assignStatement);
}
}
internal class ShapeDeleteCommand : Command
{
private int index;
internal ShapeDeleteCommand(int index)
{
this.index = index;
}
/// <summary>
/// Generates code for the ShapeDeleteCommand object.
/// This method will generate code of the form:
/// this.ActiveDrawing.Shapes.Remove(this.ActiveDrawing.Shapes[index]);
/// </summary>
/// <param name="w">The command writer to write the statement to.</param>
internal override void Save(ICommandWriter w)
{
CodePropertyReferenceExpression drawingRef =
new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "ActiveDrawing");
CodePropertyReferenceExpression shapesRef =
new CodePropertyReferenceExpression(drawingRef, "Shapes");
CodeIndexerExpression shapeRef =
new CodeIndexerExpression(shapesRef, new CodePrimitiveExpression(index));
CodeMethodInvokeExpression removeStatement =
new CodeMethodInvokeExpression(shapesRef, "Remove", shapeRef);
w.Write(removeStatement);
}
}
#endregion
#endregion
#endregion
#region Helper Methods
#endregion
}