47
[1] hiyohiyo Twitter: @openlibsys http://crystalmark.info/ CLR/H 第93回勉強会 2015 MVP Community Camp 北海道エリア

Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

Embed Size (px)

Citation preview

Page 1: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[1]

hiyohiyoTwitter: @openlibsys

http://crystalmark.info/

CLR/H 第93回勉強会2015 MVP Community Camp

北海道エリア

Page 2: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[2]

自己紹介VSC2013の紹介これからのデスクトップアプリWPF + Win32 DLLWPF + Win32 EXEまとめ

Page 3: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[3]

自己紹介

Page 4: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[4]

自己紹介

名前:hiyohiyo/ひよひよ

年齢:36歳

家族:愛妻, 愛娘, 愛息子

趣味:フリーソフト開発 (約16年)

住所:北海道札幌市

□代表作: CrystalDiskInfo, CrystalDiskMark 他(通称 Crystal シリーズ)

パソコンがもっと好きになるフリーソフトを一貫して開発しています

Microsoft MVP for Visual C++Jan 2014 -

Page 5: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[5]

CrystalDiskMark 3 Shizuku Edition

新世代ディスクベンチマーク

ベンチマーク結果なんておまけですwww

通常版

150万DL/年※Shizuku Edition と通常版の合計

Page 6: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[6]

CrystalDiskInfo 6 Shizuku Edition

HDDやSSDの健康状態を音声で教えてくれる!!

新世代ディスク情報ツール

通常版

300万DL/年※Shizuku Edition と通常版の合計

Ultimate Edition は 9 テーマ 約160MB

Page 7: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[7]

Crystal Dew World 公式応援キャラクター

水晶雫について

私のメインサイト

↓一昨年の結果

Page 8: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[8]

壁紙 (デスクトップ~モバイル)8K(7680x4320)他 約50種類のサイズを用意!!

http://水晶雫.com/

Page 9: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[9]

本題の前に・・・

CLR/H代表ナオキ氏

ひよひよさんー。来年1月31日(土)にMVP Community Camp 実施するんですが講師登壇しませんかーーー??ぶっ飛んだ内容でもOKです!

もちろん良いですよ。万人ウケする有意義なネタを考えておきます。

昨年は萌え萌えだったから今年は漢らしく決める!!

http://www.slideshare.net/hiyohiyo/mddwin32

Page 10: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[10]

Visual Studio Community

2013

Page 11: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[11]

Visual Studio Community 2013

http://visualstudio.com/free

Page 12: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[12]

Visual Studio Community 2013

出典: http://www.microsoft.com/ja-jp/dev/products/community.aspx

機能は Professional 相当です!!多くの方が無料で使えますよ!!

Page 13: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[13]

Express Edition との違い

出典: http://www.microsoft.com/ja-jp/dev/products/community.aspx

『機能拡張』が使えます!!

Page 14: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[14]

Visual Studio に壁紙を設定可能!!Visual Studio痛IDE拡張1.6

© 踊れないダメ人間 さん http://aoikagami.wordpress.com/

スライドショーで萌え放題です!!

Page 15: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[15]

MFC!! MFC!! MFC!! (某バルマー氏風に)

だっ、誰ですか?過去の遺産とか言ってるのは!!

ついに無料版でも MFC が使えます!!

Microsoft Foundation Class とは

• 多くの Win32/COM API のラッパーを提供するクラスライブラリです。

• Win32 API を直接使うよりも簡単にWindows アプリを構築することが出来ます。

Page 16: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[16]

今更 MFC と思っていませんか?

そっ、そんなことありません!!

MFCで書いたアプリなんて↓みたいなもんだろwww

Page 17: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[17]

MFC アプリケーション ウィザード

Page 18: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[18]

1 分で超ド級重量アプリの雛形が完成!!

すっ、凄いです!!

Page 19: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[19]

HiDPI にも微対応 (拡大率 200%)

きょっ、許容範囲ですね!!

Page 20: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[20]

