マンガでよめる痔のこと・薬のこと

SendMessageというAPIを試しているのですが、まず試しに
Button2.Text = "test"
と同じ結果をSendMessageでやってみたいのですが
下のようにしてみたのですが、変更になりませんでした。
どのようにすれば良いかご教授頂ければ幸いです。よろしくお願致します。

Private Declare Function SendMessage Lib "user32"
Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer

Private Const WM_SETTEXT As Integer = &HC

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim h As Integer
h = Me.Button2.Handle.ToInt32
SendMessage(h, WM_SETTEXT, 0&, "test")
End Sub

VB.NET2003
FrameWork1.1
WindowsXP-PRO(SP2)
です。

A 回答 (2件)

ボタンの場合はうまく行かないようです



LabelやTextBoxやComboBoxなどはこの方法で変更出来るようです
ただし API呼び出しの後でコントロールのRefreshメソッドなどを呼び出して描画を更新しないといけないようです

CheckBox、RadioButton、Button、ListBoxは変更出来ませんでした

SendMessageのAPI宣言は
  Declare Ansi Function SendMessage Lib "user32" Alias "SendMessageA" _
    (ByVal hWnd As IntPtr, ByVal wMsg As Integer, _
      ByVal wParam As Integer, _
      <MarshalAsAttribute(UnmanagedType.AsAny)> ByVal lParam As Object) As Integer
といった具合の方がより実情に合うかと思います
    • good
    • 0

このように書いてください。



Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer

Const WM_SETTEXT = &HC

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
SendMessage(TextBox1.Handle, WM_SETTEXT, 0&, "test")
End Sub
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QVB.netでSendMessageを使用して電卓を閉じたい

環境:Win XP,VB.net 2003
sendmessageを使用して電卓を閉じるプログラムを作成しているのですが、どうもあと少しでうまくいかないので質問させていただきます。
Dim hfwnd As Long
hfwnd = FindWindowEx(0, 0, "SciCalc", "電卓")
If FindWindowEx(0, 0, vbNullString, "電卓") Then
MsgBox("電卓動いてます。")
Call SendMessage(hfwnd, WM_CLOSE, 0&, 0&)
end if
この時点で電卓が開いているかどうかの判定はうまくいっています。
ですが、sendmessageのところでうまくいっておらず、hfwndに取得したウインドハンドルが代入されていない?と思いGetWindowTextでタイトル取得してみたところ空白でした。電卓をSendMessageを使用して終了させるにはどのようにしたら良いのでしょうか?

Aベストアンサー

> クラス名を同じにしても電卓をいうキャプションを持っているのがcalcだけの為、結局は同じ結果になってしまうのです。

貴方のおっしゃりたい事は分かりますが・・・
でしたら、ちゃんと、同じにしたコードを提示してください。

それから、「hfwnd」の値は確認されましたか?ちゃんと「有効な値」になってますか?

> おそらく問題はifで判断している時は成功しているということは、ハンドルは正常に持ってきているので

このIf文で分かるのは、『「FindWindowEx」の結果が「True」と判断されるものである。』と言うだけであって、
『ハンドルは正常』かどうかは分からないのでは?

#全然関係ないWindowのハンドルを持ってきている可能性だってあります。
#いや、実際「GetWindowTextでタイトル取得してみたところ空白でした。」って事は、全然関係ないハンドルって事でしょうね。


「FindWindowEx」や「SendMessage」の宣言はどうしてますか?

また、
> Dim hfwnd As Long

となってますが、WindowのハンドルってIntegerの範囲なのでは・・・

#VB6までなら、Long型で良かったですが、
#VB.NETでは、型の有効範囲が変わってますのでLongだと誤動作する可能性が・・・
#特に「FindWindowEx」や「SendMessage」の宣言でLong型にしていると、
#ほぼ確実に誤動作を起こすでしょうね。

> クラス名を同じにしても電卓をいうキャプションを持っているのがcalcだけの為、結局は同じ結果になってしまうのです。

貴方のおっしゃりたい事は分かりますが・・・
でしたら、ちゃんと、同じにしたコードを提示してください。

それから、「hfwnd」の値は確認されましたか?ちゃんと「有効な値」になってますか?

> おそらく問題はifで判断している時は成功しているということは、ハンドルは正常に持ってきているので

このIf文で分かるのは、『「FindWindowEx」の結果が「True」と判断されるもので...続きを読む

QVB.netでFindWindowExやると・・・9222812402616107008!?

VB.netでWin32APIのFindWindowExを使うと,
たとえばスタートボタンのHWNDを拾ってくるとき,
本当なら65662(6.0のSpy++で確認+10進変換)が返ってきて欲しいんですが,
9222812402616107008という,異常な数が返ってきます.

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, <MarshalAs(UnmanagedType.LPTStr)> ByVal lpsz1 As String, <MarshalAs(UnmanagedType.LPTStr)> ByVal lpsz2 As String) As Long
とやってあります.
VB6.0のAPIビューワからコピペして,MarshalAsをつけてみました. 
 (初心者なので,わけわからないまま付けましたけど;

hWnd_ShellTrayWnd = FindWindowEx(0,0,"Shell_TrayWnd",vbNullString)
hWnd_StartButton = FindWindowEx(hwnd_ShellTrayWnd,0,"Button",vbNullString)
とやってるのですが・・・.
不思議なのは,hWnd_ShellTrayWndが9222812402616238204になっているにもかかわらず,次のFindWindowExで,hWnd_StartBtnが9222812402616107008になってるところです・・・. しかも,ありえないクラス名(KeyBoadぐちゃぐちゃ押し)を指定しても,なぜか数が返ってくるんです.

FindWindowExを成功させる(きちんとした数を取る)方法,またはFindWindowEx以外でhWndを拾ってくる方法,ありましたら,教えてください.

VB.netでWin32APIのFindWindowExを使うと,
たとえばスタートボタンのHWNDを拾ってくるとき,
本当なら65662(6.0のSpy++で確認+10進変換)が返ってきて欲しいんですが,
9222812402616107008という,異常な数が返ってきます.

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, <MarshalAs(UnmanagedType.LPTStr)> ByVal lpsz1 As String, <MarshalAs(UnmanagedType.LPTStr)> ByVal lpsz2 As String) As Long
とやってあります.
...続きを読む

Aベストアンサー

あちゃぁ、英語のサイトから持ってきたのでコメント診て無かったです。すみません。
翻訳しても良くわからなかったですが、どう見ても記述が違いますね。

で、再度アドバイスです。

>Private Declare Function FindWindowEx ~
Integerを全てLongに書き換えてやってますよね。

引数・戻り値を全てIntegerにしてやって見てください。
当方では、問題なくウィンドウハンドルの取得が出来ましたよ。
ちなみに、MarshalAs属性は使用しなくてOKでした。
使用すると、戻り値が0になりました。

当方で確認したソースを記述します。
以下よりソース。

Option Strict Off
Option Explicit On

Imports System.Runtime.InteropServices

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
  (ByVal hWnd1 As Integer,
  ByVal hWnd2 As Integer,
  ByVal lpsz1 As String,
  ByVal lpsz2 As String) As Integer

  Private Sub Form1_Load(ByVal eventSender As System.Object, _
             ByVal eventArgs As System.EventArgs) Handles MyBase.Load
    Dim hWnd_StartButton As Integer
    Dim hwnd_ShellTrayWnd As Integer

    hwnd_ShellTrayWnd = FindWindowEx(0, 0, "Shell_TrayWnd", vbNullString)
    hWnd_StartButton = FindWindowEx(hwnd_ShellTrayWnd, 0, "Button", vbNullString)

    System.Diagnostics.Debug.WriteLine(hwnd_ShellTrayWnd & ";" & hWnd_StartButton)
End Sub

あちゃぁ、英語のサイトから持ってきたのでコメント診て無かったです。すみません。
翻訳しても良くわからなかったですが、どう見ても記述が違いますね。

で、再度アドバイスです。

>Private Declare Function FindWindowEx ~
Integerを全てLongに書き換えてやってますよね。

引数・戻り値を全てIntegerにしてやって見てください。
当方では、問題なくウィンドウハンドルの取得が出来ましたよ。
ちなみに、MarshalAs属性は使用しなくてOKでした。
使用すると、戻り値が0になりました。

当方で確...続きを読む

QVB6.0の「vbFromUnicode」はVB.NETではどれに相当しますか?

VB6.0で、例:StrConv(Text, vbFromUnicode)とかで使用する、
「vbFromUnicode」(文字列を Unicode からシステムの既定のコードページに変換する)
は、VB.NETでは使用できないようです。(相当する定数はない?)

「vbFromUnicode」と同等の機能を、VB.NETで使用したいのですが、
どうすれば良いでしょうか?

Aベストアンサー

思いっきり、例文に「COM1」と書いてますが、USBに書き換えてくださいね^^;

それとふと思ったのですが
udtReaderWriterModeWithoutEncryption
変数は構造体ですよね?

メンバが
lngPortName
lngBardRate
というのは、型宣言をINTEGERに変換してますよね?

ちょっとばかり不安に思ったので、追記しておきました。

参考URL:http://okweb.jp/kotaeru.php3?q=1257613

QCloseとDisposeの違い

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、タイマーコントロールのイベントに記述していますと、それは実行され続けます。

これを防ぐために、Me.Dispose() を使います。すると、きれいにプロセスは終了し、イベントは発生しない模様です。

そこで、「フォームを閉じる」意味のMe.Close() をすべてMe.Dispose() に変えてしまいました。確実にプロセスを破棄出来ると思ったからです。Webで調べると、違いは「再利用できる、できないの違い」という答えがありましたが、それはきっと、ファイルやオブジェクトのことで、フォームの場合は、再びShowまたはShowDialogで表示させることは可能でしたので、特に問題は感じていませんでした。

ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。Me.Close() に変えるとうまくいきました。

わけわからなくなってきました。。。

ちなみに、その残ったフォームは、スタートアップフォームであり、別のフォームからShowまたはShowDialogメソッドで呼び出したものではありません。

ここで4つの仮説を立ててみました。

1. ShowDialogで呼び出したフォームは、Me.Dispose()、Showで呼び出した、あるいは、スタートアップフォームは、Me.Close() すれば破棄できる

2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

3. 呼び出し方ではなく、別の要因が存在する

4. 併記する必要がある場合がある

Me.Close()
Me.Dispose()

または、

Me.Dispose()
Me.Close()



どれが正しいのでしょうか?どなたがご存じの方がいらっしゃいましたら、ご教授いただけませんでしょうか? どうぞよろしくお願い申し上げます。ありがとうございました。

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、...続きを読む

Aベストアンサー

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。
Me.Close() に変えるとうまくいきました。

通常はどちらでもうまくいきます。

>2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

ShowDialogの場合は、メソッド内部で、ハンドルが破棄されているため、Close()メソッドの際にDispose()メソッドが呼び出されます。

>3. 呼び出し方ではなく、別の要因が存在する

そう思います。

>4. 併記する必要がある場合がある

インスタンスを明示的に破棄したほうがよい場合は多く存在します。
Disposeが使えるメンバはIDisposableをインターフェースとして持っているメンバです。
これらのメンバは、外部とのやり取りを行うものが多くあります。
たとえばSQLClientに含まれるようなメンバです。

外部とのコネクションを確実に破棄を保障してほしいなどという場合がありますよね、このようなときに使用します。

Using構文を使用するのとまったく同じ理由になります。
正確にはUsing構文を使用できるメンバには条件があります、IDisposableをインターフェースとして持っているメンバに限るというものです。

ほかにもガーベージコレクタによるファイナライズを伴うかどうかという違いがあります。
Disposeの場合はファイナライズが同時に行われるため、使用していたメモリ空間を開放することができます。

上記のような理由により、
Me.Close()
Me.Dispose()
は両方書いたほうがよいと思います。

蛇足ですが、
Me.Dispose()
Me.Close()
はエラーになります。
Me.Dispose()により、Me本体(インスタンス)は削除されてしまいます。
存在しないMeに対してCloseメソッドを要求することはできないためです。

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリ...続きを読む

Q親ウインドウにあるOKボタンを押す方法

非常に基本的なことを質問して申し訳ございません。

●やりたいこと●
ある親ウィンドウに「テキスト」と「OKボタン」があります。
OKボタンはひとつだけです。
このOKボタンを押して、親ウィンドウを閉じるだけです。
OKボタンを押せば、親ウィンドウは勝手に閉じます。


親ウィンドウのハンドルは取得できたのですが、
子ウィンドウ(ボタン"OK")のハンドルが取得できず、
その後の処理もできておりません。

ボタンはひとつだけなので、ボタンのハンドルを検索したりしなくても、
押すことはできるような気がするのですが・・・
初心者の浅知恵で申し訳ございません。

