⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainfrm.pas

📁 Java实例入门
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit MainFrm;

interface

uses
  SysUtils, Windows, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, Buttons, ExtCtrls, ColorGrd, StdCtrls, Menus, ComCtrls;

const
  crMove = 1;
type

  TDrawType = (dtLineDraw, dtRectangle, dtEllipse, dtRoundRect,
               dtClipRect, dtCrooked);

  TMainForm = class(TForm)
    sbxMain: TScrollBox;
    imgDrawingPad: TImage;
    pnlToolBar: TPanel;
    sbLine: TSpeedButton;
    sbRectangle: TSpeedButton;
    sbEllipse: TSpeedButton;
    sbRoundRect: TSpeedButton;
    pnlColors: TPanel;
    cgDrawingColors: TColorGrid;
    pnlFgBgBorder: TPanel;
    pnlFgBgInner: TPanel;
    Bevel1: TBevel;
    mmMain: TMainMenu;
    mmiFile: TMenuItem;
    mmiExit: TMenuItem;
    N2: TMenuItem;
    mmiSaveAs: TMenuItem;
    mmiSaveFile: TMenuItem;
    mmiOpenFile: TMenuItem;
    mmiNewFile: TMenuItem;
    mmiEdit: TMenuItem;
    mmiPaste: TMenuItem;
    mmiCopy: TMenuItem;
    mmiCut: TMenuItem;
    sbRectSelect: TSpeedButton;
    SaveDialog: TSaveDialog;
    OpenDialog: TOpenDialog;
    stbMain: TStatusBar;
    pbPasteBox: TPaintBox;
    sbFreeForm: TSpeedButton;
    RgGrpFillOptions: TRadioGroup;
    cbxBorder: TCheckBox;
    mmiHelp: TMenuItem;
    mmiAbout: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure sbLineClick(Sender: TObject);
    procedure imgDrawingPadMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure imgDrawingPadMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure imgDrawingPadMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure cgDrawingColorsChange(Sender: TObject);
    procedure mmiExitClick(Sender: TObject);
    procedure mmiSaveFileClick(Sender: TObject);
    procedure mmiSaveAsClick(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure mmiNewFileClick(Sender: TObject);
    procedure mmiOpenFileClick(Sender: TObject);
    procedure mmiEditClick(Sender: TObject);
    procedure mmiCutClick(Sender: TObject);
    procedure mmiCopyClick(Sender: TObject);
    procedure mmiPasteClick(Sender: TObject);
    procedure pbPasteBoxMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure pbPasteBoxMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure pbPasteBoxMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure pbPasteBoxPaint(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure RgGrpFillOptionsClick(Sender: TObject);
  public
    { Public declarations }
    MouseOrg: TPoint;    // 用于保存鼠标信息
    NextPoint: TPoint;   // 用于保存鼠标信息
    Drawing: Boolean;
    DrawType: TDrawType; // 用于保存绘画类型信息
    FillSelected,
    BorderSelected: Boolean;
    EraseClipRect: Boolean;
    Modified: Boolean;
    FileName: String;
    OldClipViewHwnd: Hwnd;
    { Paste Image variables }
    PBoxMoving: Boolean;
    PBoxMouseOrg: TPoint;
    PasteBitMap: TBitmap;
    Pasted: Boolean;
    LastDot: TPoint;

    procedure DrawToImage(TL, BR: TPoint; PenMode: TPenMode);
    { This procedure paints the image specified by the DrawType field
      to imgDrawingPad }
    procedure SetDrawingStyle;
    { This procedure sets various Pen/Brush styles based on values
      specified by the form's controls. The Panels and color grid is
      used to set these values }
    procedure CopyPasteBoxToImage;
    { This procedure copies the data pasted from the Windows clipboard
      onto the main image component imgDrawingPad }
    procedure WMDrawClipBoard(var Msg: TWMDrawClipBoard);
       message WM_DRAWCLIPBOARD;
    { This message handler captures the WM_DRAWCLIPBOARD messages
      which is sent to all windows that have been added to the clipboard
      viewer chain. An application can add itself to the clipboard viewer
      chain by using the SetClipBoardViewer() Win32 API function as
      is done in FormCreate() }
    procedure CopyCut(Cut: Boolean);
    { This method copies a portion of the main image, imgDrawingPad, to the
      Window's clipboard. }
  end;

var
  MainForm: TMainForm;

implementation
uses ClipBrd, Math;

{$R *.DFM}

procedure TMainForm.FormCreate(Sender: TObject);
{ This method sets the form's field to their default values. It then
  creates a bitmap for the imgDrawingPad.  This is the image on which
  drawing is done. Finally, it adds this application as part of the
  Windows clipboard viewer chain by using the SetClipBoardViewer()
  function. This makes enables the form to get WM_DRAWCLIPBOARD messages
  which are sent to all windows in the clipboard viewer chain whenever
  the clipboard data is modified. }
begin
  Screen.Cursors[crMove] := LoadCursor(hInstance, 'MOVE');

  FillSelected   := False;
  BorderSelected := True;

  Modified := False;
  FileName := '';
  Pasted := False;
  pbPasteBox.Enabled := False;

  // Create a bitmap for imgDrawingPad and set its boundaries
  with imgDrawingPad do
  begin
    SetBounds(0, 0, 600, 400);
    Picture.Graphic := TBitMap.Create;
    Picture.Graphic.Width := 600;
    Picture.Graphic.Height := 400;
  end;
  // Now create a bitmap image to hold pasted data
  PasteBitmap := TBitmap.Create;
  pbPasteBox.BringToFront;
  { Add the form to the Windows clipboard viewer chain. Save the handle
    of the next window in the chain so that it may be restored by the
    ChangeClipboardChange() Win32 API function in this form's
    FormDestroy() method. }
  OldClipViewHwnd := SetClipBoardViewer(Handle);
end;

procedure TMainForm.WMDrawClipBoard(var Msg: TWMDrawClipBoard);
begin
  { This method will be called whenever the clipboard data
    has changed. Because the main form was added to the clipboard
    viewer chain, it will receive the WM_DRAWCLIPBOARD message
    indicating that the clipboard's data was changed. }
  inherited;
  { Make sure that the data contained on the clipboard is actually
    bitmap data. }
  if ClipBoard.HasFormat(CF_BITMAP) then
    mmiPaste.Enabled := True
  else
    mmiPaste.Enabled := False;
  Msg.Result := 0;
end;


procedure TMainForm.DrawToImage(TL, BR: TPoint; PenMode: TPenMode);
{ 该过程用于执行指定的绘画操作,绘画操作由DrawType决定}
begin
  with imgDrawingPad.Canvas do   //在画布上绘画
  begin
    Pen.Mode := PenMode;  //指定笔模式

    case DrawType of
      dtLineDraw:     //画直线
        begin
          MoveTo(TL.X, TL.Y);
          LineTo(BR.X, BR.Y);
        end;
      dtRectangle:    //画矩形
        Rectangle(TL.X, TL.Y, BR.X, BR.Y);
      dtEllipse:      //画椭圆
        Ellipse(TL.X, TL.Y, BR.X, BR.Y);
      dtRoundRect:      //画圆角矩形
        RoundRect(TL.X, TL.Y, BR.X, BR.Y,
          (TL.X - BR.X) div 2, (TL.Y - BR.Y) div 2);
      dtClipRect:       //画剪裁区域
        Rectangle(TL.X, TL.Y, BR.X, BR.Y);
    end;
  end;
end;

procedure TMainForm.CopyPasteBoxToImage;
{ 这个过程复制从剪贴板粘贴到 imgDrawingPad
This method copies the image pasted from the Windows clipboard onto
  imgDrawingPad. It first erases any bounding rectangle drawn by PaintBox
  component, pbPasteBox. It then copies the data from pbPasteBox onto
  imgDrawingPad at the location where pbPasteBox has been dragged
  over imgDrawingPad. The reason we don't copy the contents of
  pbPasteBox's canvas and use PasteBitmap's canvas instead, is because
  when a portion of pbPasteBox is dragged out of the viewable area,
  Windows does not paint the portion pbPasteBox not visible. Therefore,
  it is necessary to the pasted bitmap from the off-screen bitmap }
var
  SrcRect, DestRect: TRect;
begin
  // 首先,擦除由pbPasteBox绘制的矩形
  with pbPasteBox do
  begin
    Canvas.Pen.Mode := pmNotXOR;
    Canvas.Pen.Style := psDot;
    Canvas.Brush.Style := bsClear;
    Canvas.Rectangle(0, 0, Width, Height);
    DestRect := Rect(Left, Top, Left+Width, Top+Height);
    SrcRect := Rect(0, 0, Width, Height);
  end;
  { Here we must use the PasteBitmap instead of the pbPasteBox because
    pbPasteBox will clip anything outside if the viewable area. }
  imgDrawingPad.Canvas.CopyRect(DestRect, PasteBitmap.Canvas, SrcRect);
  pbPasteBox.Visible := false;
  pbPasteBox.Enabled := false;
  Pasted := False;  // 完成粘贴操作
end;

procedure TMainForm.imgDrawingPadMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Modified := True;
  // Erase the clipping rectangle if one has been drawn
  if (DrawType = dtClipRect) and EraseClipRect then
    DrawToImage(MouseOrg, NextPoint, pmNotXOR)
  else if (DrawType = dtClipRect) then
    EraseClipRect := True; // Re-enable cliprect erasing

  { If an bitmap was pasted from the clipboard, copy it to the
    image and remove the PaintBox. }
  if Pasted then
    CopyPasteBoxToImage;

  Drawing := True;
  // Save the mouse information
  MouseOrg := Point(X, Y);
  NextPoint := MouseOrg;
  LastDot := NextPoint;   // Lastdot is updated as the mouse moves
  imgDrawingPad.Canvas.MoveTo(X, Y);
  stbMain.Panels[0].Text := Format('原始鼠标位置坐标:   (%d, %d)', [X, Y]);
end;

procedure TMainForm.imgDrawingPadMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
{ This method determines the drawing operation to be performed and
  either performs free form line drawing, or calls the
  DrawToImage method which draws the specified shape }
begin
  if Drawing then
  begin
    if DrawType = dtCrooked then
    begin
      imgDrawingPad.Canvas.MoveTo(LastDot.X, LastDot.Y);
      imgDrawingPad.Canvas.LineTo(X, Y);
      LastDot := Point(X,Y);
    end
    else begin
      DrawToImage(MouseOrg, NextPoint, pmNotXor);
      NextPoint := Point(X, Y);
      DrawToImage(MouseOrg, NextPoint, pmNotXor)
    end;
  end;
  // 以当前鼠标位置更新状态条
  stbMain.Panels[1].Text := Format('当前鼠标位置坐标:   (%d, %d)', [X, Y]);
end;

procedure TMainForm.imgDrawingPadMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Drawing then
  { Prevent the clipping rectangle from destroying the images already
    on the image }
    if not (DrawType = dtClipRect) then
      DrawToImage(MouseOrg, Point(X, Y), pmCopy);
  Drawing := False;
end;

procedure TMainForm.sbLineClick(Sender: TObject);
begin
  // First erase the cliprect if current drawing type
  if DrawType = dtClipRect then
     DrawToImage(MouseOrg, NextPoint, pmNotXOR);

  { Now set the DrawType field to that specified by the TSpeedButton
    invoking this method. The TSpeedButton's Tag values match a
    specific TDrawType value which is why the typecasting below
    successfully assigns a valid TDrawType value to the DrawType field. }
  if Sender is TSpeedButton then
    DrawType := TDrawType(TSpeedButton(Sender).Tag);

  // Now make sure the dtClipRect style doesn't erase previous drawings
  if DrawType = dtClipRect then begin
    EraseClipRect := False;
  end;
  // Set the drawing style
  SetDrawingStyle;
end;

procedure TMainForm.cgDrawingColorsChange(Sender: TObject);
{ This method draws the rectangle representing fill and border colors
  to indicate the users selection of both colors. pnlFgBgInner and
  pnlFgBgBorder are TPanels arranged one on to of the other for the
  desired effect }
begin
  pnlFgBgBorder.Color := cgDrawingColors.ForeGroundColor;
  pnlFgBgInner.Color := cgDrawingColors.BackGroundColor;
  SetDrawingStyle;
end;


procedure TMainForm.SetDrawingStyle;
{  This method sets the various drawing styles based on the selections

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -