INIファイルを使って、設定データの保存をします。
INIファイルは次のようになっています。
[Section1] Key1 = Value1 Key2 = Value2 ... [Section2] ...
上記のSection1、Section2・・・は「セクション名」と呼ばれます。
また、Key1、Key2・・・は、「キー名」と呼びます。
テキストの表示 - インコのWindowsSDK で作成したソースを修正します。
流れ
1.shlobj.h をインクルードします。
SHGetFolderPath() で使用します。
WM_CREATE
1.SHGetFolderPath()で特殊フォルダのパス名を取得します。
ここでは、ユーザーフォルダにある Application Data (AppData)フォルダに保存します。
Program filesフォルダに保存した場合、Windows Vista以降では、「管理者として実行」するかどうかで、INIファイルを保存する場所が変わったり、保存されなかったりします。ここでは常に同じフォルダに保存されるようにするため、INIファイルは、ユーザーフォルダに保存するようにします。
HRESULT SHGetFolderPath( HWND hwndOwner, // オーナー(親)ウィンドウのハンドル int nFolder, // CSIDL値 HANDLE hToken, DWORD dwFlags, LPTSTR pszPath // パス名 );
hwndOwner | オーナー(親)ウィンドウのハンドル |
nFolder | CSIDL値 |
hToken | NULL固定 |
dwFlags | NULL固定 |
pszPath | フォルダのパス名 |
CSIDL値 | |
CSIDL_DESKTOP | デスクトップ |
CSIDL_PERSONAL | マイ ドキュメント |
CSIDL_LOCAL_APPDATA |
Application Data Windows XP以前 ・・・ C:\Documents and Settings\[アカウント名]\Local Settings\Application Data Windows Vista以降 ・・・ C:\Users\[アカウント名]\AppData\Local |
CSIDL_WINDOWS | Windows フォルダ |
CSIDL_SYSTEM | Windows System フォルダ |
CSIDL_PROGRAM_FILES | Program Files フォルダ |
2.CreateDirectory()でフォルダの作成をします。
すでにフォルダが作成されている場合は、戻り値に fulse が入ります。
BOOL CreateDirectory( LPCTSTR lpPathName, // ディレクトリ名 LPSECURITY_ATTRIBUTES lpSecurityAttributes // セキュリティ識別子 );
3.wsprintf()で、INIファイル名(ここでは test.ini )をセット。
lpFmt パラメータの書式指定子の形式は、次のとおりです。[] 内は省略可能です。
%[#][0][width]type
# | 16進数文字列の先頭に、0xをつけます。 | |
0 | フィールドの幅いっぱいになるまで、0を追加 | |
width | 出力バッファへコピーするべき最小文字数 | |
type | どのようなタイプ(文字、文字列、数値)で出力するかを指定 | |
s | 文字列として出力 | |
x | 符号なし16進数の整数型として出力 | |
d i |
符号付き10進数の整数型として出力 | |
u | 符号なし10進数の整数型として出力 |
4..iniファイルからデータを取得
取得するデータが文字列のときなら、GetPrivateProfileString()を使います。
DWORD GetPrivateProfileString( LPCTSTR lpAppName, // セクション名 LPCTSTR lpKeyName, // キー名 LPCTSTR lpDefault, // キー名を取得できなかったときの文字列 LPTSTR lpReturnedString, // 情報が格納されるバッファ DWORD nSize, // 情報バッファのサイズ LPCTSTR lpFileName // INIファイルの名前 );
符号なし整数を取得するときなら、GetPrivateProfileInt()を使います。
UINT GetPrivateProfileInt( LPCTSTR lpAppName, // セクション名 LPCTSTR lpKeyName, // キー名 INT nDefault, // キー名を取得できなかったときの文字列 LPCTSTR lpFileName // INIファイルの名前 );
5.フォント設定をグローバルデータに保存
WM_DESTROY
WritePrivateProfileSection()で、指定された INIファイルの、指定されたセクション内の既存のキー名と値を削除し、指定されたキーとその値のペアを書き込みます。
BOOL WritePrivateProfileSection( LPCTSTR lpAppName, // セクション名 LPCTSTR lpString, // 書き込むデータ LPCTSTR lpFileName // INIファイルの名前 );
ソースコードの入力
ソースコードは下記のように入れてください。
#include <windows.h> #include <shlobj.h> #include <tchar.h> #include "resource.h" #define MAX_SIZE 1024 // グローバル変数: TCHAR strPathIni[MAX_PATH + 1]; TCHAR str1[MAX_SIZE]; TCHAR str2[MAX_SIZE]; TCHAR str_ini1[MAX_SIZE]; TCHAR str_ini2[MAX_SIZE]; int intCount = 0; // このコード モジュールに含まれる関数の宣言を転送します: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; MyRegisterClass(hInstance); // アプリケーションの初期化を実行します: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } // メイン メッセージ ループ: while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam; } // // 関数: MyRegisterClass() // // 目的: ウィンドウ クラスを登録します。 // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(NULL , IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_HP); wcex.lpszClassName = TEXT("HP"); wcex.hIconSm = LoadIcon(NULL , IDI_APPLICATION); return RegisterClassEx(&wcex); } // // 関数: InitInstance(HINSTANCE, int) // // 目的: メイン ウィンドウを作成します。 // BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(TEXT("HP"), TEXT("HP"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } // // 関数: WndProc(HWND, UINT, WPARAM, LPARAM) // // 目的: メイン ウィンドウのメッセージを処理します。 // // WM_COMMAND - アプリケーション メニューの処理 // WM_PAINT - メイン ウィンドウの描画 // WM_DESTROY - 中止メッセージを表示して戻る // // LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_CREATE: // INIファイルからの読み込み SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, strPathIni); wsprintf(strPathIni, TEXT("%s\\test"), strPathIni); CreateDirectory(strPathIni, NULL); wsprintf(strPathIni, TEXT("%s\\%s"), strPathIni, TEXT("test.ini")); intCount = GetPrivateProfileInt( TEXT("COUNT"), TEXT("count"), 1, strPathIni ); GetPrivateProfileString( TEXT("COUNT2"), TEXT("count"), TEXT("起動回数:1"), str2, MAX_SIZE, strPathIni ); _stprintf_s(str1, MAX_SIZE, TEXT("起動回数:%d"), intCount); intCount++; wsprintf(str_ini1, TEXT("count = %d"), intCount); wsprintf(str_ini2, TEXT("count = 起動回数:%d"), intCount); break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // 選択されたメニューの解析: switch (wmId) { case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); TextOut(hdc, 10, 10, str1, _tcslen(str1)); TextOut(hdc, 10, 40, str2, _tcslen(str2)); EndPaint(hWnd, &ps); break; case WM_DESTROY: WritePrivateProfileSection(TEXT("COUNT"), str_ini1, strPathIni); WritePrivateProfileSection(TEXT("COUNT2"), str_ini2, strPathIni); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
上記の太線で示している箇所のみ追加です。
#define IDM_ABOUT 104 #define IDM_EXIT 105 #define IDC_HP 109
#include "resource.h" ///////////////////////////////////////////////////////////////////////////// // // メニュー // IDC_HP MENU BEGIN POPUP "ファイル(&F)" BEGIN MENUITEM "アプリケーションの終了(&X)", IDM_EXIT END POPUP "ヘルプ(&H)" BEGIN MENUITEM "バージョン情報(&A)...", IDM_ABOUT END END