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

📄 wlxproc.pas

📁 ATViewer is a component for Delphi/C++Builder, which allows to view files of various types. There is
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{**************************************************}
{                                                  }
{  WLXProc - Total Commander Lister API Wrapper    }
{  Copyright (C) 2006-2008 Alexey Torgashin        }
{  http://atorg.net.ru                             }
{  support@uvviewsoft.com                          }
{                                                  }
{**************************************************}

{$BOOLEVAL OFF} //Short boolean evaluation required.

{$I ATViewerOptions.inc} //ATViewer options.

unit WLXProc;

interface

uses
  Windows, Messages, SysUtils, Controls,
  {$ifdef WLX_FORM} Forms, {$endif}
  WLXPlugin;

const
  WlxPluginsMaxCount = 200;

type
  TListLoad = function(ParentWin: THandle; FileToLoad: PChar; ShowFlags: Integer): THandle; stdcall;
  TListLoadNext = function(ParentWin, PluginWin: THandle; FileToLoad: PChar;
                           ShowFlags: Integer): Integer; stdcall;
  TListCloseWindow = procedure(ListWin: THandle); stdcall;
  TListSetDefaultParams = procedure(dps: pListDefaultParamStruct); stdcall;
  TListGetDetectString = procedure(DetectString: PChar; maxlen: Integer); stdcall;
  TListSendCommand = function(ListWin: THandle; Command, Parameter: Integer): Integer; stdcall;
  TListPrint = function(ListWin: THandle; FileToPrint, DefPrinter: PChar;
                        PrintFlags: Integer; const {was var!} Margins: TRect): Integer; stdcall;
  TListSearchText = function(ListWin: THandle; SearchString: PChar;
                             SearchParameter: Integer): Integer; stdcall;
  TListSearchDialog = function(ListWin: THandle; FindNext: Integer): Integer; stdcall;


type
  TWlxFileName = AnsiString; //No support for Unicode plugins filenames currently

  TWlxNameEvent = procedure(const APluginName: string) of object;

  TWlxPluginRecord = record
    FileName: TWlxFileName;
    DetectStr: string;
    HLib: THandle;
    HWnd: THandle;
    ListLoad: TListLoad;
    ListLoadNext: TListLoadNext;
    ListCloseWindow: TListCloseWindow;
    ListSetDefaultParams: TListSetDefaultParams;
    ListSendCommand: TListSendCommand;
    ListPrint: TListPrint;
    ListSearchText: TListSearchText;
    ListSearchDialog: TListSearchDialog;
  end;

  TWlxPlugins = class
  private
    FPlugins: array[1..WlxPluginsMaxCount] of TWlxPluginRecord;
    FCount: Word;
    FActive: Word;
    FActiveFileName: AnsiString;
    FActivePosPercent: Word;
    FActiveForceMode: Boolean;
    FParent: TWinControl;
    FIniFileName: AnsiString;
    {$ifdef WLX_FORM}
    FTCWindow: TForm;
    {$endif}
    FFocused: Boolean;
    FBeforeLoading: TWlxNameEvent;
    FAfterLoading: TWlxNameEvent;
    function IsIndexValid(n: Word): Boolean;
    function Present(const AFileName: TWlxFileName): Boolean;
    function Load(n: Word): Boolean;
    procedure Unload(n: Word);
    function OpenWnd(n: Word; const AFileName: AnsiString; AFlags: Integer): Boolean;
    function ReopenWnd(const AFileName: AnsiString; AFlags: Integer): Boolean;
    procedure CloseWnd(n: Word);
    procedure ResizeWnd(n: Word; const ARect: TRect);
    procedure SendCommandWnd(n: Word; ACmd, AParam: Integer);
    procedure SetActivePosPercent(AValue: Word);
    function GetName(n: Word): string;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Clear;
    procedure InitParams(AParent: TWinControl; const AIniFileName: AnsiString);
    function AddPlugin(const AFileName: TWlxFileName; const ADetect: string): Boolean;
    function GetPlugin(n: Word; var AFileName: TWlxFileName; var ADetect: string): Boolean;
    procedure ShowDebugInfo;
    function OpenMatched(const AFileName: WideString; AFit, AFitLargeOnly, ACenter, ATextWrap, AAnsiCP, ANewFile: Boolean): Boolean;
    procedure CloseActive;
    procedure ResizeActive(const ARect: TRect);
    procedure SendCommandToActive(ACmd, AParam: Integer);
    procedure SendParamsToActive(AFit, AFitLargeOnly, ACenter, ATextWrap, AAnsiCP: Boolean);
    function SendMessageToActive(const AMessage: TMessage): LRESULT;
    function PrintActive(const ARect: TRect): Boolean;
    function SearchActive(const AString: string; AFindFirst, AWholeWords, ACaseSens, ABackwards: Boolean): Boolean;
    function SearchDialogActive(AFindNext: Boolean): Boolean;
    function GetActiveName: string;
    procedure SetFocusToActive;
    property ActivePosPercent: Word read FActivePosPercent write SetActivePosPercent;
    function ActiveSupportsSearch: Boolean;
    function ActiveSupportsPrint: Boolean;
    function ActiveSupportsCommands: Boolean;
    function ActiveWindowHandle: THandle;
  published
    property IsFocused: Boolean read FFocused write FFocused;
    property OnBeforeLoading: TWlxNameEvent read FBeforeLoading write FBeforeLoading;
    property OnAfterLoading: TWlxNameEvent read FAfterLoading write FAfterLoading;
  end;

function WlxGetDetectString(const AFileName: TWlxFileName): string;


implementation

uses
  ATxSProc, ATxFProc, ATViewerMsg;

{ Not published Lister API constants }

const
  cWlxFindFirst = 0;
  cWlxFindNext = 1;


{ Helper fake TC window }

{$ifdef WLX_FORM}

{$R WLXProc_FormTC.dfm}

type
  TTOTAL_CMD = class(TForm)
  public
  end;

{$endif}


{ Helper functions }

// Currently we use simplified detect-string checking:
//
// 1) If string is empty (i.e. it doesn't contain 'EXT=' part), it's matched.
// 2) If it's not empty, it's matched when corresponding 'EXT=' part is present.
// 3) 'FORCE' special word is supported now. But it is expected only in its special
//    meaning, i.e. not as a part of file extension.
//
// To-do: add full parsing of detect-strings.
//

function WlxDetectMatch(const AFileName, ADetectStr: AnsiString; AForceMode: Boolean): Boolean;
var
  FN, Str, Ext: AnsiString;
  Empty, ExtMatch, ForceMatch: Boolean;
begin
  //Delete last slash from folder names:
  FN := AFileName;
  SDelLastSlash(FN);

  Str := UpperCase(ADetectStr);
  Ext := UpperCase(ExtractFileExt(FN));
  Delete(Ext, 1, 1);

  Empty := Pos('EXT=', Str) = 0;
  ExtMatch := Pos(Format('EXT="%s"', [Ext]), Str) > 0;
  ForceMatch := Pos('FORCE', Str) > 0;

  if AForceMode and ForceMatch then
    begin Result := True; Exit end;

  if Empty then 
    begin Result := True; Exit end;

  Result := ExtMatch;
end;


procedure MsgErrorWlx(const AFileName: TWlxFileName; const AFuncName: AnsiString);
begin
  MsgError(Format(MsgViewerWlxException, [ExtractFileName(AFileName), AFuncName]));
end;


function WlxGetDetectString(const AFileName: TWlxFileName): string;
const
  cBufSize = 4 * 1024; //4 Kb should be enough
var
  HLib: THandle;
  Buffer: array[0 .. cBufSize - 1] of Char;
  ListGetDetectString: TListGetDetectString;
begin
  Result := '';

  HLib := LoadLibrary(PChar(AFileName));
  if HLib <> 0 then
  begin
    ListGetDetectString := GetProcAddress(HLib, 'ListGetDetectString');

    if Assigned(ListGetDetectString) then
      try
        FillChar(Buffer, SizeOf(Buffer), 0);
        ListGetDetectString(Buffer, SizeOf(Buffer));
        Result := Buffer;
      except
        MsgErrorWlx(AFileName, 'ListGetDetectString');
      end;

    FreeLibrary(HLib);
  end;
end;

procedure InitPluginRecord(var Rec: TWlxPluginRecord);
begin
  with Rec do
  begin
    HLib := 0;
    HWnd := 0;
    ListLoad := nil;
    ListLoadNext := nil;
    ListCloseWindow := nil;
    ListSetDefaultParams := nil;
    ListSendCommand := nil;
    ListPrint := nil;
    ListSearchText := nil;
    ListSearchDialog := nil;
  end;
end;

function ParamsToFlags(AFit, AFitLargeOnly, ACenter, ATextWrap, AAnsiCP, AForceMode: Boolean): Integer;
begin
  Result := 0;

  if AFit then
    Inc(Result, lcp_fittowindow);

  if AFit and AFitLargeOnly then
    Inc(Result, lcp_fitlargeronly);

  if ACenter then
    Inc(Result, lcp_center);

  if ATextWrap then
    Inc(Result, lcp_wraptext);

  if AAnsiCP then
    Inc(Result, lcp_ansi)
  else
    Inc(Result, lcp_ascii);

  if AForceMode then
    Inc(Result, lcp_forceshow);
end;


{ Helper cracker class }

type
  TWinControlCracker = class(TWinControl);


{ TWlxPlugins }

constructor TWlxPlugins.Create;
begin
  inherited Create;

  FillChar(FPlugins, SizeOf(FPlugins), 0);
  FCount := 0;
  FActive := 0;
  FActiveFileName := '';
  FActivePosPercent := 0;
  FActiveForceMode := False;
  FParent := nil;
  FIniFileName := '';

  {$ifdef WLX_FORM}
  FTCWindow := nil;
  {$endif}

  FFocused := False;
  FBeforeLoading := nil;
  FAfterLoading := nil;
end;

destructor TWlxPlugins.Destroy;
begin
  Clear;
  inherited Destroy;
end;

procedure TWlxPlugins.Clear;
var
  i: Word;
begin
  CloseActive;

  for i := FCount downto 1 do
    with FPlugins[i] do
    begin
      FileName := '';
      DetectStr := '';
    end;

  FCount := 0;
  FActive := 0;
  FActiveFileName := '';
  FActivePosPercent := 0;
  FActiveForceMode := False;
end;

function TWlxPlugins.IsIndexValid(n: Word): Boolean;
begin
  Result := (n > 0) and (n <= FCount);
end;

function TWlxPlugins.Present(const AFileName: TWlxFileName): Boolean;
var
  i: Word;
begin
  Result := False;
  for i := 1 to FCount do
    if StrIComp(PChar(AFileName), PChar(FPlugins[i].FileName)) = 0 then
      begin Result := True; Break end;
end;

function TWlxPlugins.AddPlugin(const AFileName: TWlxFileName; const ADetect: string): Boolean;
begin
  Result := (FCount < WlxPluginsMaxCount) and (not Present(AFileName));
  if Result then
  begin
    Inc(FCount);
    with FPlugins[FCount] do
    begin
      FileName := AFileName;
      DetectStr := ADetect;
      SReplaceAll(DetectStr, ' = ', '='); //Some plugins give string with 'EXT = "extension"'
      InitPluginRecord(FPlugins[FCount]);
    end;
  end;
end;

function TWlxPlugins.GetPlugin(n: Word; var AFileName: TWlxFileName; var ADetect: string): Boolean;
begin
  Result := IsIndexValid(n);
  if Result then
  begin
    AFileName := FPlugins[n].FileName;
    ADetect := FPlugins[n].DetectStr;
  end
  else
  begin
    AFileName := '';
    ADetect := '';
  end;
end;

procedure TWlxPlugins.InitParams(AParent: TWinControl; const AIniFileName: AnsiString);
begin
  FParent := AParent;
  FIniFileName := AIniFileName;
end;

procedure TWlxPlugins.Unload(n: Word);
begin
  if not IsIndexValid(n) then Exit;

  with FPlugins[n] do
    if HLib <> 0 then
    begin
      CloseWnd(n);
      {$ifdef WLX_UNLOAD}
      FreeLibrary(HLib);
      InitPluginRecord(FPlugins[n]);
      {$endif}
    end;

⌨️ 快捷键说明

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