Win32 API Topic (Raw Windows C++ ftw!)

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

KnightExemplar
Posts: 5494
Joined: Sun Dec 26, 2010 1:58 pm UTC

Win32 API Topic (Raw Windows C++ ftw!)

Postby KnightExemplar » Sun Apr 27, 2014 5:16 am UTC

I've grown interested in Win32 programming recently. Like many from college, I've only had experience with Linux-based systems. It has been quite interesting seeing how different Win32 programming is. Unlike the status-quo however, I'm interested in the low-level stuff, so I'm making this topic for everyone who might be interested in this topic. I myself am roughly in the beginner stage of this exploration. So this topic is as much a reference for me, as it is for anyone else out there who might find it useful. :wink:

The Win32 API is the oldest Windows API in existence. Win32 itself originated in Windows95, although it was heavily based upon earlier APIs from 3.1 and earlier. Nonetheless, the Win32 API has received regular updates... growing ever larger. Naturally, some parts of the Win32 API are so old that they are irrelevant, while other parts of the API have been introduced as late as Windows 8.1.

Here's a brief overview of the topics I find interesting in the Win32 API. For a complete listing, browse the MSDN documentation yourself!

Important Win32 Legacy stuff (Vista and older):
Windows (Win95 and older):
The Window, the signature GUI interface which gave "Windows" its name. Everything you can see in Windows is a Window. Buttons are a kind of window. The big programs with the little "x" in the top right corner are windows. Moving a mouse or typing on the keyboard sends messages to Windows. Anyone who wishes to learn about how Windows works needs to start with fully understanding how the "window" works. Believe it or not, very little has changed with the core Window API.

COM (Ancient)
COM is Microsoft's language-neutral Object-Oriented Application Binary Interface from 1988. Chances are, if there is an Object-Oriented library in Windows, it will speak through COM. DirectX for example is all composed of calls to COM objects. Similarly, if you are going to pass an "object" to a library call, you should expect to pass in a COM object (ie: implements IUnknown). This isn't an "API" per se, but is instead a Binary Interface that a lot of libraries use.

TabletPC API (WinXP Tablet Edition / Windows Vista)
For the most part, stylus input is captured in a datatype called "ink". "Ink" is composed of strokes (pen-down to pen-up), and strokes are composed of points, each point can have a pressure value associated with it. The Windows Tablet API provides a way to process Ink, convert Ink into text (handwriting recognition), or convert ink into gestures. RealTimeStylus is a good starting point for Windows Tablet stuff.

Direct3D
The low-level 3d API of choice for games on the Windows platform.

Direct2D (Windows Vista SP2 / Windows 7)
The low-level 2D API of choice for modern Windows applications. Because modern GPUs are designed to run Direct3D code efficiently, all modern (Windows7+) APIs are built on top of Direct3D. Direct2D is no exception. Fortunately, the Direct2D API is _MUCH_ easier to understand than Direct3D. To understand Fortunately, you don't need to understand Direct3D to use the modern APIs... but just keep this fact in mind. Modern computers will perform Affine Transformations more efficiently than a "Bit-Blit".

The older GDI interface remains compatible with Direct2D.

Interesting Windows7 APIs

WM_Touch
Believe it or not, Windows7 is fully touch ready. Few applications support touch very well, but yes, the APIs exist. Multi-touch, Gestures, Panning, Inertia... everything you'd expect from an iPhone or Android actually exists in Windows7. Windows8 provides an easier API to use... Nonetheless, if you are targeting Windows7 touch systems, WM_Touch is the way to go.

Windows Ribbon Framework (Windows Vista SP2 Compatible)
The Windows Ribbon is a XAML-based system that honestly is much better to use than "menus" and "toolbars". I think its overall a usability win. This COM-based library will allow you to add Ribbons to your applications. Ribbons have a bit of "ramp up", in that you'll have to use a XAML-like language to build Ribbons, use the UICC compiler to create your .h file, resource, and ribbon binary. Then, you have to include those files, create COM objects to receive commands from the Ribbon... and COM objects to manipulate the Ribbon's different states.