MFC の厳しいところ・・・

• Visual C++ 2008 Feature Pack 以降大きな機能拡張なし。⇒ 今後にも全く期待出来ない。

• 有料版のみに提供されてきたためライブラリのため、新規に取り組むハードルが高かった。⇒ 今更人気大爆発!! とは多分ならない。

• HiDPI, Per Monitor DPI など最新トレンドへのサポートは弱い!! Win16 時代からの伝統あるライブラリですから。

今更取り組む価値はあるのか?もっ、もしかしてオ○コンなのか・・・

Page 21: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[21]

良くある要望 – あなたならどうしますか?

どっ、どうしたら・・・

やぁ。あなたのソフトを WinPE で使いたいんだが WoW64が入っていない んだ。ネイティブ x64 バイナリを作ってくれないかい?

やぁ。あなたのソフトを Server Core で使おうと思ったんだけど動かないんだ。なんとか対応してくれないかい?

Page 22: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[22]

Server Core とは?Windows Server 2008/2012 をサーバーとして動作させるために

必要な最小限の機能のみをインストールするオプションです。GUI 機能は大きく制限されており、エクスプローラーや IE は使えません。

※WinPE は使ったことがないので解説は割愛させていただきます m(_ _)m

Page 23: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[23]

MFC の素晴らしいところ

MFC をスタティックリンクすれば、多くの環境で動作可能(ランタイムライブラリ不要)

Server Core でも動きます!!

Page 24: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[24]

しかも、情熱さえあれば何でも出来る!!

