PDFファイルを開く – プログラミング – Home

通知
すべてクリア

[解決済] PDFファイルを開く

固定ページ 1 / 2

GG
 GG
(@GG)
ゲスト
結合: 18年前
投稿: 185
Topic starter  

お世話になっています、GGです。

PDFファイルを開きたいのですが、どうしたらいいでしょうか。
例:
ダイアログ上であるボタンをクリックするとEfg.pdfを開くということです。

環境:.Net MFC使用、Win2000

アドバイスよろしくお願いします。


引用未解決
トピックタグ
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

拡張子に関連づいたアプリケーションを動かすのではダメなんでしょうか?
(たとえば、AcrobatReaderとかを動かす)
→ShellExecture関数で出来る。

それとも、自分で pdf の構造を解析して、自分のアプリ上で表示したいのでしょうか?
これをやるとしたら、まずは pdf の構造を理解して、とカナリの工数になりそうです。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

訂正)

>→ShellExecture関数で出来る
ShellExecute


返信引用
GG
 GG
(@GG)
ゲスト
結合: 18年前
投稿: 185
Topic starter  

Blueさん

いつもお世話になっています。

>ShellExecuteEx関数で出来る
うまくできました。

>それとも、自分で pdf の構造を解析して、自分のアプリ上で表示したいのでしょうか?
>これをやるとしたら、まずは pdf の構造を理解して、とカナリの工数になりそうです。

今回はPdfファイルを開くだけです、そこまでにするには、実力がないです。
貴重なアドバイスありがとう。

ほんとに、ありがとうございました。


返信引用
GG
 GG
(@GG)
ゲスト
結合: 18年前
投稿: 185
Topic starter  

追加質問があります。

開いたpdfファイルを閉じると
どうしたらいいでしょうか。

よろしくお願いします。


返信引用
?
 ?
(@?)
ゲスト
結合: 23年前
投稿: 49
 

>開いたpdfファイルを閉じると
>どうしたらいいでしょうか

???閉じたら 何か不都合でも起きたのですか
たとえば自分のアプリにもどらないとか


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

何のために、PDFを表示させるんでしょうか?
確認用に「一定時間だけ表示させたい」ということでしょうか?

ShellExecuteのヘルプを読むとわかると思いますが、
別プロセスとして起動するので、呼び出し元がそのプロセスに対して
どうこうするってことは普通は考えません。
ユーザが普通に×ボタンかなんかで閉じてもらうようにするのが普通です。
(まぁできないこともないが。)


返信引用
GG
 GG
(@GG)
ゲスト
結合: 18年前
投稿: 185
Topic starter  

?, Blueさん、
ご返事ありがとう

説明が不足ですが、
ダイアログのボタンでPDFファイルを開きます、
まだ、このボタンを押すと、既に開いたPDFを閉じて、
別のPDFファイルを開くということです.
当然、PDFのアプリ自身の閉じるボタンがあるのですが、
でも、そのボタンを押さない場合は、
ダイアログ側のボタンを押すと複数PDFを開いた、
そのことを避けたいのです。
(ダイアログ側のボタンを押すと、PDFを閉じる)

よろしくお願いします。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

なにが、PDFを表示していますか?
Adobe Readerでしょうか?

私の環境では、デフォルトで、Adobe Readerの起動オプションに /n がついていないの
で、別のインスタンスとして起動されるようなことはありません。

どんなコマンドで実行されているか確認してください。
(エクスプローラのフォルダオプションあたりで拡張子PDFのものを確認。
Windows2000はどうなっているのか忘れたので詳しくはかけません。)


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

ShellExecuteだと開きっぱなしになるので、
呼び出し元のプロセスから操作(閉じる)をしたければ、
CreateProcessを使いましょう。

「他のAP実行」の実装例
http://www24.cds.ne.jp/~neg/pro/piyo1/index.html#ap


返信引用
GG
 GG
(@GG)
ゲスト
結合: 18年前
投稿: 185
Topic starter  

Blueさん
ご返事ありがとう.

>なにが、PDFを表示していますか?
>Adobe Readerでしょうか?

はい、Adobe Reader Ver.7.0です、
ShellExecuteEx関数で起動が出来ています。

問題なのは、開いたAdobe Readerを閉じるということです。
ようするに、自作したアプリのダイアログ上に配置したボタン
を押すと、Adobe Readerを起動(終了)することです。

