アプリ版:「スタンプのみでお礼する」機能のリリースについて

Excel2000のVBAでFormに配置したコントロールのハンドルを取得するにはどうしたらよいのでしょうか?

目的は、Winsock API(ws2_32.dll)の WSAAsyncSelect関数の2番目の引数にセットする値を取得することです。USER32.dll の GetDlgItem が使用できそうなことがわかったのですが、こちらもその2番目の引数にセットするIDがわかりません。

A 回答 (4件)

すみません、説明がVBベースでした・・・。


メッセージのキャッチ目的なら、KenKen_SPさんの
仰るとおりで完璧だと思います。
もしUserFormをサブクラスせず別オブジェクトに専属させたいのであれば、
RegisterClass,CreateWindow API関数で別の親ウインドウを作成して
クラスモジュールでメッセージハンドラ用プロシージャを
用意して当てればモジュールがすっきりします。
スモールアイコン、拡張スタイルは無関係なので Ex いらずです。
互換プログラミングスタイルで私はVB、VBAでも極力APIで埋め込みますが、
小規模ならKenKen_SPさんのやり方を適用するべきです。
    • good
    • 1
この回答へのお礼

ありがとうございました。
別ウインドウを作成する方法もやってみます。

お礼日時:2007/05/04 10:47

> ウインドウメッセージを捕らえたいのではなく、(特殊な方法で)


> ウインドウメッセージを送りたいのです。

WinSock から通知されてくるメッセージ、例えば FD_READ を捕らえ
たら、recv() をコール...するといった処理をさせるわけではない..
ということですね?

ダミーで良いなら、通知先は Userform で良いのでは?
#2 のコードで得られたハンドルで良いと思います。

Frame などは下記のようなコードで取れるは取れるのですけど、確実に
「この Frame のハンドル」とは取れないのです。

例えば、Form 内に Frame が 2つ配置されていたり、ListBox も配置
されていたら、その内のどれかのハンドル...といった具合です。
したがって、「取れる・取れない」というレベルでは、「取れる」なの
ですが、実用に使えるものではありません。

 # これが Excel VBA の仕様なのでどうしようもないんです...

Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" ( _
    ByVal lpClassName As String, _
    ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" ( _
    ByVal hWnd1 As Long, _
    ByVal hWnd2 As Long, _
    ByVal lpsz1 As String, _
    ByVal lpsz2 As String) As Long

Private Sub CommandButton1_Click()
  
  Dim hWnd As Long
  hWnd = FindWindow("ThunderDFrame", Me.Caption)
  hWnd = FindWindowEx(hWnd, 0&, "F3 Server 60000000", vbNullString)
  hWnd = FindWindowEx(hWnd, 0&, "F3 Server 60000000", vbNullString)
  MsgBox hWnd

End Sub

興味本位で恐縮ですが、メッセージを受け取らないのに、なぜ通知先
が必要なんでしょう? だとしたら、WSAAsyncSelect の意図がよく
分かりません。

あまりご期待に沿う回答ができず、すみません。

この回答への補足

> WinSock から通知されてくるメッセージ、例えば FD_READ を捕らえ
> たら、recv() をコール...するといった処理をさせるわけではない..
> ということですね?

そういう処理をしたいのですが、そういう処理をダミーとして配置したコントロールのイベントとして記述しようとしているのです。

> 興味本位で恐縮ですが、メッセージを受け取らないのに、なぜ通知先
> が必要なんでしょう? だとしたら、WSAAsyncSelect の意図がよく
> 分かりません。
メッセージは受け取りたいのです。メッセージを受けるコントロールがダミーなだけで、メッセージを受けても処理しないわけではありません。

考えていた方法では困難そうですので、
方向転換して、UserFormをサブクラス化する方向で少し検討してみませす。
ありがとうございました。

補足日時:2007/05/04 10:33
    • good
    • 0
この回答へのお礼

ご丁寧に教えていただきありがとうございました。

お礼日時:2007/05/04 10:44

VBA の標準コントロール(Microsoft Forms2 Object Library)は、


一部( ListBox や Frame )を除いてウインドウハンドルを取得
できません。SPY++ で調べるとわかります(^^;

 # テキストボックスなどはハンドルが無いので、FindWindowEx
 # を使っても取得できません。
 
これは、VB6.0 との差別化のための仕様だと思いますが...

WSAAsyncSelect について詳しくはありませんが、ウインドウ
メッセージを捕らえるなら、別にコントロールでなくとも
Userform のウインドウハンドルが取得できれば良いのでは
ありませんか?

Userform のハンドル取得方法は FindWindow API を使用します。

注意点としては、Excel97 と Excel2000以降のバージョンで
クラス名が変更になっている点です。

  クラス名: "ThunderXFrame" ' Excel 97
  クラス名: "ThunderDFrame" ' Excel 2000 Later

もし Excel97 での動作も視野に入れるなら下記のようなコード
で条件分岐させれば良いでしょう。

  sClass = IIf(Val(Application.Version) <= 9, _
       "ThunderXFrame", _
       "ThunderDFrame")
  hWnd = FindWindow(sClass, UserForm1.Caption)

あとはこのハンドルを使って、Userform をサブクラス化すれば
メッセージをフックできると思います。

この回答への補足

丁寧な回答ありがとうございます。

ListBox や Frameのハンドルが取得できるのであれば、目的は達成できるのですが、これはどのようにすれば取得できるのでしょうか?

> WSAAsyncSelect について詳しくはありませんが、ウインドウ
> メッセージを捕らえるなら、別にコントロールでなくとも
> Userform のウインドウハンドルが取得できれば良いのでは
> ありませんか?

ウインドウメッセージを捕らえたいのではなく、
(特殊な方法で)ウインドウメッセージを送りたいのです。(実際に送るのはシステム?がします)
そのために、送り先のコントロールのハンドルが必要になっています。

WSAAsyncSelectは、その為の設定をします。
[使用イメージ]
WSAAsyncSelect(ソケット, 送り先のハンドル, 送信メッセージ, イベント) as エラーコード

メッセージを受けるコントロールはダミーなので、ListBox でも問題ありません。

補足日時:2007/05/03 20:11
    • good
    • 1

コントロールハンドルでしたらやはり


 ≫コントロール名.hwnd(Button1.hwnd のように)
で取得できますが取得実体がなければ、
 1.EnumChildWindows 関数で列挙
 2.GetClassName 関数でクラス名を照合させて洗い出す
後者は動的コントロール作成でも使えます。
(VBプログラマはほとんど使わないですけど・・・)

この回答への補足

早速の回答ありがとうございます。
しかし、、、

Button1.hWnd のようにしてみましたが、「コンパイルエラー メソッド又はデータメンバーが見つかりません」となります。(入力補完でもでてきませんが、なぜか"w"は自動的に大文字になります。Button1.hWnd()ともしてみましたが、同じでした)

> 1.EnumChildWindows 関数で列挙
> 2.GetClassName 関数でクラス名を照合させて洗い出す
これについては、使用方法がわかりませんが、もう少し調べてみます。

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

補足日時:2007/05/03 18:38
    • good
    • 0

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

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


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