☆Docuworksで「ファイル名に日付を付加する」プラグイン

Docuworksは、設定すればスキャン時に日時をファイル名に自動的に付加してくれますが、 印刷した場合等には自分で付ける必要があります。(と思います。)
そこで、作成日時か最終更新日時の内、古い方の日時をファイル名に付加する機能を 持つプラグインを作ってみます。(実は仕事で必要だったりします。)

前回のプラグインのコードと同様なので、PLG_ExecuteCommand関数のみ書きますね。
// ExecuteCommand Entry
function PLG_ExecuteCommand(pPlgStruct: PLUGGEDIN_STRUCT): LongInt; stdcall;

  function GetFileDateTime(const FileName: String; var CreateYMD, LastWriteYMD,
    LastAccessYMD: TDateTime): Boolean;
  var
    Handle: Integer;
    Time1, Time2, Time3: TFILETIME;
    SysTime: TSYSTEMTIME;
    SECURITYATTRIBUTES: TSECURITYATTRIBUTES;
  begin
    Result := False;
    with SECURITYATTRIBUTES do
    begin
      nLength := SizeOf(TSECURITYATTRIBUTES);
      lpSecurityDescriptor := nil;
      bInheritHandle := False;
    end;

    Handle := CreateFile(PChar(FileName),GENERIC_READ,0,@SECURITYATTRIBUTES,
                          OPEN_EXISTING,FILE_ATTRIBUTE_READONLY,0);

    if Handle = 0 then Exit;
    try
      GetFileTime(Handle, @Time1, @Time2, @Time3);

      FileTimeToLocalFileTime(Time1,Time1);
      FileTimeToSystemTime(Time1, SysTime);
      CreateYMD := SystemTimeToDateTime(SysTime);

      FileTimeToLocalFileTime(Time2,Time2);
      FileTimeToSystemTime(Time2, SysTime);
      LastAccessYMD := SystemTimeToDateTime(SysTime);

      FileTimeToLocalFileTime(Time3,Time3);
      FileTimeToSystemTime(Time3, SysTime);
      LastWriteYMD := SystemTimeToDateTime(SysTime);

      Result := True;
    finally
      CloseHandle(Handle);
    end;
  end;

var
  I: Integer;
  S: String;
  InputFile: String;
  CreateYMD, LastWriteYMD, LastAccessYMD: TDateTime;
begin
  S := '';
  for I := 0 to pPlgStruct^.ps_nFiles-1 do
  begin
    InputFile := pPlgStruct^.ps_pszFiles^[I];
    if GetFileDateTime(InputFile, CreateYMD, LastWriteYMD, LastAccessYMD) then
    begin
      if CreateYMD <= LastWriteYMD then
        S := FormatDateTime('yyyymmdd', CreateYMD)
      else
        S := FormatDateTime('yyyymmdd', LastWriteYMD);
      S := ExtractFilePath(InputFile) + S + ExtractFileName(InputFile);
      RenameFile(InputFile, S);
    end;
  end;
  Result := 1;
end;

上記のコードで、きちんとファイル名を修正してくれるのですが、Docuworks Deskでのファイル位置が 一番最後に移動してしまいます。DocuworksのAPIには、ファイル名の変更をするものがなさそうなので、 解決できずにいます。メッセージでメニューとクリップボードを使って処理する方法もありますが、 スマートじゃないですよね。

|

☆Docuworksプラグイン「自動正立」を作る。

最近の記事の処理を組み合わせて、実際に使えるプラグイン「自動正立」を作ってみます。このプラグインは、Docuworks Deskで選択したファイルの全ページを文字の読める方向に自動回転させます。

library Project1;

uses
  Windows,
  SysUtils;

{$R *.res}

// xdwapiを使うための宣言--ここから
const
  XDW_OPEN_UPDATE	= 1;

