0

I'm creating a dll file.

My code:

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);

void test() {
    EnumWindows(EnumWindowsProc, NULL);
}

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    char class_name[80];
    char title[80];
    GetClassName(hwnd, (LPWSTR) class_name, sizeof(class_name));
    GetWindowText(hwnd, (LPWSTR) title,sizeof(title));
    std::string titlas(title);
    std::string classas(class_name);
    Loggerc(titlas);
    Loggerc("Gooing");
    return TRUE;
}

Then I just call test().

In the log, titlas is empty and code stops.

When I try this code in a Win32 app with CodeBlock, everything works, all of the titles show. But in a dll, it does not work.

Where is the problem?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770

1 Answers1

2
char class_name[80];
char title[80];
GetClassName(hwnd, (LPWSTR) class_name, sizeof(class_name));
GetWindowText(hwnd, (LPWSTR) title,sizeof(title));
std::string titlas(title);
std::string classas(class_name);

Considering that since VS2005 the default has been building in Unicode mode (instead of ANSI/MBCS) and that you have those (ugly C-style) (LPWSTR) casts, I'm assuming that you got compile-time errors when passing your char-based string buffers to APIs like GetClassName() and GetWindowText(), and you tried to fix those errors with casts.
That's wrong. The compiler was actually helping you with those errors, so please follow its advice instead of casting the compiler errors away.

Assuming Unicode builds, you may want to use wchar_t and std::wstring instead of char and std::string, and _countof() instead of sizeof() to get the size of buffers in wchar_ts, not in bytes (chars).

E.g.:

// Note: wchar_t used instead of char
wchar_t class_name[80];
wchar_t title[80];

// Note: no need to cast to LPWSTR (i.e. wchar_t*)
GetClassName(hwnd, class_name, _countof(class_name));
GetWindowText(hwnd, title, _countof(title));

// Note: std::wstring used instead of std::string
std::wstring titlas(title);
std::wstring classas(class_name);

If other parts of your code do use std::string, you may want to convert from UTF-16-encoded text stored in std::wstring (returned by Windows APIs) to UTF-8-encoded text and store it in std::string instances.

Mr.C64
  • 41,637
  • 14
  • 86
  • 162
  • @EvaldasJankauskas: You're welcome. Hope you learned the lesson to not shut up C++ compiler warnings in general :) – Mr.C64 Sep 01 '16 at 15:21
  • 1
    @EvaldasJankauskas The lesson to learn is *never cast string types*. If you find yourself casting a string type, the code is automatically suspect, and in most cases wrong. If a function wants a `WidgetString`, you provide a `WidgetString`, not something casted to it. Casting does **not** convert one string type to another -- there are Windows functions available to do the string conversion. – PaulMcKenzie Sep 01 '16 at 15:39
  • @PaulMcKenzie: *"Casting does not convert one string type to another"* - Absolute statements are easily refuted, with a single counter-example, such as a string type implementing a [user-defined conversion](http://en.cppreference.com/w/cpp/language/cast_operator) operator. Casts should not be used unless required. That doesn't make them **always** the wrong tool (although C-style casts have no place in C++). – IInspectable Sep 01 '16 at 17:08
  • 1
    The lesson to learn is, never use a cast to hide a compiler warning unless you absolutely know what you're doing. – Jonathan Potter Sep 01 '16 at 20:22