![]() |
Probleme mit Sendkey nach Umstieg auf Win764Bit
Hallo,
ich hab ein Programm seit einem Jahr im Einsatz, welches die Überwachten Ausdrücke von Delphi in eine Textdatei speichert. Nun, nach dem Umstieg von WinXP32Bit auf Win764Bit funktioniert es nicht mehr. Ich habe im Programm eine Funktion aus dem Netz genutzt, die jetzt anscheinend die Probleme macht. Normale Tastendrücke wie z.B. VK-DOWN funktionieren. Was nicht mehr funktioniert ist alles in Verbindung mit [ssCtrl]. Ich hab aber nun keine Ahnung, warum das unter 64Bit plötzlich nicht mehr funktionieren sollte...
Delphi-Quellcode:
Gut, es gibt zwar noch die Möglichkeit mit keybd_event zu arbeiten, aber eigendlich möchte ich den Tastendruck explizit an ein Fenster senden.
procedure PostKeyExHWND(hWindow: HWnd; key: Word; const shift: TShiftState;
specialkey: Boolean); {************************************************************ * Procedure PostKeyEx * * Parameters: * hWindow: target window to be send the keystroke * key : virtual keycode of the key to send. For printable * keys this is simply the ANSI code (Ord(character)). * shift : state of the modifier keys. This is a set, so you * can set several of these keys (shift, control, alt, * mouse buttons) in tandem. The TShiftState type is * declared in the Classes Unit. * specialkey: normally this should be False. Set it to True to * specify a key on the numeric keypad, for example. * If this parameter is true, bit 24 of the lparam for * the posted WM_KEY* messages will be set. * Description: * This procedure sets up Windows key state array to correctly * reflect the requested pattern of modifier keys and then posts * a WM_KEYDOWN/WM_KEYUP message pair to the target window. Then * Application.ProcessMessages is called to process the messages * before the keyboard state is restored. * Error Conditions: * May fail due to lack of memory for the two key state buffers. * Will raise an exception in this case. * NOTE: * Setting the keyboard state will not work across applications * running in different memory spaces on Win32 unless AttachThreadInput * is used to connect to the target thread first. *Created: 02/21/96 16:39:00 by P. Below ************************************************************} type TBuffers = array [0..1] of TKeyboardState; var pKeyBuffers: ^TBuffers; lParam: LongInt; begin (* check if the target window exists *) if IsWindow(hWindow) then begin (* set local variables to default values *) pKeyBuffers := nil; lParam := MakeLong(0, MapVirtualKey(key, 0)); (* modify lparam if special key requested *) if specialkey then lParam := lParam or $1000000; (* allocate space for the key state buffers *) New(pKeyBuffers); try (* Fill buffer 1 with current state so we can later restore it. Null out buffer 0 to get a "no key pressed" state. *) GetKeyboardState(pKeyBuffers^[1]); FillChar(pKeyBuffers^[0], SizeOf(TKeyboardState), 0); (* set the requested modifier keys to "down" state in the buffer*) if ssShift in shift then pKeyBuffers^[0][VK_SHIFT] := $80; if ssAlt in shift then begin (* Alt needs special treatment since a bit in lparam needs also be set *) pKeyBuffers^[0][VK_MENU] := $80; lParam := lParam or $20000000; end; if ssCtrl in shift then pKeyBuffers^[0][VK_CONTROL] := $80; if ssLeft in shift then pKeyBuffers^[0][VK_LBUTTON] := $80; if ssRight in shift then pKeyBuffers^[0][VK_RBUTTON] := $80; if ssMiddle in shift then pKeyBuffers^[0][VK_MBUTTON] := $80; (* make out new key state array the active key state map *) SetKeyboardState(pKeyBuffers^[0]); (* post the key messages *) if ssAlt in Shift then begin PostMessage(hWindow, WM_SYSKEYDOWN, key, lParam); PostMessage(hWindow, WM_SYSKEYUP, key, lParam or $C0000000); end else begin PostMessage(hWindow, WM_KEYDOWN, key, lParam); PostMessage(hWindow, WM_KEYUP, key, lParam or $C0000000); end; (* process the messages *) Application.ProcessMessages; (* restore the old key state map *) SetKeyboardState(pKeyBuffers^[1]); finally (* free the memory for the key state buffers *) if pKeyBuffers <> nil then Dispose(pKeyBuffers); end; { If } end; end; { PostKeyEx } Kann jemand weiterhelfen? Gruß BBB |
Re: Probleme mit Sendkey nach Umstieg auf Win764Bit
Mit welchen Rechten läuft deine IDE?
Ein Nicht-Admin-Prozess kann nicht mit einem Admin-Prozess komminizieren. (man hat nur noch auf anndere Prozesse mit gleichwertigen oder weniger Rechten Zugriff) |
Re: Probleme mit Sendkey nach Umstieg auf Win764Bit
Es sind beide Progs von mir gestartet. Ich hab Administratorrechte. Habe beide Progsauch nicht mit der Option "Als Administrator ausführen" gestartet.
Das seltsame ist zudem, dass das Senden normaler Tastendrücke ja funktioniert... |
Re: Probleme mit Sendkey nach Umstieg auf Win764Bit
Handelt es sich um eine 64bit App, an die du die Messages schickst?
Dann musst du evtl ![]() |
Re: Probleme mit Sendkey nach Umstieg auf Win764Bit
Zitat:
|
Re: Probleme mit Sendkey nach Umstieg auf Win764Bit
Zitat:
|
Re: Probleme mit Sendkey nach Umstieg auf Win764Bit
Dieses oder ein ähnliches Programm schwirrt irgendwo in der DP rum ... vielleicht hatte ich beim Verstehen daher einen Vorteil, weil ich dieses/sowas schonmal gesehn hab. :angel:
|
Re: Probleme mit Sendkey nach Umstieg auf Win764Bit
Also, es handelt sich um die Lieste der überwachten Ausdrücke in Delphi 5. An dieses Fenster schicke ich die Botschaften. Und das ganze passiert von einem in Delphi geschriebenen Programm. Sollte also beides 32 Bit sein.
Das Dumme ist, dass ich auch gar nicht checken kann, was in dem Fenster ankommt... |
Re: Probleme mit Sendkey nach Umstieg auf Win764Bit
versuch es mal so
Delphi-Quellcode:
Es wird nicht umsonst ständig gesagt, daß man gefälligst mal die Rückgabewerte prüfen soll ... vorallem wenn etwas nicht geht und man weiß nicht warum.
procedure SendKeyEx(hWindow: HWnd; key: Word;
const shift: TShiftState; specialkey: Boolean); {************************************************************ * Procedure SendKeyEx * * Parameters: * hWindow: target window to be send the keystroke * key : virtual keycode of the key to send. For printable * keys this is simply the ANSI code (Ord(character)). * shift : state of the modifier keys. This is a set, so you * can set several of these keys (shift, control, alt, * mouse buttons) in tandem. The TShiftState type is * declared in the Classes Unit. * specialkey: normally this should be False. Set it to True to * specify a key on the numeric keypad, for example. * If this parameter is true, bit 24 of the lparam for * the posted WM_KEY* messages will be set. * Description: * This procedure sets up Windows key state array to correctly * reflect the requested pattern of modifier keys and then posts * a WM_KEYDOWN/WM_KEYUP message pair to the target window. Then * Application.ProcessMessages is called to process the messages * before the keyboard state is restored. * Error Conditions: * May fail due to lack of memory for the two key state buffers. * Will raise an exception in this case. * NOTE: * Setting the keyboard state will not work across applications * running in different memory spaces on Win32 unless AttachThreadInput * is used to connect to the target thread first. *Created: 02/21/96 16:39:00 by P. Below ************************************************************} type TBuffers = array [0..1] of TKeyboardState; var pKeyBuffers: ^TBuffers; lParam: LongInt; begin (* check if the target window exists *) if IsWindow(hWindow) then begin (* set local variables to default values *) pKeyBuffers := nil; lParam := MakeLong(0, MapVirtualKey(key, 0)); (* modify lparam if special key requested *) if specialkey then lParam := lParam or $1000000; (* allocate space for the key state buffers *) New(pKeyBuffers); try (* Fill buffer 1 with current state so we can later restore it. Null out buffer 0 to get a "no key pressed" state. *) GetKeyboardState(pKeyBuffers^[1]); FillChar(pKeyBuffers^[0], SizeOf(TKeyboardState), 0); (* set the requested modifier keys to "down" state in the buffer*) if ssShift in shift then pKeyBuffers^[0][VK_SHIFT] := $80; if ssAlt in shift then begin (* Alt needs special treatment since a bit in lparam needs also be set *) pKeyBuffers^[0][VK_MENU] := $80; lParam := lParam or $20000000; end; if ssCtrl in shift then pKeyBuffers^[0][VK_CONTROL] := $80; if ssLeft in shift then pKeyBuffers^[0][VK_LBUTTON] := $80; if ssRight in shift then pKeyBuffers^[0][VK_RBUTTON] := $80; if ssMiddle in shift then pKeyBuffers^[0][VK_MBUTTON] := $80; (* make out new key state array the active key state map *) SetKeyboardState(pKeyBuffers^[0]); (* post the key messages *) if ssAlt in Shift then begin if not PostMessage(hWindow, WM_SYSKEYDOWN, key, lParam) or not PostMessage(hWindow, WM_SYSKEYUP, key, lParam or $C0000000) then raise Exception.Create(SysErrorMessage(GetLastError)); end else begin if not PostMessage(hWindow, WM_KEYDOWN, key, lParam) or not PostMessage(hWindow, WM_KEYUP, key, lParam or $C0000000) then raise Exception.Create(SysErrorMessage(GetLastError)); end; (* restore the old key state map *) SetKeyboardState(pKeyBuffers^[1]); finally (* free the memory for the key state buffers *) Dispose(pKeyBuffers); end; { If } end; end; { PostKeyEx } Wobei man es auch mal über SendMessage/SendMessageTimeout anstatt über PostMessage versuchen könnte, dann würde man auch noch den Rückgabewert des Programms erfahren. MSDN: PostMessage Microsoft Windows Vista and later. Message posting is subject to User Interface Privilege Isolation (UIPI). The thread of a process can post messages only to message queues of threads in processes of lesser or equal integrity level. |
Re: Probleme mit Sendkey nach Umstieg auf Win764Bit
Wenn ich Deinen Quelltext nehme, ist der Rückgabewert von Postmessage jeweils true.
Wenn ich Sendmessage verwende, ist der Rückgabewert 0. Auch wenn ich das Programm als Administrator starte ändert sich das Verhalten leider nicht. |
Re: Probleme mit Sendkey nach Umstieg auf Win764Bit
Für SendMessage müßte 0 richtig sein (0 = ich habe verarbeitet).
Hmmmm, dann weiß ich auch erstmal nicht weiter. :gruebel: Das richtige Fenster (HWND) wird auch verwendet? |
Re: Probleme mit Sendkey nach Umstieg auf Win764Bit
Also das richtige Handle scheint es zu sein. Hab mal ein Closewindow mit dem Handle gemacht und die Liste geht zu.
Zumal kommen ja die Befehle mit Shiftstate=[] an. Nur die z.B. nicht die ssctrl haben... Hier auch noch mal der ganze Quelltext:
Delphi-Quellcode:
Program SaveWatchList;
{$IFDEF COMPILER_8} {$IFNDEF VER170} {$IFNDEF VER160} {$IFNDEF VER150} {$IFNDEF VER140} {$IFNDEF VER130} {$IFNDEF VER120} {$IFNDEF VER100} {$IFNDEF VER90} {$IFNDEF VER80} {$DEFINE Delphi_2005_UP} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} {$ENDIF} Uses Forms, Windows, Messages, Classes, SysUtils, shellapi, ClipBrd; {$R-} Type pHWND=^HWND; Procedure PostKeyExHWND(hWindow:HWnd;key:Word;Const shift:TShiftState;specialkey:Boolean=false); Type TBuffers=Array[0..1] Of TKeyboardState; Var pKeyBuffers :^TBuffers; lParam :LongInt; Begin (* check if the target window exists *) If IsWindow(hWindow) Then Begin (* set local variables to default values *) pKeyBuffers := Nil; lParam := MakeLong(0,MapVirtualKey(key,0)); (* modify lparam if special key requested *) If specialkey Then lParam := lParam Or $1000000; (* allocate space for the key state buffers *) New(pKeyBuffers); Try (* Fill buffer 1 with current state so we can later restore it. Null out buffer 0 to get a "no key pressed" state. *) GetKeyboardState(pKeyBuffers^[1]); FillChar(pKeyBuffers^[0],SizeOf(TKeyboardState),0); (* set the requested modifier keys to "down" state in the buffer*) If ssShift In shift Then pKeyBuffers^[0][VK_SHIFT] := $80; If ssAlt In shift Then Begin (* Alt needs special treatment since a bit in lparam needs also be set *) pKeyBuffers^[0][VK_MENU] := $80; lParam := lParam Or $20000000; End; If ssCtrl In shift Then pKeyBuffers^[0][VK_CONTROL] := $80; If ssLeft In shift Then pKeyBuffers^[0][VK_LBUTTON] := $80; If ssRight In shift Then pKeyBuffers^[0][VK_RBUTTON] := $80; If ssMiddle In shift Then pKeyBuffers^[0][VK_MBUTTON] := $80; (* make out new key state array the active key state map *) SetKeyboardState(pKeyBuffers^[0]); (* post the key messages *) If ssAlt In Shift Then Begin If Not PostMessage(hWindow,WM_SYSKEYDOWN,key,lParam) Or Not PostMessage(hWindow,WM_SYSKEYUP,key,lParam Or $C0000000) Then Raise Exception.Create(SysErrorMessage(GetLastError)); End Else Begin If Not PostMessage(hWindow,WM_KEYDOWN,key,lParam) Or Not PostMessage(hWindow,WM_KEYUP,key,lParam Or $C0000000) Then Raise Exception.Create(SysErrorMessage(GetLastError)); End; (* restore the old key state map *) SetKeyboardState(pKeyBuffers^[1]); Finally (* free the memory for the key state buffers *) Dispose(pKeyBuffers); End;{ If } End; End;{ PostKeyEx } Procedure SelectAll_CopyClipboard_SaveToFile(wndParent,wndChild:HWND;Filename:String;bAppendFile:Boolean); Var List :TStringlist; Var hOtherWin,hFocusWin :THandle; OtherThreadID,ProcessID :DWORD; Text :String; Begin List := Nil; hOtherWin := wndChild; If IsWindow(hOtherWin) Then Begin OtherThreadID := GetWindowThreadProcessID(hOtherWin,@ProcessID); If AttachThreadInput(GetCurrentThreadID,OtherThreadID,True) Then Begin hFocusWin := GetFocus; If hFocusWin<>0 Then Try Clipboard.Clear; List := TStringlist.Create; If bAppendFile And Fileexists(FileName) Then List.LoadFromFile(FileName); List.Add('**** '+DateTimeToStr(Now)+'****'); {$IFDEF Delphi_2005_UP} PostKeyExHWND(wndChild,VK_HOME, []); {$ELSE} PostKeyExHWND(wndChild,VK_HOME, [ssCtrl]); {$ENDIF} Repeat Sleep(30); PostKeyExHWND(wndChild,Ord('C'), [ssCtrl]); Sleep(30); PostKeyExHWND(wndChild,VK_DOWN, []); Sleep(30); Text := Clipboard.AsText; List.Add(Text); Until Text=''; List.SaveToFile(FileName); *) Finally AttachThreadInput(GetCurrentThreadID,OtherThreadID,False); list.Free; End; End; End; End; Procedure HandleParamstr(Out FileName:String;Out bAppendFile,bOpen:Boolean); Function IsInParam(Const s:String):Boolean; Var i :Byte; Begin Result := false; For i := 1 To ParamCount Do Begin If pos(s,uppercase(paramstr(i)))=1 Then Result := true; End; End; Begin FileName := 'SaveWatchlist.txt'; bAppendFile := true; If ParamCount>0 Then Begin If (UpperCase(Paramstr(1))='/HELP')Or(Paramstr(1)='/?') Then Begin MessageBox(0,'Saves the Delphi Watch List to a file specified by the filename parameter.' +#13#10#13#10+'Usage: SaveWatchlist [<path>] <parameter>' +#13#10#13#10+'Parameter:' +#13#10+' /append'+#9+'Appends the output to the outputfile' ,'Save Watch List',MB_OK); End Else Begin bAppendFile := IsInParam('/APPEND'); bopen := IsInParam('/OPEN'); If copy(paramstr(1),0,1)<>'/' Then FileName := Paramstr(1); End; End; End; Function EnumProcTWatchWindow(wnd:HWND;pwnd:pHWND):BOOL; Stdcall; Var buf :Array[0..255] Of char; Begin Result := True; GetClassName(wnd,buf,SizeOf(buf)-1); If (buf='TWatchWindow') Then Begin pwnd^ := wnd; Result := false; End; End; Function FindWatchWindow(Out wndWatchWindow,wndChild:HWND):Boolean; Var wndEditWindow :HWND; Begin Result := False; wndWatchWindow := 0; //Fenster TWatchWindow suchen EnumWindows(@EnumProcTWatchWindow,integer(@wndWatchWindow)); //Wenn es angedockt ist, befindet es sich in einen TEditWindow If wndWatchWindow=0 Then Begin wndEditWindow := FindWindow('TEditWindow',Nil); EnumChildWindows(wndEditWindow,@EnumProcTWatchWindow,integer(@wndWatchWindow)); End; If wndWatchWindow<>0 Then Begin {$IFDEF Delphi_2005_up} wndChild := FindWindowEx(wndWatchWindow,0,'TVirtualStringTree',Nil); {$ELSE} wndChild := FindWindowEx(wndWatchWindow,0,'TDrawGrid',Nil); {$ENDIF} Result := wndChild<>0; End; End; Var wndWatchWindow,wndChild :HWND; OutPutFilename :String; bAppendFile,bOpen :Boolean; Begin HandleParamstr(OutPutFilename,bAppendFile,bOpen); If FindWatchWindow(wndWatchWindow,wndChild) Then Begin SetForeGroundWindow(wndWatchWindow); SetFocus(wndWatchWindow); Sleep(200); SelectAll_CopyClipboard_SaveToFile(wndWatchWindow,wndChild,OutPutFilename,bAppendFile); If bopen Then ShellExecute(0,'open',pchar(OutPutFilename),Pchar(''),Nil,SW_SHOWDEFAULT) End Else MessageBox(0,'The Watch Window could not be found.','Information',MB_OK); End. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:27 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz