Slide 1

Slide 1 text

Modern WPF 2014/05/31 Room metro Tokyo #4 Manato KAMEYA (@Grabacr07)

Slide 2

Slide 2 text

Subject • デスクトップはどうなっていくの? − 成熟したプラットフォーム − 今後大きなアップデートはない (と思われる) ただし… − Visual Studio や Photoshop、デスクトップで使いますよね? ≠ デスクトップの終焉

Slide 3

Slide 3 text

Subject • 目的 − KanColleViewer で得たデスクトップ / WPF ネタの放出 − de:code でのデスクトップ アプリに関するセッションのキャッチアップ • ゴール − モダンな UI を持つ WPF アプリの開発手法を知る − Windows 8 / 8.1 時代の WPF アプリとは何かを知る

Slide 4

Slide 4 text

Agenda デスクトップ アプリがこの先 生きのこるには Introduction for Windows 8.1 WPF Modern Style Conclusion Modern WPF

Slide 5

Slide 5 text

• 内容は個人に帰属します 所属する組織を代表するものではありません

Slide 6

Slide 6 text

Introduction

Slide 7

Slide 7 text

Self Introduction • Work − 拝承業者? (メーカー系 SIer 所属エンジニア) − C# + WPF (Windows Client Application 開発) • Private activity − Web: http://grabacr.net/ − Twitter: @Grabacr07 (ぐらばく) − めとべや東京勉強会スタッフ − Microsoft MVP for Visual C# (2014/04 ~)

Slide 8

Slide 8 text

Recent activity

Slide 9

Slide 9 text

KanColleViewer • Windows Desktop app − .NET Framework 4.5 − Visual C# + WPF • 艦これ プレイングツール Internet Explorer Shell + FiddlerCore • 2013/12 公開 (約 5 ヶ月) − 1,650,000 downloads − Blog は Azure Web Sites へ移行 thanks @guitarrapc_tech

Slide 10

Slide 10 text

KanColleViewer • 常にエゴサーチ (twitter) − メンタル鍛えられます • ユーザーの反応 − 機能に対する反応・要望 − UI に対する反応・要望 • デベロッパーの反応 − 「この見た目どうやって作んの」

Slide 11

Slide 11 text

モダンな外観への道のり WPF Modern Style

Slide 12

Slide 12 text

How to: Modern Window • Window system 2 つの領域からなる Nonclient Area (非クライアント領域) • ウィンドウの枠 • サイズ変更 • 移動 • キャプション ボタン (最小化・最大化・閉じる) • アイコン • タイトル • システム メニュー 描画・管理: OS のウィンドウ マネージャー Client Area (クライアント領域) • アプリケーションのコンテンツ 描画・管理: アプリケーション

Slide 13

Slide 13 text

How to: Modern Window • WindowStyle.None

Slide 14

Slide 14 text

How to: Modern Window • WindowStyle.None − 非クライアント領域を削除 − 標準ウィンドウの動作を エミュレートするロジックが必要 Nonclient Area (非クライアント領域) • ウィンドウの枠 • サイズ変更 • 移動 • キャプション ボタン (最小化・最大化・閉じる) • アイコン • タイトル • システム メニュー 描画・管理: OS のウィンドウ マネージャー 要自作

Slide 15

Slide 15 text

How to: Modern Window • WindowStyle.None − 非クライアント領域を削除 − 標準ウィンドウの動作を エミュレートするロジックが必要 − 使いどころは ▫ スプラッシュ画面 ▫ デスクトップ ウィジェット等 ウィンドウ枠・サイズ変更の必要なし キャプション バー必要なし (ウィンドウ全体でドラッグできる)

Slide 16

Slide 16 text

Excursus: Splash Screen • なる早で出したいスプラッシュ画面 画像のビルド アクションを “SplashScreen” に • または、SplashScreen class で Show(bool) • WPF の Application インスタンス が生成される前に表示される • ネイティブ コードを使っている • つまり、表示されるまでが早い!

Slide 17

Slide 17 text

Excursus: Splash Screen • 画像とウィンドウの両方を出す (Blend for Visual Studio のケース) − まず、画像で素早く出す − 次に、本格的 (?) なのを出す ▫ ローカライズされたもの ▫ アニメーションも可 (Office など)

Slide 18

Slide 18 text

How to: Modern Window • WindowStyle.None − 非クライアント領域を削除 − 標準ウィンドウの動作を エミュレートするロジックが必要 − 使いどころは ▫ スプラッシュ画面 ▫ デスクトップ ウィジェット等 @CST_negi 氏の作品 https://github.com/NegishiTakumi/ARiALauncher

Slide 19

Slide 19 text

How to: Modern Window • Windows API Code Pack (2009 ~) Windows Vista / 7 で追加された機能のマネージ ラッパー − Application service (recovery, battery, …) − Task bar (progress bar, jump list, …) .NET Framework 4.0 で BCL 入り − Shell (dialog, window chrome, …) − Etc…

Slide 20

Slide 20 text

How to: Modern Window • Windows API Code Pack (2009 ~) Windows Vista / 7 で追加された機能のマネージ ラッパー − Application service (recovery, battery, …) − Task bar (progress bar, jump list, …) .NET Framework 4.0 で BCL 入り − Shell (dialog, window chrome, …) − Etc…

Slide 21

Slide 21 text

How to: Modern Window • Windows API Code Pack (2009 ~) Windows Vista / 7 で追加された機能のマネージ ラッパー − Application service (recovery, battery, …) − Task bar (progress bar, jump list, …) .NET Framework 4.0 で BCL 入り − Shell (dialog, window chrome, …) − Etc…

Slide 22

Slide 22 text

How to: Modern Window • WindowChrome class − Window API Code Pack -> .NET Framework 4.5 で BCL へ − クライアント領域を拡張 非クライアント領域を覆うように拡張する ▫ ウィンドウ フレームに WPF の コンテンツを含めることが可能 ▫ リサイズ・キャプション領域で システム本来の動作を維持 Nonclient Area (非クライアント領域) • ウィンドウの枠 • サイズ変更 • 移動 • キャプション ボタン (最小化・最大化・閉じる) • アイコン • タイトル • システム メニュー ※ WindowChrome がやってくれるもの

Slide 23

Slide 23 text

キャプション バーと 認識させるサイズ How to: Modern Window • WindowChrome class CaptionHeight property サイズ変更枠と 認識させる太さ ResizeBorder Thickness property サイズ変更グリップ の動作の方向 ResizeGrip Direction attached property

Slide 24

Slide 24 text

How to: Control library • WPF カスタム コントロール ライブラリ − カスタム コントロール&スタイル群 − 別アプリでも同じ外観を再現できる ライブラリ (アセンブリ) を参照し、App.xaml の ResourceDictionary でマージするだけ

Slide 25

Slide 25 text

How to: Control library • WPF カスタム コントロール ライブラリ − カスタム コントロール&スタイル群 − 別アプリでも同じ外観を再現できる ライブラリ (アセンブリ) を参照し、App.xaml の ResourceDictionary でマージするだけ − 使うブラシ定義は統一しておくとよい Normal 時、Active 時、非 Active 時、など

Slide 26

Slide 26 text

How to: Control library • WPF カスタム コントロール ライブラリ − カスタム コントロール&スタイル群 − 別アプリでも同じ外観を再現できる ライブラリ (アセンブリ) を参照し、App.xaml の ResourceDictionary でマージするだけ − 自分で作ってるアプリのブランド化 社内向けツールとかも

Slide 27

Slide 27 text

Elysium • お手軽モダン UI ライブラリ これ使うだけでそれっぽく見える − http://elysium.codeplex.com/ − Zune 風コントロール・スタイル群 再現度はあまり高くない… − Visual Studio 2010 or 2012 が必要

Slide 28

Slide 28 text

Elysium • お手軽モダン UI ライブラリ これ使うだけでそれっぽく見える − http://elysium.codeplex.com/ − Zune 風コントロール・スタイル群 再現度はあまり高くない… − インストーラーに弾かれる VS2010 or 2012 が必要って言われる − 独自のトースト通知システム Windows 7 でも通知できるが…

Slide 29

Slide 29 text

MahApps.Metro • お手軽モダン UI ライブラリ これ使うだけでそれっぽく見える − http://mahapps.com/MahApps.Metro/ − Windows ストアアプリ風 コントロール・スタイル群 − 割とおすすめ

Slide 30

Slide 30 text

High DPI を前提とした Windows 8 / 8.1 の世界 for Windows 8.1

Slide 31

Slide 31 text

for the Tablet PC…? • Windows 8 と様々なタブレット PC の登場 例のソフトウェア、 Windows 8 でも動くよね? 既に動作確認は取れております タブレット PC で表示が狂う件 大変申し訳ございません早急に 調査し対応致しますので今暫く お待ち頂きますよう宜しくお願

Slide 32

Slide 32 text

for the Tablet PC…? • Windows 8 と様々なタブレット PC の登場 例のアプリ、 Windows 8 でも動くよね? 既に動作確認は取れております タブレット PC で表示が狂う件 大変申し訳ございません早急に 調査し対応致しますので今暫く お待ち頂きますよう宜しくお願 高 DPI 環境で表示不良

Slide 33

Slide 33 text

for the Tablet PC…? • Windows 8 と様々なタブレット PC の登場 − ディスプレイの小型化 + 高精細化 TABLET / PC SIZE RESOLUTION PPI Surface Pro 2 10.6 inch Full-HD (1920 x 1080) 208 ppi 0.122 mm Surface Pro 3 12 inch Quad-HD (2160 x 1440) 216 ppi 0.117 mm MacBook Pro (Retina) 13.3 inch WQXGA (2560 x 1600) 227 ppi 0.112 mm ThinkPad 8 8.3 inch Full-HD (1920 x 1080) 265 ppi 0.096 mm 高 DPI 環境の標準化 物理的な 1 ドット サイズ

Slide 34

Slide 34 text

What is DPI? • 今更ですが… • Dots Per Inch − 1 インチの幅でどれだけのドットを表現できるか − Windows では 1 インチ = 96 pixel − 100 % (96 dpi)、125 % (120 dpi)、150 % (144 dpi) などの設定 [コントロール パネル] -> [デスクトップのカスタマイズ] -> [テキストやその他の項目の大きさの変更] 96 dpi 100 x 50 px 144 dpi 150 x 75 px 96 dpi 100 x 50 px 144 dpi 150 x 75 px

Slide 35

Slide 35 text

96 DPI (100 %) 1920 x 1080

Slide 36

Slide 36 text

120 DPI (125 %) 1536 x 864

Slide 37

Slide 37 text

144 DPI (150 %) 1280 x 720

Slide 38

Slide 38 text

High DPI Issues • UI 要素やテキストが切れる • フォント サイズ / レイアウトが不適切になる • UI 要素がぼやける • 座標空間の位置調整が不適切で、入力に影響する 狙った場所にドラッグ&ドロップできなくなったり • 全画面表示のアプリケーションが部分的にしかレンダリングされない 全画面表示のゲームなどで見られる • etc...

Slide 39

Slide 39 text

DPI-unaware application • 文字が切れる、レイアウトが崩れる、etc… (悪意のある例ですが) 本当に何も対策しないとこうなる 96 dpi 環境 (100 %) 120 dpi 環境 (125 %) 144 dpi 環境 (150 %)

Slide 40

Slide 40 text

DPI-aware application • Win32 application − マニフェストで True 宣言 − GetDeviceCaps 関数 GetSystemMetrics 関数 SystemParametersInfo 関数 • Windows Forms application − AutoScaleMode プロパティを Dpi に − 開発環境の DPI を記憶

Slide 41

Slide 41 text

DPI-aware application 96 dpi 環境 (100 %) 144 dpi 環境 (150 %) • DPI を考慮すると スケーリングされて意図した外観に スケーリングされて サイズが変わってる

Slide 42

Slide 42 text