type
  XDW_DOCUMENT_HANDLE = record
    dummy: LongInt;
  end;

  XDW_OPEN_MODE = record
    nSize: Integer;
    nOption: Integer;
  end;

  XDW_DOCUMENT_INFO = record
    nSize: Integer;
    nPages: Integer;
    nVersion: Integer;
    nOriginalData: Integer;
    nDocType: Integer;
    nPermission: Integer;
    nShowAnnotations: Integer;
    nDocuments: Integer;
    nBinderColor: Integer;
    nBinderSize: Integer;
  end;

  function XDW_OpenDocumentHandle(const lpszFilePath: PAnsiChar;
    var Handle: XDW_DOCUMENT_HANDLE; var OpenMode: XDW_OPEN_MODE): Integer;
    stdcall; external 'xdwapi.dll';

  function XDW_GetDocumentInformation(Handle: XDW_DOCUMENT_HANDLE;
    var DocumentInfo: XDW_DOCUMENT_INFO): Integer;
    stdcall; external 'xdwapi.dll';

  function XDW_RotatePageAuto(Handle: XDW_DOCUMENT_HANDLE; nPage: Integer;
    reserved: Pointer=nil): Integer; stdcall; external 'xdwapi.dll';

  function XDW_SaveDocument(Handle: XDW_DOCUMENT_HANDLE;
    reserved: Pointer= nil): Integer; stdcall; external 'xdwapi.dll';

  function XDW_CloseDocumentHandle(Handle: XDW_DOCUMENT_HANDLE;
    reserved: Pointer=nil): Integer; stdcall; external 'xdwapi.dll';

  function XDW_Finalize(reserved: Pointer = nil): Integer;
    stdcall; external 'xdwapi.dll';

// xdwapiを使うための宣言--ここまで

// 以下、PLUGINSPI用の処理
const
  PLUGGEDIN_REGKEY = 'Software\\FujiXerox\\MPM3\\MPWS\\PLUGGEDIN';
  MAX_PLUGGEDIN_NUMBER = 30;
  PLUGGEDIN_VERSION = 2;
  //
  PLUGGEDIN_NAME_INITIALIZE = '_PLG_Initialize@4';
  PLUGGEDIN_NAME_FINALIZE ='_PLG_Finalize@4';
  PLUGGEDIN_NAME_CANFINALIZE = '_PLG_CanFinalize@4';
  PLUGGEDIN_NAME_REQUIREFILES =  '_PLG_RequireFiles@4';
  PLUGGEDIN_NAME_EXECUTECOMMAND = '_PLG_ExecuteCommand@4';
  PLUGGEDIN_NAME_ISPARALLEL = '_PLG_IsParallel@4';
  PLUGGEDIN_NAME_ISCLONINGCOMMAND = '_PLG_IsCloningCommand@4';
  PLUGGEDIN_NAME_GETNEWCLONE =  '_PLG_GetNewClone@8';
  PLUGGEDIN_NAME_RELEASECLONE = '_PLG_ReleaseClone@4';
  PLUGGEDIN_NAME_EXECUTABLE =  '_PLG_Executable@8';
  PLUGGEDIN_NAME_CANSETPROFILE = '_PLG_CanSetProfile@4';
  PLUGGEDIN_NAME_SETPROFILE = '_PLG_SetProfile@4';
  PLUGGEDIN_NAME_GETCOMMANDICON = '_PLG_GetCommandIcon@8';
  PLUGGEDIN_NAME_ENUMERATECOMMANDS = '_PLG_EnumerateCommands@12';

type
  Tps_pszFiles = ^_Tps_pszFiles;
  _Tps_pszFiles = array[0..32767] of PChar;

  Tps_pnPageNumbers = ^_ps_pnPageNumbers;
  _ps_pnPageNumbers = array[0..32767] of LongInt;

  PLUGGEDIN_STRUCT = ^TPluggedin_struct;
  TPluggedin_struct = packed record
    ps_nPlugVersion: LongInt;
    ps_pszFunction: PChar;
    ps_execParallel: LongInt;
    ps_nFiles: LongInt;
    ps_pszFiles: Tps_pszFiles;
    ps_pnPageNumbers: Tps_pnPageNumbers;
    ps_pszExecFolder: PChar;
    ps_hwndDWDesk: LongInt;
  end;

