質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Q&A

0回答

615閲覧

Win32 APIでウィンドウにコントロールを配置できない

lattex

総合スコア4

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

0グッド

0クリップ

投稿2022/04/06 00:57

前提

Rust言語でGUIライブラリを作っています。ウィンドウにコントロールを追加する機能を作成しています。
しかしウィンドウにコントロールを追加してもコントロールが表示されません。

該当のソースコード

window.rs

Rust

1#[cfg(windows)] 2use windows_sys::Win32::UI::WindowsAndMessaging::*; 3#[cfg(windows)] 4use windows_sys::Win32::Foundation::*; 5use std::sync::{Arc, mpsc, Mutex}; 6use std::thread; 7use std::thread::park_timeout; 8use std::time::Duration; 9use crate::natives_and_messaging::AdvancedWindowStyle; 10use crate::widget::NWidget; 11use super::*; 12#[derive(Clone)] 13pub struct Window { 14 handle: windows_sys::Win32::Foundation::HWND, 15 message: windows_sys::Win32::Foundation::WPARAM, 16 17 attributes: Attributes, 18 pub wh: Arc<Mutex<WindowHandler>>, 19 pub is_handle_created: bool 20} 21impl Window { 22 pub fn new(attributes: Attributes) -> Self { 23 Self { 24 handle: 0, 25 message: 0, 26 27 attributes, 28 wh: Arc::new(Mutex::new(WindowHandler::new(0))), 29 is_handle_created: false 30 } 31 } 32 pub fn run(self, action: fn(wh: WindowHandler)) { 33 let (wtx, wrx) = mpsc::channel(); 34 let (atx, arx) = mpsc::channel(); 35 wtx.send(self.clone()).unwrap(); 36 atx.send(self.clone().wh); 37 let build_h = thread::spawn(move || { 38 wrx.recv().unwrap().build(); 39 }); 40 park_timeout(Duration::new(1,0)); 41 println!("{}",self.wh.lock().unwrap().handle); 42 let action_h = thread::spawn(move || { 43 action(*arx.recv().unwrap().lock().unwrap()) 44 }); 45 dbg!(build_h.join()); 46 dbg!(action_h.join()); 47 } 48 fn build(&mut self) { 49 use windows_sys::Win32::System::LibraryLoader::GetModuleHandleA; 50 unsafe { 51 let instance = GetModuleHandleA(std::ptr::null()); 52 debug_assert!(instance != 0); 53 54 let window_class = b"window\0".as_ptr(); 55 56 let wc = WNDCLASSA { 57 hCursor: LoadCursorW(0, IDC_ARROW), 58 hInstance: instance, 59 lpszClassName: window_class, 60 style: CS_HREDRAW | CS_VREDRAW, 61 lpfnWndProc: Some(Self::wndproc), 62 cbClsExtra: 0, 63 cbWndExtra: 0, 64 hIcon: 0, 65 hbrBackground: 5, 66 lpszMenuName: std::ptr::null(), 67 }; 68 let atom = RegisterClassA(&wc); 69 debug_assert!(atom != 0); 70 let handle = CreateWindowExA(0, window_class, format!("{}\0",self.attributes.title).as_ptr(), self.attributes.style, self.attributes.x, self.attributes.y, self.attributes.width, self.attributes.height, 0, 0, instance, self as *mut _ as _); 71 self.wh.lock().unwrap().handle = handle; 72 let mut message = std::mem::zeroed(); 73 while GetMessageA(&mut message, 0, 0, 0) != 0 { 74 DispatchMessageA(&message); 75 } 76 } 77 // let handle = CreateWindowExA(0, b"window\0".as_ptr(), format!("{}\0",self.attributes.title).as_ptr(), WS_OVERLAPPEDWINDOW, self.attributes.x, self.attributes.y, self.attributes.width, self.attributes.height, 0, 0, instance, self as *mut _ as _); 78 } 79 extern "system" fn wndproc(window: HWND, message: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT { 80 unsafe { 81 match message { 82 WM_DESTROY => { 83 PostQuitMessage(0); 84 return 0 85 } 86 _ => {} 87 } 88 89 if message == WM_NCCREATE { 90 let cs = lparam as *const CREATESTRUCTA; 91 println!("CREATESTRUCT A {:?}",cs); 92 let this = (*cs).lpCreateParams as *mut Self; 93 println!("This : {:?}",this); 94 (*this).handle = window; 95 println!("Finish"); 96 97 SetWindowLongW(window, GWLP_USERDATA, this as _); 98 println!("Set Window Long"); 99 } else { 100 let _this = GetWindowLongW(window, GWLP_USERDATA) as *mut Self; 101 } 102 103 DefWindowProcA(window, message, wparam, lparam) 104 } 105 } 106} 107 108#[derive(Clone,Copy)] 109pub struct WindowHandler { 110 handle: windows_sys::Win32::Foundation::HWND 111} 112 113impl WindowHandler { 114 pub fn new(handle: windows_sys::Win32::Foundation::HWND) -> Self { 115 Self { 116 handle 117 } 118 } 119 120 pub fn show(&self) { 121 unsafe { 122 println!("Window Handler handle: {}",self.handle); 123 ShowWindow(self.handle, SW_SHOWNORMAL); 124 info!("A window has appeared. handle: {}", self.handle); 125 } 126 } 127 128 pub fn add(&self,widget: impl NWidget + Copy) { 129 unsafe { 130 SetWindowLongA(widget.get_handle(),GWL_STYLE,(WS_VISIBLE|WS_CHILD) as i32); 131 SetParent(widget.get_handle(),self.handle); 132 } 133 } 134 /// Returns the window handle. 135 pub fn get_window(&self) -> windows_sys::Win32::Foundation::HWND { 136 self.handle 137 } 138}