よろしくお願いします。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

まぁ、CreateProcessでも出来なくはないですが、Adobe Readerのフルパスが必要になっ
てしまうので、ShellExecuteEx関数で起動後、対象のウィンドウハンドルを探して、
WM_CLOSEをSendMessageするようにしてはどうでしょうか?

※対象のウィンドウハンドルを探すには、FindWindowあたりの関数を使ってください。
ウィンドウタイトルで探せばいいと思います。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> ウィンドウタイトルで探せばいいと思います。
クラス名で探したほうがよかったかも。

ダイアログクラスにCWnd*型のメンバ変数を用意して、
ShellExecuteEx関数の実行後、ウィンドウハンドルを探して保持しておき、
閉じるボタンを押したときに、そのメンバ変数に対してSendMessageします。

適当にやってみた。

○XXXXDlg.h

CXXXXDlgクラス内に

private:
CWnd* m_pPDFExeWnd;

を記述

○XXXXDlg.cpp

CXXXXDlgクラスのコンストラクタにm_pPDFExeWndの初期化処理を記述

CXXXXDlg::CXXXXDlg(CWnd* pParent /*=NULL*/)
: CDialog(CXXXXDlg::IDD, pParent), m_pPDFExeWnd(NULL) // ←これ
{

ボタン1で開く

void CXXXXDlg::OnButton1()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
TCHAR PDFPath[MAX_PATH];

_tcscpy(PDFPath, _T(E:\\test.pdf)); // 適当なファイルのパス

SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(sei);
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
sei.hwnd = this->m_hWnd;
sei.lpVerb = _T(open);
sei.lpFile = PDFPath;
sei.lpParameters = NULL;
sei.lpDirectory = NULL;
sei.nShow = SW_SHOW;

if (::ShellExecuteEx(&sei))
{
// アイドル状態になるまでまつ
::WaitForInputIdle(sei.hProcess, INFINITE);
// すでに開いていないとき、クラス名 AdobeAcrobat として対象の
// アプリを探す。
// ※クラス名はVer6.0のAdobe Readerですので、Ver7.0で取得できない場合
// Spy++でクラス名を確認して適切に変更してください。
if (!this->m_pPDFExeWnd)
this->m_pPDFExeWnd = this->FindWindow(_T(AdobeAcrobat), NULL);
}
}

ボタン2で閉じる

void CXXXXDlg::OnButton2()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
if (this->m_pPDFExeWnd)
{
if (!this->m_pPDFExeWnd->SendMessage(WM_CLOSE))
this->m_pPDFExeWnd = NULL; // 閉じたので
}
}


返信引用
GG
 GG
(@GG)
ゲスト
結合: 18年前
投稿: 185
Topic starter  

たいちうさん、Blueさん

ご返事ありがとう.

>CreateProcessを使いましょう。

CreateProcess()とEnumWindows()で、
閉じることが出来ました。

>if (!this->m_pPDFExeWnd)
> this->m_pPDFExeWnd = this->FindWindow(_T(AdobeAcrobat), NULL);
で閉じることも出来ました。

ありがとうございました。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

>CreateProcess()とEnumWindows()で、
>閉じることが出来ました。
本当にそれでよかったんでしょうか?

前述どおりAdobe Readerのフルパスが必要になります。
きめうちでフルパスを書くと、Adobe Readerのバージョンや
インストールしてあるドライブによっては動きません。
ですので、やはりShellExecuteExを使ったほうがよさそうですけど。
(拡張子PDFに関連づいているアプリのフルパスを取得するにはレジストリを見ることに
なります。)

> if (!this->m_pPDFExeWnd->SendMessage(WM_CLOSE))
> this->m_pPDFExeWnd = NULL; // 閉じたので
ちなみに、ここには間違いがあります。
ボタンでなくユーザが手動でAdobe Readerを閉じると、デバッグモードではASSERTしま
す。
ですので、条件として、ウィンドウハンドルが有効かどうか調べる必要があるでしょ
う。

if (!::IsWindow(this->m_pPDFExeWnd->GetSafeHwnd()) ||
!this->m_pPDFExeWnd->SendMessage(WM_CLOSE))
this->m_pPDFExeWnd = NULL;


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました