DOBON.NETプログラミング道掲示板

■ 「新規作成」から投稿できます。
■ マルチポストされた投稿を見つけたときは、その投稿に返信することによりご報告ください。その際は匿名で投稿し、マルチポストされている場所を併記してください。
■ スパム対策のため、メールアドレスの先頭に"_"という文字が付加されています。
RSS 2.0 RSS 2.0 | RSS 0.91 | 携帯電話用 | 自分専用のアイコンを使用するには | 掲示板への要望 | 管理人に連絡 | お気楽掲示板
■ 24時間以内に作成されたスレッドは New で表示されます。
■ 24時間以内に更新されたスレッドは UpDate で表示されます。

記事リスト ( )内の数字はレス数
UpDate共変性と反変性ってこういうこと?(4) | Nomalモードレスフォーム Warning IDE0067を回避したい(7) | NomalLINQの拡張メソッドの定義(1) | Nomalこんな演算子初めて見ました。(5) | Nomalプロセスからウインドウを取得(4) | Nomalフォーム外のカーソルの変更(2) | NomalLINQのメソッド構文の書き方(3) | NomalVB.NETでCSVを読み込む際にSQL文を使いたい(3) | NomalRichTextBoxで入力文字の自動折り返しを止めたい(2) | NomalRichTextBoxで入力文字の自動折り返しを止めたい(5) | Nomalラムダ式の勉強中(2) | NomalWebClientで、短期間にDownloadStringAsyncを実行したい(2) | Nomalvb.net+SQLiteで複数データベースファイルへのトランザクション方法(3) | NomalNewの使い方間違ってますか?(4) | Nomalジェネリック型インターフェースを使った変数を扱いたい(3) | NomalC#をVBに変換(2) | NomalProcess.WaitForExitで正常に動作しない?(3) | NomalCatch時のex.StackTraceの情報(3) | Nomalユーザーコントロール内のテキストボックスのmodifiedプロパティ(4) | NomalPictureBox.Locationのキャンセル(3) | NomalJOIN操作の構文エラー(4) | NomalVisualStudioでマクロ(3) | NomalVisualStudioでExcelのVSTO開発(3) | NomalOracleDataAccess を参照したプログラムでデバッグモードが機能しなくなる(3) | NomalIE11では表示されるが、.netのWebBrowserでは、表示されないHPを表示する方法(7) | NomalマウスのないOSでマウスカーソルの表示(2) | NomalRDP接続でのネットワーク帯域制限(0) | NomalFILE.COPYでIOExceptionエラーが出る(11) | NomalToolStripMenuItemにShortcutKeysを指定した際の、元のコントロールを取得する方法(2) | Nomal動的にプロパティや変数の値の取得(4) | NomalVB6 ほかのアプリケーションを起動し そのアプリケーションは終了させる方法(4) | NomalMouseEventArgsのカレント座標(2) | Nomalリッチテキストボックスでの字間の調整(2) | NomalDrawImage でメモリ不足エラー(3) | Nomal必須コンポーネントの一覧に追加したい(0) | NomalCode128でバーコードが読み取れない(8) | NomalあるWindows10PCでビルドしたEXEがW8.1以下で実行エラー(5) | NomalApp.configのMy.Application.Log設定で使用できない属性が出る(0) | NomalVC++ → VB.Netに変換時に文法エラー(2) | Nomalvb2010を使用したmicrosoft Wordの任意の行の削除(0) | NomalVb.netからAccessへの接続について(3) | NomalSQL-Server Compact 4.0が表示されない(2) | Nomalバーコードの数字を非表示にしたい(2) | Nomal令和の日付への対応(3) | Nomalスクロールバーが出た時に高さを変えたい(4) | Nomal自作したアプリの発行元を明記したい(2) | NomalHTTP 417エラーを発生させるためのIIS設定はどうすればよいか(3) | Nomal起動ディスプレイの指定方法について(6) | NomalSystem.Threading.Thread.Sleep()と変数(2) | NomalVisual Studio DataTableの値のアクセスの仕方(2) | NomalDatagridviewのクリア(2) | NomalDataGridView 行の背景色の設定(2) | NomalListBoxにデータが表示されない(6) | NomalPIctureBox同士を論理合成したい(3) | NomalDrawString前のFillRectangle有無により文字の太さが違う理由について教えて下さい(3) | Nomalポルトガル語の登録(5) | NomalnumericUpDwonコントロールのvalue(2) | Nomalデータセット定義ファイルからDataTable(3) | NomalDataTableの構造が同じか調べるメソッド(2) | Nomalネットの画像の複数枚を重ね合わせたい(3) | Nomalリストを別フォームに渡す方法(9) | Nomal例外発生した場合に変数をcatchに渡したい(9) | NomalRejectChangesについて(2) | Nomal数字だけで構成されてるCSVフィールドが自動的に数値として解釈される(7) | NomalDataGridViewで検索をかける方法(3) | NomalDataGridViewの選択時の色を透明にしたい(3) | NomalPC機種によってスタートアップ画面が中央から左上にずれる、Fontがおかしくなる。(2) | Nomalタスクスケジュール登録時の例外メッセージ(2) | Nomal参照dllへの文字列引数をutf8で渡したい。(13) | Nomal管理者モードでクリック(2) | NomalVB2017でのインストーラ作成時のエラーについて(2) | Nomal文字列を8bit に戻してから UTF-8 に変換する方法(6) | NomalDatagridViewの行高さ変更について(4) | NomalWebRequest でメモリが解放されない(1) | NomalWebBrowserでWebページからのメッセージ(3) | NomalASP.NETから呼ばれているかどうか判定する方法(3) | NomalCA2213の警告が消えません(3) | NomalSQLServerテーブル内容をDataGridViewに表示するコードについて(6) | Nomaloo4oのAddTableをADOに移行したい(5) | Nomalデータバインド時のDataGridViewのカスタムソート(2) | NomalFunction プロシージャからの文字選択(1) | NomalMicrosoft Azure OCRのサンプルコード実行時エラー(2) | Nomal文字列構造体のListのソート(6) | NomalフォームコントロールへのDataBindingsでプロパティが相互反映されない(7) | NomalC# 現在のコンテキスト内にxxxという文字は存在しませんと出ます(3) | NomalWinFormsでWindows10のカメラアプリと連携したい(0) | NomalObject型からDecimalへの変換(2) | NomalWindows10(1803)からGetHostEntryでipv4が取得出来ない場合がある(2) | Nomalユーザーコントロールのプロパティが保存されない(2) | Nomal擬似言語をVBのプログラミングに変換(2) | Nomal「Environment.SpecialFolder.MyDocuments」の戻り値(2) | Nomalエクスプローラーのポインタ下のアイテムの取得(8) | NomalGIFで使うPNGファイルにおける容量削減について(5) | NomalProcess.StartでPDFファイルが開かない(Windows10)(3) | Nomal定数を複数繰り返す時(1) | Nomaloo4oのAddTableをODP.NETに移行したい(2) | NomalWindows標準TCPIPポートについて(4) | Nomalユーザーコントロールをツールバーに表示できない(8) | Nomalレンタルサーバからファイルを取得する方法を教えてください。(12) | NomalIEnumerableについてまとめてみました。(2) |



