「私はド素人、内容には全く自身を持てません」状態からヨチヨチ歩き程度に上達できたと思う今日この頃なので、一旦内容を整理した。
 
 
 VC++ ver.6 を使用中。
 
 *Win32API [#m7786998]
 
 いわゆるSDKプログラミング。これを知らねばはじまらない
 **link [#we9c2ad9]
 -[[WisdomSoft:http://wisdom.sakura.ne.jp/]] WinAPIはもとより、各言語が広範に渡り解説されている。
 -[[Win32 プログラミング入門:http://www7.plala.or.jp/keny01/windows/win32/]]
 -[[猫でもわかるプログラミング(biglobe):http://www2m.biglobe.ne.jp/~yasutaka/]] 定番。MFCもあり
 -[[VC++ programming tips:http://win32lab.com/tips/]]
 
 **メモ [#ya71b298]
 -アイコンはウィンドウクラス登録時に wc.hIcon = LoadIcon (NULL, MAKEINTRESOURCE(IDI_MYICON)); として指定。
 -外部プロセス起動はWinExec
 -Windowsは、各プロセスに固有のインスタンスハンドルを割当てる
 
 **ウィンドウプロシージャ [#ada54a0a]
 WindowClassで定義。戻り値は多分重要でない。
 デフォルトの挙動は DefWindowProc で実現されるので、望むメッセージ処理の後にこれを入れると良い。CALLBACK修飾子が宣言されねばならない。
 
 **別なプログラムのウィンドウハンドル取得 [#q3f9db1d]
 FindWindow、WindowFromPointあたりを使う。FindWindowExで子ウィンドウも検索できる。[[プログラムのウィンドウハンドルの取得:http://www14.big.or.jp/~ken1/tech/tech8.html]]も参照。
 
 
 **ダイアログボックス [#r5fa1ba8]
 ダイアログボックスを使って得た入力値をプログラム中で使うにはどうすれば良いか?
 
 グローバル変数を使うのが一つの解であるが、DialogBoxParamがベスト(多分)。まずやりとりしたいデータを構造体にしておいて、最後の引数にそこへのポインタを指定すると良い。
 
 
 **コモンコントロール [#wfdd61e5]
 -[[猫でもわかるプログラミング(biglobe):http://www2m.biglobe.ne.jp/~yasutaka/]]より[[第111章 ツリービューの基礎:http://www2m.biglobe.ne.jp/~yasutaka/sdk2/sdk_111.htm]]
 
 **DoEvents [#qe3a68ea]
 VB6でいうところのDoEventsは以下(なのだそうだ。出典は失念)
  MSG msg;
  if(::PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
      ::TranslateMessage(&msg);
      ::DispatchMessage(&msg);
  }
 
 
 **DLLを使う [#s54fcce6]
 インポートライブラリを使ってビルド時に関数を参照する方法と、実行中に動的に関数を参照する方法とがある。
 
 以前A社の計測装置を購入した際、USBによる操作用にDLLが添付されてきたことがあった(実はそれがお目当て)。しかし、言語のサポートとしてはVisual Basic用の標準モジュールのみで、インポートライブラリはもちろんCのヘッダもなかった。その時標準モジュールを参考にヘッダを書き、何とか動的呼び出しにまでこじつけたのが勉強したきっかけ。
 
 -[[ダイナミックリンク:http://wisdom.sakura.ne.jp/system/winapi/win32/win149.html]]
 -[[DLLの動的呼出:http://www10.plala.or.jp/yaoshi/masa/comp/prog/dll.html]]
 
 お目当ての関数ポインタには、ちゃんと自ら型(引数、戻り値)を指定してやる。
 -[[[00021443](SET)] 実引数が多すぎます:http://forums.belution.com/ja/vc/000/214/43s.shtml]]
 
 *IDEの操作 [#hc7c1a0f]
 ジワジワと操作を覚え、ジワジワと便利になってゆくもの
 **メモ [#ze396a69]
 -プロジェクト >> プロジェクトへ追加 >> 新規作成 としてファイルを追加。
 -デバッグ・リリースビルドは、ビルド >> アクティブな構成の設定 から選択。
 -選択範囲にインデントを適用したい場合、編集 >> 高度な操作 >> 選択範囲の書式自動設定
 -インテリセンスが出なくなって困ったら*.ncbと*.optを削除してワークスペースを開きなおせば良いということを、[[http://search.acty-net.ne.jp/mfc_search/archive/2001-1/msg03130.html]] にて学んだ。
 
 **ライブラリ [#j6aef7a0]
 ある関数に必要なヘッダとライブラリはヘルプに記載されている。ヘッダは include すれば良い。ライブラリは
 -プロジェクト >> プロジェクトへ追加 >> ファイル
 -プロジェクト >> 設定 >> リンク >> オブジェクト/ライブラリ モジュール
 
 のいずれかで追加する(両者はどう違うのだ?)
 
 **デバッグ [#pe230bf4]
 :ステップオーバー | main routineのみのtrace。そこでcallされた関数内部に行かない
 :ステップイン | main routineでcallされた関数内部に行く。外部ライブラリのコードの海に突き進むことも。
 :ステップアウト | 現在のroutineを抜けて呼出し元に戻る
 
 
 
 *全般的なこと [#z5f81526]
 
 **link [#f5ec93c8]
 -[[VC++超初心者のホームページ:http://www.mtakahashi.com/]]
 -[[Object Pascal, C/C++, VBのデータ型:http://homepage1.nifty.com/susho/windoze/datatype.html]]
 
 **GDI+ [#eacc95d6]
 
 jpeg表示に便利だそうだ。
 -[[GDI+に関するメモ:http://www.nilab.info/megabbs/readres.cgi?bo=computer&vi=1093051600]]
 -[[GDI+の導入:http://lamoo.s53.xrea.com/develop/gdiplus/gdiplus.html]]
 -[[第335章 GDI+の基礎 その1(猫でもわかるプログラミングより):http://www.kumei.ne.jp/c_lang/sdk4/sdk_335.htm]]
 -[[第336章 GDI+の基礎 その2(猫でもわかるプログラミングより):http://www.kumei.ne.jp/c_lang/sdk4/sdk_336.htm]]
 
 platformSDKが必要みたいだ。
 -[[Windows Server 2003 PSDK Full Download with Local Install(Windows 2000でもこちらから導入するらしい):http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm]]
 -[[Visual C++ Toolkit + Platform SDK のインストールとテスト:http://homepage1.nifty.com/kazubon/progdoc/poor/vctoolkit.html]]
 
 
 **同種のコントロールたちを、例えばVBのコントロール配列の様にして一括して処理したい [#zb7b0798]
 -[[同種複数のメッセージをひとつのハンドラで処理する-2. コントロール編 + DDX 変数の配列:http://www.interq.or.jp/jazz/iijima/mfc/iijima/05range2.html]]
 
 以下[[VC++超初心者のホームページ:http://www.mtakahashi.com/]]から。
 
 -[[A7592 コントロール配列と同じことは?:http://www.mtakahashi.com/old/a7600.html#A7592]]
 -[[A7371 ボタンを配列化したい:http://www.mtakahashi.com/old/a7375.html#A7371]]
 -[[A3610 VBのコントロール配列の様な使い方:http://www.mtakahashi.com/old/a3625.html#A3610]]
 -[[A3283 VBでいうコントロール配列をVCでするには:http://www.mtakahashi.com/old/a3300.html#A3283]]
 
 自分で適当に配列を作って、コントロールIDを格納するのが(実装と理解の観点で)一番お手軽
 
 
 **グラフ [#xc5a4a94]
 SDKに限った話ではないが、VCでグラフを実現するのはそう簡単なことではなさそうだ。自分で描画することはできるが面倒くさいのでパス。そこで既存のものを使いたくなるわけだが、標準でついてくるのはMSChartくらい。VBから使うのは簡単だが、VCから使うにはかなりのクセモノである上に文書も少ない。定番がどれなのかもよくわからない。[[CodeGuru:http://www.codeguru.com/]]でも乱立してるみたいだ。
 -[[CodeGuru より Other Controls:http://www.codeguru.com/Cpp/controls/controls/]]
 
 -[[株式会社インターフェース:http://www.interface.co.jp/]]に10,000円の市販ActiveXがある(試用版あり)。
 
 **インストーラ [#p7f8959d]
 [[National Instruments:http://www.ni.com]]の[[Measurement Studio:http://www.ni.com/mstudio/]]を使って、計測制御用のプログラムが使い慣れた言語でラクラク書けてとても幸せだが、成果物の配布にあたっては「インストーラを作りなさい」とのことであった。そういえばインストーラについては全く知らなかったのでWeb上の文書をひととおり調べた結果が以下。
 
 -[[Windows Installer:http://www.cocky.to/Wininst/tools.html]]
 -[[Visual Studio Installer:http://www.microsoft.com/japan/msdn/vstudio/downloads/vsi/]]
 -[[love unstable: フリーなWindowsのインストーラ作成ツール:http://kumiki.c.u-tokyo.ac.jp/~ichiyama/mt/archives/000029.html]]
 -[[Advanced Installer:http://www.advancedinstaller.com/]]
 -[[Inno Setup:http://www.jrsoftware.org/isinfo.php]]
 -[[NSIS:http://nsis.sourceforge.net/]]
 -[[VBに適したインストーラを探そう:http://dobon.net/vb/installer/index.html]]
 -[[のぶきちのホームページ:http://www5a.biglobe.ne.jp/~nobukich/index_j.htm]]
 -[[かいちょのどうぐばこ:http://homepage1.nifty.com/BXW01421/]]
 
 
 
 *WTL [#v84678ad]
 非常に大雑把にいうと「手動MFC亜種」。実行ファイルが軽いという利点がある。MFC、ClassWizardの動作を見つめなおすきっかけにもなる。
 
 **link [#s62aa2ce]
 -[[Roy.'s Homepage:http://homepage1.nifty.com/Roy_/index.htm]]より[[WTL研究所:http://homepage1.nifty.com/Roy_/Software/WTL/WTL.htm]]
 -[[The So-Software Studio:http://home.att.ne.jp/banana/akatsuki/]]より[[ATL/WTLによるWindowsプログラミング:http://home.att.ne.jp/banana/akatsuki/doc/atlwtl/index.html]]
 -[[Virtual Truth Lab.:http://lamoo.s53.xrea.com/]]より[[Develop:http://lamoo.s53.xrea.com/develop/index.html]]の項。GDI+の話題なども。
 -[[かっとしの記録場所:http://www.mars.dti.ne.jp/~kattoshi/]]より[[Windows Template Library:http://www.mars.dti.ne.jp/~kattoshi/Program/]]
 -[[The Code Project:http://www.codeproject.com/]]から[[WTL:http://www.codeproject.com/wtl/]]
 
 **メモ [#edb2f589]
 -DDX_TEXTでCStringを使おうとしたが、「この変換を実行可能なユーザー定義変換演算子がないか、または演算子を呼び出せません」と言われて怒られた。原因は面倒なので調べてないが、atlmisc.h を atlddx.h よりあとにincludeしていたのが原因のようであった。
 
 
 *COM [#t592e873]
 高度なテクノロジ。本腰入れて勉強しないと理解に至れない。
 
 **link [#sb0e8ad9]
 -[[やじやじ's Page:http://www.asahi-net.or.jp/~kv8s-yjm/]]より[[温COM知新:http://www.asahi-net.or.jp/~kv8s-yjm/another/yjamain.htm]]
 -[[COM総合研究所:http://www5.plala.or.jp/atata/]]
 -[[COM プログラミングの基本 (上):http://www.microsoft.com/japan/msdn/thisWeek/combasics/combasics1.asp]]
 
 **メモ [#ddcc61ff]
 -[[SDKでActiveX MFCを利用する:http://www.heppoko.gr.jp/~shimatta/blog/programs/archives/000016.html]]
 -ProgIDが知りたい時には、レジストリでHKEY_CLASSES_ROOT以下を見るとよい。
 
 **VARIANT、COleVariant、SAFEARRAY、COleSafeArray... [#f3f092b0]
 便利なんだか不便なんだかよくわからないのでムカついていた時に参考にしたのが以下。
 --[[ActiveXオートメーションの概要:http://homepage1.nifty.com/macbs/auto1.htm]]
 --[[範囲指定したCellへ配列データを出力:http://www.attain-sys.com/vc/excel/xls_setarray_exp.html]]、及び[[範囲指定したCellのデータを取得:http://www.attain-sys.com/vc/excel/xls_getarray_exp.html]]
 
 
 
 *MFC [#hbf7de34]
 業界標準のフレームワークだが、全くのWindowsプログラミング初学者が手を染めるべきではないと思う。(とりあえずは動作しても、何が何だかわからない状態になると思われる)
 
 **link [#vd4dac63]
 -[[Masayuki Tanaka's Home Page:http://www-kobayashi.ctrl.titech.ac.jp/~mtanaka/]]より[[Visual C++講座:http://www-kobayashi.ctrl.titech.ac.jp/~mtanaka/vc/]]
 -[[VisualC++でソフトを作ろう:http://www.geocities.jp/chiakifujimon/]]
 
 **メモ [#j68bf0c3]
 -ラジオボタンは、プロパティでグループにチェックしておかなければ、ClassWizardのメンバ変数の覧に登場してくれないようである。
 -MFCでプリコンパイル済みヘッダを利用している際には、全てのcppファイルについてstdafx.hをインクルードしておかなくてはいけない。([[MFCの森:http://www.page.sannet.ne.jp/t1533/program/tips.html]]における記述の抜粋にすぎません)
 -AppWizardでオートメーションを選択すると、もれなくAfxOleInit()なる記述が追加される。これは内部でOleInitializeを呼び出しているとは聞いていたが、VC98/MFC/SRC/OLEINIT.CPP で実装を見ることができて、確かにOleInitializeがあった。
 -印刷の際、紙の向きのデフォルトを変えたいなと思っていたら[[こちらの文書:http://www.hey-to.net/ML-archive/vcppML/2000/msg00084.html]]を見つけた。目的達成。
 
 **ダイアログベースでEnter [#v834b7db]
 [[「MFCでEnterキーが反応してしまう」:http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200408/04080061.txt]]のやりとりを参考にしました。
 
 ダイアログのデフォルト動作では、Enterによって終了してしまう。これを変えるには例えば以下のようにする。
  BOOL CxxxDlg::PreTranslateMessage(MSG* pMsg)
  {
      if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
          return TRUE;
      return CDialog::PreTranslateMessage(pMsg);
  }
 
 
 **ユーザー定義メッセージ [#fb6d6cb2]
 MFCではメッセージマップをClassWizardで楽々記述できるのが大変らくちんなのだが、ユーザー定義メッセージを扱う際には手動でなくてはいけない。
 
 -[[ユーザーメッセージ:http://homepage2.nifty.com/DSS/VCPP/API/UserMessage.htm]]
 
 
 **エディットボックスの表示更新のタイミングについて [#rfe25aa8]
 調べようと思ってとりあえず以下の文書を見つけたが、詳しい検証はしていない。
 
 -[[http://search.acty-net.ne.jp/mfc_search/archive/2004-2/msg00085.html]]
 
 **ワーカスレッドとUpdateData [#xac43f4b]
 -AfxBeginThread でワーカスレッド作って、そこでもとのウィンドウのUpdateData呼出すとDebug Assertion Failedとなる件について、[[■ VisualC++(MFC限定)相談室 MFC7.dll■:http://pc2.2ch.net/tech/kako/1047/10479/1047949606.html]]の174,176,177さんがやりとりされていた。
 
 -[[クラス関数をスレッドにする:http://homepage2.nifty.com/DSS/VCPP/MFC/Thread/ThreadClass.htm]]
 
 **'s'の初期化が'default'ラベルによって行われませんでした [#u05b3f1d]
 switch文を使っていたら上記のようなエラー(C2361)に遭遇した。あるcaseのみで使う変数をそこで宣言した場合に、残りのcaseでもスコープが残っているけどいいのか、というニュアンスなのだそうだ。こんな時は変数を宣言・使用している箇所をブロックの中に閉じ込めてしまえばよい。
 
 ・・・という内容を http://frog.raindrop.jp/knowledge/archives/000223.html にて学びました。
 
 **右クリックメニュー [#p7389b4f]
 [[右クリックでポップアップメニューを出す方法:http://www.ne.jp/asahi/hishidama/home/tech/vcpp/popmenu.html]]を見て学んだ。このページに記述されていることではあるが、念のためこちらにも書く。何か処理をする(ハンドラを書く)ためにはメニューIDとハンドラとの対応をとってやらないといけない。このあたりはClassWizardにやらせるとラクだが、メニューIDを直接ソースに書くとClassWizardはそれに気づいてくれない。そこで、(実際にはどこにも使われないけど)メニューリソースをひとつ用意し、そこで適当な
 メニューIDを登録しておけばよい。するとClassWizardはそれを認識してくれるので、同じメニューIDを用いれば右クリックメニューのハンドラが楽に実装できる。
 
 
 
 *SDK雛型 [#k6883f62]
 **シングルウィンドウ [#c29cbab0]
 -[[WisdomSoft:http://wisdom.sakura.ne.jp/]]より[[終了処理:http://wisdom.sakura.ne.jp/system/winapi/win32/win11.html]]がベース。
 
  #include<windows.h>
  const char lpClassName[]="SDKTemplate";    // window class
  
  LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
      switch (msg) {
          case WM_COMMAND:
          switch(LOWORD(wp)) {
              //case BUTTON:
              //break;
              }
          break;
          case WM_DESTROY:
              PostQuitMessage(0);
              return 0;
          }
          return DefWindowProc(hwnd , msg , wp , lp);
  }
  
  int WINAPI WinMain(HINSTANCE hInst , HINSTANCE hPrevInstance , PSTR lpCmdLine , int nCmdShow ) {
      HWND hwnd;
      MSG msg;
      WNDCLASS winc;
  
      winc.style	= CS_HREDRAW | CS_VREDRAW;
      winc.lpfnWndProc = WndProc;
      winc.cbClsExtra = 0;
      winc.cbWndExtra = 0;
      winc.hInstance = hInst;
      winc.hIcon	= LoadIcon(NULL , IDI_APPLICATION);
      winc.hCursor = LoadCursor(NULL , IDC_ARROW);
      winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
      winc.lpszMenuName = NULL;
      winc.lpszClassName = lpClassName;
  
      if (!RegisterClass(&winc)) return 0;
  
      hwnd = CreateWindow(
          lpClassName ,    // class name
          TEXT("My SDK") , // window name
          WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
          100 , 100 , // horizontal, vertical position
          200 , 200 , // width and height
          NULL ,	// parent window
          NULL ,	// menu
          hInst , // application instance
          NULL // window-creation data
      );
  
      if (hwnd == NULL) return 0;
  
      while (GetMessage(&msg , NULL , 0 , 0)) DispatchMessage(&msg);
      return msg.wParam;
  }
 
 **ダイアログベース [#z1ef9dde]
 
 -[[初歩のVC++Programming Tips Win32SDK篇--ダイアログベースアプリケーションの作り方:http://win32lab.com/tips/tips11.html]]
 -[[ダイアログウィンドウ:http://wisdom.sakura.ne.jp/system/winapi/win32/win89.html]]([[WisdomSoft:http://wisdom.sakura.ne.jp/]])
 -[[skamachi's factory:http://skamachi.gotdns.com/index.html]]より[[ダイアログベース アプリケーション:http://skamachi.gotdns.com/sdk0.html]]
 -[[u1271055のページ:http://home.hiroshima-u.ac.jp/u1271055/]]の[[SDK Programming Samples:http://home.hiroshima-u.ac.jp/u1271055/sdk/]]
 
 以上を参考に作成しましたが、理解不足に基づくミスを私が犯してる可能性は大いにあります。
 
  #include<windows.h>
  #include"resource.h"
  
  BOOL CALLBACK DialogProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
  {
    switch(msg){
    case WM_INITDIALOG:
      // initialize
      return TRUE;
    case WM_COMMAND:
      switch(LOWORD(wp)){
      case IDOK:
        EndDialog(hDlg,LOWORD(wp));
        return TRUE;
      case IDCANCEL:
        EndDialog(hDlg,LOWORD(wp));
        return TRUE;
      }
      break;
    case WM_CLOSE:
      PostQuitMessage(0);
      break;
    }
    return FALSE;
  }
  
  
  int WINAPI WinMain(HINSTANCE hinst,HINSTANCE hPreInst, LPSTR pCmdLine,int nCmdShow)
  {
    DialogBox(hinst,MAKEINTRESOURCE(IDD_DIALOG1),NULL,DialogProc);
    return FALSE;
  }
 
 
 // コンパイルの前にIDD_DIALOG1なるダイアログのリソースを作成しておく必要がある。その時、
 // ダイアログのクラス名(リソースのプロパティでMFCのチェックを外すと編集可)はソース内で指定したウィンドウクラス名と同一にする。
 // 
 // #include<windows.h>
 // #include"resource.h"
 // const char szClassName[]="dialogbase_template";    // window class
 // 
 // 
 // LRESULT CALLBACK mainDlgProc(HWND hWnd,UINT uMessage,WPARAM wParam,LPARAM lParam)
 // {
 // 
 //     switch(uMessage){
 //     case WM_INITDIALOG:
 //         break;
 //     case WM_COMMAND:
 //         switch(LOWORD(wParam)){
 //         case IDCANCEL:
 //             DestroyWindow(hWnd);
 //             break;
 //         default:
 //             return DefWindowProc(hWnd,uMessage,wParam,lParam);
 //         }
 //         break;
 //     case WM_CLOSE:
 //         PostMessage(hWnd,WM_COMMAND,IDCANCEL,0);
 //         break;
 //     case WM_DESTROY:
 //         PostQuitMessage(0);
 //         break;
 //     default:
 //         return DefWindowProc(hWnd,uMessage,wParam,lParam);
 //     }
 //     
 //     return 0;
 // }
 // 
 // 
 // 
 // int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hinstPrevious, LPSTR lpszCmdLine, int nCmdShow)
 // {
 //     HWND hDlg;
 //     MSG msg;
 //     WNDCLASS winc;
 //     
 //     winc.style         = 0;
 //     winc.lpfnWndProc   = mainDlgProc;
 //     winc.cbClsExtra    = 0;
 //     winc.cbWndExtra    = DLGWINDOWEXTRA;
 //     winc.hInstance     = hInst;
 //     winc.hIcon         = LoadIcon(NULL,IDI_APPLICATION);
 //     winc.hCursor       = LoadCursor(NULL,IDC_ARROW);
 //     winc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
 //     winc.lpszMenuName  = NULL;
 //     winc.lpszClassName = szClassName; 
 // 
 //     if(!RegisterClass(&winc)) return FALSE;
 // 
 //     hDlg = CreateDialog(hInst,MAKEINTRESOURCE(IDD_DIALOG1),0,mainDlgProc);
 //     if(!hDlg) return FALSE;
 // 
 //     ShowWindow(hDlg, nCmdShow);
 //     UpdateWindow(hDlg);
 // 
 // 
 //     while(GetMessage(&msg, NULL, 0, 0))
 //     {
 //         if(IsDialogMessage(hDlg,&msg) == FALSE)
 //         {
 //             TranslateMessage(&msg);
 //             DispatchMessage(&msg);
 //         }
 //     }
 // 
 //     return msg.wParam;
 // }