C++ Windowing Class

I’m going to hate myself for even writing about this because I’ll probably abandon this project soon. I’ll most likely lose interest in it like most of my projects. But here goes.

A long time ago I started writing a Visual Basic 6.0 application to help my mom organizing her library that has thousands of books. The project got really far but I stopped once I noticed that creating an installer for it was a pain. It would install, but the program wouldn’t run, unless the PC had Visual Basic 6.0 installed. Due to this frustration, I put the project on hold.

I then wanted to write it in C++, but my knowledge of C++ was not very advanced and I had a lot of bad experience a couple of years ago when I tried learning it. It was just too damn hard. But I tried creating a simple Win32 application. I wasn’t interested in console apps. After going through countless tutorials, the only way I managed to compile a Win32 app was to copy/paste someone’s code. When I tried writing it myself, either it crashed or no window appeared at all. Furthermore, the code for creating a window was long, ugly and incomprehensible to me. I became frustrated again. I started to miss the Java Swing library with which it was so easy to create GUI application (GUI stands for Graphical User Interface).

So what did I want to do? I wanted to write a class in C++ that would resemble the Java Swing library as much as possible. I also didn’t want to use any platform specific data types (such as HWND, HINSTANCE, RECT…) for the public interfaces. This had the great side effect that if one day I wanted to port my app to Linux, I would just need to implement the class functions and interfaces using, for example, the GTK library. In theory, (yes, in theory because I haven’t tried it yet, I still need to get Gentoo reinstalled, but really don’t feel like it) I will be able to port my apps to Linux by making minor changes to my code (except for the wrapper classes which would have to go under heavy renovation if you ask me). Another great side effect is that I’d also get to learn C++, which is always good. I wouldn’t want to be in a job interview and get asked: “How good are you at C++?” I don’t want to answer: “Errr, well, I know how to print ‘Hello, World’.”

I started this project in March. Since March I’ve restarted the project 4 times. Yes, four times. When it comes to designing something, I’ll restart it as much as I need to because if I see that there is a better way to design it, I for sure will go with it. If you get the basics right, then building on top of it just becomes a matter of writing code. It’s the concepts that are the things that keep me thinking real hard late at night or when I’m showering.

But I had quite a few bumps on the road. How would I implement an add(Component) function for the Window à la Java? How would I add action listeners to controls? Something I also noticed was that Visual C++ and other’s used resource files to designate buttons and other controls which would later be included in the code. How would I ever design my classes so that I can mimic the behavior of a resource file. Basically, I wanted the classes to do the thinking for me when it comes to Windows, Buttons and all. If the classes are the ones taking care of the dirty work, then I can take care of building a great app.

Ok, so enough with all the talk. I’ve solved all of the above questions. While there still are some bugs, I think my design works pretty well. I’m really proud. Will I release the code? Not yet, the code still looks ugly and I’m hoping of fixing stuff that I’m not too happy about. Also, at this time, the only things that I’ve implemented are Windows and Buttons. To make all of this really useful I’d need at least Text Boxes, Text Areas, List Boxes, Combo Boxes, Radio Buttons, and Check Boxes. Ouff, that sounds like a lot of work. I’m hoping it’s not :)

So what does a typical program look like using my class? Here’s a sample that would compile perfectly using my classes and do what you expect it to.

Update: Don’t ask me why, but WordPress had to escape all of my quotes.


#include "Window.h"
#include "Button.h"
#include "ActionListener.h"

Window *myWindow;
Button *exitButton;

class MyApp
{
    public:
        MyApp()
        {
            //Initialize the Window.
            myWindow = new Window("This Is A Test");
            myWindow->setSize(500, 500);

            //Initialize Components.
            exitButton = new Button("Exit");
            exitButton->setLocation(10, 10);
            exitButton->addActionListener(new ExitListener());

            //Add Components to the Window.
            myWindow->add(*exitButton);

            //Display the Window on the screen.
            myWindow->pack();
            myWindow->setVisible(true);
        }

        class ExitListener : public ActionListener
        {
            public:
                void actionPerformed()
                {
                    exit(0);
                }
        };
};

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    new MyApp();

    MSG message;

    while(GetMessage(&message, NULL, 0, 0) > 0)
    {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }

    return message.wParam;
}

Oh, look, I thought I said I didn’t use any system specific data types or functions. I know, but the WinMain function is required in Windows. I’m assuming that if I ever had to port my app to another platform, I’d just get rid of it, or I’d add a function that that platform requires. I didn’t say that my apps would be portable without making any changes, but I’m only envisioning minor changes and the WinMain is the only case that I have bumped into for now.

Something I’m not too happy about is the fact that the best way to use the classes I wrote is to define pointers for them outside of the application class (MyApp in this case). In a perfect world, they’d be defined as members of the MyApp class, but in C++ (unlike Java) nested classes (or what they call inner classes in Java) do not inherite the members (or instance fields as they call them in Java) of the enclosing class (MyApp in this case) and have no special access to them. But the classes derived from ActionListener have to have access to the Components or else the usefulness of these classes will go down. This pissed me off because I have to resort to a less elegant solution in my opinion. But if there’s a C++ guru out there that knows a solution, please let me know. I doubt that there would be a way of letting the ExitListener class for example have access to the myWindow and exitButton objects if I had defined them as members of the MyApp class (as you would in Java) without making them static (which I think is an even worse solution than mine).

I’m pretty excited about all of this. Even if I quit this project tomorrow, I’ve still learned a whole lot about C++.

One Response to “C++ Windowing Class”

  1. August 22nd, 2010 | 1:16 am

    Hello
    Viagra Helps COPD Patients Control Pulmonary Blood Pressure purchase generic online
    Bye !!
    ____________________________
    purchase online :)

Leave a reply