Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A wxWindows Hello, world! GUI for Windows

45 views
Skip to first unread message

Alf P. Steinbach

unread,
Jul 29, 2018, 8:48:45 AM7/29/18
to
I started with the FLTK GUI framework for the little thing I'm
hobby-working on at the moment on. But then I discovered that the main
widget I needed, a tree view, was nowhere to be found in FLTK, although
there had been a version with that widget (which google found
initiallly, which is why I felt confident enough to just start coding
with FLTK).

So I switched to wxWidgets as portable GUI framework, because Qt has
that decidedly uncute preprocessing, a custom language dialect.

I remembered from some 10-15 years ago, whatever, that wxWidgets has a
problem with global variables and the static initialization order
fiasco. That hasn't bitten me yet, but there was a problem with its main
header including `<windows.h>` in Windows. That's a lot of macros! Like
a zillion. Also it did it in a way that produced a compilation error
within some Windows header dragged in by <windows.h>. The solution: to
define `WIN32_LEAN_AND_MEAN`.

Also, I discovered, `_UNICODE` (not just `UNICODE`) needs to be defined
to make the wxWidgets environment detection scheme work.

Oh, and there was an issue with <wx/setup.h>, which is not found via the
ordinary general include path, but requires its own special include
path, down in [wxWidget root]/lib/vc_lib/mswu. Not a bad idea for
configuration. But it wasn't so clearly documented. I think tutorials
should explain things like that. The critical showstopper things.

Even with those fixes the example "Hello, world!" code I found in the
short-short tutorial at <url:
http://docs.wxwidgets.org/stable/overview_helloworld.html> didn't build
as a Windows console program. Uh oh, no `main` function! So what should
go in `main` for a wxWidgets app?

For that i dived into the macros that didn't quite work, and hopefully
reproduced the same code execution via `main`. wxWindows appears to be
built of macros, a very very 1990s approach. It so far appears very
MFC-ish, including "message maps" for mapping events to handlers.

For the release version in Visual Studio I linked with wxbase31ud.lib,
wxmsw31ud_core.lib, wxpng.lib, wxzlib.lib, kernel32.lib, user32.lib,
gdi32.lib, comdlg32.lib, comctl32.lib and rpcrt4.lib, which appears to
be minimal, roughly.

Anyway here's my result code, the tutorial's code fixed so that it
works, and re-styled to more like my code (he he), a working wxWindows
"Hello, world!" for Windows:


-----------------------------------------------------------------------
#include <stdlib/extension/type_builders.hpp> //
https://github.com/alf-p-steinbach/Wrapped-stdlib
using namespace stdlib::ext::type_builders;

// The following two macros defined by <wrapped-windows/windows-h.hpp>:
// WIN32_LEAN_AND_MEAN avoids dragging in buggy part of <windows.h>
// _UNICODE makes wxWidgets macro scheme work.
#include <wrapped-windows/windows-h.hpp> //
#include <wx/wx.h> // Includes <windows.h> :(

struct Cmd_id
{
enum Enum
{
hello = 1
};
};

