Keep a reference to MessageBox? - c#

I am trying to hide all the windows of my app when a users session time's out. That works great; however, when a MessageBox is left open when the app times out the message box still is there. I want to be able to close the message box or at least hide it. I've looked up hwnds and hinstances and I don't quite know if thats what I am looking for to accomplish this. I thought this would be fairly easy as I thought MessageBox inherited from Window and of course it doesn't. And a top of that you cannot create an instance of message box to keep track of it. At this point I am not sure what to actually do or what to actually search for.
I am in the process of trying to figure some stuff out using reflection. I can create an instance of MessageBox using reflection but don't think I can call Show() using an instance.

Short answer: just create your own window that looks like a message box
Long answer:
Message boxes are normal WinAPI windows (they have an HWND and can be manipulated by the native API windowing functions) however they are not WPF windows and don't have an associated Window object.
Since they are normal windows you can get their HWND (using FindWindow/ FindWindowEx/ EnumWindows) and trick them into closing (for example, by simulating a Cancel button click)
However, because message boxes are not designed to be manipulated like that this trick has some nasty pitfalls you have to take care of.
And, because message boxes are so simple and you can easily create a message box clone it's just easier to create the close and not take care of all the message boxes corner cases.

Related

Handling WM_ events in a windowless C# process

I've been looking around for quite a while, and can't seem to find a good way to do this.
Basically I have a C# process using WPF (which has no visible window), that I need to handle WM_ events in (such as WM_CLOSE or WM_DESTROY for example; so that I can elegantly shutdown when a user chooses to log off or restart their machine).
There are a number of solutions I've seen out there that suggest using System.Windows.InteropServices to call AddHook and provide it a pointer to a function that then becomes the WndProc. The problem with this is, as far as I can tell, it depends on the window actually being visible (and in this case there is no window).
Another way that's suggested but doesn't work is to override the WndProc method of a WinForm, but this process has no visible forms or windows.
I've also found things referring to a Message-only Window. Some kind of invisible window that still receives WM_ events. From what I've seen, this is only available in a Microsoft.WindowsCE.Forms assembly. I added a reference to this assembly in my project and subclassed MessageWindow as indicated at: http://msdn.microsoft.com/en-us/library/microsoft.windowsce.forms.messagewindow.aspx but it still seems to not work. The breakpoints inside the WndProc are not being hit.
Any clue?
Think about what you are asking- if you don't have a window, how could your application receive a window message (considering that messages are sent to a window's handle).
That's like saying "how can I receive email without having an email address?"
Michael Entin covers windows' behavior during shutdown here.
I am 99% sure that all processes running in a user's session are automatically closed when the user logs off anyway, so this shouldn't be an issue. If you really must handle this window message, you can create a hidden window as per Any way to create a hidden main window in C#?

Get newly created window using Win32 API hooks

This may be a long short or not even possible but no harm in asking.
What I am trying to do is monitor an application for any new windows it creates in its MDI control. I have implemented hooking in C# and can capture the MDICREATE window message but because I need to get information about the window after is has been created the MDICREATE message isn't much help because at that stage the window hasn't been created in the other application yet.
Without going into to much detail I just need to be able to see when a new window has been created.
Is this possible?
Thanks
I'm not aware of another message that gets the info that you are looking for off hand. But if that message works for you, you could hook that message and then do another scan of the windows to find the one you are missing. You can enumerate the child windows of the parent window. Use Spy++ to see the exact window hierarchy.
If you can watch for a particular function call, I would use some kind of hooking library to grab that (EasyHook comes to mind).
You can hook the MDI create function (assuming there is one), watch for that, then inn your code, call the original and do any lookups using the returned value. You'll have access to the returned value and any parameters, so you should be able to get some info out of those.
Two options off the top of my head.
Hook the WM_MDIACTIVATE event, the first time the window is being activated, use a flag to determine the first time the window is being activated.
If you need to run your code after the WM_MDICREATE or WM_MDIACTIVATE, you can post a new custom message from one of these messages, which is then handled after these messages have completed. You then write your code to handle the custom message.

calling the user attention outside of app

I want to create an alarm app for myself. On certain conditions (i need to poll websites) i want my app to inform me and make it HARD TO MISS. So i can take appropriate action or ignore it if i need to do something else.
I wrote a test app and using a BalloonTip (ShowBalloonTip with notifyIcon) isnt great. One of my previous apps brings the window in front of you and does a MessageBox however that doesnt always work or work well (if i somehow miss it or accidentally forget to click ok no futher messages will occur).
What are your suggestions?
You could also make it a system tray application and change the icon out if there is something which requires attention, a la a messenger application. That may not be "hard to miss" but I am trained (for better or worse) to look down at the icon tray when I see something blinking.
Where I work, we have a TimeTracker application (built in house) with which developers are supposed to log what we worked on and when. I am notorious for not using it. So, I wrote my own (Windows Forms) version for my own use which, every hour opens up and takes over my screen:
It is a frameless dialog which consumes the entire screen.
TopMost = True.
On resize, it sets WindowsState = Normal and resizes to fill the screen.
While it is open, it polls for taskmgr.exe and procexp.exe and kills them if found.
It disables the start menu to prevent cmd.exe commands from the menu in Windows 7.
The only way to close it is to enter a log, only then is the OK button shown!
So far, it's working out well - no one has been able to break it!
My less drastic suggestion would be to have a notification which pops up momentarily above the system tray. After a second or two, fade it out. Keep showing the notification every 30 seconds or so until it is dismissed.
Always-on-top window in the corner of the screen?
You could always set your window to be a top most window, make it full screen, and activate it. It would be very, very hard to miss...
Granted, it would also be very annoying, and not something I'd do to other users...
My "real" suggestion would be to use sound along with standard notification methods if this is going to be used by other people, as that's an easy way to grab attention without necessarily killing their workflow. A modeless window that appears in a corner of the screen, especially if combined with sound and color, can be very effective to grab attention.
The industry has been adopting these ambient orb devices and variations of it when such a hard-to-miss notification is required. It is used for tracking the stock-market and for broken-daily-builds.
http://www.ambientdevices.com/cat/orb/MAN_Ambient%20Orb_3-23-03.pdf
Regards

how to Make a program intangable with c#?

I just wanted to know, if there is someway to make a program (or part of a program) intangable with c#. I want to make it so that people can see the program is there, but if they were to click, it would click whatever is underneath it. I would also like to know if you can do that backwords. Is there someway to make an item that is invisable, clickable?
Thank you for your help!
To your vague question, I offer a vague response:
Sounds like your option one is possible. You would need to send the click event (message) that you receive to the appropriate window (the one underneath yours). I suspect that you would have to DllImport some stuff to do this from c#.
Your option two, while more difficult, is probably also possible because you can inject code into other running executables. This will be a privileged operation, and you will likely again have to use stuff from non .NET dlls to do it from c#. See Three Ways to Inject Your Code into Another Process on CodeProject.
If you want to display something to a user without it getting in the way of whatever it was they were doing at the time you could pop up your messages in bubble from the task bar perhaps?
The answer to this question covers this. Or if you're lazy here's the code project link.
Ok so it sometimes might be necessary to show something on screen and not let it be clickable (like On-Screen-Display for video playback to show volume increase, etc..)
Here's an example of how to this in C# - from codeproject: http://www.codeproject.com/KB/cs/OSDwindow.aspx
This uses the Win32 API ShowWindow(hWnd, SW_SHOWNOACTIVATE) to present the window without losing focus (can't be selected).
And here's the MSDN page for this call ShowWindow
To display a window that is invisible but clickable you can use a window with no border (FormBorderStyle=None) and set transparency to 1%.
Hope that helps!

Windows Terminal - Windows Form to embed cmd

I'm looking for a way to embed a cmd "Shell" into a Form. I want to build a C# based application that acts as a Terminal, better than the Powershell window (no tabs) or cmd (no nothing). Just start these interpreters in the backend.
I guess MS never thought of doing this. Any ideas what From elements I could use?
Thanks,
i/o
That's not a trivial task you're undertaking. I know of one project (Console2) which basically polls the screen buffer of the underlying console window and displays in its own. You certainly will have trouble coping with interactive applications like Far and the like as they (a) rely on getting keyboard events and (b) on manipulating their screen buffer. Both are icky things if you want a suitable wrapper around the console window functionality. Mouse input is possible as well (unless Quick Edit mode is enabled) which could give you further headaches.
I doubt you can use a ready-made control for this. Basically you need to display a grid of cells each of which has a foreground and background color. You could probably use a RichTextBox for this but I'd guess it's far from ideal.
Also I don't think no one at MS ever thought of this. It's just that there's a limited budget for new features and every one of them needs to be specified, implemented, tested, tested more for regressions with millions of applications out there, etc. It's just a freaking expensive thing (if you don't want to misuse your customers as testers, which they aren't).
It would propably be the easiest to extend the Textbox class and add logic so that it behaves like a console (respond to the KeyPressed/KeyUp/KeyDown events or similar). You can also add events for those things that your console needs to respond to. For example, add a CommandEntered event.
Basing your new console on a TextBox gives you the editing and display features of the textbox "for free", so you do not need to re-implement that.
You could use a richtext box, and set the background to black and foreground to white. RTB instead of text box to handle larger amounts of data.
You would have to write an awful lot of code to simulate the terminal though.

Categories