VB.NETでアクティブウインドウのハンドルを取得するには?

解決


日本太郎  2003-04-11 02:54:07  No: 106647

はじめまして、日本太郎です。
  私は、今VB.NETを利用しています。
  質問なのですが、アクティブウインドウのハンドルを取得するためのAPIコマンドで、
「'バッファを確保」
「Name = String(250, Chr(0))」
という式がこのホームページに載っていました。
  初心者質問で申し訳ないのですが、VB.NET対応の式に直すとどうなるのでしょうか?また、キャプチャした画像はどうやってフォームに表示させるのでしょうか。
  失礼ですが、ご存知ならば是非ご教授ください。


nanashi  2003-04-11 03:03:08  No: 106648

最近あんまり.NETには触ってないんですが、確かこんな感じだったと思います(うろ覚え/汗)

Name = New String(CChar(vbNullChar), 250)

もっとふさわしいやり方をご存知の方、フォローお願いします。


日本太郎  2003-04-11 07:09:57  No: 106649

nanashiさん。
  早速のレスありがとうございました。
  Name=の式についての問題は解決しましたが、上に書いてある通り、キャプチャした画像はどうやってフォームに表示させるのでしょうか。
  また、新たな問題なのですが、 
「'現在、アクティブウインドウは自アプリなので自分自身を表示」
「MsgBox("現在アクテイブウインドウのタイトル名は" + Name + "です")」
という式がありますが、実際に実行してみたとき「+Name+」の部分が表示されませんでした。
  何度も同じような初心者質問で申し訳ないのですが、ご存知ならば是非ご教授ください。


Loreley  2003-04-11 11:15:19  No: 106650

+を&にかえてみるといいかもしれません。
MsgBox("現在アクテイブウインドウのタイトル名は" & Name & "です")
のように。
それでもだめならNameが正しく取得できていないか
ウィンドウタイトルがない可能性があります。
Nameが正しく取得できていないというのは、たとえば
Name = New String(CChar(vbNullChar), 250)
MsgBox("現在アクテイブウインドウのタイトル名は" & Name & "です")
というようにNameに文字を代入していないにであればなにも表示されなくて正解です。

キャプチャした画像とは?
保存してある画像ファイルを貼り付けるという意味であれば
FormのPictureプロパティで設定します(VB5やVB6では)


日本太郎  2003-04-12 01:41:06  No: 106651

私の勘違いで本当にすみませんでした。
  実は、緊急で一定時間ごとに画面をキャプチャすると言うプログラムを作らなければいけない用ができてしまったのですが、初心者なのでどうしていいのかさっぱりわからなくなってしまいましたのでここで質問することにしました。
  ここのサイトの「Visual Basic APIサンプル集」にあるような感じに仕上げたいと思っています。どのAPIを使えばいいのでしょうか?
  何度も何度も同じような質問で皆様にご迷惑をかけてしまって本当に申し訳ございません。


Loreley  2003-04-12 07:20:04  No: 106652

APIは
GetDesktopwindow
GetDC
Bitblt
の3つで実現できると思います。


日本太郎  2003-04-12 18:59:07  No: 106653

Loreleyさん、レスありがとうございます。
  あれだけ親切なヒントをいただいたのですが、まだまだ知識の少ない自分にはわからないことがとても多いのでまたですが質問させていただきます。
  Bitbltの「Public Declare Function」ですが、VB.netだと「nWidthAs Long」
の部分で、エラーが出てしまいます。
  あとこれも同じくエラーなのですが、「'picture1の画像をpicture2にコピーする」の部分で、picture1とpicture2が宣言されていないと出てしまいます。
  何とかしてこのプログラムを作り上げたいので、是非ご教授ください。


Loreley  2003-04-12 23:11:11  No: 106654

コードがないので予想の枠を出ませんが
nWidthAs Long
ではなく
nWidth As Long
です。
VB.NETは使ってないので宣言がちがうのかもしれませんね。
なんかimportする必要があるのかも。

