我正在开发一个Windows应用程序,当他/她按下Alt + z时,它正在拍摄用户系统的屏幕截图。
表示我是处理Windows消息的WndProc
。
下面我提供了代码段。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Reflection;
namespace QuickScreenShot
{
public partial class Form1 : Form
{
// Assembly anAssembly;
[DllImport("User32.dll")]
protected static extern int SetClipboardViewer(int hWndNewViewer);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
// HOT key dlls
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
IntPtr nextClipboardViewer;
private System.Windows.Forms.ContextMenu contextMenu1;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.NotifyIcon notifyIcon1;
public Form1()
{
InitializeComponent();
Clipboard.Clear();
nextClipboardViewer = (IntPtr)SetClipboardViewer((int)this.Handle);
// Alt =1 , Ctrl =2, Shift =4, Win =0
//register hot Ctrl , Alt, and ‘z’
bool success;
success = Form1.RegisterHotKey(this.Handle, this.GetType().GetHashCode(), 1, (int)'Z');
if (success)
{
Console.WriteLine("Alt-z hot key successfully registered");
this.notifyIcon1 = new System.Windows.Forms.NotifyIcon();
this.notifyIcon1.Visible = true;
this.notifyIcon1.BalloonTipTitle = "Quick ScreenShot has been started.";
this.notifyIcon1.BalloonTipText = "Use Alt + z to take screenshots.";
this.notifyIcon1.Text = "Quick Screenshot is running";
this.notifyIcon1.BalloonTipIcon = ToolTipIcon.Info;
this.contextMenu1 = new System.Windows.Forms.ContextMenu();
this.menuItem1 = new System.Windows.Forms.MenuItem();
// Initialize contextMenu1
this.contextMenu1.MenuItems.AddRange(
new System.Windows.Forms.MenuItem[] { this.menuItem1 });
// Initialize menuItem1
this.menuItem1.Index = 0;
this.menuItem1.Text = "E&xit";
this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
this.notifyIcon1.ContextMenu = this.contextMenu1;
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(
"QuickScreenShot.images" + ".capture_icon.ico"))
{
this.notifyIcon1.Icon = new Icon(stream);
}
this.notifyIcon1.ShowBalloonTip(30000);
}
else
MessageBox.Show("Could not register Hotkey – there is probably a conflict. ", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
private void menuItem1_Click(object Sender, EventArgs e)
{
// Close the form, which closes the application.
Application.Exit();
this.notifyIcon1.Icon = null;
}
protected override void WndProc(ref System.Windows.Forms.Message m)
{
try
{
// defined in winuser.h
const int WM_DRAWCLIPBOARD = 0x308;
const int WM_CHANGECBCHAIN = 0x030D;
switch (m.Msg)
{
case WM_DRAWCLIPBOARD:
DisplayClipboardData();
SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
break;
case WM_CHANGECBCHAIN:
if (m.WParam == nextClipboardViewer)
nextClipboardViewer = m.LParam;
else
SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
break;
case 0x0312:
CaptureAndSave();
break;
default:
base.WndProc(ref m);
break;
}
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
void DisplayClipboardData()
{
try
{
//System.Windows.Forms.IDataObject iData = new DataObject();
//iData = Clipboard.GetDataObject();
//if (iData.GetDataPresent(DataFormats.Rtf))
// Console.WriteLine((string)iData.GetData(DataFormats.Rtf));
//else if (iData.GetDataPresent(DataFormats.Text))
// Console.WriteLine((string)iData.GetData(DataFormats.Text));
//else if (iData.GetDataPresent(DataFormats.Bitmap))
//{
if (Clipboard.ContainsImage())
{
Console.WriteLine("retrieving image");
Bitmap aBitMap = (Bitmap)Clipboard.GetImage();
string newImageName = System.IO.Path.GetTempFileName();
aBitMap.Save(newImageName, System.Drawing.Imaging.ImageFormat.Png);
ProcessStartInfo procInfo = new ProcessStartInfo();
Process Proc = Process.Start("mspaint.exe", newImageName);
while (Proc.MainWindowHandle == IntPtr.Zero)
{
System.Threading.Thread.Sleep(100);
}
System.IO.File.Delete(newImageName);
Proc.Close();
}
else
Console.WriteLine("[Clipboard data is not RTF or ASCII Text]");
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
private void CaptureAndSave()
{
uint intReturn = 0;
NativeWIN32.INPUT structInput;
structInput = new NativeWIN32.INPUT();
structInput.type = (uint)1;
structInput.ki.wScan = 0;
structInput.ki.time = 0;
structInput.ki.dwFlags = 0;
structInput.ki.dwExtraInfo = 0;
//Press Alt Key
structInput.ki.wVk = (ushort)NativeWIN32.VK.MENU;
intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
// Key down the actual key-code
structInput.ki.wVk = (ushort)NativeWIN32.VK.SNAPSHOT;
//vk;
intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
// Key up the actual key-code
structInput.ki.dwFlags = NativeWIN32.KEYEVENTF_KEYUP;
structInput.ki.wVk = (ushort)NativeWIN32.VK.SNAPSHOT;
//vk;
intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
//Keyup Alt
structInput.ki.dwFlags = NativeWIN32.KEYEVENTF_KEYUP;
structInput.ki.wVk = (ushort)NativeWIN32.VK.MENU;
intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
public class NativeWIN32
{
public const ushort KEYEVENTF_KEYUP = 0x0002;
public enum VK : ushort
{
SHIFT = 0x10,
CONTROL = 0x11,
MENU = 0x12,
ESCAPE = 0x1B,
BACK = 0x08,
TAB = 0x09,
RETURN = 0x0D,
PRIOR = 0x21,
NEXT = 0x22,
END = 0x23,
HOME = 0x24,
LEFT = 0x25,
UP = 0x26,
RIGHT = 0x27,
DOWN = 0x28,
SELECT = 0x29,
PRINT = 0x2A,
EXECUTE = 0x2B,
SNAPSHOT = 0x2C,
INSERT = 0x2D,
DELETE = 0x2E,
HELP = 0x2F,
NUMPAD0 = 0x60,
NUMPAD1 = 0x61,
NUMPAD2 = 0x62,
NUMPAD3 = 0x63,
NUMPAD4 = 0x64,
NUMPAD5 = 0x65,
NUMPAD6 = 0x66,
NUMPAD7 = 0x67,
NUMPAD8 = 0x68,
NUMPAD9 = 0x69,
MULTIPLY = 0x6A,
ADD = 0x6B,
SEPARATOR = 0x6C,
SUBTRACT = 0x6D,
DECIMAL = 0x6E,
DIVIDE = 0x6F,
F1 = 0x70,
F2 = 0x71,
F3 = 0x72,
F4 = 0x73,
F5 = 0x74,
F6 = 0x75,
F7 = 0x76,
F8 = 0x77,
F9 = 0x78,
F10 = 0x79,
F11 = 0x7A,
F12 = 0x7B,
OEM_1 = 0xBA, // ',:' for US
OEM_PLUS = 0xBB, // '+' any country
OEM_COMMA = 0xBC, // ',' any country
OEM_MINUS = 0xBD, // '-' any country
OEM_PERIOD = 0xBE, // '.' any country
OEM_2 = 0xBF, // '/?' for US
OEM_3 = 0xC0, // '`~' for US
MEDIA_NEXT_TRACK = 0xB0,
MEDIA_PREV_TRACK = 0xB1,
MEDIA_STOP = 0xB2,
MEDIA_PLAY_PAUSE = 0xB3,
LWIN = 0x5B,
RWIN = 0x5C
}
public struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public long time;
public uint dwExtraInfo;
};
[StructLayout(LayoutKind.Explicit, Size = 28)]
public struct INPUT
{
[FieldOffset(0)]
public uint type;
[FieldOffset(4)]
public KEYBDINPUT ki;
};
[DllImport("user32.dll")]
public static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);
}
}
一切正常,但是当应用程序获得消息类型WM_WININICHANGE
时,它将转到case语句的默认部分并挂起应用程序。
我不知道如何处理此消息,因此它不会挂起我的系统和应用程序。
请帮帮我。
非常感谢。