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

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

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

全過去ログを検索

<< 0 >>
■90454  Re[3]: AddHandler Eventの別スレッドについて
□投稿者/ 魔界の仮面弁士 -(2019/03/12(Tue) 14:24:57)
    No90444 (TanuTanu さん) に返信
    この掲示板では、新規投稿時の注意書きに
     『半角カナは使用しないでください。文字化けの原因になります。』
    と記載されておりますので、以後の投稿では、
    カタカナを全角表記に統一していただけるとありがたいです。


    > @ある画面のボタンを手動でクリック

    具体例となるものが欲しかったのですが……とりあえずこちらで提示してみます。

    下記は onclick 時に、JavaScript 側で confirm メソッドが呼ばれており、
    それによって Web ページダイアログが表示される仕様になっています。
    ダイアログで OK するとページ遷移、Cancel では何もしないというものです。
    https://www.javadrive.jp/javascript/event/sample2_1.html


    対してこちらは、onclick と addEventListener の併用です。
    Web ページダイアログを表示させるコードは含まれていませんが、
    ボタンを押すたびにテキストが書き込まれるようになっています。
    https://ozepon.github.io/onclick_vs_addEventListener/



    > もし可能であれば、focusoutイベントではなくボタンクリックのAttachEventHandler等で実現したい。

    mshtml に、そんなメソッドありましたっけ?

    もしかして、System.Windows.Forms.HtmlElement クラスの AttachEventHandler のことでしょうか。
    No90410 はマネージ WebBrowser の話であり、今回のような、 COM の InternetExplorer や WebBrowser には
    直接的には関係ありません。(マネージ版も内部で COM を呼んでいるので、間接的には関係ありますが)


    IHTMLDocument3 の attachEvent メソッドや、
    IEventTarget の addEventListener メソッドの事だとしたら、
    レンダリングされている HTML ドキュメントに応じて、
     IE5〜IE8 モードの場合 → attachEvent のみをサポート
     IE9〜IE10 モードの場合 → attachEventとaddEventListenerをサポート
     IE11 モードの場合 → addEventListener のみをサポート
    だったはず。

    また、イベントは登録した順に割り当てられるものであり、発生順を変えることは基本的にできません。

    onclick だけなら、イベントの付け外しも比較的容易なのですが、
    attachEvent / addEventListener の場合、detachEvent / removeEventListener するには、
    登録したリスナー(イベントハンドラとなる function オブジェクト)を入手する手段が必要で。

    同一要素に対してイベントを割り当てるのではなく、
    親要素・子要素に対してイベントを割り当てるという手はありますが、
    いずれにせよ、ページの作りにも左右される事になると思います。
    https://qiita.com/hosomichi/items/49500fea5fdf43f59c58
    https://qiita.com/landrunner/items/ab162e305fa2e279c219
記事No.90434 のレス /過去ログ156より / 関連記事表示
削除チェック/

