tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルサブモニタのキャプチャ方法
記事No9839
投稿日: 2010/02/04(Thu) 10:29
投稿者camputer

 こんにちは、質問させていただきます。

 開発環境:XP+VB2008
 VB歴約1年でございます。どうぞよろしくお願いいたします。

 モニタ上の好きな部分(Form内外問わず、デスクトップ、
ステータスバーなどすべて)をキャプチャできるようにしたつもりなのですが、
サブモニタ上でうまく動作いたしません。

 メインモニタ側はなんとか完成いたしましたが、以下のようになります。
  Form1の「Btnキャプチャ開始」クリック
 →Form2をWindowState = Maximizedで表示し、それにデスクトップの画像
   を貼り付けておく。(e.Graphics.DrawImage(screenImage, 0, 0))
 →Me.MouseDown, Me.MouseMove, Me.MouseUp 中にマウスドラッグ範囲を四角形で描画

ただこの方法を当初の目的でございました別のPC(メインモニタ+サブモニタ)に
持って行きましたところ、Form2がサブモニタ側まで広がってくれず、
キャプチャできません。。。

 そこで、以前花ちゃんさまからご教示いただいた方法にトライしてみて、
Form2外のマウスイベントを検知するところまで成功したのですが、
    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        MyBase.WndProc(m)

        If m.Msg = &H201 Then '&H201:マウスの左ボタンを押した
            mouseStart = New Point(Cursor.Position.X, Cursor.Position.Y)
            Me.Capture = True
            Me.Tag = "MouseDown"
        ElseIf m.Msg = &H200 And Me.Tag = "MouseDown" Then '&H200:マウスが移動した
            mouseEnd = New Point(Cursor.Position.X, Cursor.Position.Y)
            Invalidate()
            Me.Capture = True
        ElseIf m.Msg = &H202 Then '&H202:マウスの左ボタンが解放された
            Me.Capture = True
            Me.Tag = "MouseUp"
            Close()
        End If
    End Sub

しかしForm外に四角形(選択領域)を表示する方法と、そこの画像を
キャプチャする方法が分かりません。。

 一番早いのは、Form2をサブモニタにも入れることができることなのですが、
何かキャプチャのよさそうな方法をひらめかれる方がいらっしゃいましたら、
是非ともアドバイスいただきたくお願いいたします。
 どうぞよろしくお願いいたします。

[ツリー表示へ]
タイトルRe: サブモニタのキャプチャ方法
記事No9841
投稿日: 2010/02/04(Thu) 22:36
投稿者camputer
 こんばんは.すみません,いったん考えさせてください(_ _)
Form2_Paintイベント内で
Me.Location = New System.Drawing.Point(1281, 0)
  '1280がメインモニタ横幅でございます
といたしましたところ,Form2がサブモニタに入ってくれることが分かりました.
おそらくForm2をメインモニタに,新しくForm3をサブモニタに
作製して入れておけば2つの画像をくっつけてどうにかなるのかな,などと...
 あまりスムーズな方法ではないかもしれませんが,
頑張ってみます.

[ツリー表示へ]
タイトルRe^2: サブモニタのキャプチャ方法
記事No9842
投稿日: 2010/02/05(Fri) 01:08
投稿者オショウ
>  あまりスムーズな方法ではないかもしれませんが,
> 頑張ってみます.

  うまくいかないような・・・

  GetSystemMetrics(SM_CMONITORS)で、モニター台数が取得できますし

  仮に2台あったとして、以下のようにすれば、全画面やミニター1・
  モニター2の領域・大きさが取得できます。

  switch( sCopy ){
    case WIN_FULL:
      VirtualRec.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
      VirtualRec.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
      VirtualRec.right = VirtualRec.left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
      VirtualRec.bottom = VirtualRec.top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
      break;
    case WIN_CRT1:
      VirtualRec.left = lpGetSystemMetrics(SM_XVIRTUALSCREEN);
      VirtualRec.top = lpGetSystemMetrics(SM_YVIRTUALSCREEN);
      VirtualRec.right = VirtualRec.left + lpGetSystemMetrics(SM_CXVIRTUALSCREEN);
      VirtualRec.bottom = VirtualRec.top + lpGetSystemMetrics(SM_CYVIRTUALSCREEN);
      break;
    case WIN_CRT2:
      VirtualRec.left = lpGetSystemMetrics(SM_XVIRTUALSCREEN);
      VirtualRec.top = lpGetSystemMetrics(SM_YVIRTUALSCREEN);
      VirtualRec.right = VirtualRec.left + lpGetSystemMetrics(SM_CXVIRTUALSCREEN);
      VirtualRec.bottom = VirtualRec.top + lpGetSystemMetrics(SM_CYVIRTUALSCREEN);
      break;
  }

  何はともあれ、頑張って下さい!

以上。参考まで。

