Hacker News new | past | comments | ask | show | jobs | submit login
How do I create a topmost window that is never covered by other topmost windows? (msdn.com)
108 points by gus_massa on March 16, 2011 | hide | past | favorite | 51 comments



This is a classic arms race - an escalating conflict over a positional good that by definition can only be enjoyed by one entity at a time. Other positional goods include popularity in high school and military superiority (from which we get the term "arms race" to refer to the escalating efforts of multiple agents to achieve the good).

Generally, the only effective way to address an arms race is regulation: an encorceable arms treaty, say, or a strict school uniform.


Yeah yeah, whatever. I don't want to hear about your problems. Having problems is a sign of incompetence.

Just write me a program that always wins. While you're at it write me a program that always prints the biggest number. I expect both by tomorrow.


I can't help you with that first one, but

  perl -e 'while(1){print 9;}'
A bit of a cheap shot as that is basically printing infinity without actually calling it infinity, but I'm going to float this by on a claim that your boss won't know the difference. "It's just not done yet, sir! Keep waiting. It's printing a really big number."


Did I say tomorrow? Tomorrow's Saturday, isn't it? I meant Monday. You can do a bit of time this weekend, can't you?


I was going to chime in with my own ideas about solving this -- you can play this game all day long and I'm sure inciting that kind of discussion that was the intent of the author -- but this story about one particular request accidentally illuminates a key problem with Windows: too many developers and programs competing for one set of user eyeballs.

You'd think that would be a good thing, but far from it. What happens is that every little developer writing any kind of tiny little app 1) wants money, and 2) wants to remind you how cool they and their app is by annoying you in various ways. Sadly, the annoying part is usually done without any unkind intent on the developer's part at all.

I have no problem with the money thing, aside from it being annoying to pay for code that was just copied from MSDN and stuck in a wrapper, but the blinky-beepy-gotta-be-on-top thing is driving me nuts.

The author uses an example of one guy who "knows" he wants the screen all the time, but the real underlying architectural problem is much more subtle (and worse) than that. Every program wants to tell the user something, maybe only once a month or so. That'd be fine, if there weren't dozens if not hundreds of programs running on the average setup.

I've been using Ubnutu for the last couple months, mainly because Windows has become more like a video game, an XBox, than a serious operating system to me. When I started my windows O/S up the other day to do some multimedia chore after only two weeks without running it, every program I ran had updates and notices for me to attend to, including Windows itself. That made a 5 minute job take 2 hours, including the 15-minute boot time which was drug out because once I bought a Sprint modem, Sprint in its infinite wisdom wants to intercept and rework my network stack so they can "help me" use my computer better. This involves Sprint needing updates, resetting my wifi preferences every time it runs, forcing itself to run every time on boot, rewriting my access screens, and doing something with memory, thread, and priority allocation during boot that takes 5 minutes and can only be described from the user's standpoint as evil. And for all of my invective, I know they didn't mean it that way! As far as I know, they are honestly trying to provide assistance (assistance with lots of branding and subtle control over user behavior. Sigh)

This is crazy. Windows has become like the web, only with one web page with everything you might ever want to do on it crammed in there and you can't navigate away. Somebody at Microsoft had better get on the ball and get rid of atomic updates, garbage collection, and vendor/programmer-induced interruptive bullshit. (Yes, there are ways to eliminate GC and the nightly install crapfest, but that's a longer story) If they don't, Google is going to eat their lunch. I'm afraid you can't have one O/S that is both extremely complex and consistent across millions of different use-cases. At least not structured like this.


I agree this is crazy. Windows really needs a central infrastructure for:

- program updates (polling for them, asking the user)

- user notifications (grouped, not with a zillion different icons)

- running tasks at certain times/conditions (yes, windows has this, but many apps nevertheless insist on running their own scheduler service)

- license server? (or at least, a way to launch these on demand, no need to run adobe/flex/matlab/bla license servers when the program is not running)

Right now, every program wants to install its own background process (some very bad ones want even more than one). This is very very annoying: programs that are not running at the moment shouldn't steal memory and CPU time by running something in the background.

