3

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"myWindowClass";

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.

John
  • 6,433
  • 7
  • 47
  • 82
  • All credit to Forger for the correct example (apart fomr wchar_t for my system), I missed the wc.style initialization as my Foxit pdf reader only copy-pastes a screen at a time and I missed a line. – John Aug 29 '11 at 10:21

3 Answers3

8

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); 
Mario
  • 35,726
  • 5
  • 62
  • 78
  • I remember the _T being advocated but just read a similar thread using the L"" qualifier and well, it just worked, I'll try your _T prefixes again now. Ah, _T() is a macro and not able to initialize my strings :( error C2099: initializer is not a constant – John Aug 29 '11 at 09:36
  • @John: The L"" only worked because you were building with Unicode enabled. The point of the _T macro is to be able to _switch_ between Unicode enabled and disabled. Which is also why things like `ShellExecute` are macros that switch between `ShellExecuteA` and `ShellExecuteW`. – Nicol Bolas Aug 29 '11 at 09:40
  • "warning C4013: '_T' undefined; assuming extern returning int" and then "error LNK2019: unresolved external symbol __T referenced in function _WinMain@16" – John Aug 29 '11 at 10:06
  • 1
    Isn't the macro called `TEXT`? – Sylvain Defresne Aug 29 '11 at 10:14
  • Not "most" Win32 API but all API which have `TCHAR` parameters or return value. – i486 Nov 30 '16 at 12:49
1

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));
cpx
  • 17,009
  • 20
  • 87
  • 142
0

Add this line:

wc.style = CS_HREDRAW | CS_VREDRAW;
SChepurin
  • 1,814
  • 25
  • 17