bring an already running app to the front

  • Thread starter Thread starter cj
  • Start date Start date
C

cj

My program checks to see if another program is already running and if so
I want it to "restore" as windows puts it that other program so it
appears on top of anything else on the screen. I know how to check to
see if it's running

If UBound(System.Diagnostics.Process.GetProcessesByName("programX")) > 1
then

then what? How do I get programX "restored"?

Thanks
 
cj said:
My program checks to see if another program is already running and if so
I want it to "restore" as windows puts it that other program so it
appears on top of anything else on the screen. I know how to check to
see if it's running

If UBound(System.Diagnostics.Process.GetProcessesByName("programX")) > 1
then

then what? How do I get programX "restored"?

Thanks

AFAIK, the only way to do this is to use a Windows API call:

Private Declare Function ShowWindow Lib "user32" _
(ByVal hWnd As System.IntPtr, ByVal nCmdShow As Long) As Long

Private Const SW_RESTORE = 9

And then later when you want to restore the window:

Dim procArray As System.Diagnostics.Process
Dim proc As System.Diagnostics.Process

procArray = System.Diagnostics.Process.GetProcessesByName("programX")
If procArray.Length > 0 Then
proc = procArray(0)
ShowWindow(proc.MainWindowHandle, SW_RESTORE)
End If

I was almost going to suggest using AppActivate(proc.Id) instead of the
call to the ShowWindow() (AppActivate can be used directly without an
Imports statement; it's part of the Microsoft.VisualBasic.Interaction
namespace), but if you call AppActivate on a minimized window, it won't
actually restore the window, it just activates it the taskbar without
unminimizing it, which is kinda pointless in my opinion.

Mike S
 
Thanks Mike. That's what I needed. I did find something else on the
internet since this that also added to the solution. It solves a little
problem in your code. Your code doesn't actually give the app that it
shows focus. Here's what I ended up with for what it's worth. Bear in
mind this is not the end use, just proof it works and now I can put it
in my real project. I got a couple of whole projects devoted to testing
these things. One has 14 buttons now testing 14 different things.

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button3.Click
Dim procArray() As System.Diagnostics.Process

procArray = System.Diagnostics.Process.GetProcessesByName("notepad")

If procArray.Length > 0 Then
ShowPreviousInstance(procArray(0).MainWindowHandle)
End If
End Sub

Private SW_RESTORE As Integer = 9

Private Declare Auto Function IsIconic Lib "user32" (ByVal hWnd As
IntPtr) As Boolean
Private Declare Auto Function SetForegroundWindow Lib "user32" (ByVal
hwnd As IntPtr) As Long
Private Declare Auto Function ShowWindow Lib "user32" (ByVal hWnd As
IntPtr, ByVal nCmdShow As Integer) As IntPtr

Private Function ShowPreviousInstance(ByVal handle As IntPtr) As Boolean
If handle.ToInt32 <> IntPtr.Zero.ToInt32 Then
Try
If IsIconic(handle) Then
ShowWindow(handle, SW_RESTORE)
End If

SetForegroundWindow(handle)

ShowPreviousInstance = True

Catch ex As System.Exception
ShowPreviousInstance = False
End Try
Else
ShowPreviousInstance = False
End If
End Function

And here's the web link:
http://dotnetjunkies.com/WebLog/thomasswilliams/archive/2005/05/02/72508.aspx
 
Mike S said:
Private Declare Function ShowWindow Lib "user32" _
(ByVal hWnd As System.IntPtr, ByVal nCmdShow As Long) As Long

Your declaration is wrong. Use this declaration instead:

\\\
Private Declare Function ShowWindow Lib "user32.dll" ( _
ByVal hWnd As IntPtr, _
ByVal nCmdShow As Int32 _
) As Boolean

Private Const SW_RESTORE As Int32 = 9
///
 
Herfried said:
Your declaration is wrong. Use this declaration instead:

\\\
Private Declare Function ShowWindow Lib "user32.dll" ( _
ByVal hWnd As IntPtr, _
ByVal nCmdShow As Int32 _
) As Boolean

Private Const SW_RESTORE As Int32 = 9
///

Thanks for the heads up. I wrote it from memory and it's obviously been
a bit too long since I last had to call ShowWindow - interesting how I
mixed the VB6-style declaration with the VB.NET-style declaration. Next
time I'll go through the effort of double-checking in the APIViewer
first ;-)

On a side note, I always secretly wished VB supported the C/C++ concept
of a preprocessor + header files: namely, I wish I could #include
<windows.h> in VB to get all the relevant structure definitions and
function prototypes for the WinAPI, so that the compiler could tell me
when I mis-declare an API function. Unfortunately, I don't think that
will ever happen, since a preprocessor doesn't really fit neatly into
the VB programming paradigm.

Mike S
 
cj said:
Herfried, how did they determine SW_RESTORE needed to be set to 9?

I'm looking at
http://msdn.microsoft.com/library/d...indowreference/windowfunctions/showwindow.asp
and it shows a list of names like SW_RESTORE, SW_MAXIMIZE, SW_MINIMIZE etc
but doesn't show the values they represent.

The reference page you mentioned above mentions the C/C++ header file
(extension ".h") containing the '#define' preprocessor directives defining
these "constants". If you have VC++ installed these header files should be
available somewhere on the system. Often definitions in the header files
look like '#define XY_Z 0xfff'. The '0x' simply states that the literal is
in hexadecimal form. The VB.NET version of the define would be 'Private
Const XY_Z As Int32 = &HFFF'.
 
Mike S said:
Next time I'll go through the effort of double-checking in the APIViewer
first ;-)

Unfortunately most API viewer applications do not really support VB.NET
and/or simply convert VB6 declarations to VB.NET declatations, which often
cannot be done successfully automatically. Thus I prefer to translate the
declares, types, etc. directly from the header files or the documentation.
 
Herfried said:
Unfortunately most API viewer applications do not really support VB.NET
and/or simply convert VB6 declarations to VB.NET declatations, which often
cannot be done successfully automatically. Thus I prefer to translate the
declares, types, etc. directly from the header files or the documentation.

All this has got me thinking: I think I'll write a program to translate
windows.h into VB.NET code and put it into a format the the API Text
Viewer can understand. Could be interesting...

Mike S
 
API viewer? Is that in the IDE somewhere? It sounds like that's what I
need to see. I'd like to see more about what's in the Windows API and
for that matter what's in WMI I can't find documentation I understand
 
cj said:
is their a VB version of the web page I mentioned?

No, because the Win32 API is intended for use with C/C++ primarily.
Nevertheless it can be used within VB6 and VB.NET.
 
cj said:
API viewer? Is that in the IDE somewhere?
No.

Would the API viewer show me that SW_RESTORE should be set to 9?

Yes.

The most reliable way is to translate the '#define's in the according header
files. The name of the header file containing the define is listed in the
documentation.

My ActiveVB-coworker Christoph von Wittich provides an API viewer that can
export declares/... for VB.NET (note that the quality is poor because the
declares are based on VB6 declares which often cannot be converted to the
right VB.NET declares automatically):

ApiViewer
<URL:http://www.apiviewer.de/>

English translation:

ApiViewer (en)
<URL:http://www.activevb.de/rubriken/apiviewer/index-apiviewereng.html>

Ken Tucker [MVP] wrote an add-in for VS.NET 2003:

VB API Viewer 2003
<URL:http://www.gotdotnet.com/Community/...mpleGuid=673d6b40-3b9b-46a7-a958-a25f4e87568a>

pinvoke.net is a web-based collaborative wiki that collects declares/... for
different .NET programming languages:

pinvoke.net: the interop wiki!
<URL:http://www.pinvoke.net/>

If you don't want to struggle with the declares yourself, you can use this
library:

A Win32 Library for .NET
<URL:http://www.codeproject.com/csharp/win32.asp>
 
Ok, that's more understandable than anything I've found.

I might pass on the API viewers for now as the pinvoke site seems to
give me the listing of what kind of APIs are available and whats in them
which appears to be way to much to hope to remember but at least I can
bookmark the page. I don't quite get the code project page except I saw
a mention of Win32API.txt and I found that on my pc and it also has the
SW_RESTORE in it. Why wouldn't MS provide the definitions of the SW_
constants in I guess a header file for VB? I keep seeing where I could
agree with C++ programmers that VB is a second rate language.

More importantly how does WMI apply to the windows API we've been
discussing? As you probably know I just used WMI to automate the
shutdown of the computer. My understanding was this was the way MS
wanted us to access the windows API now and all it was really doing was
calling something in the API. So is there a way to use the WMI to
accomplish bringing an already running app to the foreground? Is there
a way in the Windows API to shutdown windows?
 
cj said:
Ok, that's more understandable than anything I've found.

I might pass on the API viewers for now as the pinvoke site seems to
give me the listing of what kind of APIs are available and whats in them
which appears to be way to much to hope to remember but at least I can
bookmark the page. I don't quite get the code project page except I saw
a mention of Win32API.txt and I found that on my pc and it also has the
SW_RESTORE in it. Why wouldn't MS provide the definitions of the SW_
constants in I guess a header file for VB? I keep seeing where I could
agree with C++ programmers that VB is a second rate language.

Regarding Win32API.txt: if you have this file, I would assume you have
the API Text Viewer installed. On my machine at work, it's under
Start-->Programs-->Microsoft Visual Studio 6.0-->Microsoft Visual
Studio 6.0 Enterprise Tools-->API Text Viewer.
Once you start it up, goto File-->Load Text File and select the
Win32API.txt file. Then you can use the Viewer to more easily navigate
through the stuff in the file. However, there is a caveat, which is
that the code you get from the API Viewer is VB6 code, not VB.NET code.
OTOH, for non-production code, I'd say it's pretty safe to use the VB6
declares in VB.NET without changing anything. For example, a Long and
an Int32 are technically equivalent and therefore safely
interchangeable in the context of API declarations; the distinction
between them is an abstract one that only the VB.NET compiler cares
about - an API function won't be able to tell the difference, because
at a lower-level there is no difference between how data of either type
is represented. In fact, all VB6 code that uses the API relies on this
fact (i.e. take pointers to void [void *] for example, they have to
passed as Longs in VB6 since VB6 doesn't have pointer types) - so I
see no real harm in using code written in VB6 into VB.NET when the code
is dealing with API calls. In VB.NET, the addition of new data types
such as Int32 allows a programmer to more correctly declare an API
function by using data types that more closely match the "real" data
types of the function's arguments, but it doesn't make the API function
work any better or any worse.


[snip]
Is there
a way in the Windows API to shutdown windows?

Yes. The .NET declaration is:

Private Declare Function ExitWindowsEx Lib "user32.dll" Alias
"ExitWindowsEx" ( _
ByVal uFlags As Int32, ByVal dwReserved As Int32 _
) As Boolean

Private Const EWX_SHUTDOWN As Int32 = 1

And to shut down Windows, the call is:

ExitWindowsEx(EWX_SHUTDOWN, 0)

But again, if you just declare this as the API Viewer declares it, with
everything as Long:

Private Declare Function ExitWindowsEx Lib "user32.dll" Alias
"ExitWindowsEx" ( _
ByVal uFlags As Long, ByVal dwReserved As Long _
) As Long

It will work just as good. As I said, Long and Int32 are *equivalent*
as far as API Declares go because they are both 32 bits wide on 32-bit
versions of Windows. As for Boolean and Long in the return values, it
actually doesn't matter if they are two different sizes - the data type
of the return value can be any type that occupies exactly 32 bits or
less, because of the way return values are handled at the machine-code
level. To sum up, it really, really does not matter which version you
use - whether it's the older VB6 Declare or the newer VB.NET Declare,
it makes no difference when you call the function.

Mike S
 
Thanks Mike. I didn't know the API viewer was from pre-.net VB. I have
VB4, VS2003 and VS2005 loaded on this machine. I found the VB4 version.
Haven't tried it yet. I stopped using 4 in 12/2002. I dabbled in
VB2003 in 2004 and started using it daily in 5/2005. I'm still getting
used to it. I never worked with APIs in VB4. Well come to think of it,
well I don't know if it's the same thing or not but wrote a program that
used excel to do something with CSV files once and I used methods from a
Terminal Emulation package to let a VB program run of mainframe program
quite often. Just loaded VB2005 Monday and plan to start it up any day
now and see what's in it.

I understand what you're saying about the data types--it's not a problem
for me. I mainly want to know where to look to see what I might be able
to do that I don't know I can do -- if you know what I mean.

Do you know how WMI fits into the picture?

Mike said:
cj said:
Ok, that's more understandable than anything I've found.

I might pass on the API viewers for now as the pinvoke site seems to
give me the listing of what kind of APIs are available and whats in them
which appears to be way to much to hope to remember but at least I can
bookmark the page. I don't quite get the code project page except I saw
a mention of Win32API.txt and I found that on my pc and it also has the
SW_RESTORE in it. Why wouldn't MS provide the definitions of the SW_
constants in I guess a header file for VB? I keep seeing where I could
agree with C++ programmers that VB is a second rate language.

Regarding Win32API.txt: if you have this file, I would assume you have
the API Text Viewer installed. On my machine at work, it's under
Start-->Programs-->Microsoft Visual Studio 6.0-->Microsoft Visual
Studio 6.0 Enterprise Tools-->API Text Viewer.
Once you start it up, goto File-->Load Text File and select the
Win32API.txt file. Then you can use the Viewer to more easily navigate
through the stuff in the file. However, there is a caveat, which is
that the code you get from the API Viewer is VB6 code, not VB.NET code.
OTOH, for non-production code, I'd say it's pretty safe to use the VB6
declares in VB.NET without changing anything. For example, a Long and
an Int32 are technically equivalent and therefore safely
interchangeable in the context of API declarations; the distinction
between them is an abstract one that only the VB.NET compiler cares
about - an API function won't be able to tell the difference, because
at a lower-level there is no difference between how data of either type
is represented. In fact, all VB6 code that uses the API relies on this
fact (i.e. take pointers to void [void *] for example, they have to
passed as Longs in VB6 since VB6 doesn't have pointer types) - so I
see no real harm in using code written in VB6 into VB.NET when the code
is dealing with API calls. In VB.NET, the addition of new data types
such as Int32 allows a programmer to more correctly declare an API
function by using data types that more closely match the "real" data
types of the function's arguments, but it doesn't make the API function
work any better or any worse.


[snip]
Is there
a way in the Windows API to shutdown windows?

Yes. The .NET declaration is:

Private Declare Function ExitWindowsEx Lib "user32.dll" Alias
"ExitWindowsEx" ( _
ByVal uFlags As Int32, ByVal dwReserved As Int32 _
) As Boolean

Private Const EWX_SHUTDOWN As Int32 = 1

And to shut down Windows, the call is:

ExitWindowsEx(EWX_SHUTDOWN, 0)

But again, if you just declare this as the API Viewer declares it, with
everything as Long:

Private Declare Function ExitWindowsEx Lib "user32.dll" Alias
"ExitWindowsEx" ( _
ByVal uFlags As Long, ByVal dwReserved As Long _
) As Long

It will work just as good. As I said, Long and Int32 are *equivalent*
as far as API Declares go because they are both 32 bits wide on 32-bit
versions of Windows. As for Boolean and Long in the return values, it
actually doesn't matter if they are two different sizes - the data type
of the return value can be any type that occupies exactly 32 bits or
less, because of the way return values are handled at the machine-code
level. To sum up, it really, really does not matter which version you
use - whether it's the older VB6 Declare or the newer VB.NET Declare,
it makes no difference when you call the function.

Mike S
 
cj said:
I understand what you're saying about the data types--it's not a problem
for me. I mainly want to know where to look to see what I might be able
to do that I don't know I can do -- if you know what I mean.

I found this site: http://www.mangovision.com/vbapi/ref/index.html
which lists a number of API functions and VB code examples; most
importantly, it tells you what the functions do and how to use 'em. You
can also find API functions by categories such as "Painting & Drawing,"
which is nice when you don't know the name of the API function you
need. I found this site about 10 seconds ago, so I'm not sure how
extensive it is, but it's definitely not a complete list. When I was
using the Windows API more often, I usually accidentally stumbled upon
API functions through Google searches; eventually I had a sizeable list
of API declares and self-written examples that I can't find anymore.
Do you know how WMI fits into the picture?

Not a clue. I'm completely unfamiliar with WMI; I've never had to deal
with it, but I'm sure someone here will be able to shed some light on
the subject.

Mike S
 
Thanks Mike, I wonder if I'll have to post a new message to get any
responses. this is pretty deep in this thread. I'll wait till tomorrow
and see if I get any responses first.
 
Back
Top