458 lines
12 KiB
ObjectPascal
458 lines
12 KiB
ObjectPascal
{-----------------------------------------------------------------------------
|
|
The contents of this file are subject to the Mozilla Public License
|
|
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
http://www.mozilla.org/MPL/MPL-1.1.html
|
|
|
|
Software distributed under the License is distributed on an "AS IS" basis,
|
|
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
|
|
the specific language governing rights and limitations under the License.
|
|
|
|
The Original Code is: JvPictEdit.PAS, released on 2002-07-04.
|
|
|
|
The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev
|
|
Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev
|
|
Copyright (c) 2001,2002 SGB Software
|
|
All Rights Reserved.
|
|
|
|
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
|
|
located at http://jvcl.sourceforge.net
|
|
|
|
Known Issues:
|
|
-----------------------------------------------------------------------------}
|
|
// $Id: JvPictureEditForm.pas 10610 2006-05-19 13:35:08Z elahn $
|
|
|
|
unit JvPictureEditForm;
|
|
|
|
{$I jvcl.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, Windows, Messages, Graphics, Forms, Controls, Dialogs, Menus,
|
|
StdCtrls, ExtCtrls, ExtDlgs, Buttons,
|
|
JvMRUManager, JvFormPlacement, JvClipboardMonitor, JvComponent, JvAppStorage,
|
|
{$IFDEF MSWINDOWS}
|
|
JvAppRegistryStorage,
|
|
{$ENDIF MSWINDOWS}
|
|
JvMRUList;
|
|
|
|
type
|
|
TPictureEditDialog = class(TJvForm)
|
|
Load: TButton;
|
|
Save: TButton;
|
|
Copy: TButton;
|
|
Paste: TButton;
|
|
Clear: TButton;
|
|
OKButton: TButton;
|
|
CancelButton: TButton;
|
|
HelpBtn: TButton;
|
|
DecreaseBox: TCheckBox;
|
|
FormStorage: TJvFormStorage;
|
|
GroupBox: TGroupBox;
|
|
ImagePanel: TPanel;
|
|
ImagePaintBox: TPaintBox;
|
|
Bevel: TBevel;
|
|
Paths: TButton;
|
|
PathsBtn: TSpeedButton;
|
|
PathsMenu: TPopupMenu;
|
|
PathsMRU: TJvMRUManager;
|
|
AppStorage: TJvAppRegistryStorage;
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
procedure LoadClick(Sender: TObject);
|
|
procedure SaveClick(Sender: TObject);
|
|
procedure ClearClick(Sender: TObject);
|
|
procedure CopyClick(Sender: TObject);
|
|
procedure PasteClick(Sender: TObject);
|
|
procedure HelpBtnClick(Sender: TObject);
|
|
procedure FormStorageRestorePlacement(Sender: TObject);
|
|
procedure FormStorageSavePlacement(Sender: TObject);
|
|
procedure ImagePaintBoxPaint(Sender: TObject);
|
|
procedure PathsClick(Sender: TObject);
|
|
procedure PathsMRUClick(Sender: TObject; const RecentName,
|
|
Caption: string; UserData: Longint);
|
|
procedure PathsMenuPopup(Sender: TObject);
|
|
procedure PathsMRUChange(Sender: TObject);
|
|
procedure PathsBtnClick(Sender: TObject);
|
|
private
|
|
FGraphicClass: TGraphicClass;
|
|
FClipMonitor: TJvClipboardMonitor;
|
|
procedure CheckEnablePaste;
|
|
procedure DecreaseBMPColors;
|
|
procedure SetGraphicClass(Value: TGraphicClass);
|
|
function GetDecreaseColors: Boolean;
|
|
procedure LoadFile(const FileName: string);
|
|
procedure UpdatePathsMenu;
|
|
procedure UpdateClipboard(Sender: TObject);
|
|
procedure WMDropFiles(var Msg: TWMDropFiles); message WM_DROPFILES;
|
|
procedure WMDestroy(var Msg: TMessage); message WM_DESTROY;
|
|
protected
|
|
procedure CreateHandle; override;
|
|
public
|
|
Pic: TPicture;
|
|
IconColor: TColor;
|
|
FileDialog: TOpenPictureDialog;
|
|
SaveDialog: TSavePictureDialog;
|
|
procedure ValidateImage;
|
|
property DecreaseColors: Boolean read GetDecreaseColors;
|
|
property GraphicClass: TGraphicClass read FGraphicClass write SetGraphicClass;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
TypInfo, SysUtils,
|
|
Clipbrd, Consts,
|
|
{$IFDEF MSWINDOWS}
|
|
ShellAPI, LibHelp,
|
|
{$ENDIF MSWINDOWS}
|
|
{$IFDEF BCB5}
|
|
JvVCL5Utils,
|
|
{$ENDIF BCB5}
|
|
JvJVCLUtils, JvJCLUtils, JvConsts, JvDsgnConsts, JvDirectoryListForm, JvTypes;
|
|
|
|
|
|
{$R *.dfm}
|
|
|
|
procedure CopyPicture(Pict: TPicture; BackColor: TColor);
|
|
begin
|
|
if Pict.Graphic <> nil then
|
|
begin
|
|
if Pict.Graphic is TIcon then
|
|
CopyIconToClipboard(Pict.Icon, BackColor)
|
|
{ check other specific graphic types here }
|
|
else
|
|
Clipboard.Assign(Pict);
|
|
end;
|
|
end;
|
|
|
|
procedure PastePicture(Pict: TPicture; GraphicClass: TGraphicClass);
|
|
var
|
|
NewGraphic: TGraphic;
|
|
begin
|
|
if Pict <> nil then
|
|
begin
|
|
if Clipboard.HasFormat(CF_ICON) and
|
|
((GraphicClass = TIcon) or (GraphicClass = TGraphic)) then
|
|
begin
|
|
NewGraphic := CreateIconFromClipboard;
|
|
if NewGraphic <> nil then
|
|
try
|
|
Pict.Assign(NewGraphic);
|
|
finally
|
|
NewGraphic.Free;
|
|
end;
|
|
end
|
|
{ check other specific graphic types here }
|
|
else
|
|
if Clipboard.HasFormat(CF_PICTURE) then
|
|
Pict.Assign(Clipboard);
|
|
end;
|
|
end;
|
|
|
|
function EnablePaste(Graph: TGraphicClass): Boolean;
|
|
begin
|
|
if Graph = TBitmap then
|
|
Result := Clipboard.HasFormat(CF_BITMAP)
|
|
else
|
|
if Graph = TMetaFile then
|
|
Result := Clipboard.HasFormat(CF_METAFILEPICT)
|
|
else
|
|
if Graph = TIcon then
|
|
Result := Clipboard.HasFormat(CF_ICON)
|
|
{ check other graphic types here }
|
|
//else
|
|
//if Graph = TGraphic then
|
|
// Result := Clipboard.HasFormat(CF_PICTURE)
|
|
else
|
|
Result := Clipboard.HasFormat(CF_PICTURE);
|
|
end;
|
|
|
|
function ValidPicture(Pict: TPicture): Boolean;
|
|
begin
|
|
Result := (Pict.Graphic <> nil) and not Pict.Graphic.Empty;
|
|
end;
|
|
|
|
//=== { TPictureEditDialog } =================================================
|
|
|
|
procedure TPictureEditDialog.SetGraphicClass(Value: TGraphicClass);
|
|
begin
|
|
FGraphicClass := Value;
|
|
CheckEnablePaste;
|
|
DecreaseBox.Enabled := (GraphicClass = TBitmap) or (GraphicClass = TGraphic);
|
|
end;
|
|
|
|
procedure TPictureEditDialog.CheckEnablePaste;
|
|
begin
|
|
Paste.Enabled := EnablePaste(GraphicClass);
|
|
end;
|
|
|
|
procedure TPictureEditDialog.ValidateImage;
|
|
var
|
|
Enable: Boolean;
|
|
begin
|
|
Enable := ValidPicture(Pic);
|
|
Save.Enabled := Enable;
|
|
Clear.Enabled := Enable;
|
|
Copy.Enabled := Enable;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.UpdateClipboard(Sender: TObject);
|
|
begin
|
|
CheckEnablePaste;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.FormCreate(Sender: TObject);
|
|
begin
|
|
Pic := TPicture.Create;
|
|
FileDialog := TOpenPictureDialog.Create(Self);
|
|
SaveDialog := TSavePictureDialog.Create(Self);
|
|
FileDialog.Title := RsLoadPicture;
|
|
SaveDialog.Title := RsSavePictureAs;
|
|
Bevel.Visible := False;
|
|
Font.Style := [];
|
|
AppStorage.Root := SDelphiKey;
|
|
PathsMRU.RecentMenu := PathsMenu.Items;
|
|
IconColor := clBtnFace;
|
|
HelpContext := hcDPictureEditor;
|
|
Save.Enabled := False;
|
|
Clear.Enabled := False;
|
|
Copy.Enabled := False;
|
|
FClipMonitor := TJvClipboardMonitor.Create(Self);
|
|
FClipMonitor.OnChange := UpdateClipboard;
|
|
CheckEnablePaste;
|
|
end;
|
|
|
|
function TPictureEditDialog.GetDecreaseColors: Boolean;
|
|
begin
|
|
Result := DecreaseBox.Checked;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.FormDestroy(Sender: TObject);
|
|
begin
|
|
FClipMonitor.Free;
|
|
Pic.Free;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.LoadFile(const FileName: string);
|
|
begin
|
|
Application.ProcessMessages;
|
|
StartWait;
|
|
try
|
|
Pic.LoadFromFile(FileName);
|
|
finally
|
|
StopWait;
|
|
end;
|
|
ImagePaintBox.Invalidate;
|
|
ValidateImage;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.LoadClick(Sender: TObject);
|
|
begin
|
|
if FileDialog.Execute then
|
|
Self.LoadFile(FileDialog.FileName);
|
|
end;
|
|
|
|
procedure TPictureEditDialog.SaveClick(Sender: TObject);
|
|
begin
|
|
if (Pic.Graphic <> nil) and not Pic.Graphic.Empty then
|
|
with SaveDialog do
|
|
begin
|
|
DefaultExt := GraphicExtension(TGraphicClass(Pic.Graphic.ClassType));
|
|
Filter := GraphicFilter(TGraphicClass(Pic.Graphic.ClassType));
|
|
if Execute then
|
|
begin
|
|
StartWait;
|
|
try
|
|
Pic.SaveToFile(FileName);
|
|
finally
|
|
StopWait;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.DecreaseBMPColors;
|
|
begin
|
|
if ValidPicture(Pic) and (Pic.Graphic is TBitmap) and DecreaseColors then
|
|
SetBitmapPixelFormat(Pic.Bitmap, pf4bit, DefaultMappingMethod);
|
|
end;
|
|
|
|
procedure TPictureEditDialog.CopyClick(Sender: TObject);
|
|
begin
|
|
CopyPicture(Pic, IconColor);
|
|
end;
|
|
|
|
procedure TPictureEditDialog.PasteClick(Sender: TObject);
|
|
begin
|
|
if Pic <> nil then
|
|
begin
|
|
PastePicture(Pic, GraphicClass);
|
|
DecreaseBMPColors;
|
|
ImagePaintBox.Invalidate;
|
|
ValidateImage;
|
|
end;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.ImagePaintBoxPaint(Sender: TObject);
|
|
var
|
|
DrawRect: TRect;
|
|
None: string;
|
|
Ico: HICON;
|
|
W, H: Integer;
|
|
begin
|
|
with TPaintBox(Sender) do
|
|
begin
|
|
Canvas.Brush.Color := Color;
|
|
DrawRect := ClientRect;
|
|
if ValidPicture(Pic) then
|
|
begin
|
|
with DrawRect do
|
|
if (Pic.Width > Right - Left) or (Pic.Height > Bottom - Top) then
|
|
begin
|
|
if Pic.Width > Pic.Height then
|
|
Bottom := Top + MulDiv(Pic.Height, Right - Left, Pic.Width)
|
|
else
|
|
Right := Left + MulDiv(Pic.Width, Bottom - Top, Pic.Height);
|
|
Canvas.StretchDraw(DrawRect, Pic.Graphic);
|
|
end
|
|
else
|
|
begin
|
|
with DrawRect do
|
|
begin
|
|
if Pic.Graphic is TIcon then
|
|
begin
|
|
Ico := CreateRealSizeIcon(Pic.Icon);
|
|
try
|
|
GetIconSize(Ico, W, H);
|
|
DrawIconEx(Canvas.Handle, (Left + Right - W) div 2,
|
|
(Top + Bottom - H) div 2, Ico, W, H, 0, 0, DI_NORMAL);
|
|
finally
|
|
DestroyIcon(Ico);
|
|
end;
|
|
end
|
|
else
|
|
Canvas.Draw((Right + Left - Pic.Width) div 2,
|
|
(Bottom + Top - Pic.Height) div 2, Pic.Graphic);
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
with DrawRect, Canvas do
|
|
begin
|
|
None := srNone;
|
|
TextOut(Left + (Right - Left - TextWidth(None)) div 2, Top + (Bottom -
|
|
Top - TextHeight(None)) div 2, None);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.CreateHandle;
|
|
begin
|
|
inherited CreateHandle;
|
|
DragAcceptFiles(Handle, True);
|
|
end;
|
|
|
|
procedure TPictureEditDialog.WMDestroy(var Msg: TMessage);
|
|
begin
|
|
DragAcceptFiles(Handle, False);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.WMDropFiles(var Msg: TWMDropFiles);
|
|
var
|
|
AFileName: array [0..255] of Char;
|
|
Num: Cardinal;
|
|
begin
|
|
Msg.Result := 0;
|
|
try
|
|
Num := DragQueryFile(Msg.Drop, $FFFFFFFF, nil, 0);
|
|
if Num > 0 then
|
|
begin
|
|
DragQueryFile(Msg.Drop, 0, PChar(@AFileName), Pred(SizeOf(AFileName)));
|
|
Application.BringToFront;
|
|
Self.LoadFile(StrPas(AFileName));
|
|
end;
|
|
finally
|
|
DragFinish(Msg.Drop);
|
|
end;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.UpdatePathsMenu;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to PathsMenu.Items.Count - 1 do
|
|
PathsMenu.Items[I].Checked :=
|
|
CompareText(PathsMenu.Items[I].Caption, FileDialog.InitialDir) = 0;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.ClearClick(Sender: TObject);
|
|
begin
|
|
Pic.Graphic := nil;
|
|
ImagePaintBox.Invalidate;
|
|
Save.Enabled := False;
|
|
Clear.Enabled := False;
|
|
Copy.Enabled := False;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.HelpBtnClick(Sender: TObject);
|
|
begin
|
|
Application.HelpContext(HelpContext);
|
|
end;
|
|
|
|
const
|
|
cBackColorIdent = 'ClipboardBackColor';
|
|
cFileDir = 'FileDialog.InitialDir';
|
|
|
|
procedure TPictureEditDialog.FormStorageRestorePlacement(Sender: TObject);
|
|
begin
|
|
IconColor := FormStorage.ReadInteger(cBackColorIdent, clBtnFace);
|
|
FileDialog.InitialDir := FormStorage.ReadString(cFileDir, FileDialog.InitialDir);
|
|
end;
|
|
|
|
procedure TPictureEditDialog.FormStorageSavePlacement(Sender: TObject);
|
|
begin
|
|
FormStorage.WriteInteger(cBackColorIdent, IconColor);
|
|
if FileDialog.InitialDir <> '' then
|
|
FormStorage.WriteString(cFileDir, FileDialog.InitialDir);
|
|
end;
|
|
|
|
procedure TPictureEditDialog.PathsClick(Sender: TObject);
|
|
begin
|
|
if EditFolderList(PathsMRU.Strings) then
|
|
UpdatePathsMenu;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.PathsMRUClick(Sender: TObject;
|
|
const RecentName, Caption: string; UserData: Longint);
|
|
begin
|
|
if DirectoryExists(RecentName) then
|
|
{SetCurrentDir(RecentName);}
|
|
FileDialog.InitialDir := RecentName
|
|
else
|
|
PathsMRU.Remove(RecentName);
|
|
UpdatePathsMenu;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.PathsMenuPopup(Sender: TObject);
|
|
begin
|
|
UpdatePathsMenu;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.PathsMRUChange(Sender: TObject);
|
|
begin
|
|
PathsBtn.Enabled := PathsMRU.Strings.Count > 0;
|
|
end;
|
|
|
|
procedure TPictureEditDialog.PathsBtnClick(Sender: TObject);
|
|
var P:TPoint;
|
|
begin
|
|
P := PathsBtn.ClientOrigin;
|
|
PathsMenu.Popup(P.X,P.Y + PathsBtn.Height);
|
|
end;
|
|
|
|
end.
|
|
|