My first job out of university was in a company that developed a GUI appication based on the Win32 C API. In fact, the product has been on the market for so long, that it's code had been a Win16 application in the past and pre-dated Win 3.1 (It is a product for a niche market, and had been the first Windows program on the market there, with all other software being MS-DOS Applications).
So, I came from university, had written Software during my master thesis with Qt, had some exposure to Gtk on my home PC a few years before, and I faced this obscure Win32 API, which looks ugly, appaling, antiquated and plainly awful.
But: Development was actually quite pleasant, and, while it didn't offer the flexibility of full-blown object oriented libraries like Gtk or Qt, it was amazingly good at getting stuff done. I wouldn't start a new project in it of course and it seems Microsoft has pretty much abandoned the API. But, I have to admit that I can see how it served Microsoft and its developer community well for a few years. In fact, a lot of things in there where quite thoughtful and I can still appreciate the non-bloaty way of doing things, if I see how many processes and memory an electron app uses that doesn't do much more than what a simple Win32 program does.
No they havent. Everything else in Windows land is just built on top of it.
I also made some Win32 development at one point. The programs made using only Win32 have a very snappy and light weight feel to them that is very nice. It is fairly low level and more for the machine than for humans. But I doubt you can have both of these things.
I started with a bit of Win16 and then moved to Win32, and don't really see why it gets a lot of hate; it's not perfect, but it looks like it does exactly what it was meant to do, and does it well. Perhaps it's because all of the tiny and fast applications I've used in the past were pure Win32. You can do a lot with it in only a few KB or tens of KB. In contrast, I don't find all the other multi-megabyte UI frameworks appealing.
> Now in Windows 10, User32/GDI is deprecated and obsolete for high-performance applications (and it’s really slow too after they axed GDI hardware acceleration in Vista), but there isn’t a single replacement, instead there’s like 5 of 6 - all incompatible with each other. While it’s true that it shouldn’t matter because OLE objects were rendered to their own separate hWnd, consider that the new UWP system doesn’t use hWnds, and frameworks like WPF have “air gap” issues with rendering their content overlaying another hWnd and often resort to hacks using window content blitting which drastically hurts performance (as you need to blit to/from RAM, instead of keeping it all in VRAM).
> and I faced this obscure Win32 API, which looks ugly, appalling, antiquated and plainly awful.
As you point out, the code you had to deal with was actually written using the Win16 API.
That Win16 API dates back to the first ever version of Windows which takes you back to a pre 1990 era.
As someone who did work on both Win16 and Win32, what I found amazing is Microsoft designed Win32 such that you could take your Win16 code, do a minimal number of changes and recompile that code for Win32.
That meant you could take your old Win16 code designed for a now obsolete version of Windows, do a minimal number of tweaks, recompile the code using a 32 bit compiler and have it running on the most resent 32 bit versions of Windows.
It was my first experience of a major coding upgrade and it was the last such upgrade that was anywhere near as simple as that upgrade.
WTL is a great attempt at creating a close-to-zero-cost C++ library around the Win32 UI architecture. I use it sometimes even today, and it's not bad considering the age of the foundations.
There are other win32 APIs that are quite interesting:
* the networking API (native proactor servers, something that Linux doesn't have yet AFAIK)
* the security and process API, which I had the pleasure to explore recently, in order to contribute to an open source server that launches a single user server for a connected user, under the user's profile. The CreateProcessAsUser function and its interactions with user authorization tokens is quite something.
I've been playing around with VMS on my MicroVAX 3800 lately, and between that and getting into Windows internals I'm just super fascinated by the difference in feel, when it comes to what the system-level APIs provide, of these highly-integrated, enterprise-oriented operating systems versus the *nix family. Particularly how robust things like user identity management are.
Not saying it's better or worse, of course. Just interesting.
I'd really love to play around with something as hyper-integrated as z/OS or something. So if anyone's got an old ES/9000 or something kicking around that they wouldn't mind sending me, let me know.
Windows via C/C++ is another one in this area. Windows Kernel Programming by Pavel Yosifovich is a recent book, but it goes much lower-level.
Windows Internals is pretty good, but it's not a programming book per se. It's trying to document the design of the OS, help with troubleshooting when you don't have the source to the OS, and help developers understand the high-level concepts.
I/O completion ports? Those are great and I wish Linux had a similar API. Epoll doesn't fully solve the asynchronous I/O problem since files always have data available to read. The kernel should be able to do reads and writes in the background while my program does something else.
My favorite Win32 tutorial is by Bartosz Milewski, I found it as a series of posts on his CodeCoop website (https://web.archive.org/web/20110129015721/http://www.codeco... ), that were later incorporated into his book "C++ in Action" (also findable online).
He uses C++ to wrap every resource acquisition in a constructor and every release of a resource in the corresponding destructor, so that by allocating new objects on the stack you avoid a whole swath of memory management errors. This was my first encounter with RAII (not sure if he calls it that), and it seems a particularly elegant way to write C++ and to make the raw Win32 C API a lot less scary.
Windows development team now has an internal C++ library used inside Windows source code to do similar things, which was recently made public and open source on GitHub: https://github.com/Microsoft/wil/wiki
I cut my teeth on making the jump from turbo pascal programs to GUI via the Win32 API. Its "rawness" felt fun, i.e. slinging around "long" pointers to stuff and big event handling switch statement state machines. As long as you didn't misbehave in the message loop, you could just kinda tinker endlessly. As both the UI evolved to many more complicated controls and the toolset was getting more abstract, I'd always find myself asking "dangit! i wish i could just get the UUID for the control that does the fizzywizzybizbang control that i see in Excel here!" Maybe that mindset is akin to a modern UI developer buried in quirksmode.org and their browser console debugger.
I wrote an emulator for an old 8080 microcomputer in 1999 or so using the Win32 API. First I bought the Petzold book, but as my program grew there were still a lot of API issues that Petzold simply couldn't fit into a book of that already impressive size. Then I got a "Win32 API Bible" type of book, then another from a different author, then I collected the multi-volume official win32 api books from microsoft, ..., and ended up with more than two linear feet of books.
And yet development was still painful. Sometimes I would want to add a feature and I'd be amazed that in 30 minutes it was done, but far more often there would be something that didn't work and I'd literally spend two weeks of free time changing the order of state setting calls, or setting state that the books didn't say needed to be set but I had seen other source code do it, reading other program source, searching online, asking in forums...
The last release was in 2005. I'd like to work on it more, but there is no way I'm ever going back to that codebase.
Aaaaah the memory of making the an efficient self extracting archive. What is brilliant about the idea is that even to this very day many "new ideas" live around same event loop idea.
Funny you mention that, but one of the better pieces of MFC related advice I read was to have a single central location for computing UI element states. It did feel a lot like React does these days (albeit with less sophistication in the underlying 'DOM model' back then, and nothing like React's differencing stuff.)
To me at least, if you change the terms in that article, it looks a lot like the arguments in favor of moving away from ad hoc jQuery spaghetti and to React's single global rendering pass.
Ah the Win32 API. Oddly, I learned quite a lot of object oriented fundamentals doing C++ Win32 programming indirectly using Paul DiLascia's excellent book "Windows++"[1]. One of the few 90s era programming books I still have.
Nice! I learned programming using "Iczelion's Win32ASM tutorials" (archived here: http://www.interq.or.jp/chubu/r6/masm32/masm006.html ). Same API, but in assembler. The terminology and variable names look very familiar
Ah, the classic approach from WinProc() upwards. While I think it might be useful to work through this once, since then you understand what a message loop is and how it dispatches to controls, but for almost all practical purposes if you want to build a classic app it's easier to do it in C++ with MFC/ATL. Or even C#/Winforms.
I note this version uses LPSTR rather than LPTSTR; perhaps it predates the UNICODE fiasco and the brief window where UCS-2 seemed like a good idea.
Note that if you decide to use MFC you still need to know Win32. A common misconception and source of frustration about MFC is that it is a layer over Win32 or that it somehow replaces it, which is not the case and if you (royal you here) expect that you'll be disappointed. MFC is a helper framework build with Win32 and C++ to ease some bits of making a Windows application, but even for the most basic stuff you are still dealing with Win32. It isn't a "Win32" or "MFC" situation, it is a "just Win32" or "Win32 and MFC" situation. If you don't like Win32 or feel it is too hard, chances are MFC wont change your opinion either (though you can like Win32 and dislike MFC - after all it has been left to rot).
I have done quite a bit of Win32 in my life and I think even to this day this knowledge helps me diagnose issues with UI performance of browsers and other applications.
I'm not much of a windows user so sorry if it's a dumb question, but don't newer UI libraries like UWP and WinUI just act as wrappers around Win32 functions?
Like if I wrote a UWP/WinUI/etc program and disassembled it, wouldn't it just call Win32 functions in some system dll to do things like create windows, receive messages etc?
Win32 was complicated. Lots of cleanup work. No forced structure. Combine that with having to use C, and the amount of low-skilled porogrammers out there, you could really see why there was so much terrible Windows software out there.
Learning Windows programming gave me so much insight to programs crashing and all the graphical bugs, beause I had caused them all in my own porograms before.
Win32, especially when it comes to GUI programming, is one of the worst APIs out there.
MFC is also quite bad because of huge abstraction leakages; it fills like Win32 with bolted on classes.
It seems like Win32 happened a bit by accident, a bit by overengineering and a bit by Microsoft's attempt to lock everyone to their 'special' development environments, which did not include C as a conscious choice by Microsoft.
> Win32, especially when it comes to GUI programming, is one of the worst APIs out there.
It's also one of the first. Win32's origins extend back over 35 years and start on machines with a tiny fraction of the capability of even the smallest of today's modern PC's. It was also built with a different set of tradeoffs and in a radically different culture of software development. (Most modern developers hadn't been born at the time of it's initial design, and most of the people who were actively writing this stuff in the early-to-mid 1980's, I'm sure have moved on. 35 years is pretty much a career.)
> MFC is also quite bad because of huge abstraction leakages; it fills like Win32 with bolted on classes.
That's pretty much what it was... by design. There was a more object-oriented library that Microsoft developed, prior to MFC. They tested it on developers that had essentially just come up to speed on the (then-new) Win16 API, who all complained about having to ascend another learning curve for a fancy object oriented language and framework. Microsoft's reaction was to drop the older framework (referred to as AFX) and develop MFC as a thin wrapper around Win16. (This is part of why there are AFX prefixes scattered throughout the MFC codebase.... it's a legacy of the earlier framework.)
Even then, early versions of MFC had some utility, mainly around making things more type safe. Because it bound C++ instances to Window system instances, it made it easy to attach user data structures to UI components. (Otherwise, you were worrying about window or class words, which were Microsoft's original approach to that problem and used by MFC under the hood.) MFC also handled parsing of window message arguments. Win16 also sent messages with just a word and a long, when what you really might need is a set of mouse button flags and an x/y position or something. MFC helped with that too, by 'cracking' the message arguments into something closer to what you'd expect.
(To this day, Win32 documentation still includes instructions on parsing WPARAMS, etc.
MFC was built for a reason. To provide that doc/view/OLE GUI. If you wander too far away from that it becomes well, lets just say, 'interesting' to use. I would many times just include MFC just to get some of those helper classes though. CString was way ahead of the game. C++ did not get a std::string standard that most people could use until well into the 2000s. Its database classes were good in a pinch to abstract away the nitpicky junk in ODBC. Then C++ took a 15 year sideways journey into getting templates right. During that time MS created C# and basically took away any reasons to really use MFC and C++ on windows for business applications.
It's kind of interesting, when you compare WinAPI to classic Mac Toolbox, how incredibly similar their core concepts are.
Especially when you take into account that the first GUI application MS made was Excel for the Macintosh. And then they more-or-less wrote Windows as a runtime environment for porting Excel to PCs.
Not getting into any of that old-school MS-stole-the-GUI flamewar business, I just think it's genuinely historically interesting to note the parallels when you play with each.
A big difference is that Windows used inversion of control. You give the system a callback and it calls you with an event. The Mac toolbox was written with the idea that each application had full control of the machine. This made multiprogramming ... interesting. On the Mac, for example, when you pressed down on a button, it would go into a mode where the button’s code would take all the events until the mouseUp event.
The design of Win32 is incredibly close to the design of Win16 and since Win16 dates back to early 90's you need to comparing it to GUI programming layers of that same era.
So the question is, back then was there any better GUI programming layers?
And the answer is yes, there was actually an API that was better and it was called OS/2.
At that time Microsoft was in a partnership with IBM to develop OS/2.
However, when the partnership fell apart, Microsoft just took big chunks of that OS/2 API and created a sub par version and called it the Windows API.
> However, when the partnership fell apart, Microsoft just took big chunks of that OS/2 API and created a sub par version and called it the Windows API.
Microsoft learned from the mistakes IBM forced on them and did a better job. Right off the top of my head:
* IBM forced 80286 compatibility in an 80386 world.
* IBM forced incompatibility between Windows and OS/2 for the sake of preserving their mainframe graphics API's.
* OS/2 had a single messaging queue for the whole desktop.
* OS/2 was tied to the underlying hardware to the extent of being written partly in assembler.
OS/2 was great... I loved OS/2 2.0 in particular (and I worked for IBM testing OS/2 LAN Server for a summer)... but IBM had no idea how to address the market and no sense of how fast it was evolving.
> It seems like Win32 happened a bit by accident, a bit by overengineering and a bit by Microsoft's attempt to lock everyone to their 'special' development environments, which did not include C as a conscious choice by Microsoft.
Maybe I just haven't had my coffee yet, but I'm not understanding what this is supposed to mean.
I don't understand this either. They've always offered C. In many ways Win32 and NT are as much a ""C operating system"" as UNIX. The only "special development environment" might be Visual Basic.
After the p-machine era, MS was all in on C. They had some technical reason for preferring the pascal calling convention, like saving a few bytes of program text.
Why on earth would anyone want to learn Win32 in 2019? It's horribly unproductive.
I've been doing Win32 (also called "Petzold-style") since 1995, and am pleased to say I'm converting to Qt for multi-platform capability.
When I look at the dreck necessary to create a dialog box in Win32, and compare to more modern frameworks, it's like milking a cow vs. buying milk at the store. Sure, you're "into the fundamentals", but is that really how you want to spend your time?
The Win32 API is on life-support. Microsoft will maintain backwards compatibility for legacy apps of course, but learning Win32 for new development doesn't seem like a good investment (unless, of course, you want to get a job maintaining a legacy Win32 app).
Because sometimes it's nice not to have to drag in a large dependency such as Qt. For example PuTTY.exe is only around 500kb and that's all there is to it.
Sometimes, when working on higher-level code, you have to dig into the plumbing layer. For example, I've been writing low-level GPU surface code lately, since SDL and the like are not suitable for our use case (web browsers). There's no getting around message loops and HWNDs if you want to put something on the screen. So it's useful to know the internals, even if you'd never want to write an app that way.
My first job out of university was in a company that developed a GUI appication based on the Win32 C API. In fact, the product has been on the market for so long, that it's code had been a Win16 application in the past and pre-dated Win 3.1 (It is a product for a niche market, and had been the first Windows program on the market there, with all other software being MS-DOS Applications).
So, I came from university, had written Software during my master thesis with Qt, had some exposure to Gtk on my home PC a few years before, and I faced this obscure Win32 API, which looks ugly, appaling, antiquated and plainly awful.
But: Development was actually quite pleasant, and, while it didn't offer the flexibility of full-blown object oriented libraries like Gtk or Qt, it was amazingly good at getting stuff done. I wouldn't start a new project in it of course and it seems Microsoft has pretty much abandoned the API. But, I have to admit that I can see how it served Microsoft and its developer community well for a few years. In fact, a lot of things in there where quite thoughtful and I can still appreciate the non-bloaty way of doing things, if I see how many processes and memory an electron app uses that doesn't do much more than what a simple Win32 program does.
"Microsoft has pretty much abandoned the API"
No they havent. Everything else in Windows land is just built on top of it.
I also made some Win32 development at one point. The programs made using only Win32 have a very snappy and light weight feel to them that is very nice. It is fairly low level and more for the machine than for humans. But I doubt you can have both of these things.
No they havent. Everything else in Windows land is just built on top of it.
There were even some articles recently about that:
https://news.ycombinator.com/item?id=19873198
I started with a bit of Win16 and then moved to Win32, and don't really see why it gets a lot of hate; it's not perfect, but it looks like it does exactly what it was meant to do, and does it well. Perhaps it's because all of the tiny and fast applications I've used in the past were pure Win32. You can do a lot with it in only a few KB or tens of KB. In contrast, I don't find all the other multi-megabyte UI frameworks appealing.
9 replies →
> Now in Windows 10, User32/GDI is deprecated and obsolete for high-performance applications (and it’s really slow too after they axed GDI hardware acceleration in Vista), but there isn’t a single replacement, instead there’s like 5 of 6 - all incompatible with each other. While it’s true that it shouldn’t matter because OLE objects were rendered to their own separate hWnd, consider that the new UWP system doesn’t use hWnds, and frameworks like WPF have “air gap” issues with rendering their content overlaying another hWnd and often resort to hacks using window content blitting which drastically hurts performance (as you need to blit to/from RAM, instead of keeping it all in VRAM).
https://news.ycombinator.com/item?id=21450112
I may be totally off-base, here, but isn't WPF independent from Win32?
2 replies →
> and I faced this obscure Win32 API, which looks ugly, appalling, antiquated and plainly awful.
As you point out, the code you had to deal with was actually written using the Win16 API.
That Win16 API dates back to the first ever version of Windows which takes you back to a pre 1990 era.
As someone who did work on both Win16 and Win32, what I found amazing is Microsoft designed Win32 such that you could take your Win16 code, do a minimal number of changes and recompile that code for Win32.
That meant you could take your old Win16 code designed for a now obsolete version of Windows, do a minimal number of tweaks, recompile the code using a 32 bit compiler and have it running on the most resent 32 bit versions of Windows.
It was my first experience of a major coding upgrade and it was the last such upgrade that was anywhere near as simple as that upgrade.
> and have it running on the most resent 32 bit versions of Windows.
Or 64-bit, for that matter.
3 replies →
Over the decades a lot of win32 code was written. You can expect that all changes from 1995 on were win32 API only
WTL is a great attempt at creating a close-to-zero-cost C++ library around the Win32 UI architecture. I use it sometimes even today, and it's not bad considering the age of the foundations.
Do you use it in open source projects of commercial applications? If the former, I'd be interested in looking at it.
I think xplorer² is written using WTL.
Yeah. It was a very good start but as usual MS abandoned it before it could get really good.
3 replies →
Abandoned? Every single Windows application uses it, regardless of the language, framework or anything else.
It is the equivalent to Linux syscalls, since it is the lowest stable layer in Windows land.
This is strictly about the win32 GUI API.
There are other win32 APIs that are quite interesting:
* the networking API (native proactor servers, something that Linux doesn't have yet AFAIK)
* the security and process API, which I had the pleasure to explore recently, in order to contribute to an open source server that launches a single user server for a connected user, under the user's profile. The CreateProcessAsUser function and its interactions with user authorization tokens is quite something.
I've been playing around with VMS on my MicroVAX 3800 lately, and between that and getting into Windows internals I'm just super fascinated by the difference in feel, when it comes to what the system-level APIs provide, of these highly-integrated, enterprise-oriented operating systems versus the *nix family. Particularly how robust things like user identity management are.
Not saying it's better or worse, of course. Just interesting.
I'd really love to play around with something as hyper-integrated as z/OS or something. So if anyone's got an old ES/9000 or something kicking around that they wouldn't mind sending me, let me know.
Also, there aren't many books about those (compared to e.g. books about the *nix API). I only know of Hart's Windows System Programming.
A very well working combo is "Windows Internals" for the high-level view + MSDN docs for the details.
Windows via C/C++ is another one in this area. Windows Kernel Programming by Pavel Yosifovich is a recent book, but it goes much lower-level.
Windows Internals is pretty good, but it's not a programming book per se. It's trying to document the design of the OS, help with troubleshooting when you don't have the source to the OS, and help developers understand the high-level concepts.
1 reply →
You don't need many books on it. There's Petzold.
3 replies →
> native proactor servers
I/O completion ports? Those are great and I wish Linux had a similar API. Epoll doesn't fully solve the asynchronous I/O problem since files always have data available to read. The kernel should be able to do reads and writes in the background while my program does something else.
My favorite Win32 tutorial is by Bartosz Milewski, I found it as a series of posts on his CodeCoop website (https://web.archive.org/web/20110129015721/http://www.codeco... ), that were later incorporated into his book "C++ in Action" (also findable online).
He uses C++ to wrap every resource acquisition in a constructor and every release of a resource in the corresponding destructor, so that by allocating new objects on the stack you avoid a whole swath of memory management errors. This was my first encounter with RAII (not sure if he calls it that), and it seems a particularly elegant way to write C++ and to make the raw Win32 C API a lot less scary.
Windows development team now has an internal C++ library used inside Windows source code to do similar things, which was recently made public and open source on GitHub: https://github.com/Microsoft/wil/wiki
I cut my teeth on making the jump from turbo pascal programs to GUI via the Win32 API. Its "rawness" felt fun, i.e. slinging around "long" pointers to stuff and big event handling switch statement state machines. As long as you didn't misbehave in the message loop, you could just kinda tinker endlessly. As both the UI evolved to many more complicated controls and the toolset was getting more abstract, I'd always find myself asking "dangit! i wish i could just get the UUID for the control that does the fizzywizzybizbang control that i see in Excel here!" Maybe that mindset is akin to a modern UI developer buried in quirksmode.org and their browser console debugger.
I wrote an emulator for an old 8080 microcomputer in 1999 or so using the Win32 API. First I bought the Petzold book, but as my program grew there were still a lot of API issues that Petzold simply couldn't fit into a book of that already impressive size. Then I got a "Win32 API Bible" type of book, then another from a different author, then I collected the multi-volume official win32 api books from microsoft, ..., and ended up with more than two linear feet of books.
And yet development was still painful. Sometimes I would want to add a feature and I'd be amazed that in 30 minutes it was done, but far more often there would be something that didn't work and I'd literally spend two weeks of free time changing the order of state setting calls, or setting state that the books didn't say needed to be set but I had seen other source code do it, reading other program source, searching online, asking in forums...
The last release was in 2005. I'd like to work on it more, but there is no way I'm ever going back to that codebase.
Ah, WinProg. The chatroom that built the world. [0] Good times, huhu.
[0] https://www.wired.com/2005/11/chat-room-that-built-the-world...
Long time I haven't seen the IRC huhu.
Is it still active? Actually I followed the link to winprog so I guess it's still active.
The irc channel is dead. But most of us mentioned in that article are still in another irc channel together and talk very frequently.
6 replies →
Aaaaah the memory of making the an efficient self extracting archive. What is brilliant about the idea is that even to this very day many "new ideas" live around same event loop idea.
hahahah. React? :)
Funny you mention that, but one of the better pieces of MFC related advice I read was to have a single central location for computing UI element states. It did feel a lot like React does these days (albeit with less sophistication in the underlying 'DOM model' back then, and nothing like React's differencing stuff.)
http://www.flounder.com/controls.htm
To me at least, if you change the terms in that article, it looks a lot like the arguments in favor of moving away from ad hoc jQuery spaghetti and to React's single global rendering pass.
Ah the Win32 API. Oddly, I learned quite a lot of object oriented fundamentals doing C++ Win32 programming indirectly using Paul DiLascia's excellent book "Windows++"[1]. One of the few 90s era programming books I still have.
[1]https://web.archive.org/web/20090606220454/http://www.dilasc...
Nice! I learned programming using "Iczelion's Win32ASM tutorials" (archived here: http://www.interq.or.jp/chubu/r6/masm32/masm006.html ). Same API, but in assembler. The terminology and variable names look very familiar
Ah, the classic approach from WinProc() upwards. While I think it might be useful to work through this once, since then you understand what a message loop is and how it dispatches to controls, but for almost all practical purposes if you want to build a classic app it's easier to do it in C++ with MFC/ATL. Or even C#/Winforms.
I note this version uses LPSTR rather than LPTSTR; perhaps it predates the UNICODE fiasco and the brief window where UCS-2 seemed like a good idea.
Note that if you decide to use MFC you still need to know Win32. A common misconception and source of frustration about MFC is that it is a layer over Win32 or that it somehow replaces it, which is not the case and if you (royal you here) expect that you'll be disappointed. MFC is a helper framework build with Win32 and C++ to ease some bits of making a Windows application, but even for the most basic stuff you are still dealing with Win32. It isn't a "Win32" or "MFC" situation, it is a "just Win32" or "Win32 and MFC" situation. If you don't like Win32 or feel it is too hard, chances are MFC wont change your opinion either (though you can like Win32 and dislike MFC - after all it has been left to rot).
I have done quite a bit of Win32 in my life and I think even to this day this knowledge helps me diagnose issues with UI performance of browsers and other applications.
I'm not much of a windows user so sorry if it's a dumb question, but don't newer UI libraries like UWP and WinUI just act as wrappers around Win32 functions?
Like if I wrote a UWP/WinUI/etc program and disassembled it, wouldn't it just call Win32 functions in some system dll to do things like create windows, receive messages etc?
Not sure about others, but e.g. WinForms is a wrapper for Win32 controls. WPF has its own rendering.
Yes, for the most part. Some of them use Win32 functions but do their own drawing, like the newer opacity parts in the UWP settings menu.
Win32 was complicated. Lots of cleanup work. No forced structure. Combine that with having to use C, and the amount of low-skilled porogrammers out there, you could really see why there was so much terrible Windows software out there.
Learning Windows programming gave me so much insight to programs crashing and all the graphical bugs, beause I had caused them all in my own porograms before.
Win32, especially when it comes to GUI programming, is one of the worst APIs out there.
MFC is also quite bad because of huge abstraction leakages; it fills like Win32 with bolted on classes.
It seems like Win32 happened a bit by accident, a bit by overengineering and a bit by Microsoft's attempt to lock everyone to their 'special' development environments, which did not include C as a conscious choice by Microsoft.
> Win32, especially when it comes to GUI programming, is one of the worst APIs out there.
It's also one of the first. Win32's origins extend back over 35 years and start on machines with a tiny fraction of the capability of even the smallest of today's modern PC's. It was also built with a different set of tradeoffs and in a radically different culture of software development. (Most modern developers hadn't been born at the time of it's initial design, and most of the people who were actively writing this stuff in the early-to-mid 1980's, I'm sure have moved on. 35 years is pretty much a career.)
> MFC is also quite bad because of huge abstraction leakages; it fills like Win32 with bolted on classes.
That's pretty much what it was... by design. There was a more object-oriented library that Microsoft developed, prior to MFC. They tested it on developers that had essentially just come up to speed on the (then-new) Win16 API, who all complained about having to ascend another learning curve for a fancy object oriented language and framework. Microsoft's reaction was to drop the older framework (referred to as AFX) and develop MFC as a thin wrapper around Win16. (This is part of why there are AFX prefixes scattered throughout the MFC codebase.... it's a legacy of the earlier framework.)
Even then, early versions of MFC had some utility, mainly around making things more type safe. Because it bound C++ instances to Window system instances, it made it easy to attach user data structures to UI components. (Otherwise, you were worrying about window or class words, which were Microsoft's original approach to that problem and used by MFC under the hood.) MFC also handled parsing of window message arguments. Win16 also sent messages with just a word and a long, when what you really might need is a set of mouse button flags and an x/y position or something. MFC helped with that too, by 'cracking' the message arguments into something closer to what you'd expect.
(To this day, Win32 documentation still includes instructions on parsing WPARAMS, etc.
https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-m... )
I think it's one of the best, because it's also the most efficient way to write GUIs on Windows. Definitely not overengineered.
MFC is horrible, I agree. I've had to work with it and the indirection just gets in the way and creates bloat. That is overengineering.
MFC was built for a reason. To provide that doc/view/OLE GUI. If you wander too far away from that it becomes well, lets just say, 'interesting' to use. I would many times just include MFC just to get some of those helper classes though. CString was way ahead of the game. C++ did not get a std::string standard that most people could use until well into the 2000s. Its database classes were good in a pinch to abstract away the nitpicky junk in ODBC. Then C++ took a 15 year sideways journey into getting templates right. During that time MS created C# and basically took away any reasons to really use MFC and C++ on windows for business applications.
4 replies →
It's kind of interesting, when you compare WinAPI to classic Mac Toolbox, how incredibly similar their core concepts are.
Especially when you take into account that the first GUI application MS made was Excel for the Macintosh. And then they more-or-less wrote Windows as a runtime environment for porting Excel to PCs.
Not getting into any of that old-school MS-stole-the-GUI flamewar business, I just think it's genuinely historically interesting to note the parallels when you play with each.
A big difference is that Windows used inversion of control. You give the system a callback and it calls you with an event. The Mac toolbox was written with the idea that each application had full control of the machine. This made multiprogramming ... interesting. On the Mac, for example, when you pressed down on a button, it would go into a mode where the button’s code would take all the events until the mouseUp event.
2 replies →
The design of Win32 is incredibly close to the design of Win16 and since Win16 dates back to early 90's you need to comparing it to GUI programming layers of that same era.
So the question is, back then was there any better GUI programming layers?
And the answer is yes, there was actually an API that was better and it was called OS/2.
At that time Microsoft was in a partnership with IBM to develop OS/2.
However, when the partnership fell apart, Microsoft just took big chunks of that OS/2 API and created a sub par version and called it the Windows API.
> However, when the partnership fell apart, Microsoft just took big chunks of that OS/2 API and created a sub par version and called it the Windows API.
Microsoft learned from the mistakes IBM forced on them and did a better job. Right off the top of my head:
* IBM forced 80286 compatibility in an 80386 world.
* IBM forced incompatibility between Windows and OS/2 for the sake of preserving their mainframe graphics API's.
* OS/2 had a single messaging queue for the whole desktop.
* OS/2 was tied to the underlying hardware to the extent of being written partly in assembler.
OS/2 was great... I loved OS/2 2.0 in particular (and I worked for IBM testing OS/2 LAN Server for a summer)... but IBM had no idea how to address the market and no sense of how fast it was evolving.
I'm pretty sure it is the other way around, the OS/2 GUI (Presentation Manager) API is a cleaned up version of the Windows 2.x API.
6 replies →
> It seems like Win32 happened a bit by accident, a bit by overengineering and a bit by Microsoft's attempt to lock everyone to their 'special' development environments, which did not include C as a conscious choice by Microsoft.
Maybe I just haven't had my coffee yet, but I'm not understanding what this is supposed to mean.
I don't understand this either. They've always offered C. In many ways Win32 and NT are as much a ""C operating system"" as UNIX. The only "special development environment" might be Visual Basic.
1 reply →
After the p-machine era, MS was all in on C. They had some technical reason for preferring the pascal calling convention, like saving a few bytes of program text.
Why on earth would anyone want to learn Win32 in 2019? It's horribly unproductive.
I've been doing Win32 (also called "Petzold-style") since 1995, and am pleased to say I'm converting to Qt for multi-platform capability.
When I look at the dreck necessary to create a dialog box in Win32, and compare to more modern frameworks, it's like milking a cow vs. buying milk at the store. Sure, you're "into the fundamentals", but is that really how you want to spend your time?
> Why on earth would anyone want to learn Win32 in 2019?
Because it's the native API on the most common desktop OS?
The Win32 API is on life-support. Microsoft will maintain backwards compatibility for legacy apps of course, but learning Win32 for new development doesn't seem like a good investment (unless, of course, you want to get a job maintaining a legacy Win32 app).
2 replies →
Because sometimes it's nice not to have to drag in a large dependency such as Qt. For example PuTTY.exe is only around 500kb and that's all there is to it.
Sometimes, when working on higher-level code, you have to dig into the plumbing layer. For example, I've been writing low-level GPU surface code lately, since SDL and the like are not suitable for our use case (web browsers). There's no getting around message loops and HWNDs if you want to put something on the screen. So it's useful to know the internals, even if you'd never want to write an app that way.
Probably most people wanting to learn Win32 in 2019 have inherited a legacy codebase too large to convert.
Personally I work in wxWidgets but occasionally it's useful to dig into wxWidgets's internals which are (for the Windows version) written in Win32.
yes