2012-11-18 61 views
0

此代碼的目的是添加或編輯KeyboardDelay REG_SZ的值。我能做的是將其值設爲0,但是當我嘗試將其設置爲31時,它失敗了,並且一個奇怪的「盒子」出現在KeyboardDelays數據值而不是數字31.我做錯了什麼,因爲它不會添加31,但它會做0嗎?C++ REG_SZ值添加失敗

HKEY key; 
if (RegOpenKey(HKEY_CURRENT_USER, TEXT("Control Panel\\Keyboard"), &key) != ERROR_SUCCESS) 
{ 
cout << "Unable to open registry key"; 
} 

if (RegSetValueEx(key, TEXT("KeyboardDelay"), 0, REG_SZ, (LPBYTE)"31", strlen("31")*sizeof(char)) != ERROR_SUCCESS) 
{ 
RegCloseKey(key); 
cout <<"Unable to set registry value value_name"; 
} 
else 
{ 
    cout << "KeyboardDelay was set" << endl; 
} 
+0

使用TEXT的是混淆你。使用寬字符文字編寫Unicode代碼並停止使用這些允許您爲Windows 98編譯的宏! –

回答

2

函數RegSetValueEx在文件Winreg.h定義如下:

#ifdef UNICODE 
#define RegSetValueEx RegSetValueExW 
#else 
#define RegSetValueEx RegSetValueExA 
#endif // !UNICODE 

這意味着UNICODE被定義那麼當RegSetValueExW將被使用。最後一個字母'W'表示它接受寬字符字符串(wchar_t *),'A'表示它接受多字節字符串。所以,如果你知道你正在使用UNICODE編譯(項目屬性 - >配置 - >字符集 - >使用Unicode字符集),你應該提供寬字符字符串文字。 Windows下的最簡單方法是使用宏:

TEXT("31") 

還是我最喜歡的:

_T("31") 

這兩個宏將導致成「31」在非UNICODE編譯和成L「31」下UNICODE彙編。

你也應該使用適當的字符串函數,以獲得長度使用wcslen的UNICODE和strlen的多字節字符集。您可以使用_t *宏來檢查字符集,並使用_tcslen()來獲取長度。

實際上,您應該在創建新項目時始終使用UNICODE。

修復代碼使用:

if (RegSetValueEx(key, TEXT("KeyboardDelay"), 0, REG_SZ, (LPBYTE)TEXT("31"),_tcslen(TEXT("31"))*sizeof(TCHAR)) != ERROR_SUCCESS) 

的sizeof(TCHAR)在這裏被使用,因爲UNICODE被定義則當單個字符是兩個字節的長度,和函數RegSetValueEx需要的字節數,而不是字符數。

+0

非常感謝!它工作完美。我嘗試過各種邪惡的東西,但都失敗了,但是你所說的就像一種魅力,再次感謝! :) – hennessy

+0

@JOELi:這意味着你的項目啓用了Unicode,所以'RegSetValueEx()'映射到'RegSetValueExW()',但你期望它映射到'RegSetValueExA()'。您不能將'char'數據傳遞給'RegSetValueExW()',您必須將'wchar_t'數據傳遞給''TEXT()''。 –

+0

如果這解決了問題,您應該考慮接受答案。但是,答案相當薄弱。答案真的應該解釋發生了什麼,而不是僅僅介紹那些讓問題消失的魔法代碼。 –

0

它在MSDN中描述'如果數據的類型是REG_SZ,REG_EXPAND_SZ或REG_MULTI_SZ,則cbData必須包含終止空字符的大小。

所以我猜的代碼應該是:

if (RegSetValueEx(key, TEXT("KeyboardDelay"), 0, REG_SZ, (LPBYTE)TEXT("31"), (_tcslen(TEXT("31")) + 1)*sizeof(TCHAR)) != ERROR_SUCCESS)