[2.9.5] cannot convert LPCTSTR to LPCWSTR for CreateDialogParamW

2,456 views
Skip to first unread message

Frédéric Bron

unread,
Sep 18, 2013, 10:58:46 AM9/18/13
to wx-u...@googlegroups.com
Since I moved to mingw-w64 cross compiler instead of mingw32, I get
the following error in 64 bits mode only:
include/wx-2.9/wx/msw/winundef.h:39:20: error: cannot convert 'LPCTSTR
{aka const char*}' to 'LPCWSTR {aka const wchar_t*}' for argument '2'
to 'HWND__* CreateDialogParamW(HINSTANCE, LPCWSTR, HWND, DLGPROC,
LPARAM)'
and many similar ones.

The code worked perfectly well with 2.9.4 and mingw32.

I read thinks about adding -D_UNICODE or -DUNICODE:
-D_UNICODE does not help
-DUNICODE helps but I then have an issue later in the compilation
process in a file totally independent of wxWidgets:
error: cannot convert 'const char*' to 'LPCWSTR {aka const wchar_t*}'
for argument '1' to 'WINBOOL SetCurrentDirectoryW(LPCWSTR)'
This is due to -DUNICODE which changes SetCurrentDirectoryA to
SetCurrentDirectoryW (I use SetCurrentDirectory in my code) and me who
uses a normal std::string as argument (however I cannot make this part
of code dependent of wx).

Why should I add -DUNICODE when wx-config --cxxflags does not say it?
Why no issue when targetting 32bit platform?
Why no issue when using mingw32 and not mingw-w64?
What is the recommended practice to avoid such things?
Frédéric

Vadim Zeitlin

unread,
Sep 18, 2013, 1:38:23 PM9/18/13
to wx-u...@googlegroups.com
On Wed, 18 Sep 2013 16:58:46 +0200 Frédéric Bron wrote:

FB> Since I moved to mingw-w64 cross compiler instead of mingw32, I get
FB> the following error in 64 bits mode only:
FB> include/wx-2.9/wx/msw/winundef.h:39:20: error: cannot convert 'LPCTSTR

Where is this header included from? If you include it directly from your
code, I can't really recommend anything other than defining UNICODE. If
this header is included implicitly by wxWidgets, then it should be already
compiled with UNICODE defined and the only reason for this not happening
that I see is that wxUSE_UNICODE is not correctly defined as 1.

FB> I read thinks about adding -D_UNICODE or -DUNICODE:

You should never have to define those for wxWidgets needs (you may want to
define them for your Win32 code not using wxWidgets though).

FB> -D_UNICODE does not help

Not surprising, it affects the CRT only. The problem here is with Windows
functions which are only affected by UNICODE.

FB> -DUNICODE helps but I then have an issue later in the compilation
FB> process in a file totally independent of wxWidgets:
FB> error: cannot convert 'const char*' to 'LPCWSTR {aka const wchar_t*}'
FB> for argument '1' to 'WINBOOL SetCurrentDirectoryW(LPCWSTR)'
FB> This is due to -DUNICODE which changes SetCurrentDirectoryA to
FB> SetCurrentDirectoryW (I use SetCurrentDirectory in my code) and me who
FB> uses a normal std::string as argument (however I cannot make this part
FB> of code dependent of wx).

This kind of situations is precisely why we don't require defining neither
_UNICODE nor UNICODE when using wxWidgets. But wxUSE_UNICODE must be
defined and we do define both _UNICODE and UNICODE ourselves in this case
(see wx/platform.h).

FB> Why should I add -DUNICODE when wx-config --cxxflags does not say it?

You shouldn't.

FB> Why no issue when targetting 32bit platform?
FB> Why no issue when using mingw32 and not mingw-w64?

No idea. There seems to be a bug somewhere but I don't know where, please
check if you can find it with the information from the above.

FB> What is the recommended practice to avoid such things?

Normally everything should just work, so there is nothing to avoid...
Clearly, this is not what happens to you in practice, but I really don't
know why, sorry.

VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

Frédéric Bron