■90455  Re[4]: AddHandler Eventの別スレッドについて
□投稿者/ 魔界の仮面弁士 -(2019/03/12(Tue) 14:31:26)
    2019/03/12(Tue) 14:41:42 編集(投稿者)

    No90452 (TanuTanu さん) に返信
    > 魔界の仮面弁士 様、Azulean 様の下記コメにもあるようにその方法しか残されていないのかもしれませんね。

    スレッド管理の話とイベントの発生順の話は無関係ですよね…?


    質問内容は「イベントの発生順を変更したい」ということではないのでしょうか。

    それともイベントの発生順は JavaScript → VB の順番のままで構わないので、
    VB 側のイベント処理を「別スレッドで処理させたい」という質問なのでしょうか。



    No90454 (魔界の仮面弁士 ) に追記
    > また、イベントは登録した順に割り当てられるものであり、発生順を変えることは基本的にできません。
    >
    > onclick だけなら、イベントの付け外しも比較的容易なのですが、

    とりあえず
     https://www.javadrive.jp/javascript/event/sample2_1.html
    に対するサンプル。


    Option Strict On
    Public Class Form1
     Private doc As mshtml.HTMLDocument
     Private yahooButton As mshtml.IHTMLElement
     Private Event1 As mshtml.HTMLInputTextElementEvents2_Event

     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
      Dim o As Object = GetIEDocument( ターゲットのHWND ) ' No90411 を参照
      doc = DirectCast(o, mshtml.HTMLDocument)
      yahooButton = DirectCast(doc.all.item("yahoo"), mshtml.IHTMLElement)
      Event1 = DirectCast(yahooButton, mshtml.HTMLInputTextElementEvents2_Event)
      AddHandler Event1.onclick, AddressOf WebDisp_click
     End Sub

     Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
      yahooButton.click()
     End Sub

     Private Function WebDisp_click(ByVal e As mshtml.IHTMLEventObj) As Boolean
      MsgBox("webDisp_onclick", MsgBoxStyle.SystemModal)
      Return True
     End Function
    End Class


    この場合、input type="button" に対する onclick が割り当て済みなので、
    その後で VB からイベントにアタッチしても、JavaScript 側の処理が先に実行されます。
    そのため VB の WebDisp_click が呼ばれるのは、Web ページダイアログが閉じられた後になります。


    上記の順番を入れ替えて、VB 側で捕らえてから JavaScript 側の処理を実行させるようにするなら、たとえばこんな感じ。


    Option Strict On
    Public Class Form1
     Private doc As mshtml.HTMLDocument
     Private yahooButton As mshtml.IHTMLElement
     Private Event1 As mshtml.HTMLInputTextElementEvents2_Event
     Private yahooButton_onclick As Object

     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
      Dim o As Object = GetIEDocument( ターゲットのHWND ) ' No90411 を参照
      doc = DirectCast(o, mshtml.HTMLDocument)
      yahooButton = DirectCast(doc.all.item("yahoo"), mshtml.IHTMLElement)

      yahooButton_onclick = yahooButton.onclick '元の function オブジェクト
      yahooButton.onclick = Nothing '割り当てクリア

      Event1 = DirectCast(yahooButton, mshtml.HTMLInputTextElementEvents2_Event)
      AddHandler Event1.onclick, AddressOf WebDisp_click
     End Sub

     Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
      yahooButton.click()
     End Sub

     Private Function WebDisp_click(ByVal e As mshtml.IHTMLEventObj) As Boolean
      MsgBox("webDisp_onclick", MsgBoxStyle.SystemModal)

      Return CBool(CallByName(yahooButton_onclick, "[DispId=0]", CallType.Method, e)) '元の onclick 処理をここで呼び出す
     End Function
    End Class
記事No.90434 のレス /過去ログ156より / 関連記事表示
削除チェック/

