PDA

View Full Version : Solved: <Win API> The code doesn't work satisfactorily!



shrivallabha
09-08-2012, 05:31 AM
Hi All,

This code is annoying me a little. The following bit of code is put in a standard module.

1) Objective of this code: To bring window to front based on the partial header match e.g. suppose I've "Some User IBM Lotus Notes" running and I use "IBM Lotus Notes" then it should bring the window to the front. [At this point I'd not like to bother about multiple windows having same text as it is not happening at the moment.]

2] The code so far:
In usage:
Public Sub TestTheCode()
'This is how we can use the code in our program
Window_Activate "VBA Express"
End Sub
And the Windows_Activate code:
Option Explicit
'This function is used to get into the loop
Declare Function GetActiveWindow Lib "user32" () As Long

'This function gets the length of window caption text
Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" _
(ByVal hwnd As Long) As Long

'This function loads up lpstring part with Window Text followed by null character
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

'This function is used for looping through windows
Declare Function GetNextWindow Lib "user32" Alias "GetWindow" _
(ByVal hwnd As Long, ByVal wFlag As Long) As Long

'This function brings the desired window to top
Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Declare Function BringWindowToTop Lib "user32" (ByVal hwnd As Long) As Long

Public Sub Window_Activate(strWinText As String)

Dim lngName As Long, lngLength As Long, lngWindow As Long
Dim strWindow As String

lngName = GetActiveWindow

Do

strWindow = Space$(512)

lngLength = GetWindowTextLength(lngName)

lngWindow = GetWindowText(lngName, strWindow, lngLength + 1)

strWindow = Left(strWindow, lngLength)

If InStr(strWindow, strWinText) > 0 Then
'AppActivate lngName :works for Lotus Notes
ShowWindow lngName, 3 'Maximizes the window
BringWindowToTop lngName 'Bring the window to top
Exit Do
End If

lngName = GetNextWindow(lngName, 2)

Loop While lngName > 0

End Sub

3] Problem : When a window [which is to be activated] is minimized then both window to be brought to front and Excel lose "focus" and remain hung. As soon as you click on window to be activated things work fine. The code as it is runs without hitch when the window to be brought front is maximized or non-minimized.

I hope to get some way forward through this. Thank you.

Tommy
09-10-2012, 02:05 PM
Have you checked the state of the window you are trying to set focus?
Have you tried to make the window non-minimized?

shrivallabha
09-11-2012, 08:11 AM
Hi Tommy,

Thanks for looking into this.

I have tried to maximize using following API function:
Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Code line:
ShowWindow lngName, 3 'Maximizes the window

But it is turning futile. Can you please suggest suitable approach?

Tommy
09-13-2012, 08:23 AM
I found this at MSN. I found also that you must make 2 calls to the SHowWindow to get any response, the first one is to assume the "ownership" of the process, where the issues come up is when you have a Admin process running and you are not Admin.

ShowWindow(hWnd, SW_SHOW); // Make the window visible if it was hidden
ShowWindow(hWnd, SW_RESTORE); // Next, restore it if it was minimized
SetForegroundWindow(hWnd); // Finally, activate the window

SW_SHOW = 5
SW_RESTORE = 9
PrivateDeclareFunction SetForegroundWindow Lib"user32" (ByVal hwnd AsLong) As Long
Link to the information : http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx

EDIT: Post didn't format corrrect

shrivallabha
09-13-2012, 10:37 AM
Bingo, that was it. Now all is fine. Many thanks Tommy for your help:friends:.

Here's the final code (calling code ex. as in first post). This was my first trial with Win API and makes me feel better.

As an aside, is this code worthy of KB entry?

Option Explicit
' ShowWindow() Commands
Public Const SW_HIDE = 0
Public Const SW_SHOWNORMAL = 1
Public Const SW_NORMAL = 1
Public Const SW_SHOWMINIMIZED = 2
Public Const SW_SHOWMAXIMIZED = 3
Public Const SW_MAXIMIZE = 3
Public Const SW_SHOWNOACTIVATE = 4
Public Const SW_SHOW = 5
Public Const SW_MINIMIZE = 6
Public Const SW_SHOWMINNOACTIVE = 7
Public Const SW_SHOWNA = 8
Public Const SW_RESTORE = 9
Public Const SW_SHOWDEFAULT = 10
Public Const SW_MAX = 10

'This function is used to get into the loop
Declare Function GetActiveWindow Lib "user32" () As Long

'This function gets the length of window caption text
Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" _
(ByVal hwnd As Long) As Long

'This function loads up lpstring part with Window Text followed by null character
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

'This function is used for looping through windows
Declare Function GetNextWindow Lib "user32" Alias "GetWindow" _
(ByVal hwnd As Long, ByVal wFlag As Long) As Long

'This function brings the desired window to top
Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Declare Function BringWindowToTop Lib "user32" (ByVal hwnd As Long) As Long

Public Sub Window_Activate(strWinText As String)

Dim lngName As Long, lngLength As Long, lngWindow As Long
Dim strWindow As String

lngName = GetActiveWindow

Do

strWindow = Space$(512)

lngLength = GetWindowTextLength(lngName)

lngWindow = GetWindowText(lngName, strWindow, lngLength + 1)

strWindow = Left(strWindow, lngLength)

If InStr(strWindow, strWinText) > 0 Then
'AppActivate lngName :works for Lotus Notes
ShowWindow lngName, SW_SHOW
ShowWindow lngName, SW_RESTORE 'Maximizes the window
BringWindowToTop lngName 'Bring the window to top
Exit Do
End If

lngName = GetNextWindow(lngName, 2)

Loop While lngName > 0

End Sub

Tommy
09-15-2012, 03:06 PM
I think it would as long as you stress that the name must be exact.

shrivallabha
09-22-2012, 05:07 AM
Here's one more snippet that I received in PM from snb. If you are using MS-Word then you can use it straight but inside other apps be sure to set reference to MS Word Library.

Sub snb()
For Each tsk In Tasks
If InStr(tsk.Name, "Lotus") Then
tsk.Activate
tsk.WindowState = wdWindowStateMaximize
End If
Next
End Sub