Untitled
unknown
rust
2 years ago
6.1 kB
16
Indexable
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;
}Editor is loading...