unhide window

  • Thread starter =?ISO-8859-1?Q?M=E9sz=E1ros_Tam=E1s?=
  • Start date
?

=?ISO-8859-1?Q?M=E9sz=E1ros_Tam=E1s?=

Hi all,

how can I set an app's main window to visible from an other application?
My problem is, that I know only the handle of the other app's main
process, because the application's main window is set to hidden, so it
doesn't have a mainwindowHandle, so I can't send a message to it.

Any idea?

Thank's in advance,

Tamas Meszaros
 
D

Dave

because the application's main window is set to hidden, so it doesn't have a mainwindowHandle

The main window of an application cannot be "hidden" if it doesn't exist. If the app has a main window, that is not visible, then
it still has a handle.

To set the visibility of a window in another process using the handle of the window:

/// <summary>Sets the visibility of a window. This method allows one process to set the visiblity of a window owned by another
process.</summary>
/// <param name="cmd">SW_SHOW = 5, SW_HIDE = 0</param>
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError=true)]
static extern bool ShowWindowAsync(IntPtr windowHandle, int cmd);
/// <summary>

/// Async version allows show window cross-process.

/// </summary>

[DllImport("user32.dll", SetLastError = true)]

private static extern bool ShowWindowAsync(IntPtr window, int cmd);
 
?

=?ISO-8859-1?Q?M=E9sz=E1ros_Tam=E1s?=

So, I try the following:

string proc=Process.GetCurrentProcess().ProcessName;
Process[] processes=Process.GetProcessesByName(proc);
if (processes.Length > 1)
{
Process p=Process.GetCurrentProcess();
int n=0;
if (processes[0].Id==p.Id)
{
n=1;
}
IntPtr hWnd=processes[n].MainWindowHandle;
...
}

But hWnd = 0, if the MainWindow is invisible, so I can't send a message
to it.

(My target is to show a previously launched instance of an application
if I try to start again. And this window can be hidden, not only minimized).

thanks

Tamas

because the application's main window is set to hidden, so it doesn't have a mainwindowHandle


The main window of an application cannot be "hidden" if it doesn't exist. If the app has a main window, that is not visible, then
it still has a handle.

To set the visibility of a window in another process using the handle of the window:

/// <summary>Sets the visibility of a window. This method allows one process to set the visiblity of a window owned by another
process.</summary>
/// <param name="cmd">SW_SHOW = 5, SW_HIDE = 0</param>
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError=true)]
static extern bool ShowWindowAsync(IntPtr windowHandle, int cmd);
/// <summary>

/// Async version allows show window cross-process.

/// </summary>

[DllImport("user32.dll", SetLastError = true)]

private static extern bool ShowWindowAsync(IntPtr window, int cmd);
 
D

Dave

But hWnd = 0, if the MainWindow is invisible, so I can't send a message to it.

No, hWnd is 0 if the MainWindow doesn't exist. It has not been created, or it was destroyed instead of being hidden.

The only way to show the window again is to recreate it.

--
Dave Sexton
[email protected]
-----------------------------------------------------------------------
Mészáros Tamás said:
So, I try the following:

string proc=Process.GetCurrentProcess().ProcessName;
Process[] processes=Process.GetProcessesByName(proc);
if (processes.Length > 1)
{
Process p=Process.GetCurrentProcess();
int n=0;
if (processes[0].Id==p.Id)
{
n=1;
}
IntPtr hWnd=processes[n].MainWindowHandle;
...
}

But hWnd = 0, if the MainWindow is invisible, so I can't send a message to it.

(My target is to show a previously launched instance of an application if I try to start again. And this window can be hidden, not
only minimized).

thanks

Tamas

because the application's main window is set to hidden, so it doesn't have a mainwindowHandle


The main window of an application cannot be "hidden" if it doesn't exist. If the app has a main window, that is not visible,
then it still has a handle.

To set the visibility of a window in another process using the handle of the window:

/// <summary>Sets the visibility of a window. This method allows one process to set the visiblity of a window owned by another
process.</summary>
/// <param name="cmd">SW_SHOW = 5, SW_HIDE = 0</param>
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError=true)]
static extern bool ShowWindowAsync(IntPtr windowHandle, int cmd);
/// <summary>

/// Async version allows show window cross-process.

/// </summary>

[DllImport("user32.dll", SetLastError = true)]

private static extern bool ShowWindowAsync(IntPtr window, int cmd);
 
?

=?ISO-8859-1?Q?M=E9sz=E1ros_Tam=E1s?=

It's sure, it exists, I've only called a Hide() method on it, and hWnd
is 0 (I've tried it).

Can I catch messages somehow, which are sent to the process handle?
(wndproc handles messages sent to the window handle only)

thanks

Tamas
 
D

Dave

I just looked at your code to access the process that you posted earlier. It seems your attempting to acquire the current process:
Process p=Process.GetCurrentProcess();

Why not just use Process.GetCurrentProcess().MainWindowHandle?
I don't understand how that is useful. Isn't your code running in the main form?
It's sure, it exists, I've only called a Hide() method on it, and hWnd is 0 (I've tried it).

What did you try? A handle of 0 (zero) means that no window exists. (period).

Can I catch messages somehow, which are sent to the process handle?
(wndproc handles messages sent to the window handle only)

I believe you have to use Hooks for that... Check out MSDN for the Windows API functions pertaining to Messaging and Hooks. You'll
have to use interop.

You can use Spy++ to monitor messages sent to a window (tool that ships with C++).
 
?

=?ISO-8859-1?Q?M=E9sz=E1ros_Tam=E1s?=

I just looked at your code to access the process that you posted
earlier. It seems your attempting to acquire the current process:
Why not just use Process.GetCurrentProcess().MainWindowHandle?
I don't understand how that is useful. Isn't your code running in
the main form?

I use GetCurrentProcess( ).Processname to determine the name of the
process. Then I look for other running processes whit the same name. If
any other process exists whit the same name, then I would like to set
that other window visible, and close this one.

So I don't want to allow to run two instances from the same application.
When I try to execute the second one, I would like to set the first
one visible, and exit the second one.
hWnd is 0 (I've tried it).
What did you try? A handle of 0 (zero) means that no window exists.
(period).

I started the application, then started an other instance of it, and the
second one could realize the windowhandle of the first one. Then I hid
the first app's main window (with Form.Hide( )), looked for the window
handle of it, but it was 0. I've tried "third party" applications as
well, and they found the handle to bo 0 as well. So if a window is
hidden, it seems not to have a windowhandle.

Tamas
 
D

Dave

If your want to ensure that only a single instance of your application may be executed at any given time, then use a Mutex object,
which can be shared across-process boundaries as a singleton:

private static Mutex SingleInstanceMutex;

/// <summary>Disposes the mutex object that ensures only a single instance of this application will execute at any given
time.</summary>
private static void SingleInstanceProcess_Exited(object sender, EventArgs e)
{
if (SingleInstanceMutex != null)
SingleInstanceMutex.Close();
}

public static void Main()
{
Process process = Process.GetCurrentProcess();
bool createdNew;
SingleInstanceMutex = new Mutex(true, process.ProcessName, out createdNew);

if (createdNew)
process.Exited+= new EventHandler(SingleInstanceProcess_Exited);
else
// Allow only a single instance of the app to execute
process.Kill();
}
So if a window is hidden, it seems not to have a windowhandle.

Incorrect. I attempted to reproduce the behavior your experiencing and I've done so with success. Take this code for example:

CheckHiddenHandleForm form = new CheckHiddenHandleForm();

Console.WriteLine("Show Form...");

form.Show();
System.Windows.Forms.Application.DoEvents();

Console.WriteLine("\tMainWindowHandle: {0}", Process.GetCurrentProcess().MainWindowHandle);
Console.WriteLine("\tForm.Handle: {0}", form.Handle);

Console.WriteLine("Hide Form...");

form.Hide();
System.Windows.Forms.Application.DoEvents();

Console.WriteLine("\tMainWindowHandle: {0}", Process.GetCurrentProcess().MainWindowHandle);
Console.WriteLine("\tForm.Handle: {0}", form.Handle);

Console.WriteLine("Close Form...");

form.Close();
System.Windows.Forms.Application.DoEvents();

Console.WriteLine("\tMainWindowHandle: {0}", Process.GetCurrentProcess().MainWindowHandle);


Outputs the following results to the Console window:


Show Form...
MainWindowHandle: 5308896 -- MainWindowHandle
Form.Handle: 5308896 -- Notice that the Form.Handle is the MainWindowHandle
Hide Form...
MainWindowHandle: 0 -- there is no longer a Main window for the process since the Form has been hidden
Form.Handle: 5308896 -- *** The window still has a handle ***
Close Form...
MainWindowHandle: 0 -- The window is now disposed (Form.Handle is now inaccessible and assumed
IntPtr.Zero)
Press any key to continue


As you can see, the window still has a handle, however, once it is hidden it is no longer the "MainWindow" of the process. You may
have to use Windows API calls to obtain the handle to the window, or just ignore it because it's hidden. That's what you're
attempting to accomplish anyway, correct?

I suggest looping through all of the processes with the same name if you do not want to ensure a single instance of the app using
the Mutex in my code example above. If the process Id is not of the current process, AND the MainWindowHandle is not IntPtr.Zero
then use my Interop code I supplied to you in a previous post to show the window.

GL
 
?

=?ISO-8859-1?Q?M=E9sz=E1ros_Tam=E1s?=

As you can see, the window still has a handle, however, once it is hidden it is no longer the "MainWindow" of the process.

That's what I didn't know till now. But everything is clear now!

Thank's a lot for your help

Tamas
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top