「picture1とpicture2が宣言されていない」
というエラーであれば
Picture1とPicture2をそのままつかってませんか?
必要なのは、picture1.hdcやpicture2.hdcになります。
これを使っていてエラーがでるとすれば
「ユーザー定義型は宣言されていません」になるはずなので。


nanashi  2003-04-13 01:17:56  No: 106655

「nWidth As Long」は.NETでは「nWidth As Integer」にして下さい。
この部分だけに限らず、VB6でLong宣言されてるものは.NETではIntegerにしないとAPIは使えません。
VB6ではIntegerが16bit、Longが32bitでしたが、
>NETではIntegerが32bit、Longが64bitに変更されてますので。


nanashi  2003-04-13 01:19:09  No: 106656

あ、なんか変な投稿になっちゃってますね(^^;

VB6ではIntegerが16bit、Longが32bitでしたが、
.NETではIntegerが32bit、Longが64bitに変更されてますので。

です。


日本太郎  2003-04-13 03:52:45  No: 106657

Loreleyさん、nanashiさん、貴重なアドバイスありがとうございました。
  「nWidth As Long」の件については、解決しました。どうもありがとうございました。
  しかしLoreleyさんの言っている
>「picture1とpicture2が宣言されていない」
>というエラーであれば
>Picture1とPicture2をそのままつかってませんか?
>必要なのは、picture1.hdcやpicture2.hdcになります。
  「Picture1.○○」という様にはじめから記述しているので問題はないと思います。
>これを使っていてエラーがでるとすれば
>「ユーザー定義型は宣言されていません」になるはずなので。
  「名前'Picture○'は宣言されていません」というエラーメッセージが出ます。違ってるかもしれませんが多分、Dimに関係があると思います。
  どうすればいいのかはさっぱりなので、ご教授願います。

--------------------------宜しくお願いします。-----------------------


日本太郎  2003-04-13 03:56:57  No: 106658

上の文章の訂正

  意味の通らない文章を書いてしまって申し訳ございません。
  上から三行目は、「しかし、Loreleyさんが言っていたことについては、」
の間違いですお許しください。


Y2  2003-04-13 08:59:58  No: 106659

おそらく、Picture1とPicture2の宣言が正しくないとか、スコープ外で宣言していてアクセスできないとかだと思いますけど、ちなみに、Picture○はどうやって宣言してますか?
第3者としては、それを聞かせてもらえれば答えられる確立が増えるのですが;^^)
VB.NETはエラーメッセージを読めばどんなミスをしているかが結構わかる言語なので、意味が分からないエラーメッセージがでたりしてもそれをヒントに粘ったほうが良いかもしれないです。

画面のキャプチャを自分がやるとしたら、やっぱり、Loreleyさんと同じ方法をとると思います。
それで、サンプル作ってみました。

---<画面をキャプチャして保存するサンプル>-------
Imports System.Drawing

'宣言
Private Declare Function GetDesktopWindow Lib "user32" Alias "GetDesktopWindow" () As System.IntPtr
Private Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hwnd As System.IntPtr) As System.IntPtr
Private Declare Function ReleaseDC Lib "user32" Alias "ReleaseDC" (ByVal hwnd As System.IntPtr, ByVal hdc As System.IntPtr) As Integer
Private Declare Function BitBlt Lib "gdi32.dll" (ByVal hDestDC As IntPtr, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hSrcDC As IntPtr, ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal dwRop As Integer) As IntPtr

Private SWidth As Integer
Private SHeight As Integer
Private Hwnd As IntPtr
Private SrcHDC As IntPtr
Private Img As Bitmap
Private G As Graphics

'準備(Form_Loadあたりに)
SWidth = Screen.PrimaryScreen.Bounds.Width
SHeight = Screen.PrimaryScreen.Bounds.Height
Hwnd = GetDesktopWindow()
SrcHDC = GetDC(Hwnd)
Img = New Bitmap(SWidth, SHeight)
G = Graphics.FromImage(Img)

'開放(Form_Closedあたりに)
G.Dispose()
Img.Dispose()
ReleaseDC(Hwnd, SrcHDC)

'キャプチャ
Dim DestHDC As IntPtr = G.GetHdc()
BitBlt(DestHDC, 0, 0, SWidth, SHeight, SrcHDC, 0, 0, &HCC0020)
G.ReleaseHdc(DestHDC)
Img.Save("保存先のファイルパス", Imaging.ImageFormat.Bmp)
--------------------------------------------------

他にも効率の良いやり方があると思いますけど、日本太郎さんなりに工夫してみてください。


日本太郎  2003-04-14 05:49:18  No: 106660

Y2さん
  サンプルを作っていただいて本当にありがとうございました。

  そのサンプルなのですが、エラーが出てしまいました。

>Private SWidth As Integer
>Private SHeight As Integer
>Private Hwnd As IntPtr
>Private SrcHDC As IntPtr
>Private Img As Bitmap
>Private G As Graphics

Privateではエラーが出ましたがDimだとOKでした。

>'キャプチャ
>Dim DestHDC As IntPtr = G.GetHdc()

  「DestHDC As IntPtr = G.GetHdc()」の式については、青い波線は出ないのですが実行してボタンを押した後に、
  
  「'System.ArgumentException' のハンドルされていない例外がsystem.drawing.dll で発生しました」
  「追加情報 : 使用されたパラメータが無効です。」

  と表示され、「DestHDC As IntPtr = G.GetHdc()」の部分が、緑色になってしまいます。
  今日調べたり、試行錯誤したりして粘ってみたのですが、どうにもなりません。

  一応、コピーを載せておきます。(長いので一部省略)間違いがあれば御指摘願います。
---------------------------------------------------------------------
Imports System.Drawing
Public Class Form1
    Inherits System.Windows.Forms.Form

Public Declare Function GetDC Lib "USE...続く
Private Declare Function GetDesktopWin...続く
Private Declare Function GetDC Lib...続く
Private Declare Function ReleaseDC Li...続く
Private Declare Function BitBlt Lib "...続く

Windowsフォームデザイナで生成されたコード

'---<画面をキャプチャして保存する>---

    Private Sub Button1_Click(ByVal sender As System.Ob...続く
'宣言
        Dim SWidth As Integer
        Dim SHeight As Integer
        Dim Hwnd As IntPtr
        Dim SrcHDC As IntPtr
        Dim Img As Bitmap
        Dim G As Graphics

        '準備(Form_Loadあたりに)
        SWidth = Screen.PrimaryScreen.Bounds.Width
        SHeight = Screen.PrimaryScreen.Bounds.Height
        Hwnd = GetDesktopWindow()
        SrcHDC = GetDC(Hwnd)
        Img = New Bitmap(SWidth, SHeight)
        G = Graphics.FromImage(Img)

        '開放(Form_Closedあたりに)
        G.Dispose()
        Img.Dispose()
        ReleaseDC(Hwnd, SrcHDC)

        'キャプチャ
        Dim DestHDC As IntPtr = G.GetHdc()
        BitBlt(DestHDC, 0, 0, SWidth, SHeight, SrcHDC, 0, 0, &HCC0020)
        G.ReleaseHdc(DestHDC)
        Img.Save("保存先のファイルパス", Imaging.ImageFormat.Bmp)
    End Sub
End Class
---------------------------------------------------------------------


Y2  2003-04-14 09:13:01  No: 106661

書かなかったのが悪かったのですが、
Importsの文と'宣言の文はSubとかFunctionの外側に記述してください。
メールアドレスを教えていただければ、作ったサンプルお送りしますけど。(;^^)


日本太郎  2003-04-14 17:25:15  No: 106662

メールアドレスは、ykigoshi@msn.comです。
よろしくお願いします。


日本太郎  2003-04-15 05:17:09  No: 106663

協力していただいた皆様のおかげでわからなかったところは、一応解決いたしました。
  これからも、このプログラムに工夫と改良を重ねていきたいと思っています。これからは、わからないところはなるべく(限界まで)MSDNや検索で調べていくつもりですが、どうしてもわからないというときには皆様の力をお借りになることもあるかもしれませんので、今後とも宜しくお願いします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加