public static class HotKey
{
[DllImport("user32.dll", SetLastError = true)]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, Keys vk);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
[Flags]
public enum Modifiers : uint
{
None = 0, Alt = 1, Control = 2, Shift = 4, Win = 8
}
}
public partial class MainForm : Form
{
private ScreenBody _screenBody;
private const int HOTKEY_ID = 100;
public MainForm()
{
InitializeComponent();
// 系統匣選單
var menu = new ContextMenuStrip();
menu.Items.Add("設定熱鍵", null, (s,e) => new SetHotKeyForm().ShowDialog());
menu.Items.Add("結束", null, (s,e) => Application.Exit());
notifyIcon1.ContextMenuStrip = menu;
notifyIcon1.Visible = true;
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
RegisterHotKeyFromSettings();
}
private void RegisterHotKeyFromSettings()
{
uint mod = (uint)HotKey.Modifiers.Control;
if (Settings.Default.UseAlt) mod |= (uint)HotKey.Modifiers.Alt;
HotKey.RegisterHotKey(Handle, HOTKEY_ID, mod, Settings.Default.HotKey);
}
protected override void WndProc(ref Message m)
{
const int WM_HOTKEY = 0x0312;
if (m.Msg == WM_HOTKEY && m.WParam.ToInt32() == HOTKEY_ID)
CaptureScreen();
base.WndProc(ref m);
}
private void CaptureScreen()
{
// 全螢幕截圖
Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
using (Graphics g = Graphics.FromImage(bmp))
g.CopyFromScreen(Point.Empty, Point.Empty, Screen.PrimaryScreen.Bounds.Size);
_screenBody = new ScreenBody { BackgroundImage = bmp };
_screenBody.Show();
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
HotKey.UnregisterHotKey(Handle, HOTKEY_ID);
base.OnFormClosing(e);
}
}
static class Program
{
[DllImport("User32.dll")] private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
[DllImport("User32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd);
private const int SW_SHOWNORMAL = 1;
[STAThread]
static void Main()
{
Process current = Process.GetCurrentProcess();
Process[] procs = Process.GetProcessesByName(current.ProcessName);
foreach (var p in procs)
{
if (p.Id != current.Id &&
Assembly.GetExecutingAssembly().Location.Replace("/", "") == p.MainModule.FileName)
{
ShowWindowAsync(p.MainWindowHandle, SW_SHOWNORMAL);
SetForegroundWindow(p.MainWindowHandle);
return; // 已有實例運行
}
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
專案資料夾結構:
ScreenCutter/ Cursors/ hcross.cur, move_m.cur, size1_m.cur, size2_m.cur, size3_m.cur, size4_m.cur Icons/ app.ico Images/ (可選)
從 `C:\Windows\Cursors` 複製系統游標檔,程式中用相對路徑 `@"..\..\Cursors\xxx.cur"` 載入。
整合熱鍵、系統匣、單一實例、全螢幕截圖、可調整選區矩形,構成功能完整的類 QQ 截圖工具。核心技術點:P/Invoke 熱鍵、WndProc 訊息迴路、Graphics.CopyFromScreen、ControlPaint 反轉繪製、Mutex/Process 單一實例。