It's too easy to turn your fresh windows installation into a ghetto. And it's not only fishy backwater programs that do this, the big commercial applications are just as guilty (yes, Adobe, I'm talking about you...).

Linux distributions and MacOSX have these things figured out for ages...


There is a way to launch services on demand. You can programmatically (and via sc.exe) query/stop/start services. It'd be no big deal for apps to start, check the license service, start if needed, and stop when exiting.

Are you saying the "high end" apps on Mac OS X don't install other processes for licensing?

Also, some of those license services allow floating licenses over the network -- maybe it's the same codebase?


Why do you think this is possible when you have basically rogue apps that will abuse any provided infrastructure? The only real way around it is to review every app and only allow trusted programs.


Since Linux distributions mainly distribute open source software, they can just unilaterally disable self-updating features in any applications that have them. But imagine the uproar if Microsoft or Apple tried to do that.


Last time I used OS X it didn't have program updates or user notifications figured out. I had to use Growl for the latter, and apps had to individually use Sparkle for the former, which is basically the same as the Windows situation. I agree that Windows should have centralized solutions for these problems, though.


Growl and Sparkle are the defacto standards for notifications and program updates on Mac. They are very nice because I can control how I am notified through Growl settings (no notifications) and apps tell me there is a new update when launching (or polling while use). A recent version of Sparkle has a new option that I think is genius, update on quit. This allows me to tell the app that when I quit it, install the update. That way I don't have to wait for the app to update and restart when I just want use the app for 5 minutes.

One problem with Growl is that if you don't have it installed, some apps provide their own notifications. Then when you don't want any notifications like me, you have to configure that in each app. So it is best to install Growl and disable notifications.

Now with the app store on Mac, Sparkle might not be used as much in the future because the app store will handle updates.

Overall, I think the OS X developer community has worked this out fairly well on their own.


With respect to Growl, it's become commonplace to have Growl support, even though OSX doesn't natively have it.


Hint: Don't install software you think is crap. If it annoys you, uninstall it immediately, maybe drop the author a note why you did so. That includes Windows. Return that modem to Sprint, let them know their software sucks.You don't really have to use it.

I don't seem to have the problems that you're encountering, because I pick and choose software. No Quicktime, iTunes, RealPlayer or other annoying BS. Blaming Windows for your troubles is folly, those automatic updates you get keep your PC and others around secure and prevent them from becoming spambots, which will affect you even if you use Linux.

>..Vendor/programmer-induced interruptive bullshit.

The minute Microsoft even contemplates that, there will be long posts on here about how MS is screwing with developers and controlling users freedom with their monopoly.

And what's GC got to do with your point?


GC is relevant because it's indicative of the problem: lots of little things add up to a big thing. It's not annoying, per se, that Norton pops up once a month to remind me that it did a scan, even though it always tries to overplay exactly how useful it's been ("Found a set of tracking cookies and disabled them! Time for virus updates! Etc.") but you do that 50 times with various programs, you got problems. GC is a very real hit in performance when the heap has become fragmented. Like I said, not a problem if you're only running a few programs, but if you're running a bunch -- especially if they are memory intensive or just poorly coded -- and every other program suffers. More to the point, the user suffers.

Going to "Programs and Features" on my Win7 box, I have over 250 programs installed. Yes, a very small number of them I don't need or want. How the heck did the "Ask Toolbar" get in there? Or MS LifeChat? But most of these programs were things I needed to have because either I purchased a piece of hardware that insisted on installing code (and usually a TSR app), I needed a utility that required an install (and might need it again), or wanted some completely other thing and it's install insisted on installing something else (Bonjour anybody?) And if I'm not mistaken, everybody with a little service or a tray icon wants to tell me something at some point in time. And most of the time that's why I'm trying to do something else. Maybe it's just me, but 99% of the time the thing I am doing is more important than the thing they want me to know.

It's easy to say that the user is somehow at fault, and I guess (?) I should vigorously spend a lot of time filtering through all my applications to make sure I always have the bare minimum? But that doesn't make much sense from a user's standpoint, does it?

I don't think of this as a freedom/monopoly thing. This is a display/gui/responsiveness architectural issue. There are simply things you can do now on Windows that you can't do on the web, and while that once was a benefit, it is now becoming a drawback. Windows needs to give the user more control and restrict the types of interactions developers can have with the user if it wants to solve this problem. Web developers have been living with these guidelines for a long time. It's nothing new or onerous. After all, if we're not in this for the users, what the heck are we doing? Perhaps the question could be rephrased: is Windows positioned as a tool for users, or as a tool for developers? Because it's not the same thing.

EDIT: Another anecdote: I bought a Sony Vaio notebook for a family member who doesn't know anything about computers and set it up for them. When you first start up the Vaio, it insists on asking you to register. Now I don't feel like registering, so I just dismissed it. But it keeps asking, and after an half hour of poking around the registry it beats the heck out of me where it's getting a hook to pop up the registration screen on boot. It is probably embedded in some of the proprietary vendor drivers. So it keeps popping up on boot, and he keeps closing the window. Every time. I guess I could spend some time with a low-level debugger and track down and "fix" it, but that's just crazy. He doesn't want to register. Go away already. Can you imagine what it's going to be like if every driver maker starts doing this? And what's going to stop them? (Please don't say windows driver certification. If you make widget X, you're going to own the drivers for it, no matter what kind of little logo you have or don't have on the side of a box somewhere)


