Detecting raised-event at OS-level (OS Appearance) - c#

I have what seems to be a common problem. I am running Windows 7 Home Premium on one of the most awesomest computers (when it was bought last year) and certain visual effects just automatically turn themselves off.
My average user experience rating is high, so it doesn't explain why this happens. The only feature that ever gets turned off is the 'Show window contents while dragging' option. And it really annoys me.
There are currently no working solutions to this problem online. Other than to "there must be a conflict with another app installed on your machine."
And yes, I do know what app is causing this conflict. It's my bloody Internet Provider's software - you know... that app that you absolutely MUST have open at all times when you're connected to the net.
So, I had a thought. What if I could subscribe to an event so that my app that runs in the background will detect when this 'show window contents while dragging' option is turned off - and then my app will simply turn it back on again.
When I do this manually, it seems to stay in effect for about an hour or two, then it gets switched off again.
Is it possible to handle these types of events, and re-start certain visual effect features? If so, are there any resources on this?
I have not been able to find anything on this sibject yet.

Yes the WM_SETTINGSCHANGE message is sent to all windows when a system setting is changed. Then you can call SystemParametersInfo with SPI_GETDRAGFULLWINDOWS to determine if the "Show window contents while dragging" is disabled and use SPI_SETDRAGFULLWINDOWS to enable it.
So all that you will need to do is create an application with a form (that can even stay hidden) and override the forms WndProc and handle the WM_SETTINGSCHANGE message and call SystemParametersInfo using p/Invoke. The p/Invoke definition for SystemParamtersInfo is available at pinvoke.net
Altough what may be easier is change security on the HKCU\Control Panel\Desktop\DragFullWindows registry value so that it can't be changed.

Related

C# - Transparent Window to defeat Keyloggers

How can I create a window which is fully apparent to the user but is not visible in screenshots. I know that this is possible since Neo SafeKeys (an onscreen keyboard to defeat keyloggers) does not appear in the screenshots taken by keylogging software I installed.
To give you an idea, the window is fully visible to the user, however when a screenshot is taken, the Neo SafeKeys window does not appear at all (as if it does not even exist).
Neo SafeKeys states that it uses an invisible protection layer above the window to protect against screenshots. I have searched all over the internet to see how can I reproduce this, to no avail. Does anybody know how this can be performed (windows which is visible to user but invisible in screenshots)?
What you can do is you can prevent the PrtScn key from doing anything when pressed. Take a look at this article while shows you how to do this.
What this article is doing is clearing out the clipboard. What you can do instead is capture the screen image and digitally remove your application, then put the revised image on the clipboard, thus giving the "Effect" of making your window transparent.
Also, you might want to look at this SO question which gives an alternative way to make your window just appear "blue", though its not easy to do.
Does anybody know how this can be performed (windows which is visible to user but invisible in screenshots)?
Use DirectX to render directly to the device.
In your C# application you can set up a global hook to monitor keyboard events. Then your application becomes the global handler for print screens. Now if another application managed screen prints natively, can't stop that, but anything running through windows, you can get at.
The WM_KEYBOARD_LL hook is one of the few global hooks that can be used in managed code because it doesn't require a DLL to be injected into every target.
For some code you can visit here:
Adam's Blog
Keep in mind that these are global hooks so you want to make sure nothing else (other applications) are effected. I've used these in the past as we hosted showing a power point in an application we worked on. Basically we didn't want the user to invoke any powerpoint menus or keyboard short cuts so we used a global hook. We always checked to see whether the users was in a certain area (screen) and in our application, otherwise we would effect other applications functionality (including our own!)
Microsoft Information:
Hooks Overview
There's this.....
visual cryptography
live example here
But this could be easily coded against by taking multiple screenshots and laying them overeachother and such...
If you are using Windows, and you can avoid that screenlogging happens, you can implement a nice solution like a virtual desktop to embed your process into it. When a process is running inside a virtual desktop it is possible to bypass an screenlogger tool that runs over win32 Api.
Check out this article so you can sneak a peek how to implement a nice solution to scape from screen and keyboard monitoring.
http://www.codeproject.com/Articles/7392/Lock-Windows-Desktop?fid=62485&select=3139662&fr=101#xx0xx

stop auto hiding tray notification icon

