Although string tables are used for internationalization, that is not their primary intent. Strings in string tables are managed by Windows, and they are marked for discard when the code using them either goes out of scope, or is otherwise discarded by Windows, or the application. (The segment attributes were called LOADONCALL and DISCARDABLE in 16-bit Windows versions. We are in a flat memory model, but LOADONCALL/DISCARDABLE still apply to resources.)
The only thing particularly wasteful about this is the fact that the alphanumeric keys are useable as literals ('A'/'a'), and the F1 keys, arrow keys and others are defined in an include file that you are using already. (In winuser.h)
Example:
#define VK_SPACE 0x20
#define VK_PRIOR 0x21
#define VK_NEXT 0x22
#define VK_END 0x23
#define VK_HOME 0x24
#define VK_LEFT 0x25
#define VK_UP 0x26
#define VK_RIGHT 0x27
#define VK_DOWN 0x28
#define VK_SELECT 0x29
#define VK_PRINT 0x2A
#define VK_EXECUTE 0x2B
#define VK_SNAPSHOT 0x2C
#define VK_INSERT 0x2D
#define VK_DELETE 0x2E
#define VK_HELP 0x2F
Pretty much anything you are going to need that exists in Windows is already defined using #define, as it puts the onus on the compiler, and a variable is tantamount to a memory access, whereas a define is an immediate value.