やはり、ボタンのハンドルを取得して、押すコマンドを実行しないといけないのでしょうか?

ボタンのハンドルを取得して、押すコマンドを実行する場合、
その方法を教えていただけると幸いです。

親ウィンドウのハンドルは変数「hWindow」に入っているとして、
コードをお願いいたします。

親ウィンドウのハンドル取得に使ったFindWindow以外に宣言が必要であればご教授お願いいたします。

非常に基本的なことを質問して申し訳ございません。

●やりたいこと●
ある親ウィンドウに「テキスト」と「OKボタン」があります。
OKボタンはひとつだけです。
このOKボタンを押して、親ウィンドウを閉じるだけです。
OKボタンを押せば、親ウィンドウは勝手に閉じます。


親ウィンドウのハンドルは取得できたのですが、
子ウィンドウ(ボタン"OK")のハンドルが取得できず、
その後の処理もできておりません。

ボタンはひとつだけなので、ボタンのハンドルを検索したりしなくても、
押すことはでき...続きを読む

Aベストアンサー

子ウィンドウを探すには、下の2つのAPIの使います。

  EnumChildWindows(hWnd,lpEnumFunc,0&)
  GetClassName(hWnd,lpClassName,nMaxCount)

EnumChildWindows が、親ウィンドウのハンドルと、子ウィンドウを受け取る関数を
与えます。ただし、子ウィンドウを受け取る関数はフォームモジュールではなく、
標準モジュールにないと駄目です。

すると与えた子ウィンドウを受け取る関数に、親ウィンドウに含まれる全ての子ウィンドウの
ハンドルが返ってきます。

返ってきたハンドルを元に GetClassName で、クラス名を取得し、ボタンのウィンドウを
特定します。今回の場合は、ボタンが1個しかないとのことなので、取得したクラス名が
Buttonであればそのハンドルがボタンのハンドルになります。
参考までに、複数個のボタンがあれば、この場合、どのボタンがOKボタンなのかを特定しない
といけません。「スパイ」とか言うソフトがあれば簡単に特定できるのですが、ない場合は、
子ウィンドウに含まれる、上記の手順で得た全てのボタンのハンドルに対して、プログラムで
BM_CLICKのメッセージを送り一つづつ確認していくしかありません。ただこの場合でも、
特性があって、親ウィンドウに複数個のボタンがあっても、子ウィンドウを受け取る関数には
必ず一定の順番にしか、ハンドルが返ってきないので、最初に一度だけ何番目のボタンかを特定
すればよいです。対象のアプリケーションを再度起動してもこの順番は変わりません。

あと、ボタンのクリックは、SendMessageで、BM_CLICK を送ればOKです。

今回は、簡単な他アプリの制御なので、そんなに問題がないですが、複雑な制御だと、
更に、ウエイトの方法だとか、制御するアプリが確実に動作しているか、確認する操作を
1ステップずつ挿入していかないと駄目です。そうすれば、全ての他のアプリケーションを
自由に操る事ができます。

本格的に作るとなると大変なので、フリーのソフトで沢山でていると思います。一度さがされたら
よいと思います。DLLタイプになっているのがよいとは思います。
以前私も使ったことがありますが、憶えていません。あしからず。現在は自作しております。
自作のがよりきめ細かく制御出来るからです。

子ウィンドウを探すには、下の2つのAPIの使います。

  EnumChildWindows(hWnd,lpEnumFunc,0&)
  GetClassName(hWnd,lpClassName,nMaxCount)

EnumChildWindows が、親ウィンドウのハンドルと、子ウィンドウを受け取る関数を
与えます。ただし、子ウィンドウを受け取る関数はフォームモジュールではなく、
標準モジュールにないと駄目です。

すると与えた子ウィンドウを受け取る関数に、親ウィンドウに含まれる全ての子ウィンドウの
ハンドルが返ってきます。

返ってきたハンドルを元に G...続きを読む

Q他のアプリケーションとの連携

 VBを使って他の既存のソフトなどへ何らかの命令をかけることは可能でしょうか?
 
 具体的には起動中のほかのアプリケーションへキー操作をさせる…というようなことは可能でしょうか?

 たとえば、コマンドを設置しておいて、そのコマンドをクリックすると起動中の別のアプリケーション上でEnterキーを押した状態を引き起こさせるというようなことです。
 
 また、それとは逆に他のアプリケーションを監視して、キーが押されたときに反応させるというようなことは可能でしょうか?

 API関数等を使用するのでしたらどういう関数を使用すればよいか教えてください。
 よろしくお願いします。