Whenever my windows forms application runs for the first time, the tray icon stays visible for about less than a minute, and then it autohides, what can i do to make it stick and not auto hide ?
I tried searching and can't find any useful information.
It appears that this is the default behavior for windows 7 and above, I wonder if there is a way to override that behavior from inside my application ?
There is no supported programmatic way to override the system's default show/hide notification icon behavior. MSDN:
When an icon is added to the notification area on Windows 7, it is added to the overflow section of the notification area by default. This area contains notification area icons that are active, but not visible in the notification area. Only the user can promote an icon from the overflow to the notification area, although in certain circumstances the system can temporarily promote an icon into the notification area as a short preview (under one minute).
Emphasis mine.
As you've no doubt read the discussion in the comments, there is indeed no supported way of doing this. That said, if you're determined and you have the time to do a little digging, I'd recommend using a few tools to bypass the documentation and looking at what's actually happening under the hood with the notification setting. There may be appropriate documentation on this but I've not found it.
The brute force approach would be to use SysInternal's RegMon tool to view all registry access . If you tie it to the "Explorer.exe" process, you will see all relevant information on what the desktop and start bar are doing, including any file access. Make no mistake - this is a brute force approach and will require a lot of effort and digging. Once tied to the explorer.exe process you can make changes to the notificaiton settings. Viewing and investigating the changes made by the process will give you an idea of where the relevant settings are stored and how. The downside is that there's going to be a lot of data to trawl through and investigate to find out what's going on but it can be done. This is not an ideal solution but if no other is forthcoming you're left with the rough and ready approach I'm afraid. It comes down to how much effort you want to put into a solution to this.

WPF application unable to handle remote desktop resolution change

