0

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

2
  • 1
    Please add a minimal reproducible example within the question. Commented Aug 22, 2024 at 10:08
  • I have edited the question to include the requested changes. Thank you for pointing it out. Commented Aug 24, 2024 at 9:06

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.