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

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

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

No.99458 の関連記事表示

<< 0 | 1 >>
■99458  PrintWindowでChromeウインドウを取得する
□投稿者/ ぜん -(2022/04/14(Thu) 15:08:05)
親記事 /過去ログ173より / 関連記事表示
削除チェック/

■99459  Re[1]: PrintWindowでChromeウインドウを取得する
□投稿者/ くま -(2022/04/14(Thu) 16:17:34)
    > Google Chromeウインドウ
    画面サイズよりページが大きい場合とかどうするつもり?
    (スクロールする場合)
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99461  Re[2]: PrintWindowでChromeウインドウを取得する
□投稿者/ ぜん -(2022/04/14(Thu) 17:05:09)
    No99459 (くま さん) に返信
    >>Google Chromeウインドウ
    > 画面サイズよりページが大きい場合とかどうするつもり?
    > (スクロールする場合)

    表示している箇所だけで十分です
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99462  Re[3]: PrintWindowでChromeウインドウを取得する
□投稿者/ くま -(2022/04/14(Thu) 18:44:46)
    chromeが黒くなるのはウインドウの描写自体が普通のウインドウと違うからなんだけど
    黒くなったかな?

    > 他のウインドウの下に隠れていても取得できるのはこれだけなので
    > これを使用したいと考えています。

    > 表示している箇所だけで十分です

    それなら多分一瞬前面に持ってきてキャプチャするのが一番良いと思うよ
    この場合だと色々多分試さないとうまくいかないと思うから
    (最小化されている場合や画面表示外の場合、最大化の場合等条件付けが多い)

    https://dobon.net/vb/dotnet/graphics/screencapture.html

