Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

7,574 views

Published on

2015 MVP Community Camp 北海道エリア
http://clrh.connpass.com/event/10428/
における発表資料です。

先日公開された Visual Studio Community 2013 では、ついに無料で MFC(Microsoft Foundation Class) が利用出来るようになりました。 本セッションでは、簡単なサンプルコードを交えながら Visual C++ による Win32/MFC ネイティブ開発の魅力と .NET(WPF) との連携について紹介します。

Published in: Software
  • Be the first to comment

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

  1. 1. [1] hiyohiyo Twitter: @openlibsys http://crystalmark.info/ CLR/H 第93回勉強会 2015 MVP Community Camp 北海道エリア
  2. 2. [2] 自己紹介 VSC2013の紹介 これからのデスクトップアプリ WPF + Win32 DLL WPF + Win32 EXE まとめ
  3. 3. [3] 自己紹介
  4. 4. [4] 自己紹介 名前:hiyohiyo/ひよひよ 年齢:36歳 家族:愛妻, 愛娘, 愛息子 趣味:フリーソフト開発 (約16年) 住所:北海道札幌市 □代表作: CrystalDiskInfo, CrystalDiskMark 他(通称 Crystal シリーズ) パソコンがもっと好きになるフリーソフトを一貫して開発しています Microsoft MVP for Visual C++ Jan 2014 -
  5. 5. [5] CrystalDiskMark 3 Shizuku Edition 新世代ディスクベンチマーク ベンチマーク結果なんておまけですwww 通常版 150万DL/年 ※Shizuku Edition と通常版の合計
  6. 6. [6] CrystalDiskInfo 6 Shizuku Edition HDDやSSDの健康状態を音声で教えてくれる!! 新世代ディスク情報ツール 通常版 300万DL/年 ※Shizuku Edition と通常版の合計 Ultimate Edition は 9 テーマ 約160MB
  7. 7. [7] Crystal Dew World 公式応援キャラクター 水晶雫について 私のメインサイト ↓一昨年の結果
  8. 8. [8] 壁紙 (デスクトップ~モバイル) 8K(7680x4320)他 約50種類のサイズを用意!! http://水晶雫.com/
  9. 9. [9] 本題の前に・・・ CLR/H代表ナオキ氏 ひよひよさんー。来年1月31日(土)に MVP Community Camp 実施するんですが講師登壇 しませんかーーー??ぶっ飛んだ内容でもOKです! もちろん良いですよ。 万人ウケする有意義なネタを考えておきます。 昨年は萌え萌えだったから 今年は漢らしく決める!! http://www.slideshare.net/hiyohiyo/mddwin32
  10. 10. [10] Visual Studio Community 2013
  11. 11. [11] Visual Studio Community 2013 http://visualstudio.com/free
  12. 12. [12] Visual Studio Community 2013 出典: http://www.microsoft.com/ja-jp/dev/products/community.aspx 機能は Professional 相当です!! 多くの方が無料で使えますよ!!
  13. 13. [13] Express Edition との違い 出典: http://www.microsoft.com/ja-jp/dev/products/community.aspx 『機能拡張』が使えます!!
  14. 14. [14] Visual Studio に壁紙を設定可能!! Visual Studio痛IDE拡張1.6 © 踊れないダメ人間 さん http://aoikagami.wordpress.com/ スライドショーで 萌え放題です!!
  15. 15. [15] MFC!! MFC!! MFC!! (某バルマー氏風に) だっ、誰ですか? 過去の遺産とか言ってるのは!! ついに無料版でも MFC が使えます!! Microsoft Foundation Class とは • 多くの Win32/COM API のラッパーを提供する クラスライブラリです。 • Win32 API を直接使うよりも簡単にWindows アプリ を構築することが出来ます。
  16. 16. [16] 今更 MFC と思っていませんか? そっ、そんなことありません!! MFCで書いたアプリなんて↓みたいなもんだろwww
  17. 17. [17] MFC アプリケーション ウィザード
  18. 18. [18] 1 分で超ド級重量アプリの雛形が完成!! すっ、凄いです!!
  19. 19. [19] HiDPI にも微対応 (拡大率 200%) きょっ、許容範囲ですね!!
  20. 20. [20] MFC の厳しいところ・・・ • Visual C++ 2008 Feature Pack 以降大きな機能拡張なし。 ⇒ 今後にも全く期待出来ない。 • 有料版のみに提供されてきたためライブラリのため、新規に 取り組むハードルが高かった。 ⇒ 今更人気大爆発!! とは多分ならない。 • HiDPI, Per Monitor DPI など最新トレンドへのサポート は弱い!! Win16 時代からの伝統あるライブラリですから。 今更取り組む価値はあるのか? もっ、もしかしてオ○コンなのか・・・
  21. 21. [21] 良くある要望 – あなたならどうしますか? どっ、どうしたら・・・ やぁ。 あなたのソフトを WinPE で使いたいんだが WoW64 が入っていない んだ。 ネイティブ x64 バイナリを作ってくれないかい? やぁ。 あなたのソフトを Server Core で使おうと思ったんだ けど動かないんだ。 なんとか対応してくれないかい?
  22. 22. [22] Server Core とは? Windows Server 2008/2012 をサーバーとして動作させるために 必要な最小限の機能のみをインストールするオプションです。 GUI 機能は大きく制限されており、エクスプローラーや IE は使えません。 ※WinPE は使ったことがないので解説は割愛させていただきます m(_ _)m
  23. 23. [23] MFC の素晴らしいところ MFC をスタティックリンクすれば、多くの環境で動作可能 (ランタイムライブラリ不要) Server Core でも動きます!!
  24. 24. [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_ZoomRatio Height=20*m_ZoomRatio X=(256+OFFSET_X)*m_ZoomRatio Y=88*m_ZoomRatio OFFSET_X HiDPI, Per Monitor DPI にも気合いで対応可能です!!
  25. 25. [25] MFC が輝く場面は 間違いなくある!! まだまだ現役ですね♪
  26. 26. [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+ ◎ ◎
  27. 27. [27] Server Core がパワーアップしてた!! WinForms + .NET4 WPF + .NET4 MFC + 超ド級重量アプリ なっ、なんだと・・・
  28. 28. [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 で動作するアプリが 開発出来る!! アピールポイントはココだ!!
  29. 29. [29] これからの デスクトップアプリ
  30. 30. [30] Win32 について
  31. 31. [31] デスクトップアプリ Win32 MFC C#/VB.NET .NET Framework HTML (CSS+JS) GDI/GDI+ WinForms WPF ネイティブ マネージド
  32. 32. [32] カーネルモード ドライバ Win32 DLL (C/C++) WPFUI ロジック これからのデスクトップアプリ Win32 EXE (C/C++) .NET (DLL) (C#, VB) WPF の表現力と C/C++ のパワー
  33. 33. [33] WPF + Win32 DLL
  34. 34. [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
  35. 35. [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)
  36. 36. [36] ■DLL の開発 BOOL // TRUE: success, FALSE: failure WINAPI Cpuid( DWORD indexEax, DWORD indexEcx, PDWORD eax, PDWORD ebx, PDWORD ecx, PDWORD edx ); ”Cpuid” 宣言 (ヘッダファイル) EXPORTS Cpuid @24 ”Cpuid” をエクスポート (DEF ファイル) DEF ファイルを用意することで適切な名前で API としてエクス ポートすることが可能です。
  37. 37. [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 など) のため、上記のように簡単に扱うことが出来ます。
  38. 38. [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 のことはもう忘れよう……
  39. 39. [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 を取得
  40. 40. [40] ネイティブとの連携は意外と簡単です!? 簡単なサンプルを使って WPF + Win32 DLL の構成を魅力を 紹介しました。C/C++ で書かれたオープンソースライブラリ は多数あるのでぜひ有効活用してください。
  41. 41. [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/
  42. 42. [42] WPF + Win32 EXE
  43. 43. [43] WPF オープンソースを部品として活用 Opus オーディオコーデック ImageMagick 画像フォーマット変換 http://www.imagemagick.org/http://opus-codec.org/ DiskSpd ディスクベンチマーク https://github.com/Microsoft/diskspd 部品としても使える形で公開された実行ファイルを呼び出し、 その結果を活用!! 柔軟性は下がりますが、DLL を使うよりも簡単です!!
  44. 44. [44] Microsoft 製オープンソースも多数登録!! GitHubに79件登録 (2015/1/30現在) https://github.com/Microsoft
  45. 45. [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. ソースコードからビルドするのが正解!!
  46. 46. [46] 【妄想】CrystalDiskMark 4 DiskMark.exe (WPF, Any) DiskSpd32.exe DiskSpd64.exe UI 実処理 +
  47. 47. [47] まとめ • MFC が輝く場面はまだまだあるはず!! ⇒ でも、こだわり続けるのはもったいない。 • WPF と C/C++, Win32 を組み合わせる ことで開発の幅が広がる!! • オープンソースを自分のプロダクトに 組み込んでパワーアップ!! • GitHub にはマイクロソフト製オープン ソースが多数登録!! ただし、ライセンスの罠には気を付けろ!!

×