widget.rs(メインメソッド)

Rust

1use nxui::natives_and_messaging::*; 2use nxui::widget::button::Button; 3use nxui::widget::menu::Menu; 4use nxui::widget::menubar::MenuBar; 5use nxui::widget::menuitem::MenuItem; 6use nxui::window::Attributes; 7use nxui::window::window::{Window, WindowHandler}; 8 9fn main() { 10 nxui::initialize(); 11 // ウィンドウを初期化する 12 let mut win = Window::new(Attributes::new(WS_NORMAL,"Widget Window".to_string(),"io.github.lattesyobon.nxui".to_string(),DF_WINDOW_SIZE,DF_WINDOW_SIZE,DF_WINDOW_POS,DF_WINDOW_POS)); 13 win.run(run_app); 14} 15 16fn run_app(wh: WindowHandler) { 17 wh.set_title("Window title changed!".to_string()); 18 // ボタンを初期化 19 let sample_button = Button::new( 20 Attributes::new( 21 WS_NORMAL, 22 "Push Button".to_string(), 23 "".to_string(), 24 DF_WINDOW_SIZE, 25 DF_WINDOW_SIZE, 26 DF_WINDOW_POS, 27 DF_WINDOW_POS, 28 ), 29 ); 30 // ボタンを追加する 31 wh.add(sample_button); 32 // ウィンドウを表示する 33 wh.show(); 34}

button.rs

Rust

1use crate::widget::NWidget; 2use crate::window::Attributes; 3 4#[cfg(windows)] 5#[derive(Clone,Copy)] 6pub struct Button { 7 pub handle: windows_sys::Win32::Foundation::HWND, 8} 9 10#[cfg(windows)] 11impl Button { 12 pub fn new(attributes: Attributes) -> Self { 13 use windows_sys::Win32::UI::WindowsAndMessaging::*; 14 use windows_sys::Win32::Foundation::WPARAM; 15 use windows_sys::Win32::Graphics::Gdi::OUT_DEFAULT_PRECIS; 16 use windows_sys::Win32::Graphics::Gdi::{CLIP_DEFAULT_PRECIS, CreateFontA, DEFAULT_QUALITY, FF_ROMAN, FW_NORMAL, SHIFTJIS_CHARSET, VARIABLE_PITCH}; 17 unsafe { 18 let handle = CreateWindowExA( 19 0, 20 "BUTTON\0".as_ptr(), 21 format!("{}\0", attributes.title).as_ptr(), 22 0, 23 attributes.x, 24 attributes.y, 25 attributes.width, 26 attributes.height, 27 0, 28 0, 29 0, 30 std::ptr::null_mut(), 31 ); 32 if handle == 0 { 33 match MessageBox::new("NXUI Warning", "NXUI Warning - Code 0002\rWidget could not be initialized\rRunning it as is may disrupt the UI\rPress Yes to continue program execution\r \rDetailed information:\rPanicked at nxui::widget::button\rTo resolve this error, contact the application developer or\rPlease report at https://github.com/LatteSyobon/nxui/issues", MS_WARNING, BS_YESNO).show() 34 { 35 MR_NO => { 36 panic!("Exit request from user"); 37 } 38 _ => {} 39 }; 40 } 41 SendMessageA(handle, WM_SETFONT, CreateFontA(26, 0, 0, 0, FW_NORMAL as i32, 0, 0, 0, SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH | FF_ROMAN, "Yu Gothic".as_ptr()) as WPARAM, 1); 42 info!("Button has been created. handle: {}", handle); 43 Self { handle } 44 } 45 } 46 47 pub fn show(&self) { 48 use windows_sys::Win32::UI::WindowsAndMessaging::ShowWindow; 49 use windows_sys::Win32::UI::WindowsAndMessaging::SW_SHOWNORMAL; 50 unsafe { 51 ShowWindow(self.handle, SW_SHOWNORMAL); 52 info!("handle: {}", self.handle); 53 } 54 } 55} 56 57#[cfg(windows)] 58impl NWidget for Button { 59 fn get_handle(self) -> windows_sys::Win32::Foundation::HWND { 60 println!("{}",self.handle); 61 self.handle 62 } 63 64 fn set_font(&self,font: Font) { 65 use windows_sys::Win32::Foundation::WPARAM; 66 use windows_sys::Win32::UI::WindowsAndMessaging::*; 67 unsafe { 68 SendMessageA(self.handle, WM_SETFONT, font.get_font() as WPARAM, 1); 69 } 70 } 71} 72 73#[cfg(unix)] 74pub struct Button { 75 pub handle: gtk::Button, 76}

試したこと

ボタンのウィンドウハンドルが存在しているかも確認したのですが、ちゃんと存在していることがわかりました。

補足情報(FW/ツールのバージョンなど)

  • Rustc 1.57
  • windows_sys 0.34.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問