記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99463  Re[4]: PrintWindowでChromeウインドウを取得する
□投稿者/ ぜん -(2022/04/14(Thu) 19:07:32)
    一瞬だけ前面に持って行く方法も知っていますが
    他の作業をしながらだと
    うまくいかない場合があるため、やはり背面にある状態で取得したいと思います。
    何か他に方法はございませんでしょうか?
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99464  Re[5]: PrintWindowでChromeウインドウを取得する
□投稿者/ Hongliang -(2022/04/14(Thu) 19:48:08)
    対象がChrome限定なのであれば、Seleniumを使うのがいいかもしれません。
    一応既存のChromeプロセスにアタッチすることもできます。
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99466  Re[6]: PrintWindowでChromeウインドウを取得する
□投稿者/ ぜん -(2022/04/14(Thu) 20:29:30)
    ありがとうございます。
    しかしやはりVBを使いたいと考えています。
    上記のサイトによると
    #if(_WIN32_WINNT >= 0x0603)
    #define PW_RENDERFULLCONTENT 0x00000002
    #endif /* _WIN32_WINNT >= 0x0603 */

    でうまくいくと書かれていると思うのですが、
    これってどこで使っているのでしょうか?

    また、DWM Thumbnail APIでもできそうなことが書かれてあるのですが
    これはどうやって使えば良いですか?
    検索してもいまいち使い方が分かりませんでした。
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99467  Re[7]: PrintWindowでChromeウインドウを取得する
□投稿者/ Hongliang -(2022/04/14(Thu) 20:32:04)
    > しかしやはりVBを使いたいと考えています。
    SeleniumはVBを含めたいろんな言語から呼び出せる、ブラウザのオートメーション用ライブラリです。
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99468  Re[8]: PrintWindowでChromeウインドウを取得する
□投稿者/ ぜん -(2022/04/14(Thu) 23:19:12)
    できればSeleniumを使わずに実行したいと考えていますが、
    上記のサイトの方法は使えないでしょうか?
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99469  Re[7]: PrintWindowでChromeウインドウを取得する
□投稿者/ radian -(2022/04/15(Fri) 07:22:33)
    No99466 (ぜん さん) に返信
    > ありがとうございます。
    > しかしやはりVBを使いたいと考えています。
    > 上記のサイトによると
    > #if(_WIN32_WINNT >= 0x0603)
    > #define PW_RENDERFULLCONTENT 0x00000002
    > #endif /* _WIN32_WINNT >= 0x0603 */
    >
    > でうまくいくと書かれていると思うのですが、
    > これってどこで使っているのでしょうか?

    C++のヘッダで定義されてる内容だと思いますが。
    試しにPrintWindowのnFlagsに2指定してみたらキャプチャできたんで、やってみればよいのでは?
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99472  Re[1]: PrintWindowでChromeウインドウを取得する
□投稿者/ 魔界の仮面弁士 -(2022/04/15(Fri) 10:47:26)
    No99458 (ぜん さん) に返信
    > しかし、Chrome以外のウインドウだとうまくいくのですが
    > Chromeだけは、画像が真っ暗になってしまいます。

    対象のウィンドウは "Chrome_WidgetWin_1" クラスですか?


    No99466 (ぜん さん) に返信
    > また、DWM Thumbnail APIでもできそうなことが書かれてあるのですが
    > これはどうやって使えば良いですか?
    > 検索してもいまいち使い方が分かりませんでした。
    そうですか? 使い方の説明なら、すぐに出てきましたよ。
    使う関数もそう多くは無いですし。
    https://docs.microsoft.com/ja-jp/windows/win32/dwm/thumbnail-ovw


    Option Strict On
    Imports System.Runtime.InteropServices

    Public Class Form1
      Private ThumbnailId As IntPtr = IntPtr.Zero
      Private Function GetChromeHandle() As IntPtr
       Throw New NotImplementedException("取得対象の HWND を取得するコードをここに記述")
      End Function

      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Button1.Text = "描画開始"
      End Sub
      Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        If ThumbnailId <> IntPtr.Zero Then
          DwmUnregisterThumbnail(ThumbnailId)
          ThumbnailId = IntPtr.Zero
        End If
      End Sub

      Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If ThumbnailId = IntPtr.Zero Then
          Dim chromeHandle As IntPtr = GetChromeHandle()
          DwmRegisterThumbnail(Me.Handle, chromeHandle, ThumbnailId)
          UpdateThumbnail()
          Button1.Text = $"描画停止:{ThumbnailId}"
        Else
          DwmUnregisterThumbnail(ThumbnailId)
          ThumbnailId = IntPtr.Zero
          Button1.Text = "描画開始"
        End If
      End Sub

      Private Sub UpdateThumbnail()
        If ThumbnailId <> IntPtr.Zero Then
          Dim rect = Me.RectangleToClient(PictureBox1.RectangleToScreen(PictureBox1.ClientRectangle))
          DwmUpdateThumbnailProperties(ThumbnailId, New DWM_THUMBNAIL_PROPERTIES(rect, False))
        End If
      End Sub


    #Region "DWM サムネイル API"
      Private Declare Auto Function DwmRegisterThumbnail Lib "dwmapi" (hwndDestination As IntPtr, hwndSource As IntPtr, <Out> ByRef phThumbnailId As IntPtr) As Integer
      Private Declare Auto Function DwmUpdateThumbnailProperties Lib "dwmapi" (hThumbnailId As IntPtr, <[In]> ptnProperties As DWM_THUMBNAIL_PROPERTIES) As Integer
      Private Declare Auto Function DwmUnregisterThumbnail Lib "dwmapi" (hThumbnailId As IntPtr) As Integer
      <StructLayout(LayoutKind.Sequential)>
      Public Structure RECT
        Public left As Integer, top As Integer, right As Integer, bottom As Integer
        Public Shared Widening Operator CType(r As RECT) As Rectangle
          Return Rectangle.FromLTRB(r.left, r.top, r.right, r.bottom)
        End Operator
        Public Shared Widening Operator CType(r As Rectangle) As RECT
          Return New RECT With {.left = r.Left, .top = r.Top, .right = r.Right, .bottom = r.Bottom}
        End Operator
      End Structure
      <Flags>
      Private Enum DWM_TNP As UInteger
        None = 0
        RectDestination = &H1UI
        RectSource = &H2UI
        Opacity = &H4UI
        Visible = &H8UI
        SourceClientAreaOnly = &H10UI
      End Enum
      <StructLayout(LayoutKind.Sequential)>
      Private Class DWM_THUMBNAIL_PROPERTIES
        Public dwFlags As DWM_TNP = DWM_TNP.None
        Public rcDestination As RECT
        Public rcSource As RECT
        Public opacity As Byte = 255
        <MarshalAs(UnmanagedType.Bool)> Public fVisible As Boolean = False
        <MarshalAs(UnmanagedType.Bool)> Public fSourceClientAreaOnly As Boolean = False
        Public Sub New()
        End Sub
        Public Sub New(destination As Rectangle, clientOnly As Boolean)
          dwFlags = DWM_TNP.RectDestination Or DWM_TNP.SourceClientAreaOnly
          rcDestination = destination
          fSourceClientAreaOnly = clientOnly
        End Sub
      End Class
    #End Region
    End Class
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99474  Re[2]: PrintWindowでChromeウインドウを取得する
□投稿者/ 魔界の仮面弁士 -(2022/04/15(Fri) 13:40:07)
    2022/04/15(Fri) 13:53:51 編集(投稿者)

    No99472 (魔界の仮面弁士) に追記
    > ■No99466 (ぜん さん) に返信
    >>また、DWM Thumbnail APIでもできそうなことが書かれてあるのですが
    >>これはどうやって使えば良いですか?
    >>検索してもいまいち使い方が分かりませんでした。
    > そうですか? 使い方の説明なら、すぐに出てきましたよ。
    > 使う関数もそう多くは無いですし。

    すみません。質問の意図を勘違いしていました。


    サムネイルを取得したいわけではなく、あくまでも「スクリーンショット」が目的なので、
    恐らくはそれを画像として保存する必要があるのですよね。
    (クリップボードに送るのか、ファイルとして保持するのかはさておき)


    DWM でサムネイルを得る方法の場合、撮影対象のアプリは背面表示でも構いませんが、
    撮影結果は HDC でなく、トップレベルウィンドウの HWND を指定する方法であるため、
    そのサムネイルを、画像として直接保存する手段が無さそうですね…。

    二次転写でも構わないのであれば、Graphics.CopyFromScreen あるいは BitBlt で、
    サムネイルを再撮影するという手が一応あります。
    (二次転写ゆえ、サムネイルを表示中のウィンドウを可視状態にしておく必要あり)
    https://dobon.net/vb/dotnet/graphics/screencapture.html


    (1) 一瞬だけ前面に持ってきてから撮影する案
    (2) PrintWindow(hwnd, hdc, PW_RENDERFULLCONTENT) 案
    (3) Selenium 案(WebDriver の ITakesScreenshot インターフェイス)
    (4) DWM Thumbnail 後に二次転写案
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99476  Re[3]: PrintWindowでChromeウインドウを取得する
□投稿者/ 魔界の仮面弁士 -(2022/04/15(Fri) 14:25:08)
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99478  Re[4]: PrintWindowでChromeウインドウを取得する
□投稿者/ ぜん -(2022/04/15(Fri) 19:27:57)
    ありがとうございます。

    (2) PrintWindow(hwnd, hdc, PW_RENDERFULLCONTENT) 案

    これでうまくいきました。
    https://docs.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-printwindow

    このページを見ると

    nflagsにはPW_CLIENTONLYのオプションしかないように思えたのですが
    他にオプションがあったのですね。
    オプションを使い分ければもっと良い動作ができるのではないかと思い
    nflagsのオプションを調べてみたのですが
    検索しても書かれているページが見つかりませんでした。
    どこかで解説されていますでしょうか??
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99481  Re[5]: PrintWindowでChromeウインドウを取得する
□投稿者/ 魔界の仮面弁士 -(2022/04/15(Fri) 20:48:01)
    No99478 (ぜん さん) に返信
    > nflagsにはPW_CLIENTONLYのオプションしかないように思えたのですが
    > 他にオプションがあったのですね。

    PrintWindow API は XP/2003 からの機能で、
    PW_CLIENTONLY は Windows 8.1 で追加されたオプションですね。
    現時点ではドキュメントに記載のない隠しフラグになります。


    > オプションを使い分ければもっと良い動作ができるのではないかと思い
    0 だとウィンドウ全体、
    1 だとクライアント領域のみ(PW_CLIENTONLY)
    2 がフルコンテキスト(PW_RENDERFULLCONTENT)のようですが、そのほかに
    3 を渡すこともできるみたいですね。undocumented ゆえ詳細は不明ですが。

    上記以外の値を渡した時は、当方環境では戻り値が FALSE となりました。
    ※エラー 87 (パラメーターが間違っています。)
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99483  Re[6]: PrintWindowでChromeウインドウを取得する
□投稿者/ 魔界の仮面弁士 -(2022/04/15(Fri) 21:12:17)
    2022/04/15(Fri) 21:13:57 編集(投稿者)

    No99481 (魔界の仮面弁士) に追記
    >>オプションを使い分ければもっと良い動作ができるのではないかと思い
    > 0 だとウィンドウ全体、
    > 1 だとクライアント領域のみ(PW_CLIENTONLY)
    > 2 がフルコンテキスト(PW_RENDERFULLCONTENT)のようですが、そのほかに
    > 3 を渡すこともできるみたいですね。undocumented ゆえ詳細は不明ですが。

    https://docs.microsoft.com/ja-jp/windows/win32/api/winuser/nf-winuser-printwindow
    によれば
      By default, the entire window is copied.
      既定ではウィンドウ全体がコピーされる。
    とあり、PW_CLIENTONLY を指定した場合は
      Only the client area of the window is copied to hdcBlt.
      ウィンドウのクライアント領域のみがhdcBltにコピーされる。
    とあることから、1 (PW_CLIENTONLY) だけでなく 0 も有効であると読み取ることができます。

    2 (PW_RENDERFULLCONTENT) は、WinUser.h の記載から、
    PrintWindow に渡せるのだと推察できますが、このフラグの意味は、
    現時点において、明確に文書化されてはいないようです。

    3 については、当方で実際に試してみたら動いた、という状況です。
    メモ帳で試した場合、1 と 3 は、共に「クライアント領域」を描画しました。


    Chrome の場合は、タイトルバー部にタブを重ねているので、
    ウィンドウ全体の撮影なのかクライアント領域の撮影なのか区別し辛いですが
    手元の環境では、2 と 3 の内容がほぼ同じになりました。
    しかし、たまに違う結果になるウィンドウもありました。謎。

    0 = 黒一色(0x000000)。稀に、左端と下端に、ビジュアル スタイルのウィンドウ枠が現れる事もある。
    1 = 黒一色。
    2 = 0 でウィンドウ枠が出ていた場合は、左端に黒い余白が入る。
    3 = 2 を指定したようなズレは生じず、全体が綺麗に描画された。
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99485  Re[7]: PrintWindowでChromeウインドウを取得する
□投稿者/ 魔界の仮面弁士 -(2022/04/15(Fri) 21:51:45)
    No99483 (魔界の仮面弁士) に追記
    > Chrome の場合は、タイトルバー部にタブを重ねているので、
    > ウィンドウ全体の撮影なのかクライアント領域の撮影なのか区別し辛いですが
    > 手元の環境では、2 と 3 の内容がほぼ同じになりました。
    > しかし、たまに違う結果になるウィンドウもありました。謎。
    >
    > 0 = 黒一色(0x000000)。稀に、左端と下端に、ビジュアル スタイルのウィンドウ枠が現れる事もある。
    > 1 = 黒一色。
    > 2 = 0 でウィンドウ枠が出ていた場合は、左端に黒い余白が入る。
    > 3 = 2 を指定したようなズレは生じず、全体が綺麗に描画された。


    参考までに、フラグ 0〜4 に変化させて Chrome を撮影した結果を載せておきます。
    前半は通常サイズのウィンドウで、後半は最小化されている状態で PrintWindow したものです。

    https://www.vb-user.net/junk/replySamples/2022.04.15.21.45/PrintWindow.apng

    ※PNG アニメで保存しているので、IE 以外のブラウザで見てください。
