The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

stuck with ugly GUI

I am developing an application using wxWidgets. The application does not need to be x-platform. I picked this framework because it was very easy to pick up.

Now I am running into problems. The widgets are the OS native ones. There is no easy way to skin them using the wxWidgets framework because this framework wasn't designed for that. Writing my own widgets is out of the question. Too much work.

I never programmed in MFC. I took a look at the Prof-UIS widgets. They look very nice and there are lots of samples, but these samples might as well have been written in gibrish. I did a search on this forum. Most people vote against it anyway.

I don't know Delphi or Pascal. That's probably not the way to go either. Rewriting the codebase in Delphi/Pascal would probably too much work.

.NET is a possibility. I see myself eventually switching to using C#, but for now I don't want to dig into it.. at least not until the majority of people are using Vista or have .NET installed.

ATL? WTL? I haven't programmed using these either. All I know about ATL is Joel complaining about how horrible it is to deal with.

I am just thinking out loud. I don't want you to think I don't want to learn anything new. From all the options I have, it looks like MFC is the way to go.

Anyone would like to chime in?
eye_candy
Sunday, March 25, 2007
 
 
>I never programmed in MFC. I took a look at the Prof-UIS widgets. They look very nice and there are lots of samples, but these samples might as well have been written in gibrish. I did a search on this forum. Most people vote against it anyway.

Where precisely "Most people vote against it ..."?

I've been using Prof-UIS for several years and am overall quite happy with it. Like any library you need to put the effort into learning it. As you say Prof-UIS has plenty of examples and their support is very good, at least for the paid product.

If you wanted a nice looking app then I can't understand why you used wXWidgets. Looks like you've waisted a lot of time and effort.
Neville Franks Send private email
Sunday, March 25, 2007
 
 
> If you wanted a nice looking app then I can't understand
> why you used wXWidgets. Looks like you've waisted a lot of
> time and effort.

The motivation was that it was very easy to pickup. The underlying logic is still C++. It is not a complete waste. Plus, wxWidgets is supposed to be very similar to MFC. In most cases you can replace "wx" with "C" and you get MFC.

I just don't know the inner guts of MFC. Before I start putting a ton of time into learning it, I just wanted to poll the audience here and see what they think
eye_candy
Sunday, March 25, 2007
 
 
I wouldn't have thought MFC was any harder to pickup than wxWidgets. There is a ton of info available on MFC so if anything you should be better placed.

Try and use as little MFC as possible. Use STL and Boost instead of stuff like CString, CArray et.all. Use a library like Prof-UIS or CodeJock for the GUI.

And use http://www.codeproject.com for all things Windows/C++/C# etc.
Neville Franks Send private email
Sunday, March 25, 2007
 
 
If they're native widgets and you don't want to rewrite, you could do something like this.

Learn enough Windows API to do this:

1. Hook a new window in your app being created

2. Subclass it

3. Handle the painting yourself, and pass everything else on to the original functionality.


It wouldn't fundamentally change the UI functionality - you don't get new controls out of this -  but it could jazz up the appearance a little.
S. Tanna
Sunday, March 25, 2007
 
 
Notwithstanding what I just said, if I was starting with a clean slate with your requirements, I would have used MFC.

In fact, I did on my most recent app which I finished on Friday.
S. Tanna
Sunday, March 25, 2007
 
 
If you're prepared to go to the enormous effort of reading through the many code samples on the wxWidgets website, you'll find that it's possible and easy to vary the appearance of the GUI. If you're using Windows XP and using either native Win32 code, MFC, or wxWidgets, you'll get the same old-style appearance *unless* you use an appropriate manifest file. Going to all the effort of learning a new API and then discoving that this is the important detail would be good for a laugh, at your expense.

And, more amusingly, you'll find that generally when people "skin" ye olde Win32 windows, they end up with a garish and painful mess. It's a rare occurance for code or API to be the true cause of a low quality UI.

That and the fact that a non-native appearance will often detract from the quality of your application. If you're writing a Windows-only application, making it look like a MacOS or Linux application will hurt, and making it look like something that noone has seen before will also hurt.

Honestly, inability to "skin" GUI controls seems unlikely to be the principal source of your troubles, even if you do want to change the API you use.

Monday, March 26, 2007
 
 
Noname,

Thanks for your comments.

I do use the manifest file under XP, and the app does look much nicer.