// Initialize Entry
function PLG_Initialize(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 1;
end;

// Finalize Entry
function PLG_Finalize(const cmdName: PChar): LongInt; stdcall;
begin
  XDW_Finalize(nil);
  Result := 1;
end;

// CanFinalize Entry
function PLG_CanFinalize(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 1;
end;

// RequireFiles Entry
function PLG_RequireFiles(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 1;
end;

// ExecuteCommand Entry
function PLG_ExecuteCommand(pPlgStruct: PLUGGEDIN_STRUCT): LongInt; stdcall;
const
  M1 = '自動正立';
  M2 = '時間がかかるけどいいの?';
  M3 = '終了しました。';
var
  I,J,K,L,Last_Page: Integer;
  S: String;
  h: XDW_DOCUMENT_HANDLE;
  mode: XDW_OPEN_MODE;
  info: XDW_DOCUMENT_INFO;
  InputFile: String;

begin
  Result := 1;
  if MessageBox(0, PChar(M2), PChar(M1), MB_OKCANCEL) <> 1 Then Exit;

  // 文書ハンドルを開く
  mode.nSize := sizeof(XDW_OPEN_MODE);
  mode.nOption := XDW_OPEN_UPDATE;

  S := '';
  for I := 0 to  pPlgStruct^.ps_nFiles-1 do
  begin
    //pPlgStruct^.ps_pnPageNumbers[I]; 表示ページ番号
    InputFile := pPlgStruct^.ps_pszFiles^[I];
    J := XDW_OpenDocumentHandle(PAnsiChar(InputFile), h, mode);
    try
      if J > -1 then
      begin
        info.nSize := SizeOf(XDW_DOCUMENT_INFO);

        XDW_GetDocumentInformation(h, info);
        Last_Page := info.nPages;

        K := 0;
        for L := 1 to Last_Page do
        begin
          J := XDW_RotatePageAuto(h, L);
          K := K + J;
        end;

        // エラーがない場合に変更内容を保存する
        if K = 0 then
          XDW_SaveDocument(h);
      end;
    finally
      // 文書ハンドルを閉じる
      XDW_CloseDocumentHandle(h);
    end;
  end;

  MessageBox(0, PChar(M3),PChar(M1), MB_OK);

  Result := 1;
end;

// IsParallel Entry
function PLG_IsParallel(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 0;
end;

// IsCloning Entry
function PLG_IsCloningCommand(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 0;
end;

// GetNewClone Entry
function PLG_GetNewClone(cmdName: PChar; nBufSize: LongInt): LongInt; stdcall;
begin
  Result := 0;
end;

// ReleaseClone Entry
function PLG_ReleaseClone(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 0;
end;

// Executable Entry
function PLG_Executable(const cmdName: PChar; nArgFiles: LongInt):
  LongInt; stdcall;
begin
  Result := nArgFiles; // ファイルが選択されていない場合には処理させない。
end;

// CanSetProfile Entry
function PLG_CanSetProfile(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 0;
end;

// SetProfile Entry
function PLG_SetProfile(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 0;
end;

// GetAppIcon Entry
function PLG_GetCommandIcon(const cmdName: PChar; bNormalSize: LongInt):
  HICON; stdcall;
begin
  // 本当はbNormalSize (0,1) により大きなアイコンと小さなものを設定する。
  Result:= LoadIcon(hInstance, MAKEINTRESOURCE('MAINICON'));
end;

// EnumerateCommands Entry
function PLG_EnumerateCommands(var cmdNameList: PChar; nBufSize: LongInt;
  var nBufSizeRequired: LongInt): LongInt; stdcall;
const
  S = '自動正立 by hiderin';
begin
  nBufSizeRequired := Length(S)+1;
  if (nBufSize < nBufSizeRequired) then
  begin
    Result := 0;
    Exit;
  end;
  StrCopy(@cmdNameList, S);
  Result := 1;
end;

exports
  PLG_INITIALIZE name PLUGGEDIN_NAME_INITIALIZE,
  PLG_FINALIZE name PLUGGEDIN_NAME_FINALIZE,
  PLG_CANFINALIZE name PLUGGEDIN_NAME_CANFINALIZE,
  PLG_REQUIREFILES name PLUGGEDIN_NAME_REQUIREFILES,
  PLG_EXECUTECOMMAND name PLUGGEDIN_NAME_EXECUTECOMMAND,
  PLG_ISPARALLEL name PLUGGEDIN_NAME_ISPARALLEL,
  PLG_ISCLONINGCOMMAND name PLUGGEDIN_NAME_ISCLONINGCOMMAND,
  PLG_GETNEWCLONE name PLUGGEDIN_NAME_GETNEWCLONE,
  PLG_RELEASECLONE name PLUGGEDIN_NAME_RELEASECLONE,
  PLG_EXECUTABLE name PLUGGEDIN_NAME_EXECUTABLE,
  PLG_CANSETPROFILE name PLUGGEDIN_NAME_CANSETPROFILE,
  PLG_SETPROFILE name PLUGGEDIN_NAME_SETPROFILE,
  PLG_GETCOMMANDICON name PLUGGEDIN_NAME_GETCOMMANDICON,
  PLG_ENUMERATECOMMANDS name PLUGGEDIN_NAME_ENUMERATECOMMANDS;

begin
end.

|

☆「char**」 を Delphiで書くと・・・。

☆Docuworksプラグインを作成してみる。で、Delphi向けに書き直したPLUGGEDIN_STRUCT 構造体(レコード型)ですが、ファイルリストの取得がうまくいかないのでチェックしてみました。
type
  PLUGGEDIN_STRUCT = ^TPluggedin_struct;
  TPluggedin_struct = packed record
 (略)
    ps_pszFiles: PChar; ←ここが問題!
  (略)
  end;

ヘッダーファイルの構造体をよく見てみると・・・ん?・・・ 「char**」 ・・・ おおっ、なんと*(アスタリスク)が2つも並んでいるではないですか。
struct _pluggedin_struct {
 (略)
  const char** ps_pszFiles;
  (略)
};

Cがよくわかっていない私には難解でしたが、昨日、今日といろいろと試した結果、 次のコードでうまく取得できました。でも合ってるのかな??
type
  Tps_pszFiles = ^_Tps_pszFiles;
  _Tps_pszFiles = array[0..32767] of PChar;

  PLUGGEDIN_STRUCT = ^TPluggedin_struct;
  TPluggedin_struct = packed record
    ps_nPlugVersion: LongInt;
    ps_pszFunction: PChar;
    ps_execParallel: LongInt;
    ps_nFiles: LongInt;
    ps_pszFiles: Tps_pszFiles;
    ps_pnPageNumbers: LongInt;
    ps_pszExecFolder: PChar;
    ps_hwndDWDesk: LongInt;
  end;      

ファイル名の取得部分です。ちょっとややこしいですね。
function PLG_ExecuteCommand(pPlgStruct: PLUGGEDIN_STRUCT): LongInt; stdcall;

  (略)
  // 選択されたファイル名を順番に取得します。
  for I := 0 to  pPlgStruct^.ps_nFiles-1 do
  begin
    InputFile := pPlgStruct^.ps_pszFiles^[I];
 (略)
end;

|

☆Docuworksプラグインを作成してみる。

Fuji XeroxはDocuworksのプラグイン仕様についても丁寧な解説とヘッダーファイルを配布しておられるのですが、 C++向けとなっており、私にはよくわからないんですよね。いろいろ試した結果、下記のコードで一応動作しているようなので書いておきますね。

プラグインの実態は、DLLなので、ファイル新規作成その他DLLウィザードをクリックして新規にプロジェクトを作成します。
library Project1;

uses
  Windows,
  SysUtils;

{$R *.res}

const
  PLUGGEDIN_REGKEY = 'Software\\FujiXerox\\MPM3\\MPWS\\PLUGGEDIN';
  MAX_PLUGGEDIN_NUMBER = 30;
  PLUGGEDIN_VERSION = 2;
  //
  PLUGGEDIN_NAME_INITIALIZE = '_PLG_Initialize@4';
  PLUGGEDIN_NAME_FINALIZE ='_PLG_Finalize@4';
  PLUGGEDIN_NAME_CANFINALIZE = '_PLG_CanFinalize@4';
  PLUGGEDIN_NAME_REQUIREFILES =  '_PLG_RequireFiles@4';
  PLUGGEDIN_NAME_EXECUTECOMMAND = '_PLG_ExecuteCommand@4';
  PLUGGEDIN_NAME_ISPARALLEL = '_PLG_IsParallel@4';
  PLUGGEDIN_NAME_ISCLONINGCOMMAND = '_PLG_IsCloningCommand@4';
  PLUGGEDIN_NAME_GETNEWCLONE =  '_PLG_GetNewClone@8';
  PLUGGEDIN_NAME_RELEASECLONE = '_PLG_ReleaseClone@4';
  PLUGGEDIN_NAME_EXECUTABLE =  '_PLG_Executable@8';
  PLUGGEDIN_NAME_CANSETPROFILE = '_PLG_CanSetProfile@4';
  PLUGGEDIN_NAME_SETPROFILE = '_PLG_SetProfile@4';
  PLUGGEDIN_NAME_GETCOMMANDICON = '_PLG_GetCommandIcon@8';
  PLUGGEDIN_NAME_ENUMERATECOMMANDS = '_PLG_EnumerateCommands@12';

type
  PLUGGEDIN_STRUCT = ^TPluggedin_struct;
  TPluggedin_struct = packed record
    ps_nPlugVersion: LongInt;
    ps_pszFunction: PChar;
    ps_execParallel: LongInt;
    ps_nFiles: LongInt;
    ps_pszFiles: PChar;
    ps_pnPageNumbers: LongInt;
    ps_pszExecFolder: PChar;
    ps_hwndDWDesk: LongInt;
  end;

// Initialize Entry
function PLG_Initialize(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 1;
end;

// Finalize Entry
function PLG_Finalize(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 1;
end;

// CanFinalize Entry
function PLG_CanFinalize(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 1;
end;

// RequireFiles Entry
function PLG_RequireFiles(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 1;
end;

// ExecuteCommand Entry
function PLG_ExecuteCommand(pPlgStruct: PLUGGEDIN_STRUCT): LongInt; stdcall;
begin
  MessageBox(0, pPlgStruct.ps_pszFunction,
    'Welcome to Docuworks Plugins', MB_OK);
  Result := 1;
end;

// IsParallel Entry
function PLG_IsParallel(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 0;
end;

// IsCloning Entry
function PLG_IsCloningCommand(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 0;
end;

// GetNewClone Entry
function PLG_GetNewClone(cmdName: PChar; nBufSize: LongInt): LongInt; stdcall;
begin
  Result := 0;
end;

// ReleaseClone Entry
function PLG_ReleaseClone(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 0;
end;

// Executable Entry
function PLG_Executable(const cmdName: PChar; nArgFiles: LongInt):
  LongInt; stdcall;
begin
  Result := 1;
end;

// CanSetProfile Entry
function PLG_CanSetProfile(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 0;
end;

// SetProfile Entry
function PLG_SetProfile(const cmdName: PChar): LongInt; stdcall;
begin
  Result := 0;
end;

// GetAppIcon Entry
function PLG_GetCommandIcon(const cmdName: PChar; bNormalSize: LongInt):
  HICON; stdcall;
begin
  Result := LoadIcon(hInstance, MAKEINTRESOURCE('MAINICON'));
end;

// EnumerateCommands Entry
function PLG_EnumerateCommands(var cmdNameList: PChar; nBufSize: LongInt;
  var nBufSizeRequired: LongInt): LongInt; stdcall;
const
  S = 'SamplePlugin by hiderin';
begin
  nBufSizeRequired := Length(S)+1;
  if (nBufSize < nBufSizeRequired) then
  begin
    Result := 0;
    Exit;
  end;
  StrCopy(@cmdNameList, S);
  Result := 1;
end;

exports
  PLG_INITIALIZE name PLUGGEDIN_NAME_INITIALIZE,
  PLG_FINALIZE name PLUGGEDIN_NAME_FINALIZE,
  PLG_CANFINALIZE name PLUGGEDIN_NAME_CANFINALIZE,
  PLG_REQUIREFILES name PLUGGEDIN_NAME_REQUIREFILES,
  PLG_EXECUTECOMMAND name PLUGGEDIN_NAME_EXECUTECOMMAND,
  PLG_ISPARALLEL name PLUGGEDIN_NAME_ISPARALLEL,
  PLG_ISCLONINGCOMMAND name PLUGGEDIN_NAME_ISCLONINGCOMMAND,
  PLG_GETNEWCLONE name PLUGGEDIN_NAME_GETNEWCLONE,
  PLG_RELEASECLONE name PLUGGEDIN_NAME_RELEASECLONE,
  PLG_EXECUTABLE name PLUGGEDIN_NAME_EXECUTABLE,
  PLG_CANSETPROFILE name PLUGGEDIN_NAME_CANSETPROFILE,
  PLG_SETPROFILE name PLUGGEDIN_NAME_SETPROFILE,
  PLG_GETCOMMANDICON name PLUGGEDIN_NAME_GETCOMMANDICON,
  PLG_ENUMERATECOMMANDS name PLUGGEDIN_NAME_ENUMERATECOMMANDS;

begin
end.



コンパイルしてできたDLLを C:\Program Files\Fuji Xerox\DocuWorks\bin\pluginsにコピーします。
Docuworksを起動させて、プラグイン設定を選択すると次のようなダイアログが表示されます。

Plugin1



実行させてみると、きちんとダイアログが表示されました。

Plugin2





DocuWorks Development Tool Kit 6.2.3 日本語版
http://www.fujixerox.co.jp/soft/docuworks/download301.html



[20080121 追記]
レコード型PLUGGEDIN_STRUCTを下記の記事で書き換えています。
☆「char**」 を Delphiで書くと・・・。

|

■DocuWorks Development Tool Kitのアップデート

Docuworksのアップデートに伴い、SDKもDocuWorks Development Tool Kit 6.2.3 日本語版にアップデートされています。 ただ、リリースノートによりますとContent Filter I/F以外は更新されていないようです。ついでにリリースノートの日付も2007年10月から更新されていませんけど(^^;

FUJI XEROX
DocuWorks Development Tool Kit 6.2.3 日本語版
http://www.fujixerox.co.jp/soft/docuworks/download301.html

|

☆DocuWorksファイルの自動正立

DocuWorksでスキャンした書類を向きを揃えるのは面倒なので、何か方法がないのかなと思って調べてみました。 DocuWorks Deskのメニューには自動処理的なものが見当たらなかったのですが、APIにXDW_RotatePageAutoというのがあったので、試してみました。
→メニューにありました。この記事の追記を参照して下さい。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  XDW_OPEN_UPDATE	= 1;

type
  XDW_DOCUMENT_HANDLE = record
    dummy: LongInt;
  end;

  XDW_OPEN_MODE = record
    nSize: Integer;
    nOption: Integer;
  end;

  XDW_DOCUMENT_INFO = record
    nSize: Integer;
    nPages: Integer;
    nVersion: Integer;
    nOriginalData: Integer;
    nDocType: Integer;
    nPermission: Integer;
    nShowAnnotations: Integer;
    nDocuments: Integer;
    nBinderColor: Integer;
    nBinderSize: Integer;
  end;

  function XDW_OpenDocumentHandle(const lpszFilePath: PAnsiChar;
    var Handle: XDW_DOCUMENT_HANDLE; var OpenMode: XDW_OPEN_MODE): Integer;
    stdcall; external 'xdwapi.dll';

  function XDW_GetDocumentInformation(Handle: XDW_DOCUMENT_HANDLE;
    var DocumentInfo: XDW_DOCUMENT_INFO): Integer;
    stdcall; external 'xdwapi.dll';

  function XDW_RotatePageAuto(Handle: XDW_DOCUMENT_HANDLE; nPage: Integer;
    reserved: Pointer=nil): Integer; stdcall; external 'xdwapi.dll';

  function XDW_SaveDocument(Handle: XDW_DOCUMENT_HANDLE;
    reserved: Pointer= nil): Integer; stdcall; external 'xdwapi.dll';

  function XDW_CloseDocumentHandle(Handle: XDW_DOCUMENT_HANDLE;
    reserved: Pointer=nil): Integer; stdcall; external 'xdwapi.dll';

  function XDW_Finalize(reserved: Pointer = nil): Integer;
    stdcall; external 'xdwapi.dll';


procedure TForm1.Button1Click(Sender: TObject);
var
  h: XDW_DOCUMENT_HANDLE;
  mode: XDW_OPEN_MODE;
  info: XDW_DOCUMENT_INFO;
  InputFile: String;
  I, J, K, Last_Page: Integer;
begin
 // 文書ハンドルを開く
  mode.nSize := sizeof(XDW_OPEN_MODE);
  mode.nOption := XDW_OPEN_UPDATE;

  InputFile := 'c:\delphi.xdw';

  I := XDW_OpenDocumentHandle(PAnsiChar(InputFile), h, mode);
  try
    if I > -1 then
    begin
      info.nSize := SizeOf(XDW_DOCUMENT_INFO);
      info.nPages := 0;
      info.nVersion := 0;
      info.nOriginalData := 0;
      info.nDocType := 0;
      info.nPermission := 0;
      info.nShowAnnotations := 0;
      info.nDocuments := 0;
      info.nBinderColor := 0;
      info.nBinderSize := 0;

      XDW_GetDocumentInformation(h, info);
      Last_Page := info.nPages;

      K := 0;
      for I := 1 to Last_Page do
      begin
        J := XDW_RotatePageAuto(h, I);
        K := K + J;
      end;

      // エラーがない場合に変更内容を保存する
      if K = 0 then
        XDW_SaveDocument(h);
    end;
  finally
    // 文書ハンドルを閉じる
    XDW_CloseDocumentHandle(h);
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  XDW_Finalize(nil);  // XDW_RotatePageAutoを呼び出したらこの処理が必ず必要
end;

end.


実行すると次のような横向きの画像が・・・

Yoko

このようにきちんと縦向きに回転されました。

Tate



上の画像以外にもページ数が多いものや少ないもの等いろいろな書類を処理してみましたが、一つだけ次のようなエラーが表示されるものがありました。

Error

状況としては10ページある書類データで最終ページの処理でエラーになります。他のデータと同じくスキャンして取り込んだものなのでパーミッションの問題ではないと思うのですが、エラーの原因はわかりませんでした。


DocuWorks Development Tool Kit 6.2 日本語版
http://www.fujixerox.co.jp/soft/docuworks/download301.html



[20080121 追記]
Docuworks Deskの設定スキャン取り込みタブにスキャン文書の後処理読める方向に全ページを自動回転するという設定がありました。

|

☆Docuworks SDKを利用する。

Fuji XeroxのDocuworksには、Docuworksと連携するための開発キットが公開されています。その内容は、各APIの細かな解説と簡単なサンプルコードがあり、とても丁寧にわかりやすく作られています。しかしながら、当然のようにC++向けとなっており、Delphiからそのまま使うことはできません。 とりあえず、サンプルにある「イメージファイルからDocuWorks文書を作成する」をDelphiで試してみました。(ヘッダーを全てDelphi向けに作ればいいんでしょうけど・・・面倒)

DocuWorks Development Tool Kit 6.2 日本語版


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  XDW_GI_DWINPUTPATH = 10;
  XDW_GI_DWDESKPATH = 11;

type
  XDW_CREATE_OPTION = record
  	nSize: Integer;
  	nFitImage: Integer;
  	nCompress: Integer;
  	nZoom: Integer;
   	nWidth: Integer;
   	nHeight: Integer;
   	nHorPos: Integer;
   	nVerPos: Integer;
  end;

  function XDW_GetInformation(nIndex: Integer; lpszOutput: PAnsiChar;
    nSize: Integer; reserved : Pointer): Integer; stdcall; external 'xdwapi.dll';

  function XDW_CreateXdwFromImageFile(const lpszInputPath: PAnsiChar;
    const lpszOutputPath: PAnsiChar; var pOption: XDW_CREATE_OPTION): Integer;
    stdcall; external 'xdwapi.dll';


procedure TForm1.Button1Click(Sender: TObject);
var
  Desk_Path, lpszOutput: array[0..MAX_PATH-1] of Char;
  Check: Integer;
  InputFile, OutputFile: String;
  pOption: XDW_CREATE_OPTION;
begin
  if not OpenDialog1.Execute then Exit;
  InputFile := OpenDialog1.FileName; // Jpeg,Bmp,Tiffのみ

  // 下記で取得するフォルダにファイルを作成すると、Docuworksを起動させたときに
  // 自動的に読み込み、表示しているフォルダにそのファイルを移動させます。
  // ちょっとややこしい仕様ですね。
  Check := XDW_GetInformation(XDW_GI_DWINPUTPATH, lpszOutput, MAX_PATH, nil);
  if (Check > -1) then
  begin
    OutputFile := String(lpszOutput) + '\aaa.xdw';

    pOption.nSize := SizeOf(XDW_CREATE_OPTION);
    pOption.nFitImage := 1;
    pOption.nCompress := 0;
    pOption.nZoom	:= 0;
    pOption.nWidth := 0;
    pOption.nHeight := 0;
    pOption.nHorPos := 0;
    pOption.nVerPos := 0;

    Check := XDW_CreateXdwFromImageFile(PAnsiChar(InputFile),
      PAnsiChar(OutputFile), pOption);
    if (Check > -1) then
    begin
      XDW_GetInformation(XDW_GI_DWDESKPATH, Desk_Path, MAX_PATH, nil);
      WinExec(Desk_Path, SW_SHOW);
    end;
  end;
end;

end.

|

その他のカテゴリー

ADO | ADT | API | ArrayList | ASP.NET | BDE | BDP.NET | BdpConnection | Borland Developer Studio 2006 | CAPICOM | class | ClipBoard | CodeEditor | Convert.ToString | Custom component | DBExpress | Delphi 2005 | Delphi 2006 | Delphi 2007 | Delphi XE2 | Delphi7 | Delphi8 | Device Driver | Dialog | Docking | DocuWorks | Docuworks SDK | Drag&Drop | Evernote | EXCEL | Firebird | FireMonkey | Game | General | Generics | Google Earth COM API | Google Maps | Google SketchUp | Graphic | IDE | Imm | Indy | InstallAware Express6 | InterBase Admin | JWW | Microsoft SQL Server | MyBase | OnMouseDown | Oracle XE | Paradox | PreviewHandler | PrintDialog | PrintPreviewDialog | PropertyGrid | PSDファイル | Ribbon Controls | RichTextBox | Servers | SubClass | TAction | TActionList | TAnimate | TButton | TCategoryButtons | TClientDataSet | TComboBox | TComboBoxEx | TCustomEdit | TDBGrid | TDockTabSet | TDrawGrid | TEdit | TExcelApplication | TFont | TForm | third party | TImage | TLabel | TList | TListBox | TListView | TMemo | TOpenDialog | TOutlookApplication | TPageControl | TPanel | TRichEdit | TShellResources | TStringGrid | TTabControl | TToolBar | TToolButton | TTreeView | TWebBrowser | Update | VCL Styles | WinInet | XE2 | XPman | オープン配列パラメータ | グループ化 | トランスレーションマネージャー | ファイル処理 | ファイル名処理 | 動的配列 | 投票 | 文字列処理 | 日本語入力 | 暗号 | | 音声合成利用