記事No.99458 のレス / END /過去ログ173より / 関連記事表示
削除チェック/

■99480  Re[5]: PrintWindowでChromeウインドウを取得する
□投稿者/ ぜん -(2022/04/15(Fri) 20:36:43)
    https://jpdebug.com/p/117894

    これを見ると
    二つしかオプションなさそうですね。

    どうもありがとうございました。
記事No.99458 のレス / END /過去ログ173より / 関連記事表示
削除チェック/

■99482  Re[6]: PrintWindowでChromeウインドウを取得する
□投稿者/ ぜん -(2022/04/15(Fri) 20:53:50)
    ありがとうございます。

    気になっているのですが
    オプション0と1って違うものなのでしょうか?
    https://jpdebug.com/p/117894

    このページでは
    "Only the client area of the window is copied to hdcBlt. By default, the entire window is copied.")]
    と書かれてありますが、
    デフォルトの設定だと1を選んだとしてもウインドウ全体を取得することになるが、
    何か設定するとクライアント領域のみを取得できるという意味なのでしょうか??
記事No.99458 のレス /過去ログ173より / 関連記事表示
削除チェック/

■99484  Re[7]: PrintWindowでChromeウインドウを取得する
□投稿者/ ぜん -(2022/04/15(Fri) 21:40:22)
    文書化されていないオプションが存在するのですね。
    ユーザーがどうやって発見したのか気になりますね。
    どうもありがとうございました。
記事No.99458 のレス / END /過去ログ173より / 関連記事表示
削除チェック/

次の20件>

<< 0 | 1 >>

パスワード/

- Child Tree -