Вход на сайт
Определение размера параметра типа tchar*, unicode
88
23.02.07 10:38
Привет.
Работаю с Visual Studio C++ 6.0,
UNICODE
Подскажите, насколько нижеследующий код правилен.
Прежде всего меня интересует правильно ли определяется размер параметра типа TCHAR* и можно ли так вообще делать? , на данный момент программа выполняет то что я ожидаю, а именно записывает в регистр передаваемое значение:
CString strValueName="Language"
CString strValue=_T("1033");
TCHAR* pSZValue;
pSZValue=(LPTSTR)(LPCTSTR)strValue;
pSZValue=strValue.AllocSysString();
...
DWORD dwSize = wcslen(pSZValue)*2+2; //
...
if(ERROR_SUCCESS==RegSetValueEx(hKeyOLE,strValueName , NULL, dwType,(LPBYTE)pSZValue, dwSize))
...
Работаю с Visual Studio C++ 6.0,
UNICODE
Подскажите, насколько нижеследующий код правилен.
Прежде всего меня интересует правильно ли определяется размер параметра типа TCHAR* и можно ли так вообще делать? , на данный момент программа выполняет то что я ожидаю, а именно записывает в регистр передаваемое значение:
CString strValueName="Language"
CString strValue=_T("1033");
TCHAR* pSZValue;
pSZValue=(LPTSTR)(LPCTSTR)strValue;
pSZValue=strValue.AllocSysString();
...
DWORD dwSize = wcslen(pSZValue)*2+2; //
...
if(ERROR_SUCCESS==RegSetValueEx(hKeyOLE,strValueName , NULL, dwType,(LPBYTE)pSZValue, dwSize))
...
стойте там и слушайте сюда, именно отсюда будет проистекать
NEW 23.02.07 15:54
#include <windows.h>
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <stdexcept>
#include <exception>
class win_error : public std::runtime_error
{
public:
win_error( const std::string& defmsg )
: std::runtime_error(defmsg) {}
};
void raise_win_error( const char* defmsg, DWORD code = 0 )
{
DWORD errcode = code == 0 ? GetLastError() : code;
if ( errcode != 0 )
{
char* pBuffer = 0;
if ( FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, 0, errcode, 0,
pBuffer, 0, 0 ) > 0 )
{
std::auto_ptr<char> freer( pBuffer );
throw win_error( std::string( pBuffer ) );
}
}
throw win_error( std::string(defmsg) );
}
template <typename Ch>
class RegistryKey
{
HKEY key_;
RegistryKey( const RegistryKey& );
RegistryKey& operator=( const RegistryKey& );
void open( HKEY parent, const std::basic_string<Ch>& subkey, REGSAM rights )
{
DWORD result = RegOpenKeyEx( parent, subkey.c_str(), 0, rights, &key_ );
if ( ERROR_SUCCESS != result )
raise_win_error( "REGOPENKEYEX", result );
}
public:
RegistryKey( const std::basic_string<Ch>& subkey,
HKEY parent = HKEY_CURRENT_USER,
REGSAM rights = KEY_ALL_ACCESS )
{
open( parent, subkey, rights );
}
RegistryKey( const std::basic_string<Ch>& subkey,
const RegistryKey& parent,
REGSAM rights = KEY_ALL_ACCESS )
{
open( parent.key_, subkey, rights );
}
~RegistryKey()
{
RegCloseKey( key_ );
}
void set( const std::basic_string<Ch>& name, const std::basic_string<Ch>& value ) const
{
DWORD result = RegSetValueEx( key_, name.c_str(), 0, REG_SZ,
(const BYTE*) value.c_str(), (DWORD) (value.length() + 1)*sizeof(Ch) );
if ( ERROR_SUCCESS != result )
raise_win_error( "REGSETVALUEEX", result );
}
std::basic_string<Ch> get( const std::basic_string<Ch>& name ) const
{
std::vector< Ch > buffer( 255, 0 );
DWORD buffer_length( (DWORD) buffer.size() );
DWORD type( REG_SZ );
DWORD result = RegQueryValueEx( key_, name.c_str(),
0, &type, (BYTE*) &buffer[0], &buffer_length );
if ( ERROR_MORE_DATA == result )
{
buffer.resize( buffer_length );
result = RegQueryValueEx( key_, name.c_str(),
0, &type, (BYTE*) &buffer[0], &buffer_length );
}
if ( ERROR_SUCCESS != result )
raise_win_error( "REGQUERYVALUEEX", result );
return std::basic_string<Ch>( &buffer[0], buffer_length );
}
};
typedef RegistryKey< wchar_t > RegistryKeyW;
int main()
{
try
{
RegistryKeyW key( L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", HKEY_LOCAL_MACHINE );
key.set( L"test", L"test_value" );
std::wcout << key.get( L"test" ) << std::endl
<< key.get( L"ProductID" ) << std::endl;
}
catch( const std::exception& e )
{
std::cout << e.what() << std::endl;
}
}