[ツリー表示へ]
タイトルRe^3: サブモニタのキャプチャ方法
記事No9843
投稿日: 2010/02/05(Fri) 07:43
投稿者camputer
 オショウ様
 どうもありがとうございます!!
今拝見しましたm(_ _)m お礼が朝になってしまってどうも申し訳ございません.

 今から移動しなければいけませんので,後で改めてお礼いたします.
いったん失礼いたします.



==(追記)===================

 ご親切にアドバイスいただきどうもありがとうございました。
「vb.net "SM_CXVIRTUALSCREEN"」とかで検索すると結構でてきますね。
コーディングの方向といたしましては、
  教えていただいた方法からサイズを取得
  Form2をMaximizeではなく、具体的にサイズ指定する
  Form2をモニタ1+2の全領域に配置しておく。
といった感じでしょうか。

改めてご報告させていただきます!どうもありがとうございました!

[ツリー表示へ]
タイトルRe: サブモニタのキャプチャ方法
記事No9844
投稿日: 2010/02/05(Fri) 11:57
投稿者魔界の仮面弁士
> サブモニタ上でうまく動作いたしません。

話がよく見えていないのですが、ドラッグで操作するということは、

  ┏━┓
  ┃1┃
┏━┻┳┻┓
┃ 2 ┃3┃
┗━━┫ ┃
   ┗━┛

のようなモニタ環境で、1・2・3すべてを含む領域をキャプチャーする事は
できない、という事になるのでしょうか?
(PrintScreen キーでキャプチャーした際には、全領域分が撮影されますよね)


>  →Form2をWindowState = Maximizedで表示し、それにデスクトップの画像
>    を貼り付けておく。(e.Graphics.DrawImage(screenImage, 0, 0))
>  →Me.MouseDown, Me.MouseMove, Me.MouseUp 中にマウスドラッグ範囲を四角形で描画

意図する物であるかどうかは分かりませんが、とりあえず作ってみました。
http://www.vb-user.net/junk/replySamples/2010.02.05.11.18/Capture.txt

[ツリー表示へ]
タイトルRe^2: サブモニタのキャプチャ方法
記事No9845
投稿日: 2010/02/05(Fri) 16:05
投稿者camputer
 魔界の仮面弁士 博士 !`-´)ゞ

 どうもありがとうございます!!
今拝見いたしました。返事が遅く申し訳ございません。
アドバイスどうもありがとうございます。

>〜  、1・2・3すべてを含む領域をキャプチャーする事は
>できない、という事になるのでしょうか?
>(PrintScreen キーでキャプチャーした際には、全領域分が撮影されますよね)

 はい、デスクトップPCの
  ┏━━┳━━┓
  ┃1 ┃2 ┃
  ┗━━┻━━┛
のような環境で、1がメインモニタ、2に実験装置にくっついていた
グラフ描画ソフトのFormがあり、それの任意領域を切り取って保存
したかった次第でございます。
・まず自分のノートPCでキャプチャソフトだけ自力で作成いたしました。
   (Form2をWindowState = Maximizedで表示
    →それにデスクトップの画像を貼り付け
    →Form上のマウスイベントを検出して、矩形描画&切り取り)
・ですが、デスクトップPCに持って行ったところ、WindowState = Maximizedとした
 Formがモニタ2に入らず、Form上のイベントを取れませんでした。
・そこで、Form外のイベントを取れるところまでできたのですが、
 その先の(Form外の)矩形描画&切り取りができず、行き詰ってしまい
 根本的なキャプチャ案をご教示いただきたく質問させていただいた次第でございます。
・そのあと自分で試しておりまして、モニタ2にFormを入れられる方法を
 発見いたしましたのでそれでどうにかできないものかと。。。頑張っておりました。

>意図する物であるかどうかは分かりませんが、とりあえず作ってみました。
>http://www.vb-user.net/junk/replySamples/2010.02.05.11.18/Capture.txt

 どうもありがとうございます!!一瞬でこんなすごいコードを。。。
>とりあえず
のレベルなんですか、これ?^^; すごいです。お忙しい中、誠にありがとうございます。
見たことのない方法が沢山詰まっているようです。おかげでまたスキルアップできそうです。
 今やっている実験の後で試してみたいので、少しお時間をいただけないでしょうか。
まず御礼だけになってしまいますが、後で改めてご報告いたします。

 どうもありがとうございました!!いったん失礼いたします!

[ツリー表示へ]
タイトル【完成】ご報告いたします
記事No9856
投稿日: 2010/02/06(Sat) 19:34
投稿者camputer
 たった今,完成いたしました! `-´)ゞ
誠にありがとうございました!!

 結局まるごと,魔界の仮面弁士様に御作成いただいたものに
差し替えさせていただきました^^;
 以下2点のみ追加いたしました.
@今回のキャプチャ対象が,実験の細かい波形グラフになりますので,
 画像サイズが元のままの方が後で比較しやすいかな?と考え,
            PictureBox1.Image = F.CaptureImage
            PictureBox1.Size = F.CaptureImage.Size'←1行追加
A皆が使ってくれる時に,ドラッグ線がWindowsのデフォルトじゃない方が
 キャプチャイメージが理解しやすいかな?などと考え,
            'ControlPaint.DrawFocusRectangle(e.Graphics, area)
            e.Graphics.DrawRectangle(Pens.Blue, area) 'に変更
 初めは自分のコードと違う部分をひとつずつ理解しながら
引用させていただいておりましたが,知らないand考えた事もないような
コーディングが余りに沢山ありましたので,全部コピペさせていただきました.

 おかげで余分なForm2(モニタ全領域に配置)を消す事が出来ましたので,
画面のちらつきも無くなり,動作が軽くなりました.

 何より,このキャプチャ動作をわずか90行足らずで
御作成できるんですねー...私のは300行以上ありましたorz

 また一個VBでできることが増えました.どうもありがとうございます.
VBは何でもできるんですねー^^VBは楽しいです.
後でもう一個作ってみたいソフトがあるのでワクワクいたしておりますが,
まだきちんと理解できていないコードがございますので,
引き続き検索させていただきます.

 この度はご閲覧&アドバイス&お忙しい立場にもかかわらず
コーディングまでいただいて,誠にありがとうございました!!!m(_ _)m

[ツリー表示へ]
タイトルRe: 【完成】ご報告いたします
記事No9863
投稿日: 2010/02/08(Mon) 15:02
投稿者魔界の仮面弁士
>  画像サイズが元のままの方が後で比較しやすいかな?と考え,
>             PictureBox1.Image = F.CaptureImage
>             PictureBox1.Size = F.CaptureImage.Size'←1行追加
原寸表示なら、毎回 Size をセットしなおさずとも、先のサンプル中の
  PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
という行を、
  PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
に変更しておくだけで良いと思いますよ。

http://www.vb-user.net/junk/replySamples/2010.02.08.14.53/Clipping.txt
# "Microsoft OneNote" の [Win]+[S] でのキャプチャ機能に似せて、
# 撮影前の画面にスモークをかけてみました。


>>とりあえず
>のレベルなんですか、これ?
この手法だと、半透明ウィンドウ(Layered Window)をキャプチャできないのです。

半透明ウィンドウも撮影したい場合には、CopyFromScreen メソッドの代わりに、
BitBlt API を CAPTUREBLT フラグ指定で呼び出す必要があります。
http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/1c60509a-ad5d-4ff0-90eb-8a279036a6ec

[ツリー表示へ]
タイトルRe^2: 【完成】ご報告いたします
記事No9864
投稿日: 2010/02/08(Mon) 17:54
投稿者camputer
 どうもありがとうございます!!
今拝見いたしました。完成後のスキルアップまでいただきまして
誠にありがとうございます。
>PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
>に変更しておくだけで良いと思いますよ。
はい、修正いたしますm(_ _)m

http://www.vb-user.net/junk/replySamples/2010.02.08.14.53/Clipping.txt
># "Microsoft OneNote" の [Win]+[S] でのキャプチャ機能に似せて、
># 撮影前の画面にスモークをかけてみました。

保存させていただきました^^今は他のアプリ(VBA)の作成を
しておりますゆえ(なのにこんな時間に掲示板閲覧するな?)、
今晩楽しませていただきます。おかげでまた自分のVBパワーが一個増えそうでございます。

>半透明ウィンドウも撮影したい場合には、CopyFromScreen メソッドの代わりに、
>BitBlt API を CAPTUREBLT フラグ指定で呼び出す必要があります。

 ほんとに、やろうとした事は何でもできるんですねー。>VB
魔界の仮面弁士様っていつ誰が作ろうとしてるアプリに対しても、
さらに付加価値の付くような飛び道具がすぐに出てまいりますね^^
物知り博士と申しますか。。。

 また楽しませていただきます!(早く新しいアプリの作成もすべきなのですが
VBは一個作り始めるとあれもこれもで手を出し初めて止まらなくなります^^;
もうしばらくこのアプリをより良い物にすべく堪能いたします^^)
 アドバイスいただきまして誠にありがとうございました!!m(_ _)m





====【追記】==============================

 こんばんは.今スモークを試させていただきました!^^
ドラッグした瞬間,半分無意識に (゜o゜オォォーー......(吐息)」と.
(↑ほんとに言いました)
こっちのバージョンで行きます!!!m(_ _)m

 お忙しい中コーディングをご提示いただいてどうもありがとうございます.
自分的にはAndAlsoに変わってるだけでも勉強になるんでございますが^^;

 誠にありがとうございました!!!

[ツリー表示へ]