class Main_window: public wxFrame
{
void on_cmd_hello( wxCommandEvent& )
{
wxLogMessage( "Hello world from wxWidgets!" );
}

void on_cmd_exit( wxCommandEvent& )
{
Close( true );
}

void on_cmd_about( wxCommandEvent& )
{
wxMessageBox( "This is a wxWidgets' Hello world sample",
"About Hello World", wxOK | wxICON_INFORMATION );
}

wxDECLARE_EVENT_TABLE();

public:
Main_window( const wxString& title, const wxPoint& pos, const
wxSize& size ):
wxFrame( nullptr, wxID_ANY, title, pos, size )
{
const ptr_<wxMenu> file_menu = new wxMenu;
file_menu->Append( Cmd_id::hello, "&Hello...\tCtrl-H",
"Help string shown in status bar for this menu
item");
file_menu->AppendSeparator();
file_menu->Append(wxID_EXIT);
const ptr_<wxMenu> help_menu = new wxMenu;
help_menu->Append( wxID_ABOUT );
const ptr_<wxMenuBar> menu_bar = new wxMenuBar;
menu_bar->Append( file_menu, "&File" );
menu_bar->Append( help_menu, "&Help" );
SetMenuBar( menu_bar );
CreateStatusBar();
SetStatusText( "Welcome to wxWidgets!" );
}
};

wxBEGIN_EVENT_TABLE( Main_window, wxFrame )
EVT_MENU( Cmd_id::hello, Main_window::on_cmd_hello )
EVT_MENU( wxID_EXIT, Main_window::on_cmd_exit )
EVT_MENU( wxID_ABOUT, Main_window::on_cmd_about )
wxEND_EVENT_TABLE()

class App: public wxApp
{
public:
auto OnInit()
-> bool override
{
const ptr_<Main_window> window =
new Main_window( "Hello World", wxPoint( 50, 50 ), wxSize(
450, 340 ) );
window->Show();
return true;
}
};

// wxIMPLEMENT_APP(App);
wxIMPLEMENT_WX_THEME_SUPPORT // Does nothing in Windows. :(

auto main()
-> int
{
wxDISABLE_DEBUG_SUPPORT(); // Don't know why, but that's in
wxIMPLEMENT_APP.
wxApp::SetInitializerFunction( []() -> ptr_<wxAppConsole> { return
new App; } );
return wxEntry(); // Undocumented, uses process arguments.
}
-----------------------------------------------------------------------


Cheers!,

- Alf

Alf P. Steinbach

unread,
Jul 29, 2018, 9:05:24 AM7/29/18
to
On 29.07.2018 14:48, Alf P. Steinbach wrote:
>
> For the release version in Visual Studio I linked with wxbase31ud.lib,
> wxmsw31ud_core.lib, wxpng.lib, wxzlib.lib, kernel32.lib, user32.lib,
> gdi32.lib, comdlg32.lib, comctl32.lib and rpcrt4.lib, which appears to
> be minimal, roughly.

Oh, that was for the debug version, sorry. Copy+paste-error.

Cheers!,

- Alf



Mr Flibble

unread,
Jul 29, 2018, 10:42:17 AM7/29/18
to
Alf, why do you think anyone would be interested in this old way of doing
things and the post in general?

These days people use Qt (or soon my lib, neoGFX).

/Flibble

--
"Suppose it’s all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I’d say, bone cancer in children? What’s that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It’s not right, it’s utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a
world that is so full of injustice and pain. That’s what I would say."

Alf P. Steinbach

unread,
Jul 29, 2018, 9:48:58 PM7/29/18
to
On 29.07.2018 16:42, Mr Flibble wrote:
> On 29/07/2018 13:48, Alf P. Steinbach wrote:
>> I started with the FLTK GUI framework for the little thing I'm
>> hobby-working on at the moment on. But then I discovered that the main
>> widget I needed, a tree view, was nowhere to be found in FLTK,
>> although there had been a version with that widget (which google found
>> initiallly, which is why I felt confident enough to just start coding
>> with FLTK).
>>
>> So I switched to wxWidgets as portable GUI framework, because Qt has
>> that decidedly uncute preprocessing, a custom language dialect.
>>
>> I remembered from some 10-15 years ago, whatever, that wxWidgets has a
>> problem with global variables and the static initialization order
>> fiasco. That hasn't bitten me yet, but there was a problem with its
>> main header including `<windows.h>` in Windows. That's a lot of
>> macros! Like a zillion. Also it did it in a way that produced a
>> compilation error within some Windows header dragged in by
>> <windows.h>. The solution: to define `WIN32_LEAN_AND_MEAN`.
>>
>> Also, I discovered, `_UNICODE` (not just `UNICODE`) needs to be
>> defined to make the wxWidgets environment detection scheme work.

After posting that I discovered that there's also a redefinition of M_PI
it isn't already defined. Which with MSVC then can trigger a warning
about "already defined". Which is not acceptable when one compiles with
warnings as errors.

So my current wrapping of the include of the wxWidgets main header now
looks like this:


------------------------------------------------------------------------
// The following two macros defined by <wrapped-windows/windows-h.hpp>:
// WIN32_LEAN_AND_MEAN avoids dragging in buggy part of <windows.h>
// _UNICODE makes wxWidgets macro scheme work.
#include <wx/msw/winver.h> // Windows version macros.
#include <wrapped-windows/windows-h.hpp> //
#include <stdlib/fix/math_constants_availability.hpp> // M_PI
#include <wx/wx.h> // Includes <windows.h> :(
------------------------------------------------------------------------


[snipalot]

Mr. Flibble, please quote only relevant stuff, but do quote that.


> Alf, why do you think anyone would be interested in this old way of
> doing things

Because AFAIK there aren't any viable modern alternatives except maybe
your library. Which I haven't tried, sorry. Well, and maybe the
Ultimate++ which likewise I haven't tried, but for different reasons.

Wikipedia's list: <url:
https://en.wikipedia.org/wiki/List_of_platform-independent_GUI_libraries>


> and the post in general?

GUI is one of the most often asked questions about C++. How does one do it?


> These days people use Qt (or soon my lib, neoGFX).

I don't like Qt. For one thing, its preprocessing, the `moc` compiler.
For another, the idea of dynamic type checking. Third, I remember years
ago when I tried to install it, the installation dialog failed to handle
the backspace key, typical for originally Unix-land code incompetently
ported to Windows (I don't recall exactly if it also had problems with
spaces in paths, but probably, it's in that general territory). Fourth,
their old white papers, pretending to have some have academic reasons
for the ungood design. That's also an incompetence indicator, defending
the bad decisions with academic nonsense that /looks/ impressive. Fifth,
that it's 1990's tech.

wxWidgets is also 1990's, but it's not Qt. :)

Do you have a tree view in neoGFX?


Cheers!,

- Alf

Paavo Helde

unread,
Jul 30, 2018, 3:49:32 AM7/30/18
to
On 29.07.2018 15:48, Alf P. Steinbach wrote:
> I started with the FLTK GUI framework for the little thing I'm
> hobby-working on at the moment on. But then I discovered that the main
> widget I needed, a tree view, was nowhere to be found in FLTK, although
> there had been a version with that widget (which google found
> initiallly, which is why I felt confident enough to just start coding
> with FLTK).
>
> So I switched to wxWidgets as portable GUI framework, because Qt has
> that decidedly uncute preprocessing, a custom language dialect.

I have tried to stay clear from GUI programming as much as possible
though there is an old legacy MFC app which I have been supporting and
occasionally extending for the last 15 years. But recently I was tasked
to rewrite a small GUI tool on Windows because the existing tool only
worked on a 32-bit Mac, a dead platform (and they were afraid the single
computer we had somewhere might die soon as well).

I think they expected me to use C# or Java or a Powershell script
because nobody makes GUI programs in C++ any more, right? But as a C++
guy and believing in portability I chose wxWidgets instead, partially
because the wxWidgets libraries happened to be already there for
satisfying some third-party dependencies.

Instead of trying to read through all the docus and build the app from
the scratch I just took some of their examples and massaged it until it
did the needed thing. So I did not encounter any problems with main(),
_UNICODE or <windows.h>, these were all resolved or avoided in the example.

To be honest, I expected something more fancy. Instead I basically found
the same old MFC, just cleaned up and regularized a bit. WxWidgets
relies heavily on macros as well (BEGIN_EVENT_TABLE, EVT_BUTTON, etc).
Also, instead of main() I seem to have something like IMPLEMENT_APP(MyApp).

So, the thing worked, but the experience was not so great. I hope to
avoid GUI programs also in the future, but if this happens to be not
possible, I will probably try out some other framework, maybe Flibble's
neoGFX?




Christian Gollwitzer

unread,
Jul 30, 2018, 4:02:46 AM7/30/18
to
Am 30.07.18 um 03:48 schrieb Alf P. Steinbach:
>> These days people use Qt (or soon my lib, neoGFX).
>
> I don't like Qt. For one thing, its preprocessing, the `moc` compiler.
> [...]
>
> wxWidgets is also 1990's, but it's not Qt. :)

