
The Infamous Windows “Hello World” Program - johndcook
http://www.charlespetzold.com/blog/2014/12/The-Infamous-Windows-Hello-World-Program.html
======
rozzie
I've uploaded three versions of the missing source code from floppies, along
with windows.h for each.

[http://ozz.ie/h31100](http://ozz.ie/h31100)

~~~
chinpokomon
Thank you, Ray. Any old compilers in your time machine as well? ;-) I had
(incorrectly) presumed that this older K&R style of C predated Windows and was
never ported from Unix.

~~~
stormbrew
Until a few years ago you could still find K&R declarations in the Ruby source
code[1]. Wasn't until 1.9 that they switched things over to ANSI style, iirc.

So, believe it or not, you might still find it out there in the wild.

[1] eg:
[https://github.com/ruby/ruby/blob/v1_8_7_374/compar.c](https://github.com/ruby/ruby/blob/v1_8_7_374/compar.c)

~~~
umanwizard
FreeBSD still uses this declaration style liberally (keep in mind FreeBSD is a
fork of BSD which has been around for some decades, and it makes sense that
there's some old code floating around in the kernel)

------
wolfgke
The same program for GNU/Linux/XLib is not much less complicated:
[http://www.paulgriffiths.net/program/c/srcs/helloxsrc.html](http://www.paulgriffiths.net/program/c/srcs/helloxsrc.html)

Under Windows it is easy to create a console application, which is similar to
the usual C helloworld. But the application here creates a windows to show
hello world - so it's fair to compare it with a similar program on
GNU/Linux/Xlib.

EDIT: Yes, it is much easier to use something as Qt on GNU/Linux, but there
are also abstractions around the WinAPI available, so using Qt on GNU/Linux
for a helloworld example yields no fair comparison.

~~~
thorin
My Master's thesis in electronic engineering was supposed to be based on a
previous work written by a maths phd in c++ on XWindows. I'd only used C and
Basic before and not done any GUI programming. I couldn't believe how much
code was involved to set up a few simple windows. It really put me off and I
pretty much gave up and started writing my own [image manipulation] code in C.
I wish I'd had the sort of resources you can get for free nowadays available
it might have been a fun project!

It was the mid 90s and I didn't have unix/linux at home. In those days you had
to pay for a compiler on windows and I didn't know anyone running linux. Just
a couple of years later it was so much easier!

------
ChuckMcM
A story. As Petzold writes, the Windows version of "hello world" was amazingly
baroque. It bothered me, a lot. I had come up in the four line hello.c world
of UNIX, and later the make/test world of UNIX, and when I had left Sun the
idea of writing code like the Hello World example was something I could not
bring myself to do. I rebelled in a bunch of different ways, but the worst
part was it started a period for me where I programmed a lot less, I was
getting curmudgeonly because programming had become so screwed up.

The thing that changed for me was getting a chance to help a young man with
his programming who had come up through Windows rather than something easier,
and he was full of all the wonder and excitement I had had at his age for
programming, and had no idea that he was running with a large handicap to his
productivity. And partly because many of the "tools" you had to have like
Visual Studio worked their butt off to make that gap small, from self writing
code to documentation at your fingertips. I realized that if I didn't get the
'wonder' back of writing code I was going to become one of those guys who sits
around grumbling about how in my day things were so much better and FORTRAN
just worked dammit :-).

What I tried to learn from it was that systems with great generality suffered
from usability efficiency. The reason UNIX hello.c was so simple is that UNIX
programs, by and large, did simple things, algorithmic computation driven by
interaction over a character based interface. One way to drive effecive use of
a system was to either eliminate or otherwise hide the modalities that were
"possible" but not probable in future execution of the program.

That has helped me see when I'm building something that is letting to much
generality leak out to the surface.

~~~
jerf
"What I tried to learn from it was that systems with great generality suffered
from usability efficiency."

I'm entering "curmudgeon" age myself, at least for our industry, and what _I
'm_ getting curmudgeonly about are my fellow curmudgeons, and that's part of
why. Oh, programming was so much better in the 8-bit era? _So go back there
then._ It's still available to you if you want it! Oh, you don't want to take
_actions_ to match your words? Why not? Because, in a nutshell, no it wasn't
easier. It was easier to do the things it could do, sure, but it can't do
much. So stop telling me about how wonderful the 8-bit era was.

That's just one example. There's several of these recurring rants that come up
here on HN periodically.

~~~
ChuckMcM
Well said, in particular this bit, _" Oh, you don't want to take actions to
match your words?"_

There is a downside though when you get a curmudgeon with a fondness for the
"old" days and takes action by re-implementing your build system to look like
something you would read about in an IBM JCL handbook :-) I'm sure 8 character
error codes were easy to remember but even better is a short sentence on what
the error was.

------
breadbox
Certainly there is advantage in having a simple hello-world program. The
original purpose of hello-world, naturally, is just to have something to
verify that your environment and tools are properly installed and configured
before you go off and do anything serious.

But because Petzold used "his" hello-world program to introduce you to a bunch
of critical, foundational concepts -- to show you everything you needed in
order to get a functioning top-level application window open on the desktop --
I myself found it a great place to start. By forcing you to confront the
message loop from square one, it really reinforced the idea that you aren't in
Kansas anymore (and you can't do things like the Kansans do).

As Petzold hints in his article, the original version of the book (for Windows
2.x) didn't even start with that program, but worked its way up to hello-world
through a sequence of 5-10 iterations that got you to that point over the
course of an entire chapter. (Thus for example one iteration actually opened a
top-level window but lacked a message loop, so the program exited and the
window immediately disappeared after it was created.) It makes sense that he
had to edit out such a lackadaisical introductory chapter as the subject of
Windows programming got bigger and bigger, but I for one always liked that
chapter.

------
ryandrake
Brings back horrid memories of learning Windows programming back in the mid
nineties. From the very first line of code, Microsoft had you doing it their
(nonstandard) way, making you use WinMain() instead of main(). That style,
too... Yuck! Even today, I can somewhat reliably identify folks who were
raised on the Windows SDK by looking for lpszHungarianNotation and
UNREADABLEALLCAPSTYPEDEFS.

Does anyone remember why the original samples allocated structures on the
heap, did stuff with them, then immediately freed them, rather than just using
them on the stack directly? Was that a thing? Were early Windows systems stack
constrained or something?

~~~
MAGZine
I used to have much disgust for hungarian notation. When I worked on my first
big C++ codebase though, hungarian notation was standard, and I have to say,
it made the code more readable. using 's' for static, 'm' for member, etc
brought some extra clarity as to what was happening. It's not that we couldn't
determine these thing for ourselves (VS has great code-crawling facilities),
but its less time hovering, symbol searching, and jumping-to-declaration.

I don't use it out of choice, but it isn't so bad. Though, this was using a
slightly HN slightly differently. complete variable types in the name i have
different feelings for!

~~~
darklajid
I think you're mixing two absolutely different types of Hungarian Notation.

No offense, but what you describe seems more or less like the reviled version
(stuffing ~redundant~ information in the name, where you end up with strName
and iCounter).

The more-or-less accepted version described in the GP is trying to fix a
shortcoming of the language's type system. If you cannot tell your compiler
that this is a (default example) pixel value and this is a color, because both
are plain ints to it, you're trying to make accidents less likely by requiring
the programmer to double-check the prefixes (which encode a subtype, a special
type. Not int, but int-representing-color or int-as-a-bool-here).

~~~
Ntrails
iCounter always makes me wonder why someone would be iterating through
counters! I've still got the:

    
    
        for iObject = 1:nObject
    

style from matlab coding firmly rooted in my head - when hungarian isn't even
creating universally and easily understood/parsed names I just can't see the
value.

------
turnip1979
Brings back memories. I recall learning to write from memory the 40+ line
win32 hello world from the Petzold bible. That's the way it was back then ...
but you got super speed from it. Event loop was blazing fast. I discovered MFC
a bit later and worked as a professional dev at an ISV that made use of it. I
have fond memories of reading the v1 MFC manual - it was small enough at that
time so that a person could understand the whole thing with relative ease.

Some interesting notes on what happened in a few years .. when I first saw
.net Compact Framework, it blew my mind how easy it was to write .net
code/WinForms stuff. Even though I was relatively poor, I bought an MSDN
subscription on the spot and started to write mobile apps. This was early
2000s. If MSFT had paid proper attention to mobile devices, they could have
rocked it.

I faced weird challenges. Companies would ask me for 20K to certify my free
apps on their phones. It was disgusting. I sold a few apps on the hangango app
store, and then got out of mobile dev (missed the whole iPhone revolution).
Talk about bad timing.

~~~
leaveyou
it brings back memories indeed.. me watching in disbelief how long, ugly and
weird Microsoft C/C++ Win32 or even MFC programming for Windows was, compared
to Borland Delphi or C++ Builder. I tried, I really tried to like it but in
the end I gave up and I became a windows programmer much later with the
arrival of .net win forms and c# (created by Delphi architect
wikipedia.org/wiki/Anders_Hejlsberg - it's scary how scarce were the sane
language/framework/IDE architects back then)

------
fit2rule
For those of us watching from the Unix world while Microsoft fumbled its way
towards world domination, it was an incredibly frustrating time to see the
banality of their technology become 'the thing' in light of so many, many,
forgotten and ignored mysteries. It was something like what it might be like
to see a new religion form for your children while watching that of your
parents die.

Thank Linus we still have an alternative to Microsoft, here and now! It is
absolutely a huge gain for us that Unix was not eradicated by the feral,
vermin new thing.

~~~
Someone1234
> Thank Linus we still have an alternative to Microsoft

Because BSD isn't a "thing?"

~~~
fit2rule
I doubt it would've been a thing if we didn't have Linux to make the idea
popular to culture, but thats just my opinion.

~~~
vezzy-fnord
BSD has existed long before Linux was even a vague idea in someone's head, and
the free software BSDs were already springing up independently of Linux,
though it took until 1992 for 386BSD to be released. Patchkits soon followed
with FreeBSD and NetBSD popping up quickly.

Linux or not, it would have happened. The difference is that if the lawsuits
didn't encumber the community and create uncertainty, it could have been the
dominant Unix-like today.

I have no idea what the hell you mean by "Linux making the idea popular to
culture".

~~~
fit2rule
I've been there and aware of the situation since the beginning. BSD may have
been 'before Linux', but it wasn't the best-promoted set of the group of Unix
OS's .. it was _always_ easier to get Linux than BSD. If Linux wasn't doing
all the stupid shit that made people re-consider Unix as a personal operating
system, I don't think it the idea of Unix on the desktop would have gained as
much traction.

Anyway, this is all "what if" line of thought .. just my opinion. But I've
been a Linux user since the days of the minix-list, and a user of Unix-based
systems since 1980.

------
jmount
Wow. Interpreting this under the "hello world is often a demonstration of a
particular point" rubric ( [http://www.win-vector.com/blog/2008/02/hello-
world-an-instan...](http://www.win-vector.com/blog/2008/02/hello-world-an-
instance-rhetoric-in-computer-science/) ) it looks like Petzoid was trying to
demonstrate that a mere finite amount of code could launch a Window API
client. Large was, of course, undesirable- but he was trying to see if the API
costs were even bounded.

