0

I'm new to winAPI and encountered a problem I can't seem to solve... Couldn't find a solution by google yet, either.

My program has several buttons of similar size so I made a macro to hide all the mess. The original macro was:

#define _BUTTON(s, x, y, v)    CreateWindowW(L"Button", (L)s, WS_VISIBLE | WS_CHILD, x, y, 75, 25, hWnd, (HMENU)v, 0, 0);

However, "L(s)" doesn't work with or without the parenthesis, on s or L. I also tried replacing L with LPCWSTR, WCHAR*, _T(), etc... The compiler error is always the same: "L (or LPCWSTR, etc) is not declared in this scope" although I thought it should be...

For now I resolved the issue by going with the non-Unicode:

#define _BUTTON(s, x, y, v)    CreateWindow("Button", s, WS_VISIBLE | WS_CHILD, x, y, 75, 25, hWnd, (HMENU)v, 0, 0);

But I'd like all the windows to support the same chars... Where is the problem?

Rosh
  • 21
  • 3
  • 2
    Unrelated to your problem, but in C all symbols beginning with an underscore followed by either another underscore or an upper-case letter (as in `_BUTTONS`) are *reserved* and you should not define such symbols yourself. – Some programmer dude Jan 19 '20 at 12:24
  • Also note that `CreateWindow` is really a *macro* that will be expanded to either `CreateWindowA` or `CreateWindowW` depending on the existence of the `UNICODE` macro. – Some programmer dude Jan 19 '20 at 12:27
  • 3
    `CreateWindowW(WC_BUTTON, L##s, ` for example – RbMm Jan 19 '20 at 12:28
  • 2
    Lastly for a way to "solve" your problem: Why not simply use `CreateWindowW` like in the first example, but let the users of the macro pass the correct type of strings? I.e. document the macro as needing a wide-character string for the first argument. If the users don't read the documentation or just don't care about it, then they will get build errors. – Some programmer dude Jan 19 '20 at 12:29
  • 1
    or even use `#define echo(x) x` and `echo(L)##echo(s)` – RbMm Jan 19 '20 at 12:32
  • @RbMm thanks for the quick reply and solution! seems to work now! – Rosh Jan 19 '20 at 13:04
  • @Someprogrammerdude well I didn't know that! We didn't cover it when I learned C, and winAPI I'm learning on my own... Thanks for the advice - gonna change it! – Rosh Jan 19 '20 at 13:05
  • 1
    See e.g. [this reserved identifier reference](https://en.cppreference.com/w/c/language/identifier#Reserved_identifiers) for details. – Some programmer dude Jan 19 '20 at 13:07
  • @Someprogrammerdude Thanks! (can't like yet) – Rosh Jan 19 '20 at 13:16
  • Why is `_BUTTON` even a macro to begin with? What's wrong with a function? It's the most fundamental abstraction we have in C. Just use it. – IInspectable Jan 19 '20 at 19:34
  • @IInspectable I find that it's easier to edit 15 statics, buttons, edits and listboxes as a macro (visually speaking). Otherwise searching for the right argument make me sad... – Rosh Jan 19 '20 at 19:56
  • I fail to see, how editing a function is any more troublesome than editing a macro. If nothing else you'll get IntelliSense support in functions. – IInspectable Jan 19 '20 at 21:01

1 Answers1

3

One way is what RbMm metioned, like:

#define Create_Button(s, x, y, v)     CreateWindowW(L"Button", L##s, WS_VISIBLE | WS_CHILD, x, y, 75, 25, hWnd, (HMENU)v, 0, 0);

Another way is to use a common approach:

#define Create_ButtonA(s, x, y, v)    CreateWindowA("Button", s, WS_VISIBLE | WS_CHILD, x, y, 75, 25, hWnd, (HMENU)v, 0, 0);
#define Create_ButtonW(s, x, y, v)    CreateWindowW(L"Button", s, WS_VISIBLE | WS_CHILD, x, y, 75, 25, hWnd, (HMENU)v, 0, 0);
#ifdef _UNICODE
#define Create_Button(s, x, y, v)     Create_ButtonW(s, x, y, v)
#else
#define Create_Button(s, x, y, v)     Create_ButtonA(s, x, y, v)
#endif

Usage:

Create_Button(TEXT("name"),10,10,2);
Create_ButtonA("name",10,10,2);
Create_ButtonW(L"name",10,10,2);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Drake Wu
  • 6,927
  • 1
  • 7
  • 30