Despite their complexity, it is clear to me that the Windows Ribbon is the way of the future. Its not like the magic commands in your resource files that create menus is super-simple either.

The Open Source Tool RibbonExplorer will be useful to you when creating Ribbons of your own. I found the SimpleRibbon example easiest to follow. (And unlike many other examples, this one will work in Visual Studio Express... no need for ATL or MFC libraries!)

Interesting Windows8 APIs:
The best "demo" for the new Windows8 API is honestly... the Windows8 Start Screen. Yeah yeah yeah, you don't like it. Hell, most people don't seem to like it. But honestly, play around with it a bit. Notice that it can accept Mouse, Stylus, OR Touch input seamlessly. Notice that Touch, Stylus, and Mouse are differentiated from each other (and its not some dumb emulation layer). Notice that you can Pan and zoom the Start Screen with your left-hand, while grabbing tiles with your right hand. All of this can be accomplished with a combination of Windows8 APIs... on the desktop with raw C++ code.

WM_Pointer
WM_Pointer is a replacement for WM_Mouse, WM_Touch, and also handles Stylus inputs. With a single Messaging structure, you can receive Mouse, Pen, and touch inputs. This should be the messaging API of choice for all applications that are willing to run on Windows8 and later. Unfortunately, WM_Pointer is not as well documented as one would hope. A better introduction into this API is the 2013 video from Microsoft's "BUILD convention".

Long story short, whenever a Stylus, Mouse, or Touch event occurs, WM_Pointer messages will be sent to your window. The message will include the x/y coordinate, as well as any other data (pressure, left click, right click)... and will also keep track of which pointers are which. (IE: If the user places his thumb first on the screen, and then places his index finder later... WM_Pointer will be able to differentiate from the first finger from the 2nd finger). While WM_Pointer is clearly superior to WM_Mouse and WM_Touch, the WinXP "RealTimeStylus" API should be used for more advanced stylus input. If you want basic "Mouse Emulation" in your application, WM_Pointer is good enough for basic stylus commands. But if you want handwriting recognition, Ink objects that can be copy/pasted into the clipboard, or other advanced stylus features... look at the WinXP TabletPC APIs.

Interaction Context
Interaction Context provides you an object that converts WM_Pointer messages into gestures. You can have multiple Interaction Contexts going on at the same time. For example, if your touchscreen supports 10-finger touch, the user can pan and zoom 5 different objects with all 10 of his fingers. Each of the five objects should have their own Interaction Context to keep track of the user's fingers.

Interaction Context converts raw WM_Pointer inputs into:
* Manipulations (Pan, Zoom, Rotate)
* Tap counts (Single-tap, double-tap, triple-tap)
* Cross-slide (The new "select" gesture in Windows8)

DirectComposition and DirectManipulation
DirectComposition and DirectManipulation are sister-APIs. DirectComposition is a scene-based rendering API based on (affine) transformations, while DirectManipulation converts WM_Pointer messages into (affine) transformations. All together, this is basically the technology that was used to create the Start Screen, or the Maps API. Panning, zooming, bounce animations, various opacity changes and so forth are all specified as transformations that are offloaded to the GPU. DirectManipulation can perform its calculations in a different thread, allowing for a fully responsive UI even if the main thread locks up.

DirectComposition can also work with the InteractionContext API to keep input-processing off of the main thread.

Interesting Windows8.1 APIs:
DPI Support
Windows 8.1 has added per-monitor DPI support, which includes a WM_DPICHANGED message, and some APIs for retrieving the monitor's DPI. Arguably, Windows as early as WinXP supported DPI scaling of some degree, but Windows 8.1 added some improvements if applications wish to auto-scale themselves as necessary.

Other Stuff
Visual Studio Image Library
A massive collection of free-to-use icons from Microsoft. One requirement before using... is that you must agree to use the icons in a manner that is consistent with their original use. Consider the VS 2010 images (in the "x--archive--" folder) for your basic stuff like the "add" icon. The VS2012 images seem to have replacements and some newer icons... but is overall incomplete compared to the archives.
First Strike +1/+1 and Indestructible.

Derek
Posts: 2181
Joined: Wed Aug 18, 2010 4:15 am UTC

Re: Win32 API Topic (Raw Windows C++ ftw!)

Postby Derek » Thu May 01, 2014 3:15 am UTC

KnightExemplar wrote:Windows (Win95 and older):
The Window, the signature GUI interface which gave "Windows" its name. Everything you can see in Windows is a Window. Buttons are a kind of window. The big programs with the little "x" in the top right corner are windows. Moving a mouse or typing on the keyboard sends messages to Windows. Anyone who wishes to learn about how Windows works needs to start with fully understanding how the "window" works. Believe it or not, very little has changed with the core Window API.

Adding to this: HWND is the "root" of the Windows object hierarchy. And by "object hierarchy", I mean that everything is an HWND and it's up to you to keep track of what kind of window each HWND actually is so you can call the right methods. And by "methods" I mean "SendMessage", which is the only function that is used to interact with most HWNDs, and you just have to know which messages you can send it to do what you want, and what to pass in it's two parameters, "wParam" and "lParam", with types "WPARAM" and "LPARAM".

Win32: How not to implement polymorphic OOP in C.

KnightExemplar
Posts: 5494
Joined: Sun Dec 26, 2010 1:58 pm UTC

Re: Win32 API Topic (Raw Windows C++ ftw!)

Postby KnightExemplar » Thu May 01, 2014 7:22 am UTC

Derek wrote:
KnightExemplar wrote:Windows (Win95 and older):
The Window, the signature GUI interface which gave "Windows" its name. Everything you can see in Windows is a Window. Buttons are a kind of window. The big programs with the little "x" in the top right corner are windows. Moving a mouse or typing on the keyboard sends messages to Windows. Anyone who wishes to learn about how Windows works needs to start with fully understanding how the "window" works. Believe it or not, very little has changed with the core Window API.

Adding to this: HWND is the "root" of the Windows object hierarchy. And by "object hierarchy", I mean that everything is an HWND and it's up to you to keep track of what kind of window each HWND actually is so you can call the right methods. And by "methods" I mean "SendMessage", which is the only function that is used to interact with most HWNDs, and you just have to know which messages you can send it to do what you want, and what to pass in it's two parameters, "wParam" and "lParam", with types "WPARAM" and "LPARAM".

Win32: How not to implement polymorphic OOP in C.


Hey, its not quite as bad as the Unix "everything is a File Descriptor", which takes "ioctl" parameters :wink: :wink: Okay, I'm kidding. Its totally just as bad as that.

Basically, its the only way to implement the Open / Close principle in C. You gotta pass around opaque pointers (or integers into an array). When you interact with those pointers, you need to have pre-defined data types that is passed into a function into the pointer's structure. It is honestly a limitation of C itself. GTK+ has a similar issue with their GObject* structures. File Descriptors and their "ioctl" are also a similar problem.
First Strike +1/+1 and Indestructible.

Derek
Posts: 2181
Joined: Wed Aug 18, 2010 4:15 am UTC

Re: Win32 API Topic (Raw Windows C++ ftw!)

Postby Derek » Thu May 01, 2014 6:14 pm UTC

KnightExemplar wrote:Basically, its the only way to implement the Open / Close principle in C. You gotta pass around opaque pointers (or integers into an array). When you interact with those pointers, you need to have pre-defined data types that is passed into a function into the pointer's structure. It is honestly a limitation of C itself. GTK+ has a similar issue with their GObject* structures. File Descriptors and their "ioctl" are also a similar problem.

No it's not. You can create an actual object hierarchy and use casting for polymorphism. Casting isn't type safe of course, but it's more typesafe than using one type for everything, and it means that when you port it to a language with an actual object system (C++) you can use the new type system basically for free. It also means you can have actual functions/methods that take the correct number and types of arguments, instead of shoehorning literally ever imaginable method into a single SendMessage function. I have used exactly this approach before, it sucks but it works much better than what they did.

korona
Posts: 495
Joined: Sun Jul 04, 2010 8:40 pm UTC

Re: Win32 API Topic (Raw Windows C++ ftw!)

Postby korona » Thu May 01, 2014 10:23 pm UTC

Derek wrote:
KnightExemplar wrote:Basically, its the only way to implement the Open / Close principle in C. You gotta pass around opaque pointers (or integers into an array). When you interact with those pointers, you need to have pre-defined data types that is passed into a function into the pointer's structure. It is honestly a limitation of C itself. GTK+ has a similar issue with their GObject* structures. File Descriptors and their "ioctl" are also a similar problem.

No it's not. You can create an actual object hierarchy and use casting for polymorphism. Casting isn't type safe of course, but it's more typesafe than using one type for everything, and it means that when you port it to a language with an actual object system (C++) you can use the new type system basically for free. It also means you can have actual functions/methods that take the correct number and types of arguments, instead of shoehorning literally ever imaginable method into a single SendMessage function. I have used exactly this approach before, it sucks but it works much better than what they did.

Well the advantage of opaque pointers is that they can be shared by multiple processes without synchronization nightmares.

Derek
Posts: 2181
Joined: Wed Aug 18, 2010 4:15 am UTC

Re: Win32 API Topic (Raw Windows C++ ftw!)

Postby Derek » Thu May 01, 2014 10:45 pm UTC

I don't see how that's relevant. A pointer to a well-defined type is just as shareable as a pointer to void*.

jareds
Posts: 436
Joined: Wed Jan 03, 2007 3:56 pm UTC

Re: Win32 API Topic (Raw Windows C++ ftw!)

Postby jareds » Fri May 02, 2014 2:23 am UTC

More to the point, doing polymorphism in C with opaque types still doesn't require you to channel everything through one function and thereby have no checking on the type and number of arguments.

Nothing is stopping you from having one function for each method, taking as arguments an opaque handle and the method-specific arguments. It can internally do a polymorphic dispatch on the handle just as before. Having a whole bunch of methods share one function whose arguments are an integer to indicate the method and a type-unsafe superset of the method arguments isn't polymorphism: it's just a lack of type safety.

In the Windows case, this approach of channeling everything through one function was presumably done with the goal of channeling everything into a message queue, not because that's the only way to do polymorphism in C with opaque types.

KnightExemplar
Posts: 5494
Joined: Sun Dec 26, 2010 1:58 pm UTC

Re: Win32 API Topic (Raw Windows C++ ftw!)

Postby KnightExemplar » Tue May 06, 2014 2:23 pm UTC

Either way, old C APIs can be annoying, but its how Win32 stuff is done. I still think the ioctl comparison is rather valid (especially since both Windows and Linux have evolved beyond the primitive "everything is a Window" or "everything is a File" philosophy).

Another resource I've found is the MSDN Magazine, which contains a ton of articles on everything relating to programming on Windows. Its still has ongoing monthly publications.
First Strike +1/+1 and Indestructible.

User avatar
forward4
Posts: 30
Joined: Wed Mar 05, 2014 2:40 pm UTC

Re: Win32 API Topic (Raw Windows C++ ftw!)

Postby forward4 » Tue May 06, 2014 3:41 pm UTC

As a point on the Win7 touch API, my family owns a win 7 gateway touch all-in-one. It has a flavor of Windows 7 that was optimized for touch! You can really see looking back that Microsoft was planning a touch OS like win8 for a while.
Minecraft and Mathematics; dragons and dinosaurs; raptors and rotational forces


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 7 guests