喫茶XRAYトップページ

[スレッド全体
]

[3460] ワード・エクセル操作フォームの印刷機能返信 削除
2010/6/16 (水) 10:38:12 Mr.XRAY
エクセル(Microsoft Excel)とワード(Microsoft Word)は,
プリンタの情報を内部で独自に持っています.
そのため,DelphiのTPrinterオブジェクトでは制御できません.
(DEVMODE構造体を設定しても,エクセル内部の設定が使用されます)

エクセルの場合,詳細なプロパティを設定して印刷したい場合は,
エクセルのダイアログを表示して印刷してください.
参考コードは,以下にあります.

[エクセルの印刷ダイアログ]
http://mrxray.on.coocan.jp/Delphi/plExcelEx/T_PrintDialog.htm

//=============================================================================
//  [印刷]ボタンクリックでエクセルの印刷ダイアログを表示して印刷する方法
//
//  継承フォームの[印刷]ボタンクリックイベントで
//  (1)inherited; を無効にする
//     (継承元のエクセル操作フォームの印刷コードを無効にする)
//  (2)印刷ダイアログを表示するコードを書く
//
//  エクセルの印刷ダイアログ表示のコードは以下を参照
//  [エクセルの印刷ダイアログ]
//  http://mrxray.on.coocan.jp/Delphi/plExcelEx/T_PrintDialog.htm
//=============================================================================
procedure TplExcelFormEx2.btnPrintClick(Sender: TObject);
begin
//  inherited;

  エクセルの印刷ダイアログ表示のコード,あるいは印刷コードを書く
end;


あるいは,独自の印刷ダイアログを作成するの1つの方法かも知れません
VBAのヘルプを[印刷]で調べるといろいろでてきます.
例えば,印刷対象となっているシートを,倍率を指定して印刷するには,

  xlfExcelSheet.PageSetup.Zoom := 200; //200%の意味
 
でできます.


[3467] まとめ返信 削除
2010/6/17 (木) 14:53:45 Mr.XRAY
拙作コンポ類をご利用いただき,ありがとうございます.

まとめです.
結論として,エクセルの[印刷]ダイアログは使用しない方がよい.

もし,印刷の際にエクセル操作フォームExの印刷ダイアログで設定可能
以外の値を設定したい場合は,

(1) サンプルプログラム集の[016]のコード類を参考に
    その設定用のコントロールを追加し,
    設定した値をエクセルのプロパティにセットする
 
(2) 専用の新しい印刷設定用のダイアログを作成し,
    そこで設定した値をエクセルのPrintメソッドの引数等に与える
 
(3) エクセル操作フォームExの使用は止めて,独自にエクセルを操作する
    コードを作成する
 
ということになるでしょうか.

エクセル操作フォームExでの[印刷プレビュー]の使用は基本的に
無理があります.
また,エラー発生時の時のいろいろな問題は利用者が対応してください.
例えば,DLLを動的にロードしていませんので,あらかじめ存在を確認
するとかですね.

エクセルのオブジェクトの操作についは,サンプルプログラム集にも
ありますので,参考にしてください.
添付のExcelKill.exeを使用しなくて,オブジェクトを取得してKillする
こともできます.

エクセルのダイアログ等が,Delphiのダイアログのような仕様であれば,
問題ないのですが,現状ではいたし方ありません.

以上です.よろしくお願い致します.


[3468] 姑息な方法返信 削除
2010/6/17 (木) 15:53:09 Mr.XRAY
> (1) サンプルプログラム集の[016]のコード類を参考に

を参考に非常に「姑息」な方法を試してみました.
[印刷プレビュー]ボタンの上にTPanelをかぶせてしまう方法です.
ただし,他のウィンドウを前面にして,また戻ると表示されていまいます.

//=============================================================================
//  継承フォームの[印刷]ボタン
//  エクセルの[印刷]ダイアログを表示する
//=============================================================================
procedure TplExcelFormEx2.btnPrintClick(Sender: TObject);
var
    pType    : OleVariant;
    pID      : OleVariant;
    pTag     : OleVariant;
    pVisible : OleVariant;
