This question already has answers here:
Keep window on top and steal focus in WinForms
(5 answers)
Closed 9 years ago.
I'm developing a simple program that reads a card or a barcode and logs that on a database. Before, I developed the same application in Visual Basic and it was working great, but due to a lot of changes on our servers, we decided to develop this app in C#.
I can get my application to start with Windows putting its shortcut on 'startup' of the start menu but the problem is that its not getting focus so that the cards and barcodes can be read and that way my program is simply useless. The machines we use are running Windows XP and Windows 7.
How is the best way to start my application on Windows Startup and keep the focus in it?
This is, in general, a pretty bad design. I just finished a project involving barcode readers and set them up to act as serial ports, instead of keyboards. You should check whether this is an option with your hardware, as the end result will be much more reliable.
That being said, you can create a timer in your form that executes this.Focus() and this.BringToFront() to steal focus. Be aware that this will, by default, only cause the task bar to flash. You'll need to use TweakUI to enable focus stealing.
Another option is discussed here on SO. Very similar question, actually. Basically, you hook the keyboard input at a low level.
Please try and find another way, monitor system events or use a polling mechanism.
Stealing focus should be avoided, read this to understand why
If I had a dollar for every time I typed a password, cleartext in the wrong application because it stole focus...
On Form Activated Event call This.SentToBack()
Related
I am currently trying to get real-time keyboard input (both press, hold, and release) in a C# console application. I've found a way that works using only Console.ReadKey(). Problem is that windows sets a delay before a key is repeated. I have found various other questions asking how to change this in code, but all the answers simply tell you to use the built in press, release, and hold events in a windows forms application. I can't use those in console.
As a note, i do not know much about API coding or DLL's.
See this previous post by me for further motivation if you need it to answer: C# Console application: Console.Readkey() has odd initial skipping behaviour on high framerates
I'd like to make my own custom program run on windows 10 in replacement of the start screen and logon screen.
Is there any way I can do this? I've currently replaced the accessibility program (accessible from the logon screen) with a command prompt, if I accidentally lock myself out (it has happened once!).
I recall seeing a particular Winlogon.exe. Is this my starting point? Am I able to replace the program that windows runs with my own?
Also, wrapping up, If I manage to replace this program, can I logon to windows in my program? I'm writing it in c#.
Old post, but still relevant...
I don't know if you can, or should replace it, but you could write an overlaying app to cover it and do it's own thing, if you can use a little windows command-line magic combined with node.js. More of a work-around, but then you won't chance destroying any os-specific functionality, and it seems to be universal from Vista on up (to my knowledge at least). Here is how you can get your starting point to run a GUI app on the logon screen.
Node-Windows - Run GUI app on Logon screen
You can use this technique to run any app in any language that you can open it's window from a command-line.
There will be a brief period where the normal logon screen will be visible before your app starts, but this will let you do it.
Whatever language you use for your logon GUI, you will need to send simulated key input to the real logon screen, possibly mouse-clicks-- but you can likely use simulated tabs to get to the right logon. Likely MS has API's for C# as well as a variety of related dialects to programmatically logon to the desktop in a more elegant fashion than this last part, however.
Your app will be running as the SYSTEM user (unless you specify otherwise), therefore it will be running with the highest authority-- so you can basically do anything that is possible from there. Permissions won't stop you. Be careful with this.
Is there a practical way to set the global status message in Pidgin for Windows from .NET?
Dbus is not available in the Windows version of Pidgin.
Searching SO and the net has revealed helpful tips such as "rewrite libpurple in C#", which might be a bit beyond my time/enthusiasm level for this project at least...
Thanks
how about writing a plugin, and have it expose a way for your other program to pass the status to it. Could be a file that you write the status to, or maybe a local tcp port (if you can do that in plugins).
Have you considered simply simulating keyboard input to the Pidgin window using C#?
You will need to find the Pidgin window programmatically and then set your status by sending simulated keyboard input to that window handle.
A good Microsoft example of how it was done with Calculator:
http://msdn.microsoft.com/en-us/library/ms171548.aspx
As I recall, Pidgin will set your status if you simply put the main window (buddy list) in focus, start typing, and then press Enter. Simulating this keyboard input should be quite straightforward.
A dirty solution (that future versions of Pidgin might break), yes, but certainly MUCH easier than writing a plug-in or making your own libpurple wrapper.
I want to detect if the system is idle, ie: user not using the system. I want it like the Windows Live Messenger it changes automatically to away when I leave the computer for a time like 3 minutes, I want to set this time within the code.
I`m working on the WPF under C# environment using both visual studio 2008 and 2010 so if here is a way that work on both that`ll be great.
There's an article on CodeProject that should get you started.
I've provided an answer for detecting inactivity and activity in WPF and it might be interesting for you:
WPF inactivity and activity
Windows does provide some API's for that, although they're not reliable for multiple sessions or something like that.
What I used is a hook to WW_MOUSE_LL with SetWindowsHookEx(); That's in C. Must be pretty similar for C#. Basicaly whenever the user does something with the mouse, the timer starts from 0 again, and if the timer reaches some value, you do something upon that(act-if system is idle). You could also hook it with the keyboard, in case the user is just typing, and share the timer between the two threads. It works wonderful for me.
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.)