wxWidgets uses a very obsolete technique to handle event bindings. These
static event tables are quite inflexible and cumbersome once they become
larger.

You could have a look at "gtkmm", which uses libsigc++ for event
handling. It is based on C++ template features and achieves the same
flexibility as in QT with the moc. The moc was necessary back then when
they designed Qt, with today's C++ it is not longer necessary. They just
don't want to switch for compatibility reasons.

Christian

woodb...@gmail.com

unread,
Jul 30, 2018, 11:47:24 AM7/30/18
to
On Sunday, July 29, 2018 at 9:42:17 AM UTC-5, Mr Flibble wrote:

>
> Alf, why do you think anyone would be interested in this old way of doing
> things and the post in general?
>

Not everyone is able to use the latest tech.
I'm wondering if 2011 C++ is the new C.



Brian
Ebenezer Enterprises - "Do not boast about tomorrow, for you do
not know what a day may bring." Proverbs 27:1

http://webEbenezer.net

Melzzzzz

unread,
Jul 30, 2018, 1:27:11 PM7/30/18
to
On 2018-07-29, Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
> I started with the FLTK GUI framework for the little thing I'm
> hobby-working on at the moment on. But then I discovered that the main
> widget I needed, a tree view, was nowhere to be found in FLTK, although
> there had been a version with that widget (which google found
> initiallly, which is why I felt confident enough to just start coding
> with FLTK).
>
> So I switched to wxWidgets as portable GUI framework, because Qt has
> that decidedly uncute preprocessing, a custom language dialect.

You don't have to use qt's signal/slot at all.
Some 20 years ago I just overrode event() virtual function
of application and used my own event handling.
Also you can override per object.

> }
>
> wxDECLARE_EVENT_TABLE();
>
>
> wxBEGIN_EVENT_TABLE( Main_window, wxFrame )
> EVT_MENU( Cmd_id::hello, Main_window::on_cmd_hello )
> EVT_MENU( wxID_EXIT, Main_window::on_cmd_exit )
> EVT_MENU( wxID_ABOUT, Main_window::on_cmd_about )
> wxEND_EVENT_TABLE()

MFC anyone? ;)

--
press any key to continue or any other to quit...
0 new messages