VkKeyScan will tell you the VK for a specified character. Here's a quick demo of it since MSDN doesn't seem to have one which shows where the at key is on standard UK, US, and Dutch keyboards.
Code:
#include <iostream>
#include <cstdio>
#include <windows.h>
void PrintKeyInfo(WCHAR key, USHORT vk, USHORT shift, LPCWSTR layout)
{
// figure out the scancode for the key
BYTE scanCode = static_cast<BYTE>(MapVirtualKeyW(vk, MAPVK_VK_TO_VSC));
// put it in the bit positions specified by the docs
LONG keyParam = scanCode << 16;
// display data
WCHAR keyName[10] = {0};
GetKeyNameTextW(keyParam, keyName, ARRAYSIZE(keyName));
std::wcout << L"In keyboard layout "
<< layout << L", '" << key << L"' is at VK 0x"
<< std::hex << vk << L" (" << keyName << L") "
L"and you ";
if(!shift)
{
std::wcout << L"don't ";
}
std::wcout << L"need to hold shift to get at it\n";
}
void PrintKeyInfoForLang(WCHAR key, LANGID lang)
{
// save the current key layout
HKL currentKeyLayout = GetKeyboardLayout(GetCurrentThreadId());
WCHAR layoutName[10];
// create the layout name
swprintf(layoutName, L"0000%04x", lang);
// load the layout
HKL keyLayout = LoadKeyboardLayoutW(layoutName, KLF_ACTIVATE | KLF_NOTELLSHELL);
if(keyLayout)
{
// get key details
SHORT keyDetails = VkKeyScanExW(key, keyLayout);
USHORT vkValue = LOBYTE(keyDetails); // the Virtual Key
USHORT shiftState = HIBYTE(keyDetails); // the shift state
PrintKeyInfo(key, vkValue, shiftState, layoutName);
ActivateKeyboardLayout(currentKeyLayout, 0);
UnloadKeyboardLayout(keyLayout);
}
else
{
std::cout << "Couldn't load keyboard layout\n";
}
}
int main()
{
WCHAR at = WCHAR(0x40); // 0x40 is @ in UTF-8/UTF-16
PrintKeyInfoForLang(at, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK));
PrintKeyInfoForLang(at, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
PrintKeyInfoForLang(at, MAKELANGID(LANG_DUTCH, SUBLANG_DUTCH));
return 0;
}
Which gives me
In keyboard layout 00000809, '@' is at VK 0xc0 (') and you need to hold shift to get at it
In keyboard layout 00000409, '@' is at VK 0x32 (2) and you need to hold shift to get at it
In keyboard layout 00000413, '@' is at VK 0xde (@) and you don't need to hold shift to get at it