скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Программа для рисования 2 (Paint)



Автор: Xavier Pacheco

{
Copyright © 1999 by Delphi 5 Developer's Guide - Xavier Pacheco and Steve Teixeira
}

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;
    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;    // Stores mouse information
    NextPoint: TPoint;   // Stores mouse information
    Drawing: Boolean;    // Drawing is being performed flag
    DrawType: TDrawType; // Holds the draw type information: TDrawType
    FillSelected,        // Fill shapes flag
    BorderSelected: Boolean;  // Draw Shapes with no border flag
    EraseClipRect: Boolean;     // Specifies whether or not to erase the
                                // clipping rectangle
    Modified: Boolean;     // Image modified flag
    FileName: String;      // Holds the filename of the image
    OldClipViewHwnd: Hwnd; // Holds the old clipboard view window
    { Paste Image variables }
    PBoxMoving: Boolean;   // PasteBox is moving flag
    PBoxMouseOrg: TPoint;  // Stores mouse coordinates for moving PasteBox
    PasteBitMap: TBitmap;  // Stores a bitmap image of the pasted data
    Pasted: Boolean;       // Data pasted flag
    LastDot: TPoint;       // Hold the TPoint coordinate for performing
                           // free line drawing
    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);
{ This method performs the specified drawing operation. The
  drawing operation is specified by the DrawType field }
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;
{ 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
  // First, erase the rectangle drawn by 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;  // Pasting operation is complete
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);
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;
  // Update the status bar with the current mouse location
  stbMain.Panels[1].Text := Format('X: %d, Y: %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
   on the pnlFillStyle TPanel for Fill and Border styles }
begin
  with imgDrawingPad do
  begin
    if DrawType = dtClipRect then
    begin
      Canvas.Pen.Style := psDot;
      Canvas.Brush.Style := bsClear;
      Canvas.Pen.Color := clBlack;
    end

    else if FillSelected then
      Canvas.Brush.Style := bsSolid
    else
      Canvas.Brush.Style := bsClear;

    if BorderSelected then
      Canvas.Pen.Style := psSolid
    else
      Canvas.Pen.Style := psClear;


    if FillSelected and (DrawType <> dtClipRect) then
     Canvas.Brush.Color := pnlFgBgInner.Color;

    if DrawType <> dtClipRect then
      Canvas.Pen.Color := pnlFgBgBorder.Color;
  end;
end;

procedure TMainForm.mmiExitClick(Sender: TObject);
begin
  Close; // Terminate application
end;

procedure TMainForm.mmiSaveFileClick(Sender: TObject);
{ This method saves the image to the file specified by FileName. If
  FileName is blank, however, SaveAs1Click is called to get a filename.}
begin
  if FileName = '' then
    mmiSaveAsClick(nil)
  else begin
    imgDrawingPad.Picture.SaveToFile(FileName);
    stbMain.Panels[0].Text := FileName;
    Modified := False;
  end;
end;

