SlideShare a Scribd company logo
Win32 APIを
手なずけよう!
2015.12.12 プロ生@名古屋 KOUJI MATSUI (@KEKYO2)
自己紹介
けきょ (@kekyo2)
ロードバイク乗り
Microsoft MVP for Visual Studio and Development Technology
認定スクラムマスター・スクラムプロダクトオーナー
Center CLRオーガナイザー
今日のお題
.NETからWin32 APIを使って、.NETだけでは難しいことをしよう
巷ではUWPが流行ってますが…
デスクトップアプリケーションが避けられない場面は
あるはずです!!
◦ 最近はやりのIoT (Out of box unitと通信する)
◦ Microsoft KinectやIntel RealSenseカメラ
◦ USB機器(libusb)
◦ OpenGL / DirectX
◦ サードパーティ製ライブラリ群
… そしてWin32 API
Win32 APIとなかよくする
と言いながら、C++でがりがり書くのは色々つらい。
C#から、どうやってWin32 APIにアクセスするか?
これが出来れば、いろんなことに応用できる!!
デスクトップを駆けるプロ生ちゃん
ウインドウの上を走ってくよ~
WPFだけではどうにもならない…
デスクトップ上のどこにウインドウがあるのか?
表示されているウインドウが全て列挙出来れば、ウインドウ
の上の縁の座標が分かる。
あとは計算で何とかなりそう?
②ウインドウの上辺が分かるので
③上に乗るような感じで
横に移動させる
①ウインドウの座標が分かれば
落ちた時の着地点
落ちた時の着地点は、現在位置→次の位置(等加速度運動)で
決まる線分と、ウインドウ上辺が交差するところ。
①現在の座標
②次の座標
③ウインドウの上辺と交差する座標
→全てのウインドウを検査する
考え方はおk?
ウインドウを調べる
デスクトップ上のウインドウを全て列挙するには、
「EnumWindows」APIを使います。
https://msdn.microsoft.com/ja-jp/library/cc410851.aspx
又は、EnumWindowsでググる
C#からWin32 APIは直接呼べません
EnumWindowsを呼べば、すべてのウインドウの位置が分かる。
でもC#のコードで”EnumWindows”と書いても、もちろん呼び
出せない。
こういう時には、「P/Invoke」という機能を使います。
P/Invokeするには
Win32 APIに対応するP/Invokeの定義をC#で書きます。
EnumWindows APIの定義
(C言語による)
EnumWindows APIの定義
(P/Invoke C#)
P/Invokeの定義
APIがどのDLLに定義されているか?
(DllImport属性)
API名はほとんどの場合
C言語のAPI名と同じ
引数と戻り値の並びは同じだけど、
型は要注意
ぴよぴよ
どうやって書けば?
そんなP/Invoke初心者のために「pinvoke.net」
コミュニティベースで、Win32 APIの
P/Invoke定義を蓄積
pinvoke.net
例:「EnumWindows dllimport」とかでググると、大抵トップ
に出てくる。
コミュニティベースの定義なので、定義の質はまちまち。
複数載ってたりする(俺はこんな定義は我慢ならない、と
思ったのかも)ので、良さげなやつを選択する。
この定義をベースに、細かく修正するという手法はアリ。
主に型定義によるばらつきが多い感ある
あと、過剰な属性か足りないか…
EnumWindows P/Invokeの詳細
コールバック関数はデリゲート
として定義できる
SetLastErrorでエラーコードを返す
APIの場合は、これを追加する
EnumWindowsを使う
EnumWindowProcデリゲートに相当する実装。
列挙されたウインドウハンドルをリストに蓄積します。
APIが失敗するとfalseを返すので、その場合は
GetHRForLastWin32Errorでエラーコードを取得して、
対応する例外をThrowExceptionForHRでスローします。
ウインドウの矩形を得るには
ウインドウハンドルからウインドウ
の矩形座標を得るには、
GetWindowRect APIを使います。
RECT構造体が必要
(LPRECTはRECTへのポインタ)
ウインドウの矩形を得るには
RECT構造体のP/Invoke表現です。
これもpinvoke.netで探せます。
ウインドウハンドルからウインドウ
の矩形座標を得るには、
GetWindowRect APIを使います。
GetWindowRectを使う
呼び出すだけ。エラー処理は
EnumWindowsと同じ。
その他必要なAPI
ウインドウが可視状態かどうか → IsWindowVisible
◦ 見えていないウインドウは除外します。
デスクトップ全体の矩形を取得する → SystemParametersInfo
◦ 画面外まで移動したかどうかを判定するのに使います。
ウインドウの矩形を再設定する → SetWindowPos
◦ プロ生ちゃんアイコンの移動に使用します。
(WPFデータバインディングでの移動に不備があるため)
WPFウインドウからハンドルを得る
WPFのウインドウクラスからウインドウハンドルを取得すれば、
WPFウインドウに対して、Win32 APIを適用できます。
WindowInteropHelperクラスを使って、
Windowクラスのハンドルを操作
内部でSetWindowPos APIを呼び出す
総仕上げ
デスクトップ上のウインドウ群の矩形座標が手に入ったので
上辺群を抽出
歩行中と落下中をステートマシンで管理
落下中は交点座標を計算 → 結果が得られれば着地!
上辺の左端を超えたら落下
画面外に出たら最初の座標にリセット
アイコン(透過PNG)で透過ウインドウを作って表示
歩行時はアイコンを切り替えてアニメーション
タイマーで定期的にステートマシンを実行
デモ
もっと面白くするために
アニメーションパターンを増やしたいね(レベル低)
◦ せっかく色々イメージがあるので…
反対にも移動したいね(レベル低)
◦ 上辺の端まで来たら気まぐれで反転するとか
ちゃんと終われるようにしたい(レベル低)
◦ タスクトレイに常駐!
ウインドウ移動に追従したいね(レベル中)
◦ ウインドウを移動したら、上辺に乗っかったまま移動とか
ウインドウのZオーダーを認識したい(レベル高)
◦ 裏に回っているウインドウにも着地してしまうよ
◦ 手前ウインドウにさえぎられて移動できない場合は反転とか
ご清聴ありがとうございました!
GitHub: Pronama.InteropDemo
https://github.com/kekyo/Pronama.InteropDemo
スライドはブログに上げます
http://www.kekyo.net/
第五回Center CLR年末会やります (2015.12.26)
名古屋市 中生涯学習センター
https://centerclr.doorkeeper.jp/events/34349

More Related Content

PDF
プログラムを高速化する話
PDF
LLVM最適化のこつ
PDF
Pythonによる黒魔術入門
PDF
CRC-32
PDF
Deflate
PDF
GoによるiOSアプリの開発
PDF
バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
PDF
C++ マルチスレッド 入門
プログラムを高速化する話
LLVM最適化のこつ
Pythonによる黒魔術入門
CRC-32
Deflate
GoによるiOSアプリの開発
バイトコードって言葉をよく目にするけど一体何なんだろう?(JJUG CCC 2022 Spring 発表資料)
C++ マルチスレッド 入門

What's hot (20)

PDF
ROSによるロボットソフトウェアの開発
PDF
フラッター開発におけるシークレット情報取扱考察
PDF
ChatGPTは思ったほど賢くない
PDF
深層学習の新しい応用と、 それを支える計算機の進化 - Preferred Networks CEO 西川徹 (SEMICON Japan 2022 Ke...
PDF
第1回 配信講義 計算科学技術特論A (2021)
PPTX
良いコードとは
PDF
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
PDF
いつやるの?Git入門 v1.1.0
PDF
O/Rマッパーによるトラブルを未然に防ぐ
PDF
20230105_TITECH_lecture_ishizaki_public.pdf
PDF
ARM CPUにおけるSIMDを用いた高速計算入門
PDF
C++ マルチスレッドプログラミング
PPTX
Java 17直前!オレ流OpenJDK「の」開発環境(Open Source Conference 2021 Online/Kyoto 発表資料)
PDF
Cache-Oblivious データ構造入門 @DSIRNLP#5
PDF
Dockerからcontainerdへの移行
PPTX
エラーハンドリング
PPTX
RLSを用いたマルチテナント実装 for Django
PPTX
C#や.NET Frameworkがやっていること
PDF
JIT のコードを読んでみた
PDF
すごい constexpr たのしくレイトレ!
ROSによるロボットソフトウェアの開発
フラッター開発におけるシークレット情報取扱考察
ChatGPTは思ったほど賢くない
深層学習の新しい応用と、 それを支える計算機の進化 - Preferred Networks CEO 西川徹 (SEMICON Japan 2022 Ke...
第1回 配信講義 計算科学技術特論A (2021)
良いコードとは
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
いつやるの?Git入門 v1.1.0
O/Rマッパーによるトラブルを未然に防ぐ
20230105_TITECH_lecture_ishizaki_public.pdf
ARM CPUにおけるSIMDを用いた高速計算入門
C++ マルチスレッドプログラミング
Java 17直前!オレ流OpenJDK「の」開発環境(Open Source Conference 2021 Online/Kyoto 発表資料)
Cache-Oblivious データ構造入門 @DSIRNLP#5
Dockerからcontainerdへの移行
エラーハンドリング
RLSを用いたマルチテナント実装 for Django
C#や.NET Frameworkがやっていること
JIT のコードを読んでみた
すごい constexpr たのしくレイトレ!
Ad

Viewers also liked (14)

PDF
不健康なIt戦士を健康的にするアレの話
PDF
抽象太郎ものがたり そして伝説へ
PDF
SourceTreeで始めよう! Gitへの乗り換え指南
PDF
式の体を成して無い式を式の体を成すように式と式木で何とかする式
PDF
ポイントをおさえて移行しよう!Git乗り換え超初級
PDF
プロ生ちゃんをひろっちゃう!
PDF
.NET Coreから概観する.NETのOSSへの取り組み
PDF
真Intermediate languageのキホン
PDF
Async deepdive before de:code
PDF
async/awaitダークサイド is 何
PDF
Final LINQ Extensions II
PDF
メタプログラミングでExcel仕様書よさらば
PDF
Hello! intermediate language
PDF
Bluetoothでgo!
不健康なIt戦士を健康的にするアレの話
抽象太郎ものがたり そして伝説へ
SourceTreeで始めよう! Gitへの乗り換え指南
式の体を成して無い式を式の体を成すように式と式木で何とかする式
ポイントをおさえて移行しよう!Git乗り換え超初級
プロ生ちゃんをひろっちゃう!
.NET Coreから概観する.NETのOSSへの取り組み
真Intermediate languageのキホン
Async deepdive before de:code
async/awaitダークサイド is 何
Final LINQ Extensions II
メタプログラミングでExcel仕様書よさらば
Hello! intermediate language
Bluetoothでgo!
Ad

More from Kouji Matsui (19)

PDF
パターンでわかる! .NET Coreの非同期処理
PDF
Making archive IL2C #6-55 dotnet600 2018
PDF
Matrix signal controller and BrainPad overview
PDF
Fun with BrainPad
PDF
What's Functional?
PDF
Pitfall for WioLTE
PDF
How to make the calculator
PDF
Write common, run anywhere
PDF
Locality of Reference
PDF
Nespのコード生成
PDF
C#でわかる こわくないMonad
PDF
You will be assimilated. Resistance is futile.
PDF
How to meets Async and Task
PDF
Beachhead implements new opcode on CLR JIT
PDF
Thread affinity and CPS
PDF
Async DeepDive basics
PDF
continuatioN Linking
PDF
Final LINQ extensions III
PDF
Final LINQ Extensions
パターンでわかる! .NET Coreの非同期処理
Making archive IL2C #6-55 dotnet600 2018
Matrix signal controller and BrainPad overview
Fun with BrainPad
What's Functional?
Pitfall for WioLTE
How to make the calculator
Write common, run anywhere
Locality of Reference
Nespのコード生成
C#でわかる こわくないMonad
You will be assimilated. Resistance is futile.
How to meets Async and Task
Beachhead implements new opcode on CLR JIT
Thread affinity and CPS
Async DeepDive basics
continuatioN Linking
Final LINQ extensions III
Final LINQ Extensions

Win32 APIをてなずけよう