2018年01月08日

Rust言語:Win32api:: EnumWinodwsのメモ 2018

Rust言語:Win32api:: EnumWinodwsのメモ 2018
はじまり
前回に続いて、Rust言語でWin32APIを使ってみたメモ。
$ rustup default nightlyを実行してnightl版にしておく必要がある。

Win32APIのEnumWinodws()がコールバック関数を引数に持つので、Rust言語で
どういう記述になるのかを実際に書いてみた。GUI用のマクロ
#![windows_subsystem = "windows"]
は、今回不要なものの残してある。特に害はない。

気づいた点:
    (1) グローバル変数名は大文字に強要される様だ。 orz
        これだと定数との区別が?になる。
callBackProc()の動作:
    (1) タイトル中に不要な文字列(Default、MSCTFIME)を持つアプリは無視し、
        それ以外の起動中のアプリのタイトル名を表示する。
    (2) この例の場合、最後に見つかったアプリのウインドウハンドル(HANDLE_APP)が取得できるので
        それを使っていろいろできる。
実行結果:
    コマンドラインで実行すると起動中のアプリのタイトル文字をつらつらと表示する。

src/main.rs
/*
 * 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
 */
#![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(callBackProc), 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"] }
posted by Copyright (C) avrin All Rights Reserved. at 23:25| Comment(0) | Rust言語 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。