|
You last visited: Today at 19:12
Advertisement
Scroll Befehl an andere Anwendung schicken per Window Handle, funktioniert nicht bei
Discussion on Scroll Befehl an andere Anwendung schicken per Window Handle, funktioniert nicht bei within the .NET Languages forum part of the Coders Den category.
12/21/2014, 19:22
|
#1
|
elite*gold: 3179
Join Date: Mar 2012
Posts: 1,972
Received Thanks: 254
|
Scroll Befehl an andere Anwendung schicken per Window Handle, funktioniert nicht bei
Hallo Com. ich habe folgendes Problem ,
Ich möchte den Scroll befehl , also wenn man mit dem Mausrad scrollt an eine andere Anwendung übertragen auch wenn diese nicht im Fokus des Anwenders liegt.
Das funktioniert auch eigentlich alles einwandfrei aber bei ein paar Anwendung kann ich einfach nicht scrollen zb. Visual Studio.
Hier mein Source , dieser erkennt das Fenster das sich unter der Maus befindet und soll dann an dieses Fenster den Scroll Befehl schicken wenn dieses nicht im Fokus ist, wie gesagt funktioniert das bei einigen Programmen(zb. Google Chrome) einwandfrei und bei anderen nicht.
Main
Code:
Option Strict On
Public Class Form1
Friend Declare Auto Function WindowFromPoint Lib "user32" (ByVal x As IntPtr, ByVal y As Int32) As Int32
Friend Declare Auto Function GetWindowText Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal lpString As System.Text.StringBuilder, ByVal cch As Int32) As Int32
Friend Declare Auto Function GetWindowTextLength Lib "user32.dll" (ByVal hwnd As IntPtr) As Int32
Friend Declare Auto Function GetParent Lib "user32.dll" (ByVal hwnd As IntPtr) As Int32
Friend Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As IntPtr) As Integer
Friend Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
Friend Declare Function GetProp Lib "user32" Alias "GetPropA" (ByVal hwnd As IntPtr, ByVal lpString As String) As Integer
Friend Declare Auto Function SetForegroundWindow Lib "user32" (ByVal hwnd As IntPtr) As Long
Friend Declare Function RegisterHotKey Lib "user32" (ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifier As Integer, ByVal vk As Integer) As Integer
Friend Declare Sub UnregisterHotKey Lib "user32" (ByVal hWnd As IntPtr, ByVal id As Integer)
Private Const WM_HOTKEY As Integer = &H312
Private Const WM_KEYDOWN As Integer = &H100
Private Const WM_SCROLL As Integer = 276 ' Horizontal scroll
Private Const WM_VSCROLL As Integer = 277 ' Vertical scroll
Private Const SB_LINEUP As Integer = 0 ' Scrolls one line up
Private Const SB_LINELEFT As Integer = 0 ' Scrolls one cell left
Private Const SB_LINEDOWN As Integer = 1 ' Scrolls one line down
Private Const SB_LINERIGHT As Integer = 1 ' Scrolls one cell right
Private Const SB_PAGEUP As Integer = 2 ' Scrolls one page up
Private Const SB_PAGELEFT As Integer = 2 ' Scrolls one page left
Private Const SB_PAGEDOWN As Integer = 3 ' Scrolls one page down
Private Const SB_PAGERIGTH As Integer = 3 ' Scrolls one page right
Private Const SB_PAGETOP As Integer = 6 ' Scrolls to the upper left
Private Const SB_LEFT As Integer = 6 ' Scrolls to the left
Private Const SB_PAGEBOTTOM As Integer = 7 ' Scrolls to the upper right
Private Const SB_RIGHT As Integer = 7 ' Scrolls to the right
Private Const SB_ENDSCROLL As Integer = 8 ' Ends scroll
Dim last_handle As Integer
WithEvents tmrCheckMouse As New Timer
Private WithEvents mouseHook As New MouseHook
Private test As String = ""
Protected Overrides Sub WndProc(ByRef m As Message)
If m.Msg = WM_HOTKEY Then
Select Case m.WParam
Case CType(1, IntPtr)
MsgBox(My.Computer.Clipboard.GetText)
End Select
End If
MyBase.WndProc(m)
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
UnregisterHotKey(Me.Handle, 1)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
tmrCheckMouse.Interval = 100
tmrCheckMouse.Start()
Try
'Install the keyboard hook
RegisterHotKey(Me.Handle, 1, &H8, Keys.C)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub mouseHook_Mouse_Wheel(ByVal ptLocat As System.Drawing.Point, ByVal Direction As MouseHook.Wheel_Direction) Handles mouseHook.Mouse_Wheel
Me.Focus()
If Direction = WindowsApplication1.MouseHook.Wheel_Direction.WheelDown Then
MsgBox(SendMessage(CType(last_handle, IntPtr), WM_VSCROLL, CType(SB_LINEDOWN, IntPtr), IntPtr.Zero))
ElseIf Direction = WindowsApplication1.MouseHook.Wheel_Direction.WheelUp Then
SendMessage(CType(last_handle, IntPtr), WM_VSCROLL, CType(SB_LINEUP, IntPtr), IntPtr.Zero)
End If
End Sub
Private Sub tmrCheckMouse_Tick(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles tmrCheckMouse.Tick
Dim txt As String = ""
txt &= "Position:" & MousePosition().ToString() & vbCrLf
Dim window_handle As Integer = _
CInt(WindowFromPoint(CType(MousePosition.X, IntPtr), _
MousePosition.Y).ToString())
txt &= "Window handle:" & window_handle & vbCrLf
last_handle = window_handle
Dim root_handle As Integer = FindRoot(window_handle)
txt &= "Root handle:" & root_handle & vbCrLf
txt &= "Root text:" & vbCrLf & WindowText(root_handle) _
& vbCrLf
Me.Invoke(Sub()
lblInfo.Text = txt
End Sub)
End Sub
Private Function FindRoot(ByVal hWnd As Int32) As Int32
Do
Dim parent_hwnd As Int32 = GetParent(CType(hWnd, IntPtr))
If parent_hwnd = 0 Then Return hWnd
hWnd = parent_hwnd
Loop
End Function
Private Function WindowText(ByVal hWnd As Int32) As String
If hWnd = 0 Then Return ""
Dim text_len As Integer = GetWindowTextLength(CType(hWnd, IntPtr))
If text_len = 0 Then Return ""
Dim sb As New System.Text.StringBuilder(text_len + 1)
Dim ret = GetWindowText(CType(hWnd, IntPtr), sb, sb.Capacity)
If ret = 0 Then Return ""
Return sb.ToString
End Function
End Class
MouseHook.vb
Code:
Option Strict On
Public Class MouseHook
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Integer, ByVal lpfn As MouseProcDelegate, ByVal hmod As Integer, ByVal dwThreadId As Integer) As Integer
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Integer, ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As MSLLHOOKSTRUCT) As Integer
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Integer) As Integer
Private Delegate Function MouseProcDelegate(ByVal nCode As Integer, ByVal wParam As Integer, ByRef lParam As MSLLHOOKSTRUCT) As Integer
Private Structure MSLLHOOKSTRUCT
Public pt As Point
Public mouseData As Integer
Public flags As Integer
Public time As Integer
Public dwExtraInfo As Integer
End Structure
Public Enum Wheel_Direction
WheelUp
WheelDown
End Enum
Private Const HC_ACTION As Integer = 0
Private Const WH_MOUSE_LL As Integer = 14
Private Const WM_MOUSEMOVE As Integer = &H200
Private Const WM_LBUTTONDOWN As Integer = &H201
Private Const WM_LBUTTONUP As Integer = &H202
Private Const WM_LBUTTONDBLCLK As Integer = &H203
Private Const WM_RBUTTONDOWN As Integer = &H204
Private Const WM_RBUTTONUP As Integer = &H205
Private Const WM_RBUTTONDBLCLK As Integer = &H206
Private Const WM_MBUTTONDOWN As Integer = &H207
Private Const WM_MBUTTONUP As Integer = &H208
Private Const WM_MBUTTONDBLCLK As Integer = &H209
Private Const WM_MOUSEWHEEL As Integer = &H20A
Private MouseHook As Integer
Private MouseHookDelegate As MouseProcDelegate
Public Event Mouse_Move(ByVal ptLocat As Point)
Public Event Mouse_Left_Down(ByVal ptLocat As Point)
Public Event Mouse_Left_Up(ByVal ptLocat As Point)
Public Event Mouse_Left_DoubleClick(ByVal ptLocat As Point)
Public Event Mouse_Right_Down(ByVal ptLocat As Point)
Public Event Mouse_Right_Up(ByVal ptLocat As Point)
Public Event Mouse_Right_DoubleClick(ByVal ptLocat As Point)
Public Event Mouse_Middle_Down(ByVal ptLocat As Point)
Public Event Mouse_Middle_Up(ByVal ptLocat As Point)
Public Event Mouse_Middle_DoubleClick(ByVal ptLocat As Point)
Public Event Mouse_Wheel(ByVal ptLocat As Point, ByVal Direction As Wheel_Direction)
Public Sub New()
MouseHookDelegate = New MouseProcDelegate(AddressOf MouseProc)
MouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookDelegate, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
End Sub
Private Function MouseProc(ByVal nCode As Integer, ByVal wParam As Integer, ByRef lParam As MSLLHOOKSTRUCT) As Integer
If (nCode = HC_ACTION) Then
Select Case wParam
Case WM_MOUSEMOVE
RaiseEvent Mouse_Move(lParam.pt)
Case WM_LBUTTONDOWN
RaiseEvent Mouse_Left_Down(lParam.pt)
Case WM_LBUTTONUP
RaiseEvent Mouse_Left_Up(lParam.pt)
Case WM_LBUTTONDBLCLK
RaiseEvent Mouse_Left_DoubleClick(lParam.pt)
Case WM_RBUTTONDOWN
RaiseEvent Mouse_Right_Down(lParam.pt)
Case WM_RBUTTONUP
RaiseEvent Mouse_Right_Up(lParam.pt)
Case WM_RBUTTONDBLCLK
RaiseEvent Mouse_Right_DoubleClick(lParam.pt)
Case WM_MBUTTONDOWN
RaiseEvent Mouse_Middle_Down(lParam.pt)
Case WM_MBUTTONUP
RaiseEvent Mouse_Middle_Up(lParam.pt)
Case WM_MBUTTONDBLCLK
RaiseEvent Mouse_Middle_DoubleClick(lParam.pt)
Case WM_MOUSEWHEEL
Dim wDirection As Wheel_Direction
If lParam.mouseData < 0 Then
wDirection = Wheel_Direction.WheelDown
Else
wDirection = Wheel_Direction.WheelUp
End If
RaiseEvent Mouse_Wheel(lParam.pt, wDirection)
End Select
End If
Return CallNextHookEx(MouseHook, nCode, wParam, lParam)
End Function
Protected Overrides Sub Finalize()
UnhookWindowsHookEx(MouseHook)
MyBase.Finalize()
End Sub
End Class
|
|
|
12/22/2014, 15:15
|
#2
|
elite*gold: 1091
Join Date: Jun 2007
Posts: 19,836
Received Thanks: 7,180
|
Vielleicht sollte man zuerst mal sagen dass die Nachrichten die du hier an das Fenster schickst keine Befehle sind sondern als Anfragen angesehen werden können. Heißt, das Fenster (bzw. das Programm welches das Fenster besitzt) muss nicht zwingend scrollen nur weil du es möchtest. Genauso könntest du eine Nachricht schicken, die das Programm auffordert sich selbst zu schließen (WM_QUIT war's glaube ich). Ob es das nun aber auch tut, ist eine andere Sache und kommt auf die Implementierung im Callback an.
Chrome hat sicherlich intern auch diesen Callback definiert, wo Nachrichten empfangen und abgearbeitet werden. Sehr wahrscheinlich prüft Chrome die Nachricht und falls die Nachricht WM_VSCROLL ist, wird das ausgeführt was Chrome definiert hat. Da es dort klappt, wurde es so implementiert wie du es erwartest.
Wie sieht's nun bei VS aus? Hm, kann ich nicht sagen - habe das noch nie benötigt aber was man aus deinem Text deuten kann, behandelt VS die von dir (oder der WinAPI) definierte Nachricht WM_VSCROLL nirgendwo, sie rutscht also wahrscheinlich einfach durch den Callback und es passiert nichts weiter.
Das ist blöd für dich. Wie löst du es nun also? Du müsstest herausfinden welche Nachricht geschickt wird, wenn du in VS scrollst. Ich persönlich würde den in der Zielanwendung hooken und protokollieren damit ich sehe, wann welche Nachricht ankommt. VS hat den garantiert genauso implementiert wie Chrome.
|
|
|
12/22/2014, 19:12
|
#3
|
elite*gold: 3179
Join Date: Mar 2012
Posts: 1,972
Received Thanks: 254
|
Quote:
Originally Posted by Mostey
Vielleicht sollte man zuerst mal sagen dass die Nachrichten die du hier an das Fenster schickst keine Befehle sind sondern als Anfragen angesehen werden können. Heißt, das Fenster (bzw. das Programm welches das Fenster besitzt) muss nicht zwingend scrollen nur weil du es möchtest. Genauso könntest du eine Nachricht schicken, die das Programm auffordert sich selbst zu schließen (WM_QUIT war's glaube ich). Ob es das nun aber auch tut, ist eine andere Sache und kommt auf die Implementierung im Callback an.
Chrome hat sicherlich intern auch diesen Callback definiert, wo Nachrichten empfangen und abgearbeitet werden. Sehr wahrscheinlich prüft Chrome die Nachricht und falls die Nachricht WM_VSCROLL ist, wird das ausgeführt was Chrome definiert hat. Da es dort klappt, wurde es so implementiert wie du es erwartest.
Wie sieht's nun bei VS aus? Hm, kann ich nicht sagen - habe das noch nie benötigt aber was man aus deinem Text deuten kann, behandelt VS die von dir (oder der WinAPI) definierte Nachricht WM_VSCROLL nirgendwo, sie rutscht also wahrscheinlich einfach durch den Callback und es passiert nichts weiter.
Das ist blöd für dich. Wie löst du es nun also? Du müsstest herausfinden welche Nachricht geschickt wird, wenn du in VS scrollst. Ich persönlich würde den in der Zielanwendung hooken und protokollieren damit ich sehe, wann welche Nachricht ankommt. VS hat den garantiert genauso implementiert wie Chrome.
|
Erstmal vielen Dank für deine Antwort. Könntest du mir vielleicht etwas genauer erklären wie ich da am besten rangehe ? Also ich müsste ja dann den Callback in das andere Programm hooken wahrscheinlich per DLL Injection oder so ? Ich bin auf den Gebiet leider noch etwas unerfahren, wenn du mir das etwas genauer erklären könntest wäre ich dir sehr dankbar.
|
|
|
12/23/2014, 00:25
|
#4
|
elite*gold: 1091
Join Date: Jun 2007
Posts: 19,836
Received Thanks: 7,180
|
Quote:
Originally Posted by Graphicscore
Erstmal vielen Dank für deine Antwort. Könntest du mir vielleicht etwas genauer erklären wie ich da am besten rangehe ? Also ich müsste ja dann den Callback in das andere Programm hooken wahrscheinlich per DLL Injection oder so ? Ich bin auf den Gebiet leider noch etwas unerfahren, wenn du mir das etwas genauer erklären könntest wäre ich dir sehr dankbar.
|
Bin da jetzt selbst nicht sonderlich erfahren aber im Grunde kannst du eine DLL in den Zielprozess injizieren, die Code ausführt um eine Funktion an Adresse X (du brauchst die Adresse, verständlicherweise) an eine deiner eigenen Funktionen umzuleiten. Dafür brauchst du wie bereits erwähnt die Funktionsadresse, die Parameter, Rückgabetyp sowie die Calling Convention. Das geht nun schon tiefer und hat mit einer .NET Anwendung nichts mehr zutun, das sollte dir klar sein. Du platzierst (aus Sichtweise von ASM Code) einen JMP der zu deiner eigenen Funktion springt und die Ausführung der eigentlichen Funktion verhindert. Da das zu großen Problemen führen kann, speicherst du die originale Adresse vor der Platzierung damit du diese jederzeit wieder aufrufen kannst.
In der Regel haut man dann am Ende seiner eigenen Funktion den Call zur originalen Funktion rein. So kann man immer schön mitloggen welche Parameter durch die Funktion gehen ohne irgendetwas zu behindern.
Dafür gibt's auch genug Guides (selbst hier in der Tutorial Sektion) - will nun nicht alles so detailreich erklären weil ich, wie bereits gesagt, selbst nicht so erfahren bin.
|
|
|
12/23/2014, 03:11
|
#5
|
elite*gold: 100
Join Date: Aug 2005
Posts: 595
Received Thanks: 208
|
Quote:
will nun nicht alles so detailreich erklären weil ich, wie bereits gesagt, selbst nicht so erfahren bin.
|
Passt alles Schön erklärt.
@OP
Ja Dll-Injection + ein Detour bieten sich hier an da es
a) ein fertiges Framework für das hooking gibt
b) unmegen Tutorials dazu
c) einige andere Methoden von anfang an relativ unsinning wären da du es in ein bereits laufendes Programm einschleusen möchtest.
.NET hat wie Mostey schon angespielt hatte zwar die Möglichkeit das ganze zu machen, ist aber einfach nicht das richtige Werkzeug für den Job. (Solang du das ganze nicht aus Neugier und als Lernerfahrung machst)
|
|
|
12/23/2014, 11:18
|
#6
|
elite*gold: 3179
Join Date: Mar 2012
Posts: 1,972
Received Thanks: 254
|
Ich habe mir jetzt so einen API Monitor geholt bei dem man sich anscheinend alle API Calls anschauen kann
Screen
Ich finde aber den Call nicht , ich will ja "nur" wissen was wie gecallt wird wenn ich in Visual Studio scrolle(mit dem Mausrad), damit ich diesen Call später von meinem Programm aus "emulieren" kann. Ich hab bei der Anwendung so ziemlich jeden Filter durch aber schlauer bin ich nicht. Bei der UI Api krieg ich die ganze Zeit nur isWindowEnabled und WindowFromPoint, und bei Input devices oder so krieg ich garnichts....
Danke für euere Hilfe schonmal.
|
|
|
|
Similar Threads
|
PHP/SQL Update Befehl funktioniert nicht
11/08/2013 - Web Development - 3 Replies
Skript: <?php session_start(); require_once('config.php'); $errmsg_arr = array(); - Pastebin.com
Zeile:
$updt = "UPDATE * FROM users SET user_firstlogin='1' WHERE username='$login' AND user_password='$password'";
Der Standardbefehl '0' wird nicht durch '1' ersetzt. Weiß jemand Rat?
|
[DayZ] BattlEye Probleme & ARMA2 OA Anwendung funktioniert nicht mehr [LÖSUNG]
12/21/2012 - DayZ - 3 Replies
Hallo.
Ich schreibe hier mal ein kleines Tutorial wie ihr sämtliche BattlEye Probleme beheben könnt - auch die Meldung: ARMA OA funktioniert nicht mehr kann mit dieser Methode behoben werden!
1. Geht unter Start - Systemsteuerung in die Ordneroptionen
2. Switcht zum Tab "Ansicht" rüber und scrollt etwas runter.
3. unter "Versteckte Datein und Ordner" den Haken bzw. den Punkt bei "Ausgeblendete Datein, Ordner und Laufwerke anzeigen" reinsetzten.
4. Übernehmen und Fenster...
|
/warp.... Befehl nicht funktioniert /command doesn't work
04/16/2012 - Metin2 Private Server - 0 Replies
Hi guys & grls, i have problem with command /warp ,.....
Any "warps" teleports to the same place, just where I stand.
syser server :
first test:
SYSERR: Apr 16 19:20:18 :: WarpSet: cannot find map location index 0 x 91110000 y 91110000 name admine
scnd test:
SYSERR: Apr 16 19:25:15 :: Process: SEQUENCE 461eb500 mismatch 0xaf != 0x0 header 254
SYSERR: Apr 16 19:25:15 :: Process: SEQUENCE_LOG -------------
|
[vb.net] Anwendung funktioniert nicht mehr
03/06/2012 - .NET Languages - 7 Replies
Hey,
ich habe eine kleine Anwendung bezogen auf Skype in Visual Basic 2010 geschrieben, wenn ich sie jedoch einem Freund schicke, stürzt das Programm einfach ab und sagt das die Anwendung nicht mehr funktioniert.
Ich bin wirklich ratlos, da ich die gegebenen Lösungen von anderen Threads ausprobiert habe , jedoch keine Lösung die richtige war.
Sourcecode : klick mich
Betriebsystem : Windows 7
Framework : 4
Wäre über jede Antwort dankbar.
|
Send Befehl funktioniert nicht
10/06/2010 - AutoIt - 4 Replies
Hallo Community,
Habe ein kleines Problem und zwar mit dem Send Befehl.
Auf meinem ersten Rechner funktioniert das Script einwandfrei.
Nun wollte ich das Script auf meinem Acer Notebook (Vista Home) nutzen.
Im Windows erkennt er den Send Befehl aber in einer 3D Anwendung nicht.
|
All times are GMT +2. The time now is 19:12.
|
|