■記事リスト / ▼下のスレッド
■34410 / 親記事)  共変性と反変性ってこういうこと?
□投稿者/ VBはじめました 一般人(25回)-(2019/12/05(Thu) 13:36:59)
  • アイコン環境/言語:[VisualStudio2017 VB.net] 
    分類:[.NET] 

    ジェネリックを勉強していると、共変性と反変性ってでてきます。
    ググればググるほどよくわからなくなるのですが、次ような解釈で問題ないでしょうか?
    詳しい方いらっしゃいましたら教えて頂けないでしょうか?
    
    (以下、自分なりの解釈)
    ジェネリック型は、さまざまなデータ型に対して、同じ機能を実行させるために必要な処理を行うプログラミング機能を提供します。ジェネリック型のメソッドは、呼び出し側が提供するデータ型に合わせてデータ型を指定してインスタンスを作成して使用することになります。その際、完全にデータ型を合致させることが望ましいのですが、場合によってが、融通性を持たせたい場合が発生します。例えば、List<String>型データとArray型のデータに対して同じ機能を実行いたい場合、List<String>型とArray型に対するジェネリック型インスタンスをそれぞれ作って使用すればいいことになります。しかし、ジェネリック型メソッドがデータソースに求める機能が列挙をベースとしたものであれば、IEnumerable<String>型で定義すれば、一つのデリゲート定義でList<String>型とArray型のデータソースが受け取れるという融通性を得ることができます。この際、呼び出し側のデータ型と受け取り側のデータ型が異なるため、データ変換処理が発生します。List<T>クラス、Arrayクラスは、共にIEnumerable<T>を実装していますので、IEnumerable<T>と比べて強い派生型(狭い型)と言えます。即ち、強い派生型から弱い派生型への型変換がなされたということになります。その際に、データとしての互換性がある状況の場合を反変性があると言います。同様な状況は、メソッドからの返り値の受け渡しでも発生し、返り値の場合は、逆に弱い派生型から強い派生型へ変換する必要があり共変性といいます。次の例は、List(Of Integer)型,Array型をIEnumerable(Of Integer)型として受け取り、なんらかの処理をした後、IEnumerable(Of  Integer)型を返し、List(Of  Integer)型、Array型として受け取った。というものです。
    
    (サンプルコード)
       Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim myList As New List(Of Integer)(New Integer() {1, 2, 3, 4, 5})
            Console.WriteLine("渡したデータ型は、{0}", myList.GetType)
            Dim RetList = Enume(myList)
            Console.WriteLine("返されたデータ型は、{0}", RetList.GetType)
            Console.WriteLine("---------")
            Dim myArray() As Integer = {1, 2, 3, 4, 5}
            Console.WriteLine("渡したデータ型は、{0}", myArray.GetType)
            Dim te2 = Enume(myArray)
            Console.WriteLine("返されたデータ型は、{0}", te2.GetType)
        End Sub
        Function Enume(MyEnume As IEnumerable(Of Integer)) 
                           As IEnumerable(Of Integer)
            Console.WriteLine("受け取ったデータ型は、{0}", MyEnume.GetType)
            '何らかの処理をしたと仮定
            Return MyEnume
        End Function
    
    解釈の内容が正しいのかと、サンプルとして適切かどうか?
    教えて頂けないでしょうか?

違反を報告
引用返信

▽[全レス4件(ResNo.1-4 表示)]
■34411 / ResNo.1)  Re[1]: 共変性と反変性ってこういうこと?
□投稿者/ 魔界の仮面弁士 大御所(1268回)-(2019/12/06(Fri) 11:05:31)
  • アイコン2019/12/06(Fri) 20:03:48 編集(投稿者)

    No34410に返信(VBはじめましたさんの記事)
    > (以下、自分なりの解釈)
    改行無い 苦行じゃない?
    その説明 C# 混じってない?


    > 例えば、List<String>型データとArray型のデータに対して同じ機能を実行いたい場合、
    ここの文面は、List(Of String) に直したほうが良いですね。


    > メソッドからの返り値の受け渡しでも発生し、返り値の場合は、
    間違っているわけではないのですが、Return Value については、
    一般的には「戻り値」と呼びます。Microsoft の資料でもそうなっているはず。


    > 次ような解釈で問題ないでしょうか?
    概要としては間違っていないと思います。


    ただし『配列』については、まだジェネリックが無かった当時の名残で、
    特例措置として共変性を持つように設計されている点に注意して下さい。
    本来は、配列に関して共変性を認めるべきではないのですが、
    互換性の都合で、ここの仕様は変更できなかったのですね。

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
      Dim x() As List(Of Button) = Nothing
      'Dim y() As List(Of Control) = x 'これは NG(コンパイルエラー)

      Dim b() As Button = {Button1}
      Dim c() As Control = b '歴史的な事情から、配列は共変となっています


      'このような場合、書き込み(反変)は本来 NG ですが、コンパイルできてしまいます。
      'そのため、実行時に ArrayTypeMismatchException 例外となってしまいます。
      c(0) = Me '本来は List(Of ) 同様、コンパイル時に検出できるのが望ましい。
    End Sub



    > ジェネリックを勉強していると、共変性と反変性ってでてきます。

    これ自体はジェネリックに限定した用語では無いですね。

    『型の共変性』とは、広い型から狭い型へ変換が常に安全に行えること。(Covariance)
    『型の反変性』とは、狭い型から広い型へ変換が常に安全に行えること。(Contravariance)
    『型の双変性』とは、広い型にも狭い型にも変換できること。(Bivariance)
    『型の不変性』とは、型を変換できないこと。(Invariance)


    上記にある「広い型」や「狭い型」ですが、ジェネリックで使われる場合、
    たとえば Double と Integer などの関係性を示しているのではありません。

    ここでは継承・派生・インターフェイス実装などの関係性、たとえば
    「TextBox のインスタンスを Control 型の引数に代入しても問題無い」とか
    「Control 型の戻り値なプロパティから TextBox のインスタンスが取得されても問題無い」
    といった関係性を指しています。


    さて、VB2010 / C# 2010 からは、ジェネリックの型パラメーターに対して
    Out / out キーワードで共変性を、In / in キーワードで反変性を
    指定できるようになりました。
    『ジェネリックを勉強していると、共変性と反変性ってでてきます。』というのも
    それが要因でしょう。

    そのため、「ジェネリックにおける共変性と反変性」について学ぶのであれば、
    In/Out キーワードについても、合わせて学んでおくべきかと思います。

    ジェネリックの共変性と反変性について書かれた下記の記事でも、In や Out が出てきますね。
    https://www.atmarkit.co.jp/fdotnet/chushin/vb2010features_01/vb2010features_01_03.html



    提示頂いたサンプルにおいて、 IEnumerable(Of T) ジェネリック型インターフェイスが登場しています。
    この型についてヘルプで調べてみると、VB2008 (.NET Framework 3.5) までは
      Public Interface IEnumerable(Of T)
       Implements IEnumerable
    という定義であると書かれていたのに対し、VB2010 (.NET Framework 4) からは
      Public Interface IEnumerable(Of Out T)
       Implements IEnumerable
    であることが分かるはずです。Out が付与されたことで、共変性を明示することができます。

    一方、反変性の In については、Action(Of T) ジェネリック型デリゲートなどで使われています。
    VB2008 付属の .NET Framework 3.5 ヘルプでは
      Public Delegate Sub Action(Of T) (obj As T)
    という定義だったものが、.NET Framework 4 からは
      Public Delegate Sub Action(Of In T)(obj As T)
    という定義に変わっていますね。



    > サンプルとして適切かどうか?

    共変性と反変性の説明のためのサンプルとして書いたのであれば、
    どの部分が共変性で、
    どの部分が反変性を示しているのかを、
    コメントで説明した方が良いかと思います。


    また、Visual Basic のサンプルとしてなら、

    '『渡したデータ型は、System.Collections.Generic.List`1[System.Int32]』
    Console.WriteLine("渡したデータ型は、{0}", myList.GetType)
    '『渡したデータ型は、System.Int32[]』
    Console.WriteLine("渡したデータ型は、{0}", myArray.GetType)

    よりも

    '『渡したデータ型は、List(Of Integer)』
    Console.WriteLine("渡したデータ型は、{0}", TypeName(myList))
    '『渡したデータ型は、Integer()』
    Console.WriteLine("渡したデータ型は、{0}", TypeName(myArray))

    の方が分かりやすいと思います。


    それと、Function の宣言途中で改行する場合、
    「As IEnumerable(Of Integer)」の前に改行を入れてはいけません。
    改行するなら As の後に加えた方が良いでしょう。もしも As の前で改行したいなら、
    その前に行継続文字「 _」が必要なはずです。 (半角の空白とアンダーバー)
