C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ownerのWindowハンドルを知りたい

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■92890 / inTopicNo.1)  ownerのWindowハンドルを知りたい
  
□投稿者/ dorago (1回)-(2019/11/05(Tue) 19:21:13)

分類:[VB.NET/VB2005 以降] 

(VB2013〜2017を使用)
Windows Formについて質問があります。
フォームForm1のインスタンスをfとして、
f.Show(owner) または f.ShowDialog(owner) とすると、
ownerオブジェクトの前面にフォームが表示されます。

このownerはIWin32Windowインタフェースを実装していればよく、
例えばコントロールをownerにしてもいいわけですが、
フォームのOwnerプロパティはFormなので、ownerがFormではない場合、
OwnerプロパティはNothingを返します。

この場合、表示フォームのownerのWindowハンドルを知りたいのですが、
方法はありますか?
(Ownerに設定されているIWin32Window型のオブジェクトが分かればよいです。)
引用返信 編集キー/
■92892 / inTopicNo.2)  Re[1]: ownerのWindowハンドルを知りたい
□投稿者/ 魔界の仮面弁士 (2460回)-(2019/11/05(Tue) 20:40:24)
No92890 (dorago さん) に返信
> このownerはIWin32Windowインタフェースを実装していればよく、
> 例えばコントロールをownerにしてもいいわけですが、
極端な話、.NET で管理されていないウィンドウでも構いません。
「メモ帳」や「電卓」のウィンドウを owner とすることもできます。


> 例えばコントロールをownerにしてもいいわけですが、
> フォームのOwnerプロパティはFormなので、ownerがFormではない場合、
> OwnerプロパティはNothingを返します。

――あれ?
通常は TextBox 等を渡したからといって、Nothing にはならないような。

非 Control な IWin32Window を対象としていたり、フォームに貼る前のコントロールを
Owner に引き渡した場合には、Nothing になりえますが…。


Owner が Control である場合は、その Control の FindForm() メソッドの戻り値
(正確には、SetTopLevel(True) な Control までの再帰 Parent 呼び出し)が
フォームの Owner プロパティに渡されるようになっていたはず。


> この場合、表示フォームのownerのWindowハンドルを知りたいのですが、
> 方法はありますか?

リフレクションしか無さそう。

Imports System.Reflection
Imports System.Runtime.CompilerServices
Public Module FormExtension
  <Extension> _
  Public Function GetOwnerHandle(this As Form) As IWin32Window
    Static key As Integer = CInt(GetType(Form).GetField("PropDialogOwner", BindingFlags.NonPublic Or BindingFlags.Static).GetValue(Nothing))
    Static ps As Func(Of Form, Object) = AddressOf GetType(Control).GetProperty("Properties", BindingFlags.NonPublic Or BindingFlags.Instance).GetValue
    Try
      Return DirectCast(CallByName(ps(this), "GetObject", CallType.Method, key), IWin32Window)
    Catch
      Return Nothing
    End Try
  End Function
End Module
引用返信 編集キー/
■92897 / inTopicNo.3)  Re[2]: ownerのWindowハンドルを知りたい
□投稿者/ dorago (2回)-(2019/11/06(Wed) 10:19:02)
> ――あれ?
> 通常は TextBox 等を渡したからといって、Nothing にはならないような。
>
> 非 Control な IWin32Window を対象としていたり、フォームに貼る前のコントロールを
> Owner に引き渡した場合には、Nothing になりえますが…。
>
>
> Owner が Control である場合は、その Control の FindForm() メソッドの戻り値
> (正確には、SetTopLevel(True) な Control までの再帰 Parent 呼び出し)が
> フォームの Owner プロパティに渡されるようになっていたはず。

これは勘違いしていたかも知れません。済みません...


>>このownerはIWin32Windowインタフェースを実装していればよく、
>>例えばコントロールをownerにしてもいいわけですが、
> 極端な話、.NET で管理されていないウィンドウでも構いません。
> 「メモ帳」や「電卓」のウィンドウを owner とすることもできます。

ところで、今開いているメモ帳をownerとするには、どうすればよいでしょうか?
試してはいないのですが、IWin32Windowインタフェースを実装したクラスを自作し、
そのHandleプロパティが、目的とするメモ帳のウィンドウハンドルを返すようにすれば
これをownerとすることができるのでしょうか?
(極端な話、コンストラクタ以外、IWin32Windowインタフェースが指定するHandleプロパティしか
メンバを持たないクラスであっても?)
引用返信 編集キー/
■92899 / inTopicNo.4)  Re[3]: ownerのWindowハンドルを知りたい
□投稿者/ 魔界の仮面弁士 (2462回)-(2019/11/06(Wed) 10:26:25)
No92897 (dorago さん) に返信
> 試してはいないのですが、IWin32Windowインタフェースを実装したクラスを自作し、
> そのHandleプロパティが、目的とするメモ帳のウィンドウハンドルを返すようにすれば
> これをownerとすることができるのでしょうか?

それで owner になります。
内部実装的には、GWL_HWNDPARENT を SetWindowLong しているだけ。
引用返信 編集キー/
■92900 / inTopicNo.5)  Re[4]: ownerのWindowハンドルを知りたい
□投稿者/ dorago (3回)-(2019/11/06(Wed) 10:57:30)
>>試してはいないのですが、IWin32Windowインタフェースを実装したクラスを自作し、
>>そのHandleプロパティが、目的とするメモ帳のウィンドウハンドルを返すようにすれば
>>これをownerとすることができるのでしょうか?
>
> それで owner になります。
> 内部実装的には、GWL_HWNDPARENT を SetWindowLong しているだけ。

ありがとうございました。
リフレクションの件もありがとうございました。
色々と試してみます。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