Страница: 1 | 2 |
Вообщем помогите кто знает... Как я могу с одного приложения управлять TextBox находящимся в другом преложении???
Как пример - код для вставки текста в тесктовое поле программы SimChat 'Form Option Explicit Private Sub Form_Load() 'Module Option Explicit Declare Function GetDesktopWindow Lib "user32" () As Long Public Function EnumChildProc(ByVal hWnd As Long, ByVal lParam As Long) As Long Все просто. По аналогии посылаются и другие сообщения для скроллинга, очистки, получения содержимого и т.п. Пардон, глюки... Код лучше было бы немного подправить Изменения в форме: Clipboard.SetText "Test string" Изменения в модуле: Form1.List1.AddItem sSave & " - " & ClassName в этом варианте не приходится самому искать хэндл окон
Вопрос: Работа с ТЕХТ БОХ в другом преложении
Добавлено: 26.05.04 08:02
Автор вопроса: Андрей Александрович | ICQ: 104110333
Ответы
Всего ответов: 25
Номер ответа: 1
Автор ответа:
ISpy
Разработчик Offline Client
Вопросов: 47
Ответов: 621
Web-сайт:
Профиль | | #1
Добавлено: 26.05.04 10:51
Если обе проги пишешь ты, то можно использовать winsock. Т.е. соединиться прогами по какому-нибудь порту на компе и передавать команды.
Возможно это слишком сложный путь и есть более легкий, но я не знаю.
Еще можно попробовать поэкспериментировать с АРI - SendMessage, тут уже не обязательно чтоб вторая прога была твоя.
Номер ответа: 2
Автор ответа:
sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #2
Добавлено: 26.05.04 11:10
Зачем же wSock тут ??? все куда проще... можжно использовать сабклассинг и стандартное SendMessage+WM_COPYDATA... тем более что даже в MSDN можно найти пример использования этой связки на VB...
Номер ответа: 3
Автор ответа:
Андрей Александрович
ICQ: 104110333
Вопросов: 1
Ответов: 9
Профиль | | #3
Добавлено: 26.05.04 16:00
Дело в том что для меня МСДН это куча текста на английском языке...а я учил немецкий.... (
Номер ответа: 4
Автор ответа:
Андрей Александрович
ICQ: 104110333
Вопросов: 1
Ответов: 9
Профиль | | #4
Добавлено: 26.05.04 16:22
И на щёт wSock... я недумаю что это подойдёт так как допустим что программа(вторая) не моя...
И я хотел бы по подробнее узнать на щёт SendMessage+WM_COPYDATA ....как это работает и что для этого используют...а также где можно найти примеры по использованию этих вещей
Номер ответа: 5
Автор ответа:
HACKER
Разработчик Offline Client
Вопросов: 236
Ответов: 8362
Профиль | | #5
Добавлено: 26.05.04 16:39
а ты в инете полазь, я где-то даже примерчик видел: есть две проги, и в той и в другой на форме галки, меняш галку в одной проге, меняется и в другой. Вообщем я пойщу, если что ссылку кину
Номер ответа: 6
Автор ответа:
Андрей Александрович
ICQ: 104110333
Вопросов: 1
Ответов: 9
Профиль | | #6
Добавлено: 26.05.04 16:43
Я искал и до сих пор немогу ничего подходящего найти
Номер ответа: 7
Автор ответа:
sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #7
Добавлено: 26.05.04 17:10
Я в общем-то и не предлагал читать MSDN, я предлагал посмотреть пример на VB... Но как я полагаю у тебя его нет, раз немецкий изучал ты, значит пример вот:
Steps to Create the Sample
To create this sample, you create two separate projects; a sending project and a target project.
Create the target application:
Start a new Standard EXE project in Visual Basic. Form1 is created by default. This project will be your target application.
Add a Label control to Form1.
Copy the following code to the Code window of Form1:
Private Sub Form_Load()
gHW = Me.hWnd
Hook
Me.Caption = "Target"
Me.Show
Label1.Caption = Hex$(gHW)
End Sub
Private Sub Form_Unload(Cancel As Integer)
Unhook
End Sub
Add a module to the project and paste the following code in the Module1 code window:
Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As Long
End Type
Public Const GWL_WNDPROC = (-4)
Public Const WM_COPYDATA = &H4A
Global lpPrevWndProc As Long
Global gHW As Long
'Copies a block of memory from one location to another.
 eclare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
 hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
 eclare Function CallWindowProc Lib "user32" Alias _
"CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As _
Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As _
Long) As Long
 eclare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
 ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As _
Long) As Long
Public Sub Hook()
lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, _
AddressOf WindowProc)
 ebug.Print lpPrevWndProc
End Sub
Public Sub Unhook()
 im temp As Long
temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)
End Sub
Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
If uMsg = WM_COPYDATA Then
Call mySub(lParam)
End If
WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, _
lParam)
End Function
Sub mySub(lParam As Long)
 im cds As COPYDATASTRUCT
 im buf(1 To 255) As Byte
Call CopyMemory(cds, ByVal lParam, Len(cds))
Select Case cds.dwData
Case 1
 ebug.Print "got a 1"
Case 2
 ebug.Print "got a 2"
Case 3
Call CopyMemory(buf(1), ByVal cds.lpData, cds.cbData)
a$ = StrConv(buf, vbUnicode)
a$ = Left$(a$, InStr(1, a$, Chr$(0)) - 1)
Form1.Print a$
End Select
End Sub
Save the project and minimize the Visual Basic IDE.
Create the Sending Application
Start a second instance of the Visual Basic IDE and create a new Standard EXE project in Visual Basic. Form1 is created by default.
Add a CommandButton to Form1.
Copy the following code to the Code window of Form1:
Private Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As Long
End Type
Private Const WM_COPYDATA = &H4A
Private Declare Function FindWindow Lib "user32" Alias _
"FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName _
As String) As Long
Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal _
wParam As Long, lParam As Any) As Long
'Copies a block of memory from one location to another.
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
 hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
Private Sub Command1_Click()
 im cds As COPYDATASTRUCT
 im ThWnd As Long
 im buf(1 To 255) As Byte
' Get the hWnd of the target application
ThWnd = FindWindow(vbNullString, "Target"
a$ = "It Works!"
' Copy the string into a byte array, converting it to ASCII
Call CopyMemory(buf(1), ByVal a$, Len(a$))
cds.dwData = 3
cds.cbData = Len(a$) + 1
cds.lpData = VarPtr(buf(1))
i = SendMessage(ThWnd, WM_COPYDATA, Me.hwnd, cds)
End Sub
Private Sub Form_Load()
' This gives you visibility that the target app is running
' and you are pointing to the correct hWnd
Me.Caption = Hex$(FindWindow(vbNullString, "Target")
End Sub
Номер ответа: 8
Автор ответа:
ISpy
Разработчик Offline Client
Вопросов: 47
Ответов: 621
Web-сайт:
Профиль | | #8
Добавлено: 26.05.04 19:36
Я на этом сайте как-то статейку видел, как раз про SendMessage, называлась: "Сообщения Windows в Visual Basic", автор: Шатрыкин Иван.
Почитай, может пригодиться.
Номер ответа: 9
Автор ответа:
Андрей Александрович
ICQ: 104110333
Вопросов: 1
Ответов: 9
Профиль | | #9
Добавлено: 27.05.04 00:34
спасибо за советы....будут ещё предложения мож у кого?
Номер ответа: 10
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #10
Добавлено: 27.05.04 09:00
Может я невнимательно читал, но при чем тут сабклассинг? SendMessage - безусловно рулит, но от сабклассинга толку не будет - нельзя сабклассировать окно другого процесса. Почитайте MSDN.
Номер ответа: 11
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #11
Добавлено: 27.05.04 10:23
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Dim tWnd As Long
Private Const WM_PASTE = &H302
tWnd = FindWindow(vbNullString, "SimChat")
EnumChildWindows tWnd, AddressOf EnumChildProc, ByVal 0&
Clipboard.SetText "Test string"
SendMessage 65772, WM_PASTE, 0, 0 ' 65772 - Найденной хэндл окна класса TMemo (чат писан на дельфе)
End Sub
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Dim sSave As String
'Get the windowtext length
Dim ClassName As String
sSave = Space$(GetWindowTextLength(hWnd) + 1)
ClassName = String(255, vbNullChar)
'get the window text
GetClassName hWnd, ClassName, 255
ClassName = Left(ClassName, InStr(ClassName, vbNullChar) - 1)
GetWindowText hWnd, sSave, Len(sSave)
'remove the last Chr$(0)
sSave = Left$(sSave, Len(sSave) - 1)
Form1.List1.AddItem sSave & " - " & ClassName & " - " & hWnd
'continue enumeration
EnumChildProc = 1
End Function
Номер ответа: 12
Автор ответа:
sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #12
Добавлено: 27.05.04 10:27
LamerOnLine, без сабклассинга ты не сможешь отследить WM_COPYDATA... И я так понял что приложение свое, а не чужое...
А ты предлагаешь сразу же изменять текстовое окно... но чтобы его найти, необходимо чтобы его текст, или хотя-бы его чать не изменялись и были константой... Т.е. можно будет изменять только половину текста, но никак не весь...
Номер ответа: 13
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #13
Добавлено: 27.05.04 10:50
For i = 0 To List1.ListCount - 1
If InStr(List1.List(i), "TMemo") <> 0 Then SendMessage List1.ItemData(i), WM_PASTE, 0, 0
Next i
End Sub
Form1.List1.ItemData(Form1.List1.NewIndex) = hWnd
Номер ответа: 14
Автор ответа:
LamerOnLine
ICQ: 334781088
Вопросов: 108
Ответов: 2822
Профиль | | #14
Добавлено: 27.05.04 10:56
Sne, я тебя не понял...
1. Ясно сказано - TextBox находится в другом приложении. Следовательно, в другом процессе. Для сабклассинга придется использовать отдельную dll, почитай в MSDN.
2. Тектовое окно ищется не по содержимому, а по имени класса. При чем тут изменение его текста?
Очевидно, ты не понял вопроса. Речь идет об управлении TEXTBOX'ом другого приложения. Я именно об этом и пишу.
Номер ответа: 15
Автор ответа:
sne
Разработчик Offline Client
ICQ: 233286456
Вопросов: 34
Ответов: 5445
Web-сайт:
Профиль | | #15
Добавлено: 27.05.04 15:51
1. Не надо мне втирать про сабклассинк глобальные и локальные хуки и посылать на почитение МСДН
2. По имени класса - смешно! Посмотри че за класс у твоего окошка !? А у другого!? А у другой программы!? Ну как, найди два различия... Для vb'шных программ это не подойдет...
А теперь посмотри на свой же пример кода, и скажи мне в каком месте ты используешь имена классов ?
Верно, ты их не используешь у тебя идет поиск только по заголовку...
Если приложение свое, то WM_COPYDATA
Если нет, - это уже в зависимости от обстоятельств и конкретной программы
Вообще не буду спорить с LOL'ом, и соглашусь с его методом, вот только не стоит использовать для вставки буфер обмена! и если окошко динамически изменяет заголовок окна - нужно будет енумить все окна и сравнивать заголовок каждого окона на предмет совпадение чего-нибудь хоть с чем-нибудь ))