違反を報告
引用返信
■34412 / ResNo.2)  Re[2]: 共変性と反変性ってこういうこと?
□投稿者/ 魔界の仮面弁士 大御所(1269回)-(2019/12/06(Fri) 11:46:15)
  • アイコン2019/12/06(Fri) 20:08:09 編集(投稿者)

    No34411に補足(魔界の仮面弁士の記事)
    > https://www.atmarkit.co.jp/fdotnet/chushin/vb2010features_01/vb2010features_01_03.html

    Visual Basic におけるジェネリックの共変性と反変性については
    上記記事でも記載されていますが、追加で説明してみます。


    たとえば、
     Dim txt As TextBox = Me.TextBox1
     Dim item As Control = txt
    というコードが問題無いことは分かりますよね。
    TextBox は Cotrol を継承していますので、問題なく代入できるわけです。


    では何故、下記のコードはエラーになるのでしょう?

    Public Class Form1
      Private items As List(Of Control)

      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim textBoxes As New List(Of TextBox)
        textBoxes.Add(Me.TextBox1)
        textBoxes.Add(Me.TextBox2)
        textBoxes.Add(Me.TextBox3)

        Me.items = textBoxes 'コンパイルエラー
      End Sub
    End Class


    TextBox 型は Control を継承しているので、一見問題無さそうに見えます。

    しかし、上記のような代入を認めてしまうと、
      Me.items(0) = Me.Button1
    のように、TextBox 以外のインスタンスに書き換えられてしまう恐れが生じます。

    Me.items が参照しているのが List(Of TextBox) のインスタンスだとしたら、
    そこに Button という、TextBox 以外のデータが格納されるのはマズイわけです。

    そのため、List(Of TextBox) のインスタンスを List(Of Control) 型の変数に
    代入することはできないように制限されています。
    ※その逆に、List(Of Control) 型のインスタンスを List(Of TextBox) 型に渡すのも駄目です。



    さて上記では、代入によって書き換えられるのが問題であるとされています。

    では、型パラメーターが「常に取得専用」でのみ使われる場合はどうでしょうか?
    items 変数の型を下記のように変更した場合は、エラーにはならずに済みます。

    Public Class Form1
      'Private items As List(Of Control)
      Private items As IEnumerable(Of Control)

      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim textBoxes As New List(Of TextBox)
        textBoxes.Add(Me.TextBox1)
        textBoxes.Add(Me.TextBox2)
        textBoxes.Add(Me.TextBox3)

        Me.items = textBoxes 'IEnumerable(Of ) への代入は OK
      End Sub
    End Class


    上記の処理が認められているのは、List(Of T) の時とは違って「入力」ができないためです。
    たとえば、List(Of Control) だと行えていた下記の処理は、IEnumerable(Of Control) だと行えません。
      Me.items(0) = Me.Button1


    IEnumerable(Of T) インターフェイスでは、型パラメーターで指定された
    T 型もしくは T を継承した型を、「出力方向だけ」にしか使用しない仕様です。

    そこでこのように、
     『指定された型パラメーターが、出力(戻り値、ReadOnly Property)にしか使われない』
    ことを明確に伝えられるよう、VB2010 からは Out キーワードをつけて宣言できるようになりました。

    > Public Interface IEnumerable(Of Out T)


    上記を踏まえて、先ほどの共変性と反変性の件と In / Out キーワードがどう関わってくるかを見てみます。


    '=== 「In」なので「入力」にしか使われていない
    Public Interface ISample1(Of In T As Control)
      'この型パラメータ T では In によって『共変性』が保証されており、
      ' T 型は常に「広い型から狭い型へ変換するだけ」の実装になっている
      Sub Test(ByVal x As T)
      WriteOnly Property Prop As T
      'たとえば Of Control で実装された場合に、上記メンバーに対して
      'Label インスタンスや Form インスタンスを「入力」したとしても、何の問題も無い
    End Interface


    '=== 「Out」なので「出力」にしか使われていない
    Public Interface ISample2(Of Out T As Control)
      'この型パラメータ T では Out によって『反変性』が保証されており、
      ' T 型は常に「狭い型から広い型へ変換するだけ」の実装になっている
      Function Test() As T
      ReadOnly Property Prop As T
      'たとえば Of Control の場合に、上記メンバーの戻り値から
      'Label インスタンスや Form インスタンスが「出力」されてきたとしても、何の問題も無い
    End Interface


    '=== 双変の場合(つまり共変と反変の両方がありうる場合)は
    '=== In も Out も付与できない(付与するとコンパイルエラー)
    Public Interface ISample3(Of T As Control)
      Sub Test(ByRef x As T)
    End Interface
    Public Interface ISample4(Of T As Control)
      Property Prop As T
    End Interface
