Why do my Win32 API calls require the 'A' suffix and should I rectify that?
To execute a command from the Win shell I needed
ShellExecuteA(NULL, "open", "http://stackoverflow.com", NULL, NULL, SW_SHOWNORMAL);
and now I am working through Forgers Win32 Tutorial I am finding the A suffix necessary to prevent printing garbage to the screen. I know this is something to do with the format of characters my OS defaults to. If I could 'normalize' my OS that might be the best solution because I am getting NULL back from RegisterClassExA
no matter how many *A functions I use in the second example (reproduced below with llloottttssss of *A suffixes added by me)
#include <windows.h>
const wchar_t g_szClassName[] = L"myWindowClass";
// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{/*...*/
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Step 2: Creating the Window...
return Msg.wParam;
}
I've revisited the code above to make it like Forgers (removed *A's) and used L""
string initializers instead, but now I get an error assigning const char g_szClassName[] = L"myWindo开发者_StackOverflowwClass";
error C2053: 'g_szClassName' : wide string mismatch
Replacing char
with wchar
generates compiler error messages indicating wchar
is not a recognized type.
_EDIT_
I gather the L""
string specifier is the preferred solution and the one I'd like to pursue, sorry if my question seems to beat around the bush, I'm open to suggestions.
Just updated that code to what I am now using and cut out the stuff I can't reach.
_EDIT_
The error code is 87, invalid parameter, so I guess assigning the wchar_t
parameter ( wc.lpszClassName = g_szClassName;
) is incorrect after all... :@(
_EDIT_
Guessed wrong?! const LPCTSTR g_szClassName = L"myWindowClass";
didn't fix (or break) a thing.
Most WinAPI calls are available in two variants: SomeFunctionA
is the single character version (i.e. using char[]
for strings), SomeFunctionW
is the wide character version (i.e. using wchar_t[]
for strings). There's usually a macro defined without that suffix (in this case SomeFunction
) that will contain either SomeFunctionA
or SomeFunctionW
depending on your project's unicode setting. In a similar way there's a macro _T
that will accept your constant string literals and add a leading L
in case unicode is used.
To pick up your initial example, this code should work with all settings (untested though):
ShellExecute(NULL, _T("open"), _T("http://stackoverflow.com"), NULL, NULL, SW_SHOWNORMAL);
If you want unicode string, the keyword is wchar_t
const wchar_t g_szClassName[] = L"myWindowClass";
Edit:
Also, make sure you zero-initialize the rest of members of structure WNDCLASSEX
that you haven't set, i.e.
WNDCLASSEX wc = {};
OR
ZeroMemory(&wc, sizeof(wc));
Add this line:
wc.style = CS_HREDRAW | CS_VREDRAW;
精彩评论