Bonjour is the only way (to my knowledge) to get Windows to resolve mDNS (AKA Zeroconf/Avahi) names and services. Without Bonjour, you have to implement your own device and service discovery protocol and application.


MSE is a much better solution than Norton, barely any dialogs except when malicious code is detected.

GC might slow down the computer a notch, but memory leaks are way too common in frameworks that don't use GC.

This is not to say that systems with GC would have zero memory leaks, but it definitely helps.

>I don't think of this as a freedom/monopoly thing. This is a display/gui/responsiveness architectural issues. There are simply things you can do now on Windows that you can't do on the web, and windows needs to give the user more control and restrict the types of interactions developers can have with the user if it wants to solve this problem. Web developers have been living with these guidelines for a long time. It's nothing new or onerous. After all, if we're not in this for the users, what the heck are we doing?

For example, how would your proposed method restrict iTunes(which installs a whole bunch of services, startup items, etc. and tries to trick the user into installing Safari). How will this affect legacy apps? The only real solution is to move to a restrictive approval process like the App store.


Not being an active Windows user I'm not fully aware of the problem, but it sounds like you're building a duct tape defense here. Defending Norton's sins with a less well-known competitor or GC slowdowns because they're a lesser evil are both valid points

But neither approach the deeper observation that the software development community and/or conventions introduce a lot of harm in the user's perspective.

It would probably require Apple to redesign iTunes and institute a large impediment to installing legacy apps. I think that's exactly the point though, right? itunes is doing mildly hostile things and anything that's "legacy" at that point is going to be build during an era of user hostility.


A solution would be to use DirectX and request exclusive access to the screen. It's rather unlikely any of the other apps are doing this.

Using DirectShow it would not even be complex - could be done in just a few lines of code.


You remind me of that guy in the Farmer's Insurance commercial[1].

"You do realize that this is just an exercise, right?"

[1]: http://www.youtube.com/watch?v=RNY98KN4p6c


You just... don't get it, do you Scott?

(There is no way to win this game by giving the best solution to it. The better you get, the worse you get.

In other words: the only way to win is not to play the game.)


dll inject all the other programs?

rootkit and write your own display driver?


Erase Windows and it shitty ecosystem and start over with code that the end user can modify and improve?


This would beat the "enumerating all the windows in the system and calling ShowWindow(SW_HIDE)" program, but not:

"setting their program as the screen saver, disabling the mouse and keyboard devices, and then invoking the screen saver on the secure desktop."

or

"enumerating all the processes on the system, attaching to each one with debug privilege, and suspending all the threads."


The screensaver mode can be disabled. The enumerating thing will most likely lead apps to crash, so I am quite sure no other app is doing this, so it's safe to ignore.


"The screensaver mode can be disabled" - the first app wants to enable the screen saver. The second app wants to disable it. What happens?

"will most likely lead apps to crash" - you're a developer who's attempting to hack somebody else's app so that yours stays on top. This is a regular topic on Raymond Chen's blog - the kind of developer who does this isn't normally worried about a bit of crashing.


No, look at the real life constraints of the problem. The screensaver can be prevented from starting by using SetThreadExecutionState or moving the mouse. Another app can't stop you from making the system unidle.

And in the second part you're not paying attention to the constraints. If you want to simply kill all programs, that's easy in windows. The problem described above is to keep the system running, but become the topmost window. So a solution that causes crashes is not a solution.

Crashing a windows program is trivially easy, and it would "solve" the problem, but that's not the right kind of solution.


You could restart them all again after your program is done. Of course, if the other programs do more than just display a message, which is hopefully on disk rather than just in RAM, then you'd still have data loss, so... yeah.


I think disabling takes precedence over enabling. This is to prevent interruption of e.g. a movie the user is watching. I can't think of a use case where the user would want a program to start the screensaver even though another app has disabled it?


You are joking right?

Because i could still just have my process kill your process and take over exclusive screen access... there's no winning this game.


Read the article - just ending processes is not allowed because those other processes need to continue to run. If you were allowed to end processes, then there would be no issue at all.


Maybe you should read the article; the point was that there's no way to win... so suggesting solutions is just as pointless as following the rules.


Unfortunately that is not the case. Things like NetMeeting and other remote desktop control apps do the same.


The FIRST app that gains control of the screen does not allow other apps do the same. Try it. Open Windows Media Player, play a video, then open VLC and play a video. You'll see that VLC output is pixelated - that's because it's rendering using RGB and not via hardware overlay.


In such a case an IT admin remote controlling a PC, or an employee goofing off with Windows Player will prevent my app from gaining exclusivity. That does not solve the problem.

Also, exclusive access to the screen does not guarantee your program will go uninterrupted. Retaining exclusivity is impossible, because you just might get an ALT+TAB, CTRL+ALT+DEL or a WM_KILLFOCUS from who knows where. There are custom techniques for getting around each of those, but they're all along the lines of what's described in the article. Attaining and retaining exclusive access to the screen is next to impossible.


I'm not sure you get it. This is hardware overlay. It's not running in user-space, it's being moved from memory to graphic card directly. A DirectX drawn window is not affected by focus or anything else. You can stop it by killing the process.

If someone came ahead of time to prevent it from ever gaining screen access, then that would be a problem, but since the order of app launches are known and can be controlled, it would still work.


In DirectX you will lose exclusive control of the screen and all rendering surfaces if your app loses focus. Retaining focus is not possible, unless by way of trickery. Game forums are riddled with developers trying to overcome this problem.


Not with DirectShow and the VMR filter.


Alas, I still work with a program where someone had the bright idea to play tricks like this and, as a result, you can get error messages stuck completely behind an unmovable topmost window.

Thankfully, there's one slightly obscure way to get Windows to move a window that's completely behind another window, but many people don't realize there's anything back there in the first place.


And what is that obscure method?


Right click it from the task tray and select move. Your mouse cursor will jump over to the top of the window (even if you can't see the window) and you will actually move the item you selected rather than the topmost window you appear to be clicking on.

I called it "slightly obscure" because while the move option is perfectly normal, I had no idea that you could still select a window that was completely behind other windows.

EDIT: And no, "close" wasn't among the options for that error.


Or you can select the window with alt-tab, press alt-space to open the window menu, press 'm' to select 'move' and then use the arrow keys.

I use this all the time when windows go completely off screen and you can't grab them with the mouse. That can happen in all sorts of surprising ways.


And once you've moved it with an arrow key, you can then move it freely with the mouse until clicking.


on win7 you can also use the win button + arrows to snap it to edges of the screen. That is if it is sizable


It wasn't sizeable (or on Win7), but that's interesting to know.


Alt + space then hit m, then use arrow keys. Try it now on a non maximized window.


The solution to this problem is to not let programs realize that there is a such thing as a window manager. "You have an x by y rectangle to draw in. There is no such thing as `other programs'. Enjoy."

Then the end user can script these complex interactions in a way that pleases him. Composibility is better than following an arbitrary spec.

UNIX gets this: I can program all my window interactions in Haskell. When mplayer wants to be fullscreen, it gets it. Everything else... nope, sorry.

(Also, I have a solution! Run all the non-super-important programs in a VM. Then minimize the VM when your super-important program wants attention. This even composes properly when a more-super-important program comes along!)


Code injection (SetWindowsHookEx, WH_CBT) and API hooking allows to filter out other programs requesting topmost display.

But this is intrusive. And it can be bypassed by other vendors, whether they workaround it by using other APIs/tricks or unhook their own process' APIs at runtime themselves.

As said here in this thread, the only way to ensure full control is to patch the kernel (Window management related syscalls). And even there it's tricky to be exhaustive.

VM is the safe way to go.


I suppose it's issues like this that make tablet PC creators choose a single-tasking (or rather, single-app-controls-the-screen) model?


I believe XCode (I may be confusing the interface with RunRev Cards thing from a while ago though) has a simple check mark to make window a top most window on Mac. But I'm not sure if they can be scaled. Some of the Logic Pro and Final Cut tools function like this, where they are abovee everything.


What if two applications has checked this box? That's the core of this article.


Please don't.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: