MapleStoryのスクリーンショットを取得しようとしたんだけど、どうも環境によって動作が違って、上手くいかなかった。
最初に試したのが、Win32APIのPrintWindow()
これだと、マルチディスプレイだろうと、画面外に飛び出していようと、他ウィンドウで隠れていようと正確にキャプチャ出来るんだけど、ホスト側の64bit7でしかちゃんと動いてくれなくて、VMのXP,7ではMapleStoryのキャプチャーは出来なかった。理由はわからないけど・・・。
msRect.***はそれぞれ座標が入ってる
1 2 3 4 5 6 7 8 9 |
//[DllImport("user32.dll")] //public extern static bool PrintWindow(IntPtr hWnd, IntPtr dc, uint reservedFlag); Bitmap msBmp = new Bitmap(( msRect.right - msRect.left ), ( msRect.bottom - msRect.top )); using( Graphics g = Graphics.FromImage(msBmp) ) { IntPtr hdc = g.GetHdc(); PrintWindow(msProcess.MainWindowHandle, hdc, 0); g.ReleaseHdc(hdc); } |
次に試したのがBitBlt
これは前に邪魔なウィンドウとかがあると、それはそのまま映り込んでしまうから正常に動作しない、最前面にウィンドウがあれば、非アクティブ状態でも取得出来る。
ホストの7と、ゲストのXPは正常動作したんだけど、VMの7だと不思議な動作だった。
非アクティブ状態と、クリックボタン押し続けてる間は取得出来る。でも、MapleStoryをアクティブにすると上手く動作しなくなる。
動画撮ったんだけど、こんな感じ。
うーん・・・不思議。
コードコピペだけど。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
private Bitmap CaptureScreen(int x, int y, int w, int h) { //プライマリモニタのデバイスコンテキストを取得 IntPtr disDC = GetDC(IntPtr.Zero); //Bitmapの作成 Bitmap bmp = new Bitmap(w, h); //Graphicsの作成 Graphics g = Graphics.FromImage(bmp); //Graphicsのデバイスコンテキストを取得 IntPtr hDC = g.GetHdc(); //Bitmapに画像をコピーする BitBlt(hDC, 0, 0, w, h, disDC, x, y, 13369376); //解放 g.ReleaseHdc(hDC); g.Dispose(); ReleaseDC(IntPtr.Zero, disDC); return bmp; } |
全部の環境で上手く行ったのがこれ。
同じくbitbltなんだけど、全体のスクリーンショットを取得してから必要な部分だけ切り抜くようにしてみたら上手く行った。
違いはなんだろう?
マルチディスプレイには対応できなくなってしまった。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//画面全体のスクリーンショットを取得 Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); IntPtr dc = GetDC(IntPtr.Zero); using( Graphics g = Graphics.FromImage(bmp) ) { IntPtr hdc = g.GetHdc(); BitBlt(hdc, 0, 0, bmp.Width, bmp.Height, dc, 0, 0, 13369376); g.ReleaseHdc(hdc); } ReleaseDC(IntPtr.Zero, dc); //必要な部分だけ切トリミング using( Graphics gra = Graphics.FromImage(msBmp) ) { gra.DrawImage(bmp, new Rectangle(0, 0, ( msRect.right - msRect.left ), ( msRect.bottom - msRect.top )), new Rectangle(msRect.left, msRect.top, ( msRect.right - msRect.left ), ( msRect.bottom - msRect.top )), GraphicsUnit.Pixel); } |
printWindowが使えれば一番良いんだけどー