fix: 型別更新
1) 新增 TShape, TMemo, TMenuItem, TImageScrollBox
2) 理清 Delphi 相依使用: IISUnit, MPSBarcode, IISImageProcess
3) 方法說明/Mermaid 生成
刪除1個檔案
修改27個檔案
新增27個檔案
4641 ■■■■ 已變更過的檔案
TImageScrollBox.pas 433 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
TMemo.pas 97 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
TMenuItem.pas 158 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
TShape.pas 42 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
doc/curtis/prompt/scanimpl_analysis/06/infer_image_interface.md 修補檔 | 檢視 | 原始 | 究查 | 歷程
doc/curtis/prompt/scanimpl_analysis/06/infer_interface.md 82 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
doc/curtis/prompt/scanimpl_analysis/06/infer_obj_interface.md 28 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
doc/curtis/prompt/scanimpl_analysis/deps/TImageScrollBox_deps.json 39 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
doc/curtis/prompt/scanimpl_analysis/deps/TMemo_deps.json 23 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
doc/curtis/prompt/scanimpl_analysis/deps/TMenuItem_deps.json 26 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
doc/curtis/prompt/scanimpl_analysis/deps/TShape_deps.json 16 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
doc/curtis/prompt/scanimpl_analysis/deps/iis_image_process_deps.json 25 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
doc/curtis/prompt/scanimpl_analysis/deps/iisunit_deps.json 26 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
doc/curtis/prompt/scanimpl_analysis/deps/mps_barcode_deps.json 6 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
doc/curtis/prompt/scanimpl_analysis/readme.md 10 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
iisunit.pas 556 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.api.pas 149 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.caseMgr.pas 43 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.convert.pas 93 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.custdoc.pas 34 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.docmod.pas 41 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.docq.pas 93 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.fileOp.pas 97 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.inbound.pas 54 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.lfcycle.pas 56 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.listMgr.pas 16 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.misc.pas 33 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.omr.pas 92 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.prUpload.pas 111 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/CB_IMGPSScanImp.preview.pas 113 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/TImageScrollBox.ts 36 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/TImageScrollBox.ts.bk 62 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/TMemo.ts 27 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/TMemo.ts.bk 34 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/TMenuItem.ts 28 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/TMenuItem.ts.bk 43 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/TShape.ts 15 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/TShape.ts.bk 17 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/iisunit.ts 83 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/iisunit.ts.bk 335 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/img/iis_image_process.ts 111 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/img/iis_image_process.ts.bk 187 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/img/mermaid/GetSiteOMR.md 12 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/img/mermaid/ImageReSize_FormID.md 2 ●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/img/mps_barcode.ts 49 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/img/mps_barcode.ts.bk 81 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/img/transformer.pas 57 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/scan/twain.pas 118 ●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/view/misc.pas 284 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/view/popupMenu.pas 140 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/view/scrollView.pas 39 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/view/toolBar.pas 73 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
reassemble/view/treeView.pas 43 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
scripts/infer_itf_scan_pas_deps.js 84 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
scripts/infer_itf_strip_ts_interface.js 89 ●●●●● 修補檔 | 檢視 | 原始 | 究查 | 歷程
TImageScrollBox.pas
比對新檔案
@@ -0,0 +1,433 @@
TImageScrollBox = class(TScrollingWinControl)
protected
    FImage               : TImage;
    FSourceGraphic       : TDibGraphic;
    FResizedBWGraphic    : TDibGraphic;
    FResizeTransform     : TResizeTransform;
    FAntiAliasTransform  : TAntiAliasTransform;
    FMouseHandler        : TMouseHandler;
    FMouseMode           : TMouseMode;
    FOnQuickSelect       : TQuickSelectEvent;
    FZoomMode            : TZoomMode;
    FZoomPercent         : Single;
    FLastZoomPercent     : Single;
    FAntiAliased         : Boolean;
    FOnZoomChange        : TZoomChangeEvent;
    FOnBeforeSave        : TBeforeSaveEvent;
    FOnRedraw            : TRedrawEvent;
    FAnimated            : Boolean;
    FAnimationTimer      : TTimer;
    FFileName            : String;
    FCentered            : Boolean;
    FRedrawInProgress    : Boolean;
    FScrollInProgress    : Boolean;
    FOnBeginScroll       : TNotifyEvent;
    FOnEndScroll         : TNotifyEvent;
    { Chained mouse handler events,  do not name these events, FOnMouseXXXX
      as this will cause stack overflows because this names are used by the
      VCL in the base class. }
    FOnImageMouseMove    : TMouseMoveEvent;
    FOnImageMouseDown    : TMouseEvent;
    FOnImageMouseUp      : TMouseEvent;
    FOnImageDblClick     : TNotifyEvent;
    FOnImageClick        : TNotifyEvent;
    FOnRubberbandChange  : TRubberbandChangeEvent;
    { MB Nov 13, 2001 }
    FImageRect           : TRect;
    { MB Nov 30, 2001 }
    FOnReadWriteProgress : TEnvisionProgressEvent;
    { MB Mar 13, 2002 }
    FReadAheadFileName   : String;
    FReadAheadGraphic    : TDibGraphic;
    { MB Oct 08, 2002 }
    FMouseHandlerOwnership : Boolean;
    { MB Oct 22, 2002 }
    FOnNewGraphic          : TNewGraphicEvent;
    { MB Nov 06, 2002 }
    FAnnotationsStr        : AnsiString;
    { MB Jan 08, 2003 }
    FAlwaysShowAnnotations : Boolean;
    FDisplayEditor         : TAnnotationsEditor;
    { MB Dec 11, 2003 }
    FMaxZoomPercent        : Double;
    procedure SetAlwaysShowAnnotations( const Show : Boolean );
    { trigger the FOnNewGraphic event }
    procedure DoNewGraphic( const Graphic : TGraphic ); virtual;
    procedure AnimateTimer( Sender : TObject );
    procedure SetZoomMode( const InZoomMode : TZoomMode );
    procedure SetZoomPercent( const InPercent : Single );
    function GetGraphic : TDibGraphic;
    procedure SetGraphic( const InGraphic : TDibGraphic );
    function GetDisplayedGraphic : TDibGraphic;
    procedure SetAntiAliased( const InAntiAliased : Boolean );
    { MB Aug 18, 1999. Resize is not virtual in Delphi 3, so the
     a message handler for WM_SIZE is used instead }
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
    { MB Nov 27, 1999. In Delphi 3, the BeforeDestruction method is not
      available in TObject, so the WM_DESTROY message is used to
      free the mouse handler }
    procedure WMDestroy(var Message: TWMDestroy); message WM_DESTROY;
    { MB Jan 30, 2000. Override to call UpdateWindow which reduces flickering
      on Windows NT }
    procedure WMHScroll(var Message: TWMHScroll); message WM_HSCROLL;
    procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;
    function GetFrameCount : LongInt;
    function GetFrame(FrameNo : LongInt) : TDibGraphic;
    function GetCurrentFrame : LongInt;
    procedure SetCurrentFrame( const FrameNo : LongInt );
    function GetAnimated : Boolean;
    procedure SetAnimated( const InAnimated : Boolean );
    procedure SetMouseMode( const InMouseMode : TMouseMode );
    procedure ImageMouseDown( Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure ImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure ImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure ImageDblClick(Sender : TObject);
    procedure ImageClick(Sender : TObject);
    procedure RedrawBW;
    procedure RedrawNotBW;
    procedure CenterImage( const NewWidth  : LongInt;
                           const NewHeight : LongInt );
    { recalcuate FZoomPercent from the current zoom mode }
    procedure RecalcZoom;
    procedure SetFileName( const FileName : String );
    procedure SetCentered( const InCentered : Boolean );
    procedure SetMouseHandler( const MouseHandler : TMouseHandler );
    procedure SetReadAheadFileName( const FileName : String );
    function InternalLoadFromStream( const Stream       : TStream;
                                     const Extension    : String;
                                     const ImageNo      : LongInt;
                                     const ShowProgress : Boolean ) : TDibGraphic;
    function GetAnnotations : AnsiString;
    procedure SetAnnotations( const Str : AnsiString );
    procedure ShowAnnotations;
    procedure HideAnnotations;
    procedure SetMaxZoomPercent( const InZoom : Double );
public
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
    { returns the number of images in a file. Useful to determinte the
      number of images in multi-image files such as TIFF. For single
      image file formats, 1 is returned. }
    function ImageCountFromFile( const FileName : String ) : LongInt;
    { see ImageCountFromFile }
    function ImageCountFromStream( const Stream    : TStream;
                                   const Extension : String ) : LongInt;
    { Load an image from a file. ImageNo must be 1 for single image file
      formats. For multiple image file formats (such as TIFF), ImageNo
      specifies the image to load. If ImageNo is 0, all images are loaded
      into memory and they are accessed with the CurrentFrame, and
      FrameCount properties. }
    procedure LoadFromFile( const FileName : String;
                            const ImageNo  : LongInt );
    { see LoadFromFile description }
    procedure LoadFromStream( const Stream    : TStream;
                              const Extension : String;
                              const ImageNo   : LongInt );
                              {$ifdef __Delphi4AndAbove}
                              overload;
                              {$endif} //mdm 02/21/2003 D3 support
    {$ifdef __Delphi4AndAbove}
    { load an image by determine the format from the contents of the Stream }
    procedure LoadFromStream( const Stream  : TStream;
                              const ImageNo : LongInt ); overload;
    {$endif}
    { save the currently displayed image to FileName in the format
      specified by the extension of FileName. To save a multi-image file such as
      TIFF, use AppendToFile/AppendToStream }
    procedure SaveToFile( const FileName  : String );
    { see SaveToFile description }
    procedure SaveToStream( const Stream    : TStream;
                            const Extension : String );
    { append the current displayed image to FileName. FileName must be
      a multi-image file format such as TIFF. }
    procedure AppendToFile( const FileName  : String );
    procedure AppendToStream( const Stream    : TStream;
                              const Extension : String );
    { clear the image in the scroll box }
    procedure Clear;
    { the Graphic property provides access to the source graphic being
      displayed in the image scroll box. Graphic.Canvas can be used to
      make changes to the Graphic. Redraw(True) must be called after
      making changes to the Graphic. }
    property Graphic : TDibGraphic read GetGraphic
                                   write SetGraphic;
    { the DisplayedGraphic property provides access to the resized graphic
      displayed in the image scroll box. Note that any change made to the
      displayed graphic will be lost when Redraw is called. }
    property DisplayedGraphic : TDibGraphic read GetDisplayedGraphic;
    procedure Redraw( const GraphicChanged : Boolean ); dynamic;
    property FrameCount : LongInt read GetFrameCount;
    property Frames[FrameNo: LongInt] : TDibGraphic read GetFrame;
    property CurrentFrame : LongInt read GetCurrentFrame
                                    write SetCurrentFrame;
    { if the image was loaded with ImageNo = 0, and the format is a multi-image
      format, setting Animated to True will animate the display of the
      images. }
    property Animated : Boolean read GetAnimated
                                write SetAnimated
                                default False;
    property MouseMode : TMouseMode read FMouseMode
                                    write SetMouseMode;
    { When setting the MouseHandler, the image scroll box becomes the
      owner of the object. The user must not free the object after it
      assigned to the MouseHandler property. This must be assigned a value
      only after setting the mouse mode to mmUser. }
    property MouseHandler : TMouseHandler read FMouseHandler
                                          write SetMouseHandler;
    { Read only access to the offset positions of the TImage on the scroll box.
      When the image is not Centered, the offset starts at 0,0 }
    property ImageRect: TRect read FImageRect;
    property ScrollInProgress : Boolean read FScrollInProgress;
    { Copy the currently selected region to the clipboard. If the MouseHandler
      is not TRubberbandMouseHandler, or a region is not selected, an
      EEnvisionError exception is raised. }
    procedure CopySelectionToClipboard;
    { Crop the currently selected region, and the selected region will replace
      the entire graphic in the  TImageScrollBox . If the MouseHandler
      is not TRubberbandMouseHandler, or a region is not selected, an
      EEnvisionError exception is raised.  }
    procedure CropToSelection;
    { extracts the currently selected region and copies it to Dest. If the
      MouseHandler is not TRubberbandMouseHandler, or a region is not selected,
      an EEnvisionError exception is raised. }
    procedure ExtractSelection(const Dest: TDibGraphic); //mdm 03/01/2003
    { Copy a graphic to the currently selected region. If the MouseHandler
      is not TRubberbandMouseHandler, or a region is not selected, an
      EEnvisionError exception is raised.  }
    procedure CopyGraphicIntoSelection( const Graphic : TGraphic );
    { Increase the zoom to display the selected region. May only be used when
      the mouse mode is mmSelect and a region is selected; otherwise an
      exception will be raised. }
    procedure ZoomToSelection;
    { procedure assign to the image scroll box the image currently loaded
      in the windows clipboard. Returns False when an image was not
      available in the clipboard (the current image is not changed in this
      case) }
    function AssignFromClipboard : Boolean;
    { annotation related properties and methods }
    { adding of graphical elements. The MouseMode must be mmAnnotate }
    function AddNote : TStickNoteMark;
    function AddText : TTextMark;
    function AddRectangle : TRectangleMark;
    function AddLine : TLineMark;
    function AddImage : TImageMark; { MB Apr 11, 2003 }
    procedure BurnAnnotations;
    { read or write the annotations. If the mouse mode is mmAnnotate, writing to the
      property will update the annotations }
    property Annotations : AnsiString read GetAnnotations
                                      write SetAnnotations;
    { MB Jan 08, 2003. If True, annotations are displayed even when MouseMode
      is not mmAnnotate }
    property AlwaysShowAnnotations : Boolean read FAlwaysShowAnnotations
                                             write SetAlwaysShowAnnotations;
    property MaxZoomPercent : Double read FMaxZoomPercent
                                     write SetMaxZoomPercent;
published
    property FileName : String read FFileName
                               write SetFileName;
    property ReadAheadFileName : String read FReadAheadFileName
                                        write SetReadAheadFileName;
    property AntiAliased : Boolean read FAntiAliased
                                   write SetAntiAliased
                                   default False;
    property ZoomMode : TZoomMode read FZoomMode
                                  write SetZoomMode
                                  default zmOriginalSize;
    property ZoomPercent : Single read FZoomPercent
                                  write SetZoomPercent;
    property Centered : Boolean read FCentered
                                write SetCentered
                                default False;
    property OnZoomChange : TZoomChangeEvent read FOnZoomChange
                                             write FOnZoomChange;
    property OnBeforeSave : TBeforeSaveEvent read FOnBeforeSave
                                             write FOnBeforeSave;
    property OnRedraw : TRedrawEvent read FOnRedraw
                                     write FOnRedraw;
    property OnNewGraphic : TNewGraphicEvent read FOnNewGraphic
                                             write FOnNewGraphic;
    property OnQuickSelect : TQuickSelectEvent read FOnQuickSelect
                                               write FOnQuickSelect;
    { Publish new mouse events which are chained from the FImage mouse
      events.  }
    property OnImageMouseMove : TMouseMoveEvent read FOnImageMouseMove
                                                write FOnImageMouseMove;
    property OnImageMouseDown : TMouseEvent read FOnImageMouseDown
                                            write FOnImageMouseDown;
    property OnImageMouseUp   : TMouseEvent read FOnImageMouseUp
                                            write FOnImageMouseUp;
    { MB Sep 23, 2002. }
    property OnImageDblClick  : TNotifyEvent read FOnImageDblClick
                                             write FOnImageDblClick;
    { Sep 29, 2003. Thanks to Yosi Mazal-Tov }
    property OnImageClick : TNotifyEvent read FOnImageClick
                                         write FOnImageClick;
    property OnRubberbandChange : TRubberbandChangeEvent
                                             read FOnRubberbandChange
                                             write FOnRubberbandChange;
    property OnReadWriteProgress : TEnvisionProgressEvent
                                     read FOnReadWriteProgress
                                     write FOnReadWriteProgress;
    property OnBeginScroll : TNotifyEvent read FOnBeginScroll
                                          write FOnBeginScroll;
    property OnEndScroll : TNotifyEvent read FOnEndScroll
                                        write FOnEndScroll;
    { If True, the mouse handler is owned by the image scroll box, and it
      will be destroyed everytime a new mouse handler is assigned and
      when the scroll box is destroyed. Default is True }
    property MouseHandlerOwnership : Boolean read FMouseHandlerOwnership
                                             write FMouseHandlerOwnership;
    property Align;
    {$ifdef __Delphi4AndAbove}
    property Anchors;
    property DockSite;
    property BiDiMode;
    property Constraints;
    property DragKind;
    property ParentBiDiMode;
    property OnCanResize;
    property OnConstrainedResize;
    property OnDockDrop;
    property OnDockOver;
    property OnEndDock;
    property OnGetSiteInfo;
    property OnResize;
    property OnStartDock;
    property OnUnDock;
    {$endif}
    property DragCursor;
    property DragMode;
    property Enabled;
    property Color nodefault;
    property Ctl3D;
    property Font;
    property ParentColor;
    property ParentCtl3D;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Visible;
    property OnClick;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnStartDrag;
    { MB Oct 11, 2002 }
    property OnKeyDown;
    property OnKeyUp;
    property OnKeyPress;
end;
TMemo.pas
比對新檔案
@@ -0,0 +1,97 @@
  TCustomMemo = class(TCustomEdit)
  private
    FLines: TStrings;
    FScrollBars: TScrollStyle;
    FWordWrap: Boolean;
    FWantReturns: Boolean;
    FWantTabs: Boolean;
    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
    procedure WMNCDestroy(var Message: TWMNCDestroy); message WM_NCDESTROY;
  protected
    function GetCaretPos: TPoint; virtual;
    procedure SetCaretPos(const Value: TPoint); virtual;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure CreateWindowHandle(const Params: TCreateParams); override;
    procedure KeyPress(var Key: Char); override;
    procedure Loaded; override;
    procedure SetLines(Value: TStrings);
    procedure SetScrollBars(Value: TScrollStyle);
    procedure SetWordWrap(Value: Boolean);
    property ScrollBars: TScrollStyle read FScrollBars write SetScrollBars default ssNone;
    property WantReturns: Boolean read FWantReturns write FWantReturns default True;
    property WantTabs: Boolean read FWantTabs write FWantTabs default False;
    property WordWrap: Boolean read FWordWrap write SetWordWrap default True;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property CaretPos: TPoint read GetCaretPos write SetCaretPos;
    property Lines: TStrings read FLines write SetLines;
  end;
  TMemo = class(TCustomMemo)
  published
    property Align;
    property Alignment;
    property Anchors;
    property BevelEdges;
    property BevelInner;
    property BevelKind default bkNone;
    property BevelOuter;
    property BiDiMode;
    property BorderStyle;
    property CharCase;
    property Color;
    property Constraints;
    property Ctl3D;
    property DoubleBuffered;
    property DragCursor;
    property DragKind;
    property DragMode;
    property Enabled;
    property Font;
    property HideSelection;
    property ImeMode;
    property ImeName;
    property Lines;
    property MaxLength;
    property OEMConvert;
    property ParentBiDiMode;
    property ParentColor;
    property ParentCtl3D;
    property ParentDoubleBuffered;
    property ParentFont;
    property ParentShowHint;
    property PopupMenu;
    property ReadOnly;
    property ScrollBars;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Visible;
    property WantReturns;
    property WantTabs;
    property WordWrap;
    property OnChange;
    property OnClick;
    property OnContextPopup;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseActivate;
    property OnMouseDown;
    property OnMouseEnter;
    property OnMouseLeave;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDock;
    property OnStartDrag;
  end;
TMenuItem.pas
比對新檔案
@@ -0,0 +1,158 @@
  TMenuItem = class(TComponent)
  private
    FCaption: string;
    FChecked: Boolean;
    FEnabled: Boolean;
    FDefault: Boolean;
    FAutoHotkeys: TMenuItemAutoFlag;
    FAutoLineReduction: TMenuItemAutoFlag;
    FRadioItem: Boolean;
    FVisible: Boolean;
    FGroupIndex: Byte;
    FImageIndex: TImageIndex;
    FActionLink: TMenuActionLink;
    FBreak: TMenuBreak;
    FBitmap: TBitmap;
    FCommand: Word;
    FHelpContext: THelpContext;
    FHint: string;
    FItems: TList;
    FShortCut: TShortCut;
    FParent: TMenuItem;
    FMerged: TMenuItem;
    FMergedWith: TMenuItem;
    FMenu: TMenu;
    FStreamedRebuild: Boolean;
    FImageChangeLink: TChangeLink;
    FSubMenuImages: TCustomImageList;
    FOnChange: TMenuChangeEvent;
    FOnClick: TNotifyEvent;
    FOnDrawItem: TMenuDrawItemEvent;
    FOnAdvancedDrawItem: TAdvancedMenuDrawItemEvent;
    FOnMeasureItem: TMenuMeasureItemEvent;
    FAutoCheck: Boolean;
    FHandle: TMenuHandle;
    procedure AppendTo(Menu: HMENU; ARightToLeft: Boolean);
    procedure DoActionChange(Sender: TObject);
    procedure ReadShortCutText(Reader: TReader);
    procedure MergeWith(Menu: TMenuItem);
    procedure RebuildHandle;
    procedure PopulateMenu;
    procedure SubItemChanged(Sender: TObject; Source: TMenuItem; Rebuild: Boolean);
    procedure TurnSiblingsOff;
    procedure VerifyGroupIndex(Position: Integer; Value: Byte);
    function GetAction: TBasicAction;
    function GetBitmap: TBitmap;
    procedure SetAction(Value: TBasicAction);
    procedure SetBitmap(Value: TBitmap);
    procedure SetSubMenuImages(Value: TCustomImageList);
    procedure ImageListChange(Sender: TObject);
    procedure InitiateActions;
    function IsCaptionStored: Boolean;
    function IsCheckedStored: Boolean;
    function IsEnabledStored: Boolean;
    function IsHelpContextStored: Boolean;
    function IsHintStored: Boolean;
    function IsImageIndexStored: Boolean;
    function IsOnClickStored: Boolean;
    function IsShortCutStored: Boolean;
    function IsVisibleStored: Boolean;
    function InternalRethinkHotkeys(ForceRethink: Boolean): Boolean;
    procedure SetAutoHotkeys(const Value: TMenuItemAutoFlag);
    function InternalRethinkLines(ForceRethink: Boolean): Boolean;
    procedure SetAutoLineReduction(const Value: TMenuItemAutoFlag);
  protected
    procedure ActionChange(Sender: TObject; CheckDefaults: Boolean); dynamic;
    procedure AdvancedDrawItem(ACanvas: TCanvas; ARect: TRect;
      State: TOwnerDrawState; TopLevel: Boolean); virtual;
    procedure AssignTo(Dest: TPersistent); override;
    procedure DefineProperties(Filer: TFiler); override;
    procedure DoDrawText(ACanvas: TCanvas; const ACaption: string;
      var Rect: TRect; Selected: Boolean; Flags: Longint);
    procedure DrawItem(ACanvas: TCanvas; ARect: TRect; Selected: Boolean); virtual;
    function GetActionLinkClass: TMenuActionLinkClass; dynamic;
    function GetHandle: HMENU;
    function GetCount: Integer;
    function GetItem(Index: Integer): TMenuItem;
    function GetMenuIndex: Integer;
    function GetAutoHotkeys: Boolean;
    function GetAutoLineReduction: Boolean;
    function InsertNewLine(ABefore: Boolean; AItem: TMenuItem): Integer;
    procedure MeasureItem(ACanvas: TCanvas; var Width, Height: Integer); virtual;
    procedure MenuChanged(Rebuild: Boolean); virtual;
    procedure Loaded; override;
    procedure Notification(AComponent: TComponent;
      Operation: TOperation); override;
    procedure SetBreak(Value: TMenuBreak);
    procedure SetCaption(const Value: string);
    procedure SetChecked(Value: Boolean);
    procedure SetChildOrder(Child: TComponent; Order: Integer); override;
    procedure SetDefault(Value: Boolean);
    procedure SetEnabled(Value: Boolean);
    procedure SetGroupIndex(Value: Byte);
    procedure SetImageIndex(Value: TImageIndex);
    procedure SetMenuIndex(Value: Integer);
    procedure SetRadioItem(Value: Boolean);
    procedure SetShortCut(Value: TShortCut);
    procedure SetVisible(Value: Boolean);
    procedure UpdateItems;
    property ActionLink: TMenuActionLink read FActionLink write FActionLink;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure InitiateAction; virtual;
    procedure Insert(Index: Integer; Item: TMenuItem);
    procedure Delete(Index: Integer);
    procedure Clear;
    procedure Click; virtual;
    function Find(ACaption: string): TMenuItem;
    function IndexOf(Item: TMenuItem): Integer;
    function IsLine: Boolean;
    procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
    function GetEnumerator: TMenuItemEnumerator;
    function GetImageList: TCustomImageList;
    function GetParentComponent: TComponent; override;
    function GetParentMenu: TMenu;
    function HasParent: Boolean; override;
    function NewTopLine: Integer;
    function NewBottomLine: Integer;
    function InsertNewLineBefore(AItem: TMenuItem): Integer;
    function InsertNewLineAfter(AItem: TMenuItem): Integer;
    procedure Add(Item: TMenuItem); overload;
    procedure Add(const AItems: array of TMenuItem); overload;
    procedure Remove(Item: TMenuItem);
    function RethinkHotkeys: Boolean;
    function RethinkLines: Boolean;
    procedure SetParentComponent(Value: TComponent); override;
    property Command: Word read FCommand;
    property Handle: HMENU read GetHandle;
    property Count: Integer read GetCount;
    property Items[Index: Integer]: TMenuItem read GetItem; default;
    property MenuIndex: Integer read GetMenuIndex write SetMenuIndex;
  published
    property Action: TBasicAction read GetAction write SetAction;
    property AutoCheck: Boolean read FAutoCheck write FAutoCheck default False;
    property AutoHotkeys: TMenuItemAutoFlag read FAutoHotkeys write SetAutoHotkeys default maParent;
    property AutoLineReduction: TMenuItemAutoFlag read FAutoLineReduction write SetAutoLineReduction default maParent;
    property Bitmap: TBitmap read GetBitmap write SetBitmap;
    property Break: TMenuBreak read FBreak write SetBreak default mbNone;
    property Caption: string read FCaption write SetCaption stored IsCaptionStored;
    property Checked: Boolean read FChecked write SetChecked stored IsCheckedStored default False;
    property SubMenuImages: TCustomImageList read FSubMenuImages write SetSubMenuImages;
    property Default: Boolean read FDefault write SetDefault default False;
    property Enabled: Boolean read FEnabled write SetEnabled stored IsEnabledStored default True;
    property GroupIndex: Byte read FGroupIndex write SetGroupIndex default 0;
    property HelpContext: THelpContext read FHelpContext write FHelpContext stored IsHelpContextStored default 0;
    property Hint: string read FHint write FHint stored IsHintStored;
    property ImageIndex: TImageIndex read FImageIndex write SetImageIndex stored IsImageIndexStored default -1;
    property RadioItem: Boolean read FRadioItem write SetRadioItem default False;
    property ShortCut: TShortCut read FShortCut write SetShortCut stored IsShortCutStored default 0;
    property Visible: Boolean read FVisible write SetVisible stored IsVisibleStored default True;
    property OnClick: TNotifyEvent read FOnClick write FOnClick stored IsOnClickStored;
    property OnDrawItem: TMenuDrawItemEvent read FOnDrawItem write FOnDrawItem;
    property OnAdvancedDrawItem: TAdvancedMenuDrawItemEvent read FOnAdvancedDrawItem write FOnAdvancedDrawItem;
    property OnMeasureItem: TMenuMeasureItemEvent read FOnMeasureItem write FOnMeasureItem;
  end;
TShape.pas
比對新檔案
@@ -0,0 +1,42 @@
TShape = class(TGraphicControl)
  private
    FPen: TPen;
    FBrush: TBrush;
    FShape: TShapeType;
    procedure SetBrush(Value: TBrush);
    procedure SetPen(Value: TPen);
    procedure SetShape(Value: TShapeType);
  protected
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    procedure StyleChanged(Sender: TObject);
    property Align;
    property Anchors;
    property Brush: TBrush read FBrush write SetBrush;
    property DragCursor;
    property DragKind;
    property DragMode;
    property Enabled;
    property Constraints;
    property ParentShowHint;
    property Pen: TPen read FPen write SetPen;
    property Shape: TShapeType read FShape write SetShape default stRectangle;
    property ShowHint;
    property Visible;
    property OnContextPopup;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDock;
    property OnEndDrag;
    property OnMouseActivate;
    property OnMouseDown;
    property OnMouseEnter;
    property OnMouseLeave;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDock;
    property OnStartDrag;
  end;
doc/curtis/prompt/scanimpl_analysis/06/infer_image_interface.md
doc/curtis/prompt/scanimpl_analysis/06/infer_interface.md
比對新檔案
@@ -0,0 +1,82 @@
---
description: 專案相依界面推斷與 TypeScript 界面生成規格
project_path: reassemble
project_files:
  - "reassemble/**/*.pas"
base_path: "doc/curtis/prompt/scanimpl_analysis"
script_path: "scripts"
units:
  - id: iisunit
    pas: "iisunit.pas"
    ts_bk: "reassemble/iisunit.ts.bk"
    ts_out: "reassemble/iisunit.ts"
  - id: iis_image_process
    pas: "iis_image_process.pas"
    ts_bk: "reassemble/img/iis_image_process.ts.bk"
    ts_out: "reassemble/img/iis_image_process.ts"
  - id: mps_barcode
    pas: "mps_barcode.pas"
    ts_bk: "reassemble/img/mps_barcode.ts.bk"
    ts_out: "reassemble/img/mps_barcode.ts"
  - id: TMemo
    pas: "TMemo.pas"
    ts_bk: "reassemble/TMemo.ts.bk"
    ts_out: "reassemble/TMemo.ts"
  - id: TImageScrollBox
    pas: "TImageScrollBox.pas"
    ts_bk: "reassemble/TImageScrollBox.ts.bk"
    ts_out: "reassemble/TImageScrollBox.ts"
  - id: TMenuItem
    pas: "TMenuItem.pas"
    ts_bk: "reassemble/TMenuItem.ts.bk"
    ts_out: "reassemble/TMenuItem.ts"
  - id: TShape
    pas: "TShape.pas"
    ts_bk: "reassemble/TShape.ts.bk"
    ts_out: "reassemble/TShape.ts"
---
## 1.0 核心處理邏輯定義 (Generic Workflow)
針對每一項 `unit`,執行以下標準化流程:
### 1.1 相依方法掃描與 JSON 匯出 (Dependency Analysis)
- **目標**:識別並過濾出在 `project_files` 中實際被引用的方法。
- **輸入**:
  - 源碼檔:`@{{unit.pas}}` (Delphi Interface section)
  - 引用者:`@{{project_files}}`
- **處理邏輯**:
  1. 提取 `{{unit.pas}}` 中 `interface` 區塊定義的所有 `procedure` 與 `function` 名稱。
  2. 遍歷 `project_files`,搜尋這些名稱的「精確匹配」(全詞匹配,忽略大小寫)。
  3. 僅保留在 `project_files` 中出現過至少一次的方法名稱。
- **輸出**:`{{base_path}}/deps/{{unit.id}}_deps.json`
  - 格式:`{ "unit": "{{unit.id}}", "used_methods": ["MethodA", "MethodB"] }`
### 1.2 TypeScript 界面精簡化 (Interface Stripping)
- **目標**:根據 1.1 的結果,將完整備份檔轉換為僅包含必要方法的界面檔。
- **輸入**:
  - 依賴清單:`{{base_path}}/deps/{{unit.id}}_deps.json`
  - TS 模板:`@{{unit.ts_bk}}`
- **處理邏輯**:
  1. 解析 TS 模板中的所有匯出成員(Exported functions/classes/interfaces)。
  2. 若該成員名稱「不包含」於 `used_methods` 列表中:
     - **完整刪除**:刪除該方法定義。
     - **關聯刪除**:必須包含該方法上方的 JSDoc (/** ... */) 或單行註解 (// ...)。
  3. 保留所有常數定義 (const)、枚舉 (enum) 及型別定義 (type/interface),除非它們被明確標記為僅供內部使用。
- **輸出腳本**:`{{script_path}}/infer_itf_strip_ts_interface.js`
- **最終產出**:`@{{unit.ts_out}}`
---
## 2.0 執行清單 (Task List)
### 2.1 基礎設施準備
- [ ] 建立 `{{base_path}}/deps/` 目錄。
- [ ] 撰寫通用掃描腳本 `{{script_path}}/infer_itf_scan_pas_deps.js`。
- [ ] 撰寫通用清理腳本 `{{script_path}}/infer_itf_strip_ts_interface.js`。
### 2.2 批次處理
| Unit ID | Step 1: Scan | Step 2: Strip |
| :--- | :--- | :--- |
| **iisunit** | 執行掃描並產出 `iisunit_deps.json` | 依據 JSON 生成 `iisunit.ts` |
| **iis_image_process** | 執行掃描並產出 `iis_image_process_deps.json` | 依據 JSON 生成 `iis_image_process.ts` |
| **mps_barcode** | 執行掃描並產出 `mps_barcode_deps.json` | 依據 JSON 生成 `mps_barcode.ts` |
doc/curtis/prompt/scanimpl_analysis/06/infer_obj_interface.md
比對新檔案
@@ -0,0 +1,28 @@
---
description: 專案物件界面推斷與 TypeScript 特定物件界面生成規格
project_path: reassemble
project_files:
  - "reassemble/**/*.pas"
base_path: "doc/curtis/prompt/scanimpl_analysis"
script_path: "scripts"
units:
  - id: TImageScrollBox
    pas: "reassemble/img/iis_image_process.ts"
    ts_bk: "reassemble/iisunit.ts.bk"
    ts_out: "reassemble/iisunit.ts"
  - id: TImageScrollBox.Graphic
    pas: "reassemble/img/iis_image_process.ts"
    ts_bk: "reassemble/img/iis_image_process.ts.bk"
    ts_out: "reassemble/img/iis_image_process.ts"
  - id: mps_barcode
    pas: "mps_barcode.pas"
    ts_bk: "reassemble/img/mps_barcode.ts.bk"
    ts_out: "reassemble/img/mps_barcode.ts"
---
## 2 介面推斷
### 2.1 推斷 TImageScrollBox 介面
### 2.1 推斷 TImageScrollBox.Graphic 介面
### 2.2 推斷 TMemo 介面
### 2.2 推斷 TShape 介面
doc/curtis/prompt/scanimpl_analysis/deps/TImageScrollBox_deps.json
比對新檔案
@@ -0,0 +1,39 @@
{
  "unit": "TImageScrollBox",
  "used_methods": [
    "Align",
    "AlwaysShowAnnotations",
    "AntiAliased",
    "AppendToStream",
    "Clear",
    "Color",
    "DisplayedGraphic",
    "DockSite",
    "DragMode",
    "Enabled",
    "FileName",
    "Font",
    "Graphic",
    "ImageCountFromFile",
    "LoadFromFile",
    "MouseMode",
    "OnClick",
    "OnDblClick",
    "OnDragDrop",
    "OnDragOver",
    "OnEndDrag",
    "OnImageClick",
    "OnImageMouseDown",
    "OnImageMouseMove",
    "OnImageMouseUp",
    "OnKeyPress",
    "PopupMenu",
    "Redraw",
    "SaveToFile",
    "SaveToStream",
    "Visible",
    "ZoomMode",
    "ZoomPercent",
    "assign"
  ]
}
doc/curtis/prompt/scanimpl_analysis/deps/TMemo_deps.json
比對新檔案
@@ -0,0 +1,23 @@
{
  "unit": "TMemo",
  "used_methods": [
    "Align",
    "Color",
    "DoubleBuffered",
    "DragMode",
    "Enabled",
    "Font",
    "Lines",
    "OnClick",
    "OnDblClick",
    "OnDragDrop",
    "OnDragOver",
    "OnEndDrag",
    "OnKeyPress",
    "OnMouseEnter",
    "OnMouseLeave",
    "ParentDoubleBuffered",
    "PopupMenu",
    "Visible"
  ]
}
doc/curtis/prompt/scanimpl_analysis/deps/TMenuItem_deps.json
比對新檔案
@@ -0,0 +1,26 @@
{
  "unit": "TMenuItem",
  "used_methods": [
    "Action",
    "Add",
    "Bitmap",
    "Break",
    "Caption",
    "Checked",
    "Clear",
    "Click",
    "Count",
    "Delete",
    "Enabled",
    "Find",
    "GetBitmap",
    "Handle",
    "Hint",
    "ImageIndex",
    "IndexOf",
    "Insert",
    "Items",
    "OnClick",
    "Visible"
  ]
}
doc/curtis/prompt/scanimpl_analysis/deps/TShape_deps.json
比對新檔案
@@ -0,0 +1,16 @@
{
  "unit": "TShape",
  "used_methods": [
    "Align",
    "DragMode",
    "Enabled",
    "OnDragDrop",
    "OnDragOver",
    "OnEndDrag",
    "OnMouseEnter",
    "OnMouseLeave",
    "Pen",
    "Shape",
    "Visible"
  ]
}
doc/curtis/prompt/scanimpl_analysis/deps/iis_image_process_deps.json
比對新檔案
@@ -0,0 +1,25 @@
{
  "unit": "iis_image_process",
  "used_methods": [
    "BWTif2Jpg",
    "CheckSize",
    "CleanupBorder",
    "ClearLine",
    "ConvertToBW",
    "ConvertToGray",
    "CropImg",
    "DeskewImg",
    "DpiResize",
    "FieldMask",
    "FindPoint",
    "GetTag",
    "Get_OMR",
    "ImageResize",
    "Image_Smooth",
    "NegativeImg",
    "PrintImg",
    "Rotate",
    "SaveAnnotation",
    "Watermark2"
  ]
}
doc/curtis/prompt/scanimpl_analysis/deps/iisunit_deps.json
比對新檔案
@@ -0,0 +1,26 @@
{
  "unit": "iisunit",
  "used_methods": [
    "ADD_Zoo",
    "AddLicense",
    "AddToolTip",
    "CM_Str2Rect",
    "CheckLicensebyIP_new",
    "Del_Sub_NothingPath",
    "En_DecryptionStr_Base64",
    "GetBalance",
    "GetBalance2Time",
    "GetCurrentVersionNo",
    "GetDate",
    "GetLocalAppDir",
    "LoadFileGetMD5",
    "PosEnd",
    "PosN",
    "SplitString",
    "Str2Dir",
    "Str2Point",
    "StringtoFile",
    "_DelTree",
    "_Msg"
  ]
}
doc/curtis/prompt/scanimpl_analysis/deps/mps_barcode_deps.json
比對新檔案
@@ -0,0 +1,6 @@
{
  "unit": "mps_barcode",
  "used_methods": [
    "MpsGetBarcode"
  ]
}
doc/curtis/prompt/scanimpl_analysis/readme.md
@@ -1,8 +1,12 @@
### 相依方法推斷
- [iis_image_process_deps.json](deps/iis_image_process_deps.json)
  推斷使用到 Delphi ImageProcess 方法
- [iisunit_deps.json](deps/iisunit_deps.json)
  推斷使用到 Delphi IISUnit 方法
- [mps_barcode_deps.json](deps/mps_barcode_deps.json)
  推斷使用到 Delphi MPSBarcode 方法
### 拆分說明:
iisunit.pas
@@ -58,124 +58,518 @@
  IIS_NowLng : String;
  Work_no : String;
function CheckRocID(ID : string) : Boolean;  //身份證號碼檢查
Function CheckBANO(const BANO: String): Boolean;  //統一編號檢查
FUNCTION  ADD_Zoo(istring,i:Integer):String; //數字補'0'轉字串
FUNCTION  ADD_Zoo1(istring:String;i:Integer):String; //字串補零
FUNCTION  ADD_Blank(istring:String;i:Integer):String; //字串補空白轉字串
Function GetDate_TW: string; //取得電腦日期民國年
Function GetDate_A: string; //取得電腦日期 XXXX/XX/XX
Function GetDate: string; //取得電腦日期
Function GetTime: string; //取得電腦時間
Function GetTime_A: string; //取得電腦時間 XX:XX:XX
Function GetTime_ms: string; //取得電腦時間至毫秒
Function GetTime2Sec(Time:String) : Integer; //將傳入時間轉成秒
Function GetBalance(ServerTime : string): Longint; //取得與Server的時間差距
Function GetBalance2Time(Balance:longint): string; //利用時間差距取得server上的時間
Function GetBalanceTime2Sec(Balance:longint): Integer; //利用時間差距取得server上的時間轉成秒
procedure Str2Dir(var Dir : String); //字串建目錄
Procedure ClearSubPath(MainPath:String);  //刪除路徑下第一層空目錄
function DirIsNull(DirName: string): Boolean; //是否為空目錄
procedure _DelTree(ASourceDir:String);  //刪掉指定目錄裡的所有檔案和子目錄(含自己)
Procedure CopyDirectory(Src, Des : string); //複製所有檔案(含子目錄)
Function UrlEncode(S : String) : String; //字串轉UrlCode
function LocalIP : String; //取得電腦的IP
function LocalIP_Single:String; //只取一個IP
Function GetMacFromIP(IP:String):String; //取出網卡
function En_DecryptionStr(CodeType:Char;InStr,Mpskey:String) :String; //字串加解密
function En_DecryptionStr_Base64(CodeType:Char;InStr,MpsKey:String):String; //字串先Base64再加解密
Procedure DecryptionFile(InFile,OutFile,MpsKey:String); //AES檔案解密(打不開)
Procedure EncryptionFile(InFile,OutFile,MpsKey:String); //AES檔案加密(打不開)
Function DecryptionStr(InStr,MpsKey:String):String; //AES字串解密(打不開)
{
  方法目的:身份證號碼檢查
  參數說明:ID - 身份證字號字串
  回傳值說明:回傳檢查結果,True 為合法,False 為不合法
}
function CheckRocID(ID : string) : Boolean;
{
  方法目的:統一編號檢查
  參數說明:BANO - 統一編號字串
  回傳值說明:回傳檢查結果,True 為合法,False 為不合法
}
Function CheckBANO(const BANO: String): Boolean;
{
  方法目的:數字補'0'轉字串
  參數說明:istring - 要轉換的數字; i - 總長度
  回傳值說明:補零後的字串
}
FUNCTION  ADD_Zoo(istring,i:Integer):String;
{
  方法目的:字串補零
  參數說明:istring - 原始字串; i - 總長度
  回傳值說明:補零後的字串
}
FUNCTION  ADD_Zoo1(istring:String;i:Integer):String;
{
  方法目的:字串補空白轉字串
  參數說明:istring - 原始字串; i - 總長度
  回傳值說明:補空白後的字串
}
FUNCTION  ADD_Blank(istring:String;i:Integer):String;
{
  方法目的:取得電腦日期民國年
  回傳值說明:民國年日期字串 (YYYMMDD)
}
Function GetDate_TW: string;
{
  方法目的:取得電腦日期 (格式: XXXX/XX/XX)
  回傳值說明:西元年日期字串 (YYYY/MM/DD)
}
Function GetDate_A: string;
{
  方法目的:取得電腦日期
  回傳值說明:西元年日期字串 (YYYYMMDD)
}
Function GetDate: string;
{
  方法目的:取得電腦時間
  回傳值說明:時間字串 (HHMMSS)
}
Function GetTime: string;
{
  方法目的:取得電腦時間 (格式: XX:XX:XX)
  回傳值說明:時間字串 (HH:MM:SS)
}
Function GetTime_A: string;
{
  方法目的:取得電腦時間至毫秒
  回傳值說明:時間字串 (HH:MM:SS:mmm)
}
Function GetTime_ms: string;
{
  方法目的:將傳入時間轉成秒
  參數說明:Time - 時間字串 (HHMMSS)
  回傳值說明:總秒數
}
Function GetTime2Sec(Time:String) : Integer;
{
  方法目的:取得與 Server 的時間差距
  參數說明:ServerTime - Server 時間字串
  回傳值說明:時間差距 (秒)
}
Function GetBalance(ServerTime : string): Longint;
{
  方法目的:利用時間差距取得 server 上的時間
  參數說明:Balance - 時間差距 (秒)
  回傳值說明:Server 時間字串 (HHMMSS)
}
Function GetBalance2Time(Balance:longint): string;
{
  方法目的:利用時間差距取得 server 上的時間轉成秒
  參數說明:Balance - 時間差距 (秒)
  回傳值說明:Server 時間總秒數
}
Function GetBalanceTime2Sec(Balance:longint): Integer;
{
  方法目的:字串建目錄
  參數說明:Dir - 目錄路徑 (var 參數,會自動補後斜線)
}
procedure Str2Dir(var Dir : String);
{
  方法目的:刪除路徑下第一層空目錄
  參數說明:MainPath - 主要路徑
}
Procedure ClearSubPath(MainPath:String);
{
  方法目的:是否為空目錄
  參數說明:DirName - 目錄路徑
  回傳值說明:True 為空目錄,False 則否
}
function DirIsNull(DirName: string): Boolean;
{
  方法目的:刪掉指定目錄裡的所有檔案和子目錄(含自己)
  參數說明:ASourceDir - 要刪除的目錄路徑
}
procedure _DelTree(ASourceDir:String);
{
  方法目的:複製所有檔案(含子目錄)
  參數說明:Src - 來源路徑; Des - 目的路徑
}
Procedure CopyDirectory(Src, Des : string);
{
  方法目的:字串轉 UrlCode
  參數說明:S - 原始字串
  回傳值說明:UrlCode 字串
}
Function UrlEncode(S : String) : String;
{
  方法目的:取得電腦的 IP
  回傳值說明:IP 清單字串 (以換行分隔)
}
function LocalIP : String;
{
  方法目的:只取一個 IP
  回傳值說明:單一 IP 字串
}
function LocalIP_Single:String;
{
  方法目的:取出網卡 MAC
  參數說明:IP - IP 位址
  回傳值說明:MAC 位址字串
}
Function GetMacFromIP(IP:String):String;
{
  方法目的:字串加解密
  參數說明:CodeType - 'E' 為加密, 'D' 為解密; InStr - 輸入字串; Mpskey - 密鑰
  回傳值說明:加解密後的字串
}
function En_DecryptionStr(CodeType:Char;InStr,Mpskey:String) :String;
{
  方法目的:字串先 Base64 再加解密
  參數說明:CodeType - 'E' 為加密, 'D' 為解密; InStr - 輸入字串; MpsKey - 密鑰
  回傳值說明:加解密後的字串
}
function En_DecryptionStr_Base64(CodeType:Char;InStr,MpsKey:String):String;
{
  方法目的:AES 檔案解密
  參數說明:InFile - 輸入檔案路徑; OutFile - 輸出檔案路徑; MpsKey - 密鑰
}
Procedure DecryptionFile(InFile,OutFile,MpsKey:String);
{
  方法目的:AES 檔案加密
  參數說明:InFile - 輸入檔案路徑; OutFile - 輸出檔案路徑; MpsKey - 密鑰
}
Procedure EncryptionFile(InFile,OutFile,MpsKey:String);
{
  方法目的:AES 字串解密
  參數說明:InStr - 輸入加密字串; MpsKey - 密鑰
  回傳值說明:解密後的字串
}
Function DecryptionStr(InStr,MpsKey:String):String;
function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;   //從前面取,第Offset個字開始取
function PosEnd(Substr,S: string): Integer;                   //從後面開始取
function PosN(Substr,S: string; N : Integer): Integer;        //指定取第幾個指定字元
function PosCount(SubStr,S : string) : Integer;      //總共有幾個指定的字元
Function P_Str2Rect(Str:String):Trect; //字串轉Rect
Function P_Rect2Str(iRect:TRect):String; //Rect轉字串
Function CM_Str2Rect(Str:String;Dpi:Integer;UpPoint:TPoint):TRect; //公分字串轉Rect
Function Rect2CM_Str(iRect:TRect;Dpi:Integer;UpPoint:TPoint):String; //Rect 轉公分字串
function GetProgID(FileName: String): String;  //取得ProgID
function GetVersion(FileName: String): String; //取得文件版本
function GetVersionForCab(FileName: String): String; //壓CAB取得文件版本,要用這個
function GetCLSID(FileName: String): WideString; //取得CoClass的ClassID
{
  方法目的:從前面取, 第 Offset 個字開始取位置
  參數說明:SubStr - 子字串; S - 原始字串; Offset - 開始偏移量
  回傳值說明:子字串位置
}
function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;
{
  方法目的:從後面開始取位置
  參數說明:Substr - 子字串; S - 原始字串
  回傳值說明:子字串位置
}
function PosEnd(Substr,S: string): Integer;
{
  方法目的:指定取第幾個指定字元位置
  參數說明:Substr - 子字串; S - 原始字串; N - 第幾個
  回傳值說明:字元位置
}
function PosN(Substr,S: string; N : Integer): Integer;
{
  方法目的:總共有幾個指定的字元
  參數說明:SubStr - 子字串; S - 原始字串
  回傳值說明:出現次數
}
function PosCount(SubStr,S : string) : Integer;
{
  方法目的:字串轉 Rect
  參數說明:Str - Rect 字串 (Left,Top,Right,Bottom)
  回傳值說明:TRect 結構
}
Function P_Str2Rect(Str:String):Trect;
{
  方法目的:Rect 轉字串
  參數說明:iRect - TRect 結構
  回傳值說明:Rect 字串 (Left,Top,Right,Bottom)
}
Function P_Rect2Str(iRect:TRect):String;
{
  方法目的:公分字串轉 Rect
  參數說明:Str - 公分字串; Dpi - DPI 值; UpPoint - 基準點
  回傳值說明:TRect 結構
}
Function CM_Str2Rect(Str:String;Dpi:Integer;UpPoint:TPoint):TRect;
{
  方法目的:Rect 轉公分字串
  參數說明:iRect - TRect 結構; Dpi - DPI 值; UpPoint - 基準點
  回傳值說明:公分字串
}
Function Rect2CM_Str(iRect:TRect;Dpi:Integer;UpPoint:TPoint):String;
{
  方法目的:取得 ProgID
  參數說明:FileName - 檔案路徑
  回傳值說明:ProgID 字串
}
function GetProgID(FileName: String): String;
{
  方法目的:取得文件版本
  參數說明:FileName - 檔案路徑
  回傳值說明:版本字串
}
function GetVersion(FileName: String): String;
{
  方法目的:壓 CAB 取得文件版本
  參數說明:FileName - 檔案路徑
  回傳值說明:版本字串 (逗號分隔)
}
function GetVersionForCab(FileName: String): String;
{
  方法目的:取得 CoClass 的 ClassID
  參數說明:FileName - 檔案路徑
  回傳值說明:CLSID 字串
}
function GetCLSID(FileName: String): WideString;
{
  方法目的:ShowTip
  參數說明:hwnd - 視窗控制代碼; lpti - ToolInfo 指標; IconType - 圖示類型; Text - 內容文字; Title - 標題文字; BackColor - 背景顏色; TextColor - 文字顏色
}
procedure AddToolTip(hwnd: dword; lpti: PToolInfo; IconType: Integer; Text, Title: PChar;
                     BackColor,TextColor:TColor); //ShowTip
                     BackColor,TextColor:TColor);
{
  方法目的:釋放 ToolTip
}
Procedure FreeToolTip;
{
  方法目的:多國語言訊息轉換
  參數說明:Msg - 訊息 Key
  回傳值說明:轉換後的訊息文字
}
Function _Msg(Msg:String):String;
Function _Msg_UTF8(Msg:String):String; //20210914增 用UTF8
Procedure Del_Sub_NothingPath(MainPath:String);  //刪除空的子目錄
{
  方法目的:多國語言訊息轉換 (UTF8)
  參數說明:Msg - 訊息 Key
  回傳值說明:轉換後的訊息文字 (UTF8)
}
Function _Msg_UTF8(Msg:String):String;
{
  方法目的:刪除空的子目錄
  參數說明:MainPath - 主要路徑
}
Procedure Del_Sub_NothingPath(MainPath:String);
{
  方法目的:字串轉 Point
  參數說明:S - Point 字串 (X,Y)
  回傳值說明:TPoint 結構
}
Function Str2Point(S:String):TPoint;
{
  方法目的:取得 AppData 目錄
  參數說明:Handle - 視窗控制代碼
  回傳值說明:路徑字串
}
Function GetAPPDir(Handle:THandle):String;
{
  方法目的:取得 Local AppData 目錄
  參數說明:Handle - 視窗控制代碼
  回傳值說明:路徑字串
}
Function GetLocalAppDir(Handle:THandle):String;
{
  方法目的:取得 System 目錄
  參數說明:Handle - 視窗控制代碼
  回傳值說明:路徑字串
}
Function GetSystemDir(Handle:THandle):String;
{
  方法目的:取得 Common AppData 目錄
  參數說明:Handle - 視窗控制代碼
  回傳值說明:路徑字串
}
Function GetCommonAppDir(Handle:THandle):String;
Procedure AddInfTxt2Img(InFile:String); //影像加辨識字串
Function CheckImage(ImageFile:String):Boolean; //檢查影像
Procedure GetAllDir(Path:String;var S :TStringlist); // 取得指定目錄下的所有子目錄清單
{
  方法目的:影像加辨識字串
  參數說明:InFile - 影像檔案路徑
}
Procedure AddInfTxt2Img(InFile:String);
{
  方法目的:檢查影像
  參數說明:ImageFile - 影像檔案路徑
  回傳值說明:True 為合法影像,False 則否
}
Function CheckImage(ImageFile:String):Boolean;
{
  方法目的:取得指定目錄下的所有子目錄清單
  參數說明:Path - 目錄路徑; S - 輸出的字串清單
}
Procedure GetAllDir(Path:String;var S :TStringlist);
Function CheckLicense(FileName:String;Var MacID,IP_Str,Msg:String;Var NowCount,TotalCount:Integer):Boolean; //檢查是有在清單內
Function CheckLicense_new(FileName:String;Var MacID,IP_Str,LegalDate,Msg:String;Var NowCount,TotalCount:Integer):Boolean; //有無限使用日期格式的
Function CheckLicensebyIP(FileName:String;Var MacID,IP_Str,Msg:String;Var NowCount,TotalCount:Integer):Boolean; //使用IP檢查是有在清單內
Function CheckLicensebyIP_new(FileName:String;Var MacID,IP_Str,LegalDate,Msg:String;Var NowCount,TotalCount,Lic_Idx:Integer):Boolean; //使用IP檢查是有在清單內及有無限使用日期格式的
{
  方法目的:檢查是否有在授權清單內
  參數說明:FileName - 授權檔案路徑; MacID - 輸出的 MAC ID; IP_Str - 輸出的 IP 字串; Msg - 輸出的訊息; NowCount - 輸出的目前計數; TotalCount - 輸出的總數計數
  回傳值說明:True 為有授權,False 則否
}
Function CheckLicense(FileName:String;Var MacID,IP_Str,Msg:String;Var NowCount,TotalCount:Integer):Boolean;
{
  方法目的:檢查授權 (含日期格式)
  參數說明:FileName - 授權檔案路徑; MacID - 輸出的 MAC ID; IP_Str - 輸出的 IP 字串; LegalDate - 輸出的合法日期; Msg - 輸出的訊息; NowCount - 輸出的目前計數; TotalCount - 輸出的總數計數
  回傳值說明:True 為有授權,False 則否
}
Function CheckLicense_new(FileName:String;Var MacID,IP_Str,LegalDate,Msg:String;Var NowCount,TotalCount:Integer):Boolean;
{
  方法目的:使用 IP 檢查是否有在授權清單內
  參數說明:FileName - 授權檔案路徑; MacID - 輸出的 MAC ID; IP_Str - 輸出的 IP 字串; Msg - 輸出的訊息; NowCount - 輸出的目前計數; TotalCount - 輸出的總數計數
  回傳值說明:True 為有授權,False 則否
}
Function CheckLicensebyIP(FileName:String;Var MacID,IP_Str,Msg:String;Var NowCount,TotalCount:Integer):Boolean;
{
  方法目的:使用 IP 檢查授權 (含日期格式)
  參數說明:FileName - 授權檔案路徑; MacID - 輸出的 MAC ID; IP_Str - 輸出的 IP 字串; LegalDate - 輸出的合法日期; Msg - 輸出的訊息; NowCount - 輸出的目前計數; TotalCount - 輸出的總數計數; Lic_Idx - 輸出的授權索引
  回傳值說明:True 為有授權,False 則否
}
Function CheckLicensebyIP_new(FileName:String;Var MacID,IP_Str,LegalDate,Msg:String;Var NowCount,TotalCount,Lic_Idx:Integer):Boolean;
Function AddLicense(FileName,MacID,IP_Str:String;Var Msg:String):Boolean; //是否還夠
{
  方法目的:增加授權
  參數說明:FileName - 授權檔案路徑; MacID - MAC ID; IP_Str - IP 字串; Msg - 輸出的訊息
  回傳值說明:True 為成功,False 則否
}
Function AddLicense(FileName,MacID,IP_Str:String;Var Msg:String):Boolean;
{
  方法目的:清除 Rect
  參數說明:iRect - TRect 結構
}
Procedure ClearRect(Var iRect:TRect);
{
  方法目的:取得位置參數
  參數說明:SiteStr - 位置字串; SpecSite - 指定位置 ('L', 'T', 'R', 'B')
  回傳值說明:參數值
}
Function GetSitepara(SiteStr,SpecSite:String):String;
{
  方法目的:取得兩數最小值
  參數說明:Value1 - 數值 1; Value2 - 數值 2
  回傳值說明:最小值
}
function MinFloat( const Value1 : Extended;
                   const Value2 : Extended ) : Extended;
{
  方法目的:字串存檔
  參數說明:S - 內容字串; FileName - 檔案路徑
}
Procedure StringtoFile(S,FileName:String);
{
  方法目的:字串存檔 (UTF8)
  參數說明:S - 內容字串; FileName - 檔案路徑
}
Procedure StringtoFile_Utf8(S,FileName:String);
{
  方法目的:字串附加至檔案
  參數說明:S - 內容字串; FileName - 檔案路徑
}
Procedure StringAddtoFile(S,FileName:String);
Function FiletoString(FileName:String):String; // 取出文字檔字串
Function FiletoString_utf8(FileName:String):String; // 取出文字檔字串
{
  方法目的:取出文字檔字串
  參數說明:FileName - 檔案路徑
  回傳值說明:檔案內容字串
}
Function FiletoString(FileName:String):String;
{
  方法目的:取出文字檔字串 (UTF8)
  參數說明:FileName - 檔案路徑
  回傳值說明:檔案內容字串 (UTF8)
}
Function FiletoString_utf8(FileName:String):String;
function IsNumberic(Value:String):Boolean; //判斷Vaule是不是數字
function IsEng_Num(Value:String):Boolean; //判斷Vaule是不是只有英數字
function IsEng(Value:String):Boolean; //判斷Vaule是不是只有英文字
Function ISBig5(Str:String):Boolean; //判斷字是否為Big5字元
Function GetFileSize(FileName:String):Int64; //取出檔案大小
Function ExeAlreadyProcess(ExeName:String):Boolean;  //程式是否已在執行(別人檢查)
Function ExeAlreadyProcessbySelf(ExeName:String):Boolean;  //程式是否已在執行(自己檢查自己)
Function GetProcessID(ExeName:String):Integer;  //取Exe程式的PID
Procedure RemovePID(PID:Integer);   //刪掉PID
function SplitString(const ch,Source:string):TStringList;overload; //分割字串
Procedure SplitString(const ch,Source:string;var List:TStringlist);overload; //分割字串
Function Getjsondata(JsonString:String;name:String):String; //取出Json指定name的值
Function SetjsonList(List:TStringlist;name:String):String; //產生Json
Function GetjsonList(JSonString:String;name:String):TStringlist; //取出Json指定name的陣列
Function GetjsonObjList(JSonString:String;name:String):TStringlist; //取出Json指定name的物件陣列
Function DeleteJsonObj(JSonString,name:String):String; //刪除Json指定的Obj
Procedure GetjsonListarray(JSonString:String;var DC:TDC); //取出Json的物件陣列
Procedure GetjsonObjectListarray(JSonString:String;Name:String;var DC:TDC); //取出Json的物件陣列
Function GetjsonObjecttoString(JSonString:String;Name:String):String; //取出JSon的物件的字串
{
  方法目的:判斷是不是數字
  參數說明:Value - 輸入字串
  回傳值說明:True 為數字,False 則否
}
function IsNumberic(Value:String):Boolean;
{
  方法目的:判斷是不是只有英數字
  參數說明:Value - 輸入字串
  回傳值說明:True 為英數字,False 則否
}
function IsEng_Num(Value:String):Boolean;
{
  方法目的:判斷是不是只有英文字
  參數說明:Value - 輸入字串
  回傳值說明:True 為英文字,False 則否
}
function IsEng(Value:String):Boolean;
{
  方法目的:判斷字是否為 Big5 字元
  參數說明:Str - 輸入字串
  回傳值說明:True 為 Big5,False 則否
}
Function ISBig5(Str:String):Boolean;
{
  方法目的:取出檔案大小
  參數說明:FileName - 檔案路徑
  回傳值說明:檔案大小 (Bytes)
}
Function GetFileSize(FileName:String):Int64;
{
  方法目的:程式是否已在執行
  參數說明:ExeName - 程式名稱
  回傳值說明:True 為已在執行,False 則否
}
Function ExeAlreadyProcess(ExeName:String):Boolean;
{
  方法目的:程式是否已在執行 (自己檢查自己)
  參數說明:ExeName - 程式名稱
  回傳值說明:True 為已在執行,False 則否
}
Function ExeAlreadyProcessbySelf(ExeName:String):Boolean;
{
  方法目的:取 Exe 程式的 PID
  參數說明:ExeName - 程式名稱
  回傳值說明:PID
}
Function GetProcessID(ExeName:String):Integer;
{
  方法目的:刪掉 PID
  參數說明:PID - 程序 ID
}
Procedure RemovePID(PID:Integer);
{
  方法目的:分割字串 (回傳 TStringList)
  參數說明:ch - 分隔字元; Source - 原始字串
  回傳值說明:分割後的字串清單
}
function SplitString(const ch,Source:string):TStringList;overload;
{
  方法目的:分割字串 (由 var List 回傳)
  參數說明:ch - 分隔字元; Source - 原始字串; List - 輸出的字串清單
}
Procedure SplitString(const ch,Source:string;var List:TStringlist);overload;
{ 取出 Json 指定 name 的值 }
Function Getjsondata(JsonString:String;name:String):String;
{ 產生 Json }
Function SetjsonList(List:TStringlist;name:String):String;
{ 取出 Json 指定 name 的陣列 }
Function GetjsonList(JSonString:String;name:String):TStringlist;
{ 取出 Json 指定 name 的物件陣列 }
Function GetjsonObjList(JSonString:String;name:String):TStringlist;
{ 刪除 Json 指定的 Obj }
Function DeleteJsonObj(JSonString,name:String):String;
{ 取出 Json 的物件陣列 }
Procedure GetjsonListarray(JSonString:String;var DC:TDC);
{ 取出 Json 的物件陣列 (指定 Name) }
Procedure GetjsonObjectListarray(JSonString:String;Name:String;var DC:TDC);
{ 取出 JSon 的物件的字串 }
Function GetjsonObjecttoString(JSonString:String;Name:String):String;
Function check_StrDate(SDate:String):Boolean; //字串日期是否合法
Function CheckDirName(DirName:String):Boolean; //檢查目錄名稱否有不合法字元
{ 字串日期是否合法 }
Function check_StrDate(SDate:String):Boolean;
{ 檢查目錄名稱是否有不合法字元 }
Function CheckDirName(DirName:String):Boolean;
{ 取得 OS 版本 }
Function GetOSVersion:Integer;
{ 取得新的 GUID }
Function GetNewGuid:String;
{ 字串轉 Hex }
function StringToHex(S: string): string; forward;
{ Hex 轉字串 }
function HexToString(S: string): string; forward;
Function CheckEAN13(Str:String):Boolean;  //檢查字串是否符合EAN13檢查
{ 檢查字串是否符合 EAN13 檢查 }
Function CheckEAN13(Str:String):Boolean;
Function GetPCName:String; //取電腦名稱
Function Stringlist2String(List:TStringlist):String; //StringList 轉字串
{ 取電腦名稱 }
Function GetPCName:String;
{ StringList 轉字串 }
Function Stringlist2String(List:TStringlist):String;
Function StringtoLogFormat(Str:String):String; //Log格式字串
{ Log 格式字串 }
Function StringtoLogFormat(Str:String):String;
{ Log 格式化 }
Function LogFormat(Str:String;Mode:Char;Var P_Start,P_Cost:DWORD):String; overload;
{ Log 格式化 (含時間) }
Function LogFormat(Str:String;Mode:Char;Var P_Start,P_Cost:DWORD;var LogSTime:String):String; overload;
{ 取得模組名稱 }
Function GetModalName(H:Cardinal):String;
{ 取代字串 }
Function ReplaceStr(Str,oldstr,Newstr:String):String;
{ 讀取檔案取得 MD5 }
Function LoadFileGetMD5(const filename: string): string;
{ 檢查子字串是否在逗號分隔字串內 }
Function SubCommaString(SubStr,CommaStr:String):Boolean;
{ 取得文件編碼類型 }
Function GetFileType(const FileName: string): TTextFormat;
{ 從螢幕大小取得 DPI }
function GetDPIFromScreenSize: Integer;
{ 延時函數 }
Procedure Delay(MSecs: Longint);
function GetCurrentVersionNo(Module:Cardinal): String; //獲取自身版本號所需要
Procedure StringtoDC(Str:String;Out DC:TDC); //將字串轉成Dictionary
{ 獲取自身版本號 }
function GetCurrentVersionNo(Module:Cardinal): String;
{ 將字串轉成 Dictionary }
Procedure StringtoDC(Str:String;Out DC:TDC);
{ 比較版本號 }
function CompareVersions(const NewVersion, OldVersion: string): Integer;
implementation
reassemble/CB_IMGPSScanImp.api.pas
@@ -1,8 +1,13 @@
{ ==============================================================================
  方法名稱:GetServerDate
  引用相依:ProcessServlet_Get
  方法描述:從伺服器獲取伺服器時間。透過 HTTPS 請求取得時間字串,解析日期與時間,並
            計算 Server 與本機的時間差(Balance)供後續校時使用。
  引用相依:GetBalance, ProcessServlet_Get
  方法描述:【獲取伺服器時間與校時】
            1. 請求:透過 HTTPS GET 請求 IMGPSC01/servertimeforocx。
            2. 解析:取得 14 位數時間字串 (YYYYMMDDHHNNSS)。
            3. 校時:截取前 8 碼存入 ServerDate,後 6 碼存入 ServerTime。
            4. 同步:呼叫 GetBalance 計算伺服器與本機的時間差 (Balance),確保後續加密
               請求的時間戳記精確。
            5. 安全:處理 Session 逾時自動導向登入頁面的情況。
============================================================================== }
Function TCB_IMGPSScanX.GetServerDate : Boolean;
begin
@@ -39,8 +44,12 @@
{ ==============================================================================
  方法名稱:GetSampleInf
  引用相依:ProcessServlet_Get
  方法描述:從伺服器獲取已註冊的範本表單 ID 清單,並存入 SampleFormIDList。
  引用相依:ProcessServlet_Get, SampleFormIDList
  方法描述:【獲取已註冊表單範本清單】
            1. 從伺服器取得該作業別 (FWork_no) 下所有已完成樣張註冊的 FormID。
            2. 回傳格式為 CommaText 字串。
            3. 解析並存入 SampleFormIDList,用於判斷掃瞄影像是否具備標準定位與
               OMR 檢核規格。
============================================================================== }
Function TCB_IMGPSScanX.GetSampleInf : Boolean;
var
@@ -78,11 +87,11 @@
{ ==============================================================================
  方法名稱:GetSetInf1
  引用相依:En_DecryptionStr_Base64, ProcessServlet_Get
  方法描述:向伺服器請求 DOC_INF 資料表資訊(模式 1)。方法會加密目前伺服器時間戳記
            並發送 HTTP GET 請求。若成功取得資料(狀態碼 '0'),則利用 SetSQLData 將
            結果解析並存入本地快取 Doc_Inf_List;若發生通訊錯誤或 Session 逾時(偵
            測到登入頁面標籤),則會記錄對應的 HttpErrStr 並返回 False。
  引用相依:En_DecryptionStr_Base64, ProcessServlet_Get, SetSQLData
  方法描述:【同步 DOC_INF 文件資訊】
            向伺服器請求 DOC_INF 資料表(Mode 1)。此表定義了作業別下所有的文件類別、
            版本、是否需分份 (IS_DOC_DIV) 以及是否入庫 (IS_IN_WH) 等關鍵屬性。
            取得資料後解析並存入本地快取 Doc_Inf_List。
============================================================================== }
Function TCB_IMGPSScanX.GetSetInf1 : Boolean; //取系統設定資訊Mode1 DOC_INF
Var
@@ -130,11 +139,11 @@
{ ==============================================================================
  方法名稱:GetSetInf2
  引用相依:En_DecryptionStr_Base64, ProcessServlet_Get
  方法描述:向伺服器請求 DM_FORM_INF 表單關聯資訊(模式 2)。流程包含加密請求參數與
            發送 GET 請求。此方法負責取得表單間的主從關係、相依性以及互斥規則,並將
            回傳的資料行解析後存入本地的 DM_FORM_INF_List。若通訊失敗或 Session
            過期,會設定錯誤訊息並中斷流程。
  引用相依:En_DecryptionStr_Base64, ProcessServlet_Get, SetSQLData
  方法描述:【同步 DM_FORM_INF 表單關聯規則】
            向伺服器請求 DM_FORM_INF 表單關聯資訊(Mode 2)。負責取得表單間的
            主從關係、相依性 (DEPE_FORM_ID) 以及互斥規則 (MUTEX_FORM_ID)。
            解析後存入本地 DM_FORM_INF_List 以供後續檢核使用。
============================================================================== }
Function TCB_IMGPSScanX.GetSetInf2 : Boolean; //取系統設定資訊Mode2  DM_FORM_INF
var
@@ -178,11 +187,11 @@
{ ==============================================================================
  方法名稱:GetSetInf3
  引用相依:En_DecryptionStr_Base64, ProcessServlet_Get
  方法描述:向伺服器請求 FORM_INF 表單詳細資料(模式 3)。方法會取得包含表單名稱、說
            明、分類、定位點類型(ANCHOR/FRAME)、最大頁數及預設高寬等中繼數據。取得的
            資料會被快取至 FORM_INF_List,作為影像處理(如自動縮放與 OMR 檢核)的重
            要依據。
  引用相依:En_DecryptionStr_Base64, ProcessServlet_Get, SetSQLData
  方法描述:【同步 FORM_INF 表單規格資訊】
            向伺服器請求 FORM_INF 實體規格(Mode 3)。取得包含表單名稱、定位點類型
            (ANCHOR/FRAME)、最大頁數及預設高寬等數據。快取至 FORM_INF_List,
            作為影像自動縮放與 OMR 檢核的位置基準。
============================================================================== }
Function TCB_IMGPSScanX.GetSetInf3 : Boolean; //取系統設定資訊mode3  FORM_INF
var
@@ -227,11 +236,11 @@
{ ==============================================================================
  方法名稱:GetSetInf4
  引用相依:En_DecryptionStr_Base64, ProcessServlet_Get
  方法描述:向伺服器請求 CHECK_RULE_INF 檢核規則資訊(模式 4)。此方法取得包含檢核
            代號、描述及顯示類型在內的驗證規則,並將其儲存於 CHECK_RULE_INF_List。
            最後會呼叫 CheckRule2OMRErrInfo,將取得的規則同步更新至 OMR 錯誤資訊
            記錄中,以確保前端檢核邏輯與伺服器同步。
  引用相依:CheckRule2OMRErrInfo, En_DecryptionStr_Base64, ProcessServlet_Get, SetSQLData
  方法描述:【同步 CHECK_RULE_INF 檢核規則】
            向伺服器請求 CHECK_RULE_INF 檢核定義(Mode 4)。取得包含檢核代號、
            錯誤描述及訊息顯示類型。同步更新至 OMR 錯誤資訊記錄 (CheckRule2OMRErrInfo),
            確保前端檢核邏輯與伺服器定義同步。
============================================================================== }
Function TCB_IMGPSScanX.GetSetInf4 : Boolean; //取系統設定資訊mode4  CHECK_RULE_INF
var
@@ -277,10 +286,10 @@
{ ==============================================================================
  方法名稱:GetSetInf5
  引用相依:En_DecryptionStr_Base64, ProcessServlet_Get
  方法描述:向伺服器請求 MEMO_INF 註記資訊(模式 5)。方法會取得預設的註記內容及其
            對應的類型名稱,並將其快取至 MEMO_INF_List。這些資料通常用於 UI 上的註
            記選擇選單,方便掃瞄人員在影像處理過程中快速標註預設的說明文字。
  引用相依:En_DecryptionStr_Base64, ProcessServlet_Get, SetSQLData
  方法描述:【同步 MEMO_INF 註記資訊】
            向伺服器請求 MEMO_INF 註記資訊(Mode 5)。取得系統預設的註記內容與類型,
            快取至 MEMO_INF_List 用於介面上的快速標註選單。
============================================================================== }
Function TCB_IMGPSScanX.GetSetInf5 : Boolean; //取系統設定資訊mode5  MEMO_INF
  var
@@ -324,11 +333,10 @@
{ ==============================================================================
  方法名稱:GetSetInf6
  引用相依:En_DecryptionStr_Base64, ProcessServlet_Get
  方法描述:向伺服器請求 WORK_INF 工作參數資訊(模式 6)。此方法取得當前工作項目的
            全域參數(如 PARA_NO 與 PARA_CONTENT),並儲存於 WORK_INF_List。這些參數
            控制了掃瞄器的預設行為(如 DPI、雙面掃瞄等),是系統初始化環境設定的關鍵
            步驟。
  引用相依:En_DecryptionStr_Base64, ProcessServlet_Get, SetSQLData
  方法描述:【同步 WORK_INF 作業全域參數】
            向伺服器請求 WORK_INF 參數資訊(Mode 6)。取得控制掃瞄器與系統行為的
            關鍵參數 (如 DPI, 雙面掃瞄, 上傳大小限制),是系統初始化環境設定的核心步驟。
============================================================================== }
Function TCB_IMGPSScanX.GetSetInf6 : Boolean; //取系統設定資訊mode5  WORK_INF
var
@@ -373,11 +381,10 @@
{ ==============================================================================
  方法名稱:GetSetInf7
  引用相依:En_DecryptionStr_Base64, ProcessServlet_Get
  方法描述:向伺服器請求 LASTEST_FORM_INF 最新表單版本資訊(模式 7)。方法會獲取各
            文件編號對應的最新表單 ID 與版本號,並儲存於 LASTEST_FORM_INF_List。此
            資訊用於確保使用者掃瞄的是最新版表單,或是用於舊案件轉檔時與歷史版本
            對照。
  引用相依:En_DecryptionStr_Base64, ProcessServlet_Get, SetSQLData
  方法描述:【同步 LASTEST_FORM_INF 最新版本資訊】
            向伺服器請求各文件編號對應的最新表單 ID(Mode 7)。用於確保目前處理的
            是最新版本,或在舊件轉檔時進行版本對比。
============================================================================== }
Function TCB_IMGPSScanX.GetSetInf7 : Boolean; //取系統設定資訊mode5  LASTEST_FORM_INF
var
@@ -422,9 +429,12 @@
{ ==============================================================================
  方法名稱:TransOldCaseFile
  引用相依:FileExists, upFile
  方法描述:處理舊件引用的檔案傳送。遍歷舊件清單,若發現有引用記錄,則透過 HTTPS 將
            引用資訊上傳至伺服器,並處理伺服器回傳狀態。
  引用相依:HTTPEncode, SplitString, UTF8Encode, upFile
  方法描述:【執行舊件引用關聯上傳】
            針對補件模式 (ESCAN) 下引用的歷史案件:
            1. 解析 FOldCaseInfo 中的 Tab 分隔元資料(案號、年度、校驗碼)。
            2. 檢查本地是否有對應舊件的 UseCase.ini。
            3. 透過 useOther 服務上傳關聯資訊,確保伺服器能正確引入歷史影像資料。
============================================================================== }
Function TCB_IMGPSScanX.TransOldCaseFile(Path:String):Boolean;
var
@@ -490,9 +500,10 @@
{ ==============================================================================
  方法名稱:Writelog
  引用相依:
  方法描述:透過 ProcessServlet 向伺服器發送列印日誌記錄。傳送案件編號與 FData 等
            參數,並檢查伺服器回傳是否成功或 Session 是否失效。
  引用相依:HTTPEncode, ProcessServlet, UTF8Encode
  方法描述:【傳送列印稽核日誌】
            將案件編號與執行人員資訊傳送至伺服器 printlog 服務,用於記錄列印行為
            與稽核追蹤。
============================================================================== }
Function TCB_IMGPSScanX.Writelog(CaseID : String):Boolean;
var
@@ -523,11 +534,9 @@
{ ==============================================================================
  方法名稱:DownLanguage
  引用相依:dnFile, dnFile_Get
  方法描述:從伺服器下載多國語言設定檔 Language.Lng。使用 HTTPS 客戶端執行 GET 請
            求,下載至本地語系路徑。下載後會檢查回傳內容,驗證是否發生錯誤、伺服器回
            傳錯誤訊息,或是因為閒置過久導致 Session 過期被導向登入頁面,並設定對
            應的錯誤字串。
  引用相依:dnFile_Get
  方法描述:【同步多國語言設定檔】
            從伺服器下載 Language.Lng,實現系統介面標籤與提示訊息的語系動態載入。
============================================================================== }
Function TCB_IMGPSScanX.DownLanguage:Boolean;  //下載多國語言檔
begin
@@ -557,10 +566,11 @@
{ ==============================================================================
  方法名稱:GetOMRCheckSet
  引用相依:FileExists, LoadFromFile, SaveToFile, dnFile, dnFile_Get
  方法描述:從伺服器下載並更新 OMR 檢核設定檔(OMRSet.zip)。程序會檢查本地 LastDat
            eTime.dat 取得最後更新時間,並發送請求。若伺服器有新資料,則下載後解壓
            縮並更新本地時間戳記;若無更新則維持現狀,並包含完整的錯誤處理邏輯。
  引用相依:ExecuteUnZip, GetBalance2Time, dnFile_Get
  方法描述:【增量更新 OMR 檢核配置】
            1. 讀取本地 LastDateTime.dat 取得最後更新點。
            2. 請求 settings (settype=3) 以獲取最新的 OMR 規則 ZIP 包。
            3. 若有新資料,下載後解壓縮並更新本地時間戳記,確保檢核邏輯維持最新。
============================================================================== }
Function TCB_IMGPSScanX.GetOMRCheckSet : Boolean; //下載OMR檢核XML檔
var
@@ -624,10 +634,10 @@
{ ==============================================================================
  方法名稱:GetKeyinSet
  引用相依:FileExists, LoadFromFile, SaveToFile, dnFile, dnFile_Get
  方法描述:從伺服器下載並更新登打設定檔(KeyinSet.zip)。運作機制與 GetOMRCheckSet
             相同,透過比對時間戳記決定是否執行下載與解壓縮,確保本地的登打定位資
            訊與伺服器同步。
  引用相依:ExecuteUnZip, GetBalance2Time, dnFile_Get
  方法描述:【增量更新登打欄位配置】
            1. 請求 settings (settype=2) 獲取最新的登打定位設定 ZIP 包。
            2. 機制與 OMR 更新相同,確保掃瞄人員在進行欄位校對時具備最新的欄位座標。
============================================================================== }
Function TCB_IMGPSScanX.GetKeyinSet : Boolean; //取登打設定
var
@@ -691,10 +701,11 @@
{ ==============================================================================
  方法名稱:CaseAsk
  引用相依:ProcessServlet_Get
  方法描述:在上傳案件前,向伺服器詢問該案件是否可進行傳送。針對 NSCAN 或 DSCAN 模
            式,會封裝案件編號與加密驗證資訊發送至 IMGPSC05/isnew 服務。根據伺服器
            回傳結果(0 表示可上傳,1 表示重複),決定後續的上傳流程。
  引用相依:HTTPEncode, ProcessServlet_Get, UTF8Encode
  方法描述:【上傳前置重複案號檢查】
            針對 NSCAN/DSCAN 模式,向伺服器確認案號是否可上傳。
            - 伺服器回傳 '0':新案件,可繼續上傳。
            - 伺服器回傳 '1':案件已存在或重複處理中。
============================================================================== }
Function TCB_IMGPSScanX.CaseAsk(CaseID: string):Integer;
var
@@ -749,11 +760,15 @@
{ ==============================================================================
  方法名稱:CaseComplete
  引用相依:En_DecryptionStr_Base64, FileExists, LoadFromFile
  方法描述:通知伺服器案件傳送完成。函式會收集案件的各項元數據,包含總頁數、主表單
            ID、經辦資訊、被保人資料等,並根據不同的業務模式(如 NSCAN, ESCAN)格式化
            發送數據。若包含 OMR 檢核失敗資訊或備註,也會一併封裝傳送,最後根據伺服
            器回傳值判定作業是否成功。
  引用相依:En_DecryptionStr_Base64, GetCaseFormID, GetBalance2Time,
            HTTPEncode, ProcessServlet, UTF8Encode
  方法描述:【上傳結案通知與元數據傳送】
            在影像 ZIP 包傳輸成功後,通知伺服器處理入庫:
            1. 封裝數據:包含 OMR 辨識值 (GetValue.xml)、經辦資訊、案件優先級、
               被保人資料、檢核備註 (CheckMemo) 與排除原因 (RemoveMemo)。
            2. 分流處理:根據業務模式呼叫不同的 Servlet (CWC05/08/09) 觸發後端
               資料庫寫入。
            3. 異常監控:若回傳非 '0',則代表後端處理失敗,提示使用者錯誤原因。
============================================================================== }
Function TCB_IMGPSScanX.CaseComplete(Path,CaseID:String;MainCase:Boolean):Boolean;  //通知傳送完成
var
reassemble/CB_IMGPSScanImp.caseMgr.pas
@@ -1,7 +1,9 @@
{ ==============================================================================
  方法名稱:Node2DocNo
  引用相依:
  方法描述:從樹狀結構節點 2(文件層)的文字中解析並提取文件編號(DocNo)。
  方法名稱 : Node2DocNo
  引用相依 : PosEnd
  方法描述 : 【從文件節點提取編號】
             解析 TreeView 中的文件層級節點文字 (格式如: 名稱{編號}-頁數)。
             透過 PosEnd 定位大括號 '{}',截取其中間的文件編號 (DocNo)。
============================================================================== }
Function TCB_IMGPSScanX.Node2DocNo(Node2:TTreeNode):String;  //MyTreeNode2取DocNo出來
var
@@ -19,9 +21,11 @@
{ ==============================================================================
  方法名稱:Node3DocNo
  引用相依:
  方法描述:從樹狀結構節點 3(表單層)的父節點文字中提取文件編號(DocNo)。
  方法名稱 : Node3DocNo
  引用相依 : PosEnd
  方法描述 : 【從表單節點之父層提取文件編號】
             針對 TreeView 的表單層級節點,取得其父節點 (文件層) 的文字,
             並比照 Node2DocNo 邏輯截取文件編號。
============================================================================== }
Function TCB_IMGPSScanX.Node3DocNo(Node3:TTreeNode):String;  //MyTreeNode3取DocNo出來
var
@@ -39,10 +43,12 @@
{ ==============================================================================
  方法名稱:CaseDelete_Enable
  引用相依:FileExists, LoadFromFile
  方法描述:判斷案件是否允許刪除。若案件下有任何文件目錄已被其他程序引用,則禁止刪
            除。
  方法名稱 : CaseDelete_Enable
  引用相依 : GetUseCase, CaseDocNoList
  方法描述 : 【判定案件可否刪除】
             1. 載入案件目錄清單。
             2. 遍歷所有文件目錄,呼叫 GetUseCase 檢查該目錄是否正被其他程序引用。
             3. 若有任何目錄處於被引用狀態,則禁止刪除該案件,以確保資料一致性。
============================================================================== }
Function TCB_IMGPSScanX.CaseDelete_Enable(CaseID:String):Boolean;  //案件可否被刪除
var
@@ -67,9 +73,11 @@
{ ==============================================================================
  方法名稱:DocNoExistsinTree
  引用相依:
  方法描述:檢查指定的案件節點下,是否已經存在具備該文件代號(DocNo)的子節點。
  方法名稱 : DocNoExistsinTree
  引用相依 : DocNode2Info
  方法描述 : 【檢查樹狀結構是否已有重複文件】
             在 TreeView 的案件節點下搜尋,利用 DocNode2Info 提取子節點的代號,
             判定是否已存在指定的文件編號 (DocNo),避免 UI 上出現重複的文件分類。
============================================================================== }
Function TCB_IMGPSScanX.DocNoExistsinTree(CaseNode:TTreeNode;DocNo:String):Boolean; //是否己存在樹裡
var
@@ -89,10 +97,11 @@
{ ==============================================================================
  方法名稱:DocnoNeedGroup
  引用相依:
  方法描述:查詢 Doc_Inf_List 判斷傳入的文件代號是否需要進行文件分組(IS_DOC_DIV
            = "Y")。
  方法名稱 : DocnoNeedGroup
  引用相依 : Doc_Inf_List, FindSQLData
  方法描述 : 【判定文件是否需執行分組邏輯】
             查詢系統設定 Doc_Inf_List,若該文件編號的 IS_DOC_DIV 欄位為 'Y',
             則代表該類文件在掃瞄時需根據分隔頁進行自動目錄切分。
============================================================================== }
Function TCB_IMGPSScanX.DocnoNeedGroup(DocNo:String):Boolean; //傳入的DocNo是否需分組
begin
reassemble/CB_IMGPSScanImp.convert.pas
@@ -1,8 +1,9 @@
{ ==============================================================================
  方法名稱:Path2DocDir
  引用相依:FileExists, LoadFromFile
  方法描述:將實體路徑轉換為案件內的文件目錄名稱。透過比對路徑字串與 CaseDocNo.da
            t 中的清單來識別對應的目錄。
  方法名稱 : Path2DocDir
  引用相依 : CaseDocNo.dat
  方法描述 : 【將實體路徑還原為文件目錄名稱】
             透過比對傳入的完整 Path 與案件目錄下 CaseDocNo.dat 定義的子目錄清單,
             找回對應的邏輯目錄名稱。
============================================================================== }
Function TCB_IMGPSScanX.Path2DocDir(Path,CaseID:String):String;
var
@@ -31,10 +32,12 @@
{ ==============================================================================
  方法名稱:FormCode2FormName
  引用相依:
  方法描述:將表單代碼轉換為易讀的文件名稱。優先查詢系統定義表,若無則至自定義文件
            清單中搜尋。
  方法名稱 : FormCode2FormName
  引用相依 : FORM_INF_List, GetCustomDocName
  方法描述 : 【表單代碼轉顯示名稱】
             1. 基本判定:若代號為空或附件 (Attach),回傳「未歸類」。
             2. 系統查詢:從 FORM_INF_List 查找對應的 FORM_DESC。
             3. 自定義查找:若系統查無結果,則至案件本地的自訂文件設定中搜尋。
============================================================================== }
Function TCB_IMGPSScanX.FormCode2FormName(CaseID,FormCode:String):String; //用FormCode轉成文件名稱
var
@@ -118,10 +121,11 @@
{ ==============================================================================
  方法名稱:FileName2FormCode
  引用相依:
  方法描述:從影像檔名中提取表單代碼(底線與點號之間的部分)。若檔名格式不符則視為
            附件並回傳空字串。
  方法名稱 : FileName2FormCode
  引用相依 : ExtractFileName
  方法描述 : 【從檔名提取表單代碼】
             掃瞄產生的檔名格式通常為「序號_表單代碼.副檔名」。此方法截取底線與
             點號間的字串作為 FormCode;若無底線則視為附件。
============================================================================== }
Function TCB_IMGPSScanX.FileName2FormCode(FileName:String):String; //從檔名取出FormCode
var
@@ -231,12 +235,11 @@
{ ==============================================================================
  方法名稱:FormCode2DocNo
  引用相依:
  方法描述:將表單代碼 (FormCode) 轉換為對應的文件編號 (DocNo)。方法遍歷預載的 Fo
            rmID_List,若找到匹配的表單代碼,則返回 DocNo_List 中相同索引位置的數
            值。若表單代碼不在清單中(通常為使用者自訂的文件),則預設截取代碼的前 8
             位字元作為文件編號返回。
  方法名稱 : FormCode2DocNo
  引用相依 : FormID_List, DocNo_List
  方法描述 : 【表單代碼轉文件類別編號】
             1. 查表:從同步好的映射清單中找出對應關係。
             2. 容錯:若查無此表單(自定義件),則預設取前 8 碼作為 DocNo。
============================================================================== }
Function TCB_IMGPSScanX.FormCode2DocNo(FormCode:String):String;   //FormCode轉Docno
Var
@@ -287,13 +290,14 @@
{ ==============================================================================
  方法名稱:DocNo2DocName
  引用相依:
  方法描述:解析文件編號對應的描述性名稱。優先權邏輯為:
            1. 若編號符合附件名稱 (AttName),返回「未歸類」。
            2. 從系統定義快取 (Doc_Inf_List) 中搜尋對應的描述 (DOC_U_DESC)。
            3. 若系統定義查無結果,則呼叫 GetCustomDocName 從案件本地的自訂文件設
            定中尋找對應名稱。此方法確保 UI 上能顯示人類可讀的文件類別名稱。
  方法名稱 : DocNo2DocName
  引用相依 : Doc_Inf_List, GetCustomDocName
  方法描述 : 【文件類別編號轉顯示名稱】
             解析文件編號對應的描述性名稱。優先權邏輯為:
             1. 若編號符合附件名稱 (AttName),返回「未歸類」。
             2. 從系統定義快取 (Doc_Inf_List) 中搜尋對應的描述 (DOC_U_DESC)。
             3. 若系統定義查無結果,則呼叫 GetCustomDocName 從案件本地的自訂文件設
                定中尋找對應名稱。
============================================================================== }
Function TCB_IMGPSScanX.DocNo2DocName(CaseID,DocNo:String):String; //Docno轉Doc名稱
var
@@ -386,12 +390,11 @@
{ ==============================================================================
  方法名稱:DocNoNeedDiv
  引用相依:
  方法描述:檢查指定的文件類型是否需要執行頁面拆分(分份數)。方法透過 FindSQLData
            在 Doc_Inf_List 中查詢該編號的 'IS_DOC_DIV' 欄位,若旗標值為 'Y' 則返
            回 True,否則返回 False。此設定決定了掃瞄流程中是否需要根據條碼自動切
            分文件目錄。
  方法名稱 : DocNoNeedDiv
  引用相依 : Doc_Inf_List, FindSQLData
  方法描述 : 【判定文件是否需分份】
             檢查指定的文件類型是否需要執行頁面拆分(分份數)。方法透過查詢
             Doc_Inf_List 的 'IS_DOC_DIV' 欄位,若旗標值為 'Y' 則返回 True。
============================================================================== }
Function TCB_IMGPSScanX.DocNoNeedDiv(DocNo:String):Boolean; //是否是需分份數的文件代號
var
@@ -428,12 +431,15 @@
{ ==============================================================================
  方法名稱:DocNode2Info
  引用相依:
  方法描述:從樹狀結構的文件節點文字中提取詳細資訊。節點文字格式預期為「文件名稱@
            組數{文件代號}-XX頁」。此函式會根據傳入的模式(Mode),利用分隔符號(@, {,
             }, -)定位並截取回傳文件代號(I)、文件名稱(N)、文件頁碼(P)或文件組別(G)
            。
  方法名稱 : DocNode2Info
  引用相依 : PosEnd
  方法描述 : 【解析文件節點元數據】
             針對格式為「名稱@組數{編號}-頁數」的 TreeView 節點進行字串分割。
             模式 (Mode):
             - I: 文件代號 (DocNo)
             - N: 文件名稱 (DocName)
             - P: 總頁數 (DocPage)
             - G: 分組組數 (DocGroup)
============================================================================== }
Function TCB_IMGPSScanX.DocNode2Info(Node:TTreeNode;Mode:Char):String;   //文件Node取文件代號 Mode: I:Docno;N:Docname;P:Page;G:Group
var
@@ -455,11 +461,14 @@
{ ==============================================================================
  方法名稱:FormNode2Info
  引用相依:
  方法描述:從樹狀結構的表單節點文字中提取資訊。節點文字格式預期為「表單代號{表單
            名稱}-XX頁」。根據模式(Mode)參數,解析並回傳表單代號(I)、表單名稱(N)或頁
            碼(P)。
  方法名稱 : FormNode2Info
  引用相依 : PosEnd
  方法描述 : 【解析表單節點元數據】
             針對格式為「表單代號{名稱}-頁數」的 TreeView 節點進行解析。
             模式 (Mode):
             - I: 表單 ID (FormID)
             - N: 表單名稱 (FormName)
             - P: 頁碼 (Page)
============================================================================== }
Function TCB_IMGPSScanX.FormNode2Info(Node:TTreeNode;Mode:Char):String;   //表單Node取表單代號  Mode: I:FormID;N:FormName;P:Page
var
reassemble/CB_IMGPSScanImp.custdoc.pas
@@ -1,9 +1,11 @@
{ ==============================================================================
  方法名稱:GetNewCustomDocNo
  引用相依:FileExists, LoadFromFile, SaveToFile
  方法描述:產生一個全新的自定義文件編號。讀取 CustomDocNo.ini 中的計數器,根據入
            庫/非入庫性質產生 ZZZZZ 或 YYYYY 開頭的編號,並預設其內部的第一個表單
            代碼,最後將新設定寫回 INI 檔。
  方法名稱 : GetNewCustomDocNo
  引用相依 : Add_Zoo, CustomDocNo.ini
  方法描述 : 【產生新自定義文件代號】
             1. 讀取 CustomDocNo.ini 中的累計數量。
             2. 產生編號:入庫件以 'ZZZZZ' 開頭,非入庫或補件模式以 'YYYYY' 開頭。
             3. 映射表單:預設一個基於 DocNo 的偽表單 ID (如 ZZZZZ001010101A)。
             4. 註冊:將編號、名稱與偽 ID 寫入 INI 檔,供後續辨識。
============================================================================== }
Function TCB_IMGPSScanX.GetNewCustomDocNo(Path,DocName:String):String; //取出未使用的自訂文件代號
var
@@ -108,10 +110,11 @@
{ ==============================================================================
  方法名稱:GetCustomDocDir
  引用相依:
  方法描述:根據自定義文件名稱尋找對應的目錄代號(如 ZZZZZ001)。遍歷 CustomDocNo.i
            ni 中的所有區段,讀取 Name 欄位進行比對,成功則回傳該編號。
  方法名稱 : GetCustomDocDir
  引用相依 : Add_Zoo, CustomDocNo.ini
  方法描述 : 【根據名稱反查自定義目錄代號】
             遍歷 INI 檔中 ZZZZZ 與 YYYYY 系列的所有區段,比對 'Name' 欄位,
             找回對應的自定義編號(如 ZZZZZ001)。
============================================================================== }
Function TCB_IMGPSScanX.GetCustomDocDir(Path,DocName:String):String; //取出自定文件DocDir
var
@@ -172,11 +175,14 @@
{ ==============================================================================
  方法名稱:Create_Cust_DocDir
  引用相依:DirectoryExists
  方法描述:根據外部傳入的清單(FC_DocNoList 或 FC_DocNameList)預先產生案件所需的
            文件目錄。會自動處理分份文件的命名、檢查是否已存在,並在 CustomDocNo.in
            i 中註冊新名稱。
  方法名稱 : Create_Cust_DocDir
  引用相依 : FC_DocNoList, FC_DocNameList, GetNewCustomDocNo, SetDocNoList
  方法描述 : 【根據外部指令預建目錄】
             1. 處理 DocNoList:根據網頁傳入的編號清單,檢查是否需分份,並建立
                對應目錄 (如 101, 101(2))。
             2. 處理 DocNameList:針對網頁傳入的自定義名稱,呼叫 GetNewCustomDocNo
                分配編號並建立實體目錄。
             3. 註冊:呼叫 SetDocNoList 更新案件的文件索引。
============================================================================== }
Procedure TCB_IMGPSScanX.Create_Cust_DocDir(CaseID:String); //產生外面傳入的文件代號及自定文件
var
reassemble/CB_IMGPSScanImp.docmod.pas
@@ -1,11 +1,12 @@
{ ==============================================================================
  方法名稱:OldCasetoNewCase
  引用相依:LoadFromFile, SaveToFile
  方法描述:將舊系統格式的案件文件份數轉換為新系統規則。方法會載入案件的文件目錄
            清單 (CaseDocNo.dat),並解析由全域變數傳入的舊案文件編號與名稱清單(以
             Tab 字串傳遞)。流程中會針對每個目錄編號統計其在舊資料中的出現次數,並
            將統計後的份數結果更新至 CaseDocNo_Copies.dat 檔案中,以完成歷史資料
            的規格對接。
  方法名稱 : OldCasetoNewCase
  引用相依 : FC_DocNoList, FC_DocNameList, CaseDocNo_Copies.dat
  方法描述 : 【將舊案資料結構標準化】
             1. 讀取:載入舊案實體目錄清單。
             2. 解析:從網頁傳入的 Tab 字串中解析該案件應有的文件結構。
             3. 統計:比對實體目錄與指令,計算每一類文件的正確份數。
             4. 修正:將統計結果寫入 CaseDocNo_Copies.dat,完成歷史案件到新版
                份數管理規則的對接。
============================================================================== }
Procedure TCB_IMGPSScanX.OldCasetoNewCase(CaseID:String); //將舊案份數轉成新規則
var
@@ -78,15 +79,13 @@
{ ==============================================================================
  方法名稱:ErrFormtoCurrentForm
  引用相依:FileExists, LoadFromFile, MoveFile, RenameFile, SaveToFile
  方法描述:修正案件中歸類錯誤的表單代碼及其關聯檔案。邏輯如下:
            1. 取得錯誤與正確表單對應的文件編號。
            2. 遍歷案件下的所有文件目錄,載入各目錄的影像索引檔 (Context.dat)。
            3. 識別檔名中包含 EFormID 的影像,執行實體重新命名並更新索引。
            4. 若該目錄編號與錯誤文件編號一致,則會執行 MoveFile 搬移整個目錄至新
            路徑,並同步更新總文件清單 (CaseDocNo.dat),確保影像與分類資訊的一致性
            。
  方法名稱 : ErrFormtoCurrentForm
  引用相依 : FileName2FormCode, StringReplace, MoveFile
  方法描述 : 【修正歸類錯誤的表單】
             1. 重新命名:遍歷影像索引,將檔名中錯誤的 EFormID 替換為正確的 CFormID。
             2. 目錄搬移:若該文件目錄名稱包含錯誤編號,則執行實體 MoveFile 搬移至
                正確目錄名下。
             3. 索引同步:同步更新 CaseDocNo.dat 與各目錄的 Context.dat 檔案。
============================================================================== }
Procedure TCB_IMGPSScanX.ErrFormtoCurrentForm(CaseID,EFormID,CFormID:String);//將舊案的錯誤FormID改正確的FormID
var
@@ -140,10 +139,12 @@
{ ==============================================================================
  方法名稱:SetRecordEditedDocDir
  引用相依:FileExists, LoadFromFile, SaveToFile
  方法描述:記錄案件中曾被異動(新增或刪除)的文件目錄。將目錄名稱存入 EditedDocDir
            .dat,以便後續判斷哪些內容需要同步上傳或重新計算。
  方法名稱 : SetRecordEditedDocDir
  引用相依 : EditedDocDir.dat
  方法描述 : 【記錄異動的文件目錄】
             維護 EditedDocDir.dat 檔案。當文件目錄被新增 (A) 或刪除 (D) 時,
             即時更新此清單,作為後續判斷哪些目錄需重新計算 OMR 或同步至伺服器
             的依據。
============================================================================== }
Procedure TCB_IMGPSScanX.SetRecordEditedDocDir(Mode:Char;CaseID,DocDir:String);  //記錄被異動的文件目錄  'A:加入D:刪掉'
var
reassemble/CB_IMGPSScanImp.docq.pas
@@ -1,7 +1,9 @@
{ ==============================================================================
  方法名稱:GetDataDocNoPage
  引用相依:
  方法描述:從 DOC_INF_List 資料中查詢特定文件與版本的預設頁數設定。
  引用相依:Doc_Inf_List, FindSQLData, GetFindResult
  方法描述:【從規格表獲取文件頁數】
            查詢 DOC_INF_List,根據文件編號與版本號取得系統定義的標準頁數 (FORM_PAGES)。
            若查無資料則回傳 0。
============================================================================== }
Function TCB_IMGPSScanX.GetDataDocNoPage(MainDocNo,MainVersion:String):Integer;  //取記錄的文件_版本頁數
var
@@ -21,10 +23,15 @@
{ ==============================================================================
  方法名稱:CheckCaseDocNoPage
  引用相依:LoadFromFile
  方法描述:計算案件中特定文件與版本的實際頁數。透過讀取 upload 目錄下的 Context.
            dat 與 DocDir.dat,精確比對 FormID、DocNo、版本與頁碼索引,並排除入庫狀
            態影像,回傳符合條件的影像總數。
  引用相依:FileName2FormCode, FormCode2DocNo, FormCode2Page, FormCode2Version,
            ISExistImg, LoadFromFile, LogFile1
  方法描述:【計算案件內特定文件的實體頁數】
            此方法是掃瞄後檢核的核心,用於計算案件目錄下特定文件與版本的實際影像頁數。
            1. 資料載入:讀取 upload 目錄下的 Context.dat 與 DocDir.dat。
            2. 補件過濾:若為補件模式 (FWH_category='N') 且為入庫文件,則跳過已存在的影像。
            3. 分份判定:比對 DocDir.dat,確保統計的是同一份(第一份)文件的頁數。
            4. 內容比對:遍歷影像清單,精確比對版本、DocNo 以及檔名解析出的頁碼序號。
            5. 日誌記錄:過程會詳細記錄至 LogFile1,以便追蹤檢核失敗的原因。
============================================================================== }
Function TCB_IMGPSScanX.CheckCaseDocNoPage(CaseID,DocNo,Version:String;Pages:Integer):Integer; //取案件裡的文件_版本頁數
var
@@ -103,8 +110,10 @@
{ ==============================================================================
  方法名稱:FindFormCodePages
  引用相依:LoadFromFile
  方法描述:計算案件中特定 FormID 的實際影像總數,可用於檢核。
  引用相依:FileName2FormCode, ISExistImg, LoadFromFile
  方法描述:【計算特定 FormID 的實體影像數】
            計算 upload 目錄下屬於指定 FormID 的影像總量。在補件模式下會過濾掉
            歷史已存在的影像,僅統計本次新掃入的頁數。
============================================================================== }
Function TCB_IMGPSScanX.FindFormCodePages(CaseID,FormCode:String):Integer;  //計算案件裡FormID的頁數
var
@@ -140,8 +149,10 @@
{ ==============================================================================
  方法名稱:GetDataFormCodePages
  引用相依:
  方法描述:查詢特定表單 ID 的最大頁數限制,若未設定則回傳 9999。
  引用相依:FORM_INF_List, FindSQLData, GetFindResult
  方法描述:【獲取表單最大頁數限制】
            從 FORM_INF_List 查詢特定表單 ID 的 MAX_PAGE 設定。若資料庫未設定,
            則預設回傳 9999 (代表不限制頁數)。
============================================================================== }
Function TCB_IMGPSScanX.GetDataFormCodePages(FormCode:String):Integer;   //取記錄的FormcID的頁數
begin
@@ -158,7 +169,8 @@
{ ==============================================================================
  方法名稱:GetDocDir_Page
  引用相依:FileExists, LoadFromFile
  方法描述:取得特定文件目錄下的影像總頁數。
  方法描述:【獲取目錄實體頁數】
            直接讀取指定文件目錄下的 Context.dat,統計目前已掃描並記錄的影像總頁數。
============================================================================== }
Function TCB_IMGPSScanX.GetDocDir_Page(CaseID,DocDir:String):Integer;
var
@@ -180,9 +192,10 @@
{ ==============================================================================
  方法名稱:GetDocNoCount
  引用相依:FileExists, LoadFromFile
  方法描述:統計指定案件中某文件編號(DocNo)的總份數。讀取 CaseDocNo.dat 與 CaseDo
            cNo_Copies.dat 並累加匹配項目的份數值。
  引用相依:DocNoDir2DocNo, FileExists, LoadFromFile
  方法描述:【統計文件編號總份數】
            讀取案件的 CaseDocNo.dat 與 CaseDocNo_Copies.dat,統計指定文件編號
            在所有目錄分支(含分份目錄)中的總份數。
============================================================================== }
Function TCB_IMGPSScanX.GetDocNoCount(CaseID,DocNo:String):Integer; //取DocNo數量
var
@@ -218,7 +231,8 @@
{ ==============================================================================
  方法名稱:GetDocDirCopies
  引用相依:FileExists, LoadFromFile
  方法描述:取得特定文件目錄(DocDir)目前的份數設定。
  方法描述:【獲取目錄份數設定】
            從 CaseDocNo_Copies.dat 中讀取與指定目錄索引對應的份數值。
============================================================================== }
Function TCB_IMGPSScanX.GetDocDirCopies(CaseID,DocDir:String):Integer; //取DocDir數量
var
@@ -253,8 +267,9 @@
{ ==============================================================================
  方法名稱:SetDocDirCopies
  引用相依:FileExists, LoadFromFile, SaveToFile
  方法描述:修改並儲存特定文件目錄的份數設定至 CaseDocNo_Copies.dat。
  引用相依 : FileExists, LoadFromFile, SaveToFile
  方法描述 : 【更新目錄份數設定】
             將特定目錄的新份數值寫入 CaseDocNo_Copies.dat 檔案中。
============================================================================== }
Procedure TCB_IMGPSScanX.SetDocDirCopies(CaseID,DocDir:String;NewCopies:Integer); //修改DocDir份數
var
@@ -287,9 +302,10 @@
{ ==============================================================================
  方法名稱:GetDocDirCopies_Rec
  引用相依:
  方法描述:從 FOldCaseInfo 記錄字串中解析並取得特定文件目錄在舊案中的份數。支援
            自定義文件名稱與一般文件編號的匹配。
  引用相依:GetCustomDocName, SplitString
  方法描述:【解析歷史案件份數紀錄】
            從補件掃描傳入的 FOldCaseInfo 紀錄字串中,解析並提取特定文件目錄在
            伺服器端的歷史份數設定。
============================================================================== }
Function TCB_IMGPSScanX.GetDocDirCopies_Rec(Path,CaseID,DocDir:String):Integer; //取記錄裡的DocDir份數
var
@@ -346,10 +362,12 @@
{ ==============================================================================
  方法名稱:GetDocNoEdit
  引用相依:FileExists, LoadFromFile
  方法描述:檢查指定文件是否被異動。程序會載入已編輯目錄清單,並與原始的文件代號/
            名稱清單(FC_DocNoList)進行比對。若文件代號或名稱不在原始清單中,或存在
            於已編輯清單內,則判定該文件已被異動並回傳 "Y"。
  引用相依:DocNoDir2DocNo, FC_DocNoList, FC_DocNameList, FileExists, LoadFromFile
  方法描述:【判定文件異動狀態】
            判斷指定的文件是否已被掃瞄人員異動。
            1. 檢查原始清單:若文件代號不在 FC_DocNoList 中,判定為新增。
            2. 檢查編輯記錄:若文件目錄存在於 EditedDocDir.dat 中,判定為已異動。
            3. 回傳:回傳 "Y" (有異動) 或 "N" (無異動)。
============================================================================== }
Function TCB_IMGPSScanX.GetDocNoEdit(CaseID,DocNo,DocName:String):String; //取出DocNo是否被異動 (Y/N)
var
@@ -394,10 +412,10 @@
{ ==============================================================================
  方法名稱:GetDocNo_Count
  引用相依:LoadFromFile
  方法描述:計算指定文件代號在案件中的份數。若文件不需分組則直接回傳 1。否則,遍歷
            影像清單(Context.dat),根據檔案名稱解析出的頁碼是否為第一頁("01")來累
            計該文件的份數。
  引用相依 : DocnoNeedGroup, FormCode2Page, FileName2FormCode, LoadFromFile
  方法描述 : 【計算案件內指定文件的份數】
             若文件不需分組則回傳 1。否則透過 Context.dat 與 Context_DocNo.dat
             統計檔名解析為第 '01' 頁的影像數量作為份數依據。
============================================================================== }
Function TCB_IMGPSScanX.GetDocNo_Count(Path,DocNo:String):Integer;  //取出文件份數
var
@@ -443,8 +461,8 @@
{ ==============================================================================
  方法名稱:GetDocNo_Page
  引用相依:LoadFromFile
  方法描述:計算指定文件代號在案件中擁有的總影像頁數。遍歷影像對應的文件清單(Cont
            ext_DocNo.dat),統計與傳入代號相符的項目數量。
  方法描述:【計算指定文件代號總頁數】
            遍歷 Context_DocNo.dat,統計符合目標 DocNo 的影像紀錄總數。
============================================================================== }
Function TCB_IMGPSScanX.GetDocNo_Page(Path,DocNo:String):Integer;  //取出文件總頁數
var
@@ -476,10 +494,12 @@
{ ==============================================================================
  方法名稱:FormIDExists
  引用相依:
  方法描述:檢查指定的表單代碼(FormID)是否存在於系統資料庫中。支援日期檢核模式:若
            啟用,則會進一步查詢該表單所屬文件的起迄效期(START_DATE, STOP_DATE),
            並與伺服器當前日期比對,確保表單仍在有效期限內。
  引用相依:FORM_INF_List, Doc_Inf_List, FindSQLData, ServerDate, FormCode2Version
  方法描述:【表單合法性與效期檢核】
            1. 基礎檢查:檢查 FormID 是否存在於 FORM_INF_List 中。
            2. 效期檢核:若 CheckDate 為 True,則進一步查詢該表單所屬文件的
               START_DATE 與 STOP_DATE。
            3. 判定:將伺服器當前日期 (ServerDate) 與效期區間比對,確保表單未過期。
============================================================================== }
Function TCB_IMGPSScanX.FormIDExists(FormCode:String;CheckDate:Boolean;index:Integer):Boolean;  //檢查FormID是否存在
var
@@ -522,8 +542,9 @@
{ ==============================================================================
  方法名稱:Case_DocNoExists
  引用相依:LoadFromFile
  方法描述:檢查指定的文件代號是否存在於特定案件的 Context.dat 影像清單中。
  引用相依:FileName2FormCode, FormCode2DocNo, LoadFromFile
  方法描述:【檢查案件內是否存在某類文件】
            直接掃瞄案件根目錄的 Context.dat,判斷是否有影像歸屬於指定的 DocNo。
============================================================================== }
Function TCB_IMGPSScanX.Case_DocNoExists(CaseID,Docno:String):Boolean; //Docno是否存在案件裡
var
reassemble/CB_IMGPSScanImp.fileOp.pas
@@ -1,9 +1,11 @@
{ ==============================================================================
  方法名稱:ReNameContext
  引用相依:SaveToFile
  方法描述:在指定路徑下執行影像清單的更名同步。遍歷 ContextList,比對舊檔名後更新
            為新檔名,同步更新 Context.dat 及對應的文件編號清單(Context_DocNo.dat
            )。
  方法名稱 : ReNameContext
  引用相依 : ContextList, Context_DocnoList, FileName2FormCode, FormCode2DocNo
  方法描述 : 【影像清單更名同步】
             當實體檔案更名時,同步更新記憶體中的 ContextList 與 Context_DocnoList。
             1. 尋找舊檔名索引。
             2. 更新為新檔名。
             3. 重新解析新檔名對應的 DocNo 並儲存。
============================================================================== }
Procedure TCB_IMGPSScanX.ReNameContext(Path,OldName,NewName:String);
var
@@ -24,10 +26,12 @@
{ ==============================================================================
  方法名稱:DeleteImageFile
  引用相依:DeleteImageFile, FileExists, LoadFromFile, SaveToFile
  方法描述:刪除指定的影像檔案。執行實體刪除後,自動計算文件目錄,並呼叫 SetContext
            List 從 Context 清單中移除對應的影像記錄。
  方法名稱 : DeleteImageFile
  引用相依 : Path2DocDir, SetContextList
  方法描述 : 【刪除單一影像檔案】
             1. 執行實體 DeleteFile。
             2. 自動解析檔案所屬目錄 (Path2DocDir)。
             3. 調用 SetContextList 從索引清單中移除該筆紀錄。
============================================================================== }
Procedure TCB_IMGPSScanX.DeleteImageFile(Path,FileName,CaseID:String); // 刪除檔案  (無法得到DocDir用)
var
@@ -63,12 +67,12 @@
{ ==============================================================================
  方法名稱:DeleteFormCodeFile
  引用相依:DeleteImageFile, FileExists, LoadFromFile, ReSortFileName, SaveToFil
            e
  方法描述:刪除案件中指定 FormID 的所有文件。讀取 Context.dat 並遍歷,若 FormID
            匹配則執行刪除(在 ESCAN 模式下會檢查是否非當次掃瞄以保護舊圖)。刪除後
            執行檔案序號重新排序。
  方法名稱 : DeleteFormCodeFile
  引用相依 : ISExistImg, ReSortFileName, DeleteImageFile
  方法描述 : 【刪除特定表單的所有影像】
             1. 補件保護:在補件模式下,檢查影像是否為歷史既有影像,若是則不允許刪除。
             2. 批次刪除:遍歷清單,將符合 FormID 的檔案逐一呼叫 DeleteImageFile 移除。
             3. 重新排序:刪除後執行 ReSortFileName 確保剩餘檔案序號連續。
============================================================================== }
Procedure TCB_IMGPSScanX.DeleteFormCodeFile(CaseID,DocDir,FormID:String);  //刪除指定FormID文件
var
@@ -127,12 +131,12 @@
{ ==============================================================================
  方法名稱:DeleteDocNoFile
  引用相依:DeleteDocNoFile, FileExists, LoadFromFile, ReSortFileName, SaveToFil
            e
  方法描述:刪除指定的文件編號(DocNo)影像。遍歷 ContextList,比對文件編號後執行實
            體刪除與清單移除(含 Context 與 Context_DocNo)。處理完成後執行檔案重新
            排序並重新載入清單。
  方法名稱 : DeleteDocNoFile
  引用相依 : ContextList, Context_DocnoList, ReSortFileName
  方法描述 : 【刪除特定文件類別的所有影像】
             1. 遍歷刪除:從 ContextList 末尾開始,識別歸屬於目標 DocNo 的影像並實體刪除。
             2. 索引同步:同步移除記憶體清單中的紀錄。
             3. 重排與重載:執行 ReSortFileName 並重新載入 Context 檔案,確保 UI 同步。
============================================================================== }
Function TCB_IMGPSScanX.DeleteDocNoFile(Path,DocNo:String):Boolean;  //刪除指定DocNo文件
var
@@ -162,13 +166,12 @@
{ ==============================================================================
  方法名稱:DeleteDocNoFileForESCAN
  引用相依:DeleteDocNoFile, LoadFromFile, SaveToFile, _DelTree
  方法描述:在補件模式 (ESCAN) 下刪除屬於特定文件類型 (DocNo) 的影像。方法會從索
            引清單 (ContextList) 的末尾開始向前遍歷,識別符合目標文件編號或附件名
            稱的圖檔。若該檔案並非預先存在的(ISExistImg 返回 False),則執行實體刪
            除並從索引清單中移除。若整個文件目錄因此清空,則會進一步移除該目錄並從
            文件清單中刪除紀錄。
  方法名稱 : DeleteDocNoFileForESCAN
  引用相依 : ISExistImg, SetDocNoList, _DelTree
  方法描述 : 【補件模式下的文件刪除】
             1. 條件刪除:遍歷文件目錄,僅刪除「非預先存在(當次掃描)」的實體影像檔。
             2. 目錄清理:若刪除後該目錄已無任何影像,則執行 _DelTree 移除目錄,
                並調用 SetDocNoList 從案件文件清單中註銷該目錄。
============================================================================== }
Function TCB_IMGPSScanX.DeleteDocNoFileForESCAN(Path,DocNo:String):Boolean;  //刪除指定DocNo文件
var
@@ -206,9 +209,11 @@
{ ==============================================================================
  方法名稱:DeleteShowFile
  引用相依:DeleteShowFile
  方法描述:刪除當前顯示清單(NowShowFileList)中的影像檔案並更新索引。
  方法名稱 : DeleteShowFile
  引用相依 : NowShowFileList, SetContextList
  方法描述 : 【刪除目前預覽中的影像】
             遍歷 NowShowFileList 中當前顯示的所有影像,執行實體刪除並透過
             SetContextList 同步更新案件索引檔案。
============================================================================== }
Procedure TCB_IMGPSScanX.DeleteShowFile(Path:String); //刪除顯示中的影像
var
@@ -244,11 +249,13 @@
{ ==============================================================================
  方法名稱:ReSortFileName
  引用相依:FileExists, LoadFromFile, ReSortFileName, RenameFile, SaveToFile
  方法描述:執行影像檔案名稱的重新排序與更名。讀取目錄下的 Context.dat,根據目前的
            排列順序為每個檔案產生新的三位數序號前綴,並呼叫 ReNameFile 執行磁碟
            更名,最後同步更新清單內容並儲存。
  方法名稱 : ReSortFileName
  引用相依 : Add_Zoo, FileName2NoQuene_Filename, ReNameFile, Context.dat
  方法描述 : 【影像檔案序號重排(順向)】
             當目錄內有影像插入或刪除時,重新整理檔名的三位數序號前綴。
             1. 遍歷:依據 Context.dat 既有順序讀取檔名。
             2. 產名:使用 FileName2NoQuene_Filename 去除舊序號,並加上依序遞增的新序號。
             3. 更名:執行實體 ReNameFile 並將新檔名存回 Context.dat 確保結構完整。
============================================================================== }
Procedure TCB_IMGPSScanX.ReSortFileName(Path:String); //檔名重新排序
var
@@ -280,10 +287,11 @@
{ ==============================================================================
  方法名稱:ReSortFileName_New
  引用相依:FileExists, LoadFromFile, ReSortFileName, RenameFile, SaveToFile
  方法描述:與 ReSortFileName 類似,執行影像檔案名稱的重新排序,但採用從清單末尾向
            前遍歷的方式執行更名與儲存。
  方法名稱 : ReSortFileName_New
  引用相依 : Add_Zoo, FileName2NoQuene_Filename, ReNameFile, Context.dat
  方法描述 : 【影像檔案序號重排(逆向)】
             採逆向遍歷(從最後一頁向前處理)的方式執行檔名序號重整,主要用於特定
             插入邏輯下避免更名衝突。
============================================================================== }
Procedure TCB_IMGPSScanX.ReSortFileName_New(Path:String); //檔名重新排序
var
@@ -314,10 +322,11 @@
{ ==============================================================================
  方法名稱:ReSortFileName2Scanlist
  引用相依:FileExists, LoadFromFile, ReSortFileName, RenameFile, SaveToFile
  方法描述:針對 scanlist.dat 檔案內的影像路徑進行序號重排。讀取清單後,依序為檔案
            名稱加上新的序號前綴並存回。
  方法名稱 : ReSortFileName2Scanlist
  引用相依 : Add_Zoo, FileName2NoQuene_Filename, scanlist.dat
  方法描述 : 【上傳清單序號重排】
             針對即將上傳的 scanlist.dat 檔案內容,重新計算並套用檔名序號,
             確保伺服器端接收到的影像順序符合本地最終編排。
============================================================================== }
Procedure TCB_IMGPSScanX.ReSortFileName2Scanlist(Path:String); //檔名重新排序給Scanlist.dat
var
reassemble/CB_IMGPSScanImp.inbound.pas
@@ -1,7 +1,8 @@
{ ==============================================================================
  方法名稱:GetDocNo_IS_WH
  引用相依:
  方法描述:判斷指定文件編號是否屬於「入庫文件」類別。
  方法名稱 : GetDocNo_IS_WH
  引用相依 : IN_WH_DocNoList
  方法描述 : 【判定文件編號是否入庫】
             在 IN_WH_DocNoList 清單中搜尋,判斷該文件編號是否具備入庫屬性。
============================================================================== }
Function TCB_IMGPSScanX.GetDocNo_IS_WH(DocNo:String):Boolean; //DocNo是否為入庫文件
var
@@ -20,9 +21,11 @@
{ ==============================================================================
  方法名稱:DocNoIs_In_WH
  引用相依:
  方法描述:判斷指定文件編號(包含自定義 ZZZZZ 系列)是否為入庫文件。
  方法名稱 : DocNoIs_In_WH
  引用相依 : IN_WH_DocNoList
  方法描述 : 【判定文件是否為入庫類別(含自定義)】
             1. 自定義判定:若文件代號以 'ZZZZZ' 開頭,依業務規則一律判定為入庫文件。
             2. 清單比對:若非自定義,則在 IN_WH_DocNoList 中進行全文檢索判定。
============================================================================== }
Function TCB_IMGPSScanX.DocNoIs_In_WH(DocNo:String):Boolean; //DocNo是否為入庫文件
var
@@ -46,10 +49,14 @@
{ ==============================================================================
  方法名稱:FormIDAppear
  引用相依:
  方法描述:判斷特定的表單代碼(FormID)是否符合目前入庫/非入庫作業模式的顯示規則。
            主要過濾掉不屬於當前作業範疇的文件。
  方法名稱 : FormIDAppear
  引用相依 : DocNoIs_In_WH, FIs_In_Wh, FWH_category
  方法描述 : 【表單顯示過濾器】
             判定目前的表單代碼是否符合當前的掃瞄模式。
             1. 入庫模式 (FIs_In_Wh='Y'):原則上僅顯示入庫類文件。
             2. 非入庫模式 (FIs_In_Wh='N'):原則上僅顯示非入庫類文件。
             3. 補件模式:若 FWH_category 為 'N',採放寬模式顯示。
             4. 互斥排除:自動排除附件與特定非相關分類。
============================================================================== }
Function TCB_IMGPSScanX.FormIDAppear(FormID:String):Boolean; //FormID是否可出現
var
@@ -79,10 +86,13 @@
{ ==============================================================================
  方法名稱:DocNoAppear
  引用相依:
  方法描述:判斷文件編號(DocNo)是否應在介面上顯示。包含針對附件與入庫屬性的互斥過
            濾。
  方法名稱 : DocNoAppear
  引用相依 : DocNoIs_In_WH, FIs_In_Wh
  方法描述 : 【文件代號顯示過濾器】
             判定指定的文件編號是否應於目前 UI 視窗中顯示。
             1. 入庫過濾:過濾掉不屬於入庫模式的非入庫件或 SmartLending 附件。
             2. 非入庫過濾:過濾掉入庫件或一般附件。
             3. 模式相容:若 FIs_In_Wh 為空,則不進行互斥過濾。
============================================================================== }
Function TCB_IMGPSScanX.DocNoAppear(DocNo:String):Boolean;   //DocNo是否可出現
begin
@@ -103,9 +113,11 @@
{ ==============================================================================
  方法名稱:ISGuideFormID
  引用相依:
  方法描述:檢查指定的表單代碼是否屬於「引導頁(Guide Page)」清單。
  方法名稱 : ISGuideFormID
  引用相依 : GuideFormIDList
  方法描述 : 【判定是否為引導頁表單】
             檢查 FormID 是否存在於 GuideFormIDList 中。引導頁在掃瞄時通常代表
             一組文件的開始或具備特定的分類意義。
============================================================================== }
Function TCB_IMGPSScanX.ISGuideFormID(FormID:String):Boolean;
var
@@ -124,9 +136,11 @@
{ ==============================================================================
  方法名稱:ISDivPageFormID
  引用相依:
  方法描述:檢查指定的表單代碼是否屬於「分案頁(Division Page)」清單。
  方法名稱 : ISDivPageFormID
  引用相依 : DivPageFormIDList
  方法描述 : 【判定是否為分案頁表單】
             檢查 FormID 是否存在於 DivPageFormIDList 中。分案頁在掃瞄流程中
             負責觸發自動案件切分與重新編號。
============================================================================== }
Function TCB_IMGPSScanX.ISDivPageFormID(FormID:String):Boolean;
var
reassemble/CB_IMGPSScanImp.lfcycle.pas
@@ -80,12 +80,14 @@
{ ==============================================================================
  方法名稱:DestroyEvent
  引用相依:_DelTree
  方法描述:銷毀元件時的清理工作。負責釋放大量的 TStringList 物件,包含各類資訊清
            單(表單、規則、註記、工作、影像路徑、條碼等)。針對特定模式(DSCAN/ESCAN),若
             ImagePath 不為空則刪除該目錄及其子目錄。最後觸發 COM 介面的 OnDestro
            y 事件。
  方法名稱 : DestroyEvent
  引用相依 : _DelTree
  方法描述 : 【元件銷毀與資源釋放】
             這是控制項卸載時的關鍵清理程序。
             1. 內存釋放:逐一釋放數十個 TStringList 清單物件,避免記憶體洩漏。
             2. 暫存清理:針對重掃 (DSCAN) 與補件 (ESCAN) 模式,自動刪除本地的
                ImagePath 暫存目錄。
             3. 事件通知:觸發 COM 介面的 OnDestroy,通知容器元件已移除。
============================================================================== }
procedure TCB_IMGPSScanX.DestroyEvent(Sender: TObject);
begin
@@ -183,11 +185,13 @@
{ ==============================================================================
  方法名稱:ActiveFormCreate
  引用相依:
  方法描述:ActiveForm 建立時的初始化處理。發送啟動訊息、設定預設檢視模式並初始化
            影像顯示區域。遍歷所有影像捲軸盒(ISB),設定預設滑鼠模式為 mmUser 並將
            縮放模式設為全頁顯示,最後延遲啟動 Timer。
  方法名稱 : ActiveFormCreate
  引用相依 : TImageScrollBox, Timer1
  方法描述 : 【ActiveForm 初始化啟動】
             在控制項建立後執行初步 UI 配置。
             1. 元件校正:遍歷 8 個影像顯示容器,重置其滑鼠模式與縮放倍率。
             2. 非同步啟動:開啟 Timer1 執行後續耗時的伺服器資料同步作業,
                以確保 UI 不會因網路請求而產生長時間凍結。
============================================================================== }
procedure TCB_IMGPSScanX.ActiveFormCreate(Sender: TObject);
var IScrollBox : TImageScrollBox;
@@ -224,11 +228,14 @@
{ ==============================================================================
  方法名稱:InitialLanguage
  引用相依:
  方法描述:元件多國語言初始化核心函式。讀取 Language.Lng 設定檔,根據指定的語系遞
            迴設定畫面上所有控制項(按鈕、選單、標籤、清單、群組框等)的 Caption 或 Hi
            nt 文字,實現介面語系動態切換。
  方法名稱 : InitialLanguage
  引用相依 : TMeminifile, LngPath
  方法描述 : 【介面語言動態載入】
             根據全域變數 FLanguage 讀取 Language.Lng 設定檔。
             1. 遍歷元件:使用 RTTI 遍歷畫面上所有的 Button, Label, MenuItem,
                ListView 等控制項。
             2. 標籤映射:依據「表單名.控制項名」從 INI 讀取對應語系字串。
             3. 介面更新:即時套用至 Caption 或 Hint,實現無縫的多國語言切換。
============================================================================== }
procedure TCB_IMGPSScanX.InitialLanguage(Sender: TObject);
var
@@ -310,13 +317,16 @@
{ ==============================================================================
  方法名稱:Timer1Timer
  引用相依:FJpgCompression, FileExists, GetLocalAppDir, Str2Dir, _DelTree, init
            kscan
  方法描述:OCX 元件初始化的核心程序。負責從伺服器下載各類基礎資訊(業務、表單、文件
            、檢核規則、常用片語、系統參數等),並設定本地暫存路徑(ScanTemp)。針對異動
            或重掃模式,會自動建立空案件並下載既有影像。最後執行各類屬性與語系設定
            ,確保掃描環境就緒。
  方法名稱 : Timer1Timer
  引用相依 : API 系列 (GetSetInf), ImagePath, InitialLanguage, LoadImgFile
  方法描述 : 【系統啟動與環境同步核心邏輯】
             這是 OCX 載入後最重要的初始化階段。
             1. 模式判定:根據 FMode 開關特定的 UI 功能按鈕(如補件、傳送)。
             2. 規格下載:調用 api.pas 的系列方法獲取最新的表單、規則與全域參數。
             3. 暫存路徑建立:根據單位、模式動態產生實體磁碟目錄 (Scantemp)。
             4. 業務初始化:若為異動/重掃模式,執行既有影像下載 (DownLoadImage)
                與目錄預建。
             5. 載入影像:完成所有規格同步後,正式執行 LoadImgFile 呈現案件內容。
============================================================================== }
procedure TCB_IMGPSScanX.Timer1Timer(Sender: TObject);
var
reassemble/CB_IMGPSScanImp.listMgr.pas
@@ -1,7 +1,9 @@
{ ==============================================================================
  方法名稱:SetFormID_DocNo
  引用相依:
  方法描述:提取 FORM_INF_List 中的 FormID 與 DocNo 欄位至獨立清單。
  方法名稱 : SetFormID_DocNo
  引用相依 : FORM_INF_List, FormID_List, DocNo_List
  方法描述 : 【提取表單與文件編號映射表】
             為了加速後續的轉換查找,從原始的 FORM_INF_List 中提取 T1.FORM_ID
             與 T1.DOC_NO 欄位,並分別填充至全域的 FormID_List 與 DocNo_List 中。
============================================================================== }
Procedure TCB_IMGPSScanX.SetFormID_DocNo; //將FormID及Docno抽出來另存入list裡    20130403增加
var
@@ -17,9 +19,11 @@
{ ==============================================================================
  方法名稱:SetIn_WH_DocNo
  引用相依:
  方法描述:提取所有入庫屬性(IS_IN_WH)為 'Y' 的文件編號至清單。
  方法名稱 : SetIn_WH_DocNo
  引用相依 : Doc_Inf_List, IN_WH_DocNoList
  方法描述 : 【提取入庫文件類別清單】
             從 Doc_Inf_List 掃描所有定義的文件,若 IS_IN_WH 欄位標記為 'Y',
             則將該文件編號存入 IN_WH_DocNoList,作為影像顯示過濾與入庫判定的依據。
============================================================================== }
Procedure TCB_IMGPSScanX.SetIn_WH_DocNo; //將要入庫的DocNo抽出來另存入list裡
var
reassemble/CB_IMGPSScanImp.misc.pas
@@ -1,10 +1,11 @@
{ ==============================================================================
  方法名稱:GetCurrentVersionNo
  引用相依:
  方法描述:獲取當前模組的版本號。透過 GetModuleFileName 獲取檔案路徑,再利用 GetF
            ileVersionInfoSize 和 GetFileVersionInfo 讀取版本資訊。接著從 VarFile
            Info\Translation 取得語系資訊,最後從 StringFileInfo 中提取 FileVersi
            on 並回傳為字串。
  引用相依:Windows Version API (GetFileVersionInfo)
  方法描述:【獲取元件實體版本號】
            1. 獲取路徑:透過 GetModuleFileName 取得目前執行檔 (OCX) 的實體路徑。
            2. 讀取資源:利用 GetFileVersionInfo 載入資源區段中的版本資訊塊。
            3. 解析語系:從 Translation 取得多國語言編碼映射。
            4. 提取字串:從 StringFileInfo 提取 FileVersion 欄位,回傳標準版本字串。
============================================================================== }
function TCB_IMGPSScanX.GetCurrentVersionNo: String; //獲取自身版本號所需要
var
@@ -43,11 +44,12 @@
{ ==============================================================================
  方法名稱:WMMOUSEWHEEL
  引用相依:
  方法描述:處理滑鼠滾輪事件。根據滾輪捲動方向(WHEEL_DELTA)對 ScrollBox1 或當前顯
            示的影像捲軸盒(DisplayISB)進行垂直捲動(SB_Lineup 或 SB_LINEDOWN)。若
            同時按下特定鍵(message.Keys=50),則會調整影像的縮放百分比(ZoomPercent
            )。此外也會遍歷所有影像捲軸盒元件並對取得焦點的元件執行捲動操作。
  引用相依:ScrollBox1, DisplayISB, zmPercent
  方法描述:【全域滑鼠滾輪事件處理】
            處理整個 ActiveForm 的滾輪邏輯:
            1. 捲動邏輯:若 ScrollBox1 或影像盒取得焦點,執行垂直捲動。
            2. 縮放邏輯:偵測到 message.Keys=50 (組合鍵) 時,將影像盒切換至百分比
               縮放模式 (zmPercent),並以 10% 為級距進行即時縮放。
============================================================================== }
procedure TCB_IMGPSScanX.WMMOUSEWHEEL(var message: TWMMouseWheel);
var
@@ -138,10 +140,13 @@
{ ==============================================================================
  方法名稱:InitExistImgList
  引用相依:LoadFileGetMD5, LoadFromFile
  方法描述:初始化已存在的影像清單。讀取案件路徑下 Download\Context.dat 的檔案內
            容,計算每個檔案的 MD5 雜湊值並存入 ExistImgList,同時將處理過程記錄至
            日誌檔。
  引用相依:LoadFileGetMD5, ExistImgList, LogFile1
  方法描述:【初始化歷史影像 MD5 清單】
            在補件或異動模式下,掃描 Download 目錄。
            1. 遍歷:讀取 Context.dat 檔案。
            2. 計算:對每個檔案呼叫 LoadFileGetMD5 計算指紋。
            3. 記錄:將 MD5 存入 ExistImgList 並同步寫入日誌,用於後續判定哪些
               影像是「舊有的」以實施保護邏輯。
============================================================================== }
procedure TCB_IMGPSScanX.InitExistImgList(casepath: String);
var
reassemble/CB_IMGPSScanImp.omr.pas
@@ -1,8 +1,14 @@
{ ==============================================================================
  方法名稱:GetSiteOMR
  引用相依:ClearLine, FindPoint, GetSiteOMR, Get_OMR, LoadFromFile
  方法描述:在影像指定座標執行 OMR 辨識。載入影像、計算相對於定位點的座標偏移、限制
            邊界並呼叫核心辨識程式獲取結果。
  引用相依:CM_Str2Rect, Get_OMR, ISB_BW, UpLPoint, ClearLine
  方法描述:【指定區域 OMR 辨識】
            在影像的特定座標區域執行填塗辨識。
            1. 影像準備:若傳入檔名與目前載入不同,則重新載入影像。
            2. 預處理:呼叫 ClearLine 移除表格橫線,避免干擾辨識,並強制重繪。
            3. 座標轉換:利用 CM_Str2Rect 將 XML 定義的相對座標(毫米或像素)結合
               影像 DPI 與定位基準點 (UpLPoint) 轉換為實體 Rect。
            4. 邊界校正:執行邊界檢查,確保 Rect 不超出影像實體寬高。
            5. 辨識執行:呼叫核心 Get_OMR 演算法計算填塗黑點比例,回傳辨識結果。
============================================================================== }
function TCB_IMGPSScanX.GetSiteOMR(FileName,Site:String;bt: Integer): Integer;
var
@@ -62,10 +68,13 @@
{ ==============================================================================
  方法名稱:CheckRule2OMRErrInfo
  引用相依:
  方法描述:將檢核規則清單(CHECK_RULE_INF_List)中的資料轉換為內部的 OMRErrInfo R
            ecord 陣列,設定各項規則的顯示類型(Display)、是否可忽略(Ignore)及提示
            訊息與掃瞄模式。
  引用相依:CHECK_RULE_INF_List, OMRErrInfo
  方法描述:【檢核規則元數據映射】
            將從伺服器取得的 SQL 檢核規則(共 11 項)轉換為內部的 Record 結構。
            1. 狀態映射:將 MESG_SHOW_TYPE (1:顯示, 2:隱藏) 轉為布林值。
            2. 權限映射:將 MESG_DISP_TYPE (1:可忽略, 2:強制的) 轉為 Ignore 標記。
            3. 內容填充:填入錯誤提示字串與該規則適用的掃瞄模式 (Mode)。
            此方法確保前端 UI 與檢核引擎能依據伺服器下達的最新政策執行驗證。
============================================================================== }
Procedure TCB_IMGPSScanX.CheckRule2OMRErrInfo;   //檢核規則填入OMRErrINFo Record
var i : Integer;
@@ -98,11 +107,13 @@
{ ==============================================================================
  方法名稱:DistinctFormCode
  引用相依:LoadFileGetMD5, LoadFromFile
  方法描述:從案件的 Context.dat 檔案中提取不重複的表單代碼(FormCode)並存入 OMRF
            ileList。程序會遍歷上傳目錄下的所有檔案,檢查檔案是否存在且未被處理過。
            接著比對 OMRFileList 中已有的表單代碼,若為新出現的表單代碼且檔案有效
            ,則將其加入清單中,用於後續 OMR 處理。
  引用相依:reSizeExistImgList, ISExistImg, Context.dat
  方法描述:【提取待檢核表單清單】
            從案件中篩選出不重複且需執行 OMR 的表單代碼。
            1. 補件過濾:在補件模式 (FWH_category='N') 下,透過實體檔案存在性與
               MD5 排除清單 (reSizeExistImgList) 自動跳過歷史影像。
            2. 去重邏輯:針對新掃入的影像,僅提取每種表單 ID 的第一頁 (Index 0),
               避免對多頁重複執行相同的表單級檢核。
============================================================================== }
Procedure TCB_IMGPSScanX.DistinctFormCode(CaseID:String); //從案件裡的FormCode取出第一頁
var
@@ -153,20 +164,19 @@
{ ==============================================================================
  方法名稱:OMRCheckCase
  引用相依:FileExists, FindPoint, GetSiteOMR, ImageReSize_FormID, ImageResize,
            LoadFromFile, SaveToFile
  方法描述:執行案件的自動化 OMR 規則檢核,這是確保掃瞄案件合規性的核心邏輯。程序
            流程:
            1. 初始化檢核日誌。
            2. 識別主文件並驗證必要文件是否缺漏、相依與互斥文件是否衝突、以及表單
            是否已停用。
            3. 檢查各文件類型是否超過預設的最大頁數。
            4. 針對案件內每張影像,執行十字定位點縮放 (ImageReSize_FormID) 後,載
            入對應表單的 XML 規則檔。
            5. 執行欄位級檢核,包含必填項 (settype1)、跨文件欄位關聯 (settype3/set
            type8)、相依文件需求 (settype4) 及備註填寫要求 (settype6) 等。
            6. 將所有檢核失敗原因紀錄至 Checkerr.ini。最終返回案件是否通過所有檢
            核規則。
  引用相依:XML 規則檔, ImageReSize_FormID, OMRErr2ini, 檢核子系統
  方法描述:【案件自動化合規性總檢核】
            此為系統最核心的檢核引擎,負責串接所有驗證邏輯:
            1. 檔案層級檢核:驗證主文件是否存在、頁數是否符合規格 (GetDataDocNoPage)、
               檢查相依文件需求與互斥文件衝突。
            2. 版本與效期:檢查是否有已停用 (STOP_DATE) 或未註冊的表單 ID。
            3. 表單級 OMR:
               - 定位校正:對每張影像執行十字定位縮放 (ImageReSize_FormID)。
               - 載入 XML:依據 FormID 載入對應的欄位座標與辨識規則。
               - 欄位辨識:執行必填、跨文件關聯、相依文件欄位、及備註填寫要求等檢核。
            4. 結果輸出:將所有失敗原因即時寫入 Checkerr.ini (UI 顯示) 或
               CheckMemo.dat (背景日誌)。
            回傳案件是否通過所有「強制性」檢核項。
============================================================================== }
Function TCB_IMGPSScanX.OMRCheckCase(CaseID:String):Boolean; //OMR檢核
var
@@ -867,12 +877,12 @@
{ ==============================================================================
  方法名稱:OMRErr2ini
  引用相依:FileExists, LoadFromFile, SaveToFile
  方法描述:紀錄 OMR 檢核失敗的詳細資訊。方法根據 Display 旗標決定紀錄方式:若為 T
            rue,則在案件目錄下的 Checkerr.ini 中建立新的錯誤序號區段,詳細紀錄失
            敗原因、檔案路徑、OMR 座標點、關聯檔案及定位點類型,用於後續 UI 呈現;若
            為 False,則僅將錯誤原因字串附加於 CheckMemo.dat 純文字日誌中,作為背
            景紀錄之用。
  引用相依:Checkerr.ini, CheckMemo.dat
  方法描述:【檢核錯誤持久化】
            將檢核失敗詳細資訊存檔。
            - UI 模式 (Display=True):在 Checkerr.ini 建立錯誤區段,記錄錯誤原因、
              影像路徑、座標、關聯影像與定位點類型,供 ErrList 視窗點選定位。
            - 靜默模式:將原因字串附加至 CheckMemo.dat,用於傳送案件時的背景描述。
============================================================================== }
Procedure TCB_IMGPSScanX.OMRErr2ini(CaseID,Reason,FileName,Site,RelaFileName,RelaSite,Anchor,Anchor1:String;Del,Ingnore,Display:Boolean); //OMR檢核失敗寫入ini
var
@@ -917,11 +927,10 @@
{ ==============================================================================
  方法名稱:OMRErrini2List
  引用相依:
  方法描述:將檢核失敗紀錄從 INI 設定檔載入至 UI 介面。方法會讀取 Checkerr.ini,遍
            歷所有錯誤紀錄,並過濾掉已標記為刪除 (Del) 的項目。將符合條件的錯誤原
            因填入 ErrlistForm 中的 ListView 元件,供使用者查看與修正。若清單中仍
            存在錯誤,會同步停用介面上的上傳按鈕以防止不合規案件送出。
  引用相依:Checkerr.ini, ErrlistForm
  方法描述:【加載錯誤紀錄至 UI】
            讀取 Checkerr.ini,過濾已刪除項,將錯誤原因填入 ErrlistForm 的 ListView。
            若存在錯誤,則同步停用「立即上傳」按鈕以實施業務擋控。
============================================================================== }
Procedure TCB_IMGPSScanX.OMRErrini2List(CaseID:String;ErrlistForm:TErrlistForm); //OMR檢核失敗從ini寫入ListView
var
@@ -995,11 +1004,10 @@
{ ==============================================================================
  方法名稱:OMRErrini2ListForLog
  引用相依:LoadFromFile
  方法描述:彙整系統中所有活動案件的 OMR 檢核錯誤訊息。方法讀取全域的 CaseList.da
            t,依次遍歷每個案件子目錄下的 Checkerr.ini,收集所有未被移除的錯誤原因
            ,並將其合併為一個完整的文字區塊返回。此功能主要用於產生系統運行日誌,
            方便追蹤與審查多案件的檢核狀態。
  引用相依:CaseList.dat, Checkerr.ini
  方法描述:【彙整所有待傳案件錯誤日誌】
            遍歷本地 CaseList.dat 所有活動案件,讀取其 Checkerr.ini 彙整所有
            未修正的錯誤原因,產出完整的文字報告供日誌記錄使用。
============================================================================== }
function TCB_IMGPSScanX.OMRErrini2ListForLog(CaseID: String): String;
var
reassemble/CB_IMGPSScanImp.prUpload.pas
@@ -1,8 +1,12 @@
{ ==============================================================================
  方法名稱:CreateCaseNeedData
  引用相依:FileExists, LoadFromFile, SaveToFile
  方法描述:掃描案件目錄下的 Context.dat 影像清單,自動推導並產生該案件所需的 Doc
            Dir.dat、CaseDocNo.dat 及份數清單,用於修復或重建案件結構。
  引用相依:Context.dat, DocDir.dat, CaseDocNo.dat
  方法描述:【重建案件元數據檔案】
            當案件描述檔損毀或缺失時(常見於直接截圖或外部匯入),執行自我修復。
            1. 遍歷影像:讀取實體 Context.dat。
            2. 推導 DocNo:透過檔名反查對應的文件編號。
            3. 生成清單:自動重建 DocDir.dat (對應目錄)、CaseDocNo.dat (目錄清單)
               與 CaseDocNo_Copies.dat (預設 1 份)。
============================================================================== }
Procedure  TCB_IMGPSScanX.CreateCaseNeedData(Path:String);
var
@@ -53,10 +57,17 @@
{ ==============================================================================
  方法名稱:Case2upload
  引用相依:CopyFile, DirectoryExists, FileExists, LoadFromFile, SaveToFile, Str
            2Dir, _DelTree
  方法描述:準備案件上傳用的資料夾結構。將分散在各文件子目錄下的影像檔案複製到單
            一的 Upload 目錄下並重新編號檔名,同時產生彙整後的索引檔與附件。
  引用相依:_DelTree, CopyFile, FileName2NoQuene_Filename
  方法描述:【案件上傳封裝(打平結構)】
            將本機的階層式文件目錄扁平化,準備上傳至伺服器。
            1. 清理:刪除舊的 Upload 暫存目錄。
            2. 同步配置:將案件層級的 INI/DAT 設定檔複製至 Upload 根目錄。
            3. 影像遷移:
               - 遍歷所有文件子目錄。
               - 將影像檔案重新編號(全案唯一流水號)。
               - 實體複製至 Upload 資料夾。
            4. 索引重製:同步產生彙總後的 Context.dat、Context_DocNo.dat
               與 DocDir.dat,確保伺服器接收後能還原結構。
============================================================================== }
Procedure TCB_IMGPSScanX.Case2upload(CaseID:String);
var
@@ -187,9 +198,14 @@
{ ==============================================================================
  方法名稱:Download2Case
  引用相依:CopyFile, DirectoryExists, FileExists, LoadFromFile, SaveToFile
  方法描述:將下載或匯入的案件結構還原回本系統的多層級目錄結構。包含建立文件子目
            錄、檔案複製並重新編號、以及重建各類索引與份數設定檔。
  引用相依:CreateCaseNeedData, CopyFile, ReSortFileName, InitExistImgList
  方法描述:【下載案件解構(還原層級)】
            將從伺服器下載的扁平化 ZIP 包還原為本地階層式目錄。
            1. 結構修復:若描述檔缺失,先呼叫 CreateCaseNeedData 補全。
            2. 目錄重建:依據 CaseDocNo.dat 建立各類文件子資料夾。
            3. 檔案歸位:依據 DocDir.dat 指示,將 Upload 中的影像分配回對應目錄,
               並調用 ReSortFileName 重新整理子目錄序號。
            4. 狀態更新:在補件模式下,呼叫 InitExistImgList 計算歷史影像 MD5。
============================================================================== }
Procedure TCB_IMGPSScanX.Download2Case(SoDir,DeDir:String);
var
@@ -366,10 +382,11 @@
{ ==============================================================================
  方法名稱:GetCaseFormID
  引用相依:LoadFromFile
  方法描述:從案件目錄的 Context.dat 檔案中搜尋並回傳該案件的主表單代碼(FormID)。
            程序會遍歷影像清單,提取各檔案的表單代碼,並排除特定的分案頁代碼,直到
            找到符合條件的主表單代碼為止。
  引用相依:DivPageFormIDList, FindDivFormCode, LoadFromFile
  方法描述:【偵測案件主表單代碼】
            遍歷影像清單,尋找定義為「主表單」的 FormID。
            1. 過濾:自動跳過分案頁 (Division Page) 與非主鍵表單。
            2. 識別:回傳第一個符合條件的實體表單 ID 作為案件的主索引。
============================================================================== }
Function TCB_IMGPSScanX.GetCaseFormID(Path:String):String;  //取案件的主FormID
var i,n : Integer;
@@ -396,9 +413,10 @@
{ ==============================================================================
  方法名稱:CreateFormID_FormName
  引用相依:SaveToFile
  方法描述:遍歷 ContextList,提取每個檔案的表單代號與名稱並格式化為「代號_名稱」,
            最後存成 FormCode_Name.dat 供上傳使用。
  引用相依:FormCode2FormName, SaveToFile
  方法描述:【生成表單代碼與名稱對照表】
            遍歷 ContextList,將每個影像的表單代號與人類可讀名稱格式化為
            「FormID_FormName」並存入 FormCode_Name.dat,供後端顯示參考。
============================================================================== }
Procedure TCB_IMGPSScanX.CreateFormID_FormName(Path,CaseID:String);  //產生FormID_FormName.dat
var i : Integer;
@@ -423,10 +441,11 @@
{ ==============================================================================
  方法名稱:CreateDocNo_DocName
  引用相依:SaveToFile
  方法描述:產生包含文件代號與名稱的對應檔 DocNo_Name.dat。首先執行案件內文件去重
            ,接著遍歷 CaseDocNoList 取得對應名稱,針對不需分組的文件會在名稱前加
            上星號標記,最後將結果以 UTF-8 編碼儲存。
  引用相依:DistinctDocNoinCase, DocNo2DocName, SaveToFile
  方法描述:【生成文件代號與名稱對照表】
            1. 去重:呼叫 DistinctDocNoinCase 取得案件內實際存在的文件編號。
            2. 格式化:對應名稱,若不需分組則加上星號標記(如 *101_名稱)。
            3. 持久化:存入 DocNo_Name.dat 並強制使用 UTF-8 編碼。
============================================================================== }
Procedure TCB_IMGPSScanX.CreateDocNo_DocName(Path,CaseID:String);  //產生DocNo_DocName.dat
var
@@ -453,10 +472,10 @@
{ ==============================================================================
  方法名稱:CreateIn_WH
  引用相依:FileExists, LoadFromFile, SaveToFile
  方法描述:產生在席文件清單檔 In_Wh.dat。讀取案件的文件目錄清單後,比對全域的在席
            文件清單(IN_WH_DocNoList),若文件代號匹配或屬於特定系統目錄(ZZZZZ),則
            將其加入清單並儲存,用於標記需留存實體的文件。
  引用相依:IN_WH_DocNoList, DocNoDir2DocNo, SaveToFile
  方法描述:【生成在席入庫清單】
            識別案件中哪些目錄屬於實體入庫類別(包含 ZZZZZ 自定義件)。
            將這些目錄名稱寫入 In_Wh.dat,供上傳後後端系統進行入庫追蹤。
============================================================================== }
Procedure TCB_IMGPSScanX.CreateIn_WH(CaseID:String);  //產生In_WH.dat
var
@@ -492,11 +511,12 @@
{ ==============================================================================
  方法名稱:CreateDocNo_Info
  引用相依:FileExists, LoadFromFile
  方法描述:產生案件內標準文件(非自訂)的彙總資訊字串。方法讀取 CaseDocNo.dat,針對
            每個非 'ZZZZZ' 開頭的文件編號,計算其在案件中的總份數、累計總頁數,並檢
            查編輯狀態(異動旗標)。結果以「編號[Tab]份數[Tab]頁數[Tab]狀態」的格式逐
            行組成,作為案件上傳時與伺服器比對資料完整性的核心依據。
  引用相依:DocNoDir2DocNo, GetDocNoCount, GetDocDir_Page, GetDocNoEdit
  方法描述:【生成標準文件彙總資訊】
            統計案件中非自訂文件的元數據。
            - 欄位:DocNo[Tab]份數[Tab]總頁數[Tab]異動狀態 (Y/N)。
            - 行:每個 DocNo 一行。
            此字串將作為 Java Servlet 的參數傳輸。
============================================================================== }
Function TCB_IMGPSScanX.CreateDocNo_Info(CaseID:String):String; //產生 DocNo[tab]份數[tab]總頁數[tab]是否異動[換行]DocNo[tab]份數[tab]總頁數[tab]是否異動
var
@@ -585,11 +605,10 @@
{ ==============================================================================
  方法名稱:CreateCustDocNo_Info
  引用相依:FileExists, LoadFromFile
  方法描述:產生案件內自訂文件的彙總資訊字串。方法專門處理代碼開頭為 'ZZZZZ' 的文
            件目錄,透過 GetCustomDocName 取得使用者定義的文件名稱,並彙整其總份數
            、總頁數與編輯異動狀態。最終格式與標準文件一致,但首位欄位改為顯示自訂
            名稱,確保自訂類別的文件也能正確被伺服器識別與儲存。
  引用相依:GetCustomDocName, GetDocNoCount, GetDocDir_Page, GetDocNoEdit
  方法描述:【生成自訂文件彙總資訊】
            專門針對 'ZZZZZ' 開頭的目錄,提取使用者定義的文件名稱並彙整其
            份數、頁數與異動狀態。
============================================================================== }
Function TCB_IMGPSScanX.CreateCustDocNo_Info(CaseID:String):String; //產生自訂文件 DocName[tab]份數[tab]總頁數[tab]是否異動[#13#10]DocName[tab]份數[tab]總頁數[tab]是否異動
var
@@ -647,10 +666,10 @@
{ ==============================================================================
  方法名稱:CreateDocnoFrom_Info
  引用相依:FileExists, LoadFromFile
  方法描述:產生被引進的保管袋文件詳細資訊字串。程序遍歷案件的文件目錄,排除自定義
            文件後,取得各文件的份數、總頁數、異動狀態及來源案件編號(UseCase)。若同
            一文件來自多個目錄,則會累加數據,最後產出以 Tab 分隔的文件資訊清單。
  引用相依:GetUseCase, GetDocDirCopies, GetDocDir_Page, GetDocNoEdit
  方法描述:【生成標準引用件來源清單】
            針對補件模式下「從其他案件引進」的標準文件,紀錄其來源案號與引入份數。
            彙整格式為:DocNo[Tab]份數[Tab]來源案號。
============================================================================== }
Function TCB_IMGPSScanX.CreateDocnoFrom_Info(CaseID:String):String; //產生被引進的保管袋文件資訊  Docno[tab]份數[tab]案件編號#13#10Docno[tab]份數[tab]案件編號
var
@@ -720,10 +739,10 @@
{ ==============================================================================
  方法名稱:CreateCustDocNoFrom_Info
  引用相依:FileExists, LoadFromFile
  方法描述:產出自定義文件的引進資訊字串。專門處理前綴為 "ZZZZZ" 的目錄,提取自定
            義文件名稱、份數及來源案件。與保管袋文件類似,會執行重複合併並統計總頁
            數,最後產出格式化的資訊字串。
  引用相依:GetCustomDocName, GetUseCase, GetDocDirCopies, GetDocDir_Page, GetDocNoEdit
  方法描述:【生成自訂引用件來源清單】
            針對補件模式下「從其他案件引進」的自定義文件,紀錄其來源案號與引入份數。
            彙整格式為:自訂名稱[Tab]份數[Tab]來源案號。
============================================================================== }
Function TCB_IMGPSScanX.CreateCustDocNoFrom_Info(CaseID:String):String; //產生被引進的自定文件資訊  Docno[tab]份數[tab]案件編號#13#10Docno[tab]份數[tab]案件編號
var
@@ -786,9 +805,9 @@
{ ==============================================================================
  方法名稱:CreateAttach_Info
  引用相依:
  方法描述:判斷案件是否存在附加電子檔。透過檢查附加檔案目錄的總頁數是否大於 0,回
            傳 "Y" 或 "N"。
  引用相依:GetDocDir_Page, AttName
  方法描述:【偵測是否有附加檔案】
            檢查指定的附件目錄 (AttName) 是否包含影像或電子檔,回傳 "Y" 或 "N" 標記。
============================================================================== }
Function TCB_IMGPSScanX.CreateAttach_Info(CaseID:String):String; //產生是否有Attach Y:有 N:沒有
begin
reassemble/CB_IMGPSScanImp.preview.pas
@@ -1,7 +1,9 @@
{ ==============================================================================
  方法名稱:ShapeName2PreViewISBName
  引用相依:
  方法描述:將 TShape 元件的名稱轉換為對應的預覽影像捲軸盒(PreViewISB)名稱。
  引用相依:ISBName
  方法描述:【選取框名稱轉影像盒名稱】
            將 TShape (選取框) 的物件名稱轉換為對應的預覽影像盒 (TImageScrollBox)
            名稱,用於同步選取狀態。
============================================================================== }
Function TCB_IMGPSScanX.ShapeName2PreViewISBName(SP:TShape):String; //轉出指定PreViewISBName
begin
@@ -11,11 +13,14 @@
{ ==============================================================================
  方法名稱:CreatePreViewISB
  引用相依:
  方法描述:動態建立指定數量的縮圖預覽組件。首先清空既有的預覽組件,接著在 ScrollB
            ox1 中為每個縮圖建立一個 TPanel 作為容器,並在其內嵌入一個 TImageScro
            llBox。設定組件的對齊方式、預設縮放模式及多項事件處理函式(如 Click, Mo
            useMove, DragDrop 等),並掛載右鍵選單。
  引用相依:TImageScrollBox, TPanel, ScrollBox1
  方法描述:【動態建立影像縮圖組件】
            依據傳入的影像數量,在 ScrollBox1 中動態配置預覽格位。
            1. 資源清理:呼叫 FreePreViewISB 釋放舊組件。
            2. 容器配置:為每個影像建立 TPanel (前綴 M_Pl),設定初始垂直間距。
            3. 編輯器配置:在 Panel 內建立 TImageScrollBox,掛載全套影像事件
               (Click, MouseMove, DragDrop, PopupMenu 等)。
            4. 屬性初始化:設定縮放模式為 zmFullPage 以符合縮圖比例。
============================================================================== }
Procedure TCB_IMGPSScanX.CreatePreViewISB(Count:Integer);
var
@@ -69,10 +74,10 @@
{ ==============================================================================
  方法名稱:FreePreViewISB
  引用相依:
  方法描述:釋放所有與縮圖預覽相關的動態組件。遍歷所有組件,尋找名稱中包含特定前綴
            (如 ISBName, M_Pl, SP)的 TImageScrollBox、TPanel 與 TShape 並執行 Fre
            e 動作。最後呼叫 ProcessMessages 確保 UI 資源正確釋放。
  引用相依:ActiveForm Components
  方法描述:【安全釋放預覽資源】
            逆向遍歷元件清單,識別並釋放所有動態生成的 TImageScrollBox、TPanel
            與 TShape 物件。包含異常保護處理,確保 UI 資源徹底回收並防止閃爍。
============================================================================== }
Procedure TCB_IMGPSScanX.FreePreViewISB;
var
@@ -107,10 +112,11 @@
{ ==============================================================================
  方法名稱:FitPreViewISB
  引用相依:
  方法描述:自動調整所有預覽縮圖面板的高度與位置。遍歷所有已建立的預覽組件(ISB),
            根據每個影像實際顯示的高度(DisplayedGraphic.Height)動態設定其父面板
            的高度,並依序由上而下排列,確保縮圖之間緊密銜接。
  引用相依:DisplayedGraphic.Height
  方法描述:【縮圖佈局自適應排列】
            解決縮圖因影像比例不同產生的間隙問題。
            遍歷所有預覽 ISB,讀取其影像實際顯示高度,重新計算並套用父面板的
            Top 與 Height,實現緊湊的垂直流式佈局。
============================================================================== }
Procedure TCB_IMGPSScanX.FitPreViewISB;
var
@@ -152,11 +158,12 @@
{ ==============================================================================
  方法名稱:PaintShape
  引用相依:
  方法描述:在預覽縮圖周圍繪製藍色選取框(TShape)。若僅傳入單一影像(ToImg 為 nil),
            則只在該影像位置建立選取框;若傳入起點與終點影像,則會在範圍內的所有影
            像組件上建立選取框。框線寬度設為 3 且顏色為藍色,用於視覺化標記選取狀
            態。
  引用相依:TShape, clBlue, ScrollBox1
  方法描述:【繪製選取視覺標記】
            在預覽縮圖周圍繪製藍色選取框。
            - 單選模式:在 FromImg 位置建立 TShape。
            - 範圍模式:若傳入 ToImg,則自動填補兩者間的所有格位選取框。
            邊框寬度設為 3 像素,並自動計算對齊父面板邊界。
============================================================================== }
Procedure TCB_IMGPSScanX.PaintShape(FromImg,ToImg:TImageScrollBox); //畫有被選取的影像
var
@@ -217,10 +224,11 @@
{ ==============================================================================
  方法名稱:FreeShapeobj
  引用相依:
  方法描述:刪除縮圖上的選取標記(TShape)。若傳入的 SelectISB 為 nil,則會刪除所有
            名稱前綴為 "SP" 的選取框組件;若指定了特定的影像組件,則僅刪除與該影像
            對應的選取框。
  引用相依:TShape, ScrollBox1
  方法描述:【刪除縮圖選取框】
            移除預覽組件上的選取視覺標記。
            - 全區模式 (SelectISB=nil):刪除所有名稱包含 "SP" 的 TShape。
            - 指定模式:僅移除特定影像盒對應的選取框組件。
============================================================================== }
Procedure TCB_IMGPSScanX.FreeShapeobj(SelectISB : TImageScrollBox);
var
@@ -246,11 +254,15 @@
{ ==============================================================================
  方法名稱:ISBClick
  引用相依:Image_Smooth, LoadFromFile
  方法描述:處理縮圖點擊事件,支援組合鍵選取。若按下 Shift 鍵則執行連選(PaintShape
             範圍選取);若按下 Control 鍵則切換單選狀態;一般點擊則清除舊選取並重
            新標記。點擊後會從選取的縮圖載入原圖至主顯示區(ISB1),並視需要執行影像
            平滑化處理。
  引用相依:PaintShape, FreeShapeobj, LoadFromFile, Image_Smooth
  方法描述:【處理縮圖選取與主圖載入】
            1. 組合鍵處理:
               - Shift: 範圍選取。
               - Control: 切換選取狀態。
               - 一般: 清除舊選取並單選。
            2. 狀態同步:更新 SelectPage 與選取框圖形。
            3. 主圖渲染:從縮圖檔案路徑載入原圖至主顯示區 (ISB1),針對彩色影像
               自動執行平滑化 (Image_Smooth) 優化顯示品質。
============================================================================== }
Procedure TCB_IMGPSScanX.ISBClick(Sender : TObject);
var
@@ -294,9 +306,10 @@
{ ==============================================================================
  方法名稱:ISBMouseMove
  引用相依:
  方法描述:處理縮圖區的滑鼠移動事件。當處於拖曳狀態且滑鼠移動至已選取的影像(有 S
            P 標記)時,觸發組件的 BeginDrag 開始執行拖放操作。
  引用相依:BeginDrag, TShape
  方法描述:【管理縮圖拖曳啟動】
            當滑鼠在縮圖區移動時,若偵測到 Draging 標記且滑鼠位於已選取的視覺框 (SP)
            範圍內,則正式觸發 VCL 的 BeginDrag 機制,開始執行影像重排序操作。
============================================================================== }
Procedure TCB_IMGPSScanX.ISBMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
@@ -315,11 +328,9 @@
{ ==============================================================================
  方法名稱:ISBImageMouseDown
  引用相依:LoadFromFile
  方法描述:處理縮圖預覽影像的滑鼠按下事件。當按下左鍵時,將 Draging 標記設為 True
             以利後續拖曳判斷。若未處於拖曳中,則根據是否按下 Shift 或 Control 鍵,
            執行範圍選取、加選或單選操作。選取後會更新 SelectPage,並在主顯示區(ISB
            1)同步載入對應的影像檔案。
  引用相依:Draging
  方法描述:【縮圖區域滑鼠按下處理】
            當滑鼠左鍵點擊縮圖時,開啟 Draging 判定開關,準備發起拖曳排序操作。
============================================================================== }
procedure TCB_IMGPSScanX.ISBImageMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
@@ -398,8 +409,9 @@
{ ==============================================================================
  方法名稱:ISBImageMouseUp
  引用相依:
  方法描述:處理縮圖預覽影像的滑鼠放開事件,將拖曳標記 Draging 重置為 False。
  引用相依:Draging
  方法描述:【縮圖區域滑鼠放開處理】
            當滑鼠按鍵放開時,強制關閉 Draging 判定開關,確保拖曳操作安全結束。
============================================================================== }
procedure TCB_IMGPSScanX.ISBImageMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
@@ -410,9 +422,10 @@
{ ==============================================================================
  方法名稱:ISBEndDrag
  引用相依:
  方法描述:當影像拖放操作結束時,觸發 TreeView1Click 事件以更新樹狀結構與顯示介
            面。
  引用相依:TreeView1Click
  方法描述:【拖曳操作結束回呼】
            當影像位置調整(拖放)完成後,強制觸發 TreeView1Click 重新載入
            左側樹狀結構與右側預覽區,確保 UI 顯示最新的檔案排序。
============================================================================== }
procedure TCB_IMGPSScanX.ISBEndDrag(Sender, Target: TObject; X, Y: Integer);
begin
@@ -422,9 +435,10 @@
{ ==============================================================================
  方法名稱:ISBDragDrop
  引用相依:
  方法描述:執行縮圖拖放後的影像移動操作。根據來源與目標影像的原始掃描頁碼,呼叫 M
            oveImage_Drag 調整檔案在目錄中的順序。
  引用相依:MoveImage_Drag, FileName2ScanPage
  方法描述:【執行影像頁面重排】
            1. 獲取座標:取得來源縮圖 (Source) 與目標縮圖 (Sender) 的原始掃描頁碼。
            2. 實體搬移:呼叫 MoveImage_Drag 在磁碟目錄中執行檔案更名與位置調換。
============================================================================== }
procedure TCB_IMGPSScanX.ISBDragDrop(Sender, Source: TObject; X, Y: Integer);
var
@@ -439,9 +453,12 @@
{ ==============================================================================
  方法名稱:ISBDragOver
  引用相依:
  方法描述:判斷拖放操作是否可接受。僅在來源為影像組件、檔案路徑不同且樹狀結構選取
            在文件層級(Level 2)時,才允許執行拖放。
  引用相依:TreeView1
  方法描述:【判定拖放合法性】
            1. 類型檢查:確認來源與目標皆為影像縮圖組件。
            2. 同一性檢查:防止將影像拖放到自身位置。
            3. 權限檢查:僅限定在樹狀結構選取「文件層級 (Level 2)」時才允許排序,
               避免跨案件或非法層級的檔案操作。
============================================================================== }
procedure TCB_IMGPSScanX.ISBDragOver(Sender, Source: TObject; X, Y: Integer;
      State: TDragState; var Accept: Boolean);
reassemble/TImageScrollBox.ts
比對新檔案
@@ -0,0 +1,36 @@
export abstract class TImageScrollBox {
  // 屬性 (Properties)
  abstract graphic: any; // TDibGraphic
  abstract displayedGraphic: any; // TDibGraphic
  abstract mouseMode: any; // TMouseMode
  abstract alwaysShowAnnotations: boolean;
  abstract fileName: string;
  abstract antiAliased: boolean;
  abstract zoomMode: any; // TZoomMode
  abstract zoomPercent: number;
  // 方法 (Methods)
  abstract imageCountFromFile(fileName: string): number;
  abstract loadFromFile(fileName: string, imageNo: number): void;
  abstract saveToFile(fileName: string): void;
  abstract saveToStream(stream: any, extension: string): void;
  abstract appendToStream(stream: any, extension: string): void;
  abstract clear(): void;
  abstract redraw(graphicChanged: boolean): void;
  // 事件 (Events)
  abstract onZoomChange?: (sender: any) => void;
  abstract onBeforeSave?: (sender: any) => void;
  abstract onRedraw?: (sender: any) => void;
  abstract onNewGraphic?: (sender: any, graphic: any) => void;
  abstract onQuickSelect?: (sender: any) => void;
  abstract onImageMouseMove?: (sender: any, shift: any, x: number, y: number) => void;
  abstract onImageMouseDown?: (sender: any, button: any, shift: any, x: number, y: number) => void;
  abstract onImageMouseUp?: (sender: any, button: any, shift: any, x: number, y: number) => void;
  abstract onImageDblClick?: (sender: any) => void;
  abstract onImageClick?: (sender: any) => void;
  abstract onRubberbandChange?: (sender: any) => void;
  abstract onReadWriteProgress?: (sender: any, percent: number) => void;
  abstract onBeginScroll?: (sender: any) => void;
  abstract onEndScroll?: (sender: any) => void;
}
reassemble/TImageScrollBox.ts.bk
比對新檔案
@@ -0,0 +1,62 @@
export interface TImageScrollBox {
  // 屬性 (Properties)
  graphic: any; // TDibGraphic
  displayedGraphic: any; // TDibGraphic
  frameCount: number;
  frames: (frameNo: number) => any; // TDibGraphic
  currentFrame: number;
  animated: boolean;
  mouseMode: any; // TMouseMode
  mouseHandler: any; // TMouseHandler
  imageRect: { left: number; top: number; right: number; bottom: number }; // TRect
  scrollInProgress: boolean;
  annotations: string;
  alwaysShowAnnotations: boolean;
  maxZoomPercent: number;
  fileName: string;
  readAheadFileName: string;
  antiAliased: boolean;
  zoomMode: any; // TZoomMode
  zoomPercent: number;
  centered: boolean;
  // 方法 (Methods)
  imageCountFromFile(fileName: string): number;
  imageCountFromStream(stream: any, extension: string): number;
  loadFromFile(fileName: string, imageNo: number): void;
  loadFromStream(stream: any, extension: string, imageNo: number): void;
  saveToFile(fileName: string): void;
  saveToStream(stream: any, extension: string): void;
  appendToFile(fileName: string): void;
  appendToStream(stream: any, extension: string): void;
  clear(): void;
  redraw(graphicChanged: boolean): void;
  copySelectionToClipboard(): void;
  cropToSelection(): void;
  extractSelection(dest: any): void; // TDibGraphic
  copyGraphicIntoSelection(graphic: any): void; // TGraphic
  zoomToSelection(): void;
  assignFromClipboard(): boolean;
  addNote(): any; // TStickNoteMark
  addText(): any; // TTextMark
  addRectangle(): any; // TRectangleMark
  addLine(): any; // TLineMark
  addImage(): any; // TImageMark
  burnAnnotations(): void;
  // 事件 (Events)
  onZoomChange?: (sender: any) => void;
  onBeforeSave?: (sender: any) => void;
  onRedraw?: (sender: any) => void;
  onNewGraphic?: (sender: any, graphic: any) => void;
  onQuickSelect?: (sender: any) => void;
  onImageMouseMove?: (sender: any, shift: any, x: number, y: number) => void;
  onImageMouseDown?: (sender: any, button: any, shift: any, x: number, y: number) => void;
  onImageMouseUp?: (sender: any, button: any, shift: any, x: number, y: number) => void;
  onImageDblClick?: (sender: any) => void;
  onImageClick?: (sender: any) => void;
  onRubberbandChange?: (sender: any) => void;
  onReadWriteProgress?: (sender: any, percent: number) => void;
  onBeginScroll?: (sender: any) => void;
  onEndScroll?: (sender: any) => void;
}
reassemble/TMemo.ts
比對新檔案
@@ -0,0 +1,27 @@
export abstract class TMemo {
  abstract lines: string[]; // TStrings
  abstract align?: any;
  abstract alignment?: any;
  abstract anchors?: any;
  abstract borderStyle?: any;
  abstract charCase?: any;
  abstract color?: string;
  abstract enabled: boolean;
  abstract font?: any;
  abstract hideSelection?: boolean;
  abstract maxLength?: number;
  abstract visible: boolean;
  // 事件 (Events)
  abstract onChange?: (sender: any) => void;
  abstract onClick?: (sender: any) => void;
  abstract onDblClick?: (sender: any) => void;
  abstract onEnter?: (sender: any) => void;
  abstract onExit?: (sender: any) => void;
  abstract onKeyDown?: (sender: any, key: number, shift: any) => void;
  abstract onKeyPress?: (sender: any, key: string) => void;
  abstract onKeyUp?: (sender: any, key: number, shift: any) => void;
  abstract onMouseDown?: (sender: any, button: any, shift: any, x: number, y: number) => void;
  abstract onMouseMove?: (sender: any, shift: any, x: number, y: number) => void;
  abstract onMouseUp?: (sender: any, button: any, shift: any, x: number, y: number) => void;
}
reassemble/TMemo.ts.bk
比對新檔案
@@ -0,0 +1,34 @@
export interface TMemo {
  // 屬性 (Properties)
  caretPos: { x: number; y: number }; // TPoint
  lines: string[]; // TStrings
  align?: any;
  alignment?: any;
  anchors?: any;
  borderStyle?: any;
  charCase?: any;
  color?: string;
  enabled: boolean;
  font?: any;
  hideSelection?: boolean;
  maxLength?: number;
  readOnly: boolean;
  scrollBars: any; // TScrollStyle
  visible: boolean;
  wantReturns: boolean;
  wantTabs: boolean;
  wordWrap: boolean;
  // 事件 (Events)
  onChange?: (sender: any) => void;
  onClick?: (sender: any) => void;
  onDblClick?: (sender: any) => void;
  onEnter?: (sender: any) => void;
  onExit?: (sender: any) => void;
  onKeyDown?: (sender: any, key: number, shift: any) => void;
  onKeyPress?: (sender: any, key: string) => void;
  onKeyUp?: (sender: any, key: number, shift: any) => void;
  onMouseDown?: (sender: any, button: any, shift: any, x: number, y: number) => void;
  onMouseMove?: (sender: any, shift: any, x: number, y: number) => void;
  onMouseUp?: (sender: any, button: any, shift: any, x: number, y: number) => void;
}
reassemble/TMenuItem.ts
比對新檔案
@@ -0,0 +1,28 @@
export abstract class TMenuItem {
  abstract handle: any; // HMENU
  abstract count: number;
  abstract items: TMenuItem[];
  abstract action?: any;
  abstract bitmap?: any;
  abstract break?: any;
  abstract caption: string;
  abstract checked: boolean;
  abstract subMenuImages?: any;
  abstract enabled: boolean;
  abstract hint: string;
  abstract imageIndex: number;
  abstract visible: boolean;
  abstract insert(index: number, item: TMenuItem): void;
  abstract delete(index: number): void;
  abstract clear(): void;
  abstract click(): void;
  abstract find(caption: string): TMenuItem | null;
  abstract indexOf(item: TMenuItem): number;
  abstract add(item: TMenuItem | TMenuItem[]): void;
  // 事件 (Events)
  abstract onClick?: (sender: any) => void;
  abstract onDrawItem?: (sender: any, canvas: any, rect: any, selected: boolean) => void;
  abstract onMeasureItem?: (sender: any, canvas: any, width: number, height: number) => void;
}
reassemble/TMenuItem.ts.bk
比對新檔案
@@ -0,0 +1,43 @@
export interface TMenuItem {
  // 屬性 (Properties)
  command: number;
  handle: any; // HMENU
  count: number;
  items: TMenuItem[];
  menuIndex: number;
  action?: any;
  autoCheck: boolean;
  autoHotkeys: any;
  autoLineReduction: any;
  bitmap?: any;
  break?: any;
  caption: string;
  checked: boolean;
  subMenuImages?: any;
  default: boolean;
  enabled: boolean;
  groupIndex: number;
  helpContext: number;
  hint: string;
  imageIndex: number;
  radioItem: boolean;
  shortCut: any;
  visible: boolean;
  // 方法 (Methods)
  initiateAction(): void;
  insert(index: number, item: TMenuItem): void;
  delete(index: number): void;
  clear(): void;
  click(): void;
  find(caption: string): TMenuItem | null;
  indexOf(item: TMenuItem): number;
  isLine(): boolean;
  add(item: TMenuItem | TMenuItem[]): void;
  remove(item: TMenuItem): void;
  // 事件 (Events)
  onClick?: (sender: any) => void;
  onDrawItem?: (sender: any, canvas: any, rect: any, selected: boolean) => void;
  onMeasureItem?: (sender: any, canvas: any, width: number, height: number) => void;
}
reassemble/TShape.ts
比對新檔案
@@ -0,0 +1,15 @@
export abstract class TShape {
  abstract pen: any; // TPen
  abstract shape: any; // TShapeType (e.g., stRectangle, stEllipse, etc.)
  abstract align?: any;
  abstract enabled: boolean;
  abstract visible: boolean;
  abstract showHint?: boolean;
  // 事件 (Events)
  abstract onMouseDown?: (sender: any, button: any, shift: any, x: number, y: number) => void;
  abstract onMouseMove?: (sender: any, shift: any, x: number, y: number) => void;
  abstract onMouseUp?: (sender: any, button: any, shift: any, x: number, y: number) => void;
  abstract onMouseEnter?: (sender: any) => void;
  abstract onMouseLeave?: (sender: any) => void;
}
reassemble/TShape.ts.bk
比對新檔案
@@ -0,0 +1,17 @@
export interface TShape {
  // 屬性 (Properties)
  brush: any; // TBrush
  pen: any; // TPen
  shape: any; // TShapeType (e.g., stRectangle, stEllipse, etc.)
  align?: any;
  enabled: boolean;
  visible: boolean;
  showHint?: boolean;
  // 事件 (Events)
  onMouseDown?: (sender: any, button: any, shift: any, x: number, y: number) => void;
  onMouseMove?: (sender: any, shift: any, x: number, y: number) => void;
  onMouseUp?: (sender: any, button: any, shift: any, x: number, y: number) => void;
  onMouseEnter?: (sender: any) => void;
  onMouseLeave?: (sender: any) => void;
}
reassemble/iisunit.ts
比對新檔案
@@ -0,0 +1,83 @@
/**
 * IISUnit 基礎型別定義
 */
export type TDC = Record<string, string>[];
export enum TTextFormat { tfAnsi, tfUnicode, tfUnicodeBigEndian, tfUtf8 }
export type TRect = { Left: number; Top: number; Right: number; Bottom: number };
export type TPoint = { X: number; Y: number };
export type THandle = number;
export type DWORD = number;
export type Cardinal = number;
export type TColor = number;
export type TStringList = string[];
/**
 * IIS 核心工具抽象類別 (IISUnit)
 */
export abstract class IisUnit {
    /** 數字補'0'轉字串 */
    abstract ADD_Zoo(istring: number, i: number): string;
    /** 取得電腦日期 (YYYYMMDD) */
    abstract GetDate(): string;
    /** 取得與 Server 的時間差距 (秒) */
    abstract GetBalance(ServerTime: string): number;
    /** 利用時間差距取得 server 上的時間 (HHMMSS) */
    abstract GetBalance2Time(Balance: number): string;
    /** 字串建目錄 */
    abstract Str2Dir(Dir: string): string;
    /** 刪掉指定目錄裡的所有檔案和子目錄(含自己) */
    abstract _DelTree(ASourceDir: string): void;
    /** 字串先 Base64 再加解密 */
    abstract En_DecryptionStr_Base64(CodeType: string, InStr: string, MpsKey: string): string;
    /** 從後面開始取位置 */
    abstract PosEnd(Substr: string, S: string): number;
    /** 指定取第幾個指定字元位置 */
    abstract PosN(Substr: string, S: string, N: number): number;
    /** 公分字串轉 Rect
     * scope: @view,  */
    abstract CM_Str2Rect(Str: string, Dpi: number, UpPoint: TPoint): TRect;
    /** 加入 ToolTip */
    abstract AddToolTip(hwnd: DWORD, IconType: number, Text: string, Title: string, BackColor: TColor, TextColor: TColor): void;
    /** 多國語言訊息轉換 */
    abstract _Msg(Msg: string): string;
    /** 刪除空的子目錄 */
    abstract Del_Sub_NothingPath(MainPath: string): void;
    /** 字串轉 Point */
    abstract Str2Point(S: string): TPoint;
    /** 取得 Local AppData 目錄 */
    abstract GetLocalAppDir(Handle: THandle): string;
    /** 使用 IP 檢查授權 (含日期與索引) */
    abstract CheckLicensebyIP_new(FileName: string, Result: { MacID: string, IP_Str: string, LegalDate: string, Msg: string, NowCount: number, TotalCount: number, Lic_Idx: number }): boolean;
    /** 增加授權 */
    abstract AddLicense(FileName: string, MacID: string, IP_Str: string, Result: { Msg: string }): boolean;
    /** 字串存檔 */
    abstract StringtoFile(S: string, FileName: string): void;
    /** 分割字串 */
    abstract SplitString(ch: string, Source: string): TStringList;
    /** 讀取檔案取得 MD5 */
    abstract LoadFileGetMD5(filename: string): string;
    /** 獲取自身版本號 */
    abstract GetCurrentVersionNo(Module: Cardinal): string;
}
reassemble/iisunit.ts.bk
比對新檔案
@@ -0,0 +1,335 @@
/**
 * IISUnit 基礎型別定義
 */
export type TDC = Record<string, string>[];
export enum TTextFormat { tfAnsi, tfUnicode, tfUnicodeBigEndian, tfUtf8 }
export type TRect = { Left: number; Top: number; Right: number; Bottom: number };
export type TPoint = { X: number; Y: number };
export type THandle = number;
export type DWORD = number;
export type Cardinal = number;
export type TColor = number;
export type TStringList = string[];
/**
 * IIS 核心工具抽象類別 (IISUnit)
 */
export abstract class IisUnit {
    /** 身份證號碼檢查 */
    abstract CheckRocID(ID: string): boolean;
    /** 統一編號檢查 */
    abstract CheckBANO(BANO: string): boolean;
    /** 數字補'0'轉字串 */
    abstract ADD_Zoo(istring: number, i: number): string;
    /** 字串補零 */
    abstract ADD_Zoo1(istring: string, i: number): string;
    /** 字串補空白轉字串 */
    abstract ADD_Blank(istring: string, i: number): string;
    /** 取得電腦日期民國年 (YYYMMDD) */
    abstract GetDate_TW(): string;
    /** 取得電腦日期 (XXXX/XX/XX) */
    abstract GetDate_A(): string;
    /** 取得電腦日期 (YYYYMMDD) */
    abstract GetDate(): string;
    /** 取得電腦時間 (HHMMSS) */
    abstract GetTime(): string;
    /** 取得電腦時間 (XX:XX:XX) */
    abstract GetTime_A(): string;
    /** 取得電腦時間至毫秒 (HH:MM:SS:mmm) */
    abstract GetTime_ms(): string;
    /** 將傳入時間轉成秒 (HHMMSS) */
    abstract GetTime2Sec(Time: string): number;
    /** 取得與 Server 的時間差距 (秒) */
    abstract GetBalance(ServerTime: string): number;
    /** 利用時間差距取得 server 上的時間 (HHMMSS) */
    abstract GetBalance2Time(Balance: number): string;
    /** 利用時間差距取得 server 上的時間轉成秒 */
    abstract GetBalanceTime2Sec(Balance: number): number;
    /** 字串建目錄 */
    abstract Str2Dir(Dir: string): string;
    /** 刪除路徑下第一層空目錄 */
    abstract ClearSubPath(MainPath: string): void;
    /** 是否為空目錄 */
    abstract DirIsNull(DirName: string): boolean;
    /** 刪掉指定目錄裡的所有檔案和子目錄(含自己) */
    abstract _DelTree(ASourceDir: string): void;
    /** 複製所有檔案(含子目錄) */
    abstract CopyDirectory(Src: string, Des: string): void;
    /** 字串轉 UrlCode */
    abstract UrlEncode(S: string): string;
    /** 取得電腦的 IP (清單) */
    abstract LocalIP(): string;
    /** 只取一個 IP */
    abstract LocalIP_Single(): string;
    /** 取出網卡 MAC */
    abstract GetMacFromIP(IP: string): string;
    /** 字串加解密 (CodeType: 'E' 加密, 'D' 解密) */
    abstract En_DecryptionStr(CodeType: string, InStr: string, Mpskey: string): string;
    /** 字串先 Base64 再加解密 */
    abstract En_DecryptionStr_Base64(CodeType: string, InStr: string, MpsKey: string): string;
    /** AES 檔案解密 */
    abstract DecryptionFile(InFile: string, OutFile: string, MpsKey: string): void;
    /** AES 檔案加密 */
    abstract EncryptionFile(InFile: string, OutFile: string, MpsKey: string): void;
    /** AES 字串解密 */
    abstract DecryptionStr(InStr: string, MpsKey: string): string;
    /** 從前面取, 第 Offset 個字開始取位置 */
    abstract PosEx(SubStr: string, S: string, Offset?: number): number;
    /** 從後面開始取位置 */
    abstract PosEnd(Substr: string, S: string): number;
    /** 指定取第幾個指定字元位置 */
    abstract PosN(Substr: string, S: string, N: number): number;
    /** 總共有幾個指定的字元 */
    abstract PosCount(SubStr: string, S: string): number;
    /** 字串轉 Rect */
    abstract P_Str2Rect(Str: string): TRect;
    /** Rect 轉字串 */
    abstract P_Rect2Str(iRect: TRect): string;
    /** 公分字串轉 Rect */
    abstract CM_Str2Rect(Str: string, Dpi: number, UpPoint: TPoint): TRect;
    /** Rect 轉公分字串 */
    abstract Rect2CM_Str(iRect: TRect, Dpi: number, UpPoint: TPoint): string;
    /** 取得 ProgID */
    abstract GetProgID(FileName: string): string;
    /** 取得文件版本 */
    abstract GetVersion(FileName: string): string;
    /** 壓 CAB 取得文件版本 */
    abstract GetVersionForCab(FileName: string): string;
    /** 取得 CoClass 的 ClassID */
    abstract GetCLSID(FileName: string): string;
    /** 加入 ToolTip */
    abstract AddToolTip(hwnd: dword, IconType: number, Text: string, Title: string, BackColor: TColor, TextColor: TColor): void;
    /** 釋放 ToolTip */
    abstract FreeToolTip(): void;
    /** 多國語言訊息轉換 */
    abstract _Msg(Msg: string): string;
    /** 多國語言訊息轉換 (UTF8) */
    abstract _Msg_UTF8(Msg: string): string;
    /** 刪除空的子目錄 */
    abstract Del_Sub_NothingPath(MainPath: string): void;
    /** 字串轉 Point */
    abstract Str2Point(S: string): TPoint;
    /** 取得 AppData 目錄 */
    abstract GetAPPDir(Handle: THandle): string;
    /** 取得 Local AppData 目錄 */
    abstract GetLocalAppDir(Handle: THandle): string;
    /** 取得 System 目錄 */
    abstract GetSystemDir(Handle: THandle): string;
    /** 取得 Common AppData 目錄 */
    abstract GetCommonAppDir(Handle: THandle): string;
    /** 影像加辨識字串 */
    abstract AddInfTxt2Img(InFile: string): void;
    /** 檢查影像 */
    abstract CheckImage(ImageFile: string): boolean;
    /** 取得指定目錄下的所有子目錄清單 */
    abstract GetAllDir(Path: string, List: TStringList): void;
    /** 檢查授權清單 */
    abstract CheckLicense(FileName: string, Result: { MacID: string, IP_Str: string, Msg: string, NowCount: number, TotalCount: number }): boolean;
    /** 檢查授權 (含日期) */
    abstract CheckLicense_new(FileName: string, Result: { MacID: string, IP_Str: string, LegalDate: string, Msg: string, NowCount: number, TotalCount: number }): boolean;
    /** 使用 IP 檢查授權 */
    abstract CheckLicensebyIP(FileName: string, Result: { MacID: string, IP_Str: string, Msg: string, NowCount: number, TotalCount: number }): boolean;
    /** 使用 IP 檢查授權 (含日期與索引) */
    abstract CheckLicensebyIP_new(FileName: string, Result: { MacID: string, IP_Str: string, LegalDate: string, Msg: string, NowCount: number, TotalCount: number, Lic_Idx: number }): boolean;
    /** 增加授權 */
    abstract AddLicense(FileName: string, MacID: string, IP_Str: string, Result: { Msg: string }): boolean;
    /** 清除 Rect */
    abstract ClearRect(iRect: TRect): void;
    /** 取得位置參數 */
    abstract GetSitepara(SiteStr: string, SpecSite: string): string;
    /** 取得兩數最小值 */
    abstract MinFloat(Value1: number, Value2: number): number;
    /** 字串存檔 */
    abstract StringtoFile(S: string, FileName: string): void;
    /** 字串存檔 (UTF8) */
    abstract StringtoFile_Utf8(S: string, FileName: string): void;
    /** 字串附加至檔案 */
    abstract StringAddtoFile(S: string, FileName: string): void;
    /** 取出文字檔字串 */
    abstract FiletoString(FileName: string): string;
    /** 取出文字檔字串 (UTF8) */
    abstract FiletoString_utf8(FileName: string): string;
    /** 判斷是不是數字 */
    abstract IsNumberic(Value: string): boolean;
    /** 判斷是不是只有英數字 */
    abstract IsEng_Num(Value: string): boolean;
    /** 判斷是不是只有英文字 */
    abstract IsEng(Value: string): boolean;
    /** 判斷字是否為 Big5 字元 */
    abstract ISBig5(Str: string): boolean;
    /** 取出檔案大小 */
    abstract GetFileSize(FileName: string): number;
    /** 程式是否已在執行 */
    abstract ExeAlreadyProcess(ExeName: string): boolean;
    /** 程式是否已在執行 (自己檢查自己) */
    abstract ExeAlreadyProcessbySelf(ExeName: string): boolean;
    /** 取 Exe 程式的 PID */
    abstract GetProcessID(ExeName: string): number;
    /** 刪掉 PID */
    abstract RemovePID(PID: number): void;
    /** 分割字串 */
    abstract SplitString(ch: string, Source: string): TStringList;
    /** 取出 Json 指定 name 的值 */
    abstract Getjsondata(JsonString: string, name: string): string;
    /** 產生 Json */
    abstract SetjsonList(List: TStringList, name: string): string;
    /** 取出 Json 指定 name 的陣列 */
    abstract GetjsonList(JSonString: string, name: string): TStringList;
    /** 取出 Json 指定 name 的物件陣列 */
    abstract GetjsonObjList(JSonString: string, name: string): TStringList;
    /** 刪除 Json 指定的 Obj */
    abstract DeleteJsonObj(JSonString: string, name: string): string;
    /** 取出 Json 的物件陣列 */
    abstract GetjsonListarray(JSonString: string, DC: TDC): void;
    /** 取出 Json 的物件陣列 (指定 Name) */
    abstract GetjsonObjectListarray(JSonString: string, Name: string, DC: TDC): void;
    /** 取出 JSon 的物件的字串 */
    abstract GetjsonObjecttoString(JSonString: string, Name: string): string;
    /** 字串日期是否合法 */
    abstract check_StrDate(SDate: string): boolean;
    /** 檢查目錄名稱是否有不合法字元 */
    abstract CheckDirName(DirName: string): boolean;
    /** 取得 OS 版本 */
    abstract GetOSVersion(): number;
    /** 取得新的 GUID */
    abstract GetNewGuid(): string;
    /** 字串轉 Hex */
    abstract StringToHex(S: string): string;
    /** Hex 轉字串 */
    abstract HexToString(S: string): string;
    /** 檢查字串是否符合 EAN13 檢查 */
    abstract CheckEAN13(Str: string): boolean;
    /** 取電腦名稱 */
    abstract GetPCName(): string;
    /** StringList 轉字串 */
    abstract Stringlist2String(List: TStringList): string;
    /** Log 格式字串 */
    abstract StringtoLogFormat(Str: string): string;
    /** Log 格式化 */
    abstract LogFormat(Str: string, Mode: string, Result: { P_Start: number, P_Cost: number, LogSTime?: string }): string;
    /** 取得模組名稱 */
    abstract GetModalName(H: Cardinal): string;
    /** 取代字串 */
    abstract ReplaceStr(Str: string, oldstr: string, Newstr: string): string;
    /** 讀取檔案取得 MD5 */
    abstract LoadFileGetMD5(filename: string): string;
    /** 檢查子字串是否在逗號分隔字串內 */
    abstract SubCommaString(SubStr: string, CommaStr: string): boolean;
    /** 取得文件編碼類型 */
    abstract GetFileType(FileName: string): TTextFormat;
    /** 從螢幕大小取得 DPI */
    abstract GetDPIFromScreenSize(): number;
    /** 延時函數 */
    abstract Delay(MSecs: number): void;
    /** 獲取自身版本號 */
    abstract GetCurrentVersionNo(Module: Cardinal): string;
    /** 將字串轉成 Dictionary */
    abstract StringtoDC(Str: string, DC: TDC): void;
    /** 比較版本號 */
    abstract CompareVersions(NewVersion: string, OldVersion: string): number;
}
reassemble/img/iis_image_process.ts
@@ -5,13 +5,14 @@
export type TTiffGraphic = any;
export type TJpegGraphic = any;
export type TPngGraphic = any;
export type TGraphic = any;
export type TBitmap = any;
export type TStringlist = string[];
export type TImageScrollBox = any;
export type TRect = { Left: number; Top: number; Right: number; Bottom: number };
export type TPoint = { X: number; Y: number };
export type TObject = any;
export type TGraphic = any;
export type TShape = any;
export type THandle = number | string;
@@ -25,9 +26,6 @@
    /** 自動影像歪斜矯正 */
    abstract DeskewImg(Graphic: TDibGraphic): void;
    /** 以黑白影像偵測角度後,對彩色影像進行歪斜矯正 */
    abstract DeskewImgWithRef(Graphic: TDibGraphic, CR_Graphic: TDibGraphic): void;
    /** 清除影像邊緣黑邊 */
    abstract CleanupBorder(Graphic: TDibGraphic): void;
@@ -40,74 +38,15 @@
    /** 從 TIFF 標籤取出資訊 */
    abstract GetTag(FileName: string): string;
    /** 將資訊存入 TIFF 標籤 */
    abstract SetTag(FileName: string, DataStr: string): void;
    /** 產生印章影像 */
    abstract CreateStamp(FileName: string, Title: string, UserID: string, StampDate: string, StampWidth: number, StampHeight: number): void;
    /** 產生便條紙影像 */
    abstract CreateNote(FileName: string, Title: string): void;
    /** 產生草稿影像 */
    abstract CreateDraft(FileName: string, Title: string): void;
    /** 產生補件清單影像 */
    abstract CreateReportImg(FileName: string, BarCode: string, Memo: string, BGFileName: string, DataList: TStringlist, ItemList: TStringlist): void;
    /** 根據 JSON 產生報表影像 */
    abstract CreateReportImg_JSON(FileName: string, BGFileName: string, BarCode: string, JSONStr: string): void;
    /** 在影像上列印條碼 */
    abstract PrintBarcode(FileName: string, Content: string, L: number, T: number, Width: number, Height: number): void;
    /** 正中央浮水印 */
    abstract Watermark(logoBmp: TBitmap, Opacity: number, Content: string, Graphic: TDibGraphic): void;
    /** 文字浮水印 (1) */
    abstract Watermark1(Opacity: number, Content: string, Content1: string, Graphic: TDibGraphic): void;
    /** 康和證券專用浮水印 */
    abstract Watermark1_Hong(Opacity: number, Content: string, Content1: string, Graphic: TDibGraphic, ImgH: number): void;
    /** 新版康和證券顯示用浮水印 */
    abstract Watermark1_Hong_New(Opacity: number, Content: string, Content1: string, Graphic: TDibGraphic, DisGraphic: TDibGraphic, ImgH: number): void;
    /** 左上方浮水印 */
    abstract Watermark2(logoBmp: TBitmap, Opacity: number, Content: string, Graphic: TDibGraphic): void;
    /** 尋找定位點並計算表單大小 */
    abstract FindPoint(Graphic: TDibGraphic, UpPointL: TPoint, UpPointR: TPoint, DownPointL: TPoint, FormSize: { width: number, height: number }, Anchor: string): void;
    /** 取得黑點座標字串 */
    abstract GetBlackSpots(Graphic: TDibGraphic, L: number, T: number, R: number, B: number, Ratio: number): string;
    /** 尋找定位黑點 */
    abstract FindBlackPoint(Graphic: TDibGraphic, BlackPoint: TPoint): void;
    /** OMR 點數計算 */
    /** OMR 點數計算
     * scope: @view */
    abstract Get_OMR(Graphic: TDibGraphic, iRect: TRect): number;
    /** 取得 UI 框選範圍 */
    abstract GetSelectRect(ISB: TImageScrollBox): TRect;
    /** 從右下算回的框選範圍 */
    abstract GetSelectRect_Back(ISB: TImageScrollBox): TRect;
    /** 框選範圍轉公分字串 */
    abstract GetSelectRect2String(ISB: TImageScrollBox, UpPointL: TPoint): string;
    /** 框選範圍轉右下定位公分字串 */
    abstract GetSelectRect_Black2String(ISB: TImageScrollBox, BlackPoint: TPoint): string;
    /** 設定顯示框選區域 */
    abstract SetSelectRect(ISB: TImageScrollBox, iRect: TRect): void;
    /** 設定原始大小框選區域 */
    abstract SetSelectRect_Original(ISB: TImageScrollBox, iRect: TRect): void;
    /** 顯示登打輔助遮罩 */
    abstract ShowKeyinRect(ISB: TImageScrollBox, iRect: TRect): void;
    /** 影像縮放 */
    abstract ImageResize(Graphic: TDibGraphic, DesWidth: number, DesHeight: number): void;
@@ -115,26 +54,8 @@
    /** 改變 DPI 並縮放 */
    abstract DpiResize(Graphic: TDibGraphic, DesDpi: number, CheckDpi: boolean): void;
    /** 畫定位點輔助線 */
    abstract DrawPointLine(ISB: TImageScrollBox, UpPointL: TPoint, UpPointR: TPoint, DownPointL: TPoint): void;
    /** RTS 灰階轉黑白 */
    abstract Gray2BW_RTS(ISB: TImageScrollBox, Para1: number, Para2: number, Para3: number, Part?: TRect): void;
    /** RTS 彩色轉黑白 */
    abstract Color2BW_RTS(ISB: TImageScrollBox, Para1: number, Para2: number, Para3: number, Part?: TRect): void;
    /** 浮雕效果 */
    abstract Emboss(ISB: TImageScrollBox): void;
    /** 調整亮度 */
    abstract BrightnessImg(ISB: TImageScrollBox, Precent: number): void;
    /** 轉成黑白 */
    abstract ConvertToBW(Graphic: TDibGraphic): void;
    /** 轉成 256 灰階 */
    abstract ConvertTo256Gray(Graphic: TDibGraphic): void;
    /** 清除影像上的線條 (核心辨識前處理) */
    abstract ClearLine(Graphic: TDibGraphic, bt: number): void;
@@ -142,41 +63,17 @@
    /** 影像裁切 */
    abstract CropImg(Graphic: TDibGraphic, iRect: TRect): void;
    /** 計算三點夾角 */
    abstract GetPosAngle(UpL: TPoint, DownL: TPoint, UpR: TPoint): number;
    /** 檢查尺寸並執行補償性縮放 */
    abstract CheckSize(ISB: TImageScrollBox, UpL: TPoint, UpR: TPoint, DownL: TPoint, DefWidth: string, DefHeight: string): string;
    /** 取得黑白點狀態 */
    abstract GetPixBW(srcGraphic: TDibGraphic, x: number, y: number): number;
    /** BMP 轉不壓縮 JPEG */
    abstract BmpConverJpg(Source: string, SaveFileName: string): void;
    /** 黑白 TIF 轉彩色 JPG */
    abstract BWTif2Jpg(Graphic: TDibGraphic): void;
    /** 彩色影像存 TIF */
    abstract Color2tif(Graphic: TObject, FileName: string): void;
    /** 影像遮罩處理 */
    abstract FieldMask(ISB: TImageScrollBox, SiteList: string, Mode: string, UpPointL: TPoint): void;
    /** 遮罩標記存檔 */
    abstract SaveAnnotation(ISB: TImageScrollBox, FileName: string): void;
    /** 濾色處理 (僅留黑白) */
    abstract FilterColor(SoISB: TImageScrollBox, DeISB: TImageScrollBox, Ration: number): void;
    /** 影像縮放並保留 EXIF */
    abstract JpgReSize_Exif(Maxlength: number, Quality: number, OldFile: string, NewFile: string, WaterGraphic: TGraphic, PrintDate: boolean): void;
    /** 提取 EXIF 拍攝日期 */
    abstract GetExif_CaptureDateTime(FileName: string): string;
    /** 設定新版登打區域標記 */
    abstract SetKeyinRect_New(ISB: TImageScrollBox, SiteStr: string, SiteStr_Black: string, FormHeight: string, UpPointL: TPoint, UpPointR: TPoint, SP?: TShape): void;
    /** 影像平滑化 */
    abstract Image_Smooth(Graphic: TDibGraphic): void;
reassemble/img/iis_image_process.ts.bk
比對新檔案
@@ -0,0 +1,187 @@
/**
 * 公司 IIS_ImageProcess 相關類型定義
 */
export type TDibGraphic = any;
export type TTiffGraphic = any;
export type TJpegGraphic = any;
export type TPngGraphic = any;
export type TGraphic = any;
export type TBitmap = any;
export type TStringlist = string[];
export type TImageScrollBox = any;
export type TRect = { Left: number; Top: number; Right: number; Bottom: number };
export type TPoint = { X: number; Y: number };
export type TObject = any;
export type TShape = any;
export type THandle = number | string;
/**
 * IIS 影像處理核心抽象類別
 */
export abstract class IisImageProcess {
    /** 旋轉影像 */
    abstract Rotate(Graphic: TDibGraphic, Angle: number): void;
    /** 自動影像歪斜矯正 */
    abstract DeskewImg(Graphic: TDibGraphic): void;
    /** 以黑白影像偵測角度後,對彩色影像進行歪斜矯正 */
    abstract DeskewImgWithRef(Graphic: TDibGraphic, CR_Graphic: TDibGraphic): void;
    /** 清除影像邊緣黑邊 */
    abstract CleanupBorder(Graphic: TDibGraphic): void;
    /** 影像反向處理(負片效果) */
    abstract NegativeImg(Graphic: TDibGraphic): void;
    /** 將影像轉換為灰階 */
    abstract ConvertToGray(Graphic: TDibGraphic): void;
    /** 從 TIFF 標籤取出資訊 */
    abstract GetTag(FileName: string): string;
    /** 將資訊存入 TIFF 標籤 */
    abstract SetTag(FileName: string, DataStr: string): void;
    /** 產生印章影像 */
    abstract CreateStamp(FileName: string, Title: string, UserID: string, StampDate: string, StampWidth: number, StampHeight: number): void;
    /** 產生便條紙影像 */
    abstract CreateNote(FileName: string, Title: string): void;
    /** 產生草稿影像 */
    abstract CreateDraft(FileName: string, Title: string): void;
    /** 產生補件清單影像 */
    abstract CreateReportImg(FileName: string, BarCode: string, Memo: string, BGFileName: string, DataList: TStringlist, ItemList: TStringlist): void;
    /** 根據 JSON 產生報表影像 */
    abstract CreateReportImg_JSON(FileName: string, BGFileName: string, BarCode: string, JSONStr: string): void;
    /** 在影像上列印條碼 */
    abstract PrintBarcode(FileName: string, Content: string, L: number, T: number, Width: number, Height: number): void;
    /** 正中央浮水印 */
    abstract Watermark(logoBmp: TBitmap, Opacity: number, Content: string, Graphic: TDibGraphic): void;
    /** 文字浮水印 (1) */
    abstract Watermark1(Opacity: number, Content: string, Content1: string, Graphic: TDibGraphic): void;
    /** 康和證券專用浮水印 */
    abstract Watermark1_Hong(Opacity: number, Content: string, Content1: string, Graphic: TDibGraphic, ImgH: number): void;
    /** 新版康和證券顯示用浮水印 */
    abstract Watermark1_Hong_New(Opacity: number, Content: string, Content1: string, Graphic: TDibGraphic, DisGraphic: TDibGraphic, ImgH: number): void;
    /** 左上方浮水印 */
    abstract Watermark2(logoBmp: TBitmap, Opacity: number, Content: string, Graphic: TDibGraphic): void;
    /** 尋找定位點並計算表單大小 */
    abstract FindPoint(Graphic: TDibGraphic, UpPointL: TPoint, UpPointR: TPoint, DownPointL: TPoint, FormSize: { width: number, height: number }, Anchor: string): void;
    /** 取得黑點座標字串 */
    abstract GetBlackSpots(Graphic: TDibGraphic, L: number, T: number, R: number, B: number, Ratio: number): string;
    /** 尋找定位黑點 */
    abstract FindBlackPoint(Graphic: TDibGraphic, BlackPoint: TPoint): void;
    /** OMR 點數計算 */
    abstract Get_OMR(Graphic: TDibGraphic, iRect: TRect): number;
    /** 取得 UI 框選範圍 */
    abstract GetSelectRect(ISB: TImageScrollBox): TRect;
    /** 從右下算回的框選範圍 */
    abstract GetSelectRect_Back(ISB: TImageScrollBox): TRect;
    /** 框選範圍轉公分字串 */
    abstract GetSelectRect2String(ISB: TImageScrollBox, UpPointL: TPoint): string;
    /** 框選範圍轉右下定位公分字串 */
    abstract GetSelectRect_Black2String(ISB: TImageScrollBox, BlackPoint: TPoint): string;
    /** 設定顯示框選區域 */
    abstract SetSelectRect(ISB: TImageScrollBox, iRect: TRect): void;
    /** 設定原始大小框選區域 */
    abstract SetSelectRect_Original(ISB: TImageScrollBox, iRect: TRect): void;
    /** 顯示登打輔助遮罩 */
    abstract ShowKeyinRect(ISB: TImageScrollBox, iRect: TRect): void;
    /** 影像縮放 */
    abstract ImageResize(Graphic: TDibGraphic, DesWidth: number, DesHeight: number): void;
    /** 改變 DPI 並縮放 */
    abstract DpiResize(Graphic: TDibGraphic, DesDpi: number, CheckDpi: boolean): void;
    /** 畫定位點輔助線 */
    abstract DrawPointLine(ISB: TImageScrollBox, UpPointL: TPoint, UpPointR: TPoint, DownPointL: TPoint): void;
    /** RTS 灰階轉黑白 */
    abstract Gray2BW_RTS(ISB: TImageScrollBox, Para1: number, Para2: number, Para3: number, Part?: TRect): void;
    /** RTS 彩色轉黑白 */
    abstract Color2BW_RTS(ISB: TImageScrollBox, Para1: number, Para2: number, Para3: number, Part?: TRect): void;
    /** 浮雕效果 */
    abstract Emboss(ISB: TImageScrollBox): void;
    /** 調整亮度 */
    abstract BrightnessImg(ISB: TImageScrollBox, Precent: number): void;
    /** 轉成黑白 */
    abstract ConvertToBW(Graphic: TDibGraphic): void;
    /** 轉成 256 灰階 */
    abstract ConvertTo256Gray(Graphic: TDibGraphic): void;
    /** 清除影像上的線條 (核心辨識前處理) */
    abstract ClearLine(Graphic: TDibGraphic, bt: number): void;
    /** 影像裁切 */
    abstract CropImg(Graphic: TDibGraphic, iRect: TRect): void;
    /** 計算三點夾角 */
    abstract GetPosAngle(UpL: TPoint, DownL: TPoint, UpR: TPoint): number;
    /** 檢查尺寸並執行補償性縮放 */
    abstract CheckSize(ISB: TImageScrollBox, UpL: TPoint, UpR: TPoint, DownL: TPoint, DefWidth: string, DefHeight: string): string;
    /** 取得黑白點狀態 */
    abstract GetPixBW(srcGraphic: TDibGraphic, x: number, y: number): number;
    /** BMP 轉不壓縮 JPEG */
    abstract BmpConverJpg(Source: string, SaveFileName: string): void;
    /** 黑白 TIF 轉彩色 JPG */
    abstract BWTif2Jpg(Graphic: TDibGraphic): void;
    /** 彩色影像存 TIF */
    abstract Color2tif(Graphic: TObject, FileName: string): void;
    /** 影像遮罩處理 */
    abstract FieldMask(ISB: TImageScrollBox, SiteList: string, Mode: string, UpPointL: TPoint): void;
    /** 遮罩標記存檔 */
    abstract SaveAnnotation(ISB: TImageScrollBox, FileName: string): void;
    /** 濾色處理 (僅留黑白) */
    abstract FilterColor(SoISB: TImageScrollBox, DeISB: TImageScrollBox, Ration: number): void;
    /** 影像縮放並保留 EXIF */
    abstract JpgReSize_Exif(Maxlength: number, Quality: number, OldFile: string, NewFile: string, WaterGraphic: TGraphic, PrintDate: boolean): void;
    /** 提取 EXIF 拍攝日期 */
    abstract GetExif_CaptureDateTime(FileName: string): string;
    /** 設定新版登打區域標記 */
    abstract SetKeyinRect_New(ISB: TImageScrollBox, SiteStr: string, SiteStr_Black: string, FormHeight: string, UpPointL: TPoint, UpPointR: TPoint, SP?: TShape): void;
    /** 影像平滑化 */
    abstract Image_Smooth(Graphic: TDibGraphic): void;
    /** 列印影像控制 */
    abstract PrintImg(FileName: string, LoginID: string, Datetime: string, Path: string, WaterBmp: TBitmap, Spec_Page?: number, NeedSetup?: boolean): void;
}
reassemble/img/mermaid/GetSiteOMR.md
@@ -2,12 +2,12 @@
flowchart TD
    Start([開始]) --> CheckFile{影像是否已載入?}
    CheckFile -- 否 --> LoadImg[從檔案載入影像並清除緩衝線]
    CheckFile -- 是 --> GetInfo[獲取影像 DPI 與寬高資訊]
    CheckFile -- 是 --> GetInfo[獲取影像 DPI 與寬高資訊《Graphic》]
    
    LoadImg --> GetInfo
    GetInfo --> CalcRect[將 Site 字串轉為座標矩陣, 並參考定位點位移]
    CalcRect --> BoundCheck[限制座標不超出影像邊界]
    BoundCheck --> GetOMR[呼叫 Get_OMR 執行辨識]
    GetInfo --> CalcRect[將 Site 字串轉為座標矩陣, 並參考定位點位移《CM_Str2Rect》]
    CalcRect --> BoundCheck[限制座標不超出影像邊界《If》]
    BoundCheck --> GetOMR[呼叫 Get_OMR 執行辨識《Get_OMR》]
    GetOMR --> ReturnResult[返回辨識結果] --> End([結束])
```
@@ -26,3 +26,7 @@
  XY dpi 換算
- Width, Height
## todo 方法推斷
- Graphics - UI
-
reassemble/img/mermaid/ImageReSize_FormID.md
@@ -3,7 +3,7 @@
    Start([開始]) --> GetFormInfo[查詢 FORM_INF_List 取得高寬與定位類型]
    GetFormInfo --> ValidParam{是否有定位點設定?}
    
    ValidParam -- 是 --> LoadImg[載入影像檔 (補件模式則跳過)]
    ValidParam -- 是 --> LoadImg[載入影像檔「補件模式則跳過」]
    ValidParam -- 否 --> End([結束])
    
    LoadImg --> FindAnchor[呼叫 FindPoint 尋找十字線或邊框定位點]
reassemble/img/mps_barcode.ts
@@ -23,59 +23,10 @@
 * MPS 條碼辨識與影像清理核心抽象類別
 */
export abstract class MpsBarcode {
    /**
     * 將影像區塊旋轉 180 度後進行條碼辨識
     */
    abstract R180(Graphic: TDibGraphic, BrRect: TRect): string;
    /**
     * 搜尋影像中所有條碼,並將結果存入 TMpsBarcodeinf 結構
     */
    abstract MpsGetBarcode(Graphic: TDibGraphic, MpsBarcodeinf: TMpsBarcodeinf): number;
    /**
     * 偵測並移除黑白影像中的水平黑線 (基礎判定)
     */
    abstract MpsClearLine(srcGraphic: TDibGraphic, row: number, fromCol: number, toCol: number): number;
    /**
     * 垂直方向清除線條 (包含顯示更新與容差值)
     */
    abstract MpsClearLineV(srcGraphic: TDibGraphic, DisGraphic: TDibGraphic, row: number, fromCol: number, toCol: number, bt: number): void;
    /**
     * 水平方向清除線條 (包含顯示更新與容差值)
     */
    abstract MpsClearLineH(srcGraphic: TDibGraphic, DisGraphic: TDibGraphic, Cow: number, fromCol: number, toCol: number, bt: number): void;
    /**
     * 取得黑白影像指定座標點的顏色 (0 為黑, 非 0 為白)
     */
    abstract GetPixBW(srcGraphic: TDibGraphic, x: number, y: number): number;
    /**
     * 搜尋定位點 (十字或框線)
     */
    abstract Checked_Start(bmp: TDibGraphic, fromX: number, fromY: number, toX: number, toY: number, compsize: number, tmode: number, AnchorMode: string): TPoint;
    /**
     * 搜尋定位點 (國泰專用邏輯,支援框線檢查跳過)
     */
    abstract Checked_StartEx(bmp: TDibGraphic, fromX: number, fromY: number, toX: number, toY: number, compsize: number, tmode: number, CROSS_UNCHECK_FRAME: boolean): TPoint;
    /**
     * 檢查垂直起始處是否有雜點
     */
    abstract ChkTL(srcGraphic: TDibGraphic, CowX: number, Y1: number, Y2: number, bt: number): boolean;
    /**
     * 檢查水平起始處是否有雜點
     */
    abstract ChkTH(srcGraphic: TDibGraphic, RowY: number, X1: number, X2: number, bt: number): boolean;
    /**
     * 檢查水平/垂直區域是否非連續線條 (輔助判定)
     */
    abstract ChkNotv(srcGraphic: TDibGraphic, Row: number, x1: number, x2: number): boolean;
    abstract ChkNotH(srcGraphic: TDibGraphic, Cow: number, x1: number, x2: number): boolean;
}
reassemble/img/mps_barcode.ts.bk
比對新檔案
@@ -0,0 +1,81 @@
/**
 * MPS Barcode 辨識與影像清理相關類型定義
 */
export type TDibGraphic = any;
export type TRect = { Left: number; Top: number; Right: number; Bottom: number };
export type TPoint = { X: number; Y: number };
/**
 * 條碼辨識結果結構
 */
export interface TMpsBarcodeinf {
    /** 找到的條碼數量 */
    count: number;
    /** 條碼文字內容陣列 (最多 40 個) */
    Text: string[];
    /** 條碼所在的區域矩形陣列 (最多 40 個) */
    Rect: TRect[];
    /** 條碼的旋轉角度資訊陣列 (最多 40 個) */
    r180: number[];
}
/**
 * MPS 條碼辨識與影像清理核心抽象類別
 */
export abstract class MpsBarcode {
    /**
     * 將影像區塊旋轉 180 度後進行條碼辨識
     */
    abstract R180(Graphic: TDibGraphic, BrRect: TRect): string;
    /**
     * 搜尋影像中所有條碼,並將結果存入 TMpsBarcodeinf 結構
     */
    abstract MpsGetBarcode(Graphic: TDibGraphic, MpsBarcodeinf: TMpsBarcodeinf): number;
    /**
     * 偵測並移除黑白影像中的水平黑線 (基礎判定)
     */
    abstract MpsClearLine(srcGraphic: TDibGraphic, row: number, fromCol: number, toCol: number): number;
    /**
     * 垂直方向清除線條 (包含顯示更新與容差值)
     */
    abstract MpsClearLineV(srcGraphic: TDibGraphic, DisGraphic: TDibGraphic, row: number, fromCol: number, toCol: number, bt: number): void;
    /**
     * 水平方向清除線條 (包含顯示更新與容差值)
     */
    abstract MpsClearLineH(srcGraphic: TDibGraphic, DisGraphic: TDibGraphic, Cow: number, fromCol: number, toCol: number, bt: number): void;
    /**
     * 取得黑白影像指定座標點的顏色 (0 為黑, 非 0 為白)
     */
    abstract GetPixBW(srcGraphic: TDibGraphic, x: number, y: number): number;
    /**
     * 搜尋定位點 (十字或框線)
     */
    abstract Checked_Start(bmp: TDibGraphic, fromX: number, fromY: number, toX: number, toY: number, compsize: number, tmode: number, AnchorMode: string): TPoint;
    /**
     * 搜尋定位點 (國泰專用邏輯,支援框線檢查跳過)
     */
    abstract Checked_StartEx(bmp: TDibGraphic, fromX: number, fromY: number, toX: number, toY: number, compsize: number, tmode: number, CROSS_UNCHECK_FRAME: boolean): TPoint;
    /**
     * 檢查垂直起始處是否有雜點
     */
    abstract ChkTL(srcGraphic: TDibGraphic, CowX: number, Y1: number, Y2: number, bt: number): boolean;
    /**
     * 檢查水平起始處是否有雜點
     */
    abstract ChkTH(srcGraphic: TDibGraphic, RowY: number, X1: number, X2: number, bt: number): boolean;
    /**
     * 檢查水平/垂直區域是否非連續線條 (輔助判定)
     */
    abstract ChkNotv(srcGraphic: TDibGraphic, Row: number, x1: number, x2: number): boolean;
    abstract ChkNotH(srcGraphic: TDibGraphic, Cow: number, x1: number, x2: number): boolean;
}
reassemble/img/transformer.pas
@@ -1,9 +1,20 @@
{ ==============================================================================
  方法名稱:ImageReSize_FormID
  引用相依:CheckSize, FileExists, FindPoint, ImageReSize_FormID, ImageResize, L
            oadFileGetMD5, LoadFromFile, SaveToFile
  方法描述:依據定位點縮放影像。查詢表單規格,載入影像(過濾補件模式),尋找十字線或
            邊框定位點,執行縮放並紀錄 MD5 與日誌。
  引用相依:CheckSize, FileExists, FindPoint, FileName2FormCode, FindSQLData,
            GetFindResult, ImageReSize_FormID, ImageResize, ISExistImg,
            LoadFileGetMD5, LoadFromFile, SaveToFile
  方法描述:【正式案件影像定位縮放】
            依據表單定義的定位點(十字線或邊框)對案件影像進行標準化縮放。
            1. 識別與檢核:從檔案名稱提取 FormID,並從資料庫 (FORM_INF_List) 讀取標準
               寬高與定位點類型 (ANCHOR/FRAME)。
            2. 補件保護:若 FWH_category 為 'N'(補件模式)且影像已存在,則跳過處理。
            3. 定位偵測:載入影像後,利用 FindPoint 尋找左上、右上、左下三個定位點。
            4. 縮放執行:調用 CheckSize 計算尺寸偏移量,並執行 ImageResize 進行實體
               縮放與對齊。
            5. 資料完整性:縮放後重新驗證定位點,若成功則覆蓋原檔並更新 MD5 排除清單,
               同時於 ReSize.dat 紀錄處理時間與尺寸資訊。
            6. 錯誤處理:若定位點找尋失敗(如污損、傾斜過大),則將錯誤原因紀錄於
               AnchorError.dat 以供後續人工排錯。
============================================================================== }
Procedure TCB_IMGPSScanX.ImageReSize_FormID(CaseID,FileName:String);  //依十字定位點做縮放
var
@@ -26,11 +37,9 @@
    DW := GetFindResult('T1.FORM_WIDTH');
    ANCHOR := UpperCase(GetFindResult('T1.ANCHOR'));
    ANCHOR := Index2Anchor(ANCHOR);
Display1.Lines.Add(FormID+','+DH+','+DW);
//ShowMessage('AAAAAAAAA');
    Display1.Lines.Add(FormID+','+DH+','+DW);
    if ((ANCHOR = 'ANCHOR') or (ANCHOR = 'FRAME')) and (DH <> '') and (DW <> '') then  //有十字定位點
    begin
//ShowMessage('BBBBBBB');
      ImageScrollBox1.LoadFromFile(ImageSavePath+CaseID+'\Upload\'+FileName,1);
      if (FWH_category='N') and  ISExistImg(ImageSavePath+CaseID+'\Upload\'+FileName) then
@@ -38,7 +47,6 @@
        Exit;//20171103  補件  原有的圖不作resize
      end;
      //FindPoint(ImageScrollBox1.Graphic,UpLPoint,UpRPoint,DownLPoint,NowW,NowH);
      FindPoint(ISB_BW.Graphic,UpLPoint,UpRPoint,DownLPoint,NowW,NowH,ANCHOR);
      SizeStr := CheckSize(ISB_BW,UpLPoint,UpRPoint,DownLPoint,DW,DH);
@@ -49,7 +57,6 @@
      v1 := length(SizeStr);
      IF (SizeStr <> '') and (Copy(SizeStr,1,v) <> 'ERROR') then
      begin
//ShowMessage('CCCCC');
        if (ISExistImg(ImageSavePath+CaseID+'\Upload\'+FileName)) and (reSizeExistImgList.IndexOf(LoadFileGetMD5(ImageSavePath+CaseID+'\Upload\'+FileName))=-1) then
        begin
          IsRecordMD5:=True;
@@ -59,11 +66,10 @@
        begin
          reSizeExistImgList.add(LoadFileGetMD5(ImageSavePath+CaseID+'\Upload\'+FileName));
        end;
//showmessage(ImageSavePath+CaseID+'\Upload\'+FileName);
        S := TStringlist.Create;                     ///20110422拿掉 換成上傳才做
        if FileExists(ImageSavePath+CaseID+'\Upload\ReSize.dat') then
          S.LoadFromFile(ImageSavePath+CaseID+'\Upload\ReSize.dat');
        //S.Add(FormCode2FormName(FormID)+' '+SizeStr);
        S.Add(FileName+','+SizeStr+#8+DateTimetoStr(Now));
        S.SaveToFile(ImageSavePath+CaseID+'\Upload\ReSize.dat');
        S.Free;
@@ -86,9 +92,16 @@
{ ==============================================================================
  方法名稱:ImageReSize_tmp
  引用相依:CheckSize, ImageReSize_tmp, ImageResize, LoadFromFile, SaveToFile
  方法描述:針對暫存檔執行定位點縮放。簡化版 Resize 邏輯,若偵測到尺寸偏移則直接覆
            蓋原始檔案,用於處理臨時影像。
  引用相依:CheckSize, FindSQLData, GetFindResult, Index2Anchor, ImageReSize_tmp,
            ImageResize, LoadFromFile, SaveToFile
  方法描述:【暫存影像定位縮放】
            針對掃描過程中的臨時或暫存影像檔案執行快速定位點縮放。
            1. 規格查詢:依傳入的 FormID 查詢表單規格。
            2. 自動校正:載入影像後,透過 CheckSize 自動偵測三個定位點座標。
            3. 原地覆蓋:若 CheckSize 回傳非空值(代表檢測通過且已計算偏移),則直接
               將校正後的影像儲存回原始路徑。
            此方法邏輯較 ImageReSize_FormID 簡潔,不紀錄 MD5 與詳細日誌,主要用於
            處理即時上傳或切割前的預處理影像。
============================================================================== }
Procedure TCB_IMGPSScanX.ImageReSize_tmp(FormID,FileName:String);  //依十字定位點做縮放(暫存檔)
var
@@ -119,9 +132,15 @@
{ ==============================================================================
  方法名稱:CheckNeedCrop
  引用相依:CheckNeedCrop, TDibGraphic
  方法描述:判斷影像是否需執行 A3 切割。依據影像寬度(大於 4 倍 DPI)及條碼清單中有
            效表單代碼的數量(需為 2 個)作為判定據。
  引用相依:CheckNeedCrop, FormIDExists, MpsBarcodeinf, TDibGraphic
  方法描述:【A3 影像切割判定】
            判定目前的影像是否為「一紙兩面」的 A3 規格,進而決定是否執行切割 (Crop)。
            判定邏輯包含兩大要件:
            1. 物理尺寸:影像寬度必須大於 DPI 的 4 倍(針對 A3 橫向掃描的特徵)。
            2. 內容特徵:檢查當前偵測到的條碼清單 (MpsBarcodeinf),統計其中符合系統
               定義長度 (FormIDLength) 且在資料庫中有效的 FormID 數量。
            判定結果:當上述物理條件成立,且「有效表單代碼數量精確等於 2」時,回傳
            True,觸發後續的影像切割流程。
============================================================================== }
Function TCB_IMGPSScanX.CheckNeedCrop(Graphic:TDibGraphic):Boolean; //是否是A3要切影像
Var
@@ -130,7 +149,6 @@
  Result := False;
  FormIDCount := 0;
  if (Graphic.Width > (4 * Graphic.XDotsPerInch)) {or (Graphic.Height > (15 * Graphic.YDotsPerInch))} then
  //if (Graphic.Width > (6 * Graphic.XDotsPerInch)) then
  begin
    for I := 1 to MpsBarcodeinf.Count do
    begin
@@ -139,10 +157,7 @@
        inc(FormIDCount);
      end;
    end;
  end;
//ShowMessage('FormIDCount='+IntToStr(FormIDCount)+#10#13+'MpsBarcodeinf.count='+IntToStr(MpsBarcodeinf.count));
  if FormIDCount = 2 then
  begin
    Result := True;
reassemble/scan/twain.pas
@@ -1,10 +1,20 @@
{ ==============================================================================
  方法名稱:StatrTwainScan
  引用相依:OnAcquire, Scanner, Scanner.AcquireWithSourceOpen, Scanner.CloseSour
            ce, Scanner.OpenSource, StatrTwainScan, TTiffGraphic
  方法描述:啟動 TWAIN 掃描流程。檢查驅動是否安裝,初始化 ScanInfo 並設定 DPI、影像
            格式、UI 顯示及雙面掃描模式。執行 AcquireWithSourceOpen 並利用 try...f
            inally 確保資源釋放。
  引用相依:OnAcquire, Scanner, Scanner.AcquireWithSourceOpen, Scanner.CloseSource,
            Scanner.OpenSource, StatrTwainScan, TTiffGraphic
  方法描述:【啟動 TWAIN 掃描流程】
            此方法負責初始化掃描器環境並執行影像獲取作業。
            1. 驅動檢查:確認 Scanner.IsConfigured,若未安裝則提示使用者。
            2. 資訊初始化:配置 TScanInfo 結構,設定多頁模式並建立 TTiffGraphic 容器。
            3. 參數設定:套用掃描 DPI (ScanDpi)、影像格式 (ScanColor) 及 UI 顯示模式
               (TwainShowUI)。
            4. 來源配置:開啟掃描來源 (OpenSource),根據掃描模式 (ScanDuplex) 設定雙面
               功能,並在樣本掃描模式 (SAMPLESCAN) 下強迫關閉雙面。
            5. 影像校調:若 ScanImgSetUse 為真,則套用亮度 (ScanBright) 與對比
               (ScanContrast) 設定。
            6. 執行獲取:呼叫 AcquireWithSourceOpen 並掛載 OnAcquire 回調函數。
            7. 資源釋放:利用巢狀 try...finally 確保在任何異常發生時都能正確關閉掃描
               來源並釋放圖形物件。
============================================================================== }
procedure TCB_IMGPSScanX.StatrTwainScan;
var ScanInfo    : TScanInfo;
@@ -63,9 +73,27 @@
{ ==============================================================================
  方法名稱:OnAcquire
  引用相依:OnAcquire, TJpegGraphic, TTiffGraphic
  方法描述:掃描影像獲取後的回調處理。處理 DIB 句柄、設定 DPI、執行條碼辨識、影像旋
            轉、反向、去偏斜及清黑邊。支援 A3 裁切判定與空白頁過濾。
  引用相依:CheckNeedCrop, CleanupBorder, ConvertToGray, CropImg, DeskewImg,
            DeviceDelete, DeviceDeleteSize, FJpgCompression, MpsBarcodeinf,
            MpsGetBarcode, NegativeImg, OnAcquire, PageDone, PageEnd, Rotate,
            ScannerReverse, ScanDeskew, TJpegGraphic, TTiffGraphic
  方法描述:【掃描影像獲取回調處理】
            當掃描器完成一張影像獲取時由 TWAIN 驅動程式觸發,負責核心影像處理。
            1. 影像載入:將 DibHandle 轉換為 TTiffGraphic,並套用 XDpi/YDpi。
            2. 格式化處理:
               - 黑白影像:執行條碼辨識 (MpsGetBarcode),若條碼具角度則進行旋轉校正;
                 依據設定執行影像反向 (NegativeImg)、去偏斜 (DeskewImg) 及清黑邊
                 (CleanupBorder);設定為 Group4 壓縮。
               - 彩色/灰階:執行條碼辨識,套用 JPEG 壓縮及品質設定 (FJpgCompression)。
            3. A3 裁切處理:呼叫 CheckNeedCrop 判定是否為 A3 橫置,若符合則將影像垂直
               裁切為左右兩頁。
            4. 空白頁過濾:若啟用 DeviceDelete,會透過 Deletepage 計算影像串流大小,
               小於 DeviceDeleteSize 則判定為空白並捨棄。
            5. 自動旋轉:對處理後的每一頁再次進行條碼偵測,若條碼顯示角度不符則執行
               最後的 Rotate。
            6. 檔案儲存:調用 PageEnd 決定檔名 (PEFileName),依副檔名執行 TIF 附加
               (AppendToStream) 或 JPG 覆蓋儲存。
            7. UI 同步:每完成一頁儲存後呼叫 PageDone 更新介面顯示。
============================================================================== }
procedure TCB_IMGPSScanX.OnAcquire( const DibHandle    : THandle;
                               const XDpi         : Word;
@@ -310,9 +338,16 @@
{ ==============================================================================
  方法名稱:PageDone
  引用相依:LoadFromFile, PageDone
  方法描述:單頁影像處理後的 UI 更新。累加計數,根據模式(新建、取代、插入、取樣)將影
            像載入對應的顯示元件,並依設定調整反鋸齒與縮放。
  引用相依:FindISB2View, LoadFromFile, PageDone, TImageScrollBox
  方法描述:【單頁影像處理完成後的介面同步】
            在影像成功儲存至磁碟後,更新系統內部的影像計數器與顯示元件。
            1. 計數累加:更新 Scaninfo.ImageCount。
            2. 模式分支處理:
               - smNew (新建):根據 ScanImgShowMode 決定顯示品質(清晰/模糊)或不顯示。
                 使用 FindISB2View 尋找對應的顯示容器。
               - smReplace (取代):直接載入至 DisplayISB。
               - smInsert/smSample (插入/取樣):載入影像並設定為自動縮放至頁面寬度。
            3. 反鋸齒設定:若需清晰顯示,則啟動 AntiAliased 以提升預覽品質。
============================================================================== }
procedure TCB_IMGPSScanX.PageDone;
Var
@@ -367,10 +402,27 @@
{ ==============================================================================
  方法名稱:PageEnd
  引用相依:DirectoryExists, GetNoNameCase, PageEnd, SaveToFile, Str2Dir, _DelTr
            ee
  方法描述:管理影像儲存路徑與命名。辨識條碼區分表單、導引頁或分案頁;處理分份邏輯
            與自動建立目錄,並更新樹狀結構索引。
  引用相依:Add_Zoo, BarCode2CaseID, BarCode2FormID, DirectoryExists,
            FindDivFormCode, FindLastestDocDir, FormCode2DocNo, GetDocDir_Page,
            GetNoNameCase, ISDivPageFormID, ISGuideFormID, PageEnd, SetCaseList,
            SetContextList, SetDocNoList, Str2Dir, _DelTree
  方法描述:【掃描分案與儲存路徑管理】
            這是控制掃描流程中「自動分案」與「檔案命名」的核心邏輯方法。
            1. 條碼解析:從 MpsBarcodeinf 提取 FormID 與 CaseID。
            2. 自動分案邏輯 (smNew):
               - 識別分案頁 (DivPageFormID) 與導引頁 (GuideFormID)。
               - 偵測到分案條碼時,自動切換 ScanCaseno,清除舊有的 View 與索引,
                 實現批次掃描自動分拆案件。
            3. 目錄建立:根據案件編號與文件類型 (DocNo) 自動建立樹狀目錄。
               - 若案件路徑已存在且為首頁掃描,則會執行 _DelTree 清空舊資料。
               - 使用 Str2Dir 確保實體路徑層級完整。
            4. 文件分份處理:呼叫 DocNoNeedDiv 判定是否需根據份數另建子目錄 (如 001,
               002...)。
            5. 命名規則:
               - 一般文件:序號(3位) + '_' + FormID + 副檔名。
               - 附件:序號(3位) + 副檔名。
            6. 結構同步:更新 TreeView 樹狀結構,並透過 SetContextList 與
               SetCaseList 將新掃描的影像資訊寫入系統索引檔。
============================================================================== }
procedure TCB_IMGPSScanX.PageEnd;
Var
@@ -592,9 +644,14 @@
{ ==============================================================================
  方法名稱:R_W_Scanini
  引用相依:Scanner
  方法描述:讀取或寫入 FBScan.ini。處理包含空白頁刪除、影像反向、清黑邊、旋轉、去偏斜
            、亮度對比及顯示模式等掃描參數。
  引用相依:Tinifile
  方法描述:【掃描設定檔持久化管理】
            負責 FBScan.ini 設定檔的讀取與寫入作業,確保使用者的掃描偏好得以跨診次保留。
            1. 讀取模式 ('R'):從 ini 讀取空白頁刪除 (DeviceDelete)、影像反向、清黑邊、
               旋轉角度、去偏斜、亮度對比及顯示模式等參數。若設定不存在則採用系統預設值。
            2. 寫入模式 ('W'):將目前的掃描環境變數同步至 ini 檔案中。
            3. 參數對照:包含 DeviceDeleteSize (空白頁判定門檻) 及 ScanImgSetUse (是否
               覆蓋掃描器內建調校) 等關鍵邏輯開關。
============================================================================== }
Procedure TCB_IMGPSScanX.R_W_Scanini(Mode:Char); //'R'讀取;'W'寫入
var
@@ -641,9 +698,17 @@
{ ==============================================================================
  方法名稱:GetDefScanIni
  引用相依:FJpgCompression, Rotate, Scanner
  方法描述:從資料庫參數清單初始化掃描預設值。設定 DPI、雙面模式、旋轉角度、路徑、導
            引頁及分案頁代碼等關鍵系統變數。
  引用相依:GetSQLData, WORK_INF_List
  方法描述:【系統預設參數初始化】
            從資料庫的參數列表 (WORK_INF_List) 中載入系統全局掃描設定。
            1. 基礎防呆:預設 DPI 為 300,空白頁門檻為 3072 bytes。
            2. 參數對照表:遍歷 WORK_INF_List,將資料庫代碼轉化為布林值或數值。
               - SCAN_BLANKDEL_USE/SIZE: 空白頁過濾開關與大小。
               - SCAN_DPI / SCAN_DUPLEX: 掃描解析度與雙面模式。
               - SCAN_ROTATE_MODE: 定義 0, 90, 180, 270 度旋轉映射。
               - GUIDEFORMID / DIVPAGEFORMID: 定義自動分案用的表單特徵代碼。
            3. 特殊邏輯:處理進件截止時間 (ScanDenialTime) 與上傳限制 (FMaxUploadSize)
               等業務邏輯控制變數。
============================================================================== }
Procedure TCB_IMGPSScanX.GetDefScanIni; //取得掃瞄的預設值
var
@@ -825,9 +890,14 @@
{ ==============================================================================
  方法名稱:initkscan
  引用相依:Scanner, Scanner.CloseSource, Scanner.OpenSource, initkscan
  方法描述:偵測掃描器硬體能力。嘗試開啟掃描來源以檢查是否支援雙面掃描 (DuplexCap
            ),並據此啟用 UI 控制項。
  引用相依:Scanner, Scanner.CloseSource, Scanner.OpenSource
  方法描述:【掃描器硬體能力偵測】
            在掃描開始前探測掃描器支援的功能特性。
            1. UI 控制:預設關閉雙面掃描勾選框 (ScanDuplexCB)。
            2. 硬體握手:嘗試 OpenSource,成功後讀取 Scanner.DuplexCap。
            3. 動態啟用:若硬體回報 DuplexCap > 0,則動態啟用介面上的雙面掃描選項,
               供使用者勾選。
            4. 例外保護:若開啟來源失敗,則觸發 DataLoading(False,True) 並優雅結束偵測。
============================================================================== }
procedure TCB_IMGPSScanX.initkscan;
begin
reassemble/view/misc.pas
@@ -1,9 +1,16 @@
{ ==============================================================================
  方法名稱:Initialize
  引用相依:TDibGraphic
  方法描述:初始化元件狀態。註冊各類視窗與滑鼠事件處理函式(如 OnActivate, OnClick
            , OnCreate 等),並設定多項預設參數,包含 MpsKey、瀏覽窗邊界、檔案副檔名、
            案件與表單編號長度、去直線容忍值及切圖條碼類型。
  方法描述:【元件核心初始化】
            執行繼承之初始化程序並配置控制項全域參數。
            1. 事件掛載:連結 Delphi 表單生命週期事件 (OnCreate, OnDestroy, OnActivate)
               與使用者互動事件 (OnClick, OnKeyPress, MouseEnter/Leave)。
            2. 系統變數配置:
               - MpsKey: 設定通訊與加密用的金鑰 ('fbim')。
               - Seg/SafePixel: 定義檢視區域邊界與處理安全像素。
               - Ext: 預設影像副檔名為 '.tif'。
            3. 業務長度規範:設定案件編號 (16碼) 與表單編號 (15碼) 的預設辨識長度。
            4. 影像處理參數:設定去直線容忍值 (Bt=4) 與觸發 A3 裁切的特定條碼代碼 ('CC')。
============================================================================== }
procedure TCB_IMGPSScanX.Initialize;
begin
@@ -33,7 +40,8 @@
{ ==============================================================================
  方法名稱:Get_Active
  引用相依:
  方法描述:獲取元件的 Active 狀態。
  方法描述:【COM 屬性讀取:Active】
            獲取目前 ActiveX 控制項的 Active 啟動狀態,回傳 WordBool 類型。
============================================================================== }
function TCB_IMGPSScanX.Get_Active: WordBool;
begin
@@ -44,7 +52,8 @@
{ ==============================================================================
  方法名稱:Get_AlignDisabled
  引用相依:
  方法描述:獲取元件的 AlignDisabled 狀態。
  方法描述:【COM 屬性讀取:AlignDisabled】
            獲取目前控制項是否已停用對齊功能 (AlignDisabled),回傳 WordBool 類型。
============================================================================== }
function TCB_IMGPSScanX.Get_AlignDisabled: WordBool;
begin
@@ -55,7 +64,8 @@
{ ==============================================================================
  方法名稱:Get_AlignWithMargins
  引用相依:
  方法描述:獲取元件的 AlignWithMargins 狀態。
  方法描述:【COM 屬性讀取:AlignWithMargins】
            獲取控制項是否啟用邊界對齊 (AlignWithMargins) 設定。
============================================================================== }
function TCB_IMGPSScanX.Get_AlignWithMargins: WordBool;
begin
@@ -66,7 +76,8 @@
{ ==============================================================================
  方法名稱:Get_AutoScroll
  引用相依:
  方法描述:獲取元件的 AutoScroll 狀態。
  方法描述:【COM 屬性讀取:AutoScroll】
            獲取控制項是否在內容超出時自動顯示捲軸 (AutoScroll)。
============================================================================== }
function TCB_IMGPSScanX.Get_AutoScroll: WordBool;
begin
@@ -77,7 +88,8 @@
{ ==============================================================================
  方法名稱:Get_AutoSize
  引用相依:
  方法描述:獲取元件的 AutoSize 狀態。
  方法描述:【COM 屬性讀取:AutoSize】
            獲取控制項是否根據內容自動調整大小 (AutoSize)。
============================================================================== }
function TCB_IMGPSScanX.Get_AutoSize: WordBool;
begin
@@ -88,7 +100,8 @@
{ ==============================================================================
  方法名稱:Get_AxBorderStyle
  引用相依:
  方法描述:獲取元件的 AxBorderStyle 邊框樣式。
  方法描述:【COM 屬性讀取:AxBorderStyle】
            獲取 ActiveX 元件的邊框樣式,將 TxActiveFormBorderStyle 轉為 Ord 整數。
============================================================================== }
function TCB_IMGPSScanX.Get_AxBorderStyle: TxActiveFormBorderStyle;
begin
@@ -99,7 +112,8 @@
{ ==============================================================================
  方法名稱:Get_Caption
  引用相依:
  方法描述:獲取元件的標題文字。
  方法描述:【COM 屬性讀取:Caption】
            獲取目前控制項的標題文字,轉換為 WideString 格式以符合 COM 標準。
============================================================================== }
function TCB_IMGPSScanX.Get_Caption: WideString;
begin
@@ -110,7 +124,8 @@
{ ==============================================================================
  方法名稱:Get_Color
  引用相依:
  方法描述:獲取元件的背景顏色。
  方法描述:【COM 屬性讀取:Color】
            獲取目前控制項的背景顏色,轉換為 OLE_COLOR 數值格式。
============================================================================== }
function TCB_IMGPSScanX.Get_Color: OLE_COLOR;
begin
@@ -121,7 +136,8 @@
{ ==============================================================================
  方法名稱:Get_DockSite
  引用相依:
  方法描述:獲取元件的 DockSite 狀態。
  方法描述:【COM 屬性讀取:DockSite】
            獲取目前控制項是否作為停靠站 (DockSite) 接收其他元件。
============================================================================== }
function TCB_IMGPSScanX.Get_DockSite: WordBool;
begin
@@ -132,7 +148,8 @@
{ ==============================================================================
  方法名稱:Get_DoubleBuffered
  引用相依:
  方法描述:獲獲取元件的 DoubleBuffered 狀態。
  方法描述:【COM 屬性讀取:DoubleBuffered】
            獲取控制項是否啟用雙重緩衝繪圖 (DoubleBuffered) 以減少閃爍。
============================================================================== }
function TCB_IMGPSScanX.Get_DoubleBuffered: WordBool;
begin
@@ -143,7 +160,8 @@
{ ==============================================================================
  方法名稱:Get_DropTarget
  引用相依:
  方法描述:獲取元件的 DropTarget 狀態。
  方法描述:【COM 屬性讀取:DropTarget】
            獲取控制項是否作為拖放目標 (DropTarget) 接收外部檔案或物件。
============================================================================== }
function TCB_IMGPSScanX.Get_DropTarget: WordBool;
begin
@@ -154,7 +172,8 @@
{ ==============================================================================
  方法名稱:Get_Enabled
  引用相依:
  方法描述:獲取元件的啟用狀態。
  方法描述:【COM 屬性讀取:Enabled】
            獲取控制項目前的啟用或禁用狀態。
============================================================================== }
function TCB_IMGPSScanX.Get_Enabled: WordBool;
begin
@@ -165,7 +184,8 @@
{ ==============================================================================
  方法名稱:Get_ExplicitHeight
  引用相依:
  方法描述:獲取元件的明確高度。
  方法描述:【COM 屬性讀取:ExplicitHeight】
            獲取控制項在設計階段或被強制指定的明確高度數值。
============================================================================== }
function TCB_IMGPSScanX.Get_ExplicitHeight: Integer;
begin
@@ -176,7 +196,8 @@
{ ==============================================================================
  方法名稱:Get_ExplicitLeft
  引用相依:
  方法描述:獲取元件的明確左座標。
  方法描述:【COM 屬性讀取:ExplicitLeft】
            獲取控制項相對於父容器的明確左方位置。
============================================================================== }
function TCB_IMGPSScanX.Get_ExplicitLeft: Integer;
begin
@@ -187,7 +208,8 @@
{ ==============================================================================
  方法名稱:Get_ExplicitTop
  引用相依:
  方法描述:獲取元件的明確頂座標。
  方法描述:【COM 屬性讀取:ExplicitTop】
            獲取控制項相對於父容器的明確上方位置。
============================================================================== }
function TCB_IMGPSScanX.Get_ExplicitTop: Integer;
begin
@@ -198,7 +220,8 @@
{ ==============================================================================
  方法名稱:Get_ExplicitWidth
  引用相依:
  方法描述:獲取元件的明確寬度。
  方法描述:【COM 屬性讀取:ExplicitWidth】
            獲取控制項目前的明確寬度數值。
============================================================================== }
function TCB_IMGPSScanX.Get_ExplicitWidth: Integer;
begin
@@ -209,7 +232,8 @@
{ ==============================================================================
  方法名稱:Get_Font
  引用相依:
  方法描述:獲取元件的字型。
  方法描述:【COM 屬性讀取:Font】
            利用 GetOleFont 將 Delphi VCL 字型物件轉換為 COM 標準的 IFontDisp 介面。
============================================================================== }
function TCB_IMGPSScanX.Get_Font: IFontDisp;
begin
@@ -220,7 +244,8 @@
{ ==============================================================================
  方法名稱:Get_HelpFile
  引用相依:
  方法描述:獲取元件的說明檔路徑。
  方法描述:【COM 屬性讀取:HelpFile】
            獲取目前元件關連的說明文件檔案路徑。
============================================================================== }
function TCB_IMGPSScanX.Get_HelpFile: WideString;
begin
@@ -231,7 +256,8 @@
{ ==============================================================================
  方法名稱:Get_KeyPreview
  引用相依:
  方法描述:獲取元件的鍵盤預覽狀態。
  方法描述:【COM 屬性讀取:KeyPreview】
            獲取控制項是否優先攔截鍵盤事件 (KeyPreview) 再傳送至子元件。
============================================================================== }
function TCB_IMGPSScanX.Get_KeyPreview: WordBool;
begin
@@ -242,7 +268,8 @@
{ ==============================================================================
  方法名稱:Get_MouseInClient
  引用相依:
  方法描述:獲取滑鼠是否在元件內部區域。
  方法描述:【COM 屬性讀取:MouseInClient】
            動態獲取滑鼠目前是否正處於控制項的客戶區域 (Client Area) 內。
============================================================================== }
function TCB_IMGPSScanX.Get_MouseInClient: WordBool;
begin
@@ -253,7 +280,8 @@
{ ==============================================================================
  方法名稱:Get_ParentCustomHint
  引用相依:
  方法描述:獲取元件的 ParentCustomHint 狀態。
  方法描述:【COM 屬性讀取:ParentCustomHint】
            獲取元件是否繼承父視窗的自定義提示訊息設定。
============================================================================== }
function TCB_IMGPSScanX.Get_ParentCustomHint: WordBool;
begin
@@ -264,7 +292,8 @@
{ ==============================================================================
  方法名稱:Get_ParentDoubleBuffered
  引用相依:
  方法描述:獲取元件的 ParentDoubleBuffered 狀態。
  方法描述:【COM 屬性讀取:ParentDoubleBuffered】
            獲取元件是否繼承父視窗的雙重緩衝繪圖設定。
============================================================================== }
function TCB_IMGPSScanX.Get_ParentDoubleBuffered: WordBool;
begin
@@ -275,7 +304,8 @@
{ ==============================================================================
  方法名稱:Get_PixelsPerInch
  引用相依:
  方法描述:獲取元件的 PixelsPerInch 設定。
  方法描述:【COM 屬性讀取:PixelsPerInch】
            獲取控制項目前設定的 DPI 解析度 (每英吋像素數)。
============================================================================== }
function TCB_IMGPSScanX.Get_PixelsPerInch: Integer;
begin
@@ -286,7 +316,8 @@
{ ==============================================================================
  方法名稱:Get_PopupMode
  引用相依:
  方法描述:獲取元件的彈出視窗模式。
  方法描述:【COM 屬性讀取:PopupMode】
            獲取控制項的彈出視窗行為模式 (如 Auto, Explicit, MainForm)。
============================================================================== }
function TCB_IMGPSScanX.Get_PopupMode: TxPopupMode;
begin
@@ -297,7 +328,8 @@
{ ==============================================================================
  方法名稱:Get_PrintScale
  引用相依:
  方法描述:獲取元件的列印縮放比例。
  方法描述:【COM 屬性讀取:PrintScale】
            獲取控制項在執行列印動作時的預設縮放比例設定。
============================================================================== }
function TCB_IMGPSScanX.Get_PrintScale: TxPrintScale;
begin
@@ -308,7 +340,8 @@
{ ==============================================================================
  方法名稱:Get_Scaled
  引用相依:
  方法描述:獲取元件的 Scaled 縮放狀態。
  方法描述:【COM 屬性讀取:Scaled】
            獲取控制項是否隨系統字型或 DPI 進行自動縮放調整。
============================================================================== }
function TCB_IMGPSScanX.Get_Scaled: WordBool;
begin
@@ -319,7 +352,8 @@
{ ==============================================================================
  方法名稱:Get_ScreenSnap
  引用相依:
  方法描述:獲取元件的 ScreenSnap 狀態。
  方法描述:【COM 屬性讀取:ScreenSnap】
            獲取視窗是否啟動靠近螢幕邊界自動吸附功能。
============================================================================== }
function TCB_IMGPSScanX.Get_ScreenSnap: WordBool;
begin
@@ -330,7 +364,8 @@
{ ==============================================================================
  方法名稱:Get_SnapBuffer
  引用相依:
  方法描述:獲取元件的 SnapBuffer 設定。
  方法描述:【COM 屬性讀取:SnapBuffer】
            獲取視窗吸附功能作用的像素緩衝區距離。
============================================================================== }
function TCB_IMGPSScanX.Get_SnapBuffer: Integer;
begin
@@ -341,7 +376,8 @@
{ ==============================================================================
  方法名稱:Get_UseDockManager
  引用相依:
  方法描述:獲取元件是否使用 Dock 管理。
  方法描述:【COM 屬性讀取:UseDockManager】
            獲取控制項是否由 Dock Manager 統一管理停靠介面。
============================================================================== }
function TCB_IMGPSScanX.Get_UseDockManager: WordBool;
begin
@@ -352,7 +388,8 @@
{ ==============================================================================
  方法名稱:Get_Visible
  引用相依:
  方法描述:獲取元件的顯示狀態。
  方法描述:【COM 屬性讀取:Visible】
            獲取控制項目前在介面上是否處於可見狀態。
============================================================================== }
function TCB_IMGPSScanX.Get_Visible: WordBool;
begin
@@ -363,7 +400,8 @@
{ ==============================================================================
  方法名稱:Get_VisibleDockClientCount
  引用相依:
  方法描述:獲取元件的可見 Dock 客戶端數量。
  方法描述:【COM 屬性讀取:VisibleDockClientCount】
            獲取目前已停靠在控制項上的可見客戶端數量。
============================================================================== }
function TCB_IMGPSScanX.Get_VisibleDockClientCount: Integer;
begin
@@ -374,7 +412,9 @@
{ ==============================================================================
  方法名稱:_Set_Font
  引用相依:
  方法描述:設定元件的字型。
  方法描述:【COM 屬性設定:Font】
            利用 SetOleFont 將傳入的 COM IFontDisp 介面轉換並套用至元件的 VCL
            Font 屬性。
============================================================================== }
procedure TCB_IMGPSScanX._Set_Font(var Value: IFontDisp);
begin
@@ -384,9 +424,11 @@
{ ==============================================================================
  方法名稱:mode1Click
  引用相依:
  方法描述:切換至檢視模式 0(單頁顯示),呼叫 GoViewMode 更新佈局,並隱藏 Panel14
            控制面版。
  引用相依:GoViewMode
  方法描述:【切換至單頁檢視模式】
            1. 設定檢視模式索引 VMode := 0。
            2. 呼叫 GoViewMode 重新計算並排列影像顯示容器。
            3. 隱藏影像微調控制面板 (Panel14)。
============================================================================== }
procedure TCB_IMGPSScanX.mode1Click(Sender: TObject);
begin
@@ -399,9 +441,11 @@
{ ==============================================================================
  方法名稱:mode2Click
  引用相依:
  方法描述:切換至檢視模式 1(兩頁顯示),呼叫 GoViewMode 更新佈局,並顯示 Panel14
            控制面版。
  引用相依:GoViewMode
  方法描述:【切換至雙頁檢視模式】
            1. 設定檢視模式索引 VMode := 1。
            2. 呼叫 GoViewMode 重新排列影像顯示容器,實現左右對照佈局。
            3. 顯示影像微調控制面板 (Panel14),提供對比與亮度調整。
============================================================================== }
procedure TCB_IMGPSScanX.mode2Click(Sender: TObject);
begin
@@ -414,9 +458,11 @@
{ ==============================================================================
  方法名稱:mode3Click
  引用相依:
  方法描述:切換至檢視模式 2(多頁網格顯示),呼叫 GoViewMode 更新佈局,並觸發捲軸變
            動以重新載入影像。
  引用相依:GoViewMode, ScrollBar1Change
  方法描述:【切換至 2x2 網格檢視模式】
            1. 設定檢視模式索引 VMode := 2。
            2. 呼叫 GoViewMode 排列為 2x2 的顯示格位。
            3. 觸發 ScrollBar1Change 以根據當前捲軸位置重新載入並顯示影像預覽。
============================================================================== }
procedure TCB_IMGPSScanX.mode3Click(Sender: TObject);
begin
@@ -428,9 +474,11 @@
{ ==============================================================================
  方法名稱:mode4Click
  引用相依:
  方法描述:切換至檢視模式 3(自定義檢視模式),呼叫 GoViewMode 更新佈局,並觸發捲軸
            變動以重新載入影像。
  引用相依:GoViewMode, ScrollBar1Change
  方法描述:【切換至 2x3 網格檢視模式】
            1. 設定檢視模式索引 VMode := 3。
            2. 呼叫 GoViewMode 排列為 2x3 的多頁顯示格位。
            3. 觸發 ScrollBar1Change 同步更新顯示內容。
============================================================================== }
procedure TCB_IMGPSScanX.mode4Click(Sender: TObject);
begin
@@ -443,7 +491,8 @@
{ ==============================================================================
  方法名稱:Set_AlignWithMargins
  引用相依:
  方法描述:設定元件的 AlignWithMargins 屬性。
  方法描述:【COM 屬性寫入:AlignWithMargins】
            同步更新 VCL 控制項的邊距對齊設定。
============================================================================== }
procedure TCB_IMGPSScanX.Set_AlignWithMargins(Value: WordBool);
begin
@@ -454,7 +503,8 @@
{ ==============================================================================
  方法名稱:Set_AutoScroll
  引用相依:
  方法描述:設定元件的 AutoScroll 屬性。
  方法描述:【COM 屬性寫入:AutoScroll】
            同步更新控制項是否自動啟用內容捲動條。
============================================================================== }
procedure TCB_IMGPSScanX.Set_AutoScroll(Value: WordBool);
begin
@@ -465,7 +515,8 @@
{ ==============================================================================
  方法名稱:Set_AutoSize
  引用相依:
  方法描述:設定元件的 AutoSize 屬性。
  方法描述:【COM 屬性寫入:AutoSize】
            同步更新控制項是否根據子元件佈局自動調整外部大小。
============================================================================== }
procedure TCB_IMGPSScanX.Set_AutoSize(Value: WordBool);
begin
@@ -476,7 +527,8 @@
{ ==============================================================================
  方法名稱:Set_AxBorderStyle
  引用相依:
  方法描述:設定元件的 AxBorderStyle 屬性。
  方法描述:【COM 屬性寫入:AxBorderStyle】
            設定 ActiveX 控制項的邊框風格,執行 Ord 整數與列舉值的轉換。
============================================================================== }
procedure TCB_IMGPSScanX.Set_AxBorderStyle(Value: TxActiveFormBorderStyle);
begin
@@ -487,7 +539,8 @@
{ ==============================================================================
  方法名稱:Set_Caption
  引用相依:
  方法描述:設定元件的標題文字。
  方法描述:【COM 屬性寫入:Caption】
            接收 COM 傳入的 WideString 並套用至控制項標題。
============================================================================== }
procedure TCB_IMGPSScanX.Set_Caption(const Value: WideString);
begin
@@ -498,7 +551,8 @@
{ ==============================================================================
  方法名稱:Set_Color
  引用相依:
  方法描述:設定元件的背景顏色。
  方法描述:【COM 屬性寫入:Color】
            將 OLE_COLOR 值轉換為 VCL TColor 並更新背景色。
============================================================================== }
procedure TCB_IMGPSScanX.Set_Color(Value: OLE_COLOR);
begin
@@ -509,7 +563,8 @@
{ ==============================================================================
  方法名稱:Set_DockSite
  引用相依:
  方法描述:設定元件的 DockSite 屬性。
  方法描述:【COM 屬性寫入:DockSite】
            動態啟用或關閉控制項的停靠容器特性。
============================================================================== }
procedure TCB_IMGPSScanX.Set_DockSite(Value: WordBool);
begin
@@ -520,7 +575,8 @@
{ ==============================================================================
  方法名稱:Set_DoubleBuffered
  引用相依:
  方法描述:設定元件的 DoubleBuffered 屬性。
  方法描述:【COM 屬性寫入:DoubleBuffered】
            切換繪圖緩衝模式,用於優化大量影像捲動時的流暢度。
============================================================================== }
procedure TCB_IMGPSScanX.Set_DoubleBuffered(Value: WordBool);
begin
@@ -531,7 +587,8 @@
{ ==============================================================================
  方法名稱:Set_DropTarget
  引用相依:
  方法描述:設定元件的 DropTarget 屬性。
  方法描述:【COM 屬性寫入:DropTarget】
            啟用或禁用控制項接收檔案拖放的功能。
============================================================================== }
procedure TCB_IMGPSScanX.Set_DropTarget(Value: WordBool);
begin
@@ -542,7 +599,8 @@
{ ==============================================================================
  方法名稱:Set_Enabled
  引用相依:
  方法描述:設定元件的啟用狀態。
  方法描述:【COM 屬性寫入:Enabled】
            控制 ActiveX 控制項及其所有子視窗的互動狀態。
============================================================================== }
procedure TCB_IMGPSScanX.Set_Enabled(Value: WordBool);
begin
@@ -553,7 +611,8 @@
{ ==============================================================================
  方法名稱:Set_Font
  引用相依:
  方法描述:設定元件的字型。
  方法描述:【COM 屬性寫入:Font】
            利用 SetOleFont 轉換介面指標並同步更新全域字型設定。
============================================================================== }
procedure TCB_IMGPSScanX.Set_Font(const Value: IFontDisp);
begin
@@ -564,7 +623,8 @@
{ ==============================================================================
  方法名稱:Set_HelpFile
  引用相依:
  方法描述:設定元件的說明檔路徑。
  方法描述:【COM 屬性寫入:HelpFile】
            設定與系統說明按鈕關連的本地或網路路徑。
============================================================================== }
procedure TCB_IMGPSScanX.Set_HelpFile(const Value: WideString);
begin
@@ -575,7 +635,8 @@
{ ==============================================================================
  方法名稱:Set_KeyPreview
  引用相依:
  方法描述:設定元件的鍵盤預覽狀態。
  方法描述:【COM 屬性寫入:KeyPreview】
            配置鍵盤攔截優先權。
============================================================================== }
procedure TCB_IMGPSScanX.Set_KeyPreview(Value: WordBool);
begin
@@ -586,7 +647,8 @@
{ ==============================================================================
  方法名稱:Set_ParentCustomHint
  引用相依:
  方法描述:設定元件的 ParentCustomHint 屬性。
  方法描述:【COM 屬性寫入:ParentCustomHint】
            設定是否跟隨父層元件的提示外觀。
============================================================================== }
procedure TCB_IMGPSScanX.Set_ParentCustomHint(Value: WordBool);
begin
@@ -597,7 +659,8 @@
{ ==============================================================================
  方法名稱:Set_ParentDoubleBuffered
  引用相依:
  方法描述:設定元件的 ParentDoubleBuffered 屬性。
  方法描述:【COM 屬性寫入:ParentDoubleBuffered】
            設定是否跟隨父層元件的緩衝繪圖邏輯。
============================================================================== }
procedure TCB_IMGPSScanX.Set_ParentDoubleBuffered(Value: WordBool);
begin
@@ -608,7 +671,8 @@
{ ==============================================================================
  方法名稱:Set_PixelsPerInch
  引用相依:
  方法描述:設定元件的 PixelsPerInch 屬性。
  方法描述:【COM 屬性寫入:PixelsPerInch】
            設定控制項的設計參考解析度。
============================================================================== }
procedure TCB_IMGPSScanX.Set_PixelsPerInch(Value: Integer);
begin
@@ -619,7 +683,8 @@
{ ==============================================================================
  方法名稱:Set_PopupMode
  引用相依:
  方法描述:設定元件的彈出視窗模式。
  方法描述:【COM 屬性寫入:PopupMode】
            設定 ActiveX 內嵌視窗的彈出層級行為。
============================================================================== }
procedure TCB_IMGPSScanX.Set_PopupMode(Value: TxPopupMode);
begin
@@ -685,7 +750,8 @@
{ ==============================================================================
  方法名稱:Set_Visible
  引用相依:
  方法描述:設定元件的顯示狀態。
  方法描述:【COM 屬性寫入:Visible】
            直接控制 ActiveX 元件在瀏覽器中的呈現與隱藏。
============================================================================== }
procedure TCB_IMGPSScanX.Set_Visible(Value: WordBool);
begin
@@ -695,9 +761,12 @@
{ ==============================================================================
  方法名稱:N1Click
  引用相依:
  方法描述:彈出對話框要求使用者輸入目標頁碼,呼叫 MoveImage 將當前顯示的影像移動
            到指定的位置。
  引用相依:InputBox, MoveImage, strtoint
  方法描述:【執行影像頁碼搬移】
            當使用者點選選單中的「移動頁數」時:
            1. 彈出 InputBox 詢問目標頁碼。
            2. 若輸入有效數值,呼叫 MoveImage 將目前選中的影像檔案實體搬移至指定
               序號位置,實現影像重排序功能。
============================================================================== }
procedure TCB_IMGPSScanX.N1Click(Sender: TObject);
var
@@ -713,9 +782,11 @@
{ ==============================================================================
  方法名稱:N51Click
  引用相依:
  方法描述:切換至檢視模式 4,呼叫 GoViewMode 更新佈局,並觸發捲軸變動以重新載入影
            像。
  引用相依:GoViewMode, ScrollBar1Change
  方法描述:【切換至 2x4 網格檢視模式】
            1. 設定檢視模式索引 VMode := 4。
            2. 呼叫 GoViewMode 排列為 2x4 的多頁緊湊顯示佈局。
            3. 更新捲軸狀態以重繪影像。
============================================================================== }
procedure TCB_IMGPSScanX.N51Click(Sender: TObject);
begin
@@ -728,7 +799,8 @@
{ ==============================================================================
  方法名稱:Panel11DblClick
  引用相依:
  方法描述:Panel11 的連按兩下事件,目前實作已註解掉。
  方法描述:【輔助控制面板雙擊事件】
            目前實作為預留空殼,用於未來擴充按鈕顯示或自定義文件模式切換。
============================================================================== }
procedure TCB_IMGPSScanX.Panel11DblClick(Sender: TObject);
begin
@@ -741,7 +813,9 @@
{ ==============================================================================
  方法名稱:Panel1DblClick
  引用相依:
  方法描述:Panel1 的連按兩下事件,用於切換 Button1 與 Button2 的顯示狀態。
  方法描述:【工程師隱藏開關】
            連按兩下 Panel1 會切換 Button1 與 Button2 的顯示狀態,這通常是用於開發
            者測試用的隱藏偵錯按鈕。
============================================================================== }
procedure TCB_IMGPSScanX.Panel1DblClick(Sender: TObject);
begin
@@ -752,8 +826,10 @@
{ ==============================================================================
  方法名稱:Panel9Resize
  引用相依:
  方法描述:當 Panel9 大小改變時,呼叫 GoViewMode 重新調整影像佈局。
  引用相依:GoViewMode
  方法描述:【佈局自適應調整】
            當主顯示面板 Panel9 大小改變(如縮放視窗)時,觸發 GoViewMode 重新計算
            格位大小,確保影像顯示視窗能填滿可用空間。
============================================================================== }
procedure TCB_IMGPSScanX.Panel9Resize(Sender: TObject);
begin
@@ -763,10 +839,12 @@
{ ==============================================================================
  方法名稱:DocNoIsExistImg
  引用相依:FileExists, LoadFromFile
  方法描述:檢查指定的文件目錄路徑下是否存在影像檔案。首先讀取目錄中的 Context.da
            t 檔案,接著遍歷清單中的所有檔名並檢查實際檔案是否存在。若發現任何一個
            影像檔案存在則回傳 False(表示非空),否則回傳 True。
  引用相依:FileExists, ISExistImg, TStringList
  方法描述:【文件目錄影像存在性判定】
            1. 檢查目標路徑下的索引檔 Context.dat。
            2. 遍歷索引中紀錄的所有影像檔案。
            3. 若發現任何一個影像檔案實際存在於磁碟上,則回傳 False(代表非空)。
            4. 僅當目錄內完全無對應影像檔時回傳 True,用於目錄清理與空箱判定。
============================================================================== }
function TCB_IMGPSScanX.DocNoIsExistImg(DocNopath:String):boolean;
var
@@ -795,8 +873,9 @@
{ ==============================================================================
  方法名稱:_DelTreeForExistImg
  引用相依:_DelTree
  方法描述:存根方法,目前未包含具體實作邏輯。
  引用相依:
  方法描述:【根據影像存在狀態執行目錄清理】
            目前為空實作,預留供未來實施「僅刪除空目錄」或「條件式刪除案件」時使用。
============================================================================== }
procedure TCB_IMGPSScanX._DelTreeForExistImg(ASourceDir:String);
var
@@ -809,8 +888,11 @@
{ ==============================================================================
  方法名稱:ScrollBar1Change
  引用相依:
  方法描述:捲軸變動處理,目前實作已透過 Exit 暫時停用。
  引用相依:view_image_FormCode
  方法描述:【檢視捲軸變動同步處理】
            當使用者拖曳捲軸時,依據目前在 TreeView 選中的節點層級(案件、文件或單頁)
            計算偏移量,並呼叫 view_image_FormCode 進行批次影像重載與預覽。
            註:目前代碼開頭有 Exit,代表此同步載入機制暫時處於停用狀態。
============================================================================== }
procedure TCB_IMGPSScanX.ScrollBar1Change(Sender: TObject);
begin
@@ -833,10 +915,12 @@
{ ==============================================================================
  方法名稱:ActiveFormKeyUp
  引用相依:
  方法描述:處理 ActiveForm 按鍵放開事件。當文字輸入框取得焦點且有選取影像時,攔截
            上下方向鍵並將其轉化為 PriorPage 或 NextPage 翻頁操作,並同步滾動捲軸
            。
  引用相依:NextPage, PriorPage
  方法描述:【鍵盤翻頁快捷鍵攔截】
            當焦點位於頁碼輸入框 (Edit1) 且有影像被選取時:
            1. 偵測到 VK_UP:呼叫 PriorPage 跳至上一頁,並同步滾動捲軸向上。
            2. 偵測到 VK_Down:呼叫 NextPage 跳至下一頁,並同步滾動捲軸向下。
            實現流暢的鍵盤影像瀏覽體驗。
============================================================================== }
procedure TCB_IMGPSScanX.ActiveFormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
@@ -867,10 +951,14 @@
{ ==============================================================================
  方法名稱:AddAttFileLBClick
  引用相依:CopyFile, FileExists
  方法描述:處理「加入附加電子檔」按鈕點擊。開啟檔案對話框選取多個 PDF 檔案,支援覆
            蓋檢查。執行 CopyFile 將檔案複製到案件目錄下,並呼叫 SetAttContextList
             更新附加檔案清單後載入顯示。
  引用相依:CopyFile, DataLoading, FileExists, HTTPEncode, LoadAttFile,
            Messagedlg, OpenDialog1, SetAttContextList, UTF8Encode
  方法描述:【加入附加 PDF 電子檔】
            1. 呼叫 OpenDialog 選取多個 PDF 檔案。
            2. 遍歷選取的檔案,執行 URL 編碼處理檔名。
            3. 若檔案已存在於案件目錄,提示使用者是否覆蓋。
            4. 使用 CopyFile 將實體檔案複製到案件目錄。
            5. 調用 SetAttContextList 紀錄附件索引,最後呼叫 LoadAttFile 刷新顯示。
============================================================================== }
procedure TCB_IMGPSScanX.AddAttFileLBClick(Sender: TObject);
var
@@ -905,8 +993,12 @@
{ ==============================================================================
  方法名稱:AddCredit1RGClick
  引用相依:
  方法描述:處理信用註記點擊,更新 Case_loandoc 狀態並寫入索引檔。
  引用相依:WriteCaseIndex
  方法描述:【更新信用資訊註記】
            當使用者變更信用註記 RadioGroup 時:
            1. 映射 Index 為 'Y', 'N' 或空字串。
            2. 更新 Case_loandoc 變數。
            3. 呼叫 WriteCaseIndex 立即將此註記同步至本地案件索引檔中。
============================================================================== }
procedure TCB_IMGPSScanX.AddCredit1RGClick(Sender: TObject);
begin
@@ -924,8 +1016,10 @@
{ ==============================================================================
  方法名稱:BtnMouseEnter
  引用相依:
  方法描述:當滑鼠進入按鈕區域時,顯示該按鈕的 Hint 文字提示。
  引用相依:AddToolTip
  方法描述:【按鈕 Hint 文字氣泡提示】
            利用 Windows API 的 ToolTip 機制,在滑鼠滑過 BitBtn 時,將其 Hint 屬性
            的內容動態顯示在浮動視窗中,增強介面引導。
============================================================================== }
procedure TCB_IMGPSScanX.BtnMouseEnter(Sender: TObject);
begin
reassemble/view/popupMenu.pas
@@ -1,11 +1,14 @@
{ ==============================================================================
  方法名稱:PM401Click
  引用相依:FileExists, GetNoNameCase, LoadFromFile, RenameFile, SaveToFile, Str
            2Dir
  方法描述:影像列表右鍵選單功能:從指定頁面分出新案。確認使用者選取的分案起點(不
            能為第一頁)後,取得新的流水案號並建立目錄。將原案件中該頁碼之後的所有
            影像檔案更名並搬移至新案目錄,同步更新原案與新案的 Context.dat 與 Cas
            eIndex.dat。完成後重新載入影像列表並提示完成。
  引用相依:GetNoNameCase, ReNameFile, SetCaseList, WriteCaseIndex, FileName2NoQuene_Filename
  方法描述:【執行影像分案作業】
            將目前案件中選取頁面之後的所有影像拆分至一個新案件中。
            1. 檢查:禁止從第一頁開始分案。
            2. 目錄準備:取得新流水案號 (GetNoNameCase) 並建立實體目錄。
            3. 檔案遷移:遍歷 ContextList,將目標索引後的檔案實體更名搬移至新路徑。
            4. 索引更新:同步扣除原案件的 Context 紀錄,並為新案件產生 Context.dat。
            5. 資料複製:將原案的經辦資訊 (CaseIndex.dat) 繼承至新案。
            6. 結構同步:將新案加入全域案件清單 (SetCaseList) 並重載介面。
============================================================================== }
procedure TCB_IMGPSScanX.PM401Click(Sender: TObject);
var
@@ -96,11 +99,12 @@
{ ==============================================================================
  方法名稱:PM404Click
  引用相依:
  方法描述:影像列表右鍵選單功能:文件歸類。開啟 TDocListForm 顯示可用的表單清單供
            使用者選擇。確認後根據當前 TreeView 的選取層級(案件級別、文件級別或特
            定表單),呼叫 PageReplaceFormID 將影像重新歸類至選定的表單類型。歸類完
            成後重新繪製樹狀結構並清空檢核記錄,最後回到原先選取的節點。
  引用相依:TDocListForm, PageReplaceFormID, DrawDocItem2, ClearErrini
  方法描述:【影像列表:執行文件歸類】
            1. 選單展示:開啟 TDocListForm,由 FORM_INF_List 中過濾目前有效的表單。
            2. 層級識別:根據 TreeView 選取的 Level(案件、文件或表單)決定替換範圍。
            3. 批量替換:呼叫 PageReplaceFormID 執行所有選中影像的 FormID 修正。
            4. 結構重繪:歸類完成後重新繪製樹狀圖並清空歷史檢核錯誤標記。
============================================================================== }
procedure TCB_IMGPSScanX.PM404Click(Sender: TObject);
var
@@ -174,13 +178,15 @@
{ ==============================================================================
  方法名稱:PM601Click
  引用相依:CopyFile, DeleteImageFile, DirectoryExists, FileExists, LoadFromFile
            , ReSortFileName, RenameFile, SaveToFile
  方法描述:縮圖瀏覽區右鍵選單功能:文件歸類。針對所有被選取(由 Shape 標記)的影像,
            開啟 TDocListForm 選擇目標表單。核心邏輯包含:判斷目標文件是否需要區分
            份數、自動產生新的文件目錄或沿用既有目錄、根據檔案序號產生新檔名、執行
            檔案複製並更新 ContextList。最後刪除原檔案、重新排序原目錄並重新繪製樹
            狀結構。
  引用相依:FindLastestDocDir, SetDocNoList, SetContextList, DeleteImageFile, ReSortFileName
  方法描述:【縮圖區域:執行選中影像歸類】
            針對縮圖預覽區選中的所有標記影像執行批次表單分類。
            1. 分類判定:開啟表單選擇清單,取得目標 FormID 與 DocNo。
            2. 目錄決策:判斷目標文件是否需分份 (DocNoNeedDiv),據此建立新目錄或
               沿用現有目錄。
            3. 檔案遷移:將選中影像複製到目標目錄,並依序產出新的序號檔名。
            4. 索引維護:更新目標目錄與原目錄的 Context.dat,並執行實體刪除原檔案。
            5. UI 同步:重新排序受影響的目錄,並刷新 TreeView。
============================================================================== }
procedure TCB_IMGPSScanX.PM601Click(Sender: TObject);
var
@@ -339,12 +345,13 @@
{ ==============================================================================
  方法名稱:PM602Click
  引用相依:CopyFile, DeleteImageFile, FileExists, LoadFromFile, ReSortFileName,
             SaveToFile, Str2Dir
  方法描述:縮圖瀏覽區右鍵選單功能:歸類至自定義文件。彈出對話框要求使用者輸入新文
            件名稱,檢核名稱是否重複後產生新的自定義文件編號。接著將所有選取的影像
            複製到新建立的文件目錄下,更新 ContextList並刪除原檔案。最後重新排序並
            刷新樹狀顯示。
  引用相依:GetNewCustomDocNo, SetDocNoList, SetContextList, DeleteImageFile, ReSortFileName
  方法描述:【縮圖區域:歸類至自定義文件】
            將選取的影像歸類至使用者自行命名的文件類別中。
            1. 名稱設定:彈出對話框詢問名稱,並檢查是否與現有文件衝突。
            2. 代號分配:呼叫 GetNewCustomDocNo 配發 ZZZZZ 或 YYYYY 編號。
            3. 檔案遷移:建立實體目錄,複製選中影像並產生對應的偽表單檔名。
            4. 清理與重繪:執行原目錄檔案刪除與排序,更新樹狀結構統計。
============================================================================== }
procedure TCB_IMGPSScanX.PM602Click(Sender: TObject);
var
@@ -458,10 +465,13 @@
{ ==============================================================================
  方法名稱:PM605Click
  引用相依:DeleteImageFile, ReSortFileName
  方法描述:縮圖瀏覽區右鍵選單功能:刪除影像。在使用者確認後,遍歷所有選取的影像元
            件,呼叫 DeleteImageFile 刪除實際檔案。刪除完成後,執行檔案重新排序(ReS
            ortFileName),更新樹狀結構上的頁數統計文字,並刷新顯示。
  引用相依:DeleteImageFile, ReSortFileName, NewTreeNodeRefresh, ClearErrini
  方法描述:【縮圖區域:批量刪除影像】
            執行物理刪除並同步系統索引。
            1. 確認:彈出對話框確認刪除意圖。
            2. 迭代刪除:遍歷所有標記 (Shape) 的影像,呼叫 DeleteImageFile 移除檔案。
            3. 重整:執行 ReSortFileName 重新整理目錄序號。
            4. 連動:更新案件總頁數標籤,清空檢核記錄,並重載 TreeView 層級。
============================================================================== }
procedure TCB_IMGPSScanX.PM605Click(Sender: TObject);
var
@@ -504,11 +514,15 @@
{ ==============================================================================
  方法名稱:PM101Click
  引用相依:DeleteDocNoFile, DirectoryExists, _DelTree
  方法描述:處理樹狀結構(TreeView)的右鍵刪除選單。根據選取的節點類型(新掃瞄件、案
            件、文件或表單)執行不同範圍的刪除:包含刪除實體目錄、清空影像清單、更新
            案件索引及檢核記錄。針對異動模式(ESCAN),若刪除後無影像則會重建空案件
            以維持結構。
  引用相依:DeleteDocNoFileForESCAN, DeleteFormCodeFile, SetCaseList, SetDocNoList, _DelTree, ClearErrini
  方法描述:【樹狀結構:多層級刪除處理】
            根據 TreeView 目前選取的節點深度執行聯動刪除:
            1. 根節點 (NewTreeNode):刪除本地所有案件暂存。
            2. 案件節點 (Level 1):刪除該案目錄並從案件清單中移除。
            3. 文件節點 (Level 2):刪除特定類別目錄。若為補件模式 (ESCAN),呼叫
               DeleteDocNoFileForESCAN 僅刪除當次新掃影像以保護舊檔。
            4. 表單節點 (Level 3):呼叫 DeleteFormCodeFile 刪除單一表單的所有頁面。
            所有操作均會同步執行 ReSortFileName 與筆數統計重新計算。
============================================================================== }
procedure TCB_IMGPSScanX.PM101Click(Sender: TObject);
var
@@ -618,10 +632,13 @@
{ ==============================================================================
  方法名稱:PM102Click
  引用相依:DirectoryExists, RenameFile
  方法描述:處理「修改案件編號」右鍵選單。彈出輸入盒要求輸入新編號並驗證長度與是否
            重複。確認修改後,先清空當前影像顯示,接著執行磁碟目錄更名並更新案件清
            單文字。最後重新繪製該案件的文件樹狀結構並提示完成。
  引用相依:RenameFile, SetCaseList, DrawDocItem2, ClearView
  方法描述:【變更案件編號】
            1. 檢查:確認輸入的新案號符合長度規範且無重複。
            2. 同步:清除當前影像預覽以釋放檔案鎖定。
            3. 更名:執行 RenameFile 進行磁碟目錄重新命名。
            4. 索引維護:呼叫 SetCaseList 更新本地全域案件清單文字。
            5. UI 重繪:更新樹狀結構頂層文字並重新繪製子節點。
============================================================================== }
procedure TCB_IMGPSScanX.PM102Click(Sender: TObject);
var
@@ -713,16 +730,16 @@
{ ==============================================================================
  方法名稱:PM104Click
  引用相依:CheckNeedCrop, ConvertToBW, ConvertToGray, CropImg, DeskewImg, Direc
            toryExists, FJpgCompression, FileExists, FindFirst, GetNoNameCase, L
            oadFromFile, MpsGetBarcode, Rotate, SaveQuality, SaveToFile, Str2Dir
            , TJpegGraphic, TTiffGraphic, _DelTree, ifBlackWhite, ifColor25, ifG
            ray256, ifTrueColor, tcGroup4, tcJpeg
  方法描述:處理「匯入影像檔案」右鍵選單。開啟檔案對話框選取 TIF/JPG/PNG 檔,並檢查
            檔案大小是否超過限制。核心流程包含:計算總頁數、逐頁載入、執行自動去偏斜
            (Deskew)、條碼辨識以判斷 FormID、處理 A3 切圖(左右分割)、將影像轉換為對
            應格式(黑白轉 TIF G4,彩色/灰階轉 JPG)並寫入磁碟,最後更新索引、樹狀結
            構與頁數統計。
  引用相依:MpsGetBarcode, CheckNeedCrop, Rotate, CropImg, DeskewImg, SetContextList
  方法描述:【外部影像檔案匯入】
            支援 TIF/JPG/PNG 格式,整合自動化處理流水線。
            1. 限額檢核:比對 FFileSizeLimit,防止匯入過大檔案影響傳輸。
            2. 圖像增強:載入後即執行自動去偏斜 (Deskew)。
            3. A3 分割判定:若偵測到影像寬度特徵符合 A3 規格 (CheckNeedCrop),
               則將影像垂直裁切為左右兩張單頁。
            4. 條碼導向:執行條碼辨識,根據結果自動決定存放的文件子目錄 (DocDir)。
            5. 標準化封裝:將黑白圖存為 G4 TIF,彩色圖以 30% 質量壓縮存為 JPG。
            6. 完成聯動:更新全案索引、清空舊檢核紀錄並重刷 UI。
============================================================================== }
Procedure TCB_IMGPSScanX.PM104Click(Sender: TObject);
Var
@@ -1343,10 +1360,11 @@
{ ==============================================================================
  方法名稱:PM109Click
  引用相依:SaveToFile
  方法描述:處理「案件 OMR 檢核」右鍵選單。清空當前顯示並開啟檢核進度,呼叫 OMRCheck
            Case 對案件執行光學劃記辨識檢核。若檢核成功則建立 OMRCheckOk.dat 標記
            檔,最後重新載入影像、刷新樹狀結構並提示檢核完成。
  引用相依:OMRCheckCase, LoadImgFile
  方法描述:【執行單筆案件 OMR 檢核】
            1. 觸發檢核:呼叫 OMRCheckCase 執行自動辨識與規則校驗。
            2. 狀態記錄:若通過所有檢核規則,產生 OMRCheckOk.dat 標記。
            3. UI 回饋:重新載入影像並更新樹狀圖示(顯示通過/失敗圖示)。
============================================================================== }
procedure TCB_IMGPSScanX.PM109Click(Sender: TObject);
var
@@ -1381,10 +1399,12 @@
{ ==============================================================================
  方法名稱:PM110Click
  引用相依:Str2Dir
  方法描述:處理「新增其他文件」右鍵選單。彈出對話框要求輸入自定義名稱,驗證無誤後產
            生新的文件編號並在案件目錄下建立實體子目錄。隨後將新目錄加入清單並重
            新繪製樹狀結構,最後自動展開新建立的節點。
  引用相依:GetNewCustomDocNo, SetDocNoList, DrawDocItem2
  方法描述:【樹狀區域:新增自定義文件】
            1. 設定名稱:彈出對話框供使用者自定義文件標題。
            2. 分配:呼叫 GetNewCustomDocNo 取得 ZZZZZ/YYYYY 編號。
            3. 建立:在實體磁碟建立對應子目錄。
            4. 註冊:將新文件加入 CaseDocNo.dat 索引並刷新樹狀顯示。
============================================================================== }
procedure TCB_IMGPSScanX.PM110Click(Sender: TObject);
var
@@ -1419,10 +1439,12 @@
{ ==============================================================================
  方法名稱:PM111Click
  引用相依:
  方法描述:處理「修改文件份數」右鍵選單。取得當前份數並供使用者修改(範圍 1-9999)。
            若份數有變動則執行驗證(如分份文件限制),確認後更新 SetDocDirCopies 設
            定並標記文件已編輯,最後刷新樹狀結構統計。
  引用相依:SetDocDirCopies, SetRecordEditedDocDir, DrawDocItem2
  方法描述:【修改文件預期份數】
            1. 範圍:使用者可調整該文件類別的份數 (1~9999)。
            2. 規則限制:若該類文件定義為需分份 (DocNoNeedDiv),則份數不可降為 1。
            3. 儲存:呼叫 SetDocDirCopies 更新 CaseDocNo_Copies.dat。
            4. 記錄:同步標記該目錄為「已編輯」,用於上傳異動判定並重繪 UI 統計。
============================================================================== }
procedure TCB_IMGPSScanX.PM111Click(Sender: TObject);
var
reassemble/view/scrollView.pas
@@ -1,9 +1,10 @@
{ ==============================================================================
  方法名稱:ISB1Click
  引用相依:
  方法描述:影像滾輪盒(ISB)的點擊處理。更新當前顯示的 ISB 對象,調整 Shape1 標記框
            的位置以框選當前 ISB。根據 ISB 名稱與捲軸位置計算並更新 PageLV 清單中
            的選取狀態(NowPage 與 ItemIndex)。
  引用相依:DisplayISB, Shape1, PageLV
  方法描述:【影像顯示視窗點擊處理】
            1. 焦點切換:將全域 DisplayISB 指向被點擊的視窗。
            2. 標記同步:將選取框 Shape1 移至該視窗位置。
            3. 清單同步:計算當前視窗對應的影像索引,同步更新 PageLV 的選取項。
============================================================================== }
procedure TCB_IMGPSScanX.ISB1Click(Sender: TObject);
var
@@ -61,11 +62,12 @@
{ ==============================================================================
  方法名稱:ISB1ImageMouseDown
  引用相依:LoadFromFile
  方法描述:影像滑鼠按下事件。設定當前 DisplayISB 並視情況取得焦點,更新 Shape1 的
            選取框位置。同步更新 PageLV 的選取頁面。若處於特定模式(NowClick = -1)
            且按下左鍵,則啟動影像的拖曳操作(BeginDrag)。此外也會處理旋轉模式下的
            影像載入。
  引用相依:DisplayISB, BeginDrag, LoadFromFile
  方法描述:【影像滑鼠按下處理】
            1. 狀態選取:更新選取視窗並同步 PageLV 索引。
            2. 拖曳發起:若處於編輯模式 (NowClick = -1),啟動 VCL 拖曳機制以便執行
               跨視窗的影像調換。
            3. 旋轉預載:若處於旋轉模式,強制重新載入原圖以確保旋轉基底正確。
============================================================================== }
procedure TCB_IMGPSScanX.ISB1ImageMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
@@ -141,10 +143,12 @@
{ ==============================================================================
  方法名稱:ISB1ImageMouseUp
  引用相依:SaveQuality, SaveToFile, TJpegGraphic
  方法描述:影像滑鼠放開事件。處理多種滑鼠模式:在 mmDelete 模式下觸發刪除功能;在
            旋轉模式(mmR90等)下儲存旋轉後的影像檔案,並同步更新預覽圖(SelectISB)
            與清空檢核記錄。最後針對縮放或拖曳模式更新捲軸位置數據。
  引用相依:TJpegGraphic, SaveToFile, FitPreViewISB, ClearErrini
  方法描述:【影像滑鼠放開處理(存檔觸發)】
            1. 刪除模式:觸發 PM508Click 刪除影像。
            2. 旋轉模式:將旋轉後的 Graphic 實體存回磁碟(JPG 採品質 30 壓縮)。
            3. 連動:同步更新縮圖預覽 (FitPreViewISB) 並清空檢核紀錄。
            4. 座標儲存:將縮放與捲動位置存入 ScrollRec 緩存。
============================================================================== }
procedure TCB_IMGPSScanX.ISB1ImageMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
@@ -195,10 +199,11 @@
{ ==============================================================================
  方法名稱:FindISB2View
  引用相依:
  方法描述:根據檢視模式,在畫面中尋找下一個可顯示影像的 TImageScrollBox。遍歷 ISB
            1-ISB8,檢查 FileName 是否為空;若已滿則會清空特定位置影像並重新開始,
            確保影像載入有對應視窗。
  引用相依:Vmode, ISB1-8
  方法描述:【尋找可用影像視窗】
            依據檢視模式(1x1, 2x2, 2x3, 2x4)決定搜尋範圍。
            1. 優先回傳目前 FileName 為空的 TImageScrollBox。
            2. 若全滿,則循環清空並從第一個視窗重新開始。
============================================================================== }
Function TCB_IMGPSScanX.FindISB2View(Vmode:Integer):TImageScrollBox; //找空的ISB來顯示
var
reassemble/view/toolBar.pas
@@ -1,10 +1,12 @@
{ ==============================================================================
  方法名稱:WNoteBtnClick
  引用相依:FileExists, LoadFromFile, SaveToFile
  方法描述:開啟備註編輯視窗。首先初始化多國語言並從 MEMO_INF_List 載入註記範本資
            訊。若存在 Scan_Memo.dat,則讀取既有的註記內容。顯示 TSortMemoForm 供使
            用者編輯,確認後將編輯結果存回 Scan_Memo.dat。最後視需要觸發 CaseHelpB
            tnClick 以更新狀態。
  引用相依:TSortMemoForm, MEMO_INF_List, Scan_Memo.dat
  方法描述:【編輯案件備註】
            1. 資料準備:從 MEMO_INF_List 載入各類註記範本提供下拉選單。
            2. 載入既有:讀取案件目錄下的 Scan_Memo.dat 並填入清單。
            3. 編輯介面:開啟 TSortMemoForm,使用者可新增、刪除或排序註記。
            4. 持久化:確認後將變動結果寫回 CSV 格式的 Scan_Memo.dat。
            5. 聯動:標記 Ch_WriteNote 並重新整理介面狀態。
============================================================================== }
procedure TCB_IMGPSScanX.WNoteBtnClick(Sender: TObject);
var
@@ -211,11 +213,13 @@
{ ==============================================================================
  方法名稱:NewScanBtnClick
  引用相依:StatrTwainScan
  方法描述:點擊「新案掃瞄」按鈕的處理。首先檢查初始化狀態。針對重掃(RSCAN)、異動(ESC
            AN)或重掃指定件(DSCAN),會自動選取新件節點並觸發追加掃瞄。若是全新掃瞄
            ,則重設掃瞄模式與路徑,清空清單,最後呼叫 StatrTwainScan 啟動掃瞄程序,
            並在結束後重新載入影像檔案。
  引用相依:StatrTwainScan, LoadImgFile, smNew, smInsert
  方法描述:【啟動新案掃瞄流程】
            1. 模式切換:若為異動/重掃模式 (RSCAN/ESCAN/DSCAN),自動轉呼叫
               AddScanBtnclick 進行追加。
            2. 資源初始化:清空當前 View、重置掃瞄路徑為空、設定模式為 smNew。
            3. 執行硬體:呼叫 StatrTwainScan 與掃瞄器溝通獲取影像。
            4. 結果展示:掃瞄結束後自動執行 LoadImgFile 刷新案件內容。
============================================================================== }
procedure TCB_IMGPSScanX.NewScanBtnClick(Sender: TObject);
begin
@@ -299,12 +303,13 @@
{ ==============================================================================
  方法名稱:OptionBtnClick
  引用相依:Scanner
  方法描述:處理「掃瞄參數設定」按鈕點擊。首先確認系統初始化是否完成,接著建立 TPatc
            hDlg 對話框並載入多國語言。將目前的掃瞄設定(如自動刪除空白頁、DPI、單/
            雙面、反白、去邊、去偏斜、亮度、對比、旋轉角度及顯示模式等)同步至對話框。使
            用者完成設定後,將新參數存回系統變數,並呼叫 R_W_ScanIni 將設定寫入設
            定檔。
  引用相依:TPatchDlg, R_W_ScanIni, DeviceDelete, ScanDpi, ScanRotate
  方法描述:【配置掃瞄器與軟體處理參數】
            提供完整的掃瞄環境微調介面:
            - 硬體端:DPI、雙面、亮度、對比、自動進紙。
            - 軟體端:空白頁刪除門檻、自動反向、清黑邊、自動去偏斜。
            - 顯示端:旋轉角度、顯示品質。
            設定後同步至 FBScan.ini 持久化並更新全域變數。
============================================================================== }
procedure TCB_IMGPSScanX.OptionBtnClick(Sender: TObject);
var
@@ -421,11 +426,13 @@
{ ==============================================================================
  方法名稱:SampleScanBtnClick
  引用相依:BWTif2Jpg, FileExists, LoadFromFile, SaveToFile, StatrTwainScan, upF
            ile
  方法描述:處理「範本掃瞄」按鈕點擊。切換為範本模式並引導使用者輸入 FormID,掃瞄後
            產生 TIF 與 JPG 影像。隨後透過 HTTPS 將範本上傳至伺服器,上傳過程中會
            嚴格檢查網路狀態、Session 有效性與伺服器回傳結果。
  引用相依:StatrTwainScan, BWTif2Jpg, upFile, SamplePath
  方法描述:【範本樣張掃瞄與註冊】
            1. 交互:提示輸入 FormID 並檢查是否已有範本需要取代。
            2. 掃瞄:設定模式 smSample 並指定輸出至 SamplePath。
            3. 標準化:掃瞄產生的黑白 TIF 會自動轉存一份 JPG 作為 Web 預覽用。
            4. 上傳:將 TIF 與 JPG 樣張透過 HTTPS 上傳至伺服器樣張庫。
            用於系統初次建立表單規則前的實體影像採集。
============================================================================== }
procedure TCB_IMGPSScanX.SampleScanBtnClick(Sender: TObject);
var
@@ -561,10 +568,13 @@
{ ==============================================================================
  方法名稱:AddScanBtnClick
  引用相依:StatrTwainScan
  方法描述:處理「追加掃瞄」按鈕點擊。檢查狀態後設定掃瞄模式為 smInsert(插入模式),
            初始化掃瞄參數並啟動 StatrTwainScan。完成後重新繪製樹狀結構、更新筆數
            統計並清空檢核記錄,最後自動選取新文件節點。
  引用相依:StatrTwainScan, smInsert, DrawDocItem2, NewTreeNodeRefresh
  方法描述:【執行影像追加掃瞄】
            在目前選取的案件或目錄後方繼續獲取影像。
            1. 資源定位:鎖定當前 NowCaseno 與 NowDocDir。
            2. 模式設定:掃瞄模式 smInsert,從既有頁數 ContextList.Count 開始累加。
            3. 執行硬體:觸發 StatrTwainScan。
            4. 後置重整:掃瞄後重新計算總頁數文字、刷新文件樹節點並清空舊檢核紀錄。
============================================================================== }
procedure TCB_IMGPSScanX.AddScanBtnClick(Sender: TObject);
var
@@ -905,10 +915,15 @@
{ ==============================================================================
  方法名稱:TransBtnClick
  引用相依:LoadFromFile
  方法描述:處理工具列「上傳」按鈕的點擊事件。執行完整的前置檢查(包含案件配號、歸類、
            收件時間限制等),接著遍歷所有案件執行 OMR 檢核與 ReSize,最後呼叫 Tran
            sCaseID 將案件封裝傳送至伺服器。上傳結束後會顯示成功/失敗的統計報告。
  引用相依:CheckCaseID_OK, CheckCaseAttach_OK, OMRCheckCase, TransCaseID, CaseAsk
  方法描述:【案件上傳總控邏輯】
            這是將影像正式送往伺服器的最後關口。
            1. 前置攔截:驗證案件是否已配號、是否仍有未歸類文件、是否超過收件時間。
            2. 批次處理:遍歷所有待傳案件。
            3. 伺服器詢問:透過 CaseAsk 確認案號是否重複處理或已存在。
            4. 實體準備:執行 CaseReSize 標準化尺寸,並自動啟動 OMRCheckCase 檢核。
            5. 正式傳輸:檢核通過後呼叫 TransCaseID 執行 ZIP 封裝與上傳 (Http/Ftp)。
            6. 回報:產出成功/失敗統計報告,引導使用者查看失敗原因。
============================================================================== }
procedure TCB_IMGPSScanX.TransBtnClick(Sender: TObject);
Var
reassemble/view/treeView.pas
@@ -1,10 +1,14 @@
{ ==============================================================================
  方法名稱:DrawDocItem2
  引用相依:DirectoryExists, FileExists, LoadFromFile
  方法描述:在樹狀結構中繪製指定案件的文件與表單節點。讀取 CaseDocNo.dat 取得文件
            清單,逐一建立文件節點並根據引用狀態設定圖示。接著在文件節點下建立表單
            節點,區分制式表單與自定義表單。包含入庫過濾與附件處理,是樹狀 UI 呈現
            的核心。
  引用相依:CaseDocNo.dat, CaseDocNo_Copies.dat, LASTEST_FORM_INF_List, GetUseCase
  方法描述:【深度建構案件文件樹】
            此方法將本地磁碟結構轉化為多層級 UI 樹狀結構。
            1. 根層:建立案件案號節點。
            2. 目錄層:讀取 CaseDocNo.dat,為每個文件子目錄建立節點,顯示文件名稱、
               目錄原名與預期份數。根據 GetUseCase 標記「引入/被引用」特殊圖示。
            3. 頁面層:遍歷子目錄影像,提取 FormID,對應顯示為表單名稱節點。
            4. 補件過濾:補件模式下,僅顯示當次掃瞄的新影像節點。
            5. 特殊處理:處理附件 (Attach) 目錄與自定義 (ZZZZZ) 文件節點。
============================================================================== }
Function TCB_IMGPSScanX.DrawDocItem2(CaseNode : TTreenode;Caseno:String):Boolean;  //畫出文件名稱的Tree
Var
@@ -269,11 +273,16 @@
{ ==============================================================================
  方法名稱:TreeView1Click
  引用相依:FileExists, LoadFromFile
  方法描述:處理樹狀結構(TreeView)的點擊事件,是切換顯示內容的核心入口。根據點擊的
            層級(案件、文件、表單),重置全域變數並設定對應的 DisplayPath、NowDocNo
            與 NowFormCode。接著載入並顯示該層級對應的影像與附件清單,同時動態調整
            按鈕與選單的可用性。
  引用相依:DisplayPath, NowDocDir, LoadImgFile, ReadCaseIndex, PageLV
  方法描述:【樹狀結構選取點擊處理】
            本系統導航的核心中心點。
            1. 狀態重置:清空當前所有 NowXxxx 全域變數。
            2. 層級識別:
               - 案件層:設定 DisplayPath,讀取案件索引,載入該案所有影像至預覽區。
               - 文件層:鎖定 NowDocDir,僅載入該目錄影像,同步更新附件清單。
               - 表單層:鎖定 NowFormCode,僅顯示特定表單頁面。
            3. UI 權限:根據選取層級動態啟用「追加掃瞄」、「上傳」、「歸類」等按鈕。
            4. 縮圖連動:同步產生 PageLV 頁碼清單供快速跳轉。
============================================================================== }
procedure TCB_IMGPSScanX.TreeView1Click(Sender: TObject);
Var
@@ -506,11 +515,15 @@
{ ==============================================================================
  方法名稱:TreeView1DragDrop
  引用相依:CopyFile, DeleteImageFile, LoadFromFile, ReSortFileName, RenameFile,
             SaveToFile, _DelTree
  方法描述:處理樹狀結構的拖放操作,實現影像的快速歸類或跨案件移動。當使用者將影像
            縮圖拖至樹狀節點時,程序會判斷目標層級,執行實際的檔案搬移(Copy/Delete
            )與更名,同步更新 Context.dat 索引檔案,並重新整理樹狀顯示與筆數統計。
  引用相依:CopyFile, DeleteImageFile, ReSortFileName, DrawDocItem2, ClearErrini
  方法描述:【樹狀結構:執行影像拖放歸類】
            將影像縮圖拖至樹狀節點,實現快速分類。
            1. 目標識別:解析 X,Y 座標,判斷目標為文件 (Level 2) 或表單 (Level 3) 節點。
            2. 實體遷移:
               - 同案件:執行檔案更名、複製並刪除原檔案,更新 Context。
               - 跨案件:跨磁碟目錄遷移檔案,同步建立目標案的文件結構。
            3. 索引與排序:呼叫 ReSortFileName 重新整理來源與目標目錄的序號。
            4. 狀態連動:重新繪製案件樹,清空兩案的檢核記錄,並重載筆數統計。
============================================================================== }
procedure TCB_IMGPSScanX.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
scripts/infer_itf_scan_pas_deps.js
比對新檔案
@@ -0,0 +1,84 @@
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
/**
 * 從 Delphi .pas 檔案中提取 interface 區塊的方法名
 * @param {string} pasContent
 * @returns {string[]}
 */
function extractMethodsFromPas(pasContent) {
    let section = pasContent;
    const interfaceMatch = pasContent.match(/interface([\s\S]*?)implementation/i);
    if (interfaceMatch) {
        section = interfaceMatch[1];
    }
    // 匹配 function, procedure 或 property
    const methodRegex = /(?:procedure|function|property)\s+([\w]+)/gi;
    const methods = [];
    let match;
    while ((match = methodRegex.exec(section)) !== null) {
        methods.push(match[1]);
    }
    return [...new Set(methods)];
}
/**
 * 檢查方法是否在專案檔案中被引用
 * @param {string} methodName
 * @param {string[]} projectGlobs
 * @returns {boolean}
 */
function isMethodUsed(methodName, projectGlobs) {
    // 使用 grep 進行全詞匹配,忽略大小寫
    // 由於 grep 不一定支援 globstar (**),我們改用 find + grep
    // 注意:我們排除 .ts.bk 和 .pas 本身
    // 這裡我們簡化處理,直接在 reassemble 目錄下找 .pas 檔案
    const cmd = `find reassemble -name "*.pas" -exec grep -i -w -q "${methodName}" {} +`;
    try {
        execSync(cmd, { stdio: 'ignore' });
        // 如果 execSync 沒有拋出錯誤,表示 grep 找到了匹配項 (exit code 0)
        return true;
    } catch (e) {
        // grep 沒找到會回傳 exit code 1,execSync 會拋出錯誤
        return false;
    }
}
async function main() {
    const args = process.argv.slice(2);
    if (args.length < 4) {
        console.log('Usage: node infer_itf_scan_pas_deps.js <unit_id> <pas_file> <output_json> <project_glob_1> [project_glob_2 ...]');
        process.exit(1);
    }
    const [unitId, pasFile, outputJson, ...projectGlobs] = args;
    console.log(`Scanning methods in ${pasFile}...`);
    const pasContent = fs.readFileSync(pasFile, 'utf8');
    const allMethods = extractMethodsFromPas(pasContent);
    console.log(`Found ${allMethods.length} total methods.`);
    const usedMethods = [];
    for (const method of allMethods) {
        // 為了區分定義與使用,我們在搜尋時排除原始 pas 檔名
        // 但規格說是在 reassemble/**/*.pas 找,通常這些檔案不會包含原始 pas 的內容
        if (isMethodUsed(method, projectGlobs)) {
            usedMethods.push(method);
        }
    }
    console.log(`Found ${usedMethods.length} used methods.`);
    const result = {
        unit: unitId,
        used_methods: usedMethods.sort()
    };
    fs.mkdirSync(path.dirname(outputJson), { recursive: true });
    fs.writeFileSync(outputJson, JSON.stringify(result, null, 2));
    console.log(`Result written to ${outputJson}`);
}
main();
scripts/infer_itf_strip_ts_interface.js
比對新檔案
@@ -0,0 +1,89 @@
const fs = require('fs');
const path = require('path');
function stripTsInterface(tsContent, usedMethods) {
    const usedMethodsLower = new Set(usedMethods.map(m => m.toLowerCase()));
    // 將內容分割成塊:註解 + 方法
    // 我們先尋找所有 abstract 方法的起始位置
    const lines = tsContent.split(/\r?\n/);
    const resultLines = [...lines];
    const toDelete = new Set(); // 儲存要刪除的行索引
    for (let i = 0; i < lines.length; i++) {
        const line = lines[i];
        const methodMatch = line.match(/^[ \t]*abstract\s+(\w+)\s*[:(]/);
        if (methodMatch) {
            const methodName = methodMatch[1];
            if (!usedMethodsLower.has(methodName.toLowerCase())) {
                toDelete.add(i);
                // 往上找註解
                let j = i - 1;
let inComment = false;
while (j >= 0) {
    const prevLine = lines[j].trim();
    if (prevLine === '') {
        if (inComment) toDelete.add(j);
        else break;
        j--;
        continue;
    }
    if (prevLine.startsWith('/**') && prevLine.endsWith('*/')) {
        toDelete.add(j);
        break; // 單行 JSDoc
    }
    if (prevLine.endsWith('*/')) {
        inComment = true;
        toDelete.add(j);
    } else if (prevLine.startsWith('/**')) {
        toDelete.add(j);
        break; // 註解結束
    } else if (inComment || prevLine.startsWith('//') || prevLine.startsWith('*')) {
        toDelete.add(j);
    } else {
        break;
    }
    j--;
}
            }
        }
    }
    const finalLines = resultLines.filter((_, idx) => !toDelete.has(idx));
    return finalLines.join('\n').replace(/\n{3,}/g, '\n\n');
}
function main() {
    const args = process.argv.slice(2);
    if (args.length !== 3) {
        console.log('Usage: node infer_itf_strip_ts_interface.js <deps_json> <ts_bk_file> <ts_out_file>');
        process.exit(1);
    }
    const [depsJson, tsBkFile, tsOutFile] = args;
    console.log(`Loading dependencies from ${depsJson}...`);
    const deps = JSON.parse(fs.readFileSync(depsJson, 'utf8'));
    const usedMethods = deps.used_methods;
    console.log(`Loading template from ${tsBkFile}...`);
    const tsContent = fs.readFileSync(tsBkFile, 'utf8');
    console.log(`Stripping unused methods...`);
    const result = stripTsInterface(tsContent, usedMethods);
    fs.mkdirSync(path.dirname(tsOutFile), { recursive: true });
    fs.writeFileSync(tsOutFile, result);
    console.log(`Result written to ${tsOutFile}`);
}
main();