透過 P/Invoke 呼叫 GDI32 / User32 API,可擷取桌面全螢幕畫面至 Bitmap,再以 GetPixel 取得滑鼠指標位置的顏色值。適用於拾色器、螢幕分析等工具開發。
using System.Runtime.InteropServices;
public static class Win32Api
{
[DllImport("gdi32.dll")] public static extern bool BitBlt(IntPtr hdcDest, int x, int y, int w, int h, IntPtr hdcSrc, int srcX, int srcY, int rop);
[DllImport("gdi32.dll")] public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int w, int h);
[DllImport("gdi32.dll")] public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")] public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObj);
[DllImport("gdi32.dll")] public static extern bool DeleteDC(IntPtr hdc);
[DllImport("gdi32.dll")] public static extern bool DeleteObject(IntPtr hObj);
[DllImport("user32.dll")] public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")] public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll")] public static extern int GetSystemMetrics(int nIndex);
[DllImport("user32.dll")] public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
public static Bitmap CaptureDesktop()
{
IntPtr hDesk = GetDesktopWindow();
IntPtr hdcSrc = GetDC(hDesk);
IntPtr hdcDest = CreateCompatibleDC(hdcSrc);
int w = GetSystemMetrics(0); // SM_CXSCREEN
int h = GetSystemMetrics(1); // SM_CYSCREEN
IntPtr hBmp = CreateCompatibleBitmap(hdcSrc, w, h);
if (hBmp == IntPtr.Zero) return null;
IntPtr hOld = SelectObject(hdcDest, hBmp);
BitBlt(hdcDest, 0, 0, w, h, hdcSrc, 0, 0, 0x00CC0020); // SRCCOPY
SelectObject(hdcDest, hOld);
DeleteDC(hdcDest);
ReleaseDC(hDesk, hdcSrc);
Bitmap bmp = Image.FromHbitmap(hBmp);
DeleteObject(hBmp);
GC.Collect();
return bmp;
}
}
private Bitmap _screenBmp;
private void Label_MouseDown(object sender, MouseEventArgs e)
{
_screenBmp = Win32Api.CaptureDesktop();
}
private void Label_MouseUp(object sender, MouseEventArgs e)
{
if (_screenBmp == null) return;
Color c = _screenBmp.GetPixel(Cursor.Position.X, Cursor.Position.Y);
label1.BackColor = c;
label1.Text = $"R:{c.R} G:{c.G} B:{c.B} #{c.R:X2}{c.G:X2}{c.B:X2}";
_screenBmp.Dispose();
_screenBmp = null;
}
Graphics.CopyFromScreen 替代 GDI API。Graphics.CopyFromScreen 範例:
Bitmap bmp = new Bitmap(1, 1);
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(Cursor.Position, Point.Empty, new Size(1, 1));
}
Color c = bmp.GetPixel(0, 0);
GetSystemMetrics(0/1) 僅回傳主螢幕尺寸。多螢幕環境請用 Screen.AllScreens 計算虛擬桌面範圍。