How would I open a program inside of a windows form? - c#

I want a program, let's say google chrome, to open inside of a windows form but not be able to be moved outside of the form or seen on the taskbar.

You can't embed arbitrary applications into yours, unless they provide an API for that. If you want to embed a browser, take a look at WebBrowser control or Awesomium project that happens to be a .Net wrapper for Chromium.

Although rather hacky, this can be done by using the SetParent ( http://msdn.microsoft.com/en-gb/library/windows/desktop/ms633541(v=vs.85).aspxwindows ) API function.
I have done this when I've needed to integrate with a buggy video libraries which would crash periodically. It was not acceptable to have the main user interface crash when the video library died so I spawned another application to show the video, and parented it to a window in the main application.
Once parented you may want to use other functions to move it around or resize it e.g. MoveWindow.
Using this method can have some side effects which you may need to manage.

Related

interact with external application in c#

I was playing around with Microsoft Spy++ and noticed that not only does it find the open processes, but can find the individual components running in each process. For example there is this application that allows you to open a window in which there is a textbox for an IP address and textbox for a port. Spy++ can detect these components. Knowing that Spy++ can detect them, is there anyway possible to find them in a separate c# application and go on to MODIFY their contents and otherwise interact with the program? (such as firing a click event on a button)
This is feasible. Try use PInvoke (InterOp) or AutomationElement, or AutomationPeer (for WPF applications) to automate all you wish to do.
Also you might wish to try Inspect and UISpy application as well.
Automation elements/peer is a non-intrusive mechanism to control UI using accessibility framework. One of the weaknesses in windows is its lack of defence against code injection. Put simply:
As a privileged user,
- You can Open and Modify a running Process image
- Make it load your OWN DLL
- Make it run your OWN thread (that potentially listens to commands from your process) and
- allows you to read any bits of memory you want.
Look at detours (http://research.microsoft.com/en-us/projects/detours/) for how to do it with Managed Processes.. Unfortunately, Microsoft removed the inject at runtime features.
Also look at http://msdn.microsoft.com/en-us/magazine/cc163617.aspx for doing things in the managed world (Apps like Snoop utilise that)

Windows Form as child window of an unmanaged app

I am looking for a way to embed Windows Forms applications written in C# in a C++ windows application. The native application main window is subdivided into several panes. The C# app is supposed to appear within one of those panes, i.e. the root window of the C# component (the outermost form) must be a child window of the main application.
Can this be done? If so, how?
Some additional context: To my knowledge, there are two ways to go about this. First, host the CLR in the native app by using the .net hosting APIs (ICLRRuntimeHost, etc.). Second, host the CLR by putting the windows form in an ActiveX control.
Regarding the first approach, I have managed to get the CLR started up and to load a C# assembly (thanks largely to Mattias Högström). Where I am hitting a road block is that I see no way how to tell the component I am running in the CLR that it needs to be a child of a window passed in from the C++ side.
I have also experimented with the second method (using ActiveX and thanks to Daniel Yanovsky). It almost, but only almost, works for my purposes. I can let arbitrary Windows Forms components run in a child pane of the native app. BUT they always run on the main thread of the main app. This means they use the windows message loop of the main app. MSDN says this will not work reliably since the standard Windows message loops don't meet the requirements of Windows Forms (I wanted to post the link to MSDN here but have already used up my new-user-two-link-allotment).
The exceptions to the message loop issue are, according to MSDN, Internet Explorer and MFC apps. The native app I am using as a host is definitely not Internet Explorer. Also, it uses the windows API as wrapped by wxWidgets so MFC is not (or at least not a welcome) option.
The solutions Microsoft proposes involve letting the C# components run in their own message loops on their own threads. This, at least as far as I can tell, necessarily leads back to the first approach mentioned above. So I am back to the question of getting a Windows Form to work under a passed-in parent window.
Again, I am interested in any input that clarifies the child window issue, independent of the approaches I have mentioned here. But in light of the context I could reduce the general question to two specific questions (and I would need an answer to only one of them):
Given a Windows Form hosted in an ActiveX control, how can I allow the form to run in its own message loop on its own thread?
or
Given a Windows Form running in a CLR hosted by a native app, how can I make the form be a child window of a window in the native app?
yes, it can be done. We did the same thing years ago. This is our approach: .NET control also has native window handle, we get these handles through C++/CLI and pass them to Win32, and add these handles as the children of native windows. So the .NET controls run on the main thread of the main app, the problematic part is the message loop, as you have mentioned in your question. We need route the message between the nation and .NET windows if needed. As I remembered, we fixed a lot of bugs related to this, and still there were some mysterious problem we didn't figure out.
There's anothe way: using WPF interop. http://msdn.microsoft.com/en-us/library/ms742522.aspx . According to MS, this should fix the message problems, but we didn't try this approach. You can just use Win32 to host WPF, then use WPF to host Winform.
So for your last 2 questions:
You can't. Only one message loop.
Use handle. This article talks about the handle of Windows Forms: http://blogs.msdn.com/b/jfoscoding/archive/2004/11/24/269416.aspx

C# PInvoke and QWidget

I have an application that I am trying to automate on Windows. I need to find the location of a window that is running inside the application, and then automate a couple of mouse events on the application.
In a previous incarnation of the software that I am automating, I was able to search for child windows of the process which were named using the GetWindowText WinAPI function from C# (in combination with GetWindowTextLength).
The software manufacturers have now updated the software and updated the way that the child windows are drawn. Now each window lacks a caption, and has a class name of QWidget. I can no longer use my old strategy to find the child window location. I presume the use of QWidget means the windowing system uses the Qt framework.
Is there any way of pulling any data from the QWidget using PInvoke that I might be able to identify my windows with?
There's a couple problems here. One is that you can't get "unshared" data from another process. You can get at window data by pinvoking methods like GetWindowLong; but unless you know specific data about what QWidget does in that data (the other problem), there's not much you can do with the data.
Another problem is if you want to use most QT objects in a managed application (you can do this with C++/CLI and IJW) you need to initialize A QT Application object in your application... I'm not sure how this would impact what you want to do.

open a .exe as a window in an mdi form?

I wanted to create a program that would allow me to open instances of a already exsiting program (i just have the exe) as windows inside (i belive its called mdi)
Is that something i could do? can anyone point me to an example?
Thanks
Maybe this is the answer you are looking for here. It can be done...look in the sample on that link given.
Hope this helps,
Best regards,
Tom.
When Windows starts a program its parent is the Desktop Window.
If you could somehow manipulate that, it may work.
However, I doubt it is possible, as why would I want to allow you to run my application in your window? Especially MDI? Besides that - running in a child window isn't quite the same as running in the "main" window.
Having said that there is an application out there (can't think of it's name OH) that does place individual applications in tabs. Pretty nifty if you're not on Windows 7. The folks over at the Business of Software forum might be able to help you find it.
Well, after starting the app and storing its PID, you could start monitor the windows that get created, either thru a CBTHook or by just using a timer and the GetWindows to find when a top level window gets created by the PID in question.
Then you can use SetParent to make that window a child to your MDIChild (I doubt you can make it your MDIChild directly).
That should get you going. What you'll run into after that I really don't know. I guess you must correlate any movement of either your app or the external app so that thir windows appears to be stuck together...
Maybo you could strip away the caption from the external app (Get/SetWindowsLong). That could make it look better...

Detect and Prevent Overlapping Windows in C#

Anyone know of an efficient way of detecting movement of any windows currently open on a windows system? I need to detect a window's movement, determine if it collides with my applications Form, and bump it out from underneath if necessary.
I know I can scan through an enumerated list and check each window -- but that is way to intensive to perform constantly.
Background:
I have a taskbar-esque application that docks on the side of a user's screen. When the "Always on Top" feature is on, maximized windows will take up the remaining available space without covering the toolbar, as expected.
However, if you drag a non-maximized window over the toolbar, the application goes behind the toolbar (also expected), but you can no longer grab onto the title bar to move it back -- the window is stuck unless you disable "Always on Top" and then move it. So, I want to bump the window out from underneath.
Although not a direct answer, one possible solution to this is to create your application as an application desktop toolbar rather than a regular window. From the docs:
An application desktop toolbar(also called an appbar) is a window that is similar to the Microsoft Windows taskbar. It is anchored to an edge of the screen... The system prevents other applications from using the desktop area occupied by an appbar. (emphasis added)
This may not be a great fit for your scenario because it is oriented towards COM and unmanaged code rather than managed apps: however see this CodeProject article for info about using this feature from C#.
Failing that, you could try installing a hook (see SetWindowsHookEx) and listening for move messages but this is pretty low-level...
Try checking your PaintEventArgs ClipRectangle ..
(edit: and/or WindowFromPoint shooting match)
You can get notification of window movements using a CBT Hook: http://msdn.microsoft.com/en-us/library/ms644977(VS.85).aspx
http://www.codeproject.com/KB/dialog/FindWindow.aspx?msg=3262771
"FindWindow By Jörg Bausch"
Will get you the external (not your app's) window ID (IntPtr) the mouse went up over from within your C# application. For the desktop, and everything else on the desktop, it will return the same pointer (you can't distinguish, using this code, between as mouse-up on a folder, the desktop, the Recycle Bin).
http://www.codeproject.com/KB/cs/globalhook.aspx
"Processing Global Mouse and Keyboard Hooks in C# By George Mamaladze"
Will allow you to create GlobalHook for keyboard and mouse-events in C#. I've used it recently in VS 2010 beta 2 : it is NOT USABLE compiled against FrameWork 4.0, but does compile and work okay against FrameWork 3.5 and lower. If you download only George's demo app, be aware the download doesn't include the required dll, and will fail when you launch the .exe file (which I have brought to George's attention).
I've never worked with a "desktop application toolbar;" I hope this is relevant.
best,

Categories