Date: | February 11, 2005 / year-entry #36 |
Tags: | other |
Orig Link: | https://blogs.msdn.microsoft.com/oldnewthing/20050211-00/?p=36473 |
Comments: | 61 |
Summary: | It seems that when people notice that the Internet Explorer rendering engine doesn't use HWNDs for screen elements, they think that Internet Explorer is somehow "cheating" and doing something "undocumented" and has an "unfair advantage". Nevermind that windowless controls have been around since 1996. They aren't magic. Mind you, they're a lot of work, but... |
It seems that when people notice that the Internet Explorer rendering engine doesn't use HWNDs for screen elements, they think that Internet Explorer is somehow "cheating" and doing something "undocumented" and has an "unfair advantage". Nevermind that windowless controls have been around since 1996. They aren't magic. Mind you, they're a lot of work, but they aren't magic. Clearly Internet Explorer cannot create a real HWND for every element in an HTML page. There is a limit of 10,000 USER handles per process, and you are likely to run out of desktop heap long before then. The Internet Explorer team went and reimplemented all of the controls that a web page would need. They have their own windowless checkbox control, a windowless listbox control, a windowless edit box, and so on. In addition to reproducing all the functionality of the windowed controls, the Internet Explorer folks also had to reproduce the "look" of the windowed controls, down to the last pixel. (Functions like DrawThemeBackground and DrawFrameControl prove extremely helpful here.) If I recall correctly, the only element that is still windowed is the <SELECT> element. If you squint, you can see some places where they didn't quite nail it. For example, if you right-click in a text box, options like "Right to left reading order" and "Insert Unicode control character" are missing. As another example, notice that IE's scroll bars do not light up when you hover over them. Remember, I never worked on Internet Explorer; all I know is what I learn from people from that team. (jeffdav for example, joins the shell team for lunch nearly every day.) If you have questions about Internet Explorer, you would likely have much better success asking the Internet Explorer team yourself via their team blog. |
Comments (61)
Comments are closed. |
It still simply amazes me that people seem to think everything MS produces uses undocumented code. I discovered the above mentioned function years ago, and have used it once or twice in my own custom controls. DrawEdge is another nice function to have :)
Visual basic programmers have had windowless controls for even longer – although they were called "lightweight" controls…presumably to hide the complexity of concepts like "windows" from us ;-)
PowerBuilder does the same thing with their DataWindow. One of the things that they used to demo was a DataWindow with a bunch of "controls" on it vs. the same number of Windows controls. The datawindow would always render faster.
I think embedded objects, like Flash and Media Player, are also "Windowed" objects. Most pop-up menu systems for web sites have issues with this, and end up showing up "behind" the windowed object. Although IE has had a fix for this, for years. I believe Mozilla / Netscape also have a fix for this, now. I don’t remember the details, off hand, though, cause I haven’t done this in about 8 months.
I am not sure but I do believe the IFRAME is a window with handles as well. That is the only thing that will allow Z indexing over the select element in HTML. Which is one of those quirky things we have to do in Dynamic HTML is put an IFRAME below anything like pop out menus. Because everything can properly Z index over an IFRAME but only the IFRAME can Z index higher than a select element. Something I have always wished they would fix.
Um, that was fixed over five years ago.
http://msdn.microsoft.com/library/en-us/dnie55/html/dnie55ie55.asp
"… iframes could not play in the world of z-index-positioned elements. … In Internet Explorer 5.5, this feature is now supported."
Their implementation of horizontal scrollbars behave weird in IE. If you resize the window to have a thin height, it shrinks instead of disapearing. And the scaled down version also has some drawing/hit detection issues.
MS Access does the same (or at least it did around version 2.0 when I touched it for the last time :)
Is the <SELECT> not being windowless the reason why it will bleed through DIVs?
http://www.faqts.com/knowledge_base/view.phtml/aid/10146
A lot of Microsoft applications use windowsless controls. Use Spy++ on any of the Office dialog boxes and you’ll see they have their own way of doing things (Forms3?).
Delphi has had windowless controls since ’95 (for Win 3.1) and would have been in design for longer than that. Of course, Delphi’s windowless controls didn’t take focus, and were essentially graphical only controls: things like toolbar buttons and labels.
Aha, that explains why buttons in IE look ugly and stretched when they are beyond a certain width. IE probably just stretches a pre-drawn bitmap.
Little bit ‘o history from my point of view:
The windowless controls we have today originated from how Access internally managed high-cardinality items. Specifically for the data grid, Access (long before 1996) couldn’t possibly have afforded to create HWNDs for each cell. So there were these things called "KTs" (KonTrol?) that you could put on Access forms/surfaces which basically followed the "flyweight object" pattern.
For Sterling (I was hired in Aug 1994 to help rush out the next version of Access which was a major reachitecture, fixed all the known problems, etc. etc. etc you can fill in the rest of the blanks from the standard "we’re changing the whole world!" script)… the old forms/ui folks from Access were working on a whole new forms package which formalized the KT pattern using COM as the basis. (Not so flyweight any more but patterns like tear-offs were established since the windowless controls couldn’t afford to carry around all those vtable pointers.)
Sterling, of course, never shipped except like how most projects like it ship – bits and pieces of it dribbled into various products.
The Access forms folks (cool code name I can’t recall) joined forces with a team doing similar work in systems and formed Forms^3, which shipped as part of Office as a partial replacement for the Office Dialog Manager and I also believe it shipped with VS ’98, but I can’t call in what capacity. It was supposed to replace Ruby as VB5’s forms package but the compatibility wasn’t close enough. (I did put together a demo where we used forms3 in design mode and auto-generated the MFC message tables to give a VB-like form based app design experience for VC++.)
Forms^3 evolved into the mshtml crowd and thus you have the html renderer inheriting all the activex/windowless-controls/IFrame stuff. (But they also acquired some of the folks doing the MSN information reader from way back when; I recall the code name but I guess it was called "MSN explorer" then? No relationship to the new MSN explorer. The important thing is that these folks brought text flow and dynamic layout issues to the party.)
Meanwhile, ODM and WDM still survive, VB ended up breaking Ruby compatibility in a much much bigger way and Sterling mostly shipped eventually just like Cairo did. Except for some really cool demo-ware where you could auto-build hierarchies of tables from the data grid.
I don’t want to sound like I’m trying to flame but this is why VC++ devs should learn about the full functionality of "Windows Forms" first so they can better understand the capabilities of app-/windows/. Or better to produce a prototype in VB(6) or .Net.
Some C++ people might be shocked by the amount of experience I carried over from VBA to VC++. And no, funny guy, I don’t mean GOTO jumps. You do gain a much better understanding of the Win32 API and app-/windows/ programming concepts in general.
I have also been known to explain windowing concepts which I see as being simple to much better VC++ devs. Mainly because they look at it "bottom up" and get all confused or don’t completely understand what they are trying to do (might also explain why VC++ devs produce such ugly UIs).
Serge Wautier: Using Win32 for some elements and windowless controls for others just makes a bad situation worse. See the above discussion for the problems that <iframe> and <select> have caused over the years.
Ummm Raymond,
If it is fixed please explain to me this quick code I threw together to show you Z indexing still don’t work on select tags in IE 5.5, 6.0, 6.1 or what ever else you want. Because there are thousands of web developers that do this on a daily basis because there is no way around it.
Sorry for length just copy and paste code below and save as htm file view in IE
<HTML>
<HEAD>
<script Language="JavaScript">
var FrameVisable = true;
function HideIframe()
{
var myframe = document.getElementById("Iframe1");
if(FrameVisable)
{
FrameVisable = false;
myframe.style.visibility = "hidden";
form1.DisableButton.value = "Show Iframe"
}
else
{
FrameVisable = true;
myframe.style.visibility = "visible";
form1.DisableButton.value = "Hide IFrame"
}
}
</script>
</HEAD>
<BODY>
<iframe id="Iframe1" style="position:absolute;left:400px;top:10px;z-index:4;width:200px;height:200px"></iframe>
<form id="form1" method="post" action="">
<input id="DisableButton" style="position:absolute;left:200px;top:10px" type="Button" name="b1" value="Hide IFrame" onclick="HideIframe();">
<div id="Text1" style="position:absolute;left:400px;top:10px;z-index:5">This is some long text in a div tag</div>
<select id="select1" style="position:absolute;left:400px;top:10px;z-index:1" size="1" name="D1">
<option>This is some long text to stretch it out</option>
</select>
</form>
</BODY>
</HTML>
Oh and feel free to change the div tags to p tags or any other html tags you want, same effect
You can direct IE questions to the IE team – I included a link to their blog.
The web page I referenced said <iframe> was fixed; <select> is still windowed (as I noted in the main article).
In reply to Jonathan, Office has several different internal UI technologies (many with their own TLAs). Before it was one product, each team developed their own system of doing things, and because it’s less efficient to rewrite everything every cycle, we still maintain just about all of them, and very recently, there has been a movement to begin consolidating them into an emerging new UI platform (first seen in Office 2003)… Of course there is tremendous irony adding a new UI technology (12th or 13th time we’ve reinvented this wheel) to remove some of the old ones… But you do have to meet the needs of all of the pre-existing technologies before you can use a new one. And it was also inspired by "DirectUI".
While I’m discussing office on this blog (which talks a lot about app compatibility), one interesting thing that we have done (probably because of too many cross-Windows version bugs being discovered) is wrap chunks of the Windows APIs in wrapper code in the core Office DLL (MSO.DLL). When Windows changes between versions, we can isolate our code this way. Sometimes it also lets us work on unexpected scenarios (for example, network shares with funny permissions). That’s just one of the ways that we get new versions of an application like Word or PowerPoint to run on older systems unmodified (and share code in the process). So in addition to Windows changing its APIs trying to make past apps future compatible, Office changes its internal code to make present apps backwards compatible.
Eventually, the burden of building and testing these apps on so many versions of Windows becomes too great, so we sometimes let go of old version compatability (Win9x left us in Office 2003). Contrary to popular belief, it is not because we want to force customers to upgrade Windows. The time we save allows us to build a better system. Unfortunately for Windows, they don’t have as much luxury in that department as Office does…
Frederik Slijkerman:
> Aha, that explains why buttons in IE look ugly and stretched when they are beyond a certain width. IE probably just stretches a pre-drawn bitmap.
If I remember correctly (and I may be mistaken) this was done because the theme code mixes up the use of resolution vs. size. When drawing a nine-grid theme background, the shell APIs just allow for a final size — regardless of resolution.
When printing then the size ends up being very large and so the border is vanishingly small. The hack around this was to assume that if the button was beyond a certain size then we must be going to a printer. In that case, disable the fancy stretching behavior and just do a simple stretch.
Joe
err — should have said "theme API" instead of "shell API" up there. (But it was the shell team that implemented those APIs).
In Avalon we worked hard to make sure that resolution and control size are two different things to avoid issues like this.
Joe
We have been asking them Raymond ;-) For yes well over 5 years well before since that article was posted we have been telling them. I have seen that msdn article before. I keep hoping someday somewhere in Redmond someone like Raymond or Larry Osterman while pooring through their code may stumble upon it and fix it for real.
Creating a windowless combo box is "very hard" because the dropdown part of the combo box extends beyond the window boundaries of its parent – this practically requires a separate window.
It’s not hard, I’ve done something like that before one day because I was bored. You just make a large window that spans your monitor and manage all the fake subwindows yourself by using a region. So esentially it’s like a layer with all your windows on it and if you change the z-order for it, all the windows in that layer become that new z-order. I don’t recomend shipping a program that does things that way though.
I think this layer with all the windows on it method is how mac osx does things but I can be wrong, I’ve never actually taken a look at it.
True, I agree it is hard but that post saying it is fixed really needs to come down. It has never been fixed in IE. And no I am not throwing a Jab out there, I prefer IE as a browser but there are a great many things like this that are not issues in Firefox. Z indexing is correct in FF.
Javascript has never been a fun language for me so I try to use it as little as I can. But Dynamically moving around IFrames is just a basic thing we have been doing for years because of the Select tag.
So anyway Raymond sorry if I was rude and I just made a comment on the Iframe I think is windowed as well because of that problem. Then you came back with that same link we have been getting from the IE team for years just kind of pissed me off. You can’t believe everything you read in MSDN. Which might be why the MS blogs are so popular. A lot of minds collaborating and thinking in different directions.
Are you saying that <iframe> still cannot be z-ordered in IE 5.5? Please be specific what "it" is when you say that the "the post saying it is fixed really needs to come down". From what I can gather you’re really complaining about <select>, which nobody claimed was fixed.
Surely it isn’t gluttony to have the combo box dropdown as a live window, especially if only one is active at any given time (two if someone rigged a goofy D&D scheme).
It would be hard to believe they spent their time duplicating the control functionality without referring to the original code. THAT is what the "unfair advantage" boils down to, that I whined about many moons ago. That’s not to say that edit controls, combo boxes, buttons, etc. are rocket science, but still…
I’m nobody’s mortal enemy, I’m just trying to keep it real.
Speaking of Mozilla/Netscape, I’m pretty sure they also use "windowless" controls, for the same reasons, and also so they can promulgate a platform-independent look-and-feel. Also, Java Swing applications do the same thing (the older AWT uses windowed controls), again, for similar reasons. Nobody accuses *them* of "cheating."
Erbo:
> Speaking of Mozilla/Netscape, I’m pretty sure
> they also use "windowless" controls
Of course they do. They even go further than that, the address bar and the toolbars and the status bar and most controls in the configuration dialog are not windows either.
> Nobody accuses *them* of "cheating."
That’s not cheating, that’s reinventing the wheel :)
I’d like to toss in a minor vent with regards to Windowless controls and, specifically, the insights of "Office Mike". I’ve known about ODM for quite some even before I worked at MS. I’m sure that every UI developer since the early days of Excel has run Spy (no ++ back then) over some MS dialogs and noticed, viola!, no HWNDs. Back in 16-bit days I believe the limit on Window handles was even more extreme (I could be wrong but I think it was something like 16K handles for the ENTIRE desktop). So, if you were in the business of building UI toolkits that were scalable, what MS was doing with Excel was very interesting. To further up the ante once you had basic Windowing you then quickly wanted some more juicy features like "logical transparency" (i.e. I’d really like my dialog background to "show through" the background of my static text / pushbuttons, group box, etc..), non-rectangular clipping, and single pass rendering (very sweet when done offscreen)… A lot of this is now available with HWND but writing compatible code, as in the case with Office described earlier, means that you often have to consider the least common denominator. The end result was that when it came to any "heavy lifting" UI with a potentially information dense display the first step was to bid farewell to HWND, say hello to HRGN and use HWND only when dealing with the desktop (as in the case of popups).
The vent is simply this; if Excel, Office, and now IE have all figured out, for one reason or another, that the HWND just doesn’t cut it, why, after all this time, when I try to create a form with the latest and greatest Windows SDK, the VS form designer (and control toolkit) will place nothing but Windowed controls? As an ironic side note, I’ve noticed that VS itself sees some of the advantages of the "IE Windows SDK" with the mysterious "HTMLite" control popping up in the install.
Raymond, understood. Let me rephrase my vent; Why hasn’t MS, to date, added "industrial strength" features to the Windows SDK that all of its own apps already require? Like no limit on window handles (by this I mean LOTS of handles is the norm rather than the exception), various clipping and transparency with little cost, and implicit offscreen rendering? If the goal of Windows SDK is to take "insanely hard" but very fundemantal OS tasks and make them easily usable by 3rd party devs shouldn’t we expect the same attention to real world UI issues?
In my opinion, that’s beyond the scope of the Win32 Platform SDK. The Win32 Platform SDK describes the Windows platform. It’s job is not to give you a UI framework library. That’s what things like VB and MFC are for. It is my impression that WinFX is close to the UI framework that you’re describing.
Your blog is very intersting for me to understand the innerworking od Microsoft. Can you tell me of a blogger that almost does the same thing, but working for microsoft
The special case for <SELECT> elements has caused me pain to no end. They always apparently have the highest zIndex because everything else is drawn dynamically. So if you want to pop up a div you have to do all sorts of special coding to get it to cover up the select list. I have wondered why it was so, however.
I’m glad he finally answered this question for me.
It would be nice though if MS came up with a solution that would enable their developers to accomplish the same thing as the IE team, instead of just keeping it to themselves.
Because managing windowless controls is **insanely hard** – there is no pre-made infrastructure for it; you have to write it all yourself. The average Win32 program does just fine with boring old HWNDs. Foisting windowless control management on everybody would drive most progammers insane. ("You’re teling me that in order to display a dialog box with some text, an icon, and an OK button, I have to implement an IOleInPlaceSiteWindowless object?")
Furthermore, you can’t mix windowless and windowed controls without running into problems like the ones mentioned above. So it’s all or nothing. (Besides, Office doesn’t even use ActiveX windowless controls – they have their own private system. So there would be nothing for VS to show anyway.)
Dru, it’s called hard work. You spend a lot of time writing windowless controls and you get them to work like you want them to. Anyone else can do the same thing the IE team did using the tools provided. That’s precisly the point, HWND provide you with a generic way to build most of the common control,if you don’t want the constraints associated with being generic, and want to do whatever the hell you want, that’s precisly what a windowsless control is. The thing is, if you want none of the constraint, you gotta to do it all yourself, nearly from scratch. You can’t have it both…
Why can’t I open more than 60-70 Internet Explorer windows on Windows XP? My laptop has 1 GB of RAM and yet I can only open a few dozen IE windows; it doesn’t matter whether there’s a single process (and windows are created with Ctrl+N) or 70 processes, each having one window.
On systems with less memory (256 MB), the OS stalls at about 50-60 IE windows. On a machine with 1 GB of main memory, I get about 70-75 windows.
The truly awkward thing is that once I hit this limit, the machine becomes totally useless. I can’t even start Task Manager, open the Start Menu, nothing! Running apps can’t create new dialogs, the system is dead.
Please, don’t tell me about memory limits – I don’t buy that when I have 700 MB free. The resource count (kernel handles) is also reasonably low, and I thought Windows NT and its successors never had the kind of limitations Windows 95 had on user and GDI resources.
I can constantly reproduce this behavior on any given Windows XP machine. I’ve tested this on a dozen machines so far. If you want me to, I can record a test for you and publish it as a WMV video. I’ve known this bug since XP appeared, I haven’t seen it solved yet (currently I use XP + SP2 + all current patches) and I’m very curious about what the answer might be.
Now you’re off topic.
Sorry for being off-topic. It seems to me that using windowless controls is a good way of preserving system resources, but Internet Explorer’s behavior is completely weird. It just seemed a good place to ask the question. Again, I apologize for disturbing the thread.
You heard it from the horse’s mouth – IE doesn’t use standard Windows controls. So all those who continue to complain about how XUL "re-invents the wheel" by doing its own widgets, and how that has to be the cause of our allegedly poor performance (did you start Firefox recently?) can finally pipe down. Raymond Chen is a Microsoft guy who writes a fascinating technical blog called The Old New Thing. While hoping I never have to use any of the technologies he discusses, he writes so well and comes out with such great historical nuggets that it’s essential reading….
Sorry to be cliche, but Ovidiu, use a better browser.
http://www.mozilla.org
http://www.opera.com
And no, this isn’t a trolling attempt, it’s just a suggestion that might fix your problem by avoiding it.
Also, even when using IE, I haven’t experienced that. That includes the time I ran one of those scripts that keeps on spawning new windows. Of course, it did slow down a bit, but the machine was usable once I managed to stop the script.
I use IE, Firefox, Opera and Netscape constantly as I do web pages every once in a while. I still consider IE to be the most performant browser (and with the proper settings it’s also very secure). That’s why I’m baffled by this behavior (simple test: Open a IE window, navigate to http://www.google.com/ and press Ctrl+N. My machine gets locked after 70-75 new windows). I would have expected IE to use very few USER resources (I knew for quite a while it doesn’t use HWNDs). I don’t know about GDI resources. I was hoping to get an answer here, but I gave up. Still an IE fan, though :)
That’s probably a good discussion for another thread, but not this.
So, I’m surprised. It looks like windows really have different widget implementations, just like "other OS". The difference here is that they LOOK the same, and nobody has noticed it until you said it. Very smart move.
Windowed controls are horrible in terms of resource usage and overall performance, but its hard to write windowless controls that act just like the standard Windows controls everyone is used to. Actually, we shouldn’t have to–that’s what GUI toolkits are for. We should only have to write a new control if it does something that no other control does, and writing a multi-line text box from scratch is no easy task. It’s not impossible, but I’d rather spend my time on more productive things. Not to mention re-implementing IME would be a serious hurdle.
This is why I was initially disappointed when .NET had System.Windows.Forms, which is based entirely around Windowed controls. Even VB6 had basic support for windowless controls. But the backwards-compatability was nice, I suppose, and not having to jump through hurdles just to subclass a control was a big plus. It just seems like it should have been Microsoft.Windows.Forms and not System.Windows.Forms, in the same manner that the registry APIs in .NET aren’t in System, but I digress.
And I don’t mean to completely criticize the product, either. It’s much better than many previous attempts, but until Whidbey it was lacking in several key areas…mainly with regards to advanced controls, theming support, and text rendering that doesn’t look horrible on screen. I’m sure glad these have been addressed, as I was getting tired of addressing them myself over and over in my projects, and P/Invoke to fix things always seems like a hack and not a solution when I’m doing managed work (Not to mention the security issues with calling unmanged code).
And seeing as Avalon appears to use windowless controls (except for when you’re hosting/interoping with a SWF control, I’d wager), I can’t complain too much, except that Avalon isn’t here yet. But at least I can finally play with the preview version, if I change my theme, but i digress again.
And Avalon was certainly too big of a project to have been included in version 1 of .NET, and if it had been I’m sure it would not have been as good as it have been, so SWF is a great temporary solution.
And in regards to Diego’s comment about different wigit implementations (Win32, Office, IE), they really *don’t* look or act the same. Office controls annoy me in many ways. I can spot an Office from a Win32 control with a few seconds of use.
Well, just to tell what a I did about the <SELECT> problems (besides z-ordering, it has issues with CSS formatting).
I wrote an entirely DHTML/Javascript solution, with automatic positioning/resizing of the list pane, and even support for pagination of the list. I wrote it using VB6/XSLT, some 4 years ago.
Maybe I can recreate it as an ASP.NET Custom control for easier reuse…
FoxPro has used bitmapped controls since the Windows version appeared over 10 years ago. Version 9.0 was just released and it still uses them.
"Now you’re off topic. "
Well, I dunno about that. The entire justification for windowless controls (the reason one would put up with their massive coding effort and non-standard appearance) is to keep resource usage managable.
Yet IE still uses a huge number of USER and GDI resources. I suppose it’s possible that it’d be even worse without the windowless controls, but still… it’s pretty gross, and pretty frustrating.
People in this discussion mentioned "clipping" the select field area when moving a higher z-order DIV over a select field.
Can they please expand on this and the general approached used?
KiwiBlue: Actually, Access 2.0 created its forms by rendering the form’s controls at run-time into an on-screen bitmap. It then used two on-screen lightweight controls to (convincingly) imitate the control that currently had focus. Since Access 2.0 originally ran on Win 3.1, what they were able to accomplish on 16-bit Windows was pretty advanced at the time.
I’m waxing a bit off-topic, but FWIW, Access 2.0 had one of the finest forms designers I’ve ever seen. It was a pleasure to work with. Kudos to the original team.
(For the record, I spent way too of my life developing for Access 2.0.)
KiwiBlue: Actually, Access 2.0 created its forms by rendering the form’s controls at run-time into an on-screen bitmap. It then used two on-screen lightweight controls to (convincingly) imitate the control that currently had focus. Since Access 2.0 originally ran on Win 3.1, what they were able to accomplish on 16-bit Windows was pretty advanced at the time.
I’m waxing a bit off-topic, but FWIW, Access 2.0 had one of the finest forms designers I’ve ever seen. It was a pleasure to work with. Kudos to the original team.
(For the record, I spent way too of my life developing for Access 2.0.)
User32 IS a GUI toolkit. What is this obsession with running off and writing windowless controls anyway. I mean – "proper" windowed controls implement a certain set of functionality that contributes to their heavyweightness. Any full featured windowless control is surely going to have re-implemented enough of that to be heavy all over again?
Anyway, is the core Win32 windowing system so ossified that it couldnt be lightened up? Why ARE we worried about user32 handle limits still?
You’ll probably use it too.
PingBack from http://aspadvice.com/blogs/rbirkby/archive/2006/12/04/WPF_2F00_E-December-2006-CTP-Released.aspx
It has its ups and downs.
It has its ups and downs.
PingBack from http://blogs.xobni.com/asmith/archives/23