I am trying to draw a bitmap to screen that has rgba to my layered window I tried using the UpdateLayeredWindow function but altough it does not error (it returns 1) I don't see any red square which is what I expected what I am doing wrong? (I might be missing something very obvious I have never used the winapi before.)
Here is my code its in rust with the winapi crate (the winapi functions).
use std::{
error::Error,
os::windows::prelude::OsStrExt,
ptr::{null, null_mut},
};
use winapi::{
ctypes::*,
shared::{minwindef::*, windef::*},
um::{libloaderapi::GetModuleHandleW, wingdi::*, winuser::*},
};
fn to_wstring(value: &str) -> Vec<u16> {
std::ffi::OsStr::new(value)
.encode_wide()
.chain(std::iter::once(0))
.collect()
}
fn main() {
let hdl = create_main_window("my_windeow", "Exaemple window creation");
match hdl {
Ok(hdl) => unsafe {
let r = ShowWindow(hdl, SW_SHOW);
let mut rect = std::mem::MaybeUninit::<RECT>::uninit();
if GetWindowRect(hdl, rect.as_mut_ptr()) != 0 {
let rect = rect.assume_init();
println!("Window position: ({}, {})", rect.left, rect.top);
println!(
"Window size: {}x{}",
rect.right - rect.left,
rect.bottom - rect.top
);
} else {
// Handle error
}
println!("{:#?} 306", r);
draw(hdl);
run_message_loop(hdl);
},
Err(e) => {
println!("{:#?} 311", e);
}
}
}
fn run_message_loop(hwnd: HWND) -> WPARAM {
unsafe {
let mut msg: MSG = std::mem::uninitialized();
loop {
// Get message from message queue
if GetMessageW(&mut msg, hwnd, 0, 0) > 0 {
TranslateMessage(&msg);
DispatchMessageW(&msg);
} else {
// Return on error (<0) or exit (=0) cases
return msg.wParam;
}
}
}
}
fn create_main_window(name: &str, title: &str) -> Result<HWND, Box<dyn Error>> {
let name = to_wstring(name);
let title = to_wstring(title);
unsafe {
// Get handle to the file used to create the calling process
let hinstance = GetModuleHandleW(null_mut());
// Create and register window class
let wnd_class = WNDCLASSEXW {
cbSize: std::mem::size_of::<WNDCLASSEXW>() as u32,
style: CS_HREDRAW | CS_VREDRAW,
lpfnWndProc: Some(window_proc),
cbClsExtra: 0,
cbWndExtra: 0,
hInstance: hinstance, // Handle to the instance that contains the window procedure for the class
hIcon: LoadIconW(null_mut(), IDI_APPLICATION),
hCursor: LoadCursorW(null_mut(), IDC_ARROW),
hbrBackground: CreateSolidBrush(0),
lpszMenuName: null_mut(),
lpszClassName: name.as_ptr(),
hIconSm: LoadIconW(null_mut(), IDI_APPLICATION),
};
// Register window class
if RegisterClassExW(&wnd_class) == 0 {
MessageBoxW(
null_mut(),
to_wstring("Window Registration Failed!").as_ptr(),
to_wstring("Error").as_ptr(),
MB_ICONEXCLAMATION | MB_OK,
);
return Err("Window Registration Failed".into());
};
// Create a window based on registered class
let handle: *mut HWND__ = CreateWindowExW(
WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST | WS_EX_APPWINDOW, //| WS_EX_TOOLWINDOW,
name.as_ptr(),
title.as_ptr(),
0,
0,
0,
2560,
1440,
null_mut(),
null_mut(),
hinstance,
null_mut(),
);
if handle.is_null() {
MessageBoxW(
null_mut(),
to_wstring("Window Creation Failed!").as_ptr(),
to_wstring("Error!").as_ptr(),
MB_ICONEXCLAMATION | MB_OK,
);
return Err("Window Creation Failed!".into());
}
//SetWindowLongA(handle, GWL_STYLE, 0);
//SetLayeredWindowAttributes(handle, 0, 100 as u8, LWA_ALPHA);
Ok(handle)
}
}
unsafe fn draw(hdl: HWND) {
let window = GetDC(hdl);
let hdc = CreateCompatibleDC(window);
let header = BITMAPINFO {
bmiHeader: BITMAPINFOHEADER {
biSize: std::mem::size_of::<BITMAPINFOHEADER>() as u32,
biWidth: 2560,
biHeight: 1440,
biPlanes: 1,
biBitCount: 32,
biCompression: BI_RGB,
biSizeImage: 2560 * 1440 * 4,
biXPelsPerMeter: 0,
biYPelsPerMeter: 0,
biClrUsed: 0,
biClrImportant: 0,
},
bmiColors: [RGBQUAD {
rgbBlue: 0,
rgbGreen: 0,
rgbRed: 0,
rgbReserved: 0,
}],
};
let mut null_ptr: *mut std::ffi::c_void = std::ptr::null_mut();
let pv_bits: *mut *mut std::ffi::c_void = &mut null_ptr;
let hbitmap = CreateDIBSection(hdc, &header, DIB_RGB_COLORS, pv_bits, null_mut(), 0x0);
let buf = *pv_bits as *mut [u32; 2560 * 1440];
for i in 0..2560 * 1440 {
(*buf)[i] = 0xFFFF0000;
}
SelectObject(hdc, hbitmap as *mut c_void);
let blend: *mut BLENDFUNCTION = &mut BLENDFUNCTION {
BlendOp: AC_SRC_OVER,
BlendFlags: 0,
SourceConstantAlpha: 255,
AlphaFormat: AC_SRC_ALPHA,
} as *mut BLENDFUNCTION;
let point: *mut POINT = &mut POINT { x: 0, y: 0 } as *mut POINT;
let x = UpdateLayeredWindow(
hdl,
null_mut(),
null_mut(),
null_mut(),
hdc,
point,
0,
blend,
ULW_ALPHA,
);
//prints 1 which means no error
println!("{:#?} 448", x);
}
pub unsafe extern "system" fn window_proc(
hwnd: HWND,
msg: UINT,
wparam: WPARAM,
lparam: LPARAM,
) -> LRESULT {
match msg {
WM_CLOSE => {
DestroyWindow(hwnd);
}
WM_DESTROY => {
PostQuitMessage(0);
}
WM_LBUTTONDOWN => {}
WM_PAINT => {}
WM_CREATE => {
//draw(hwnd);
}
_ => return DefWindowProcW(hwnd, msg, wparam, lparam),
}
return 0;
}