違反を報告
引用返信
■34413 / ResNo.3)  Re[3]: 共変性と反変性ってこういうこと?
□投稿者/ VBはじめました 一般人(26回)-(2019/12/06(Fri) 23:46:38)
  • アイコン魔界様いつもすみません。

    >改行無い 苦行じゃない?
    これについては、私の方が、ビックリしました。
    当然、自動で改行されるものとおもっていました。

    >その説明 C# のじゃない?
    まさしく、その通りかもしれません。
    VBでググると情報が少なく、レベルの低い私は、いまだに、.NETにおいては、VBとC#は書き方が違うだけでイコールである。の範疇を脱することが出来ていません。よって、C#との違いを理解しないまま、C#の記事をも参考にしています。そのせいもあり、余計にこんがらがっており、質問させて頂きました。
    しかし、見る人が見れば、説明が支離滅裂なのにも関わらず、参考にした文献の言語も判別でいるのにはビックリしました。

    >「広い型」や「狭い型」がDouble と Integer などの関係性を示しているのではありません。

    まさしく、そこがポイントです。ググるとString型、Objecto型。継承の関係。デリゲートとインターフェース。こんがらがるばかりです。

    Out/Inキーワードについては、Function/Actionの関係でなんとなく解った気でいますが、本質は分かっていないんだと感じています。

    VB,.NET Fraeworkのバージョンによってヘルプが変わっていることは、言われてみれば当然なことですが、それを調べられるように環境を整えているのにもビックリしました。

    >共変性と反変性の説明のためのサンプルなのだとしたら、
    どの部分が共変性で、
    投稿した後に、私も感じました。単に、IEnumerableが使えるよってサンプルになっていることを・・
    やはり、FunctionとActionで分けて考えるべきでした。

    Public Class Form1
      Private items As List(Of Control)

      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim textBoxes As New List(Of TextBox)
        textBoxes.Add(Me.TextBox1)
        textBoxes.Add(Me.TextBox2)
        textBoxes.Add(Me.TextBox3)

        Me.items = textBoxes 'コンパイルエラー
      End Sub
    End Class

    を、コピペしてみると、VisualStudioにIEnumerableを使うことを考えろと怒られました。
    ただ、魔界さんの解説がなかったら、なんで?ここで?IEnumerableなの?
    って、疑問で、こんどは、IEnumerableでググって・・・・
    すると・・次のキーワードが出てきて、また、ググって・・・・
    同じところを、グルグル回って進みません。

    一つの解説書を順に・・とも思うのですが、頭が悪い分、理解できない部分があると、ググって・・・

    当座の最終目的は、ForEach文で、検索、抽出部分をLINQで書いて簡素にしようって
    ことなのですが、山が高くて 苦労しています。

    なんだか?魔界さんに個人レッスン料払わないとだめかな?って感じています。
    教えて頂いたおかげで、なんだか、気力が湧いてきました。
    なんとか、年内には、LINQを使えるようになれたらな?って考えています。

    もうすぐ、.NET Frameworkの時代が終わって、NET5になるって記事を読んだので
    この際、Framework4の基礎的な部分だけでも・・・と思っていますが
    同期、非同期、Yield、など、エベレスト級の山がそびえているので、どこまで
    いけるやら・・・

    少し、愚痴りましたが、教えて頂いたことは、無駄にすること無い様に熟読させて
    頂いて、なんとか習得に繋げたいと考えています。

    いつも、いつも有難うございます。




違反を報告
引用返信
■34414 / ResNo.4)  Re[4]: 共変性と反変性ってこういうこと?
□投稿者/ VBはじめました 一般人(27回)-(2019/12/06(Fri) 23:47:11)
  • アイコン解決忘れ
解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-4]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■34402 / 親記事)  モードレスフォーム Warning IDE0067を回避したい
□投稿者/ katu 一般人(1回)-(2019/11/28(Thu) 15:04:01)
  • アイコン環境/言語:[VB.NET 2019] 
    分類:[.NET] 

    VisualBasic 2019 Warning IDE0067

    使用済のオブジェクトを破棄しろ、という警告でしょうが

    モードレスフォームの表示コードではUsingまたはTry文はなじまないと思います


    Dim f as New frmA
    f.Show(Me)
    とするとこの警告が出ます

    メインフォームから frmA を表示するものとして
    どこでフォームを宣言して
    どこでモードレスフォームの表示コードを書き
    どこでどのような破棄コードを書けばいいのでしょうか?

    ご教示ください

    その他2019では数多くの IDE Warning が出ますが
    でなくなる、または少なくする設定があればご教示ください


違反を報告
引用返信

▽[全レス7件(ResNo.3-7 表示)]
■34405 / ResNo.3)  Re[3]: モードレスフォーム Warning IDE0067を回避したい
□投稿者/ katu 一般人(3回)-(2019/11/29(Fri) 10:38:05)
  • アイコンNo34404に返信(katuさんの記事)

    > サンプルプロジェクト添付しようとしましたが
    > 502Bad Gateway
    > となりました

    おかしな現象がありました
    オリジナルのサンプルプロジェクトではIDE0067がでるのですが
    zio作成が悪かったのかと思い送ろうとしたzipを解凍して
    プロジェクトを読み込む正常に読み込み、IDE0067はでません




違反を報告
引用返信
■34406 / ResNo.4)  Re[3]: モードレスフォーム Warning IDE0067を回避したい
□投稿者/ 魔界の仮面弁士 大御所(1267回)-(2019/11/29(Fri) 10:46:03)
  • アイコンNo34404に返信(katuさんの記事)
    > Community 2019 バージョン16.3.10

    こちらも 16.3.10 です。Enterprse 2019 ですけれど。

    新規プロジェクトにおいては、既定では分析機能は有効になっておらず、
    提示のコードを入力するだけでは警告が表示されることは無いはずです。

    どこかの時点で、意図的に分析設定を有効にしていたのでしょう。


    > サンプルプロジェクト添付しようとしましたが
    > 502Bad Gateway
    > となりました

    では、規則セットは分かりますか?

    検証コードの .vbproj をメモ帳で開いた上で、XML タグの

    ・/Project/Import の一覧
    ・/Project/PropertyGroup/CodeAnalysisRuleSet

    の内容を教えてください。
    新規プロジェクトだと、上記のどちらも存在しないことがありますので、
    現象の発生しているプロジェクトの物で確認して下さい。
違反を報告
引用返信
■34407 / ResNo.5)  Re[4]: モードレスフォーム Warning IDE0067を回避したい
□投稿者/ katu 一般人(4回)-(2019/11/29(Fri) 12:58:03)
  • アイコンNo34406に返信(魔界の仮面弁士さんの記事)

    お送りしようとしたプロジェクトは新規作成ですが

    Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim f As New Form2
    f.Show(Me)
    End Sub

    これでIDE0067が出ました

    このプロジェクトファイルには
    CodeAnalysisRuleSet
    は、ありません

    <Import Include="Microsoft.VisualBasic" />
    <Import Include="System" />
    <Import Include="System.Collections" />
    <Import Include="System.Collections.Generic" />
    <Import Include="System.Data" />
    <Import Include="System.Drawing" />
    <Import Include="System.Diagnostics" />
    <Import Include="System.Windows.Forms" />
    <Import Include="System.Linq" />
    <Import Include="System.Xml.Linq" />
    <Import Include="System.Threading.Tasks" />