I don't really like skinned apps either for the reasons you cited, but I'd like to keep my options open for any third-party controls. The commercial controls are primarily for MFC and .NET (and Delphi). There is noone selling commercial wxWidgets controls although wxWidgets has a thriving community and they have their own set of pretty neat widgets. However, having the option of being able to buy high quality controls is a huge plus.

I'll most likely take another look at MFC at this point.

Thanks guys!
eye_candy
Monday, March 26, 2007
 
 
If you want to maintain your sanity status, stay away from MFC. Use Qt instead.

The list of arguments against MFC is sooo long, I wouldn't go into details.
Achilleas Margaritis
Tuesday, March 27, 2007
 
 
"The list of arguments against MFC is sooo long, I wouldn't go into details."

I would like the details.  I used it in one course.  That did not give me enough to know why it is cursed.  How is it worse than anything else?  Why?

Sincerely,

Gene Wirchenko
Gene Wirchenko Send private email
Wednesday, March 28, 2007
 
 
"The list of arguments against MFC is sooo long, I wouldn't go into details."

There are always people who love something and people who hate the exact same thing for the same reasons.
eye_candy
Thursday, March 29, 2007
 
 
Ok, since you asked it, here it goes:

1) MFC violates C++'s message passing mechanism: virtual methods no longer work, instead you have to search for a method implementation using message maps.

2) if you use the Visual Studio of MFC wizard and something breaks, you are out of luck: it is very hard to fix things.

3) window classes need double creation: first you create the C++ object, then the Win32 window. Extra work for no purpose, since you can not use the C++ object until the C++ window is created.

4) MFC has no layout management. If you want to change text while the application is running, you have to adjust controls yourself.

5) some controls must be deleted by deleting the C++ object, some other controls must be deleted by invoking DestroyWindow, some other controls must be deleted by both Invoking DestroyWindow and deleting the C++ object. Hence the application will most probably leak memory.

6) DDX sucks. MFC does not use the Model-View-Controller pattern, so it is very difficult to do any meaningful editing of data structures through the GUI.

7) MDI children forms can not have controls on them. You have to put controls in dialogs, and dialogs can not be MDI children, unless you hack the system.

8) Win32 is not hidden at all. You have to look up Win32 constantly, even if you use a C++ library. You have to lookup every flag to pass to CreateWindow, for example.

9) Toolbar objects are not controls. In order to place a combobox in a toolbar, you have to hack the toolbar, or superimpose the combobox over some unused buttons.

10) changing tooltip text in toolbar buttons using code is almost impossible: almost everything crashes. You have to malloc string memory which is used by the tooltip structures, but the docs don't say when and how to free it, or if it is copied internally to some buffer.

11) There is no MouseEnter and MouseLeave events. You have to fake them using a special function.

12) the enabled/disabled state of tool buttons is checked only when the message loop detects no mouse and keyboard messages. Therefore it is quite possible to modify the state of a command to disabled, but the command will be shown enabled if the user does something that requires continuous mouse input.

13) functions placed in message maps are not checked for conformance to the required function signature. I once had forgotten to declare a parameter, the compiler quietly accepted it, the debug version was ok, but the release version crushed. There are numerous ways to mess up message maps.

14) Controls in tabs do not belong in the tabs, but in the form the tab is! that means you can not build tab pages with the UI designer, because controls have to be placed on top of each other. You can only do it with code.

15) There is no way to do proper validation of input data in text fields. The text field class does not contain the sufficient methods to properly implement masks.

16) there is not even a way to properly validate data on form acceptance: pressing the OK button does not generate any programmable event, it just invokes the OnOK function of the class of the dialog. If you place another control that must validate data(for example, Apply), the validation code in the OnOK method will not be invoked.

17) there is no way to modify the system menu of a window unless you use Win32.

18) Border type selection also defines the ability of a window to be resized(!!!).

19) MFC not only does not use the MVC model, it doesn't even use callbacks: all controls are send to parent forms: you can not do any useful subclassing of controls in this way.

20) menu items are not objects. If you expected to draw your own menu items by overriding a OnPaint method, you are out of luck: you have to use the horrible mechanism of owner-drawn menus.

21) MFC inherits the horrible Win32 API where some functions regarding rectangles use one more pixel from the right and bottom side of the rectangle. For example, drawing a rectangle inside the coordinates {x=0, y=0, width=100, height=100} will actually draw up to x=100, y=100, thus drawing a rectangle of 101 pixels size.