Aベストアンサー

># 反論~にどうぞ。
(゜ .゜)ノ カンシャ デス
真意をわかっていただいて、うれしいです。^^


サンプルです。

このサンプルを実行するには二つのプロジェクトが必要となります。

Project1
└Form1
  ├Command1
  └Command2
'Form1の中身
Option Explicit

Private Sub Command1_Click()
  MsgBox 1
End Sub

Private Sub Command2_Click()
  MsgBox 2
End Sub
と記載して、ボタンが押されたらメッセージボックスを表示するようにしておきます。
これをEXEにして起動しておいてください。



Project2
└標準モジュール
'標準モジュールの中身
Option Explicit

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const WM_COMMAND = &H111
Private Const BN_CLICKED = &H0&

Sub Main()
  Dim lngWindWnd As Long 'ウィンドウハンドル
  Dim lngBtnWnd1 As Long '最初に見つかったボタン
  Dim lngBtnWnd2 As Long '2番目に見つかったボタン
  
  
  'アプリケーションタイトルより、ウィンドウハンドル得ます
  lngWindWnd = FindWindow(vbNullString, "Form1")
  
  
  '指定のウィンドウハンドル内の、最初に見つかったクラス名[ThunderRT6CommandButton](VB6で作成したコマンドボタン)のハンドルを得ます
  '【注意:2番目の引数が0(Nullポインタ)のとき、最初に見つかったものを返すように指定している】
  lngBtnWnd1 = FindWindowEx(lngWindWnd, 0, "ThunderRT6CommandButton", vbNullString)
  Call SendMessage(lngWindWnd, WM_COMMAND, BN_CLICKED, ByVal lngBtnWnd1)
  
  
  '指定のウィンドウハンドル内の、2番目に見つかったクラス名[ThunderRT6CommandButton](VB6で作成したコマンドボタン)のハンドルを得ます
  '【注意:2番目の引数が0以外(Nullポインタではない)とき、2番目のパラメータ以降に見つかったハンドルを返すように指定している】
  lngBtnWnd2 = FindWindowEx(lngWindWnd, lngBtnWnd1, "ThunderRT6CommandButton", vbNullString)
  Call SendMessage(lngWindWnd, WM_COMMAND, BN_CLICKED, ByVal lngBtnWnd2)
End Sub




といった感じです。
一番最初にサンプルを載せたかったのですが、ちょっと納期前ということで、説明を簡略化してしまいました。


>一文字(Enterキー)を渡すだけならSendKeysでも問題はないかな..
たしかにそうですね。。。
話を戻しますが、#3で書いた電子電○帳と連携したソフトですが、目的のボタンにたどりつくために、[TAB]を数回送った後に[ENTER]を送っていました。最初から目的のボタンにフォーカスがあるのであれば、全然問題ないのですが、、、

なので、処理によってはSendkeysで十分だと思いますが、2回以上のSendkeysが連続するようなのであれば、OSの状況に影響されないAPIを使うことをお奨めします。

># 反論~にどうぞ。
(゜ .゜)ノ カンシャ デス
真意をわかっていただいて、うれしいです。^^


サンプルです。

このサンプルを実行するには二つのプロジェクトが必要となります。

Project1
└Form1
  ├Command1
  └Command2
'Form1の中身
Option Explicit

Private Sub Command1_Click()
  MsgBox 1
End Sub

Private Sub Command2_Click()
  MsgBox 2
End Sub
と記載して、ボタンが押されたらメッセージボックスを表示するようにしておきます。
これをEXEにして起動しておい...続きを読む

Q別のアプリケーションのテキストフィールドに入力する方法

他のアプリケーションのテキストフィールドがフォーカスを持っていて、そこにテンキーの「1」を入力した場合、「おはよう」と表示され、さらに改行コードも送れるプログラムを作りたいと思っています。

ヒントが掲載されているHPや書籍などの情報があれば教えていただきたいと思います。 また、お手数でなければ、具体的なコードも教えていただければありがたいです。

開発環境は VB6、OSはXP ProSP2 です。

Aベストアンサー

キーフックを使って作るのが王道のようですが、
どうもややこしそうなので思いついたソースだけ記述します。
質問者さんの思っている動きとは違うかもしれませんが、、。

以下ソースをVBで実行後、
Windows標準のメモ帳を起動し1を入力してみてください

'--------------以下貼り付けてください-----------------
Private Declare Function FindWindowA Lib "user32" (ByVal cnm As String, ByVal cap As String) As Long
Private Declare Function FindWindowExA Lib "user32" (ByVal hpar As Long, ByVal hchi As Long, ByVal cnm As String, ByVal cap As String) As Long
Private Declare Function SendMessageA Lib "user32" (ByVal hwd As Long, ByVal Msg As Long, ByVal wpara As Long, ByVal lParam As Any) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Const WM_GETTEXT = &HD
Const WM_SETTEXT = &HC

Private Sub Form_Load()

Dim hwd As Long, hwd_c As Long
Dim cap As String, ret As Long

cap = Space$(200)

Do

'メモ帳のハンドル取得
hwd = FindWindowA(vbNullString, "無題 - メモ帳")

'メモ帳のテキストハンドル取得
hwd_c = FindWindowExA(hwd, 0, "Edit", "")

'メモ帳のテキストを取得
ret = SendMessageA(hwd_c, WM_GETTEXT, 200, cap)

'メモ帳のテキストを検索
If InStr(1, cap, "1", vbTextCompare) > 0 Then
'1が入力されているなら置き換えて送信
Call SendMessageA(hwd_c, WM_SETTEXT, 0, "おはよう" & vbCrLf)
End If

DoEvents
Sleep (1000)

Loop

End Sub
'---------------------------------------------

'以下参考にしたURLです
http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/vb_t02.htm
http://hpcgi1.nifty.com/MADIA/VBBBS/wwwlng.cgi?print+200606/06060083.txt

キーフックを使って作るのが王道のようですが、
どうもややこしそうなので思いついたソースだけ記述します。
質問者さんの思っている動きとは違うかもしれませんが、、。

以下ソースをVBで実行後、
Windows標準のメモ帳を起動し1を入力してみてください

