外部アプリコントロール

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
メッセージ
作成者
まーくん

外部アプリコントロール

#1 投稿記事 by まーくん »

EXEC等で他のアプリの実行等は可能ですが、
起動させた後のコントロールって可能なんでしょうか?

例えばアプリで文章なり、計算なりさせて値をクリップボードへ保存し
メモ帳を起動した後貼り付けを行う 等
ゲスト

RE:外部アプリコントロール

#2 投稿記事 by ゲスト »

そこまでいろいろなことを実行することが可能か解りませんが、
バッチファイル、リダイレクト、パイプ等を駆使すればある程度のコントロールは可能ではないでしょうか
過去ログにDOSコマンドの実行という記述があります。
http://www.activebasic.com/forum/viewto ... bca06393b8
イグトランス
記事: 899
登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:

#3 投稿記事 by イグトランス »

アプリケーションによっていろいろな方法を使い分けることになりますが,
メモ帳でしたら,メモ帳の中にあるエディットコントロールへ直接メッセージを送り込むのが常套手段だと思います。
まーくん

#4 投稿記事 by まーくん »

レスが付かないと半ば諦めてたんですが…
2つもレスが付いていてビックリです。

>DOSコマンドの実行
リンク先を見ましたけど、ちょっと自分が考えてる物とは違う気がします^^;

> メモ帳でしたら,メモ帳の中にあるエディットコントロールへ直接メッセージを送り込むのが常套手段だと思います。
実際にコントロールしたいのがメモ帳ではないのですが
具体的な方法(クリップボードの内容を貼り付け)を教えて頂けませんか?
そこから自分なりに試行錯誤をしてみたいので。
イグトランス
記事: 899
登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:

#5 投稿記事 by イグトランス »

対象となるエディットコントロールのハンドルをhwndとすると,PostMessage(hwnd, WM_PASTE, 0, 0)でできます。
また、エディットコントロールならSendMessage(hwnd, WM_SETTEXT, でクリップボードを介さず直接テキストを設定することもできます。

そのエディットコントロールのハンドルを知る方法ですが,メモ帳の場合は,メインウィンドウにエディットコントロールが子ウィンドウとして存在するので,
メインウィンドウのハンドルからGetWindowにGW_CHILDを指定してやれば,メモ帳のエディットコントロールのハンドルが得られます。
勿論メインウィンドウのハンドルを手に入れるのもまた一手間かかりますが。

この方法は原理上他のアプリケーションにも応用できますが,
コントロールが複雑に配置されている場合,目的のウィンドウハンドルを手に入れるまでがやや大変かもしれません。
まーくん

#6 投稿記事 by まーくん »

> 対象となるエディットコントロールのハンドルをhwndとすると,PostMessage(hwnd, WM_PASTE, 0, 0)でできます。
> また、エディットコントロールならSendMessage(hwnd, WM_SETTEXT, でクリップボードを介さず直接テキストを設定することもできます。
理解出来たのはここまでです(爆)

> そのエディットコントロールのハンドルを知る方法ですが,メモ帳の場合は,メインウィンドウにエディットコントロールが子ウィンドウとして存在するので,
> メインウィンドウのハンドルからGetWindowにGW_CHILDを指定してやれば,メモ帳のエディットコントロールのハンドルが得られます。
> 勿論メインウィンドウのハンドルを手に入れるのもまた一手間かかりますが。
>
> この方法は原理上他のアプリケーションにも応用できますが,
> コントロールが複雑に配置されている場合,目的のウィンドウハンドルを手に入れるまでがやや大変かもしれません。
もう一歩踏み込んだ解説をお願い出来ないものでしょうか?

こんなアプリを見つけたのですが、これで楽にハンドル取得って出来ないものでしょうか?
時間がある時で構わないので御覧になってみて下さい。
(とりあえずインストまでは行ったのですが活用方法が・・・)
http://www.forest.impress.co.jp/article ... ector.html
ノッチ
記事: 82
登録日時: 2005年6月01日(水) 23:27
お住まい: 北海道札幌市

#7 投稿記事 by ノッチ »

> > この方法は原理上他のアプリケーションにも応用できますが,
> > コントロールが複雑に配置されている場合,目的のウィンドウハンドルを手に入れるまでがやや大変かもしれません。
> もう一歩踏み込んだ解説をお願い出来ないものでしょうか?

起動しているウィンドウのハンドルを取得するにはFindWindow、EnumWindow等
の関数を使用して取得します。
ウィンドウクラスとウィンドウテキストが固定であればFindWindowで取得可能ですが、
(メモ帳のタイトルのように)ウィンドウテキストが変更するもの、複数起動するものは
FindWindowではうまく取得できない可能性があるので、そういった場合はEnumWindow
を使用します。
そしてこの時に取得できるハンドルは親ウィンドウですので、目的のコントロールのハンドル
を取得するにはGetWindowやEnumChildWindowを使用して取得します。

と、ひとつの関数で一気に取得と言うわけにはいかないのです。


> こんなアプリを見つけたのですが、これで楽にハンドル取得って出来ないものでしょうか?
> 時間がある時で構わないので御覧になってみて下さい。
> (とりあえずインストまでは行ったのですが活用方法が・・・)

このようなソフトを使用して、親ウィンドウのクラスと目的のコントロールのIDを調べて
EnumWindowで親ウィンドウのハンドルを取得、そのハンドルをからGetDlgItemで
コントロールのハンドルを取得すればOKです。

ウィンドウハンドルは起動するたびに違う値になってしまうので決め打ちはできないのですが、
IDはソフトのバージョンアップ(これでも基本的には同じ)や動的にコントロールが増えるもの
以外では固定なはずなのでこれを利用するのが簡単(?)だと思います。
まーくん

#8 投稿記事 by まーくん »

ノッチさん、レスどうもです。

> 起動しているウィンドウのハンドルを取得するにはFindWindow、EnumWindow等
> の関数を使用して取得します。
> ウィンドウクラスとウィンドウテキストが固定であればFindWindowで取得可能ですが、
> (メモ帳のタイトルのように)ウィンドウテキストが変更するもの、複数起動するものは
> FindWindowではうまく取得できない可能性があるので、そういった場合はEnumWindow
> を使用します。
> そしてこの時に取得できるハンドルは親ウィンドウですので、目的のコントロールのハンドル
> を取得するにはGetWindowやEnumChildWindowを使用して取得します。
>
> と、ひとつの関数で一気に取得と言うわけにはいかないのです。
今、このレスを見たばっかりなので一通りちょっと調べてチャレンジしてみます。

> このようなソフトを使用して、親ウィンドウのクラスと目的のコントロールのIDを調べて
> EnumWindowで親ウィンドウのハンドルを取得、そのハンドルをからGetDlgItemで
> コントロールのハンドルを取得すればOKです。
>
> ウィンドウハンドルは起動するたびに違う値になってしまうので決め打ちはできないのですが、
> IDはソフトのバージョンアップ(これでも基本的には同じ)や動的にコントロールが増えるもの
> 以外では固定なはずなのでこれを利用するのが簡単(?)だと思います。
このアプリって使えそうなんですね♪
(インストしてみて良かった 笑)

物凄いお馬鹿な質問なんですが、クラス名とウィンドウハンドルって全く別物なんでしょうか?^^;
(どうも頭の中でごっちゃになってしまうので)
ノッチ
記事: 82
登録日時: 2005年6月01日(水) 23:27
お住まい: 北海道札幌市

#9 投稿記事 by ノッチ »

> このアプリって使えそうなんですね♪
> (インストしてみて良かった 笑)

こういったソフトはプログラミング時にあると非常に便利なものなので
インストールしておいて損はないどころかお釣りが返ってくるくらいです。

> 物凄いお馬鹿な質問なんですが、クラス名とウィンドウハンドルって全く別物なんでしょうか?^^;
> (どうも頭の中でごっちゃになってしまうので)

ウィンドウを作成する時にRegisterClassExという関数を使いますが、
その時に使用するパラメータがウィンドウクラスで、ABでは"NORMAL0"です。
"BUTTON"や"STATIC"なんかもウィンドウクラスです。

ウィンドウハンドルは作成したウィンドウを識別する番号のようなもので、
同じウィンドウクラスを使用してウィンドウを2つ作成したとしても、
ウィンドウハンドルは違うものになります。
(コントロールを同じIDで作成してもハンドルは違う値になります)
まーくん

#10 投稿記事 by まーくん »

> こういったソフトはプログラミング時にあると非常に便利なものなので
> インストールしておいて損はないどころかお釣りが返ってくるくらいです。
実はウィンドウハンドルを調べてる時に何を思ったか途中から『クラス名』で検索してたんですよね(笑)
それでこのアプリが引っ掛かってこれって使えそうと喜び勇んで早速インストしてみたという次第です。
ちなみにノッチさん(その他の皆さん)はこう言った便利なアプリは御存知でしたか?
(使う必要の無い方々が多いとは思いますが)

> ウィンドウを作成する時にRegisterClassExという関数を使いますが、
> その時に使用するパラメータがウィンドウクラスで、ABでは"NORMAL0"です。
> "BUTTON"や"STATIC"なんかもウィンドウクラスです。
>
> ウィンドウハンドルは作成したウィンドウを識別する番号のようなもので、
> 同じウィンドウクラスを使用してウィンドウを2つ作成したとしても、
> ウィンドウハンドルは違うものになります。
> (コントロールを同じIDで作成してもハンドルは違う値になります)
普段目にしない関数はちんぷんかんぷんですね^^;
単語を目にして初めてヘルプファイルを参照してみると言う所から入りますから
"BUTTON"はウィンドウクラスってのは未だわかるのですが"STATIC"や”メニュー”等もウィンドウクラスってのがピンときません
そう言うモノだと覚えてしまえば問題は無いのでしょうけども…
まーくん

#11 投稿記事 by まーくん »

色々と調べてる時にイグトランスさんが少し前に投稿されてたコードが使えそうだったので試した所、メモ帳では上手く動作したのですが他のアプリに変更するとダメです。
(イグトランスさんコード拝借いたしました^^;)

>このようなソフトを使用して、親ウィンドウのクラスと目的のコントロールのIDを調べて
>EnumWindowで親ウィンドウのハンドルを取得、そのハンドルをからGetDlgItemで
>コントロールのハンドルを取得すればOKです。
親ウィンドウのクラスは判明したのですが、目的のコントロールIDがわかりません
ソフトをインストして無いとわからないとは思うのですがコントロールIDは何処に表示されているのでしょうか?

コード: 全て選択


#strict

Const FRAME_CLASS = "Notepad"

TypeDef BOOL = Long

TypeDef WNDENUMPROC = *Function(hwnd As HWND, lp As LPARAM) As BOOL

Declare Function EnumWindows Lib "User32" (pEnumFunc As WNDENUMPROC, lParam As LPARAM) As BOOL

Function EnumWindowsProc(hwnd As HWND, lp As LPARAM) As BOOL
    Dim className[ELM(8)] As Byte ' "Notepad"がちょうど収まる大きさ
    GetClassName(hwnd, className, Len (className))
    If lstrcmp(className, FRAME_CLASS) = 0 Then
           PostMessage(GetWindow(hwnd, GW_CHILD), WM_PASTE, 0, 0)
    End If
    EnumWindowsProc = TRUE
End Function

EnumWindows(AddressOf(EnumWindowsProc), 0)
イグトランス
記事: 899
登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:

#12 投稿記事 by イグトランス »

コントロールIDもそのWinspectorなどのソフトで調べられると思います。
まーくん

#13 投稿記事 by まーくん »

> コントロールIDもそのWinspectorなどのソフトで調べられると思います。
えっ、もしや"ID"と書かれてる物でしょうか?
9桁の数字が表示されてるのですが、目的のアプリを起動する都度このID?!が変わってしまうのですが…
イグトランス
記事: 899
登録日時: 2005年5月31日(火) 17:59
お住まい: 東京都
連絡する:

#14 投稿記事 by イグトランス »

毎回違う値になってしまうのであればそれは違うでしょうね。スレッドIDかプロセスIDでしょうか。

私はSpy++を使っていますが,コントロールIDという項目がありました。
#残念ながらこれはVisual Studio付属のものでフリーではありません。
ノッチ
記事: 82
登録日時: 2005年6月01日(水) 23:27
お住まい: 北海道札幌市

#15 投稿記事 by ノッチ »

Winspectorをインストールして見てみました。
左のツリービューでアイテムを右クリック→Propertiesを選択すると
StylesExの下に表示されるIDと言う項目がウィンドウIDになります。
この項目が起動するたびに違う値になるのであれば、
決まったコントロールの配置ではなく、状況に応じて配置するコントロールを変更
している可能性があります。
(ベースとなるIDから+1したIDで次々とコントロールを作成していく等)

そうなると、IDからウィンドウハンドルを取得するのは難しいので、
GetWindowのGW_CHILDやGW_HWNDNEXTで探していくか、
EnumChildWindowでコントロールのハンドルを列挙していって
キャプション、クラス、スタイル、サイズ等を元に目的のウィンドウを探す、
という方法しか思いつきません。

ちなみに何のアプリケーションを操作したいのでしょうか?
IEの画面とかですか?
返信する