Untitled
rust
a month ago
6.1 kB
8
Indexable
Never
use std::ffi::*; use windows_sys::Win32::{ Foundation::*, Graphics::Gdi::*, System::Diagnostics::Debug::*, UI::WindowsAndMessaging::*, }; static mut hBitmap: HBITMAP = 0; fn main() { unsafe { let hDesktopWnd = GetDesktopWindow(); let mut desktopRect = std::mem::MaybeUninit::<RECT>::uninit().assume_init(); GetWindowRect(hDesktopWnd, &mut desktopRect); let hdcScreen = GetDC(0); let hdcCapture = CreateCompatibleDC(hdcScreen); hBitmap = CreateCompatibleBitmap(hdcScreen, desktopRect.right - desktopRect.left, desktopRect.bottom - desktopRect.top); SelectObject(hdcCapture, hBitmap); // https://learn.microsoft.com/en-us/windows/win32/gdi/alpha-blending-a-bitmap // make image semi-transparent let bf = BLENDFUNCTION { BlendOp: AC_SRC_OVER as u8, BlendFlags: 0, SourceConstantAlpha: 0x7f, AlphaFormat: 0, }; // let bf = { 0 }; // bf.BlendOp = AC_SRC_OVER; // bf.BlendFlags = 0; // bf.SourceConstantAlpha = 0x7f; // half of 0xff = 50% transparency // bf.AlphaFormat = 0; // ignore source alpha channel AlphaBlend(hdcScreen, 0, 0, desktopRect.right - desktopRect.left, desktopRect.bottom - desktopRect.top, hdcCapture, 0, 0, desktopRect.right - desktopRect.left, desktopRect.bottom - desktopRect.top, bf); // copy modified image device context onto desktop screen BitBlt(hdcCapture, 0, 0, desktopRect.right - desktopRect.left, desktopRect.bottom - desktopRect.top, hdcScreen, 0, 0, SRCCOPY); ReleaseDC(0, hdcScreen); DeleteDC(hdcCapture); // Create a window to display the captured image let lpszClassName = CString::new("Window in Console").unwrap(); let wcex = WNDCLASSA { style: CS_HREDRAW | CS_VREDRAW, lpfnWndProc: Some(wndproc), cbClsExtra: 0, cbWndExtra: 0, hInstance: 0, hIcon: 0, hCursor: LoadCursorW(0, IDC_ARROW), // hbrBackground: (COLOR_WINDOW + 1), as isize, hbrBackground: GetStockObject(NULL_BRUSH), lpszMenuName: std::ptr::null(), lpszClassName: lpszClassName.as_ptr() as *const u8, }; RegisterClassA(&wcex); let lpwindowname = CString::new("Window in Console").unwrap(); let hImageWnd = CreateWindowExA(0, lpszClassName.as_ptr() as *const u8, lpwindowname.as_ptr() as *const u8, WS_POPUP, desktopRect.left, desktopRect.top, desktopRect.right - desktopRect.left, desktopRect.bottom - desktopRect.top, 0, 0, 0, std::ptr::null()); ShowWindow(hImageWnd, 0); UpdateWindow(hImageWnd); // Message loop for the image window let mut msg = std::mem::MaybeUninit::<MSG>::uninit().assume_init(); while (GetMessageA(&mut msg, 0, 0, 0) == 0i32) { TranslateMessage(&msg); DispatchMessageA(&msg); } DeleteObject(hBitmap); } } type UINT = u32; static mut bSnipping: bool = false; static mut ptStart: POINT = POINT { x: 0, y: 0 }; static mut ptEnd: POINT = POINT { x: 0, y: 0 }; unsafe extern "system" fn wndproc(hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM) -> LRESULT { let hdcScreen = GetDC(0); let hdcWindow = GetDC(hwnd); let mut rect = std::mem::MaybeUninit::<RECT>::uninit().assume_init(); GetClientRect(hwnd, &mut rect); match msg { WM_NCCREATE => { println!("Continue creating window"); } WM_CLOSE => { println!("Closing window..."); DestroyWindow(hdcWindow); } WM_LBUTTONDOWN => { // println!("detected mouse click down"); bSnipping = true; GetCursorPos(&mut ptStart); } WM_LBUTTONUP => { if bSnipping { println!("detected mouse click up"); GetCursorPos(&mut ptEnd); bSnipping = false; // Capture the snipped region // do something with the result // for now just copy it onto the screen to see if its correct BitBlt(hdcWindow, 0, 0, rect.right, rect.bottom, hdcScreen, ptStart.x, ptStart.y, SRCCOPY); } } WM_MOUSEMOVE => { if bSnipping { println!("CLIPPING REGION"); GetCursorPos(&mut ptEnd); let bf = BLENDFUNCTION { BlendOp: AC_SRC_OVER as u8, BlendFlags: 0, SourceConstantAlpha: 0xff, AlphaFormat: 0 }; AlphaBlend(hdcWindow, 0, 0, rect.right, rect.bottom, hdcWindow, 0, 0, rect.right, rect.bottom, bf); BitBlt(hdcWindow, 0, 0, rect.right, rect.bottom, hdcScreen, ptStart.x, ptStart.y, SRCCOPY); InvalidateRect(hwnd, std::ptr::null(), 0); } } WM_PAINT => { let mut ps = std::mem::MaybeUninit::<PAINTSTRUCT>::uninit().assume_init(); let hdc = BeginPaint(hwnd, &mut ps); // Draw the captured image onto the window let hdcMem = CreateCompatibleDC(hdc); SelectObject(hdcMem, hBitmap); let mut bm = std::mem::MaybeUninit::<BITMAP>::uninit().assume_init(); GetObjectA(hBitmap, std::mem::size_of::<BITMAP>() as i32, &mut bm as *mut _ as *mut c_void); BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY); DeleteDC(hdcMem); EndPaint(hwnd, &ps); } WM_DESTROY => { PostQuitMessage(0); } _ => { DefWindowProcA(hwnd, msg, wparam, lparam); } } ReleaseDC(hwnd, hdcWindow); ReleaseDC(0, hdcScreen); return 0; }