Fog Creek Software
Discussion Board

Ok, now more generic

Regarding my Win32 app, how do I structure it? Which do I design first, the GUI or the backend? Which do I code first?

And how do I go about designing these apps in a more general sense? I know what I want my app to do, I know what particular features I want it to have. But how do I put that in writing? Everytime I start to design something I seem to get lost and end up doing things out of my head.

Yes, I know about Joel's article on design. But I need something more, more examples.

Thursday, May 20, 2004

I usually do a mock UI first, and try to see how it works.

As for the design of the functionality, try to forget it's a Win32 app. Abstract it away in your design. Create some sort of layer that communicates with your UI (I usually call it the controller, per MVC). Create your functionality modules/classes/whatever to communicate with this layer.

For testing purposes, you can even make the controller work through cout/cin for testing purposes, and test without needing a GUI.

If the controller starts to look messy, take a step back, and see how you can improve it. For me, it's the hardest part to get right.


Paulo Caetano
Thursday, May 20, 2004

For all of my UI's (web or desktop-based), I write a simple interface with the default buttons that just popup messages like "Processing it!!"

Then, as more functionality comes online, I replace my stubs with the actual pieces.

The nice thing is that once I get all my parameters set up, I can hand the UI off to our local web-guy for the prettiness-making process.

Thursday, May 20, 2004

You might sketch your UI design on paper until it looks and "works" the way you want it to. Then later use the dialog editor to create the frontend. (Penciling it out is faster and also easier to change than using the dialog editor.)

When I have an idea of the functions/classes/etc. I'm going to need to write, it helps to write them up in Notepad before I actually create them in my development environment (again, because it's easier and faster). At this stage I'm just defining them (interfaces & skeleton code). I'll fill in the code later. I find this prevents me from wasting time by writing two similar functions that could instead be consolidated into one.

For more complicated programs, it also helps to do a top-down design where you decide at a high level what the purpose of the program is (vision & scope) and then progressively get more detailed.

One size does not fit all. I usually use two or all three of the above approaches instead of just one. Otherwise my brain kind of gets stuck in a loop where I can't figure out what to do next.

Thursday, May 20, 2004

You said before you have a lot of time...

Do a framework and at least you'll learn a lot about a
platform and maybe you'll find out what's the problem
of that platform so you could write something to solve that
problem. Like decent resource editor.

Back to subject!

Maybe you can build something like what I have built
since Jan 16 2003 - the day I've bought Petzold.

I make my living on Mac and usually during the spring and
fall of every year I have so much time to do whatever I

With Petzold and every other Win32 book that I could've
found (around 15 of them) and with some help of Willows
and Wine and a bit of MSDN I started porting my code from
classic Mac to Win32.

My app is structured in several layers, one of them being
UI layer that relies on native API, and which I call to
actually draw something on the screen or paper.

If you look at the rest of my code it looks like lots of
initialisations and functions looking like these:

dt_getfield (), dt_putfield, dt_getlevel(), dt_setlevel(),...
With them I cover almost anything.

Native APIs are somehow too complicated. I made mine
dt_putfield() set text of any type of control, so I don't
care if something is button, edit, static, radio or whatever. Level stuff is used for lists of any kind.

dt_setlevel (form, A_CB_CURRENCY, 5, NULL);
  selects 5th item of combo A_CB_CURRENCY
dt_setlevel (form, A_CB_CURRENCY, 5, "EUR");
  sets text of 5th item to "EUR"
dt_setlevel (form, A_CB_CURRENCY, -1, "EUR");
  selects item that equals "EUR"
dt_setlevel (form, A_CB_CURRENCY, -2, "EUR");
  selects item that starts with "EUR".

No Mac API here so on Win side I had to write my library
from scratch and the rest of code would compile unchanged.
I set myself ideal where not a single line from the
rest of my code should change so I could maintain both
platforms at the same time without forks or crowded ifdefs.

Several functions had to move from general code into
library, but mostly I just define macros for Mac stuff I
use all over the place like:

#define  BlockMove(s,d,l)    MoveMemory(d,s,l)
#define  TickCount()          GetTickCount()

and for others I wrote functions by myself like this one:

void  SetPt (POINT *pt, short x, short y)
  pt->x = x;
  pt->y = y;

In my library I have one WndProc that handles everything
that happens to window and one proc for each type of controls I use.

Here and there I had to recreate EventRecord that Mac
API generates, but only for few specific cases so code like
this can work:

dt_init_form (gCopyrightForm, "About...", dBoxProc);

dt_open_form (gCopyrightForm, &tmpRect, kAboutDITL, &copy_extra_specs[0]);

dt_putfield (gCopyrightForm, A_TEXT, "My prog - 2004");

do {
  dt_GetNextEvent (everyEvent, &myEvent, FALSE);
  dt_manage_form (gCopyrightForm, &myEvent);
} while (myEvent.what != keyDown && myEvent.what != mouseDown);

dt_close_form (gCopyrightForm);

Looks strange at first that this could possibly work on
Win, but I made it work - and it works great - no memory
leaks, no resource leaks, processor at 1% because it's
simple for me to use it now and all the hard stuff is handled
somewhere deep down in library.

When I started it seemed almost impossible and crazy but
maybe that's why it was so much fun to do it. I was ready to
throw in the towel at any time and I haven't told any of my customers and associates what I'm doing at home so I could
give up if Registry and one-icon self-install or anything else
turns out to be too much for me.

The point is that I am so happy with what I did and if I
don't give up this spring I'll have a Windows product by the
end of fall.

It's a port of 12 sources or 600 K out of 8 MB of C code, 150
source files and at least 100 header files, 50 windows, 250
dialogs, 200 reports, clipboard, previews, import/export,
plugins etc. in two years as it seems now, while doing my
regular job as if nothing else is going on.
Two years of my life would have passed anyway.

Thursday, May 20, 2004

*  Recent Topics

*  Fog Creek Home