unread,
Sep 18, 2013, 1:48:39 PM9/18/13
to wx-u...@googlegroups.com
> FB> Since I moved to mingw-w64 cross compiler instead of mingw32, I get
> FB> the following error in 64 bits mode only:
> FB> include/wx-2.9/wx/msw/winundef.h:39:20: error: cannot convert 'LPCTSTR
>
> Where is this header included from? If you include it directly from your
> code, I can't really recommend anything other than defining UNICODE. If
> this header is included implicitly by wxWidgets, then it should be already
> compiled with UNICODE defined and the only reason for this not happening
> that I see is that wxUSE_UNICODE is not correctly defined as 1.

I did not include that file my-self. So I will try to see if
wxUSE_UNICODE is set correctly at the point of the error with g++ -E.

Frédéric

Frédéric Bron

unread,
Sep 19, 2013, 9:11:53 AM9/19/13
to wx-u...@googlegroups.com
> FB> Since I moved to mingw-w64 cross compiler instead of mingw32, I get
> FB> the following error in 64 bits mode only:

.../wx/include/wx-2.9/wx/msw/winundef.h: In function 'HWND__*
CreateDialog(HINSTANCE, LPCTSTR, HWND, DLGPROC)':
.../wx/include/wx-2.9/wx/msw/winundef.h:39:20: error: cannot convert
'LPCTSTR {aka const char*}' to 'LPCWSTR {aka const wchar_t*}' for
argument '2' to 'HWND__* CreateDialogParamW(HINSTANCE, LPCWSTR, HWND,
DLGPROC, LPARAM)'
return CreateDialogW(hInstance, pTemplate, hwndParent, pDlgProc);

> Where is this header included from? If you include it directly from your
> code, I can't really recommend anything other than defining UNICODE. If
> this header is included implicitly by wxWidgets, then it should be already
> compiled with UNICODE defined and the only reason for this not happening
> that I see is that wxUSE_UNICODE is not correctly defined as 1.

so I checked that. At the point of the error, wxUSE_UNICODE, _UNICODE
and UNICODE are all defined.
The error comes from the fact that:
- argument pTemplate is of type LPCTSTR
- which is a typedef for LPCSTR
(.../mingw64-4.8.1/x86_64-w64-mingw32/include/winnt.h:355)
- which is a typedef for CONST CHAR*
(.../mingw64-4.8.1/x86_64-w64-mingw32/include/winnt.h:314)
- and CHAR is a typedef for char
(.../mingw64-4.8.1/x86_64-w64-mingw32/include/winnt.h:260)
but CreateDialogW expects const wchar_t*...

a bit complicated! does this make sense for you?
attached is the winnt.h file.

Frédéric
winnt.h.bz2

David Connet

unread,
Sep 19, 2013, 10:51:55 AM9/19/13
to wx-u...@googlegroups.com
> Fr�d�ric
>

In Unicode, that's wrong. LPCTSTR (and LPTSTR) are supposed to track to
the current ansi/unicode settings. So if Unicode is set, LPCTSTR is
really LPCWSTR and when unicode is not set, it's LPCSTR.

If it's really LPCSTR, then you don't have UNICODE defined (as you can
see from the ifdef around LPCTSTR.)

Dave

Frédéric Bron

unread,
Sep 19, 2013, 11:28:24 AM9/19/13
to wx-u...@googlegroups.com
> In Unicode, that's wrong. LPCTSTR (and LPTSTR) are supposed to track to the
> current ansi/unicode settings. So if Unicode is set, LPCTSTR is really
> LPCWSTR and when unicode is not set, it's LPCSTR.
>
> If it's really LPCSTR, then you don't have UNICODE defined (as you can see
> from the ifdef around LPCTSTR.)

I suspect that for some reason, UNICODE was not defined when LPCSTR
and other typedefs were defined and is later defined when we arrive in
wx code.

Frédéric

Frédéric Bron

unread,
Sep 19, 2013, 11:50:55 AM9/19/13
to wx-u...@googlegroups.com
>> If it's really LPCSTR, then you don't have UNICODE defined (as you can see
>> from the ifdef around LPCTSTR.)
>
> I suspect that for some reason, UNICODE was not defined when LPCSTR
> and other typedefs were defined and is later defined when we arrive in
> wx code.

and that's what happens: winnt.h is included before
wx/include/wx-2.9/wx/platform.h
so when winnt.h is read, UNICODE is not set.
That's because I include boost/smart_ptr.hpp header with
BOOST_USE_WINDOWS_H defined which then includes windows.h before wx
stuff.
I had to define BOOST_USE_WINDOWS_H because of troubles with
InterlockedIncrement in boost. And I did that only for x86_64 which
explains why I have no issue for i686.

