Reputation: 13
I created a simple window in rust with the win32 api and docked it to the top of the screen using the shell api. But if I run this code, after the window has been created the taskbar reappears immediately and I cannot set it to auto hide.
use std::{ffi::OsStr, os::windows::ffi::OsStrExt, ptr::null_mut};
use windows_sys::Win32::System::LibraryLoader::GetModuleHandleW;
use windows_sys::Win32::UI::{Shell::*, WindowsAndMessaging::*};
use windows_sys::Win32::Graphics::Gdi::UpdateWindow;
use windows_sys::Win32::Foundation::*;
use std::mem::zeroed;
const WM_APPBAR: u32 = WM_USER + 1;
pub fn to_wstring(str: &str) -> Vec<u16> { OsStr::new(str)
.encode_wide().chain(Some(0).into_iter()).collect() }
unsafe extern "system" fn wnd_proc(hwnd: HWND, msg: u32, wp: WPARAM, lp: LPARAM) -> LRESULT {
match msg {
WM_APPBAR => {
if lp == ABN_POSCHANGED as isize ||
lp == ABN_STATECHANGE as isize
{ update_appbar(hwnd); } 0
},
WM_DESTROY => {
let mut abd: APPBARDATA = std::mem::zeroed();
abd.cbSize = std::mem::size_of::<APPBARDATA>() as u32;
abd.hWnd = hwnd; abd.uEdge = ABE_TOP;
abd.rc = RECT { left: 0, top: 0, right: GetSystemMetrics(SM_CXSCREEN), bottom: 30 };
abd.lParam = ABS_ALWAYSONTOP as isize;
abd.uCallbackMessage = WM_APPBAR;
SHAppBarMessage(ABM_REMOVE, &mut abd);
PostQuitMessage(0);
0
},
_ => DefWindowProcW(hwnd, msg, wp, lp)
}
}
fn main() {
unsafe {
RegisterClassW(&WNDCLASSW {
lpszClassName: to_wstring("utilbar_main_toolbar").as_ptr(),
hCursor: LoadCursorW(null_mut(), IDC_ARROW),
hInstance: GetModuleHandleW(null_mut()),
cbClsExtra: 0, cbWndExtra: 0,
lpfnWndProc: Some(wnd_proc),
hbrBackground: null_mut(),
lpszMenuName: null_mut(),
hIcon: null_mut(),
style: 0,
});
let hwnd = CreateWindowExW(
WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE,
to_wstring("utilbar_main_toolbar").as_ptr(),
to_wstring("").as_ptr(),
WS_POPUP,
0,
0,
GetSystemMetrics(SM_CXSCREEN),
30,
null_mut(),
null_mut(),
GetModuleHandleW(null_mut()),
null_mut()
);
ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); update_appbar(hwnd);
let taskbar_hwnd = FindWindowW(to_wstring("Shell_TrayWnd").as_ptr(), null_mut());
let mut abd: APPBARDATA = std::mem::zeroed(); abd.lParam = ABS_AUTOHIDE as isize;
abd.cbSize = size_of::<APPBARDATA>() as u32; abd.hWnd = taskbar_hwnd;
SHAppBarMessage(ABM_SETSTATE, &mut abd);
let mut msg: MSG = zeroed();
while GetMessageW(&mut msg, hwnd, 0, 0) > 0
{ TranslateMessage(&msg); DispatchMessageW(&msg); }
}
}
unsafe fn update_appbar(hwnd: HWND) {
let mut abd: APPBARDATA = std::mem::zeroed();
abd.cbSize = std::mem::size_of::<APPBARDATA>() as u32;
abd.hWnd = hwnd; abd.uEdge = ABE_TOP;
abd.rc = RECT { left: 0, top: 0, right: GetSystemMetrics(SM_CXSCREEN), bottom: 30 };
abd.lParam = ABS_ALWAYSONTOP as isize;
abd.uCallbackMessage = WM_APPBAR;
SHAppBarMessage(ABM_NEW, &mut abd);
SHAppBarMessage(ABM_SETPOS, &mut abd);
SHAppBarMessage(ABM_SETSTATE, &mut abd);
SetWindowPos(hwnd, null_mut(), 0, 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
Even in the settings app if I toggle "Automatically hide taskbar" it reappears.
Why does this happen? How can I fix it?
The full source code is here on github: https://github.com/barnabasd/utilbar
Upvotes: 0
Views: 56