Hacker News new | ask | show | jobs
by jxcole 5373 days ago
I disagree with you and I think the grandparent is right. Even though the handle based architecture of the wind32 system is not object oriented, it was meant to have some object oriented features. If you think about this system as one in which a window handle is a window object and a message to that window represents a function call, then the WM_CLOSE is a public method that anyone can call. WM_DESTROY, on the other hand, would be a protected method that can only be evoked by the window system. Even though they decided that the overhead of a full OO system was too much, they still could have made the intention more clear by doing something like this:

WM_PUBLIC_CREATE and WM_PROTECTED_DESTROY

Then there would be no confusion about who was supposed to send the messages and how they were meant to be interpreted. Of course they don't have to use this exact terminology, but you get the idea.

2 comments

"If you think about this system as one in which a window handle is a window object and a message to that window represents a function call, then the WM_CLOSE is a public method that anyone can call. WM_DESTROY, on the other hand, would be a protected method that can only be evoked by the window system."

Yeah well there's the error in your thinking, and exactly what the OP was about: window messages aren't that. Every message is a callback, a 'notification' if you will. If you call RegisterClass() and pass a WNDPROC that does nothing (ignores all messages), it can still be created/destroyed with CreateWindow()/DestroyWindow(), and the 'notifications' it gets (WM_CLOSE and WM_DESTROY) can happily be ignored ('happily' as far as the window manager is concerned).

Win32 is not an OO API, and thinking of it too much in those terms will cause all sorts of confusion. Win32 is a C api, and yes things like MFC put an OO wrapper around it, but at some point the abstraction will start to leak if you take it to the extreme without thinking about the underlying system. Win32 is based around the OS calling back into your code through a well-defined callback function (the WNDPROC), a function with a fixed signature, and taking two arguments that are for all intents and purposes void*'s. The message ('WM_xxx') is a way to tell you how to interpret its arguments, and inform you about changes in the life cycle or state of the window. Everything else (like being able to 'send' messages to HWND's and make them behave in a certain way) comes from there, and much of it is convention - which often works, but when it doesn't, it's not the design's 'fault'.

Using message queue semantics to implement Java-style OOP is the kind of thing that would put Alan Kay into a rage.

The failing of the Windows message system is not distinguishing between the 'command' messages that you are allowed to send to a window to effect some action (WM_NOTIFY and friends) and the 'event' messages caused by the window manager (WM_DESTROY, input events etc.). It should be apparent that getting a window to respond to an event is not the same thing as effecting that event.

Crucially, OOP languages without access modifiers (or ones you can #define away, like C++) have this same problem. If an ignorant programmer thinks he can destroy a window by calling its _onDestroy() function, you have solved nothing.

With sufficient language support you can probably save users from themselves in this case, but there are many other cases where a user can do the wrong thing by not understanding the system. At some point the effort doesn't justify itself.