違反を報告
引用返信
■34408 / ResNo.6)  【報告】この投稿はマルチポストです
□投稿者/ (報告) 大御所(272回)-(2019/11/29(Fri) 21:36:45)
  • アイコンこの投稿はマルチポストです。もし元記事の投稿者にマルチポストの心当たりがない場合は、すぐに返信でお知らせください。

    ●マルチポストされている場所
    https://social.msdn.microsoft.com/Forums/ja-JP/b72dc588-38a8-45b7-87dd-a136001b0e2c/warning0067?forum=vsgeneralja

    ----------
    この掲示板ではマルチポストが禁止されています。詳しくは、「書き込みのルールについて」をお読みください。

    ●書き込みのルールについて
    https://dobon.net/vb/bbs/index.html
違反を報告
引用返信
■34409 / ResNo.7)  Re[6]: 【報告】この投稿はマルチポストです
□投稿者/ katu 一般人(5回)-(2019/11/30(Sat) 09:26:13)
  • アイコンNo34408に返信((報告)さんの記事)
    > この投稿はマルチポストです。もし元記事の投稿者にマルチポストの心当たりがない場合は、すぐに返信でお知らせください。
    >
    > ●マルチポストされている場所
    > https://social.msdn.microsoft.com/Forums/ja-JP/b72dc588-38a8-45b7-87dd-a136001b0e2c/warning0067?forum=vsgeneralja

    魔界の仮面弁士さん、みなさま
    申しわけございませんでした

    以下で警告されなくなりましたのでご迷惑お掛けしましたが
    解決とさせていただきます


    Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim completionSource As New System.Threading.Tasks.TaskCompletionSource(Of Object)
    Using fas As New frmA
    AddHandler fas.FormClosed, Sub()
    completionSource.TrySetResult(Nothing)
    End Sub
    fas.Show(Me)
    Await completionSource.Task
    End Using
    End Sub
解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-7]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■34400 / 親記事)  LINQの拡張メソッドの定義
□投稿者/ ジャッキーチュン 一般人(1回)-(2019/11/28(Thu) 09:45:00)
  • アイコン環境/言語:[VisualStudio2017 VB] 
    分類:[.NET] 

    はじめまして。

    LINQの拡張メソッドの定義で、
    <Extension()>
    Public Function Where(Of TSource)
    (source As IEnumerable(Of TSource), predicate As Func(Of TSource, Integer, Boolean))  ←ここに()で括られた部分がある
    As IEnumerable(Of TSource)
    のようにかかれています。

    Function メッソッド名(引数)の次に()で括られたものがあり、
    その後に、As IEnumerble(Of TSource)となっています。

    ()で括られた部分は、何をするのでしょうか?
    普通は、
    Public Shared Function Format (format As String, arg0 As Object) As String
    こんな感じですよね?

    もう一つ、Formを作って、Designerを見ると
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
    のように、<>で括られたものがあります。
    これは、なんですか?

    教えて貰えれば助かります。


違反を報告
引用返信

▽[全レス1件(ResNo.1-1 表示)]
■34401 / ResNo.1)  Re[1]: LINQの拡張メソッドの定義
□投稿者/ 魔界の仮面弁士 大御所(1265回)-(2019/11/28(Thu) 11:11:32)
  • アイコンNo34400に返信(ジャッキーチュンさんの記事)
    > Function メッソッド名(引数)の次に()で括られたものがあり、
    メッソッド → メソッド


    > その後に、As IEnumerble(Of TSource)となっています。
    > ()で括られた部分は、何をするのでしょうか?

    「(Of 何某)」の事なら、『型パラメーター』と呼ばれる物です。

    Dim a As System.Collections.IEnumerable
    Dim b As System.Collections.Generic.IEnumerable(Of Integer)
    Dim c As System.Collections.Generic.IEnumerable(Of String)
    Dim d As System.Collections.Generic.IEnumerable(Of Boolean)


    上記の場合、
     a.GetEnumerator().Current は As Object
     b.GetEnumerator().Current は As Integer
     c.GetEnumerator().Current は As String
     d.GetEnumerator().Current は As Boolean
    のようになります。※「IEnumerable」と「IEnumerable(Of T)」は別の型です。


    型パラメーターを受け取るクラスを「ジェネリック クラス」と呼び、
    型パラメーターを受け取るメソッドを「ジェネリック メソッド」と呼びます。
    https://docs.microsoft.com/ja-jp/dotnet/visual-basic/programming-guide/language-features/data-types/generic-types?WT.mc_id=DT-MVP-8907


    > もう一つ、Formを作って、Designerを見ると
    > <System.Diagnostics.DebuggerNonUserCode()> _
    > Protected Overrides Sub Dispose(ByVal disposing As Boolean)
    > のように、<>で括られたものがあります。

    それは『属性』と呼ばれる物です。

    上記の場合、Dispose メソッドに対して
    System.Diagnostics.DebuggerNonUserCodeAttribute 属性クラスが
    付与されています。

    https://docs.microsoft.com/ja-jp/dotnet/visual-basic/programming-guide/concepts/attributes/?WT.mc_id=DT-MVP-8907
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-1]



■記事リスト / ▼下のスレッド / ▲上のスレッド
■34393 / 親記事)  こんな演算子初めて見ました。
□投稿者/ VBはじめました 一般人(22回)-(2019/11/25(Mon) 16:06:55)
  • アイコン環境/言語:[VisualStudio2017 VB.net] 
    分類:[.NET] 

    左外部結合の実行に載っていた次のコードに対しての質問です。
    https://docs.microsoft.com/ja-jp/dotnet/csharp/linq/perform-left-outer-joins
    
    (質問1)
    コメント@のKeyは、必要でしょうか?削除しても、同じ動作をしますが、動作を明示するためにわざわざつけた方がよいという意味でしょうか?
    
    (質問2)
    コメントAにある二項演算子で使われているものですが、VBに、こんな演算子ってありましたけ?subpet?.Name
    ビルドすると問題なく動作します。
    
    注:このコードは、C#→VBの変換をWebで行ったものを整理したものです。
    
    詳しい方いらっしゃいましたら、教えて頂けないでしょうか?
    
    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim magnus As Person =
                New Person With {.FirstName = "Magnus", .LastName = "Hedlund"}
            Dim terry As Person =
                New Person With {.FirstName = "Terry", .LastName = "Adams"}
            Dim charlotte As Person =
                New Person With {.FirstName = "Charlotte", .LastName = "Weiss"}
            Dim arlene As Person =
                New Person With {.FirstName = "Arlene", .LastName = "Huff"}
    
            Dim barley As Pet =
                New Pet With {.Name = "Barley", .Owner =
                    terry}
            Dim boots As Pet =
                New Pet With {.Name = "Boots", .Owner =
                    terry}
            Dim whiskers As Pet =
                New Pet With {.Name = "Whiskers", .Owner =
                    charlotte}
            Dim bluemoon As Pet =
                New Pet With {.Name = "Blue Moon", .Owner =
                    terry}
            Dim daisy As Pet =
                New Pet With {.Name = "Daisy", .Owner =
                    magnus}
    
            Dim people2 As List(Of Person) =
                New List(Of Person) From {
                    magnus,
                    terry,
                    charlotte,
                    arlene}
            Dim pets2 As List(Of Pet) =
                New List(Of Pet) From {
                    barley,
                    boots,
                    whiskers,
                    bluemoon,
                    daisy}
    
            Dim query = From person In people2
                        Group Join pet In pets2
                            On person Equals pet.Owner
                            Into gj = Group
                        From subpet In gj.DefaultIfEmpty()
                        Select New With {
                            person.FirstName,
                           Key .PetName = '@
                            If(subpet?.Name, String.Empty)} 'A
    
            For Each v In query
                Console.WriteLine($"{v.FirstName & ":"}{v.PetName}")
            Next
            'OutPut:
            'Magnus: daisy
            'Terry:  barley
            'Terry:  boots
            'Terry:  Blue Moon
            'Charlotte: whiskers
            'Arlene:
        End Sub
    
        Class Person
            Public Property FirstName As String
            Public Property LastName As String
        End Class
    
        Class Pet
            Public Property Name As String
            Public Property Owner As Person
        End Class
    
    End Class
    

違反を報告
引用返信

▽[全レス5件(ResNo.1-5 表示)]
■34394 / ResNo.1)  Re[1]: こんな演算子初めて見ました。
□投稿者/ 魔界の仮面弁士 大御所(1261回)-(2019/11/25(Mon) 16:30:19)
  • アイコンNo34393に返信(VBはじめましたさんの記事)
    > (質問1)
    > コメント@のKeyは、必要でしょうか?
    > Key .PetName = '@

    匿名型における Key の役割は、前回の回答 No34387 で述べております。



    > 削除しても、同じ動作をしますが、

    For Each で列挙して、v.PetName を出力していますが、
    Key が付いている場合は、PetName が ReadOnly となり、
    Key が付いていない場合は Writable となります。
    (ちなみに C# の匿名型は、常に readonly です)


    また、Key メンバーは匿名型同士の比較処理においても使われます。
    https://docs.microsoft.com/ja-jp/dotnet/visual-basic/programming-guide/language-features/objects-and-classes/anonymous-types?WT.mc_id=DT-MVP-8907


    > (質問2)
    > コメントAにある二項演算子で使われているものですが、VBに、こんな演算子ってありましたけ?subpet?.Name

    二項演算子 `If` は、Visual Basic 2008 (VB8.0)からサポートされました。
    Null 条件演算子 `?.` は、Visual Basic 2015 (VB14.0) からのサポートです。

    https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/null-conditional-operators?WT.mc_id=DT-MVP-8907
違反を報告
引用返信
■34395 / ResNo.2)  Re[1]: こんな演算子初めて見ました。
□投稿者/ 魔界の仮面弁士 大御所(1262回)-(2019/11/25(Mon) 21:39:07)
  • アイコンNo34393に返信(VBはじめましたさんの記事)
    > 動作を明示するためにわざわざつけた方がよいという意味でしょうか?
    言語仕様の観点で言えば、C# の匿名型を Visual Basic での実装へと
    「直訳」した場合には、すべてのプロパティに対して Key が付与されます。

    一方、機械的に翻訳するのではなく、コードの意図を読み取った上で
    「意訳」する場合には、Key を付与すべきかどうかを個別に判断してください。


    その項目が比較用のキーとして使いたい場合には Key を付与し、
    編集可能な項目として利用したい場合には Key は付けずに記述します。
    (どちらでも無い場合、Key を付与するかどうかは任意です)


    参考までに、Key の有無によって動作が変化するような
    VB のサンプルを挙げておきます。
    https://karuakun.wordpress.com/2014/01/10/


    > 左外部結合の実行に載っていた次のコードに対しての質問です。
    > https://docs.microsoft.com/ja-jp/dotnet/csharp/linq/perform-left-outer-joins
    > 注:このコードは、C#→VBの変換をWebで行ったものを整理したものです。

    VB の匿名型と C# の匿名型は仕様が異なるので、変換ツールによって
    解釈の違いが生じるのは致し方無いところですね。


    [FirstName も PetName も Key なしで変換されるツール]
     https://codeconverter.icsharpcode.net/

    [FirstName は Key なし、PetName は Key ありに変換されるツール]
     http://converter.telerik.com/



    > VBに、こんな演算子ってありましたけ?
    参考までに:

    【Visual Basic の新機能】※VB2015(14.0)〜VB2019(16.0)
    https://docs.microsoft.com/ja-jp/dotnet/visual-basic/getting-started/whats-new?WT.mc_id=DT-MVP-8907
違反を報告
引用返信
■34396 / ResNo.3)  Re[2]: こんな演算子初めて見ました。
□投稿者/ VBはじめました 一般人(23回)-(2019/11/26(Tue) 09:49:51)
  • アイコン魔界の仮面弁士さん
    いつもお世話になっております。

    Keyについては、前回教えて頂いたことを踏まえて、ワザワザつける必要があるのか?付けることがマナーなのか?と疑問に感じたのと、LINQでGroup句を使用すると勝手に名前に[Key]って使われるので、また別の意味があるのかな?って思って質問させて頂きました。添付ファイル参照

    Null条件演算子については、手元の資料「独習 VisualBasic2010」でも調べて、ネットでもググって引っかからなかったので、質問させて頂きました。
    演算子って基礎事項と思っていたので、増えるという発想が無かったです。
    VBAからVisualBasic2005に移行する時は、一通り入門書を読んだのですが、知っていると思い込んでいる部分は、斜め読みをしていました。
    今回、Null条件演算子について教えて頂いたので、キーワードを変えてググってみると、色々追加されていることを知りました。(また、勉強の範囲が増える・・・)

    ヨチヨチですが、進めていますので、今後ともよろしくお願い致します。
    早く「意訳」できるようになりたい。

314×331 => 237×250
イメージ
1574729391.png
/9KB
違反を報告
引用返信
■34397 / ResNo.4)  Re[3]: こんな演算子初めて見ました。
□投稿者/ VBはじめました 一般人(24回)-(2019/11/26(Tue) 09:50:47)
  • アイコン解決済み
解決み!
違反を報告
引用返信
■34399 / ResNo.5)  Re[3]: こんな演算子初めて見ました。
□投稿者/ 魔界の仮面弁士 大御所(1264回)-(2019/11/26(Tue) 12:20:55)
  • アイコン# 解決済みマークはつけたままにしておきます。

    No34396に返信(VBはじめましたさんの記事)
    > LINQでGroup句を使用すると勝手に名前に[Key]って使われるので、また別の意味があるのかな?

    はい。その Key は Visual Basic の Key キーワードとは異なる意味を持ちます。


    クエリ構文の Group や、拡張メソッド構文の Enumerable.GroupBy メソッドでは
    列挙結果が IGrouping(Of TKey, TElement) 型の要素となるのですが、
    この型が持っている『Key プロパティ』を指していますね。
    https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.igrouping-2.key?WT.mc_id=DT-MVP-8907&view=netframework-4.8


    > 「独習 VisualBasic2010」でも調べて、

    VB2010 当時の書籍をお使いのようですが、その後のバージョンでも
    細かい追加機能等が色々とありますので、幾つか紹介しておきます。
    (C# に比べれば、進化のスピードは緩めですが)

    http://bbs.wankuma.com/search.cgi?no=0&word=No87377&andor=and&logs=all&PAGE=20

    Dim a = 123 + 'VB2015 以降では、このコードで
     456 '変数 a に対して「579」が代入されるが
     'VB2013 以下ではエラーになる

    Dim b = 123 + _ 'VB2019 以降では、このコードで
     456 '変数 a に対して「579」が代入されるが
     'VB2015〜VB2017 ではエラーになる


    --- 以下抜粋 ---

    VB2012 (version 11.0) の新機能
    ・Iterator / Yield キーワードによる反復子の簡易実装をサポート(重要)
    ・Async / Await キーワードによる非同期処理実装をサポート(重要)
    ・メソッドの呼び出し元情報の自動埋め込み(Caller Information)
    https://www.atmarkit.co.jp/fdotnet/special/vs2012review/vs2012review_04.html

    VB2013 (version 12.0) の新機能
    ・Visual Studio の準備機能強化はあるが、言語機能の変更はなし。

    VB2015 (version 14.0) の新機能
    ・メソッド内での #Region〜#End Region の利用を許可(C# は以前からできていた)
    ・VB2005 で追加された IsNot 演算子を、TypeOf 演算子と共に使えるように
    ・NameOf 演算子の追加(リファクタリングや MVC に便利)
    ・文字列中での改行を許可("〜" 内で改行して良い)
    ・文字列補間(既に使用されていた $"〜" 構文)
    ・Null 条件演算子( Return foo?.Property とか Return foo?(idx) とか)
    ・日付型リテラルで #MM-dd-yyyy# 表記だけでなく #yyyy-MM-dd# も許可
    ・LINQ 式の途中などでのコメントをサポート
    https://qiita.com/tadnakam/items/9df14667db41cd81c193

    VB2017 (version 15.0) の新機能
    ・#Disable Warning と #Enable Warning による警告の部分的な抑制
    ・Partial Module および Partial Interface のサポート(VB2005 の Partial Class、VB2010 の Partial Private Sub の延長)
    ・タプル(ValueTuple 型)に対する言語サポート … Dim sample As (Url As String, Title As String)
    ・2 進数リテラルの追加 … Dim value As Byte = &B01101110
    ・数値リテラルの桁区切り記号 … Dim value As Integer = 123_456_789
    ・ByRef 戻り値のサポート … VB で宣言することはできないが、利用することはできる
    ・ReadOnly インターフェイスのプロパティ
    https://qiita.com/yaju/items/2b07b54444707ee9abae


    VB2017 2017年8月更新 (version 15.3) の新機能
    ・名前付きタプルの推論 … Dim sample = (Now, Err)

    VB2017 2017年12月更新 (version 15.5) の新機能
    ・「Private Protected」スコープの追加 … .NET Framework 1.0 当時からあったが、VB や C# ではサポートされていなかった
    ・非末尾名前付き引数のサポート … Array.Copy(sourceArray:=a, destinationArray:=b, 3)
    ・16 進数/2 進数/8 進数の先頭区切り記号 … Dim meat As Integer = &H_DEAD_BEEF

    VB2017 2018年8月更新 (version 15.8) の新機能
    ・浮動小数点数(Double, Single)を整数型に変換する際のパフォーマンスの大幅な向上

    VB2019 (version 16.0) の新機能
    ・明示的な行継続文字(空白+アンダーバー)の後でのコメントを許可
解決み!
違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-5]



■記事リスト / ▲上のスレッド
■34379 / 親記事)  プロセスからウインドウを取得
□投稿者/ /400 一般人(1回)-(2019/11/11(Mon) 23:26:51)
  • アイコン環境/言語:[vb.net2005] 
    分類:[.NET] 

    vb.net2005 winformです
    ウインドウの一覧を先に取得してそれをプロセスで束ねてく方法は分かるのですが、
    それだと時間がかかるのでプロセス一覧を先に取得して画面のあるものだけ
    ウインドウを取得したいのです
    ただそれだと一つのプロセスから複数のウインドウを表示しているような場合取得
    できません
    どのようにすればよいのでしょう

違反を報告
引用返信

▽[全レス4件(ResNo.1-4 表示)]
■34381 / ResNo.1)  Re[1]: プロセスからウインドウを取得
□投稿者/ 魔界の仮面弁士 大御所(1254回)-(2019/11/12(Tue) 10:28:08)
  • アイコンNo34379に返信(/400さんの記事)
    > ウインドウの一覧を先に取得して
    ここでいうウィンドウとは、何を指していますか?

    トップレベルウィンドウ(EnumWindows)だけではなく、
    TextBox や Button、あるいは ComboBox のエディタ部とリスト部などといった、
    hWnd を持つオブジェクトすべてを指しているのでしょうか? (EnumChildWindows)


    > それをプロセスで束ねてく方法は分かるのですが、

    別案を求めるのであれば、そもそも現状、どうやって取得しているのかを
    示してもらった方が答えやすいです。たとえばこういった処理を行っているのでしょうか。
    https://www.atmarkit.co.jp/fdotnet/dotnettips/233enumwin/enumwin.html

    あるいは EnumWindows のコールバック結果を GetWindowThreadProcessId で判定しているとか?
    https://smdn.jp/programming/tips/enumwindows/



    > それだと時間がかかるので
    まず、列挙の目的は何でしょうか?
    そして現状の方法だとどの程度かかっていて、それをどの程度にまで短縮させたいのでしょうか?
    また、現状の処理で特に時間がかかっているのは、どの部分でしょうか?


    > ただそれだと一つのプロセスから複数のウインドウを表示しているような場合取得
    > できません
    どういう処理を書いているか分かりませんが、単一ウィンドウを取得する方法の場合、
    十分に短い時間で処理できているのでしょうか?

    ちなみに Process.MainWinowHandle プロパティの実装は、
    EnumWindows + GetWindowThreadProcessId で判定するという手法で実装されています。
    加えて、それがメインウィンドウであるかの判定のために、
    GetWindow(HWND, GW_OWNER) が IntPtr.Zero かつ IsWindowVisible(HWND) が True で
    あるかどうかも検査しています。アンマネージコードでも構わなければ、上記手法で
    最初に見つけたところで列挙を終えず、そのままコールバックを継続すればよいかと。
違反を報告
引用返信
■34390 / ResNo.2)  Re[2]: プロセスからウインドウを取得
□投稿者/ /400 一般人(4回)-(2019/11/14(Thu) 18:15:24)
  • アイコンNo34381に返信(魔界の仮面弁士さんの記事)

    レスありがとうございます

    > ここでいうウィンドウとは、何を指していますか?

    > まず、列挙の目的は何でしょうか?

    簡易的なタスクスイッチャーみたいなものを作ろうとしていて、例えばWZEditorというエディタがあるのですがタスクマネージャーのプロセスにはWZ_Main.exeだけがあり、アプリケーションの方には読ませたファイルの数だけ実際に見えているウインドウが並んでいるわけです("Hoge1.txt - WZ EDITOR" "Hoge2.txt - WZ EDITOR"みたいに)
    ところがプロセスのメインウインドウだとそのうちの1つしか取得できませんよね
    でプロセスが表示している全てのウインドウが取得出来ないかなと

    プロセスの取得はManagementObjectCollectionからプロセスIDを取得してそのプロセスIDからGetProcessByIdでプロセスを取得しています
    で、プロセスのMainWindowHandleがIntPtr.Zeroで無いものを処理しています

違反を報告
引用返信
■34391 / ResNo.3)  Re[3]: プロセスからウインドウを取得
□投稿者/ 魔界の仮面弁士 大御所(1259回)-(2019/11/14(Thu) 20:31:01)
  • アイコンNo34390に返信(/400さんの記事)
    > プロセスの取得はManagementObjectCollectionからプロセスIDを取得して
    WMI からのアプローチなのですね。
    使っているのは、root\CIMV2 名前空間の Win32_Process クラスあたりでしょうか。


    > そのプロセスIDからGetProcessByIdでプロセスを取得しています
    新しいプロセスの起動等を検知するために、__InstanceCreationEvent / __InstanceDeletionEvent を
    仕掛けているといった事情があるのなら、WMI を使う価値はあるかもしれませんが、
    単に Process クラスのインスタンスを得ることが目的なのだとしたら、プロセスの列挙は
    WMI を経由させずとも、最初から Process.GetProcesses を使った方が手っ取り早い気がします。


    ただ、最終的に必要なのはウィンドウハンドル(あるいはそのタイトル?)のようなので、その場合、
    前回の回答で述べた EnumWindows + GetWindowThreadProcessId で探すことになりそうです。
    ここの Tips 集にある [プロセス]>[ウィンドウのタイトルからプロセスを探す] でも使われていますね。


    とはいっても、最初の質問で
    >>> ウインドウの一覧を先に取得してそれをプロセスで束ねてく方法は分かるのですが、
    との事ですので、恐らくその方法は既にご存知なのかと思います。

    ウィンドウ数が膨大で列挙が遅いというのであれば、列挙完了まで待たせるのではなく、
    探索はワーカースレッドに任せ、対象プロセスのウィンドウだったものが
    逐次通知されてくるようにするのはどうでしょうか。
違反を報告
引用返信
■34392 / ResNo.4)  Re[4]: プロセスからウインドウを取得
□投稿者/ 魔界の仮面弁士 大御所(1260回)-(2019/11/14(Thu) 21:47:22)
  • アイコン
    No34391に追記(魔界の仮面弁士の記事)
    >>>> ウインドウの一覧を先に取得してそれをプロセスで束ねてく方法は
    >>>> 分かるのですが、それだと時間がかかるので
    > ウィンドウ数が膨大で列挙が遅いというのであれば、
    
    手元の VB2005 で試してみましたが、数百ミリ秒以内に列挙が完了しており、
    言うほど時間がかかるようには思えませんでした。
    
    比較のため、そちらで実装したコードを見せて頂けないでしょうか?
    
    
    Option Strict On
    Imports System.Runtime.InteropServices
    Imports System.Text
    Imports System.ComponentModel
    Public Class Form1
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim dt As New DataTable()
            dt.Columns.Add("PID", GetType(Integer))
            dt.Columns.Add("ProcessName", GetType(String))
            dt.Columns.Add("HWND", GetType(IntPtr))
            dt.Columns.Add("Title", GetType(String))
            EnumWindows(AddressOf EnumWindowCallBack, dt)
            Me.DataGridView1.DataSource = dt
            Me.DataGridView1.Columns("PID").DefaultCellStyle.Format = "X8"
            Me.DataGridView1.Columns("HWND").DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
        End Sub
    
        Private Function EnumWindowCallBack(ByVal hWnd As IntPtr, ByVal lparam As DataTable) As Boolean
            If GetWindow(hWnd) = IntPtr.Zero AndAlso IsWindowVisible(hWnd) Then
                Dim processId As Integer
                GetWindowThreadProcessId(hWnd, processId)
                Dim procName As String = ""
                Try
                    'procName = Process.GetProcessById(processId).ProcessName
                Catch
                End Try
                Dim Title As String = ""
                'Dim textLen As Integer = GetWindowTextLength(hWnd)
                'If textLen > 0 Then
                '    Dim tsb As New StringBuilder(textLen + 1)
                '    GetWindowText(hWnd, tsb, tsb.Capacity)
                '    Title = tsb.ToString(0, textLen)
                'End If
                lparam.Rows.Add(processId, procName, hWnd, Title)
            End If
            Return True
        End Function
        <DllImport("user32.dll", CharSet:=CharSet.Unicode, EntryPoint:="GetWindowTextW", SetLastError:=True)> _
        Private Shared Function GetWindowText(ByVal hWnd As IntPtr, ByVal lpString As StringBuilder, ByVal nMaxCount As Integer) As Integer
        End Function
        <DllImport("user32.dll", CharSet:=CharSet.Unicode, EntryPoint:="GetWindowTextLengthW", SetLastError:=True)> _
        Private Shared Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer
        End Function
        Private Delegate Function EnumWindowsDelegate(ByVal hWnd As IntPtr, ByVal lparam As DataTable) As Boolean
        <DllImport("user32.dll")> _
        Private Shared Function EnumWindows(ByVal lpEnumFunc As EnumWindowsDelegate, ByVal lparam As DataTable) As Boolean
        End Function
        <DllImport("user32.dll", SetLastError:=True)> _
        Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
        End Function
        Private Const GW_OWNER As Integer = 4
        <DllImport("user32.dll")> _
        Private Shared Function GetWindow(ByVal hWnd As IntPtr, Optional ByVal uCmd As Integer = GW_OWNER) As IntPtr
        End Function
        <DllImport("user32.dll")> _
        Private Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As Boolean
        End Function
    End Class

違反を報告
引用返信

■記事リスト / レス記事表示 → [親記事-4]






Mode/  Pass/


- Child Tree -

2019/12/07(Sat) 14:05:34 に作成されたキャッシュを表示しています。
生のデータを表示する | キャッシュを最新にする