DPI Virtualization and Scaling • DPI 仮想化機能 − DPI-unaware applications のための救済措置 − Windows Vista で導入 − DPI 設定に合わせて自動的に拡大 96 dpi で画面表示領域外にレンダリングされ、 DWM が拡大して表示 − ぼやける (重要) このチェックを 外した状態

Slide 43

Slide 43 text

DPI Virtualization and Scaling • ぼやける ただ拡大しているだけなので… 96 dpi 環境 (100 %) 144 dpi 環境 (150 %) 拡大しただけなので サイズは変わってない

Slide 44

Slide 44 text

Device Independent Pixel • DIP (デバイス非依存ピクセル) − Direct2D, WPF など − 環境の DPI 設定に関わらず 1 dip = 1/96 inch とする − コントロールやフォントのサイズは全て DIP で指定する 開発者が DPI を意識して座標やサイズの計算をする必要がない! − DPI 仮想化が効かない (仮想化する必要がない) − WPF ->「解像度およびデバイスに依存しないグラフィックス」

Slide 45

Slide 45 text

Device Independent Pixel (WPF) • ぼやけない そのための特別なコードも必要なし 96 dpi 環境 (100 %) 144 dpi 環境 (150 % のサイズで描画) DIP なので サイズ変わってない

Slide 46

Slide 46 text

DPI Settings (Windows 8.1) モニターごとの スケーリング (新機能)

Slide 47

Slide 47 text

Per-Monitor DPI • モニターごとにスケーリング Primary: 10.6” Tablet (1920 x 1080) Secondary: 24” Display (1920 x 1200) 144 dpi (150 %) 96 dpi (100 %)

Slide 48

Slide 48 text

DPI Awareness Level • DPI-unaware applications − 高 DPI 環境非対応、スケーリングなし − 一応 DPI 仮想化は効くけど、品質はお察しレベル • System DPI-aware applications − スケーリングされるので、高 DPI 環境でも表示できる − Windows 8.1 で異なる DPI のディスプレイに移動すると仮想化されてしまう • Per-Monitor DPI-aware ← New! − Windows 8 までの環境で、高 DPI 環境でも表示できる − Windows 8.1 で異なる DPI のディスプレイに移動しても表示できる Windows Forms WPF Windows Store apps

Slide 49

Slide 49 text

Per-Monitor DPI + WPF • ひつようなもの − マニフェスト Per-Monitor DPI に対応していることを宣言 True/PM dpi-Aware 値 効果 False High DPI 対応してません True High DPI 対応してます (Per-Monitor DPI は無理) Per-Monitor Per-Monitor DPI 対応してます (Windows Vista ~ 8 では False) True/PM Per-Monitor DPI 対応してます (Windows Vista ~ 8 では True)

Slide 50

Slide 50 text

Per-Monitor DPI + WPF • ひつようなもの − MonitorFromWindow 関数 指定したウィンドウがどのモニターに属するかを取得 − GetDpiForMonitor 関数 (Windows 8.1 で追加) 指定したモニターの DPI を取得 − WM_DPICHANGED メッセージ (Windows 8.1 で追加) DPI が変更されたとき (ディスプレイをまたいだときなど) に飛んでくる

Slide 51

Slide 51 text

Conclusion

Slide 52

Slide 52 text

Conclusion • モダンな UI を持つ WPF アプリの開発手法 − 非クライアント領域の削除方法 ▫ WindowChrome class ▫ WindowStyle 用途に応じて使い分け − WPF カスタム コントロール ライブラリ • Windows 8 / 8.1 時代の WPF アプリ − デスクトップ アプリの High DPI 対応は、もはや必須 − WPF は何もしなくても対応済み、ただし Per-Monitor DPI は対応が必要

Slide 53

Slide 53 text

Conclusion • WPF アプリのここがつらい − 配布プラットフォームがない ▫ ので、Azure 課金地獄っぽい 酷い日だと Azure のデータ転送量 1 日 20 GB とか ▫ とりあえず、バイナリのみ GitHub に置いて対応中 − 広告プラットフォームがない ▫ 野良アプリだと収益化が難しい ▫ やるとしたら、インストーラーに何かバンドルするとか