I'm working on a .NET 4 WPF application, and just the other day, came across a very peculiar bug. I have three Windows 7 Pro machines involved: laptop (1366x768), desktop (1680x1050, multi-monitor), and the remote machine (resolution unknown). Our application is installed on the remote machine.
Consider the following events: I remote desktop into the remote machine from my laptop, start our application, and launch a particular feature (an mdi child) within the application. If I connect to the same remote session from my desktop (thus closing the session on my laptop), this feature within my application becomes completely unusable. By unusable, I mean combo box drop downs are showing in the top/left corner (much like what's described here), other controls aren't laid out correctly, and some controls don't even show at all. Mouse coordinates appear to be off in that clicking certain controls no longer invokes the appropriate actions. It's the strangest thing I've ever seen.
If I close the application and launch a new instance on my desktop, things work great. Also, it only seems to happen when I launch the feature on my laptop, then move to the desktop. Never the other way around.
I wish I could show some code, but I don't really even know where to start or what to show. I can say that it only happens on certain features. Some features handle the resolution change perfectly.
Has anyone else seen these types of symptoms? Or know what could cause them or how they could be fixed?
This is a little embarrassing. After a few hours of "process of elimination", I found that another developer had added some unmanaged code to automatically maximize the window. The approach they followed is documented here. This approach does not work through remote desktop sessions. Lol.

Programmatically (first-time!) enable aero theme/desktop composition

I want to enable desktop composition on a Windows 7 machine programmatically (preferrable C#) and already tried to do it with the infamous DwmEnableComposition P/Invoke. However, this does not seem to work if DWM has never been enabled (and the performance test has not run). I can, however, enable DWM via the "Personalization" control panel w/o running the performance test.
My question therefore is: how can I do the same programmatically? And a second question: how can I achieve that a change in the setting is persistent (e. g. if I set DwmEnableComposition(false) on a machine that has DWM enabled, it is re-enabled once the application exits)?
I found a less nasty solution than my first one: Invoking winsat dwm will turn on Aero automatically once it finishes and if the hardware supports it - and it does not change the wallpaper etc.
The answer is: You cannot do that.
Microsoft does not expose a programmatic way for programs to enable or disable desktop composition on the user's machine.
The reason they don't provide an API is that programs might use it.
In the past Microsoft trusted developers not to do the wrong thing. That has changed
Because programmers were trusted to do the right thing
DwmEnableComposition is only for your application to temporarily disable DWM if you aren't compatible with composition. It cannot be used to turn on composition, when the user has already turned it off.
Any computer sold in the last 5 years is graphically capable of using composition, and Windows turns it on by default if its supported. The only reason it would be turned off is:
the user turned it off
another application is running that doesn't support composition
In either case: you should not (and therefor cannot) turn it on.
You cannot do that.

Prevent Process 'A' from spawning Process 'B' which then shows up on top of what should be the "TopMost" Process 'C'

I have a windows form application which needs to be the TopMost. I've set my form to be the TopMost and my application works as I'd like it to except for in one case.
There is a 3rd party application (referred to as player.exe) that displays SWF movie files on a portion of the screen that popup on top of my application.
Using Process Monitor I determined that player.exe application calls
flash.exe <PositionX> <PositionY> <Width> <Height> <MovieFile>
in my case:
flash.exe 901 96 379 261 somemovie.swf
Since flash.exe is being spawned in a new process after my form has been set to the TopMost it is appearing on top of my application.
First thing I did was make my application minimize the player.exe main application window hoping that this would prevent the Flash from appearing also. But, unfortunately it doesn't... even with the window minimized whenever the flash movie starts it shows up at the pixel location (901,96). I then tried creating a timer to keep setting the form.TopMost property to true every 10ms. This sort of works but you still see a very quick blip of the swf file.
Is there some type of Windows API call which can be used to temporarily prevent player.exe from spawning child processes which are visible? I admit it sounds a little far fetched. But, curious if anyone else has had a similar problem.
Addendum:
This addendum is to provide a reply to some of the suggestions layed out in Mathew's post below.
For the emergency situation described in the comments, I would look at possible solutions along these lines:
1) How does the third party application normally get started and
stopped? Am I permitted to close it
the same way? If it is a service, the
Service Control Manager can stop it.
If it is a regular application,
sending an escape keystroke (with
SendInput() perhaps) or WM_CLOSE
message to its main window may work.
Easiest way to close the app is to CTRL-ALT-DEL, then kill process. -OR-
The proper way is to Hold ESC while clicking the left mouse button... then input your username and password, navigate some menu's to stop the player.
There is no PAUSE command... believe it or not.
I don't think using WM_CLOSE will help since minimizing the application doesn't. Would that kill the process also? If not, how do you reopen it.
2) If I can't close it nicely, am I permitted to kill it? If so,
TerminateProcess() should work.
I can't kill the process for two reasons. 1) Upon relaunch you need to supply username/password credentials... There may be a way to get around this since it doesn't prompt when the machine is rebooted but... 2) Whenever I kill the process in task manager it doesn't die gracefully and asks if you want to send an error report.
3) If I absolutely have to leave the other process running, I would try
to see if I can programmatically
invoke fast user switching to take me
to a different session (in which there
will be no competing topmost windows).
I don't know where in the API to start
with this one. (Peter Ruderman
suggests SwitchDesktop() for this
purpose in his answer.)
I got really excited by this idea... I found this article on CodeProject which provides a lot of the API Wrapper methods. I stopped implementing it because I think that in order for desktop's to work you must have explorer.exe running (which I do not).
EDIT2: On second thought... maybe explorer.exe isn't needed. I'll give it a try and report back.
Edit3: Was unable to get the code in that article working. Will have to put this on hold for a moment.
Answer Summary
As one might have expected, there is no simple answer to this problem. The best solution would be to problematically switch to a different desktop when you need to guarantee nothing will appear over it. I was unable to find a simple C# implementation of desktop switching that worked and I had a looming doubt that I would just be opening a whole new set of worms once it was implemented. Therefore, I decided not to implement the desktop switching. I did find a C++ Implementation that works well. Please post working C# virtual desktop implementations for others.
Setting the TopMost property (or adding the WS_EX_TOPMOST style to a window) does not make it unique in the system. Any number of topmost windows may be created by any number of applications; the only guarantee is that all topmost windows will be drawn 'above' all non-topmost windows. If there are two or more topmost windows, the Z-order still applies. From your description, I suspect that flash.exe is also creating a topmost window.
Aside from periodically forcing your window to the top of the Z-order, I think there is little you can do. Be warned, however, that this approach is dangerous: if two or more windows are simultaneously trying to force themselves to the top of the Z-order, the result will be a flickering mess that the user will likely have to use the task manager to escape.
I recommend that your program not attempt to meddle with other processes on the computer (unless that is its explicit purpose, e.g. a task manager clone). The computer belongs to the user, and he may not value your program more highly than all others.
Addendum:
For the emergency situation described in the comments, I would look at possible solutions along these lines:
How does the third party application normally get started and stopped? Am I permitted to close it the same way? If it is a service, the Service Control Manager can stop it. If it is a regular application, sending an escape keystroke (with SendInput() perhaps) or WM_CLOSE message to its main window may work.
If I can't close it nicely, am I permitted to kill it? If so, TerminateProcess() should work.
If I absolutely have to leave the other process running, I would try to see if I can programmatically invoke fast user switching to take me to a different session (in which there will be no competing topmost windows). I don't know where in the API to start with this one. (Peter Ruderman suggests SwitchDesktop() for this purpose in his answer.)
You can use the Process class to start flash.exe directly - and use an appropriate ProcessStartInfo settings to show the window in a hidden state - or with a WindowStyle of hidden or minimized.
You could also consider using the SetWindowsHookEx API to intercept the process start API calls, and when the process is flash.exe run some code to restore you window to top-most status.
Matthew's answer is excellent, but I suspect you may be asking the wrong question. Why does your application need to be topmost? If you're trying to create a kiosk or some such, then topmost is not the way to go.
Edit: After reading your response to Matthew's comment, I'd suggest creating a new desktop and switching to it before displaying your alert. (See CreateDesktop and SwitchDesktop in MSDN.)

Categories

Resources