------
forca
I really miss the "old days" of programming. Things were simpler then. I
fondly remember the early 80s programming on a Commodore 64, then moving to
the early IBM machines and DOS.

Even though I favour a _nix environment, there is more sanity in Windows
programming circles methinks. I have been thinking about getting into some
.NET development these days and moving away from doing_ nix stuff, altho I
really love the BSDs.

~~~
moron4hire
It's pulling teeth to get 3rd party library developers to make anything up to
the standard of the BCL. A lot of times it feels like someone just copied a
Java library into C# and did a bunch of global text replaces until the
compiler stopped complaining. The BCL is very extensive, but if it's not
already in the BCL, .NET is a pain.

------
raverbashing
And then MS came up with MFC which was slightly better. But only slightly.

Borland had a better solution if I remember, in their C++ Builder thing.

Another "adventure" I had in Win32, trying to make a dynamic dialog box
(basically, selecting something in a list opened up a list of properties -
like the Preferences dialog box in most browsers). It was some time before I
figured out how to do it (there was a coordinate conversion needed)

~~~
bhouston
Borland has OWL:
[http://en.wikipedia.org/wiki/Object_Windows_Library](http://en.wikipedia.org/wiki/Object_Windows_Library)

Strangely it is still maintained by volunteers:
[http://sourceforge.net/projects/owlnext/](http://sourceforge.net/projects/owlnext/)

But it was always behind Microsoft's MFC in terms of features. And you had to
drop out of it for advanced stuff and then you had to spend a bunch of time
figuring out how it actually worked.

~~~
stormbrew
> And you had to drop out of it for advanced stuff and then you had to spend a
> bunch of time figuring out how it actually worked.

This was really no less true of MFC, and imo the OWL code was a lot cleaner
and easier to understand. In the end, though, they were both just wrappers
around the windows api.

But the GP seems to be referring to VCL, which is what came with
Delphi/C++Builder. One of the reasons OWL was usually behind MFC was that
Borland basically abandoned it and their mainline compiler products for the
Delphi line, and C++Builder was always a second-rate product behind Delphi as
well.

~~~
geoelectric
MFC was much more of a thin wrapper than OWL was, IIRC.

Microsoft concentrated on bringing MVC-enabling classes for application
development, and otherwise just basically wrapped the raw Windows API, whereas
Borland actually created an honest-to-gosh object library to represent the GUI
(and to an extent, provide a migration path from TurboVision, their DOS GUI
library).

VCL was even thicker still, having come from Delphi's rather successful
attempt to duplicate the Visual Basic VBX components in a highly-extensible
and more native way.

Like you hint at, it was kind of a weird fit for C++Builder, since Object
Pascal had somewhat different capabilities that they had to lay into CB making
it a little bit of a bastardized spinoff of C/C++.

.NET/C# was ultimately what came out of that heritage, after MS poached
Delphi's architect. I think it benefited from not claiming to be C++.

~~~
pjmlp
I read a story somewhere that MFC was originally much like OWL, but when
Microsoft gave it to their test groups they found it too OO was thus MFC as
thin layer was born.

The Afx prefix comes from this library.

------
CurtHagenlocher
From what I remember, the equivalent code in something like Toolbox or Xt
wasn't better or easier -- just different.

~~~
ultramancool
Quite amazing to see how Qt compares to this these days. Can accomplish this
in a few lines without any generated code or other nonsense.

~~~
wolfgke
Qt wraps both XLib and WinAPI. So the same argument can be brought for WinAPI,
too.

------
bluedino
I couldn't even imagine the breath of fresh air it must have been to have
worked with Windows programming in the 80's and then discovered something like
NeXTSTEP.

~~~
dugmartin
Coming from DOS programming where you had to draw your own "windows" using
using extended ASCII characters and listen for interrupts to handle mouse
clicks I thought Win32 API was awesome. I think NeXTSTEP would have blown my
mind if I had chance to touch a NeXT box.

~~~
protomyth
You spend a goodly amount of time looking at the interface builder and trying
to figure out why you did not have to add code to the button or subclass it.
There is a definite "wow" moment.

------
atburrow
Does anyone have a mirror? The link appears to be dead.

~~~
csixty4
[https://archive.today/dmmJI](https://archive.today/dmmJI)

------
megablast
> That version probably has as much relevance to real-life Windows programming
> as printf("hello world") has to real-life character-mode C programming.

A simple program has a lot of advantages, it shows you can actually compile
and run a program. When you have never done so before, there are 100s of
hurdles that regular developers would not even consider when starting out.

------
billforsternz
I remember back in the day being annoyed and frustrated that the two functions
in the canonical Petzold "Hello World" were WinMain() and WndProc(). "Why not
WinMain() and WinProc() ?" I used to silently scream. I must be getting more
mature because I am not quite so pedantic about these sorts of things these
days.

------
aurora72
With the Win32 API, we saw some innovative use of C in action, such as the
function pointers and the callback functions.

~~~
goalieca
What? Checkout the signature for the posix signal function. Notice the
function pointer?

[http://man7.org/linux/man-
pages/man2/signal.2.html](http://man7.org/linux/man-pages/man2/signal.2.html)

"Signals have been around since the 1970s Bell Labs Unix and have been more
recently specified in the POSIX standard." \--wikipedia

Basically, they're a software interrupt handler. Not too different from
assembly. I don't see why that would be innovative at all?

In fact, early C++ just compiled to C. You can write structs with function
pointers and vtables all in C if you wanted. People have been doing that since
the 80s.

------
bkeroack
I had that book ( _Programming Windows_ ) as a preteen. This is actually Win16
API programming--the event loop gives it away. This was before Windows had
preemptive multitasking (which came with Win95, IIRC). If you forgot to yield
at the bottom of the loop you'd lock up the whole OS.

Fun times.

------
nevster
As a unix/c coder in the early to mid 90's, the future seemed to be Windows
and I dreaded having to learn that gobbledegook. Then Java came along and I
never had to. Thank goodness.

~~~
goalieca
It's funny, but AbstractBaseFactoryLongName is less annoying than
LPSTERVOIDFOO _PACSCAL nonsense.

------
weddpros
It says "Service Unavailable"... Fun!

