VB.NET и Win32 API не дружат?
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Public Class Form1
<DllImport("User32.dll", EntryPoint:="FindWindow")> _
Public Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("User32.dll", EntryPoint:="GetWindowTextLength")> _
Public Shared Function GetWindowTextLength(ByVal hwnd As IntPtr) As Integer
End Function
<DllImport("User32.dll", EntryPoint:="GetWindowText")> _
Public Shared Function GetWindowText(ByVal hwnd As IntPtr, _
ByRef lpString As String, _
ByVal cch As Integer) As Integer
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim hwnd As IntPtr = FindWindow(vbNullString, "Form1")
Dim length As Integer = GetWindowTextLength(hwnd)
Dim sText As String = Space(length)
Dim Res As Integer = GetWindowText(hwnd, sText, length)
TextBox1.Text = sText
End Sub
End Class
1) Что за ошибка. Compile-time или run-time??? И текст её желательно
2) С какой целью WinAPI здесь используешь?? Можно и без него обойтись (в твоём коде точно).
А зчем - нужно запустить EnumChildWindows и получить список окон внутри программы с именами и назв.класса и т.п. В NET, насколько я знаю альтернативы нет
А зчем - нужно запустить EnumChildWindows и получить список окон внутри программы с именами и назв.класса и т.п. В NET, насколько я знаю альтернативы нет
А вот и зря, если нужно перечислить все открытые формы в твоём приложении, то Application.OpenForms. Если все дочерние окна в MDI приложении, то Form.MdiChildren.
Спасибо, я посмотрю. Но ответ не понял - NET & API лучше не смешивать?
Конечно лучше не смешивать, это замедляет работу приложения, может быть причиной Memory Leak, потеря кроссплатформенности.
То что ты хочешь делается так (без WinAPI, чистый managed):
[SIZE=2][COLOR=#0000ff][FONT=Courier New]Imports[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System[/FONT][/SIZE]
[SIZE=2][COLOR=#0000ff][FONT=Courier New]Imports[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] System.Collections[/FONT][/SIZE]
[SIZE=2][COLOR=#0000ff][FONT=Courier New]Module[/FONT][/COLOR][/SIZE][SIZE=2][FONT=Courier New] Module1[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff] Sub[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] Main()[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff] For [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]Each[/COLOR][/SIZE][SIZE=2] proc [/SIZE][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][SIZE=2] Process [/SIZE][SIZE=2][COLOR=#0000ff]In[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] Process.GetProcesses(Environment.MachineName)[/FONT][/SIZE]
[SIZE=2][FONT=Courier New] Console.WriteLine([/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#800000]"Main Window Title: {0}"[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New], proc.MainWindowTitle)[/FONT][/SIZE]
[SIZE=2][FONT=Courier New] Console.WriteLine([/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#800000]"Main Window Handle: {0}"[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New], proc.MainWindowHandle)[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff] Next[/COLOR][/SIZE][/FONT][SIZE=2][FONT=Courier New] proc[/FONT][/SIZE]
[SIZE=2][FONT=Courier New] Console.ReadKey()[/FONT][/SIZE]
[FONT=Courier New][SIZE=2][COLOR=#0000ff] End [/COLOR][/SIZE][/FONT][SIZE=2][COLOR=#0000ff][FONT=Courier New]Sub[/FONT][/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff][FONT=Courier New]End [/FONT][/COLOR][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]Module[/COLOR][/SIZE][/FONT]
С помощью класса System.Diagnostics.Process узнаешь и о хэндле главного окна, и о HInstance модуля и т.д..
Как вариант можно получать хэндл главного окна процесса, создать экземпляр Form и передать в конструктор этот хэндл. И потом при помощи класса ApplicationContext получить другие окна.
утчеки памяти при грамотном обращении случиться не должно.
Насчёт потери производительности, это тоже не факт... .net сама по себе делает много всяких действий и в итоге обращается к API. Накладные расходы на вызов API функции могут окупиться....
Против смешивания .NET и API явное наршение общего стиля при том, что явно редко возникает необходимость в его использовании из под .NET
платформа - это не только операционная система. это скорее операционная система + аппаратное обеспечение.
Не должно. А утечки бывают и не только при обращении к Win32API.
Не каждый вот так сразу сможет написать заголовок к апишке.
Насчёт потери производительности, это тоже не факт... .net сама по себе делает много всяких действий и в итоге обращается к API. Накладные расходы на вызов API функции могут окупиться....
Это как-то сомнительно. Скорее всего это приведёт - это к потере читабельности кода.
К томуже в Висте Win32 API уже как таковых нет. Есть WinFX, частью которой является MSFw.
Правильно, но тем не менее ьез API порой не обойтись, и делать это нужно аккуратно. Посмотрите http://www.codeproject.com/ - ярые поклонники NET не стесняются применять функции API
Есть хендл, есть New Form. Подскажи, что дальше.
FM = Form.FromHandle(hwnd)
Могучий ЗАЗ, вытягивай.
Control mainForm = Control.FromHandle(p.MainWindowHandle);
if (mainForm == null)
continue;
textBox1.Text += p.ProcessName + " " + mainForm.Text + "\r\n";
foreach (Control c in mainForm.Controls) {
textBox1.Text += " " + c.Text + "\r\n";
}
}
Control.FromHandle возвращет объект только если хэндл принадлежит нашему приложению.
Может нет каких-то прав вроде UIPermission?
Собственно моя заковырка вот в чем - мне нужно получить имя (не заголовок) окна или найти окно по имени (не по заголовку). Ф-ции API с именем не работают, NET не работает с handle (в моем случае). Как быть?
MFC позволяет это решить, но с С++ я не работаю. Кстати, а нельзя ли классы MFC к NETу прицепить?
Спасибо. С API я вроде как разобрался. И с NET немного тоже. Остается их как-то связать. Пока моя задача осталась невыполнимой, а именно получить хендл форма (контрола) по его Name (не по заголовку).
Немного приоткрою завесу таинственности: пишу DLL для с..кой пронраммы 1С. Для функционирования большинства ф-ции (они из API) требуется хендл. Свойства формы/контрола Handle/hwnd в 1С нет, форма 1С не может иметь меню, больше половины типов контролов не имеют свойства "Заголовок". Свойство "Имя" есть у всех контролов, но нет у формы. Вот и головоломкаЮ получить хендл. Скажу сразу, хендл формы 1С я все-таки получил (хитрая получилась технология). Для контролов, имеющих свойство "Заголовок" - тоже могу получить. А вот для контролов, имеющих только имя - бьюсь.
Я сейчас смотрю, как у нормальных людей сделано все это для 1С на C++/MFC. Но мне кажется классы MFC вряд ли прикрутишь к VB/C#. В С++ точно используется CWmd. На С++ у меня пока импотенция. А только средствами API получить имя окна по хендлу (а это мне и нужно после Enum) не получится. В общем есть список контролв, вернее их hwnd & Caption & ClassName, нет Name.
Я сейчас смотрю, как у нормальных людей сделано все это для 1С на C++/MFC. Но мне кажется классы MFC вряд ли прикрутишь к VB/C#. В С++ точно используется CWmd. На С++ у меня пока импотенция. А только средствами API получить имя окна по хендлу (а это мне и нужно после Enum) не получится. В общем есть список контролв, вернее их hwnd & Caption & ClassName, нет Name.
Приведи нужные функции WinAPI (ведь MFC использует WinAPI), я тебе их переведу на VB.NET.