wx/msw/winundef.h in 3.0.2 - unicode macros

213 views
Skip to first unread message

Greg Jung

unread,
Dec 6, 2014, 3:03:57 AM12/6/14
to wx-u...@googlegroups.com
I was including the wx/wx.h headers to bring in a pre-built binary wxWidgets-3.0.2 from MSYS2/mingw32.
I got unicode-related errors from wx/msw/winundef.h:
~~~~
C:/msys32/mingw32/include/wx-3.0/wx/msw/winundef.h: In function 'HWND__* CreateDialog(HINSTANCE, LPCTSTR, HWND, DLGPROC)':
C:/msys32/mingw32/include/wx-3.0/wx/msw/winundef.h:38: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);
                    ^
~~~~

So I don't know why, when its _UNICODE, LPCTSTR is not already equivalent to LPCWSTR - I'm too newbie to do more than wonder - I suppose its just too hard to wedge into the typedef-ing scheme.  Other than semantic difficulties, though,
they are the same, right? So when I change this line to 

      return CreateDialogW (hinstance, (LPCWSTR) pTemplate, hwndParent, rDlgProc), 

because CreateDialogW is defined with LPCWSTR declarations,
  I am simply by-passing a computer's misunderstanding.  Is that correct? it compiles, anyway.

  winundef has a few more snags like that, as well as a block of correctly posed re-defined macros:

~~~~~~~~~
#ifdef fcn
#undef (fcn)
#ifdef _UNICODE
     fcn( blah, blah, LPCWSTR x)
     return fcnW( x)
#else
     fcn( blah, blah, LPCSTR x)
     return fcnA(x)
#endif
#endif
~~~~~~~~
e.g.
~~~~~~
// FindWindow

#ifdef FindWindow
   #undef FindWindow
   #ifdef _UNICODE
   inline HWND FindWindow(LPCWSTR classname, LPCWSTR windowname)
   {
      return FindWindowW(classname, windowname);
   }
   #else
   inline HWND FindWindow(LPCSTR classname, LPCSTR windowname)
   {
      return FindWindowA(classname, windowname);
   }
   #endif
#endif
~~~~~~~~

   Is what I did equivalent? also, why hasn't this already been done?

Vadim Zeitlin

unread,
Dec 6, 2014, 8:10:34 AM12/6/14
to wx-u...@googlegroups.com
On Sat, 6 Dec 2014 00:03:57 -0800 (PST) Greg Jung wrote:

GJ> I was including the wx/wx.h headers to bring in a pre-built binary
GJ> wxWidgets-3.0.2 from MSYS2/mingw32.
GJ> I got unicode-related errors from wx/msw/winundef.h:
GJ> ~~~~
GJ> C:/msys32/mingw32/include/wx-3.0/wx/msw/winundef.h: In function 'HWND__*
GJ> CreateDialog(HINSTANCE, LPCTSTR, HWND, DLGPROC)':
GJ> C:/msys32/mingw32/include/wx-3.0/wx/msw/winundef.h:38:20: error: cannot
GJ> convert 'LPCTSTR {aka const char*}' to 'LPCWSTR {aka const wchar_t*}' for
GJ> argument '2' to 'HWND__* CreateDialogParamW(HINSTANCE, LPCWSTR, HWND,
GJ> DLGPROC, LPARAM)'
GJ> return CreateDialogW(hInstance, pTemplate, hwndParent,
GJ> pDlgProc);
GJ> ^
GJ> ~~~~

This probably means that UNICODE is not defined.

GJ> So when I change this line to
GJ>
GJ> return CreateDialogW (hinstance, (LPCWSTR) pTemplate, hwndParent,
GJ> rDlgProc),
GJ>
GJ> because CreateDialogW is defined with LPCWSTR declarations,
GJ> I am simply by-passing a computer's misunderstanding. Is that correct?
GJ> it compiles, anyway.

Yes, but it won't work during run-time.

GJ> Is what I did equivalent? also, why hasn't this already been done?

Because normally it's not necessary. How exactly do you compile your code
to get these errors?

Regards,
VZ

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

Domingo Becker

unread,
Dec 6, 2014, 9:12:01 AM12/6/14
to wx-u...@googlegroups.com
2014-12-06 5:03 GMT-03:00 Greg Jung <gvj...@gmail.com>:
> I was including the wx/wx.h headers to bring in a pre-built binary
> wxWidgets-3.0.2 from MSYS2/mingw32.

And using the same compiler options that were used to build that
pre-built wxWidgets binary?

Greg Jung

