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 Sub
Lä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 Sub
Kun 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.