Rust言語:Win32api:: EnumWinodwsのメモ 2018
はじまり
前回に続いて、Rust言語でWin32APIを使ってみたメモ。
$ rustup default nightly
を実行してnightl版にしておく必要がある。
Win32APIのEnumWinodws()
がコールバック関数を引数に持つので、Rust言語で
どういう記述になるのかを実際に書いてみた。GUI用のマクロ
気づいた点
グローバル変数名は大文字に強要される様だ。 orz
これだと定数との区別が?になる。
callBackProc()の動作
- タイトル中に不要な文字列(Default、MSCTFIME)を持つアプリは無視し、
それ以外の起動中のアプリのタイトル名を表示する。 - この例の場合、最後に見つかったアプリのウインドウハンドル(HANDLE_APP)が取得できるので
それを使っていろいろできる。
実行結果
コマンドラインで実行すると起動中のアプリのタイトル文字をつらつらと表示する。
(#![windows_subsystem = "windows"]
の行があるとコマンドラインでprintln文が無効になる)
src/main.rs (ファイルはUTF-8で保存)
/*
* Windows File open dialog demo.
* rustc 1.25.0-nightly (6828cf901 2018-01-06)
* This file must be saved as UTF-8 format.
*
* 2018/01/13 by audin
*/
/* バックグラウンドのコンソールウインドウを排除する場合、以下を有効にする。
* println文はコマンドラインで表示されなくなる
*
#![windows_subsystem = "windows"]
*/
extern crate winapi;
extern crate user32;
/* usnused
use std::ffi::OsStr;
use std::os::windows::ffi::OsStrExt;
use std::iter::once;
*/
use std::ptr::null_mut;
use std::result;
use winapi::um::winuser::*;
use winapi::shared::windef::*;
use winapi::shared::minwindef::*;
const SZW_SIZE_MAX: usize = 512;
// Type alias to simplify representation.
type Result<T> = result::Result<T,String>;
type TSzwBuf = [u16; SZW_SIZE_MAX];
static mut SZW_BUF: TSzwBuf = [0; SZW_SIZE_MAX];
// Convert from TSzwBuf([u16;512]) to String type.
fn szw_to_string( szwbuf: &TSzwBuf ) -> Result<String> {
szwbuf.iter()
.position(|wch| wch == &0)
.ok_or("String : Can't find zero terminator !".to_owned())
.and_then(|ix| String::from_utf16( &szwbuf[..ix] )
.map_err(|e| e.to_string()))
}
// Convert from String to Vec<u16> with trailing \0.
/* unused function
fn str_to_szw(str_body: &str) -> Vec<u16> {
return OsStr::new(str_body)
.encode_wide()
.chain(once(0)) // 終端文字\0を追加
.collect::<Vec<u16>>();
}
*/
static mut HANDLE_APP: HWND = null_mut();
#[allow(non_snake_case)]
unsafe extern "system"
fn callBackProc( hWnd: HWND, _lparam: LPARAM) -> BOOL{
GetWindowTextW( hWnd, SZW_BUF.as_mut_ptr(), SZW_BUF.len() as i32);
if let Ok(sTitle) = szw_to_string( &SZW_BUF ) {
if sTitle.len() > 0 {
if (None != sTitle.find("Default")) || (None!=sTitle.find("MSCTFIME")) {
// Eliminate verbose stings
}
else {
// Result in HANDLE_APP is equal to the Window handle of a last application found.
HANDLE_APP = hWnd;
println!("{}",sTitle); // List up application tilte with UTF-8 string.
}
}
};
TRUE // Continue enumeration to find a next Window activating.
}
fn main() {
unsafe {
EnumWindows( Some(<strong class=cly>callBackProc</strong>), 0);
if HANDLE_APP != null_mut() {
// Some codes using Window handle
}
}
}
tomlファイルには前回に加えて「windef」と「minwindef」を追加した。
「commdlg」は未使用だけど残した。
Cargo.toml
[package]
name = "enumwindows"
version = "0.1.0"
authors = ["audin"]
[dependencies]
user32-sys="0.2.0"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.3", features = ["winuser","commdlg","windef","minwindef"] }