手順書などを作るために画面のキャプチャをする時に、Alt+PrintScreen でアクティブな画面をキャプチャします。
が、メニューをキャプチャしたいときに【Alt】キーを押すと、そのメニューが消えてしまうんですよね。
なので、各種ツールを探すんですが...Ctrl+PrintScreen に割り当てればいいんじゃないの?ということで自作します。
Ctrl キーの場合は、メニューが閉じられませんからね。
こんな感じで、手軽にメニューもキャプチャできます。
■アクティブウィンドウのキャプチャ
using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)] private struct RECT { public int left; public int top; public int right; public int bottom; } [DllImport("user32.dll")] private static extern IntPtr GetWindowDC(IntPtr hwnd); [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] private static extern int GetWindowRect(IntPtr hwnd, ref RECT lpRect); private const int SRCCOPY = 13369376; [DllImport("user32.dll")] private static extern IntPtr GetDC(IntPtr hwnd); [DllImport("gdi32.dll")] private static extern int BitBlt(IntPtr hDestDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop); [DllImport("user32.dll")] private static extern IntPtr ReleaseDC(IntPtr hwnd, IntPtr hdc); /// /// アクティブウィンドウをキャプチャ /// /// private Bitmap ActiveWindowCapture() { IntPtr hWnd = GetForegroundWindow(); IntPtr hDC = GetWindowDC(hWnd); //ウィンドウの大きさを取得 RECT rect = new RECT(); GetWindowRect(hWnd, ref rect); Bitmap bmp = new Bitmap(rect.right - rect.left, rect.bottom - rect.top); Graphics g = Graphics.FromImage(bmp); IntPtr gDC = g.GetHdc(); BitBlt(gDC, 0, 0, bmp.Width, bmp.Height, hDC, 0, 0, SRCCOPY); g.ReleaseHdc(gDC); g.Dispose(); ReleaseDC(hWnd, hDC); return bmp; }
win api を多用しないといけないので、DllImport が多いですが、こんな感じ。
# BitBlt とか使いたくないけど、他にいい方法がありませんかね?
■ホットキーの登録/解除
ホットキーは、RegisterHotKey と UnregisterHotKey を使います。
HOTKEY_ID のほうは、他のアプリケーションとダブらないように適当に変えてください。
// [DllImport("user32.dll")] extern static int RegisterHotKey(IntPtr hWnd, int id, int modKey, int key); [DllImport("user32.dll")] extern static int UnregisterHotKey(IntPtr hWnd, int id); const int MOD_ALT = 0x0001; const int MOD_CONTROL = 0x0002; const int MOD_SHIFT = 0x0004; const int HOTKEY_ID = 0x1234; // // HotKeyのイベントを示すメッセージID // const int WM_HOTKEY = 0x0312; /// /// ホットキーを登録 /// /// <param name="sender" /> /// <param name="e" /> private void button5_Click(object sender, EventArgs e) { if (RegisterHotKey(this.Handle, HOTKEY_ID, MOD_CONTROL, (int)Keys.PrintScreen) == 0) { MessageBox.Show("既に他のアプリで使用されています。"); } } /// /// ホットキーを解除 /// /// <param name="sender" /> /// <param name="e" /> private void button6_Click(object sender, EventArgs e) { UnregisterHotKey(this.Handle, HOTKEY_ID); } /// /// Window Proc のオーバーライド /// /// <param name="message" /> protected override void WndProc(ref Message message) { if (message.Msg == WM_HOTKEY && (int)message.WParam == HOTKEY_ID) { Bitmap bmp = ActiveWindowCapture(); // bmp.Save(@"c:\work\bmp\" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".bmp"); // クリップボードへコピー Clipboard.SetImage(bmp); return; } base.WndProc(ref message); }
■参考先
画面をキャプチャする: .NET Tips: C#, VB.NET, Visual Studio
http://dobon.net/vb/dotnet/graphics/screencapture.html
ホットキー(HotKey)の設定 (DllImport, InteropServices, RegisterHotKey, UnRegisterHotKey) - いろいろ備忘録日記
http://d.hatena.ne.jp/gsf_zero1/20070416/p1
キーボードでメニューを開き(【Alt】+Fなど)その後【Alt】を押しっぱなしの状態でPrintScreenをすればキャプチャできます。
コンテキストメニューは難しいです。
【Alt】を押しっぱなしにしていると、右クリックしてもメニューが出てきません。
【Alt】+【Ctrl】+右クリックなどとすると、メニューが表示できます。これでキャプチャできます。
ただし、キーボードとの組み合わせによりメニューが異なる場合などは使えません。
> キーボードでメニューを開き(【Alt】+Fなど)その後【Alt】を押しっぱなしの状態でPrintScreenをすればキャプチャできます。
おッ、なるほど、これだといけますね。情報 Thanx です。
Excel 2010 のリボンで使えるかどうか、後で試して見ます。
Excel2007ですが、リボンは微妙な動きをしますね。
単純にキーボードでやると、キーボードのヒントが出てしまいます。
しかも、ドロップダウンを開いた状態でPrintScreenをすると、なんとメニューだけキャプチャされます。
別ウィンドウということらしいです。
マウスでやる場合は【Alt】+【Ctrl】+クリックでドロップダウンが開けますが、こちらもメニューだけキャプチャされるようです。
あ~、そもそも win api を使った方法でキャプチャをすると、右クリックメニュー部分がキャプチャできていないという現象が。
Windows XP だと ok なのに、Windows 7 だとダメでした。
用途に足りてないので、あとで方法を考え直しますか。
IE9 のメニューだとキャプチャできるけど、Visual Studio 2010 のメニューだとキャプチャできないという…謎。
おそらく、ActiveWindow の DC でキャプチャしているので、メニューが消えてしまっている。なので、Desktop の DC を使って、ActiveWinodow の分を切り取れば OK かなぁ。後で試してみる。