Skip to main content

pacenotes_installer\ui/
control_text.rs

1/// Sets a dialog control's caption from the string table.
2pub unsafe fn set_text(dialog: windows_sys::Win32::Foundation::HWND, control: u16, string_id: u16) {
3    set_text_raw(dialog, control, &crate::i18n::load_string(string_id));
4}
5
6pub unsafe fn set_text_raw(dialog: windows_sys::Win32::Foundation::HWND, control: u16, text: &str) {
7    let wide = crate::i18n::to_wide(text);
8    windows_sys::Win32::UI::WindowsAndMessaging::SetDlgItemTextW(
9        dialog,
10        control as i32,
11        wide.as_ptr(),
12    );
13}
14
15/// Adds a line at the end of a multi-line edit control, which scrolls to it.
16/// Setting the whole text again for each line made a long run's log
17/// quadratic: 20 s for 1 500 lines, measured on the control itself.
18pub unsafe fn append_line(dialog: windows_sys::Win32::Foundation::HWND, control: u16, line: &str) {
19    let edit = windows_sys::Win32::UI::WindowsAndMessaging::GetDlgItem(dialog, control as i32);
20    if edit.is_null() {
21        return;
22    }
23    let length = windows_sys::Win32::UI::WindowsAndMessaging::GetWindowTextLengthW(edit) as usize;
24    let text = if length == 0 {
25        crate::i18n::to_wide(line)
26    } else {
27        crate::i18n::to_wide(&format!("\r\n{line}"))
28    };
29    let send = windows_sys::Win32::UI::WindowsAndMessaging::SendMessageW;
30    // A pane appended to is capped at 30 000 characters unless lifted; 0 lifts it.
31    send(
32        edit,
33        windows_sys::Win32::UI::Controls::EM_SETLIMITTEXT,
34        0,
35        0,
36    );
37    send(
38        edit,
39        windows_sys::Win32::UI::Controls::EM_SETSEL,
40        length,
41        length as isize,
42    );
43    send(
44        edit,
45        windows_sys::Win32::UI::Controls::EM_REPLACESEL,
46        0,
47        text.as_ptr() as isize,
48    );
49}
50
51/// At most 1023 characters, which no control here holds more of.
52pub unsafe fn get_text(dialog: windows_sys::Win32::Foundation::HWND, control: u16) -> String {
53    let mut buffer = [0u16; 1024];
54    let length = windows_sys::Win32::UI::WindowsAndMessaging::GetDlgItemTextW(
55        dialog,
56        control as i32,
57        buffer.as_mut_ptr(),
58        buffer.len() as i32,
59    );
60    String::from_utf16_lossy(&buffer[..length as usize])
61}
62
63pub unsafe fn set_window_text(window: windows_sys::Win32::Foundation::HWND, text: &str) {
64    let wide = crate::i18n::to_wide(text);
65    windows_sys::Win32::UI::WindowsAndMessaging::SetWindowTextW(window, wide.as_ptr());
66}
67
68pub unsafe fn enable(dialog: windows_sys::Win32::Foundation::HWND, control: u16, enabled: bool) {
69    windows_sys::Win32::UI::Input::KeyboardAndMouse::EnableWindow(
70        windows_sys::Win32::UI::WindowsAndMessaging::GetDlgItem(dialog, control as i32),
71        i32::from(enabled),
72    );
73}