DLLのデバッグ
- DLLのデバッグ情報(pdbファイル)を生成する
- プロパティ→リンカ→デバッグ→デバッグ情報を生成する→はい
- 作成されたpdbファイルをexeと同じディレクトリにコピー
ラジオボタン
グループ化
- ラジオボックスのタブオーダーが連続しているように設定 (グループごと)
- 各、グループの先頭のラジオ ボックスのプロパティのGroup を True にする。
タブ画面
STL
- コンテナ
- vector, list, 配列等のオブジェクトを入れる入れ物のこと
いろいろ
- win32API
- WindowsOS(9X, 2000, XP, Vista) が提供しているWindowsの内部API群
- MFC
- MicrosoftがVCでの開発の為Win32APIを使いやすく加工してくれたクラス群
- 処理が重いので敬遠されがちらしい
- リンクするとアプリのサイズがでかくなるから敬遠されがちらしい
Windows が使用する DLL 検索パス
- 暗黙的なリンクと明示的なリンクの両方で、Windows は、Kernel32.dll や User32.dll などの "既知の DLL" を最初に検索します。
- 次に、以下に示す順序で DLL が検索されます。
- 実行中のプロセスの実行形式モジュールがあるフォルダ
- 現在のフォルダ
- Windows システム フォルダ
- このフォルダへのパスは、GetSystemDirectory 関数で取得できる
- WinXPの場合、一般的には「C:\Windows\System32」
- Windows ディレクトリ
- このフォルダへのパスは、GetWindowsDirectory 関数で取得できる
- WinXPの場合、一般的には「C:\Windows」
- 環境変数 PATH 内に記述されたフォルダ。
参考サイト
コールバック関数の作成
- 通常の関数は __cdel、CALLBACK関数は __stdcall
- ライブラリ等で提供するコールバック関数は__stdcall であるべき
- ライブラリ側関数宣言例
#include <windows.h>
typedef BOOL (CALLBACK* CALLBACKFUNCAAA)(char *aaa, int *bbb);
BOOL FUNC_XXX(int aaa, CALLBACKFUNCAAA funcaaa);
- CALLBACK は __stdcall のキャストと同等 windows.hでdefineしてる模様
- 呼び出し側ソース
BOOL __stdcall XXX::CALLBACKFUNCAAA(char *aaa, int *bbb)
{
//処理
}
static BOOL __stdcall CALLBACKFUNCAAA(char *aaa, int *bbb);
DLL, libの作成
- DLLの作成用のプロパティ
- 構成プロパティ→全般→構成の種類→ダイナミックライブラリ
- 標準 Windows ライブラリを使用する
- ソース
#include "stdafx.h"
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
return TRUE;
}
- ヘッダファイル
- 下記 TESTLIB_EXPORTS はプロジェクト→プロパティ→構成→C/C++→プリプロセッサに定義あり(プロジェクトにより異なる)
- 以下の定義を追加
#ifdef TESTLIB_EXPORTS
#define _EXPORT __declspec(dllexport)
#else
#define _EXPORT __declspec(dllimport)
#endif /* TESTLIB_EXPORTS */
_EXPORT int aaa(void);
MS独自関数への変更警告を表示しない
#pragma warning(disable : 4996)
リストビューにソートアイコン表示
CListCtrl *clc = (CListCtrl *)GetDlgItem(IDC_LIST);
CHeaderCtrl *pHeader = clc->GetHeaderCtrl();
HDITEM hdrItem;
hdrItem.mask = HDI_FORMAT;
pHeader->GetItem(index, &hdrItem);
//hdrItem.fmt = hdrItem.fmt & HDF_JUSTIFYMASK | HDF_STRING | HDF_SORTUP; // ▼の場合は「HDF_SORTDOWN」
pHeader->SetItem(index, &hdrItem);
このアイコンはWinXP以降の機能のため、「HDF_SORTUPが未定義の識別子」というエラーが出る場合は
stdafx.h 内のWindows XP 以降の機能を使用できるよう変更。(以下のdefine値を変更)
WINVER 0x0400 → 0x0501
_WIN32_WINNT 0x0400 → 0x0501
_WIN32_IE 0x0400 → 0x0600
ofstream 「日本語ファイル」名のオープンエラー
原因
locale設定がされていないため、ofstream のファイル名が化けている。
ofstreamを使って、日本語ファイル名をオープン
→ファイル名を一旦UNICODEに変換
→グローバルロケールを参照(設定していないとlocale "C")
→ファイル名が文字化け
VC2005からUNICODEに変換ロジックが追加された模様。
回避策
プログラムの先頭にlocale設定を追加。
#include <locale.h>
setlocale(LC_ALL,"Japanese");
参考サイト
処理中ダイアログ
- 自分でダイアログクラスを作って、モードレスダイアログとして開く
- ダイアログクラスのプロパティをvisble=TRUEにしておかないとCreate() だけでは表示されない
XXXDialog xdialog;
xdialog.Create();
xdialog.ShowWindow(SW_SHOW);
Create外部プログラム実行時のエラー
現象
LoadLibrary→GetProcAddressでライブラリの明示的ロードを実施。呼び出した処理は正常終了。
ただしその後、その関数を抜けようとすると以下のようなエラーとなり落ちる。
The value of ESP was not properly saved across a function call.
This is usually a result of calling a function declared with one
calling convention with a pointer declared with a different calling convention
原因
呼び出し関数の宣言が実体と会っていないらしい。
(VC++ 2005からは関数宣言と実関数との整合性チェックを行い、整合性が取れていないと止めてしまうらしい)
解決策
以下のように、宣言に「APIENTRY」を追加したら解決した
typedef int (APIENTRY *call_func)(CString, char *);
HWND, CWnd変換
// HWND→CWnd*
CWnd* pCWnd = CWnd::FromHandle( hwnd );
// CWnd*→HWND
HWND hwnd = pCWnd->GetSafeHwnd();
GUIアプリのコマンド起動
- コマンド起動はできる
- 引数の解釈も可能
- コマンド起動したコマンドプロンプトへ、結果を出力することはたぶんできない
- subsystem指定みてWindows側で処理を行うから
- 参考サイト
LNK2005エラー
- 例) LNK2005: _fflush は既に MSVCRT.lib(MSVCR80.dll) で定義されています。
- 構成プロパティ→C/C++→コード生成→ランタイムライブラリ→MT
~Ex関数
- 基本機能は~Exがついていない関数と同様だが、機能拡張されている。オプションが多い等。
最終更新:2010年06月24日 16:30