m_CtrlFirmware.InitControl (256 + OFFSET_X, 88, 180, 20, m_ZoomRatio,m_CtrlSerialNumber.InitControl(256 + OFFSET_X, 112, 180, 20, m_ZoomRatio,m_CtrlInterface.InitControl (256 + OFFSET_X, 136, 180, 20, m_ZoomRatio,m_CtrlTransferMode.InitControl(256 + OFFSET_X, 160, 180, 20, m_ZoomRatio,m_CtrlDriveMap.InitControl (256 + OFFSET_X, 184, 180, 20, m_ZoomRatio,m_CtrlAtaAtapi.InitControl (256 + OFFSET_X, 208, 408, 20, m_ZoomRatio,m_CtrlFeature.InitControl (256 + OFFSET_X, 232, 408, 20, m_ZoomRatio,

x Y W H Zoom

Width=180*m_ZoomRatioHeight=20*m_ZoomRatio

X=(256+OFFSET_X)*m_ZoomRatioY=88*m_ZoomRatio

OFFSET_X

HiDPI, Per Monitor DPIにも気合いで対応可能です!!

Page 25: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[25]

MFC が輝く場面は間違いなくある!!

まだまだ現役ですね♪

Page 26: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[26]

良くある要望への回答

神は言っている、Visual C++ で書けと真の漢は MASM かもしれないが・・・

Server Core Windows 8.1

C++, MFC, GDI/GDI+ ◎ ◎

C++, MFC, HTML+CSS × ◎

C#, WinForms × ◎

C#, WPF × ◎

MASM, Win32, GDI/GDI+ ◎ ◎

Page 27: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[27]

Server Core がパワーアップしてた!!

WinForms + .NET4 WPF + .NET4

MFC + 超ド級重量アプリ

なっ、なんだと・・・

Page 28: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[28]

【最新版】良くある要望への回答

Server Core Windows 8.1

C++, MFC, GDI/GDI+ ○ ◎

C++, MFC, HTML+CSS × ◎

C#, WinForms ◎ ◎

C#, WPF ◎ ◎

MASM, Win32, GDI/GDI+ ◎ ◎

MFC の強みって……

Windows 2000/XP で動作するアプリが開発出来る!! アピールポイントはココだ!!

Page 29: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[29]

これからのデスクトップアプリ

Page 30: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[30]

Win32 について

Page 31: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[31]

デスクトップアプリ

Win32

MFCC#/VB.NET

.NET Framework

HTML(CSS+JS)

GDI/GDI+ WinForms WPF

ネイティブ マネージド

Page 32: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[32]

カーネルモードドライバ

Win32 DLL (C/C++)

WPFUI

ロジック

これからのデスクトップアプリ

Win32 EXE(C/C++)

.NET (DLL)(C#, VB)

WPF の表現力と C/C++ のパワー

Page 33: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[33]

WPF + Win32 DLL

Page 34: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[34]

cpuid32.dll(32bit)

cpuid.exe(WPF, Any)

ネイティブだから出来ること

cpuid64.dll(64bit)

.NET では実現が難しい* 事例として CPUID 命令を使った簡単な CPU 情報取得プログラムを作ってみます。

CPUID: CPU の機種や対応機能を識別するための命令

*NyaRuRuが地球にいたころ - C# のコードに x86/x86-64 命令を直接組み込むhttp://nyaruru.hatenablog.com/entry/20100516/p1

Page 35: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[35]

■DLL の開発

BOOL WINAPI Cpuid(DWORD indexEax, DWORD indexEcx, DWORD *pEAX, DWORD *pEBX, DWORD *pECX, DWORD *pEDX){

int info[4];__cpuidex(info, indexEax, indexEcx);*pEAX = info[0];*pEBX = info[1];*pECX = info[2];*pEDX = info[3];return TRUE;

}

”Cpuid” 実装

簡単のためエクスポートする API は “Cpuid” 1 つだけとします。

CPUID 命令は、主に EAX レジスタの値をインデックスとして該当する情報を取得します。EAX = 00h ⇒ ベンダー ID (GenuineIntel, AuthenticAMD など)EAX = 01h ⇒ CPU の機能など

Visual C++ 2012 から導入された組み込み関数Visual C++ 2005 で導入された __cpuid ではECX レジスタをインデックスとして扱えない。※以前はもっと大変でした。- インラインアセンブラ (x86)- アセンブラ (x64)

Page 36: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[36]

■DLL の開発

BOOL // TRUE: success, FALSE: failureWINAPI Cpuid(

DWORD indexEax,DWORD indexEcx,PDWORD eax,PDWORD ebx,PDWORD ecx,PDWORD edx

);

”Cpuid” 宣言 (ヘッダファイル)

EXPORTSCpuid @24

”Cpuid” をエクスポート (DEF ファイル)

DEF ファイルを用意することで適切な名前で API としてエクスポートすることが可能です。

Page 37: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[37]

■EXE の開発 - DLL の呼び出し

[DllImport("kernel32")]public extern static IntPtr LoadLibrary(string lpFileName);

[DllImport("kernel32", SetLastError = true)]private static extern bool FreeLibrary(IntPtr hModule);

[DllImport("kernel32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = false)]private static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName);

DLL ロード準備

Windows 標準 DLL は DLL 名が固定 (64bit 版も kernel32.dll など) のため、上記のように簡単に扱うことが出来ます。

Page 38: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[38]

■EXE の開発 - DLL の呼び出し

string fileName;if (System.IntPtr.Size == 8){

fileName = dllName64; // “cpuid64.dll”}else{

fileName = dllName32; // “cpuid32.dll”}module = Ols.LoadLibrary(fileName);Cpuid = (_Cpuid)GetDelegate("Cpuid", typeof(_Cpuid));

DLL ロード (32bit/64bit で振り分け)

自作する DLL は 32bit と 64bit で名前が異なるため、少々複雑な手続きが必要となります。もちろん、32bit 専用と割り切れば簡単になりますが…….NET 側を Any でビルドできなくなってしまいます。

ポインタのバイト数で振り分けIA64 のことはもう忘れよう……

Page 39: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[39]

■EXE の開発 - DLL の呼び出し

ols.Cpuid(0, 0, ref eax, ref ebx, ref ecx, ref edx);

string name = "";name += Convert.ToChar((byte)((ebx & 0x000000FF) >> 0)).ToString();name += Convert.ToChar((byte)((ebx & 0x0000FF00) >> 8)).ToString();name += Convert.ToChar((byte)((ebx & 0x00FF0000) >> 16)).ToString();name += Convert.ToChar((byte)((ebx & 0xFF000000) >> 24)).ToString();name += Convert.ToChar((byte)((edx & 0x000000FF) >> 0)).ToString();name += Convert.ToChar((byte)((edx & 0x0000FF00) >> 8)).ToString();name += Convert.ToChar((byte)((edx & 0x00FF0000) >> 16)).ToString();name += Convert.ToChar((byte)((edx & 0xFF000000) >> 24)).ToString();name += Convert.ToChar((byte)((ecx & 0x000000FF) >> 0)).ToString();name += Convert.ToChar((byte)((ecx & 0x0000FF00) >> 8)).ToString();name += Convert.ToChar((byte)((ecx & 0x00FF0000) >> 16)).ToString();

name += Convert.ToChar((byte)((ecx & 0xFF000000) >> 24)).ToString();

ProcessorName.Content = name;

CPUID 命令実行

イケてないけど全 12 バイトの ASCII を Unicode に変換してラベルに設定

CPUID 命令(EAX=0h, ECX=0h)でベンダー ID を取得

Page 40: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[40]

ネイティブとの連携は意外と簡単です!?

簡単なサンプルを使って WPF + Win32 DLL の構成を魅力を紹介しました。C/C++ で書かれたオープンソースライブラリは多数あるのでぜひ有効活用してください。

Page 41: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[41]

【参考】カーネルモードドライバの例

カーネルモードドライバ

Win32 DLL (C/C++)

WPF EXE• DLL のロード• DLL が提供する API の呼び出し

• RDMSR 命令を発行

.NET だけでは実現が出来ない事例として、RDMSR 命令を使った仮想化支援機能(Intel VT, AMD-V)の状態把握ツールを紹介。

RDMSR: システム固有情報を取得、特権命令

• カーネルモードドライバのロード• DeviceIoControl 経由で RDMSR 命令

の発行をカーネルモードドライバに依頼

参考: http://crystaldew.info/2009/11/27/virtualchecker-wpf/

Page 42: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[42]

WPF + Win32 EXE

Page 43: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[43]

WPF

オープンソースを部品として活用

Opusオーディオコーデック

ImageMagick画像フォーマット変換

http://www.imagemagick.org/http://opus-codec.org/

DiskSpdディスクベンチマーク

https://github.com/Microsoft/diskspd

部品としても使える形で公開された実行ファイルを呼び出し、その結果を活用!! 柔軟性は下がりますが、DLL を使うよりも簡単です!!

Page 44: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[44]

Microsoft 製オープンソースも多数登録!!

GitHubに79件登録 (2015/1/30現在)

https://github.com/Microsoft

Page 45: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[45]

Microsoft 製オープンソースの罠!!DiskSpd (ディスクベンチマーク) のライセンス

https://github.com/Microsoft/diskspd

ソースコード

The MIT License

http://aka.ms/diskspd

実行ファイル

謎ライセンス

3. BACKUP COPY. You may make one backup copy of the software. You may use it only to reinstall the software.

ソースコードからビルドするのが正解!!

Page 46: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[46]

【妄想】CrystalDiskMark 4

DiskMark.exe(WPF, Any)

DiskSpd32.exe DiskSpd64.exe

UI

実処理

Page 47: Visual Studio Community 2013 で始めるプログラミング Win32/MFC #clrh93

[47]

まとめ

• MFC が輝く場面はまだまだあるはず!!⇒ でも、こだわり続けるのはもったいない。

• WPF と C/C++, Win32 を組み合わせることで開発の幅が広がる!!

• オープンソースを自分のプロダクトに組み込んでパワーアップ!!

• GitHub にはマイクロソフト製オープンソースが多数登録!! ただし、ライセンスの罠には気を付けろ!!