So I know where to look at now, thanks,

Frédéric

David Connet

unread,
Sep 19, 2013, 12:20:39 PM9/19/13
to wx-u...@googlegroups.com
(sorry for top-post - using Yahoo's web interface which makes everything harder now)

For your own solutions, when using unicode, you must enable it. Evidently, wx was compiled as unicode, but your solution is not. Simply enabling unicode in the project settings will fix things for you. How wx was compiled and how you compile your projects have nothing to do with each other. Except when you assume char type by using LPCTSTR - then you and wx have an argument (and the compiler tosses up its hands and says 'you two figure it out')!

Dave


From: Frédéric Bron <freder...@m4x.org>
To: wx-u...@googlegroups.com
Sent: Thursday, September 19, 2013 8:50 AM
Subject: Re: [2.9.5] cannot convert LPCTSTR to LPCWSTR for CreateDialogParamW

Vadim Zeitlin

unread,
Sep 29, 2013, 12:08:17 PM9/29/13
to wx-u...@googlegroups.com
On Thu, 19 Sep 2013 17:50:55 +0200 Frédéric Bron wrote:

FB> >> If it's really LPCSTR, then you don't have UNICODE defined (as you can see
FB> >> from the ifdef around LPCTSTR.)
FB> >
FB> > I suspect that for some reason, UNICODE was not defined when LPCSTR
FB> > and other typedefs were defined and is later defined when we arrive in
FB> > wx code.
FB>
FB> and that's what happens: winnt.h is included before
FB> wx/include/wx-2.9/wx/platform.h
FB> so when winnt.h is read, UNICODE is not set.
FB> That's because I include boost/smart_ptr.hpp header with
FB> BOOST_USE_WINDOWS_H defined which then includes windows.h before wx
FB> stuff.

Generally speaking, I recommend including wx headers first. This is a bit
immodest, of course, but we make a real effort to isolate your code from
undesired side-effects of the inclusion of the platform-specific headers
and this is not always the case for all third-party libraries. Although I
admit I had no idea Boost was guilty of this as well, especially such a
fundamental part of it as smart pointers library.

FB> So I know where to look at now, thanks,

I don't think we can do anything about this anyhow. You must either
include wx headers first or ensure that UNICODE (and then _UNICODE too,
just for consistency) is defined on the compiler command line.

Regards,

Frédéric Bron

unread,
Sep 30, 2013, 9:59:46 AM9/30/13
to wx-u...@googlegroups.com
> FB> >> If it's really LPCSTR, then you don't have UNICODE defined (as you can see
> FB> >> from the ifdef around LPCTSTR.)
> FB> >
> FB> > I suspect that for some reason, UNICODE was not defined when LPCSTR
> FB> > and other typedefs were defined and is later defined when we arrive in
> FB> > wx code.
> FB>
> FB> and that's what happens: winnt.h is included before
> FB> wx/include/wx-2.9/wx/platform.h
> FB> so when winnt.h is read, UNICODE is not set.
> FB> That's because I include boost/smart_ptr.hpp header with
> FB> BOOST_USE_WINDOWS_H defined which then includes windows.h before wx
> FB> stuff.
>
> Generally speaking, I recommend including wx headers first. This is a bit
> immodest, of course, but we make a real effort to isolate your code from
> undesired side-effects of the inclusion of the platform-specific headers
> and this is not always the case for all third-party libraries. Although I
> admit I had no idea Boost was guilty of this as well, especially such a
> fundamental part of it as smart pointers library.
>
> FB> So I know where to look at now, thanks,
>
> I don't think we can do anything about this anyhow. You must either
> include wx headers first or ensure that UNICODE (and then _UNICODE too,
> just for consistency) is defined on the compiler command line.

We have fixed the issue in boost (no need to #include <windows.h>). It
will come in the next release (1.55).

regards,

Frédéric

Vadim Zeitlin

unread,
Sep 30, 2013, 11:36:48 AM9/30/13
to wx-u...@googlegroups.com
On Mon, 30 Sep 2013 15:59:46 +0200 Frédéric Bron wrote:

FB> We have fixed the issue in boost (no need to #include <windows.h>). It
FB> will come in the next release (1.55).

Great, thanks for letting us know,
Reply all
Reply to author
Forward
0 new messages