unit childwin; //{$DEFINE _DEBUG} interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, ActnList, Menus, ImgList, ToolWin, Spin, System.Actions; type TApp_TOOLDskCaptWindow = class(TForm) ActionList1: TActionList; actFile_SaveAs: TAction; actFile_Close: TAction; actEdit_Copy: TAction; actZoom_Fit: TAction; actZoom_100: TAction; actZoom_Up: TAction; actZoom_Down: TAction; PopupMenu1: TPopupMenu; MenuItem_PFileSaveAs: TMenuItem; MenuItem_PEditCopy: TMenuItem; MenuItem_PLine1: TMenuItem; MenuItem_PZoomFit: TMenuItem; MenuItem_PZoom100: TMenuItem; MenuItem_PZoomUp: TMenuItem; MenuItem_PZoomDown: TMenuItem; MenuItem_PLine3: TMenuItem; MenuItem_PFileClose: TMenuItem; imgBrush: TImage; MenuItem_PLine2: TMenuItem; actFrame_Back: TAction; actFrame_Next: TAction; actFrame_End: TAction; actFrame_Head: TAction; ToolBar1: TToolBar; ToolButton1: TToolButton; ToolButton2: TToolButton; ToolButton3: TToolButton; ToolButton4: TToolButton; ToolButton5: TToolButton; actEdit_Cut: TAction; actEdit_Paste: TAction; actEdit_Del: TAction; actEdit_Redo: TAction; actEdit_Undo: TAction; ToolButton6: TToolButton; ToolButton7: TToolButton; ToolButton8: TToolButton; ToolButton10: TToolButton; lblFrame: TLabel; ToolButton11: TToolButton; ToolButton12: TToolButton; ToolButton13: TToolButton; ToolButton14: TToolButton; ToolButton15: TToolButton; ToolButton9: TToolButton; Panel1: TPanel; edtNum_Delay: TSpinEdit; lblNum_Delay: TLabel; actEdit_Replace: TAction; ToolButton16: TToolButton; barWidth: TScrollBar; barHeight: TScrollBar; MenuItem_PZoomSmooth: TMenuItem; procedure actNop (Sender: TObject); procedure actFile_CloseExecute (Sender: TObject); procedure actFile_SaveAsExecute(Sender: TObject); procedure actEdit_UndoExecute (Sender: TObject); procedure actEdit_RedoExecute (Sender: TObject); procedure actEdit_CopyExecute (Sender: TObject); procedure actEdit_CutExecute (Sender: TObject); procedure actEdit_PasteExecute (Sender: TObject); procedure actEdit_DelExecute (Sender: TObject); procedure actZoom_UpExecute (Sender: TObject); procedure actFrame_BackExecute (Sender: TObject); procedure FormCreate (Sender: TObject); procedure FormClose (Sender: TObject; var Action: TCloseAction); procedure FormDestroy (Sender: TObject); procedure FormResize (Sender: TObject); procedure FormPaint (Sender: TObject); procedure FormActivate (Sender: TObject); procedure FormDblClick (Sender: TObject); procedure FormMouseDown (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseMove (Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure FormMouseUp (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); procedure FormKeyDown (Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormKeyUp (Sender: TObject; var Key: Word; Shift: TShiftState); procedure ImageList_FrameChange(Sender: TObject); procedure barWidthChange (Sender: TObject); procedure barHeightChange(Sender: TObject); private { Private 宣言 } FiObject, FiIndex : Integer; FsFileName : WideString; FbSaved : Boolean; FiCloseAction : Integer; FptMousePos : TPoint; // FImage : TBitmap; //キャプチャ画像。リストから取り出すために必要 FBuffBitmap : TBitmap; //画面表示用 FrcImage : TRect; FiFrameIndex : Integer; FImageList : TList; function FGetVScrollVisible: Boolean; function FGetHScrollVisible: Boolean; function FGetTop: Integer; function FGetClientWidth: Integer; function FGetClientHeight: Integer; function FGetClientRect: TRect; function FGetBitmap: TBitmap; function FGetBitmapWidth: Integer; function FGetBitmapHeight: Integer; procedure FSetFileName(sFileName: WideString); function FSaveToFile: Boolean; procedure FSetInfo; procedure FSetFrameIndex(iIndex: Integer); function FGetFrameCount: Integer; public { Public 宣言 } procedure AddFrame(ABitmap : TBitmap); property Bitmap : TBitmap read FGetBitmap; property BitmapWidth : Integer read FGetBitmapWidth; property BitmapHeight : Integer read FGetBitmapHeight; property FileName : WideString read FsFileName; // write F_SetFileName; property Saved : Boolean read FbSaved; // write F_bSaved; property CloseAction : Integer read FiCloseAction; property Frame : Integer read FiFrameIndex write FSetFrameIndex; property FrameCount : Integer read FGetFrameCount; end; function gfnCreateCaptWindow(ABitmap: TBitmap; iObject: Integer; iIndex: Integer): TApp_TOOLDskCaptWindow; //var // App_TOOLDskCaptWindow: TApp_TOOLDskCaptWindow; implementation uses {$IFDEF _DEBUG} myDebug, {$ENDIF} Clipbrd, FTGifAnimate, System.Types, myAvi, myControl, myFile, myGDIPlus, myGIFImage, myGraphic, myList, myMessageDlg, myNum, mySize, myString, myWindow, myWStrings, main; {$R *.dfm} function gfnCreateCaptWindow(ABitmap: TBitmap; iObject: Integer; iIndex: Integer): TApp_TOOLDskCaptWindow; const lci_TOPLEFT = 20; lci_CASCADE = 5; var li_Index : Integer; li_Width, li_Height : Integer; ls_Caption : String; l_MenuItem : TMenuItem; l_Bitmap : TBitmap; begin Result := TApp_TOOLDskCaptWindow.Create(Application.MainForm); with Result do begin FiObject := iObject; FiIndex := iIndex; li_Index := (FiIndex -1) mod lci_CASCADE; ls_Caption := Format('Image%d', [iIndex]); l_MenuItem := NewItem( ls_Caption, //Caption 0, //ShortCut False, //Checked True, //Enabled G_MainForm.mniWindowClick, //OnClickイベント 0, //HelpContext gfnsAvailableName('__mniWindow_Child') //Name ); l_MenuItem.Tag := Integer(Handle); //Tagに識別用のハンドルをセット l_MenuItem.Hint := ls_Caption; //Hintにフルパスのファイル名 l_MenuItem.OnAdvancedDrawItem := G_MainForm.mniFileAdvancedDrawItem; l_MenuItem.RadioItem := True; G_MainForm.mniWindow.Add(l_MenuItem); l_MenuItem.Checked := True; //この関数を呼び出した側のビットマップ(ABitmap)をリストに追加すると呼び出し側 //で変更・破棄してしまった場合に対処が難しくなるのでl_Bitmapにコピーを行って //そちらをリストに追加する。 l_Bitmap := TBitmap.Create; l_Bitmap.Assign(ABitmap); if (l_Bitmap.Width > 0) or (l_Bitmap.Height > 0) then begin FImageList.Add(l_Bitmap); Frame := 0; gpcFitToRectVideoSizeGet(l_Bitmap, FGetClientRect, li_Width, li_Height); if (li_Width > l_Bitmap.Width) and (li_Height > l_Bitmap.Height) then begin li_Width := l_Bitmap.Width; li_Height := l_Bitmap.Height; end; FrcImage := Rect(0, 0, li_Width, li_Height); SetBounds( li_Index * lci_TOPLEFT, li_Index * lci_TOPLEFT, li_Width + (Width - ClientWidth) + (ClientWidth - FGetClientWidth), li_Height + (Height - ClientHeight) + (ClientHeight - FGetClientHeight) ); end else begin SetBounds(li_Index * lci_TOPLEFT, li_Index * lci_TOPLEFT, Width, Height); end; FSetFileName(ls_Caption); FormActivate(nil); Tag := 1; FormResize(nil); end; end; //============================================================================== procedure TApp_TOOLDskCaptWindow.FormCreate(Sender: TObject); begin {$IFDEF _DEBUG} myDebug.gpcExeMode; {$ENDIF} FBuffBitmap := TBitmap.Create; FBuffBitmap.Canvas.Brush.Bitmap := imgBrush.Picture.Bitmap; FImageList := TList.Create; gpcWindowStyleAdd(edtNum_Delay.Handle, ES_RIGHT); FbSaved := False; FiCloseAction := ID_NO; FptMousePos := Point(-1, -1); Self.Constraints.MinWidth := 32 + (Width - ClientWidth); Self.Constraints.MinHeight := 32 + (Height - ClientHeight) + ToolBar1.Height; end; procedure TApp_TOOLDskCaptWindow.FormClose(Sender: TObject; var Action: TCloseAction); begin // Tag := 0; FiCloseAction := ID_NO; Action := caFree; if (App_TOOLDskCapt.actWindow_ConfirmSave.Checked) and not(FbSaved) then begin FiCloseAction := gfniMessageBoxYesNoCancel(WideFormat('%s は保存されていません'#13'保存しますか', [gfnsFileNameGet(FsFileName)])); if (FiCloseAction = ID_CANCEL) then begin Action := caNone; end else begin if (FiCloseAction = ID_YES) then begin if not(FSaveToFile) then begin FiCloseAction := ID_CANCEL; Action := caNone; end; end; end; end; end; procedure TApp_TOOLDskCaptWindow.FormDestroy(Sender: TObject); var l_MenuItem : TMenuItem; i : Integer; begin Tag := 0; for i := FImageList.Count-1 downto 0 do begin TBitmap(FImageList[i]).Free; FImageList.Delete(i); end; FImageList.Free; if not(Application.Terminated) then begin l_MenuItem := G_MainForm.GetWindowMenuItem(Self.Handle); l_MenuItem.Free; end; G_MainForm.CaptWindow := nil; FBuffBitmap.Free; end; procedure TApp_TOOLDskCaptWindow.FormResize(Sender: TObject); var li_Left, li_Top, li_Width, li_Height : Integer; lb_VScroll : Boolean; lb_HScroll : Boolean; begin if (Application.Terminated) or (Self.Tag = 0) or (FGetBitmapWidth <= 0) or (FGetBitmapHeight <= 0) then begin Exit; end; lb_VScroll := FGetVScrollVisible; lb_HScroll := FGetHScrollVisible; if (lb_VScroll) then begin //縦スクロールバー li_Left := ClientWidth - barHeight.Width; if (lb_HScroll) then begin li_Height := ClientHeight - barWidth.Height; end else begin li_Height := ClientHeight; end; if (ToolBar1.Visible) then begin Dec(li_Height, ToolBar1.Height); end; barHeight.SetBounds(li_Left, FGetTop, barHeight.Width, li_Height); barHeight.Max := gfniRectHeight(FrcImage) - FGetClientHeight; end; barHeight.Visible := lb_VScroll; if (lb_HScroll) then begin li_Top := ClientHeight - barWidth.Height; if (lb_VScroll) then begin li_Width := ClientWidth - barHeight.Width; end else begin li_Width := ClientWidth; end; barWidth.SetBounds(0, li_Top, li_Width, barWidth.Height); barWidth.Max := gfniRectWidth(FrcImage) - FGetClientWidth; end; barWidth.Visible := lb_HScroll; if (FGetClientHeight <= 0) or (FGetClientWidth <= 0) then begin Exit; end; FBuffBitmap.Width := FGetClientWidth; FBuffBitmap.Height := FGetClientHeight; if (G_MainForm.Action_ZoomAlwaysFit.Checked) then begin //ウィンドウに合わせる gpcFitToRectVideoSizeGet(FGetBitmap, FGetClientRect, li_Width, li_Height); end else begin li_Width := gfniRectWidth (FrcImage); li_Height := gfniRectHeight(FrcImage); end; li_Left := FrcImage.Left; li_Top := FrcImage.Top; FrcImage := Rect(li_Left, li_Top, li_Left + li_Width, li_Top + li_Height); { if (barWidth.Visible) then begin barWidth.Position := -F_rcImage.Left; end; if (barHeight.Visible) then begin barHeight.Position := -F_rcImage.Top; end; } FormMouseUp(nil, mbLeft, [], 0, 0); //引数はmbLeft以外は適当で良い。 FSetInfo; end; procedure TApp_TOOLDskCaptWindow.FormPaint(Sender: TObject); var lrc_Rect : TRect; begin if (Application.Terminated) or (Self.Tag = 0) or (FGetBitmapWidth <= 0) or (FGetBitmapHeight <= 0) then begin Exit; end; lrc_Rect := Rect(0, 0, FBuffBitmap.Width, FBuffBitmap.Height); FBuffBitmap.Canvas.FillRect(lrc_Rect); if (gfniRectWidth(FrcImage) < FGetBitmapWidth) or (App_TOOLDskCapt.Action_ZoomSmooth.Checked) then begin SetStretchBltMode(FBuffBitmap.Canvas.Handle, HALFTONE); end; if (FGetBitmap = nil) then begin Exit; end else begin StretchBlt( FBuffBitmap.Canvas.Handle, FrcImage.Left, FrcImage.Top, gfniRectWidth (FrcImage), gfniRectHeight(FrcImage), FGetBitmap.Canvas.Handle, 0, 0, FGetBitmapWidth, FGetBitmapHeight, SRCCOPY ); end; BitBlt( Self.Canvas.Handle, 0, FGetTop, FGetClientWidth, FGetClientHeight, FBuffBitmap.Canvas.Handle, 0, 0, SRCCOPY ); end; procedure TApp_TOOLDskCaptWindow.FormDblClick(Sender: TObject); begin if (gfniRectWidth (FrcImage) = FGetBitmapWidth) and (gfniRectHeight(FrcImage) = FGetBitmapHeight) then begin actZoom_UpExecute(actZoom_Fit); end else begin actZoom_UpExecute(actZoom_100); end; end; procedure TApp_TOOLDskCaptWindow.FormActivate(Sender: TObject); begin App_TOOLDskCapt.CaptWindow := Self; end; procedure TApp_TOOLDskCaptWindow.actFile_CloseExecute(Sender: TObject); //閉じる begin Close; end; procedure TApp_TOOLDskCaptWindow.FSetInfo; var li_Len : Integer; li_Width : Integer; lf_Zoom : Extended; ls_Per : String; begin li_Width := gfniRectWidth(FrcImage); if (li_Width = 0) or (FGetBitmapWidth = 0) then begin Exit; end; lf_Zoom := (li_Width / FGetBitmapWidth) * 100; if (lf_Zoom < 1) then begin ls_Per := Format('%.2f%%', [lf_Zoom]); end else begin ls_Per := Format('%d%%', [gfniRound(lf_Zoom)]); end; Self.Hint := Format('%s %dx%d [%s]', [ gfnsFileNameGet(FsFileName), FGetBitmapWidth, FGetBitmapHeight, ls_Per ]); Self.Caption := Self.Hint; li_Len := Length(Format('%d', [FGetFrameCount])); lblFrame.Caption := Format(' %*d/%d ', [li_Len, FiFrameIndex +1, FGetFrameCount]); end; function TApp_TOOLDskCaptWindow.FGetVScrollVisible: Boolean; var li_Width : Integer; li_Height : Integer; li_ClientHeight : Integer; begin Result := False; if (ToolBar1.Visible) then begin //ツールバーの高さ分をマイナス li_ClientHeight := ClientHeight - ToolBar1.Height; end else begin li_ClientHeight := ClientHeight; end; li_Height := gfniRectHeight(FrcImage); if (li_Height > li_ClientHeight) then begin //表示イメージの高さが画像表示領域より大きい //縦のスクロールバーは表示される Result := True; end else begin //表示イメージの高さは画像表示領域内に収まる li_Width := gfniRectWidth(FrcImage); if (li_Width > ClientWidth) //横スクロールバーは表示される and (li_Height + barWidth.Height > li_ClientHeight) //縦スクロールバーも表示される then begin Result := True; end; end; end; function TApp_TOOLDskCaptWindow.FGetHScrollVisible: Boolean; var li_Width : Integer; li_Height : Integer; li_ClientHeight : Integer; begin Result := False; if (ToolBar1.Visible) then begin li_ClientHeight := ClientHeight - ToolBar1.Height; end else begin li_ClientHeight := ClientHeight; end; li_Width := gfniRectWidth(FrcImage); if (li_Width > ClientWidth) then begin //描画イメージの幅が描画領域より大きい //横スクロールバーが表示される Result := True; end else begin //描画イメージの幅は描画領域内に収まる li_Height := gfniRectHeight(FrcImage); if (li_Height > li_ClientHeight) and (li_Width + barHeight.Width > ClientWidth) then begin //縦スクロールバーは表示される //横スクロールバーも表示される Result := True; end; end; end; function TApp_TOOLDskCaptWindow.FGetClientWidth: Integer; { var li_Width : Integer; li_Height : Integer; li_ClientHeight : Integer; } begin if (FGetVScrollVisible) then begin Result := ClientWidth - barHeight.Width; end else begin Result := ClientWidth; end; { if (ToolBar1.Visible) then begin //ツールバーの高さ分をマイナス li_ClientHeight := ClientHeight - ToolBar1.Height; end else begin li_ClientHeight := ClientHeight; end; li_Height := gfniRectHeight(F_rcImage); if (li_Height > li_ClientHeight) then begin //表示イメージの高さが画像表示領域より大きい //縦のスクロールバーは表示される Result := ClientWidth - barHeight.Width; end else begin //表示イメージの高さは画像表示領域内に収まる li_Width := gfniRectWidth(F_rcImage); if (li_Width > ClientWidth) //横スクロールバーは表示される and (li_Height + barWidth.Height > li_ClientHeight) //縦スクロールバーも表示される then begin Result := ClientWidth - barHeight.Width; end else begin Result := ClientWidth; end; end; } end; function TApp_TOOLDskCaptWindow.FGetClientHeight: Integer; begin if (ToolBar1.Visible) then begin Result := ClientHeight - ToolBar1.Height; end else begin Result := ClientHeight; end; if (FGetHScrollVisible) then begin Dec(Result, barWidth.Height); end; end; function TApp_TOOLDskCaptWindow.FGetTop : Integer; begin if (ToolBar1.Visible) then begin Result := ToolBar1.Height; end else begin Result := 0; end; end; function TApp_TOOLDskCaptWindow.FGetClientRect: TRect; var li_Top : Integer; begin if (ToolBar1.Visible) then begin li_Top := ToolBar1.Height; end else begin li_Top := 0; end; Result := Rect(0, li_Top, FGetClientWidth, FGetClientHeight); end; function TApp_TOOLDskCaptWindow.FGetBitmap: TBitmap; begin if (gfnbIsInsideRange(FiFrameIndex, 0, FGetFrameCount -1)) then begin Result := TBitmap(FImageList[FiFrameIndex]); end else begin Result := nil; end; end; function TApp_TOOLDskCaptWindow.FGetBitmapWidth: Integer; begin if (FGetBitmap = nil) then begin Result := 0; end else begin Result := FGetBitmap.Width; end; end; function TApp_TOOLDskCaptWindow.FGetBitmapHeight: Integer; begin if (FGetBitmap = nil) then begin Result := 0; end else begin Result := FGetBitmap.Height; end; end; procedure TApp_TOOLDskCaptWindow.actNop(Sender: TObject); begin // end; procedure TApp_TOOLDskCaptWindow.FSetFileName(sFileName: WideString); var l_MenuItem : TMenuItem; begin FsFileName := sFileName; FSetInfo; l_MenuItem := G_MainForm.GetWindowMenuItem(Self.Handle); if (l_MenuItem <> nil) then begin l_MenuItem.Caption := gfnsFileNameGet(FsFileName); l_MenuItem.Hint := FsFileName; end; end; //--- ファイル ----------------------------------------------------------------- //保存 function TApp_TOOLDskCaptWindow.FSaveToFile: Boolean; function _SaveAvi : Boolean; var l_AviBitCount: TMyAviBitCount; begin //AVI if (App_TOOLDskCapt.Action_File_AviRGB24.Checked) then begin l_AviBitCount := bt24; end else begin l_AviBitCount := bt32; end; Result := gfnbAviSave(FsFileName, FImageList, 1000 div edtNum_Delay.Value, 1, l_AviBitCount); end; function _SaveBmp: Boolean; begin //BMP Result := gfnbBmpSave(FGetBitmap, FsFileName); end; function _SaveGif: Boolean; begin //GIF if (App_TOOLDskCapt.Action_File_GifTransparent.Checked) then begin Result := gfnbGifSave(FGetBitmap, FsFileName, App_TOOLDskCapt.BGColor); end else begin Result := gfnbGifSave(FGetBitmap, FsFileName); end; end; function _SaveGifAnime : Boolean; var lcl_Color : TColor; begin //GIFアニメ if (App_TOOLDskCapt.Action_File_GifTransparent.Checked) then begin //透過GIF lcl_Color := App_TOOLDskCapt.BGColor end else begin lcl_Color := -1; end; Result := gfnbGifAnimeSave(FImageList, FsFileName, lcl_Color, edtNum_Delay.Value); end; function _SaveJpeg: Boolean; begin //JPEG Result := gfnbJpegSave(FGetBitmap, FsFileName, 80); //品質は80で固定 end; function _SavePng: Boolean; begin //PNG Result := gfnbPngSave(FsFileName, FGetBitmap); // Result := False; end; function _SaveTiff : Boolean; begin //TIFF Result := gfnbTiffSave(FsFileName, FGetBitmap); // Result := False; end; const lcs_AVI = '.avi'; lcs_BMP = '.bmp'; lcs_GIF = '.gif'; lcs_JPEG : array[0..1] of WideString = ('.jpg', '.jpeg'); lcs_PNG = '.png'; lcs_TIFF : array[0..1] of WideString = ('.tif', '.tiff'); var ls_Ext : WideString; li_Ret : Integer; begin Result := False; App_TOOLDskCapt.Dialog_File_SaveAs.FileName := FsFileName; // App_TOOLDskCapt.Action_File_SaveSerialNum.Visible := False; // App_TOOLDskCapt.chkFile_SaveSequenceNum.Visible := False; if (FGetBitmapWidth > 0) and (FGetBitmapHeight > 0) and (App_TOOLDskCapt.Dialog_File_SaveAs.Execute) then begin Screen.Cursor := crHourGlass; try case App_TOOLDskCapt.Dialog_File_SaveAs.FilterIndex of G_ciFILESAVE_BMP :begin //BMP ls_Ext := lcs_BMP; end; G_ciFILESAVE_JPEG :begin //JPEG ls_Ext := lcs_JPEG[0]; end; G_ciFILESAVE_GIF, G_ciFILESAVE_GIFANIME :begin //GIF ls_Ext := lcs_GIF; end; G_ciFILESAVE_AVI :begin //AVI ls_Ext := lcs_AVI; end; { G_ciFILESAVE_PNG :begin //PNG ls_Ext := lcs_PNG; end; G_ciFILESAVE_TIFF :begin //TIFF ls_Ext := lcs_TIFF[0]; end; } else begin //「すべて」を選んだ場合のフォーマットはBMP ls_Ext := lcs_BMP; end; end; FsFileName := App_TOOLDskCapt.Dialog_File_SaveAs.FileName; App_TOOLDskCapt.Dialog_File_SaveAs.InitialDir := gfnsFilePathGet(FsFileName); if (WideLowerCase(gfnsFileExtGet(FsFileName)) <> ls_Ext) then begin //選択ファイルの拡張子がls_Extと同じならそのまま。違えばls_Extを付け足す FsFileName := FsFileName + ls_Ext; end; if (gfnbFileExists(FsFileName)) then begin li_Ret := gfniMessageBoxYesNo(WideFormat('%s'#13'は既に存在します。上書きしますか?', [FsFileName]), '名前を付けて保存'); if (li_Ret <> ID_YES) then begin Exit; end; end; FSetFileName(FsFileName); if (ls_Ext = lcs_AVI) then begin Result := _SaveAVI; end else if (ls_Ext = lcs_BMP) then begin //BMP Result := _SaveBmp; end else if (ls_Ext = lcs_GIF) then begin //GIF if (App_TOOLDskCapt.Dialog_File_SaveAs.FilterIndex = G_ciFILESAVE_GIFANIME) then begin //アニメーションGIF Result := _SaveGifAnime; end else begin Result := _SaveGif; end; end else if gfnbIsIncludeList(ls_Ext, lcs_JPEG) then begin //JPEG Result := _SaveJpeg; end else if (ls_Ext = lcs_PNG) then begin //PNG Result := _SavePng; end else if gfnbIsIncludeList(ls_Ext, lcs_TIFF) then begin //TIFF Result := _SaveTiff; end; finally Screen.Cursor := crDefault; end; if not(Result) then begin gpcShowMessage(WideFormat('%s'#13'の書き込みに失敗しました', [FsFileName])); end; FbSaved := FbSaved or Result; end; end; procedure TApp_TOOLDskCaptWindow.actFile_SaveAsExecute(Sender: TObject); begin FSaveToFile; end; //--- 編集 --------------------------------------------------------------------- procedure TApp_TOOLDskCaptWindow.ImageList_FrameChange(Sender: TObject); var lb_Bitmap : Boolean; begin if (Application.Terminated) or (Tag = 0) then begin Exit; end; lb_Bitmap := (FGetBitmapWidth > 0) and (FGetBitmapHeight > 0); actEdit_Cut.Enabled := (FGetFrameCount > 1) and lb_Bitmap; //(FiFrameIndex >= 0); actEdit_Copy.Enabled := (FGetFrameCount > 0) and lb_Bitmap; //(FiFrameIndex >= 0); // actEdit_Paste.Enabled := FiFrameIndex >= 0; actEdit_Del.Enabled := actEdit_Cut.Enabled; end; procedure TApp_TOOLDskCaptWindow.actEdit_UndoExecute(Sender: TObject); //元に戻す begin // end; procedure TApp_TOOLDskCaptWindow.actEdit_RedoExecute(Sender: TObject); //やり直し begin // end; procedure TApp_TOOLDskCaptWindow.actEdit_CutExecute(Sender: TObject); //切り取り begin if (FGetBitmap.Width > 0) and (FGetBitmap.Height > 0) and (FGetFrameCount > 1) then begin //フレームが一つしかない場合は切り取りできない actEdit_CopyExecute(nil); actEdit_DelExecute(nil); end; end; procedure TApp_TOOLDskCaptWindow.actEdit_CopyExecute(Sender: TObject); //コピー begin if (FGetBitmap <> nil) and (FGetBitmapWidth > 0) and (FGetBitmapHeight > 0) then begin Clipboard.Assign(FGetBitmap); end; end; procedure TApp_TOOLDskCaptWindow.AddFrame(ABitmap: TBitmap); var l_Bitmap : TBitmap; begin l_Bitmap := TBitmap.Create; l_Bitmap.Assign(ABitmap); FImageList.Add(l_Bitmap); FSetFrameIndex(FGetFrameCount -1); end; procedure TApp_TOOLDskCaptWindow.actEdit_PasteExecute(Sender: TObject); //貼り付け、挿入 var l_Bitmap: TBitmap; begin if (actEdit_Paste.Tag = 1) then begin Exit; end; actEdit_Paste.Tag := 1; if (Clipboard.HasFormat(CF_BITMAP)) then begin l_Bitmap := TBitmap.Create; gfnbBitmapFromClipboard(l_Bitmap); { if (l_Bitmap.Width <> ImageList_Frame.Width) then begin l_Bitmap.Width := ImageList_Frame.Width; end; if (l_Bitmap.Height <> ImageList_Frame.Height) then begin l_Bitmap.Height := ImageList_Frame.Height; end; } if (FGetFrameCount = 0) then begin FImageList.Add(l_Bitmap); end else if (Sender = actEdit_Replace) then begin TBitmap(FImageList[FiFrameIndex]).Free; FImageList.Delete(FiFrameIndex); FImageList.Insert(FiFrameIndex, l_Bitmap); end else begin FiFrameIndex := gfniNumLimit(FiFrameIndex, 0, FGetFrameCount -1); Inc(FiFrameIndex); FImageList.Insert(FiFrameIndex, l_Bitmap); end; FSetFrameIndex(FiFrameIndex); end; actEdit_Paste.Tag := 0; end; procedure TApp_TOOLDskCaptWindow.actEdit_DelExecute(Sender: TObject); //削除 begin if (FGetFrameCount > 1) then begin //フレームが一つしかない場合は削除できない FiFrameIndex := gfniNumLimit(FiFrameIndex, 0, FGetFrameCount -1); TBitmap(FImageList[FiFrameIndex]).Free; FImageList.Delete(FiFrameIndex); FSetFrameIndex(FiFrameIndex); end; end; //--- ズーム ------------------------------------------------------------------- //画像を掴んで移動 procedure TApp_TOOLDskCaptWindow.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if (Button = mbLeft) then begin if (PtInRect(FrcImage, Point(X, Y))) then begin if (gfniRectWidth (FrcImage) <= FGetClientWidth) and (gfniRectHeight(FrcImage) <= FGetClientHeight) then begin //表示画像の幅はフォームのクライアントの幅未満 FptMousePos := Point(-1, -1); end else begin //Image1などの場合と違うことに注意。 FptMousePos := Point(X - FrcImage.Left, Y - FrcImage.Top); end; end else begin // gpcControlMove(Self, X, Y); end; end; end; procedure TApp_TOOLDskCaptWindow.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var li_Left, li_Top : Integer; begin if (FptMousePos.X >= 0) or (FptMousePos.Y >= 0) then begin //Image1などの場合と違うことに注意。 li_Left := {FrcImage.Left +} X - FptMousePos.X; li_Top := {FrcImage.Top +} Y - FptMousePos.Y; FrcImage := Rect(li_Left, li_Top, li_Left + gfniRectWidth(FrcImage), li_Top + gfniRectHeight(FrcImage)); if (barWidth.Visible) then begin barWidth.Position := -FrcImage.Left; end; if (barHeight.Visible) then begin barHeight.Position := -FrcImage.Top; end; FormPaint(nil); end; end; procedure TApp_TOOLDskCaptWindow.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var li_Left, li_Top, li_Width, li_Height, li_ClientWidth, li_ClientHeight : Integer; lrc_Client : TRect; begin if (Button = mbLeft) then begin li_ClientWidth := FGetClientWidth; li_ClientHeight := FGetClientHeight; lrc_Client := FGetClientRect; li_Width := gfniRectWidth (FrcImage); li_Height := gfniRectHeight(FrcImage); if (li_Width <= li_ClientWidth) then begin //表示画像の幅はフォームのクライアントの幅未満 li_Left := (li_ClientWidth - li_Width) div 2; end else begin li_Left := FrcImage.Left; if (FrcImage.Right <= lrc_Client.Right) then begin li_Left := li_Left + lrc_Client.Right - FrcImage.Right; end; if (FrcImage.Left >= lrc_Client.Left) then begin li_Left := li_Left + lrc_Client.Left - FrcImage.Left; end; end; if (li_Height <= li_ClientHeight) then begin //表示画像の高さはフォームのクライアントの高さ未満 li_Top := (lrc_Client.Bottom - li_Height) div 2; end else begin li_Top := FrcImage.Top; if (FrcImage.Bottom <= lrc_Client.Bottom) then begin li_Top := li_Top + lrc_Client.Bottom - FrcImage.Bottom; end; if (FrcImage.Top >= lrc_Client.Top) then begin // li_Top := li_Top + lrc_Client.Top - FrcImage.Top; li_Top := 0; end; end; FrcImage := Rect(li_Left, li_Top, li_Left + li_Width, li_Top + li_Height); FormPaint(nil); end; if (barWidth.Visible) then begin barWidth.Position := -FrcImage.Left; end; if (barHeight.Visible) then begin barHeight.Position := -FrcImage.Top; end; FptMousePos := Point(-1, -1); end; (* procedure TApp_TOOLDskCaptWindow.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin if (Button = mbLeft) then begin if (Image1.Width <= ClientWidth) or (Image1.Height <= ClientHeight) then begin //表示画像の幅はフォームのクライアントの幅未満 F_ptMousePos := Point(-1, -1); end else begin F_ptMousePos := Point(X, Y); end; end; end; procedure TApp_TOOLDskCaptWindow.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var li_Left, li_Top : Integer; begin if (F_ptMousePos.X >= 0) and (F_ptMousePos.Y >= 0) then begin li_Left := Image1.Left + X - F_ptMousePos.X; li_Top := Image1.Top + Y - F_ptMousePos.Y; { if (li_Left >= 0) then begin li_Left := 0; end else if (li_Left + Image1.Width <= ClientWidth) then begin li_Left := ClientWidth - Image1.Width; end; if (li_Top >= 0) then begin li_Top := 0; end else if (li_Top + Image1.Height <= ClientHeight) then begin li_Top := ClientHeight - Image1.Height; end; } // F_MoveImage(li_Left, li_Top); Image1.SetBounds(li_Left, li_Top, Image1.Width, Image1.Height); // F_rcImage := Rect(li_Left, li_Top, li_Left + Image1.Width, li_Top + Image1.Height); end; end; procedure TApp_TOOLDskCaptWindow.Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var li_Left, li_Top : Integer; begin if (Button = mbLeft) then begin if (Image1.Width <= ClientWidth) or (Image1.Height <= ClientHeight) then begin //表示画像の幅はフォームのクライアントの幅未満 li_Left := (ClientWidth - Image1.Width) div 2; li_Top := (ClientHeight - Image1.Height) div 2; end else begin li_Left := Image1.Left; li_Top := Image1.Top; if (Image1.BoundsRect.Right <= ClientRect.Right) then begin li_Left := li_Left + ClientRect.Right - Image1.BoundsRect.Right; end; if (Image1.BoundsRect.Bottom <= ClientRect.Bottom) then begin li_Top := li_Top + ClientRect.Bottom - Image1.BoundsRect.Bottom; end; if (Image1.BoundsRect.Left >= ClientRect.Left) then begin li_Left := li_Left + ClientRect.Left - Image1.BoundsRect.Left; end; if (Image1.BoundsRect.Top >= ClientRect.Top) then begin li_Top := li_Top + ClientRect.Top - Image1.BoundsRect.Top; end; end; Image1.SetBounds(li_Left, li_Top, Image1.Width, Image1.Height); F_rcImage := Rect(li_Left, li_Top, li_Left + Image1.Width, li_Top + Image1.Height); end; F_ptMousePos := Point(-1, -1); end; *) //--- ズーム ------------------------------------------------------------------- procedure TApp_TOOLDskCaptWindow.actZoom_UpExecute(Sender: TObject); //拡大 function _GetZoomL(iShift : Integer; fZoom : Extended) : Extended; const lci_ZOOM_L : array[0..10] of Extended = (0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1); var i : Integer; li_Index : Integer; lf_Ret : Extended; begin Result := fZoom; if (fZoom <= 0) then begin Exit; end; if (fZoom < 0.1) then begin Result := _GetZoomL(iShift, fZoom * 10) / 10; end else begin lf_Ret := gfnfNumNearest(fZoom, lci_ZOOM_L); for i := 0 to High(lci_ZOOM_L) do begin if (lci_ZOOM_L[i] = lf_Ret) then begin li_Index := i + iShift; if (li_Index <= 0) then begin Result := _GetZoomL(iShift, fZoom * 10) / 10; end else if (li_Index > High(lci_ZOOM_L)) then begin //本来ここには来ないはず Result := 1.1; Break; end else begin Result := lci_ZOOM_L[li_Index]; Break; end; end; end; end; end; function _GetZoom(iShift : Integer) : Extended; const lci_ZOOM_H : array[0..19] of Extended = (0.9, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 3, 4, 5, 6, 7, 8, 9, 10); var i : Integer; li_Index : Integer; begin Result := gfniRectWidth(FrcImage) / FGetBitmap.Width; if (Result >= 1) then begin Result := gfnfNumNearest(Result, lci_ZOOM_H); for i := 0 to High(lci_ZOOM_H) do begin if (lci_ZOOM_H[i] = Result) then begin li_Index := i + iShift; if (li_Index >= 0) and (li_Index <= High(lci_ZOOM_H)) then begin Result := lci_ZOOM_H[li_Index]; Break; end; end; end; end else if (Result < 1) then begin Result := _GetZoomL(iShift, Result); end; end; const lci_ZOOM = 10; lci_MINSIZE = 16; //最小ピクセル(倍率ではない) lci_MAXZOOM = 10; //最大倍率 (ピクセル数ではない) var lf_Zoom : Extended; li_Shift : Integer; li_MaxSize : Integer; li_Left : Integer; li_Top : Integer; li_Width : Integer; li_Height : Integer; li_FWidth : Integer; li_FHeight : Integer; li_ClientWidth : Integer; li_ClientHeight : Integer; lpt_Pos : TPoint; begin if (FGetBitmap.Width <= 0) or (FGetBitmap.Height <= 0) then begin Exit; end; li_ClientWidth := FGetClientWidth; li_ClientHeight := FGetClientHeight; if (Sender = actZoom_Fit) then begin //ウィンドウサイズに合わせる gpcFitToRectVideoSizeGet(FGetBitmap, Rect(0, FGetTop, ClientWidth, ClientHeight), li_Width, li_Height); end else if (Sender = actZoom_100) then begin //実寸表示 li_Width := FGetBitmap.Width; li_Height := FGetBitmap.Height; end else if (Sender = actZoom_Up) or (Sender = actZoom_Down) then begin if (Sender = actZoom_UP) then begin //拡大 li_Shift := 1; end else begin //縮小 li_Shift := -1; end; if (gfnbKeyState(VK_SHIFT)) then begin //1ピクセルづつの拡大縮小 li_Width := gfniRectWidth(FrcImage) + (li_Shift * 1); end else begin lf_Zoom := _GetZoom(li_Shift); li_Width := Round(FGetBitmap.Width * lf_Zoom); end; li_MaxSize := FGetBitmap.Width * lci_MAXZOOM; li_Width := gfniNumLimit(li_Width, lci_MINSIZE, li_MaxSize); li_Height := gfniRound(li_Width * (FGetBitmap.Height / FGetBitmap.Width)); end else begin Exit; end; lpt_Pos := Self.ScreenToClient(gfnptMousePosGet); Dec(lpt_Pos.Y, FGetTop); if (li_Width < li_ClientWidth) then begin li_Left := (li_ClientWidth - li_Width) div 2; end else if (PtInRect(ClientRect, lpt_Pos)) then begin li_Left := lpt_Pos.X - gfniRound((lpt_Pos.X - FrcImage.Left) * li_Width / gfniRectWidth(FrcImage)); end else begin li_Left := FrcImage.Left; end; if (li_Height < li_ClientHeight) then begin li_Top := (li_ClientHeight - li_Height) div 2; end else if (PtInRect(Rect(0, FGetTop, li_ClientWidth, FGetTop + li_ClientHeight), lpt_Pos)) then begin li_Top := lpt_Pos.Y - gfniRound((lpt_Pos.Y - FrcImage.Top) * li_Height / gfniRectHeight(FrcImage)); end else begin li_Top := FrcImage.Top; end; FrcImage := Rect(li_Left, li_Top, li_Left + li_Width, li_Top + li_Height); if (Sender <> actZoom_Fit) then begin li_FWidth := Width - ClientWidth; li_FHeight := Height - ClientHeight; if (ToolBar1.Visible) then begin Inc(li_FHeight, ToolBar1.Height); end; li_Width := gfniRectWidth(FrcImage) + li_FWidth; li_Height := gfniRectHeight(FrcImage) + li_FHeight; if (li_Width <= App_TOOLDskCapt.WorkareaWidth) and (li_Height <= App_TOOLDskCapt.WorkareaHeight) then begin li_Left := gfniMax([Left, 0]); li_Top := gfniMax([Top, 0]); SetBounds(li_Left, li_Top, li_Width, li_Height); end; end; FormResize(nil); end; procedure TApp_TOOLDskCaptWindow.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean); begin if (WheelDelta < 0) then begin //縮小 actZoom_UpExecute(actZoom_Down); end else begin //拡大 actZoom_UpExecute(actZoom_Up); end; end; //--- キーボードショートカット ------------------------------------------------- procedure TApp_TOOLDskCaptWindow.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var li_MoveX, li_MoveY : Integer; begin case Key of VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT :begin //移動 li_MoveX := 0; li_MoveY := 0; case Key of VK_UP : li_MoveY := -1; VK_DOWN : li_MoveY := +1; VK_LEFT : li_MoveX := -1; VK_RIGHT : li_MoveX := +1; end; if (ssShift in Shift) then begin li_MoveX := li_MoveX * 10; li_MoveY := li_MoveY * 10; end; FrcImage := gfnrcRectShift(FrcImage, li_MoveX, li_MoveY); FormMouseUp(nil, mbLeft, [], 0, 0); //引数はmbLeft以外は適当で良い。 end; VK_PRIOR :begin //拡大 actZoom_UpExecute(actZoom_Up); end; VK_NEXT :begin //縮小 actZoom_UpExecute(actZoom_Down); end; end; end; procedure TApp_TOOLDskCaptWindow.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin // if (ssCtrl in Shift) then begin case Key of VK_C :begin //コピー actEdit_CopyExecute(nil); end; VK_S :begin //保存 actFile_SaveAsExecute(nil); end; VK_1 :begin //実寸表示 actZoom_UpExecute(actZoom_100); end; VK_F :begin //ウィンドウサイズに合わせる actZoom_UpExecute(actZoom_Fit); end; end; end; end; procedure TApp_TOOLDskCaptWindow.FSetFrameIndex(iIndex : Integer); begin if (FGetFrameCount = 0) then begin FiFrameIndex := 0; end else begin FiFrameIndex := gfniNumLimit(iIndex, 0, FGetFrameCount -1); // ImageList_Frame.GetBitmap(FiFrameIndex, FImage); end; FormPaint(nil); FSetInfo; App_TOOLDskCapt.__Menu_ChildPopup(nil); end; function TApp_TOOLDskCaptWindow.FGetFrameCount : Integer; begin // Result := ImageList_Frame.Count; Result := FImageList.Count; end; procedure TApp_TOOLDskCaptWindow.actFrame_BackExecute(Sender: TObject); begin //F_iFrameIndexは0ベース if (Sender = actFrame_Back) then begin FiFrameIndex := gfniNumLimit(FiFrameIndex -1, 0, FGetFrameCount -1); end else if (Sender = actFrame_Next) then begin FiFrameIndex := gfniNumLimit(FiFrameIndex +1, 0, FGetFrameCount -1); end else if (Sender = actFrame_Head) then begin FiFrameIndex := 0; end else if (Sender = actFrame_End) then begin FiFrameIndex := FGetFrameCount -1; end; FSetFrameIndex(FiFrameIndex); end; procedure TApp_TOOLDskCaptWindow.barWidthChange(Sender: TObject); //水平スクロールバー var li_Left : Integer; begin li_Left := -(barWidth.Position); FrcImage := Rect(li_Left, FrcImage.Top, li_Left + gfniRectWidth(FrcImage), FrcImage.Bottom); FormPaint(nil); end; procedure TApp_TOOLDskCaptWindow.barHeightChange(Sender: TObject); //垂直スクロールバー var li_Top : Integer; begin li_Top := -(barHeight.Position); FrcImage := Rect(FrcImage.Left, li_Top, FrcImage.Right, li_Top + gfniRectHeight(FrcImage)); FormPaint(nil); end; end.