unread,
Dec 6, 2014, 4:11:42 PM12/6/14
to wx-u...@googlegroups.com
There's no special compiler options, it comes in with a CMAKE build, but _UNICODE is set otherwise it wouldn't be compiling that block which defines the W( function, it would be on the A( block.

all I know is what wx-config tells me:  msw-unicode-3.0. (see below for the dump)

--GJ> it compiles, anyway.


 Yes, but it won't work during run-time
What happens? I am thinking, no conversion of pointers will be done, TCHAR=wide_t and everything will pass through untouched.
~~~~
 # CMAKE generated file: DO NOT EDIT!
# Generated by "MSYS Makefiles" Generator, CMake Version 3.1

# compile CXX with C:/msys32/mingw32/bin/g++.exe
CXX_FLAGS = -O3 -DNDEBUG @CMakeFiles/gdl.dir/includes_CXX.rsp   -fopenmp

CXX_DEFINES = -DHAVE_CONFIG_H -DWXUSINGDLL -D_FILE_OFFSET_BITS=64 -D__WXMSW__
~~~~
more stuff:

~~~~
$ wx-config --cxxflags
-IC:/msys32/mingw32/lib/wx/include/msw-unicode-3.0 -IC:/msys32/mingw32/include/wx-3.0 
-D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXMSW__ -mthreads -fpermissive

-IC:/msys32/mingw32/include/GraphicsMagick 
-IC:/msys32/mingw32/lib/wx/include/msw-unicode-3.0 
-IC:/msys32/mingw32/include/wx-3.0 
-IC:/msys32/mingw32/include/python2.7 
-IC:/msys32/mingw32/lib/python2.7/site-packages/numpy/core/include 
-IC:/msys32/home/greg/gdl95cvs/gdl -IC:/msys32/home/greg/gdl95cvs/gdl/src/antlr -IC:/msys32/home/greg/gdl95cvs/gdl/blddell 

~~~~
TMI:
~~~~~~~~
$ gcc -v
Using built-in specs.
COLLECT_GCC=C:\msys32\mingw32\bin\gcc.exe
COLLECT_LTO_WRAPPER=C:/msys32/mingw32/bin/../lib/gcc/i686-w64-mingw32/4.9.2/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with: ../gcc-4.9.2/configure --prefix=/mingw32 --with-local-prefix=/mingw32/local --build=i686-w64-mingw32 --host=i686-w64-mingw32 --target=i686-w64-mingw32 --with-native-system-header-dir=/mingw32/i686-w64-mingw32/include --libexecdir=/mingw32/lib --with-gxx-include-dir=/mingw32/include/c++/4.9.2 --enable-bootstrap --with-arch=i686 --with-tune=generic --enable-languages=c,lto,c++,objc,obj-c++,fortran,ada --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-time=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-cloog-backend=isl --enable-version-specific-runtime-libs --disable-cloog-version-check --disable-isl-version-check --enable-lto --enable-libgomp --disable-multilib --enable-checking=release --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-libiconv --with-system-zlib --with-gmp=/mingw32 --with-mpfr=/mingw32 --with-mpc=/mingw32 --with-isl=/mingw32 --with-cloog=/mingw32 --with-pkgversion='Rev2, Built by MSYS2 project' --with-bugurl=http://sourceforge.net/projects/msys2 --with-gnu-as --with-gnu-ld --disable-sjlj-exceptions --with-dwarf2
Thread model: posix
gcc version 4.9.2 (Rev2, Built by MSYS2 project)

greg@dellbert ~
$ wx-config --version-full
3.0.1.0

greg@dellbert ~
$ wx-config --selected-config
msw-unicode-3.0

greg@dellbert ~
$ wx-config --selected-config --cppflags
msw-unicode-3.0
-IC:/msys32/mingw32/lib/wx/include/msw-unicode-3.0 -IC:/msys32/mingw32/include/wx-3.0 -D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXMSW__

Vadim Zeitlin

unread,
Dec 6, 2014, 4:22:39 PM12/6/14
to wx-u...@googlegroups.com
On Sat, 6 Dec 2014 13:11:40 -0800 Greg Jung wrote:

GJ> There's no special compiler options, it comes in with a CMAKE build, but
GJ> _UNICODE is set

Sorry, I don't know anything CMake (except that I want to avoid using it
as much as possible), so I can't help you but _UNICODE appears nowhere in
the text of your message and so it does seem like it's simply not defined
and this is definitely a problem. Define it and everything should be fine.

Greg Jung

unread,
Dec 6, 2014, 11:51:59 PM12/6/14
to wx-u...@googlegroups.com
_UNICODE is defined, as it should be, and as it shouldn't be by me but by the wx
code as it runs through its inspection.   By the time winundef.h was processing, it was defined - thats where my errors were. To further demonstrate, I modified the heading at the originating code

~~~~~
using namespace std;
#ifdef _UNICODE
#warning " _UNICODE is defined"
#else
#warning " _UNICODE is not defined"
#endif
vector< void*> DStructGDL::freeList;
#ifdef HAVE_LIBWXWIDGETS
#include <wx/wx.h>
wxMutex mutexNewDelete;
#define LOCK_MUTEXNEWDELETE mutexNewDelete.Lock();
#define UNLOCK_MUTEXNEWDELETE mutexNewDelete.Unlock();
#else
#define LOCK_MUTEXNEWDELETE ;
#define UNLOCK_MUTEXNEWDELETE ;
#endif
#ifdef _UNICODE
#warning " _UNICODE is defined"
#else
#warning " _UNICODE is not defined"
#endif
~~~~~~~~~~~~~~~~~~

The result:

~~~~
C:/msys32/home/greg/gdl95cvs/gdl/src/dstructgdl.cpp:29:2: warning: #warning " _UNICODE is not defined" [-Wcpp]
 #warning " _UNICODE is not defined"
  ^
C:/msys32/home/greg/gdl95cvs/gdl/src/dstructgdl.cpp:42:2: warning: #warning " _UNICODE is defined" [-Wcpp]
 #warning " _UNICODE is defined"
  ^
~~~~

Vadim Zeitlin

unread,
Dec 8, 2014, 7:00:54 AM12/8/14
to wx-u...@googlegroups.com
On Sat, 6 Dec 2014 20:51:57 -0800 Greg Jung wrote:

GJ> _UNICODE is defined, as it should be, and as it shouldn't be by me but
GJ> by the wx code as it runs through its inspection. By the time
GJ> winundef.h was processing, it was defined - thats where my errors were.
GJ> To further demonstrate, I modified the heading at the originating code

Sorry, I am somewhat lost in what exactly is this supposed to demonstrate.
Could you please show the *exact* command line you use for compilation? Are
you absolutely sure it contains /D_UNICODE or /DUNICODE or
/DwxUSE_UNICODE=1? If it doesn't, you need to add it there, it's as simple
as that.

Greg Jung

unread,
Dec 8, 2014, 3:27:13 PM12/8/14
to wx-u...@googlegroups.com
if D_UNICODE were required it would appear in `wx-config --cxxflags`; it doesn't, but
instead -I/.../wx/msw-unicode-blahblah is how UNICODE is defined, and so the code snippet
above,, was run to demonstrate that _UNICODE gets defined when wx/wx.h is processed.

Vadim Zeitlin

unread,
Dec 8, 2014, 3:33:12 PM12/8/14
to wx-u...@googlegroups.com
On Mon, 8 Dec 2014 12:27:10 -0800 Greg Jung wrote:

GJ> if D_UNICODE were required it would appear in `wx-config --cxxflags`;
GJ> it doesn't

No, it never does currently. This is probably a mistake, actually, but
wx-config is primarily a Unix tool and so doesn't take it into account.

GJ> On Mon, Dec 8, 2014 at 4:00 AM, Vadim Zeitlin <va...@wxwidgets.org> wrote:
GJ> > Are you absolutely sure it contains /D_UNICODE or /DUNICODE or
GJ> > /DwxUSE_UNICODE=1? If it doesn't, you need to add it there, it's as
GJ> > simple as that.

More importantly, I'm afraid I just don't have much to add to the above.
If you want to fix your problem, this should be enough. If you'd like to
improve wxWidgets, this is even better and we'd gladly welcome your help.

Greg Jung

unread,
Dec 8, 2014, 3:49:09 PM12/8/14
to wx-u...@googlegroups.com
You needn't feel compelled to respond if you don't have constructive help.  At no point in the process do I touch a line that says, "g++ ... this or that".  It is done, for all of several files in the project, based on the works of several predecessor developers, which I use. And the wx package is a part of that system.  CMAKE sets it up and then it is processed through the "make" command.  So my question pointed out a minor defect (or not) based on an error I got.  If UNICODE is already defined, it makes no sense to try to define it again.  And it was, and that is evident in my first EMail because it wouldn't have put out those errors if it were processing the ANSI branch.

Greg Jung

unread,
Dec 9, 2014, 7:27:37 PM12/9/14
to wx-u...@googlegroups.com
The answer is, whether UNICODE is pre-defined for the benefit of <windows.h> via winnt.h.
This is now different from _UNICODE which wxwidgets sets and uses. 

~~~~
#ifdef UNICODE,
  typedef LPWSTR PTSTR,LPTSTR;
  typedef LPCWSTR PCTSTR,LPCTSTR;
#else
  typedef LPSTR PTSTR,LPTSTR,PUTSTR,LPUTSTR;
  typedef LPCSTR PCTSTR,LPCTSTR,PCUTSTR,LPCUTSTR;
~~~~
 So Vadim's solution, to hammer it all with UNICODE (not _UNICODE), would have let it compile.
wx/msw/winundef should however be usable without this assumption.
Reply all
Reply to author
Forward
0 new messages