The following code is how I initiate the program:
System.Diagnostics.Process fooProgram;
fooProgram = System.Diagnostics.Process.Start("foo.exe");
Now I know that you can set the StartInfo parameters to have the program run hidden but is there some way to hide it and bring it back during processing as I only want to show certain screens to the user and then I want it to automatically hide itself when the information has been shown. I was hoping for something as simple as fooProgram.Show() and fooProgram.Hide() but it appears that it is not quite that simple.
Simply sending it behind the other program and bringing it back to focus would be enough as well, however this also doesn't seem to be in the list of available actions.
The program being launched is a .NET 4 form.
I don't think you can do this in .NET - you'll need to use interop.
Check out these functions:
FindWindow
ShowWindow
SetForegroundWindow
SendMessage
So you'll use FindWindow() to get the window handle and then you'll execute those other functions on that handle. In terms of exposing those functions to C# check out this awesome interop website: pinvoke.net
Also, instead of HWND use IntPtr.
Related
I am attempting to determine whether a Window with the Class Name of "Static", CONTAINS "Scan finished." via .NET/C#.
Specifically, I have automated the use of RogueKiller and would like to detect when the "Scan" is done.
I have tried numerous PInvoke methods, but nothing I can find allows me to do (pseudo) Caption.Contains("Scan finished");.
Any help would be wonderful!
The Window Structure Works as:
Parent (RogueKiller™...etc)
Windows - Class:Static, Caption:
Scan finished. Please look at the different tabs and delete items with the buttons
I need to detect "Scan finished".
I think you want to call EnumWindows and call GetWindowText in your callback. I hesitate to copy/paste another StackOverflow answer. So for a detailed example, see How can I use EnumWindows to find windows with a specific caption/title?
I have a application in which i want to open a calculator on a button click and once the operation are performed on calculator and calculator is closed, I want that value back to my text box.
How can I achieve this functionality.
private void btnDollarTransferHelp_Click(object sender, EventArgs e)
{
System.Diagnostics.Process myProcess = System.Diagnostics.Process.Start("calc.exe");
}
I am using C# 4.0 and its a window based application.
Regards and Thanks
You may use the Microsoft Script Control to implement the calculator functionality in your C# app. The control has a simple Eval() method to evaluate expressions that may range from simple "2+2" to VBScript commands. More information here:
http://msdn.microsoft.com/en-us/library/aa227637(v=vs.60).aspx
It is indeed simpler to implement a calculator in your app: reading the content of another's process window is not trivial! And being notified when the calculator is "about to close" is even harder.
It involves, for sure, widows API (FindMessage/SendMessage) (see for example https://stackoverflow.com/a/360247/863564), probably P/Invoke, probably even hooking calc.exe (the technique used by Spy++ -- you need it to capture the WM_CLOSE message - see here what happens when you are closing a window)
(You need to capture WM_CLOSE, because it is the latest sensible moment to grab the result from the control on the window)
So, the alternative: a great one is scriptcs, but it may be well too much! A quick search revealed
some
great
projects
Either way, have fun!
you could use an existing library e.g. http://nclac.codeplex.com to provide calculation within your application.
We have an old Windows 32 bit app written in C++ which does some stuff and displays the results in what resembles a textbox.
I have been ask to write an application in C# that reads the data out of the old app and then further process the data.
The issue is how do I read the textbox in the old application?
Someone told me I can get the “handle “of the application using windows API and step through the controls and then read each ones data! Is this true and if so how would I do it from C#?
This is to be a .Net 4 Windows forms Application.
Many thanks
You're probably going to have to use some Interop calls to accomplish this, specifically using a combination of FindWindow / FindWindowEx and SendMessage & WM_GETTEXT / WM_GETTEXTLENGTH.
Here is an article on the subject (in c++, however the same concepts will just need to be ported to use P/Invoke), it's a bit dated but I believe is should be very relevant to your situation.
You can use Spy++ application (comes with VisualStudio) to inspect your native application and find class name of control you are looking for.
Having that, you can get your native application's main window handle, which is easy if you are responsible for launching that application from your c# app:
...
var proc = Process.Start();
var mainWndHandle = proc.MainWindowHandle;
Otherwise, you will have to find other means of finding that window, fe. you can use function that I've described below to look for that window on your desktop (see msdn page for more info)
If you have all that, you can then get handle to the textbox control, using FindWindowEx function (as well as you can use it to find main window, by passing NULL as a hwndParent).
And when you have handle to this textbox, you can read it contents, by sending message of WM_GETTEXT.
If you haven't been PInvoke'ing much, you can check http://pinvoke.net/ for reference on how to call WINAPI function from your c# program.
Do you really need the UI of the C++ application? Because it will be very unconfortable to have 2 separate UIs with different message pumps. You'll need to syncronize this mess on the update of the value.
Why don't you properly strip the logic code from the C++ application and expose it in a Interop CLR project (C++/CLI)? If you don't need to add more features to the C++ app, it seems very straightforward to me
I m using c# and I want to make a window a modal one and I want to use methods from Windows API for that.
The SetWindowPos function can make a window a top most one, but I couldn t find a way to make it modal...
Is there a way to do so with SetWindowPos or if not, is there any other windows function to do so?
Considering that your question is tagged c#, you have the entire .NET Framework at your disposal, which provides built-in functionality for displaying windows (forms) as modal dialogs. There's no reason you should have to call functions from the Windows API to do this.
In general, the only reason to P/Invoke functions from the Windows API is to use features that were not already exposed through managed code. The average application will have to do this only rarely, and basic use cases like showing a modal dialog certainly does not require it.
The way to do this in C# (or any .NET language) is to change the way you show the form in question. Instead of calling the Form.Show method, you should use the Form.ShowDialog method.
There are two overloads available. The first accepts no parameters and sets the owner of the dialog box to the currently active window. The second accepts a single parameter that specifies the window that will own this dialog.
The Form.Modal property provides a quick way of checking to see whether or not the form is displayed modally. As the documentation notes, however, it is read-only. The only way to display a form modally is to call the ShowDialog method, as discussed above.
As far as a Windows API solution, there isn't any such function that you can call. A window cannot be transformed into a modal dialog after it has been created. You have to display it that way initially. In a Win32 application, you do that by calling the DialogBox function (as opposed to CreateDialog).
MFC shows a modal dialog using the CDialog::DoModal function, but it doesn't truly show a modal dialog. Instead, it uses a hack to create a pseudo (or simulated) modal dialog that involves disabling the owner window, running its own message loop inside the DoModal method, and waiting for a pre-defined series of events that causes the modal loop to exit gracefully. I do not recommend doing this in your own application. It's simply not necessary, and it's too easy to get wrong. There are/were enough bugs in the MFC approach, and that team had the full knowledge of the Win32 internals at its disposal.
The ShowDialog method in WinForms works on a model very similar to that of MFC. Hans's answer here provides additional information. Do note that if you're going to implement your own modal dialog loop, you need to remember to re-enable the
owner window first, and then destroy the modal dialog. If you don't do this in the correct order, you'll end up with the wrong window having the focus. Microsoft's Raymond Chen posted a blog entry about this: The correct order for disabling and enabling windows.
EDIT: Added more information, based on comments from asker.
I'm not sure why you need the wrapper you've created to customize the save dialog to be a UserControl. It's not a control, the user isn't going to interact with it on your form. You're only going to show it from your code. Thus, I think the better option would be to create a new class, call it something like SaveDialogHelper, and expose a static method called ShowSaveDialog or something like that. For example:
public static class SaveDialogHelper
{
public string ShowSaveDialog(IWin32Window owner)
{
// Fill the OPENFILENAME struct, and do any necessary customizations
// ...
// Show the save dialog
// ...
// Return the path that was selected by the user
// ...
}
}
Notice that the ShowSaveDialog function accepts a single parameter (owner) of type IWin32Window, just like the ShowDialog method(s) in the .NET Framework. When you call that function, just specify the form that you want to own the dialog:
SaveDialogHelper.ShowSaveDialog(this);
And inside the function, you can extract the window handle (hwnd in Win32 terminology) using the Handle property, and set the hwndOwner member of the OPENFILENAME structure accordingly:
hwndOwner = owner.Handle;
You can't make it modal if it was not upon creation. But you can achieve similar effect by disabling its parent owner.
When enumerating windows using EnumWindows, I get hundreds of handles instead of one per open window on my desktop.
First of all, i am curious if this is the correct behavior.
Secondly, trying to get a difference between open windows before and after launching a process returns 15-20 new handles. I am wondering if there is a way to filter these based on some flag, i really need just the mainwindow handle.
Any ideas?
To get the main window of a process, use the Process.MainWindowHandle property.
To answer your question, you can see exactly what all of the handles are using Spy++.
In short, many applications will create hidden windows to run message loops.
You can filter within the enum callback by checking IsWindowVisible() & ignoring invisible system/message sink windows.