Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[107.21.176.63] |
|
Сообщ.
#1
,
|
|
|
Доброго времени суток!
Запущен процесс "MsgLab.exe". Необходимо найти его hWnd и показать его, так как он свёрнут. Подскажите, пожалуйста, что я не так делаю в коде? Option Explicit Const TH32CS_SNAPHEAPLIST = &H1 Const TH32CS_SNAPPROCESS = &H2 Const TH32CS_SNAPTHREAD = &H4 Const TH32CS_SNAPMODULE = &H8 Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or TH32CS_SNAPTHREAD Or TH32CS_SNAPMODULE) Const TH32CS_INHERIT = &H80000000 Const MAX_PATH As Integer = 260 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 Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal lFlags As Long, ByVal 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 OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Private Declare Sub CloseHandle Lib "kernel32" (ByVal hPass As Long) Const SW_NORMAL = 1 Const SW_MAXIMIZE = 3 Const SW_MINIMIZE = 6 Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long Private Declare Function SetActiveWindow Lib "user32" (ByVal hwnd As Long) As Long Private Function GetWndProcess(ByVal name_proc As String) As Long Dim hSnapShot As Long Dim uProcess As PROCESSENTRY32 Dim r As Long Dim ProcessName As String hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0&) uProcess.dwSize = Len(uProcess) r = Process32First(hSnapShot, uProcess) Do While r ProcessName = Left$(uProcess.szExeFile, IIf(InStr(uProcess.szExeFile, Chr$(0)) > 0, InStr(uProcess.szExeFile, Chr$(0)) - 1, 0)) If ProcessName = name_proc Then GetWndProcess = OpenProcess(&H1, False, uProcess.th32ProcessID) Exit Do End If r = Process32Next(hSnapShot, uProcess) Loop CloseHandle hSnapShot End Function Private Sub Form_Load() Dim hWnd_app As Long hWnd_app = GetWndProcess("MsgLab.exe") ShowWindow hWnd_app, SW_NORMAL CloseHandle hWnd_app End Sub |
Сообщ.
#2
,
|
|
|
Получилось таким образом вывести сразу несколько hWnd одного окна "MsgLab.exe", а нужен только 1, который именно отвечал бы за окно! Как его выделить из общего списка hWnd (там их у меня 4 штуки вывелось)?
Public Function EnumWindows() As String() Dim r As Long Dim pArr() As String Dim count As Long Dim hwnd As Long Dim sss As String Dim vvv As String Dim sSave As String Dim Ret As Long Dim mv As Long Dim sw_found As LogVar Dim ccc() As String Dim ddd() As String sw_found = 0 vvv = "MsgLab.exe" Dim hWndChildProcessID As Long r = GetWindow(GetDesktopWindow, GW_CHILD) Do While r sss = GetExeFromHandle(r) If sss = vvv Then Add_Array ccc, r: sw_found = 1 ElseIf sss <> vvv And sw_found = 1 Then Exit Do End If DoEvents count = count + 1 r = GetWindow(r, GW_HWNDNEXT) Loop EnumWindows = ccc End Function Public Function GetExeFromHandle(hwnd As Long) As String Dim threadID As Long, processID As Long, hSnapshot As Long Dim uProcess As PROCESSENTRY32, rProcessFound As Long Dim i As Integer, szExename As String threadID = GetWindowThreadProcessId(hwnd, processID) If threadID = 0 Or processID = 0 Then Exit Function hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&) If hSnapshot = -1 Then Exit Function uProcess.dwSize = Len(uProcess) rProcessFound = ProcessFirst(hSnapshot, uProcess) Do While rProcessFound If uProcess.th32ProcessID = processID Then i = InStr(1, uProcess.szExeFile, Chr(0)) If i > 0 Then szExename = Left$(uProcess.szExeFile, i - 1) Exit Do Else rProcessFound = ProcessNext(hSnapshot, uProcess) End If Loop Call CloseHandle(hSnapshot) GetExeFromHandle = szExename End Function |
Сообщ.
#3
,
|
|
|
Нашёл хороший пример (прикрепил во вложении).
Ещё нашёл несколько примеров в интернете. Из них скомпоновал такие функции. API констант или функций, типов может не хватать, вырезал из рабочей программы. Основные функции постарался учесть. Всем спасибо за внимание. Option Explicit Public Name_EXE As String Public hWnd_list() As String Public Const GW_CHILD = 5 Public Const GW_HWNDNEXT = 2 Public Const TH32CS_SNAPHEAPLIST = &H1 Public Const TH32CS_SNAPPROCESS = &H2 Public Const TH32CS_SNAPTHREAD = &H4 Public Const TH32CS_SNAPMODULE = &H8 Public Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or TH32CS_SNAPTHREAD Or TH32CS_SNAPMODULE) Const TH32CS_INHERIT = &H80000000 Const MAX_PATH As Integer = 260 Public 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 Public Declare Function CreateToolhelpSnapshot Lib "kernel32" Alias "CreateToolhelp32Snapshot" (ByVal lFlgas As Long, ByVal lProcessID As Long) As Long Public Declare Function Process32First Lib "kernel32" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long Public Declare Function Process32Next Lib "kernel32" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Public Declare Sub CloseHandle Lib "kernel32" (ByVal hPass As Long) Public Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Boolean Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long Public Declare Function GetDesktopWindow Lib "user32" () As Long Public Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long Public Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long Public Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long Public Function hWndFromEXE(ByVal str_name_EXE As String) As Long Name_EXE = str_name_EXE EnumWindows AddressOf EnumWindowsProc, ByVal 0& hWndFromEXE = Val(hWnd_list(0)) End Function Public Function hWndFromInvisibleEXE(ByVal str_name_EXE As String) As Long ' String() Dim r As Long Dim m As Long Dim sss As String Dim sSave As String Dim Ret As Long Dim sw_found As LogVar Dim ccc() As String sw_found = 0 r = GetWindow(GetDesktopWindow, GW_CHILD) Do While r sss = GetExeFromHandle(r) Ret = GetWindowTextLength(r) sSave = Space(Ret) GetWindowText r, sSave, Ret + 1 If sss = str_name_EXE Then sw_found = 1 Add_Array ccc, r ' моя ф-я добавления в массив ccc строки r, она не показана тут m = IsWindowVisible(r) If m = 0 Then hWndFromInvisibleEXE = r ElseIf sss <> str_name_EXE And sw_found = 1 Then Exit Do End If DoEvents r = GetWindow(r, GW_HWNDNEXT) Loop End Function Public Function GetExeFromHandle(ByVal h_hwnd As Long) As String Dim threadID As Long Dim processID As Long Dim hSnapshot As Long Dim uProcess As PROCESSENTRY32 Dim rProcessFound As Long Dim i As Integer Dim szExename As String threadID = GetWindowThreadProcessId(h_hwnd, processID) If threadID = 0 Or processID = 0 Then Exit Function hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&) If hSnapshot = -1 Then Exit Function uProcess.dwSize = Len(uProcess) rProcessFound = Process32First(hSnapshot, uProcess) Do While rProcessFound If uProcess.th32ProcessID = processID Then i = InStr(1, uProcess.szExeFile, Chr(0)) If i > 0 Then szExename = Left$(uProcess.szExeFile, i - 1) Exit Do Else rProcessFound = Process32Next(hSnapshot, uProcess) End If Loop Call CloseHandle(hSnapshot) GetExeFromHandle = szExename End Function Public Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Boolean EnumWindowsProc = True If GetExeFromHandle(hwnd) = Name_EXE Then Add_Array hWnd_list, hwnd ' моя ф-я добавления в массив hWnd_list строки hwnd, она не показана тут End Function Прикреплённый файлGetHwnd.rar (2,31 Кбайт, скачиваний: 171) |
Сообщ.
#4
,
|
|
|
А обычным FindWindow нельзя окно найти?
|
Сообщ.
#5
,
|
|
|
Black Star, если известен заголовок, то можно, а если известно только имя *.EXE файла? я не знаю, если честно
|
Сообщ.
#6
,
|
|
|
Цитата salieri @ если известно только имя *.EXE файла? Перебор процессов и перебор потоков, после -- перебор окон в каждом отдельном потоке средствами EnumThreadWindows |