■90469  Re[9]: AddHandler Eventの別スレッドについて
□投稿者/ 魔界の仮面弁士 -(2019/03/13(Wed) 09:51:47)
    2019/03/13(Wed) 14:39:48 編集(投稿者)

    No90463 (TanuTanu さん) に返信
    > CreateObject("Shell.Application").Windows

    えぇ…。(−ー;
    別スレッドである No90411 を含め、今までこんなコードの話は
    出ていなかったように思うんですが、どこかで言及されていましたっけ?


    上記をレイトバインドで処理したいのであれば、
    過去ログの No47158 , No35068 あたりを探ってみてください。


    というか上記を使っているのなら、わざわざ API を駆使して
    >>> 下記サイトのGetIEDocumentでHTMLDocumentを取得しております。
    のような方法を取る必要は無いと思いますよ。

    Windows プロパティから得たコレクションを列挙することで、
    個々の InternetExplorer オブジェクトを取得できるので、
    その Document プロパティにアクセスすれば、
    HTMLDocument のインスタンスを得ることができますよね。


    > エラー BC30512 Option Strict On では 'Object' から 'InternetExplorer' への暗黙的な変換は許可されていません。
    > objIE.LocationName
    objIE 変数が As Object なのだとしたら、As SHDocVw.InternetExplorer にしてください。

    この場合、参照設定として、
     ・"Microsoft Internet Controls" (SHDocVw)
     ・"Microsoft Shell Controls And Automation" (Shell32)
    が必要です。


    参照設定を加えずに Option Strict On のままにしたいのであれば、
    先日の回答 ( No90410 , No90461 )や、上記過去ログ ( No35068 )などのように、
    CallByName を経由してアクセスする必要があります。


    > エラー BC30512 Option Strict On では 'Integer' から 'IntPtr' への暗黙的な変換は許可されていません。
    > PWnd = FindWindowExA(0, 0,・・・
    IntPtr 型の引数に 「0」という Integer 値を渡しているからでしょう。
    ここは IntPtr.Zero とすべきです。

    さらに言えば、FindWindowExA API ではなく FindWindowExW API を用いた方が望ましいと思います。


    > 下記が表示されました。
    > ※ボタン名称は非公開にしております。
    だとしたら、ターゲットにしているページが間違っています。

    取得した HTMLDocument が、先の No90454 で示した
    >> https://www.javadrive.jp/javascript/event/sample2_1.html
    になっていることを再度確認してみてください。

    このページから取得した yahoo ボタンであれば、下記の内容が表示されるはずなんですが…。

    ---------------------------
    function onclick(event)
    {
    kakunin(1)
    }
    ---------------------------


    上記の URL でも問題が生じるなら、環境依存の問題がありそうです。

    上記の URL では成功したけれども、目標としている URL だと失敗するのなら、
    jQueryのイベントハンドラが使われているなど、そのページ固有の
    別の問題がある可能性があるので、具体的な URL なり、
    正確なページの内容(HTML & JavaScript)が分からない事には、
    情報不足過ぎて答えようが無いです。
記事No.90434 のレス /過去ログ156より / 関連記事表示
削除チェック/

■90511  Re[6]: AddHandler Eventの別スレッドについて
□投稿者/ 魔界の仮面弁士 -(2019/03/15(Fri) 11:55:19)
    2019/03/15(Fri) 12:07:39 編集(投稿者)

    解決済みで閉じられているので、いちおうチェックは付けた状態に戻しておきます。


    No90477 (TanuTanu さん) に返信
    > その結果、yahooButton = DirectCast(doc.all.item("yahoo"), mshtml.IHTMLElement)の行にて下記エラーが発生致しました。

    その行のどの部分に問題があるのかを確認してみてください。

    NullReferenceException とは、インスタンスが空の時、すなわち
    オブジェクトが Nothing である場合に、
    そのメンバーを操作しようとして発生する例外ですよね。


    If doc Is Nothing Then
     MsgBox("doc が空だった")
    ElseIf doc.all Is Nothing Then
     MsgBox("doc.all が空だった")
    ElseIf doc.all.item("yahoo") Is Nothing Then
     MsgBox("doc.all.item(""yahoo"") が空だった")
    Else
     MsgBox("いずれも空ではなさそう")
     yahooButton = DirectCast(doc.all.item("yahoo"), mshtml.IHTMLElement)
    End If




    > FindWindowExWの値は0ですが、FindWindowではハンドル値取得できました。
    > PWnd1 = FindWindowExW(IntPtr.Zero, IntPtr.Zero, "TabThumbnailWindow", "JavaScript テスト - Internet Explorer")

    示されているのが結果だけで、要因となりうる情報が隠されたままなので、修正すべき箇所を指摘できないです。(^^;

    あえてもう一度質問させていただきます。
    『その API (FindWindowEx および FindWindowExW) の宣言部はどうなっていますか?』( No90475 の再掲 )


    少なくとも当方では、下記の API 宣言で取得できています。

    ' Imports System.Runtime.InteropServices

    ' === 案1 ===
    <DllImport("user32", CharSet:=CharSet.Unicode, SetLastError:=True)>
    Private Shared Function FindWindowExW(hwndParent As IntPtr, hwndChildAfter As IntPtr, lpszClass As String, lpszWindow As String) As IntPtr
    End Function

    ' === 案2 ===
    <DllImport("user32", CharSet:=CharSet.Auto, SetLastError:=True)>
    Private Shared Function FindWindowEx(hwndParent As IntPtr, hwndChildAfter As IntPtr, lpszClass As String, lpszWindow As String) As IntPtr
    End Function

    ' === 案3 ===
    Private Declare Unicode Function FindWindowExW Lib "user32" (hwndParent As IntPtr, hwndChildAfter As IntPtr, <MarshalAs(UnmanagedType.LPTStr)> lpszClass As String, <MarshalAs(UnmanagedType.LPTStr)> lpszWindow As String) As IntPtr

    ' === 案4 ===
    Private Declare Auto Function FindWindowEx Lib "user32" (hwndParent As IntPtr, hwndChildAfter As IntPtr, <MarshalAs(UnmanagedType.LPTStr)> lpszClass As String, <MarshalAs(UnmanagedType.LPTStr)> lpszWindow As String) As IntPtr




    宣言が間違っていて、IntPtr.Zero が返却されてしまうパターン。

    ' === 没1 ===
    <DllImport("user32", EntryPoint:="FindWindowExW", SetLastError:=True)>
    Private Shared Function FindWindowEx(hwndParent As IntPtr, hwndChildAfter As IntPtr, lpszClass As String, lpszWindow As String) As IntPtr
    End Function

    ' === 没2 ===
    <DllImport("user32", SetLastError:=True)>
    Private Shared Function FindWindowExW(hwndParent As IntPtr, hwndChildAfter As IntPtr, lpszClass As String, lpszWindow As String) As IntPtr
    End Function

    ' === 没3 ===
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExW" (hwndParent As IntPtr, hwndChildAfter As IntPtr, lpszClass As String, lpszWindow As String) As IntPtr



    正しい宣言ではないが、一応呼び出せてしまうパターン。

    ' === 非推奨1 ===
    Private Declare Unicode Function FindWindowExW Lib "user32" (hwndParent As IntPtr, hwndChildAfter As IntPtr, lpszClass As String, lpszWindow As String) As IntPtr

    ' === 非推奨2 ===
    Private Declare Unicode Function FindWindowEx Lib "user32" Alias "FindWindowExW" (hwndParent As IntPtr, hwndChildAfter As IntPtr, lpszClass As String, lpszWindow As String) As IntPtr



    >  WEBページ・・・CreateObject("Shell.Application").Windowsで対応しております。
    これを用いている部分のコードも見せていただけないでしょうか。

    SHDocVw.ShellWindows を宣言しておきながら、FindWindowEx API や、GetIEDocument までも
    追加で呼び出している理由が、どうしても分からなかったのです。

    No90463 の発言より、「objIE.LocationName」を利用しているであろうことは推察できましたが、
    目的は LocationName プロパティでウィンドウのタイトルを得ることだけなのでしょうか。
    あるいは HWND プロパティからウィンドウハンドルも得ているとか?

    objIE.Document プロパティを通じて HTMLDocument を得ることができるはずなので、
    わざわざ GetIEDocument を呼び出す必要性は無いと思っています。( No90469 で指摘 )

    (例)
    http://jumbofoot.cocolog-nifty.com/yass_vbnet_tips/2007/02/shellhtmldocume_f1cd.html


    WM_HTML_GETOBJECT でないと取得できない相手の場合は、API 宣言が必要になりますが、
    その場合、今度は CreateObject("Shell.Application").Window を使う意味が分からない…。



    >  上記WEBページから派生したWEBページダイアログ ・・・ GetIEDocument で対応(現在、ここのボタンクリックのイベントを対応しております。)

    ここでいう『派生』とは何を示していますか? ページ遷移の事でしょうか?

    ページが遷移したのであれば、以前の HTMLDocument はもう使えないので、
    読み込みが完了したことを通知するための DocumentComplete イベントにて、
    イベント引数 pDisp の Document プロパティを受け取るようにします。
    (フレームを持つページの場合は、各フレームごとに発生することに注意)

    あるいは、ターゲットとなる InternetExplorer オブジェクト(IWebBrowser2)を保持しておいて、
    その Document プロパティを取得しなおすという方法も使えますが、いずれにせよ、
    読み込みが完了する前に GetIEDocument なり Document プロパティなりで
    HTMLDocument を得ていた場合、DOM が不完全な状態になっていることがあります。

    なので、取得した HTMLDocument が、目的のページの内容を指しているかを
    確認しておくことも重要です。(これも No90469 で指摘 )


    それに、FindWindowEx を使うにしても、その使い方が不自然に思えます。
    そもそも "TabThumbnailWindow" クラスを探している理由は何でしょうか?
    先の GetIEDocument を使うことが目的なら、探すべきウィンドウは
    "Internet Explorer_Server" クラスのウィンドウ(またはその親ウィンドウ)の
    ハンドルであるはずですよね。


    また、「WEBページダイアログ」とは何を指していますか?
    キャプションが "JavaScript テスト - Internet Explorer" となる、 No90454
    https://www.javadrive.jp/javascript/event/sample2_1.html だとすれば、
    そもそもダイアログは存在していません。
    別のページが対象なのかもしれませんが、その場合は、doc.all.item("yahoo") は存在しないかもしれませんし。

    No90476 では「javascriptによる擬似モーダルダイアログ『だと思う』」とお答えいただきましたが、
    それが具体的になんであるのか(たとえば jQuery の colorbox とか)や、
    イベント割り当てが onclick なのかそれ以外なのかもはっきりしないままです。
記事No.90434 のレス / END /過去ログ156より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -