What is the story behind multimon.h?

Commenter asdf wonders what the deal is with that multimon.h header file.

Let's set some context. That header file was written back in the time when Windows 98 was still under development. Windows 98 was the first version of Windows to support multiple monitors. At the time, most application authors had Windows 95 as their target platform. And even after Windows 98 shipped, the expectation was that programmers would target both Windows 95 and Windows 98 for at least a little while longer.

The problem then is convincing programmers to write their code in a manner that works well in the face of multiple monitors. If you say, "Well, you need to call these functions, but only if running on a version of Windows which supports multiple monitors. If running on an older version of Windows, then you'll need to keep doing things the old way because the functions you want to call don't exist there."

Remember, if you want people to do something that doesn't directly benefit them, you need to make it easy or they won't bother. Therefore, the multimon.h header file was created which did the dirty work of checking whether it was running on a version of Windows which supported multiple monitors. If so, then it called those functions, and if not, then it emulated them. Applications could then use the multimon.h header file and write code on the assumption that the operating system supported multiple monitors: If it didn't, then the stub functions in multimon.h would kick in and implement "fake multimonitor support". For example, if you called GetSystemMetrics(SM_CMONITORS), the stub function would simply return 1. If you asked for GetSystemMetrics(SM_CXVIRTUALSCREEN), the stub function just gave you the width of the (one) monitor.

Of course, those old versions of Windows which don't support multiple monitors are long obsolete, and there is no longer any need for the multimon.h header file. It long ago accomplished its intended goal. Give it a nice pat on the back.

But the header file still lingers in the Platform SDK. If you have a program written back in the days when you couldn't count on multiple monitor support, then removing that header file would result in a build break in your program. That wouldn't be fun.

Comments (24)
  1. Random832 says:

    The obvious next question is, why does the header file still actually do all that work?

  2. James Schend says:


    I’m there there are hundreds or thousands of programs out there originally targeted for Windows 95, which get occasional updates (business rules change, for example), and therefore still need the header to compile.

  3. James Schend says:

    Wow, I meant to type "I’m guessing there are". Need more coffee, sorry.

  4. Gabe says:

    Random832: Are you suggesting that they touch known-working code that is causing no problems?

  5. Henke37 says:

    He is, because the rules change. Business follows different rules and so on.

  6. Random099 says:

    The header doesn’t look multithread safe to me. I guess it should be avoided.

  7. A different asdf says:


    I believe we know your stance on backwards compatibility, but I would like to know what you think about Apple’s strategy regarding this. In Apple-land, builds regularly break if you switch over to a new SDK. You can keep on using the old SDK, but only until it is removed (you can of course keep an old machine around running an older OS with an older version of the tools).

    As annoying as I sometimes think some of the outwardly arbitrary breaking changes are, when reading stories like this I can’t help but feel that this forced rejuvenation of my and others’ code is actually a good thing.

    I realize that this policy would never work in Windows-land due to a multitude of business and economic reasons (I can only imagine the volume of complaints about "forced upgrades" if Microsoft ever switched to something like this), but what do you think?

  8. mpbk says:

    No one uses Macs for custom business code, or any sort of code that has to last past one year.  Therefore, it really doesn’t matter if Apple breaks things on every SDK release.

  9. Yuhong Bao says:

    Another header file that does something similar is NewAPIs.h included with older SDKs. It is now removed in the latest SDKs because it is no longer needed

  10. Dean Harding says:

    @Random099: Seems thread-safe to me. There’s the possibility of doing initialization more than once, but I don’t see why that would be an issue. Besides, I can’t imagine why you’d use this on a non-UI thread anyway.

    Also, what would be the point of removing the file? All you’d do is save a whole 16KB of the platform SDK…

  11. Olivier says:

    @A different asdf : Apple strategy is just stupid, they just lose their customers:

    I coded a program which should works from Win95 up to 7 and also should works on OSX.

    It was working great on OSX 10.3 and 10.4, then for some reasons it didn’t work correctly on 10.5 and up.

    I just had to tell my customers to buy PCs to continue to use my software. I had lost enough time and money to try to get my soft working on OSX, now they had to spend time and money buying and learning Windows. They didn’t have choice because my software is linked to the services my customers wants from me.

    BTW: I don’t have anymore customers using Win9x, they all have at least Win2000 :)

  12. Ken Hagan says:

    Because somewhere there probably *is* someone still targetting Win95.

  13. JenK says:

    Speaking of Win95 apps that still work – Hover does ;)

  14. Random099 says:

    @Dean Harding

    > @Random099: Seems thread-safe to me.

    At least strongly implementation-dependent. Consider the following scenario:

    [1] In a call to xGetSystemMetrics, Thread A calls InitMultipleMonitorStubs and successfully initializes the function pointers.

    [2] Before it processes the line

       g_fMultiMonInitDone = TRUE; return TRUE;

    thread B has its turn. Since g_fMultiMonInitDone is not yet set, Thread B will again attempt to initialize the function pointers.

    [3] Thread B’s call to GetModuleHandle fails due to a memory allocation error. (Note that either GetModuleHandleA or GetModuleHandleW probably requires a string mapping.)

    [4] At some time after thread B sets g_pfnGetSystemMetrics=NULL, thread A resumes control. It sets g_fMultiMonInitDone to TRUE, returns TRUE from InitMultipleMonitorStubs, and consequently calls g_pfnGetSystemMetrics. At that point the program will crash.

    [Good theoretical analysis, but in this case, the header file takes advantage of implementation details that avoid the problem. (The kernel pre-allocates memory for simple string thunks which can be used under certain conditions, and this happens to be one of them.) -Raymond]
  15. Lawrence says:

    It is a great strength of MS’ that they keep these old "no longer needed" stubs around. I know there are people who dislike this – heck, in my own code I remove stuff like this – but knowing that I can recompile old working code to accommodate a change is a big part of the reason I only target Windows for my customers’ bespoke apps.

    If MS didn’t have this attitude, I’d probably just not update my SDK/Dev environment. Which is MS’ loss as much as my own (I won’t be using any of their new features).

  16. Jeroen Mostert says:

    @Teo: "Hint: compile a program using the Vista VSS SDK, and try running it on XP – yes, it crashes." This is a bug in XP with the way manifests are treated, not a by-design backwards compat break, and it’s been fixed in SP3. While pretty embarrassing as bugs go, it can’t be taken as representative of how the SDKs deal with backwards compatibility.

  17. someone else says:

    @Olivier: "I coded a program which should works from Win95 up to 7"

    Next challenge: Make it work on NT 3.1!

  18. Harry Hill says:

    Comparing Microsoft and Apple on backwards compatibility and market share, which is the chicken, which is the egg?

    Say what you will about Steve Ballmer, but he was spot on with his "Developers Developers Developers Developers!" speech.

    "Build the applications, and they (customers) will come". Microsoft let you build the applications, Apple keep you going back over last year’s applications trying to get them working again.

  19. Teo says:

    @Jeroen Mostert, I test only on SP3, so these are different issues.

  20. dzandkamp@hotmail.com says:

    @ Teo:

    There are two very distinct entries regarding to VSS.

    http://msdn.microsoft.com/en-us/library/bb968832(VS.85).aspx states an explicit  SDK for XP/2003.

  21. Teo says:

    Yes, the strong backwards compatibility is a very, very good feature, but the price is that writing software that wants to use new features but still work on older platforms is one big giant ridiculously messed “thing” (and that “thing” has hundreds of tentacles and three rows of steel teeth, oh and eats babies for snack). For example, the structures for menus and toolbars are so different on Vista and XP that you need special ifs on various places in your code. Mind you, menus and toolbars are just the START, the real hidden dragons await later.

    Also, as I discovered, MS *tells* everybody, how Windows SDK is oh so backwards compatible, but in practice it is NOT. It breaks arbitrary. Hint: compile a program using the Vista VSS SDK, and try running it on XP – yes, it crashes. No, you are not using Vista-specific calls.

    [Is it better that something be possible but difficult, or not possible at all? -Raymond]
  22. porter says:

    > Next challenge: Make it work on NT 3.1!

    Next challenge: Make it work in Win32S

  23. Random832 says:

    Next challenge: Make it compile cleanly for Win16.

  24. Teo says:

    @alt-92, I know. This very well proves that it is *very maddeningly hard* to write a Windows program that runs on particular version of Windows *and* uses features of newer versions of Windows when available. To understand my point of view, try to build a program that runs on XP correctly and when run on Vista, uses functionality from IVssBackupComponentsEx2.

    Raymond, you are correct that it is better something to be possible and so on and so forth, but you miss a problem: Windows is a *graphical* ui os. If showing the *menu* of your window is so hard that you cannot do it right from the first time, then there is a very deep problem. I’ve seen such mistakes in gui frameworks, which are supposed to abstract away these issues. Imagine the novice GUI developers’ life.

    Anyway, back to the topic of this article.

    And it is that regretfully, I have to point that multimon.h is probably one of the last times when MS actually allowed programmers to transparently use newer functionality with older OSes. After it, there’s the gdi+ redist and the FileExtd.h which covers just XP/2003. Why did MS stopped helping us programmers cover more of their platforms?

Comments are closed.