procedure TMainForm.mmiSaveAsClick(Sender: TObject);
{ This method launches SaveDialog to get a file name to which
  the image's contents will be saved. }
begin
  if SaveDialog.Execute then
  begin
    FileName := SaveDialog.FileName;  // Store the filename
    mmiSaveFileClick(nil)
  end;
end;

procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
{ If the user attempts to close the form before saving the image, they
  are prompted to do so in this method. }
var
  Rslt: Word;
begin
  CanClose := False; // Assume fail.
  if Modified then begin
    Rslt := MessageDlg('File has changed, save?', mtConfirmation, mbYesNOCancel, 0);
    case Rslt of
      mrYes: mmiSaveFileClick(nil);
      mrNo: ;  // no need to do anything.
      mrCancel: Exit;
    end
  end;
  CanClose := True;    // Allow use to close application
end;

procedure TMainForm.mmiNewFileClick(Sender: TObject);
{ This method erases any drawing on the main image after prompting the
  user to save it to a file in which case the mmiSaveFileClick event handler
  is called. }
var
  Rslt: Word;
begin
  if Modified then begin
    Rslt := MessageDlg('File has changed, save?', mtConfirmation, mbYesNOCancel, 0);
    case Rslt of
      mrYes: mmiSaveFileClick(nil);
      mrNo: ;  // no need to do anything.
      mrCancel: Exit;
    end
  end;

   with imgDrawingPad.Canvas do begin
     Brush.Style := bsSolid;
     Brush.Color := clWhite;  // clWhite erases the image
     FillRect(ClipRect);      // Erase the image
     FileName := '';
     stbMain.Panels[0].Text := FileName;
   end;
   SetDrawingStyle;   // Restore the previous drawing style
   Modified := False;
end;

procedure TMainForm.mmiOpenFileClick(Sender: TObject);
{ This method opens a bitmap file specified by OpenDialog.FileName. If
  a file was already created, the user is prompted to save
  the file in which case the mmiSaveFileClick event is called. }
var
  Rslt: Word;
begin

  if OpenDialog.Execute then
  begin

    if Modified then begin
      Rslt := MessageDlg('File has changed, save?', mtConfirmation, mbYesNOCancel, 0);
      case Rslt of
        mrYes: mmiSaveFileClick(nil);
        mrNo: ;  // no need to do anything.
        mrCancel: Exit;
      end
    end;

    imgDrawingPad.Picture.LoadFromFile(OpenDialog.FileName);
    FileName := OpenDialog.FileName;
    stbMain.Panels[0].Text := FileName;
    Modified := false;
   end;

end;

procedure TMainForm.mmiEditClick(Sender: TObject);
{ The timer is used to determine if an area on the main image is
  surrounded by a bounding rectangle. If so, then the Copy and Cut
  menu items are enabled. Otherwise, they are disabled. }
var
  IsRect: Boolean;
begin
  IsRect := (MouseOrg.X <> NextPoint.X) and (MouseOrg.Y <> NextPoint.Y);
  if (DrawType = dtClipRect) and IsRect then
  begin
    mmiCut.Enabled := True;
    mmiCopy.Enabled := True;
  end
  else begin
    mmiCut.Enabled := False;
    mmiCopy.Enabled := False;
  end;
end;

procedure TMainForm.CopyCut(Cut: Boolean);
{ This method copies a portion of the main image to the clipboard.
  The portion copied is specified by a bounding rectangle
  on the main image. If Cut is true, the area in the bounding rectandle
  is erased. }
var
   CopyBitMap: TBitmap;
   DestRect, SrcRect: TRect;
   OldBrushColor: TColor;
begin
  CopyBitMap := TBitMap.Create;
  try
    { Set CopyBitmap's size based on the coordinates of the
      bounding rectangle }
    CopyBitMap.Width := Abs(NextPoint.X - MouseOrg.X);
    CopyBitMap.Height := Abs(NextPoint.Y - MouseOrg.Y);
    DestRect := Rect(0, 0, CopyBitMap.Width, CopyBitmap.Height);
    SrcRect := Rect(Min(MouseOrg.X, NextPoint.X)+1,
                    Min(MouseOrg.Y, NextPoint.Y)+1,
                    Max(MouseOrg.X, NextPoint.X)-1,
                    Max(MouseOrg.Y, NextPoint.Y)-1);
    { Copy the portion of the main image surrounded by the bounding
      rectangle to the Windows clipboard }
    CopyBitMap.Canvas.CopyRect(DestRect, imgDrawingPad.Canvas, SrcRect);
    { Previous versions of Delphi required the bitmap's Handle property
      to be touched for the bitmap to be made available. This was due to
      Delphi's caching of bitmapped images. The step below may not be
      required. }
    CopyBitMap.Handle;
    // Assign the image to the clipboard.
    ClipBoard.Assign(CopyBitMap);
    { If cut was specified the erase the portion of the main image
      surrounded by the bounding Rectangle }
    if Cut then
      with imgDrawingPad.Canvas do
      begin
        OldBrushColor := Brush.Color;
        Brush.Color := clWhite;
        try
          FillRect(SrcRect);
        finally
          Brush.Color := OldBrushColor;
        end;
      end;
  finally
    CopyBitMap.Free;
   end;
end;

procedure TMainForm.mmiCutClick(Sender: TObject);
begin
  CopyCut(True);
end;

procedure TMainForm.mmiCopyClick(Sender: TObject);
begin
  CopyCut(False);
 end;

procedure TMainForm.mmiPasteClick(Sender: TObject);
{ This method pastes the data contained in the clipboard to the
  paste bitmap. The reason it is pasted to the PasteBitmap, an off-
  screen bitmap, is so that the user can relocate the pasted image
  elsewhere on to the main image. This is done by having the pbPasteBox,
  a TPaintBox component, draw the contents of PasteImage. When the
  user if done positioning the pbPasteBox, the contents of TPasteBitmap
  is drawn to imgDrawingPad at the location specified by pbPasteBox's location.}
begin
  { Clear the bounding rectangle }

  pbPasteBox.Enabled := True;
  if DrawType = dtClipRect then
  begin
    DrawToImage(MouseOrg, NextPoint, pmNotXOR);
    EraseClipRect := False;
  end;

  PasteBitmap.Assign(ClipBoard);   // Grab the data from the clipboard
  Pasted := True;
  // Set position of pasted image to top left
  pbPasteBox.Left := 0;
  pbPasteBox.Top := 0;
  // Set the size of pbPasteBox to match the size of PasteBitmap
  pbPasteBox.Width := PasteBitmap.Width;
  pbPasteBox.Height := PasteBitmap.Height;

  pbPasteBox.Visible := True;
  pbPasteBox.Invalidate;
           end;

procedure TMainForm.pbPasteBoxMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
{ This method set's up pbPasteBox, a TPaintBox for being moved by the
  user when the left mouse button is held down }
begin
  if Button = mbLeft then
  begin
    PBoxMoving := True;
    Screen.Cursor := crMove;
    PBoxMouseOrg := Point(X, Y);
  end
  else
    PBoxMoving := False;
end;

procedure TMainForm.pbPasteBoxMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
{ This method moves pbPasteBox if the PBoxMoving flag is true indicating
  that the user is holding down the left mouse button and is dragging
  PaintBox }
begin
  if PBoxMoving then
  begin
    pbPasteBox.Left := pbPasteBox.Left + (X - PBoxMouseOrg.X);
    pbPasteBox.Top := pbPasteBox.Top + (Y - PBoxMouseOrg.Y);
  end;
end;

procedure TMainForm.pbPasteBoxMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
{ This method disables moving of pbPasteBox when the user lifts the left
  mouse button }
  if PBoxMoving then
  begin
     PBoxMoving := False;
     Screen.Cursor := crDefault;
  end;
  pbPasteBox.Refresh; // Redraw the pbPasteBox.
end;

procedure TMainForm.pbPasteBoxPaint(Sender: TObject);
{ The paintbox is drawn whenever the user selects the Paste option
  form the menu. pbPasteBox draws the contents of PasteBitmap which
  holds the image gotten from the clipboard. The reason for drawing
  PasteBitmap's contents in pbPasteBox, a TPaintBox class, is so that
  the user can also move the object around on top of the main image.
  In other words, pbPasteBox can be moved, and hidden when necessary. }
var
  DestRect, SrcRect: TRect;
begin
  // Display the paintbox only if a pasting operation occurred.
  if Pasted then
  begin
    { First paint the contents of PasteBitmap using canvas's CopyRect
      but only if the paintbox is not being moved. This reduces
      flicker }
    if not PBoxMoving then
    begin
      DestRect := Rect(0, 0, pbPasteBox.Width, pbPasteBox.Height);
      SrcRect := Rect(0, 0, PasteBitmap.Width, PasteBitmap.Height);
      pbPasteBox.Canvas.CopyRect(DestRect, PasteBitmap.Canvas, SrcRect);
    end;
    { Now copy a bounding rectangle to indicate that pbPasteBox is
      a moveable object. We use a pen mode of pmNotXOR because we
      must erase this rectangle when the user copies PaintBox's
      contents to the main image and we must preserve the original
      contents. }
    pbPasteBox.Canvas.Pen.Mode := pmNotXOR;
    pbPasteBox.Canvas.Pen.Style := psDot;
    pbPasteBox.Canvas.Brush.Style := bsClear;
    pbPasteBox.Canvas.Rectangle(0, 0, pbPasteBox.Width, pbPasteBox.Height);
  end;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  // Remove the form from the clipboard chain
  ChangeClipBoardChain(Handle, OldClipViewHwnd);
  PasteBitmap.Free; // Free the PasteBitmap instance
end;

procedure TMainForm.RgGrpFillOptionsClick(Sender: TObject);
begin
  FillSelected   := RgGrpFillOptions.ItemIndex = 0;
  BorderSelected := cbxBorder.Checked;
  SetDrawingStyle;
end;

end.
Скачать весь проект





Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook