Miten onnistuu VB:ssä fokuksen vaihto toiseen ohjelmaan, jos toisen ohjelman otsikkopalkin tekstiä ei tiedetä?
Tiedetäänkö toisesta ohjelmasta jotain muuta?
tiedetään prosessin nimi
Tässä tulee esimerkki, joka venähti aika pitkäksi. Aluksi käydään prosesseja läpi, kunnes löytyy oikeanniminen prosessi. Sitten käydään ikkunoita läpi ja tutkitaan niihin liittyvien prosessien tunnuksia. Kun ikkunan prosessin tunnus on sama kuin aiemmin haettu prosessin tunnus, tämä ikkuna on oikea ja se voidaan aktivoida.
Option Explicit
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal lFlags As Long, lProcessID As Long) As Long
Private Declare Function Process32First Lib "kernel32" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "kernel32" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Const TH32CS_SNAPPROCESS = 2
Private Const MAX_PATH = 260
Private Const GW_HWNDNEXT = 2
Private Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szexeFile As String * MAX_PATH
End Type
' etsii prosessin tunnuksen nimen perusteella
Function ProsessinID(nimi As String) As Long
Dim prosessit As Long
Dim tiedot As PROCESSENTRY32
Dim tila As Long
nimi = LCase(nimi)
prosessit = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
tiedot.dwSize = Len(tiedot)
tila = Process32First(prosessit, tiedot)
Do While tila
If LCase(Left(tiedot.szexeFile, InStr(tiedot.szexeFile, Chr(0)) - 1)) = nimi Then
ProsessinID = tiedot.th32ProcessID
Exit Do
End If
tila = Process32Next(prosessit, tiedot)
Loop
CloseHandle prosessit
End Function
' aktivoi prosessin sen nimen perusteella
Sub AktivoiProsessi(nimi As String)
Dim ikkuna As Long, prosessi As Long
Dim haettava As Long
haettava = ProsessinID(nimi)
ikkuna = FindWindow(vbNullString, vbNullString)
Do While ikkuna
If GetParent(ikkuna) = 0 Then
GetWindowThreadProcessId ikkuna, prosessi
If prosessi = haettava Then
SetForegroundWindow ikkuna
End If
End If
ikkuna = GetWindow(ikkuna, GW_HWNDNEXT)
Loop
End Sub
Private Sub Form_Click()
' aktivoidaan pasianssi
AktivoiProsessi "SOL.EXE"
End SubLähteitä:
http://www.thescripts.com/forum/threadnav14893-2-10.html
http://support.microsoft.com/kb/242308/
Jos joku tietää yksinkertaisemman tavan, niin saa kertoa!
Kiitos Antti Laaksonen sinulle tuosta koodista.. Minua askarruttaa vielä, miten saisin sen ohjelman myös muiden ohjelmien päällimmäiseksi, kun tuo kyllä antaa focuksen sille, mutta ei laita sitä muiden ikkunoiden päälle.
Jos ikkuna on pienennetty, se täytyy vielä erikseen tuoda näkyviin.
Tässä on joukko määrityksiä ja uusi aliohjelma:
Private Declare Function GetWindowPlacement Lib "user32" (ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT) As Long
Private Declare Function SetWindowPlacement Lib "user32" (ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT) As Long
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type WINDOWPLACEMENT
Length As Long
flags As Long
showCmd As Long
ptMinPosition As POINTAPI
ptMaxPosition As POINTAPI
rcNormalPosition As RECT
End Type
Private Const SW_SHOWMINIMIZED = 2
Private Const SW_RESTORE = 9
' aktivoi ja tuo näkyviin ikkunan
Sub AktivoiIkkuna(ikkuna As Long)
Dim tiedot As WINDOWPLACEMENT
SetForegroundWindow ikkuna
tiedot.Length = Len(tiedot)
GetWindowPlacement ikkuna, tiedot
If tiedot.showCmd = SW_SHOWMINIMIZED Then
tiedot.showCmd = SW_RESTORE
SetWindowPlacement ikkuna, tiedot
End If
End SubKun tätä aliohjelmaa kutsuu funktion SetForegroundWindow asemesta, ohjelman ikkuna ilmestyy aina näkyviin.
Kiitos sinulle Antti Laaksonen kun ratkaisit tämän...
Aihe on jo aika vanha, joten et voi enää vastata siihen.