'--------------以下貼り付けてください-----------------
Private Declare Function FindWindowA Lib "user32" (ByVal cnm As String, ByVal cap As String) As Long
Private Declare Function FindWindowExA Lib "user32" (ByVal hpar As Long, B...続きを読む

Qウィンドウにキー送信で ENTER を送りたい

指定されたキャプションのウィンドウに ENTERキーを送りたいのですが、ものによって送れるものと送れないものがあります。

キャプションが"印刷"のものにキー送信をしているのですが、ExelやWordなどのクラス名が取得できる("bosa_sdm_XL9"等)ものだと送信でき、IE、秀丸などのクラス名が取得できないもの("#32770"と表示される)だと送信できません。

お分かりになられる方がおりましたら、ぜひ教えてください。

Aベストアンサー

>指定されたキャプションのウィンドウに ENTERキーを送りたいのですが、
>ものによって送れるものと送れないものがあります。

どうやって送ってるんですか?それを書いていただかないとなにも判断できませんが。

QEnumChildWindowsの使い方(VBA)

64bit版ExcelのVBAでEnumChildWindowsを使用して、子ウィンドウのウィンドウハンドルを
取得したいと考えています。
下記のようなサンプルを作ってみましたが、コールバック関数でExcelが異常終了します。
(05行目にブレークポイントを設定、各変数の値を参照しようとした時点でExcelが異常終了)

また、コールバック関数の第3引数(lParam)の型をInteger,Long,LongPtr等変えてみましたが、
いずれもExcelの異常終了となりました。

つきまして、64bit Excelでの本APIの使い方を教えていただきたくよろしくお願いいたします。
(なお、32bit版のExcelでは正常に動作しました)

<以下サンプルコード>
行 コード
01   Declare PtrSafe Function EnumChildWindows Lib "user32.dll" (ByVal ParenthWnd as LongPtr, ByVal EnumWindosPROC as LongPtr,ByVal lParam as Long) as Integer
02
03
04 Function ListupChildWindows(hWnd as LongPtr,lParam as Long) as Boolean
05 MsgBox hWnd
06 ListupChildWIndows =True
07 End Function
08
09 Sub test_CwinList
10 Dim ThishWnd as LongPtr
11
12 ThishWnd=Excel.Application.hWnd
13 Call EnumChildWindows (ThishWnd , AddressOf ListupChildWindows ,0)
14 End Sub

64bit版ExcelのVBAでEnumChildWindowsを使用して、子ウィンドウのウィンドウハンドルを
取得したいと考えています。
下記のようなサンプルを作ってみましたが、コールバック関数でExcelが異常終了します。
(05行目にブレークポイントを設定、各変数の値を参照しようとした時点でExcelが異常終了)

また、コールバック関数の第3引数(lParam)の型をInteger,Long,LongPtr等変えてみましたが、
いずれもExcelの異常終了となりました。

つきまして、64bit Excelでの本APIの使い方を教えていただきたくよろしくお...続きを読む

Aベストアンサー

こんにちは。

ご提示のサンプルですが、当方のVBA7x64環境でも
(実行の度に無条件で必ず)Excelの異常終了を再現できました。

この問題の解決については、私の力量を越えていますので、
情報提供、という形でお応えします。

『APPS PRO > VBA Tips > How Can I Locate a Specific Child Window Handle?』
http://www.appspro.com/Tips/VBA%20Tips.htm
こちらのページの一番下の[EnumChildWindows]をクリックすると
x32|x64両方対応のサンプルコードが入手できます。
そのままこちらで試してみた処、
(このサンプルは、ThisWorkbook.Windows(1)のハンドル'だけ'を取得するものなので)
エラーにはなりませんでした。
コールバック関数側で、条件分岐を書き換えてみたり、
無条件でWindowClassやWindowTitleを取得するよう試みたりして、
約30(重複を含む)の子ウィンドウのウィンドウハンドルが取得出来る所までは確認しましたが、
すべてを取得出来ていないか、うまく終了させることが出来ていないか、どちらかで、
完全な動作を確認するには至りませんでした。
デバッグのヒントにはなりそうな気はしますので、サンプル試してみては如何でしょう。

もしうまく行く方法があるとすれば、
WindowClassとWindowTitleでの条件分岐を整理して、
適切に列挙を終了させることになるような気がしています。
例えばThisWorkbook.Windows(1)のWindowClassとWindowTitleが確認できたら、
(そこから数えてx番目の子ウィンドウで、、、x = 0 かも?)
コールバック関数の戻りを0にして列挙を終了する、、、、みたいな?
或いは、特定の子ウィンドウに限定できるなら、同様にうまく扱えるようにも思えます。

実践的には、同じハンドルが重複して戻る場合があることを考慮して、
ハンドル列挙の受け皿としてCollectionオブジェクト等を用いることになるかと思いますが、
もしかしたら、この戻り値の重複についてもチェックしてみた方がいいのかも??知れません。

参考になるか解りませんが、以上です。

こんにちは。

ご提示のサンプルですが、当方のVBA7x64環境でも
(実行の度に無条件で必ず)Excelの異常終了を再現できました。

この問題の解決については、私の力量を越えていますので、
情報提供、という形でお応えします。

『APPS PRO > VBA Tips > How Can I Locate a Specific Child Window Handle?』
http://www.appspro.com/Tips/VBA%20Tips.htm
こちらのページの一番下の[EnumChildWindows]をクリックすると
x32|x64両方対応のサンプルコードが入手できます。
そのままこちらで試してみた処、
(このサ...続きを読む

QVisual Basic でのコードをASCII変換、16進変換したものを元に戻す方法を教えてください

string(9)のエリア"Aa1アあa "の文字を1文字ずつASCII変換して、16進変換し、string(18)のエリアに格納します
すると"416131B182A08281202020"と変換されます
(一文字ずつ Hex(Asc(Buf))を使用しました)

逆に、"416131B182A08281202020"を"Aa1アあa "に戻したいのですが、
どのような関数を使えばよいのかわかりません。
困っています。教えてください。よろしくお願いいたします。

Aベストアンサー

VB既存の関数ではできないと思うので、自分で関数を作るなりしてください。

ヒントです。
ASC関数により変換された2バイト文字(シフトJIS)の1バイト目は81~9FおよびE0~FC(すべて16進)になります。
16進数から10進数に戻すには、頭に"&H"をつけます。(&H82A0 = 「あ」のシフトJISコード)
文字を数字に変換するのはVal関数、数字(文字コード)から文字に変換するのはChr関数です。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング