Windows CEプラットフォームでの組み込みアプリケーション開発において、レジストリ操作はシステム設定や永続データ管理の基本要素です。Win32 APIを直接使用する場合、エラーハンドリングやリソース管理が複雑になるため、ラッパークラスによる抽象化が有効です。以下に実装例を示します。
#ifndef REGISTRY_ACCESSOR_H
#define REGISTRY_ACCESSOR_H
#include <windows.h>
class RegistryAccessor {
public:
bool removeKey(const TCHAR* path);
bool removeValue(const TCHAR* name);
bool setMultiString(const TCHAR* name, const TCHAR* value, DWORD length);
bool setBinaryData(const TCHAR* name, const BYTE* data, DWORD size);
bool setDwordValue(const TCHAR* name, DWORD value);
bool setStringValue(const TCHAR* name, const TCHAR* value);
bool setStringValue(const TCHAR* name, const TCHAR* value, DWORD length);
DWORD getDwordValue(const TCHAR* name, DWORD defaultValue = 0);
const TCHAR* getStringValue(const TCHAR* name);
BYTE* getBinaryData(const TCHAR* name);
DWORD getBinaryData(const TCHAR* name, BYTE* buffer, DWORD bufferSize);
bool getStringValue(const TCHAR* name, TCHAR* buffer, DWORD bufferSize);
bool enumerateValue(TCHAR* nameBuffer, DWORD nameSize,
TCHAR* valueBuffer, DWORD valueSize);
bool enumerateSubkey(TCHAR* buffer, DWORD bufferSize);
bool isValid() const;
operator HKEY() const;
void reset();
RegistryAccessor(HKEY rootKey, const TCHAR* subkeyPath);
bool openKey(HKEY rootKey, const TCHAR* subkeyPath, REGSAM access = KEY_READ);
bool createKey(HKEY rootKey, const TCHAR* subkeyPath);
RegistryAccessor();
~RegistryAccessor();
private:
HKEY registryHandle;
DWORD currentIndex;
BYTE* valueBuffer;
};
#endif
実装クラスでは、Win32レジストリAPIを安全にラップするためのメカニズムを提供します。特にリソースリーク防止のため、デストラクタで確実にハンドルを解放し、動的メモリを適切に管理します。
#include "RegistryAccessor.h"
#define SAFE_FREE(ptr) { \
if (ptr) { \
LocalFree(ptr); \
ptr = nullptr; \
} \
}
RegistryAccessor::RegistryAccessor()
: registryHandle(nullptr),
currentIndex(0),
valueBuffer(nullptr) {}
RegistryAccessor::RegistryAccessor(HKEY rootKey, const TCHAR* subkeyPath)
: registryHandle(nullptr),
currentIndex(0),
valueBuffer(nullptr)
{
openKey(rootKey, subkeyPath);
}
RegistryAccessor::~RegistryAccessor() {
if (registryHandle) {
RegCloseKey(registryHandle);
}
SAFE_FREE(valueBuffer);
}
bool RegistryAccessor::createKey(HKEY rootKey, const TCHAR* subkeyPath) {
DWORD disposition;
return RegCreateKeyEx(
rootKey,
subkeyPath,
0,
nullptr,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
nullptr,
®istryHandle,
&disposition
) == ERROR_SUCCESS;
}
bool RegistryAccessor::openKey(HKEY rootKey, const TCHAR* subkeyPath, REGSAM access) {
return RegOpenKeyEx(
rootKey,
subkeyPath,
0,
access,
®istryHandle
) == ERROR_SUCCESS;
}
void RegistryAccessor::reset() {
if (registryHandle) {
RegCloseKey(registryHandle);
registryHandle = nullptr;
}
SAFE_FREE(valueBuffer);
currentIndex = 0;
}
RegistryAccessor::operator HKEY() const {
return registryHandle;
}
bool RegistryAccessor::isValid() const {
return registryHandle != nullptr;
}
bool RegistryAccessor::enumerateSubkey(TCHAR* buffer, DWORD bufferSize) {
if (!registryHandle) return false;
return RegEnumKeyEx(
registryHandle,
currentIndex++,
buffer,
&bufferSize,
nullptr,
nullptr,
nullptr,
nullptr
) == ERROR_SUCCESS;
}
bool RegistryAccessor::enumerateValue(TCHAR* nameBuffer, DWORD nameSize,
TCHAR* valueBuffer, DWORD valueSize) {
if (!registryHandle) return false;
DWORD valueType;
DWORD actualValueSize = valueSize * sizeof(TCHAR);
return RegEnumValue(
registryHandle,
currentIndex++,
nameBuffer,
&nameSize,
nullptr,
&valueType,
(BYTE*)valueBuffer,
&actualValueSize
) == ERROR_SUCCESS;
}
DWORD RegistryAccessor::getDwordValue(const TCHAR* name, DWORD defaultValue) {
if (!registryHandle) return defaultValue;
DWORD result = defaultValue;
DWORD size = sizeof(DWORD);
RegQueryValueEx(
registryHandle,
name,
nullptr,
nullptr,
(BYTE*)&result,
&size
);
return result;
}
bool RegistryAccessor::setDwordValue(const TCHAR* name, DWORD value) {
if (!registryHandle) return false;
return RegSetValueEx(
registryHandle,
name,
0,
REG_DWORD,
(BYTE*)&value,
sizeof(DWORD)
) == ERROR_SUCCESS;
}
bool RegistryAccessor::setStringValue(const TCHAR* name, const TCHAR* value) {
return setStringValue(name, value, _tcslen(value) + 1);
}
bool RegistryAccessor::setStringValue(const TCHAR* name,
const TCHAR* value,
DWORD length) {
if (!registryHandle) return false;
return RegSetValueEx(
registryHandle,
name,
0,
REG_SZ,
(BYTE*)value,
length * sizeof(TCHAR)
) == ERROR_SUCCESS;
}
bool RegistryAccessor::removeValue(const TCHAR* name) {
if (!registryHandle) return false;
return RegDeleteValue(registryHandle, name) == ERROR_SUCCESS;
}