begin
    MyPanel := TPanel.Create(Self);
    try
      pType    := EmptyParam;
      pID      := 4;
      pTag     := EmptyParam;
      pVisible := EmptyParam;

      try
        xlfExcelApp.CommandBars.FindControl(pType,pID,pTag,pVisible).Execute;
      except
      end;
    finally
      FreeAndNil(MyPanel);
    end;
end;

//=============================================================================
//  このフォームのWndProcメソッド
//  エクセルの[印刷]ダイアログを表示したら,表示前に作成したMyPanel(TPanel)を
//  [印刷プレビュー]ボタンの上に配置して使用不可にする姑息な方法
//=============================================================================
procedure TplExcelFormEx2.WndProc(var Message: TMessage);

  //---------------------------------------------------------------------------
  //  ウィンドウハンドルからウィンドウのタイトルを取得
  //---------------------------------------------------------------------------
  function GetWindowTextStr(hWindow: HWND): String;
  var
      Buffer : Array[0..MAX_PATH-1] of char;
  begin
      Result := '';
      if (GetWindowText(hWindow, Buffer, MAX_PATH)<>0) then begin
        Result := Buffer;
      end;
  end;

//-----------------------------------------------------------------------------
var
  DialogWnd : HWND;
  ARect     : TRect;
  APos      : TPoint;
begin
  inherited;

  if Message.Msg = WM_ACTIVATE then begin
    DialogWnd := Message.LParam;
    if GetWindowTextStr(DialogWnd) <> '印刷' then exit;

    GetWindowRect(DialogWnd, ARect);
    APos.x := ARect.Left;
    APos.y := ARect.Bottom;

    MyPanel.Width        := 150;
    MyPanel.Height       := 30;
    MyPanel.BevelOuter   := bvNone;
    MyPanel.ParentWindow := DialogWnd;

    APos := MyPanel.ScreenToClient(APos);

    MyPanel.Left := APos.X;
    MyPanel.ToP  := APos.Y - MyPanel.Height;
  end;
end;

プロジェクトのダウンロード
http://mrxray.on.coocan.jp/Delphi/zipothers/DD_ExcelPrintDialog_NonPreviewButton.zip


[3469] Re:姑息な方法 修正版返信 削除
2010/6/17 (木) 20:15:46 Mr.XRAY
修正しました.
こちらの方がいいようです.
ダウンロードのプロジェクトも更新しました.
動作確認環境は,Windows XP(SP3) + Delphi 2010 + Excel2000 です.
他の環境では全くテストしていません.

procedure TplExcelFormEx2.WndProc(var Message: TMessage);
var
  DialogWnd : HWND;
  ARect     : TRect;
begin
  inherited;

  if Message.Msg = WM_ACTIVATE then begin
    DialogWnd := FindWindow(nil, '印刷');
    if DialogWnd = 0 then exit;

    Windows.GetClientRect(DialogWnd, ARect); //ClientRectの方がいいですね (^^;

    MyPanel.Width        := 150;
    MyPanel.Height       := 30;
    MyPanel.BevelOuter   := bvNone;
    MyPanel.ParentWindow := DialogWnd;

    MyPanel.Left := 0;
    MyPanel.ToP  := (ARect.Bottom - ARect.Top) - MyPanel.Height;
    MyPanel.Update; //Updateする
  end;
end;

[3476] Re2:姑息な方法 修正版返信 削除
2010/6/18 (金) 19:17:04 Mr.XRAY
>     DialogWnd := FindWindow(nil, '印刷');
>     if DialogWnd = 0 then exit;


これダメですね.Windows 7 + Excel2007でやったら,
エクセル操作フォームExの[印刷]ボタンを検出してしまいました.
前の

    DialogWnd := Message.LParam;
    if GetWindowTextStr(DialogWnd) <> '印刷' then exit;

にしたらOKでした.当然か!?
単に,タイトルが[印刷]のウィンドウを探すのではなく,
アクティブになったウィンドウの[印刷]のウィンドウを探すのだから?


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82