22) drag-n-drop is really difficult to implement, especially within a tree view. You have to use image lists, and then do the drag-n-drop manually (tree nodes are not recognized, you have to have code in OnMouseMove).

23) thread objects are not automatically deleted when the thread ends, even if autodelete is true. Many leaks from this.

24) the class Lock<T> does not lock the critical section, mutex or semaphore passed to it unless you pass TRUE to the constructor. Which is very silly, and costed me a whole week's trip to the contractor's country because the app was crashing, because I thought that Lock<CMutex> lock1(mutex1) locked the mutex automatically.

25) GUI commands are delivered through the OnCommand messages, making most of the application a big switch statement on the command id. Some may not think this is a big deal, but when you have lots of commands, it is very boring to having to write a case statement for each new id. Plus it makes the application really slow.

26) dialog controls are not classes, unless you map each win32 component to a class. You have to create the control in the UI, then map a member instance to the control. Triple work for achieving the same thing that other toolkits do in a line of code.

27) non-control of the message pump loop makes it really difficult to write any good state-driven code that drives the GUI. You have to write new win32 message ids, post messages in the message queue, and any data the message has, must be put in another parallel queue, because the message queue only takes a WPARAM/LPARAM. Alternatively, you can place the pointer value of your message data in LPARAM, and hoping you remember the correct type afterwards.

28) controls can not have parents other than dialogs or control toolbars. You can not nest controls.

29) radio button frames are treated like tabs: radio buttons are not children of the frame, hence if you move the frame, you have to move the buttons as well.

30) ids of radio buttons must be sequential, otherwise radio buttons will not work, because the API uses the range of IDs to deselect a radio button. Which means that, if you want to insert a new radio button later, you are screwed: you have to edit the control ids by hand.

Overall, MFC is very stupid. My first commercial project was with MFC. A horrible experience. Then I bought Qt and never looked back.

MFC is a horrible hack meant to give C++ a bad name and turn programmers away from C++ and onto Visual Basic, which is proprietary. It is no coincidence that only Visual Studio 6 and prior versions use MFC. The Microsoft's flagship products (Office etc) do not use MFC at all (you can test that using Spy++: no AFX classes in other apps except Visual Studio).
Achilleas Margaritis
Thursday, March 29, 2007
 
 
> MFC is a horrible hack meant to give C++ a bad name and turn programmers away from C++ and onto Visual Basic, which is proprietary. It is no coincidence that only Visual Studio 6 and prior versions use MFC. The Microsoft's flagship products (Office etc) do not use MFC at all (you can test that using Spy++: no AFX classes in other apps except Visual Studio).


I love the conspiracy version of history.

Word and Excel don't use MFC, simply because they predate MFC. 

Fact is, whatever its imperfections, that there are plenty of apps, both MS and non-MS, that do use MFC.
S. Tanna
Thursday, March 29, 2007
 
 
Including, Spy++ itself
S. Tanna
Thursday, March 29, 2007
 
 
> The Microsoft's flagship products (Office etc) do not use
> MFC at all?

What does MS Office use then? Win32 API directly?
coder
Thursday, March 29, 2007
 
 
Yes I think it mostly does, although no doubt they have their own libraries.

I know that some of the mini-apps (WordArt?) in Office, that were added later, are MFC
S. Tanna
Thursday, March 29, 2007
 
 
It's not a matter of conspiracy. Nowadays Visual Studio is mostly .NET, for example. So Microsoft can rebuilt their flagship products in another language/environment. If MFC was  any good, they would have used in their Office suite.
Achilleas Margaritis
Friday, March 30, 2007
 
 
Why would they rewrite anything?  There's no reason or ROI to rewrite millions of lines of code in Word or Excel.

Fact is that MS did use MFC for some projects, and it worked for them.  As did many others.  Which proves that whatever its perceived imperfections, MFC can be used to produce successful commercial apps.

Friday, March 30, 2007
 
 
MFC has its limitations and flaws, its true. For example do a google search on "mfc strtok". However, it still has its place (for a while). I use a combo of MFC and STL, MFC for the ease of creating a windows gui app and STL for the collection classes and !broken stdlib impl. This will soon be an academic argument however as C# will be the defacto standard for developing windows apps. I got a comment from a colleague who was playing with it a few months ago; he kept saying how easy it was. (Similar to Java). Easy peasy apparently.
The Code Pope
Wednesday, April 04, 2007
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz