ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年3月28日(木) 17:24

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 13 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2008年6月21日(土) 22:57 
オフライン

登録日時: 2006年6月02日(金) 18:20
記事: 106
アプリケーションのヘルプ・メニューからヘルプ(テキストファイル)を
「ShellExecute」APIを使って表示させるようにプログラムを書きました。
それ自体はうまくいったのですが、
ヘルプファイルを開いたまま本体であるアプリケーションを終了させた時
そのヘルプが残ったままという現象に気づきました。
ShellExecuteの戻り値で開いたファイルのインスタンス・ハンドルが
分かるのでそれを使ってどうにかファイルを終了させられないかと
思うのですが、ファイルの終了の方法が分からず。

「アプリケーションを終了時にヘルプファイルが開いたままの場合
それを終了させる」ことの実装について、お知りの方がおられましたら
教えて下さい。


通報する
ページトップ
投稿記事Posted: 2008年6月23日(月) 04:33 
オフライン

登録日時: 2006年6月02日(金) 18:20
記事: 106
ヘルプ・ファイルの「インスタンス・ハンドル」を入れるためのグローバル変数(hHelpFile)、を用意してヘルプの表示時に
コード:
hHelpFile=ShellExecute(hMainWnd,"open",readMe_FullPathName,NULL,NULL,SW_SHOW)
として、
もしアプリ終了時にヘルプが開いたままならそれを閉じるために
メイン・ウインドウのデストロイ・イベントで
コード:
 CloseHandle(hHelpFile)
としてみたのですが、これではヘルプを閉じてくれないようです。
試しに
コード:
DestroyWindow(hHelpFile)
としてもみたのですがこれもダメ。
ウインドウハンドルじゃなくて「インスタンス・ハンドル」ってのが
そもそもどうなんだろうかなと思っているのですが。。。


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2008年6月23日(月) 09:35 
ShellExecute/ShellExecuteExで得られるHINSTANCEはエラーを得るため以外には使えないらしいですが

ShellExecuteの変わりに
CreateProcessかShellExecuteEx使ってみては


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2008年6月23日(月) 11:16 
ヘルプファイルを開いたときに、GetActiveWindow 関数(API)でウインドウハンドルを取得するのはどうでしょうか。


通報する
ページトップ
   
投稿記事Posted: 2008年6月23日(月) 22:33 
オフライン

登録日時: 2006年6月02日(金) 18:20
記事: 106
引用:
ShellExecute/ShellExecuteExで得られるHINSTANCEはエラーを得るため以外には使えないらしいですが

ShellExecuteの変わりに
CreateProcessかShellExecuteEx使ってみては
レスありがとうございます。
自分の調べた限りですが、CreateProcessは「実行ファイル」を開くのに
使われる命令のようで、その他のファイルはShellExecuteが一般的との
印象です。
ShellExecuteExはShellExecuteの拡張版とも言えるもののようなので
やはり元のShellExecuteで出来る筈じゃないかなとも思っています。

それから、GetActiveWindow 関数ですが、もしもShellExecuteの設定で
ファイルをアクティブなウインドウとして開かなかった場合にはどうなるのかなと、、
まだ実際に自分で試してないので何とも言えないのですが。。。


最後に編集したユーザー jacoby [ 2008年6月24日(火) 02:29 ], 累計 1 回

通報する
ページトップ
 記事の件名:
投稿記事Posted: 2008年6月24日(火) 00:16 
オフライン

登録日時: 2005年5月31日(火) 17:59
記事: 899
お住まい: 東京都
正攻法はWinHelp関数やHtmlHelp関数を使うことだと思いますが、自分も使ったことないので正直よく分かりません。
http://www.kumei.ne.jp/c_lang/sdk3/sdk_284.htm

CreateProcessやShellExecuteExが勧められたのは、共に(ShellExecuteと違って)プロセスハンドルを取得できるためでしょう。プロセスハンドルがあれば、TerminateProcess関数で強制終了が可能だからです(一般的に勧められませんが)。TerminateProcessを使わないにしても、プロセスハンドルやプロセスIDが分かれば、それを基に対象のウィンドウハンドルを探せます。そうすれば、そこへWM_CLOSEを送るなど穏便な手段で終了を依頼できます。

ShellExecuteがHINSTANCEを返す理由は、16ビットWindowsではHISNTANCEが今で言うところのプロセスハンドルに近い役割を果たしていたからです。


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2008年6月24日(火) 02:00 
オフライン

登録日時: 2006年6月02日(金) 18:20
記事: 106
引用:
CreateProcessやShellExecuteExが勧められたのは、共に(ShellExecuteと違って)プロセスハンドルを取得できるためでしょう。プロセスハンドルがあれば、TerminateProcess関数で強制終了が可能だからです(一般的に勧められませんが)。TerminateProcessを使わないにしても、プロセスハンドルやプロセスIDが分かれば、それを基に対象のウィンドウハンドルを探せます。そうすれば、そこへWM_CLOSEを送るなど穏便な手段で終了を依頼できます。
レスありがとうございます。
まだ中々内容の理解が追いつかないのですが、
「プロセスハンドル」及び「プロセスID」というものが(二つとも)必要という
ことでしょうか。
それについてWeb上で他に調べていて、このような記事を見つけました。
http://okwave.jp/qa566523.html
この記事からはShellExecuteExでは「プロセスハンドル」は取得できるものの
「プロセスID」は取得出来なさそうな内容で、
「CreateProcessならプロセスIDを取得出来る」とあります。
ただし確か↓ページの説明では
http://detail.chiebukuro.yahoo.co.jp/qa ... 1310043483
引用:
CreateProcessで起動できるのは「実行ファイル」だけなので、
ShellExecuteのようにデータファイルを渡してそれに関連付けされている
アプリケーションを起動するということはできません。

ですので、メモ帳の実行ファイル名と開きたいテキストファイルの名前を
渡してやらなければなりません。
とあり、テキストファイルを「メモ帳」で開くことがあらかじめ前提となっていなくては
ならないような印象も受けます。

うーん、、あれこれ調べてはいるんですけど、何れも大変な処理になりそうな
感じで、何だかヘルプをShellExecute(Ex)やCreateProcess等で開くこと
自体がそもそも不自然なのかもと思えてきます。
そこでイグトランスさんの書かれていた、
引用:
正攻法はWinHelp関数やHtmlHelp関数を使うことだと思いますが、
ですが、これについては今、読ませてもらっています。これが一般的な方法
なのでしょうか。(ただHTML形式のヘルプを作らなければならないようですね。。)
でも、教えていただいて有難うございます。

それにしてもヘルプをShellExecuteで表示したときに比べて、後始末のほうは
何て複雑なんだろうと、、ABのプロジェクトエディターがしっかり開いたままの
ヘルプを閉じて終了する様を眺めつつ、思っています。

ゲストさん、イグトランスさん、レスありがとうございました。
またよろしくお願いします。


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2008年6月24日(火) 09:09 
オフライン

登録日時: 2005年5月31日(火) 17:59
記事: 899
お住まい: 東京都
そうです。ShellExecuteExではプロセスIDが取得できませんが、プロセスハンドルが分かれば、GetProcessId関数でプロセスIDは容易に判明します。言葉足らずでした、すみません。プロセスハンドルとプロセスIDは2つ必要というわけではなく、関数によってどちらを引数に取るかが異なるので、場合によってどちらを使うか変わってくるというだけです。

CreateProcessでも、自分で関連付けされているアプリケーションのパスを調べてくればいいはずなのですが、結構面倒そうなんですよね。


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2008年6月28日(土) 13:38 
> プロセスハンドルやプロセスIDが分かれば、それを基に対象のウィンドウハンドルを探せます。

イグトランスさん、プロセスIDからウィンドウハンドルを探す方法を具体的に教えていただけるとうれしいのですが。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2008年6月28日(土) 15:39 
オフライン

登録日時: 2005年7月25日(月) 13:27
記事: 893
お住まい: 埼玉県東松山市
EnumWindowsとGetWindowThreadProcessIdを上手く使えばいけたと思います。

_________________
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2008年7月01日(火) 08:41 
> EnumWindowsとGetWindowThreadProcessIdを上手く使えばいけたと思います。

konisiさんありがとうございました。何とかなりそうです。


通報する
ページトップ
   
投稿記事Posted: 2009年1月04日(日) 13:06 
オフライン

登録日時: 2008年3月31日(月) 19:04
記事: 11
お住まい: 東京都
AB4.24で外部機器との通信プログラムでヘルプとしてpdfファイルを表示した時に作成したものです。


Dim pi As PROCESS_INFORMATION                                  'CreateProcess実行時に取得する構造体
Dim hApplWnd As HWND
Function EnumWindowsProc(hWnd As HWND, lParam As LPARAM) As LRESULT  'CreateProcessで起動したアプリのHWNDを取得する関数
  Dim lpdwProcessId As DWord
  GetWindowThreadProcessId(hWnd, VarPtr(lpdwProcessId))              'EnumWindowsで得たhWndのProcessIdを取得し
  If pi.dwProcessId = lpdwProcessId Then                             'CreateProcessで取得したProcessIdと同じ
    hApplWnd = GetWindow(hWnd, GW_OWNER)                        'hWndの親hWndを取得する
    If hApplWnd = 0 Then hApplWnd = hWnd
  End If
  EnumWindowsProc = TRUE                                      '全てのhWndをチェック
End Function

'終了イベント
Sub MainWnd_IDM_EXIT_MenuClick()
  If pi.hProcess > 0 Then
    TypeDef WNDENUMPROC = *Function(hWnd As HWND, lp As LPARAM) As BOOL
    Declare Function EnumWindows Lib "user32" (lpEnumFunc As WNDENUMPROC, lParam As LPARAM) As BOOL
    Dim lParam As LPARAM
    EnumWindows(AddressOf(EnumWindowsProc), lParam)
    SendMessage(hApplWnd, WM_CLOSE, 0, 0)
    CloseHandle(pi.hProcess)
    CloseHandle(pi.hThread)
  End If
  SendMessage(hMainWnd,WM_CLOSE,0,0)
End Sub

2月21日追記 エラー報告
このコードではWindowが最小化されていると正常に機能しません。
タスクマネージャで終了しなければならない事になります。
手動(マウス)で元に戻すと正常に機能するのですが OpenIcon で元に戻したのでは
改善されません。

2月24日不具合を修正しコードを変更しました。


最後に編集したユーザー 田中 宏 [ 2009年2月24日(火) 23:34 ], 累計 2 回

通報する
ページトップ
投稿記事Posted: 2009年1月18日(日) 15:49 
日本語が怪しげなのと、VBらしきコードなので・・・あれですが
下記が参考になると思います。

http://support.microsoft.com/kb/242308/ja

ABに書き直しても、それほど手間ではないと思います。


通報する
ページトップ
   
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 13 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: Google [Bot] & ゲスト[7人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
cron
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean