Nachricht an ein Windows Programm schicken. [erledigt]

Fragen rund um diverse Windows-Versionen, ihr Verhalten unter Xbase++ und den Umgang mit der API

Moderator: Moderatoren

Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Nachricht an ein Windows Programm schicken. [erledigt]

Beitrag von satmax »

Ich versuche mich gearde an der WIndows API und möchte dazu eine Nachricht an ein anderes Windows Programm schicken.

Ob das Programm läuft und das ProzessHandle habe ich (aus Forumsbeispielen):

Code: Alles auswählen

Function GetProzessHandle(cExe, nPidId)
Local aProcesses  := space(10240)
Local aModules    := space(4*10)
Local cbNeeded    := 0
Local cbNeeded2   := 0
LOcal cname       := space(64)
Local nPid
Local nProcHandle
Local i,nMax
Local xRet 

EnumProcesses( @aProcesses, LEN(aProcesses) , @cbNeeded )
nMax := len(trim(aProcesses))/4

for i:= 1 to nMax
	nPid := Bin2U(substr(aProcesses,1+((i-1)*4),4))
		if nPidId==NIL .or. (nPIdId==nPid)
			nProcHandle  := OpenProcess( PROCESS_QUERY_INFORMATION + PROCESS_VM_READ ,0, nPid )
				if nProcHandle > 0
					if  EnumProcessModules( nProcHandle, @aModules,len(aModules)/4, @cbNeeded2) != 0
						cName := space(128)
						GetModuleBaseNameA( nProcHandle,bin2u(substr(aModules,1,4)),@cName,len(cName))
						cName := strtran(cname,chr(0),"")
						
						if upper(trim(cName)) == upper(cExe)
							RETURN ( nProcHandle )
						ELSE
							CloseHandle(nProcHandle)	
						endif
						
					endif
				endif
		endif
next
RETURN NIL
wie schicke ich nun eine Nachricht an dieses Programm?
Zuletzt geändert von satmax am Do, 04. Sep 2014 11:36, insgesamt 2-mal geändert.
Gruß
Markus
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken.

Beitrag von brandelh »

Ich denke die API funktion SendMessage() ist dafür vorgesehen.
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Nachricht an ein Windows Programm schicken.

Beitrag von AUGE_OHR »

satmax hat geschrieben:Ich versuche mich gearde an der WIndows API und möchte dazu eine Nachricht an ein anderes Windows Programm schicken.
um ein "Fenster" zu finden würde ich "FindWindowA" benutzten.
wenn es sich um ein Control "innerhalb" eines Fenster ist dann "FindWindowExA"

die Frage ist "was" du den anderen Windows Programm schicken willst ?
gruss by OHR
Jimmy
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken.

Beitrag von satmax »

Ich möchte ein 2. Programm (C++) auffordern eine bestimmte Aktion auszuführen, in etwa so

sendMessage(hWin,WM_USER_4096, cString)

WM_USER_4096 bekomme ich vom Programmierer des anderen Programmes, cString beinhaltet einen String mit meinen Daten < 20 Zeichen.


Bei mir haperst bei der ganzen Windows API Geschichte.... GetProzessHandle() funktioniert mal. Einen eindeutigen programmname.exe habe ich, der Fenstertitel ist immer unterschiedlich.


Nun hätte ich versucht, mit

DLLFUNCTION SendMessage(nProcHandle,nUInt , lWparam, nlParam ) USING STDCALL FROM USER32.DLL

SendMessage() einzubinden. das passt aber so nicht.

------------------------------------------------------------------------------
oError:args :
-> VALTYPE: N VALUE: 1993539584
-> VALTYPE: N VALUE: 32
-> VALTYPE: C VALUE: SendMessage
-> VALTYPE: N VALUE: 1624
-> VALTYPE: N VALUE: 1
-> VALTYPE: L VALUE: .T.
-> VALTYPE: N VALUE: 50
oError:canDefault : J
oError:canRetry : N
oError:canSubstitute: N
oError:cargo : NIL
oError:description : Unbekannte Funktion
oError:filename :
oError:genCode : 21
oError:operation : dllPrepareCall
oError:osCode : 0
oError:severity : 2
oError:subCode : 2002
oError:subSystem : BASE
Gruß
Markus
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken.

Beitrag von brandelh »

Vermutlich wieder die ANSI / UNICODE Sache, also SendMessageA() ...
Gruß
Hubert
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken.

Beitrag von satmax »

Super, danke Hubert. Bin ich wieder ein Stück weiter und weiß jetzt auch warum es so viele Funktionen mit Suffix 'A' gibt. :)

Stimmt das so im Groben:

Code: Alles auswählen

nProcHandle:=GetProzessHandle("satmax5.exe", nPidId)
nUInt   := 63333
wParam := 0
lParam := 0
@user32:SendMessageA(nProcHandle,nUInt , wParam, lParam )
nUint ist mir noch halbwegs klar, aber wParam und lParam? Wie kann ich da einen String übergeben?
Gruß
Markus
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken.

Beitrag von satmax »

ich denke:

wParam sollte ein Word sein,
lParam ein long.

In meinem Fall will ich z.B: "9999999.9999" übergeben. Da könnte ich doch

Code: Alles auswählen

wParam := 9999       // maximal 65.535	
lParam := 9999999    // maximal 4.294.967.295
daraus machen. Am anderen Ende setzt sich der Programmierer das wieder zusammen?
Gruß
Markus
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken.

Beitrag von satmax »

Offensichtlich habe ich die Prozess ID brauche aber das Fenster Handle der anderen Applikation. Kann auch über die Prozess ID auf ein Fenster Handle kommen? Oder komme ich über den Filenamen auf ein Fenster Handle? Fenstertitel scheidet aus, der wechselt.
Gruß
Markus
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken.

Beitrag von Rudolf »

Hallo, ich verwende dazu OT4XB, anbei ein Beispiel wie ich mit verschiedenen Fenstern kommuniziere, vielleicht hilft das.
Grüße
Rudolf

Code: Alles auswählen

#define MY_WINDOW_NAME "FormCommander"

function SendToServer( nCmd , cText )
******************************************************************
local cds := Array(3)
local result
static hWnd := 0

DEFAULT cText to "Test"
DEFAULT nCmd  to 999

if !@user32:["__bo__hw"]:IsWindow( hWnd )
   hWnd := 0
end
if Empty(hWnd)
   hWnd := @user32:FindWindowExA(-3,0,"_OT4XB_GENERIC_WINDOW_",MY_WINDOW_NAME)
end
if Empty(hWnd)
   return NIL
end

cds[1] := nCmd
cds[2] := Len(cText)
cds[3] := _xgrab(cText)
result := @user32:SendMessageA(hWnd,WM_COPYDATA ,0,cds)
_xfree(cds[3])
return result

function ReceiverThread()
******************************************************************
local pMsg
pMsg  := _xgrab(32)
hWndReceiver := @user32:CreateWindowExA( 0,"_OT4XB_GENERIC_WINDOW_",MY_GUID,0,0,0,0,0,-3,0,AppInstance(),0)
ot4xb_subclasswindow( hWndReceiver , ReceiverHandler() )
while @user32:GetMessageA(pMsg,0,0,0) != 0
   @user32:DispatchMessageA(pMsg)
end
_xfree( pMsg)
return NIL


CLASS ReceiverHandler
******************************************************************
EXPORTED:
INLINE CLASS METHOD wndproc(hWnd,nMsg,wp,lp)
local cds,cStr,cStatus := ""
if nMsg == WM_COPYDATA
     //altd()
   cds  := PeekDWord(lp,,3)
   cStr := PeekStr(cds[3],,cds[2])
   @user32:ReplyMessage(1) // free the sender
   if oFCSys:lStatDebug
     dcqdebug "Command:" , cds[1]
     dcqdebug "String:"  , cStr
   endif
   do case
     case "!SHOW" $ var2char(cStr)
          formcommander()
     case "!COMSTOP" $ var2char(cStr)
          STOP_COMM
     case "!COMSTART" $ var2char(cStr)
          RESTART_COMM
     case "!STATUS" $ var2char(cStr)
          bu2_action()
     case "!READ" $ var2char(cStr)
          oFCSys:cAction := "R"
     case "!RECONFIG" $ var2char(cStr)
          reconfig()
     case "!CHECK" $ var2char(cStr)
          toastmsg("Interprocess communication ok")
     case "!QUIT" $ var2char(cStr)
          cStatus := ""
          for x := 1 to 1000
                if !oFCSysThread:lIsRunning
                    cStatus := " terminated ok"
                    exit
                endif
                sleep(10)
          next x
          prot("quit from SysMon at " + timestampc() ,"system.log")
          if empty(cStatus)
               prot("   timeout waiting end reading ! ","system.log")
          endif
          _endapp()
   endcase
   return 1
elseif nMsg == WM_CLOSE
   @user32:DestroyWindow(hWnd)
   return 0
elseif nMsg == WM_NCDESTROY
   @user32:PostQuitMessage(0)
   return NIL
end
return NIL
// ---------------------------------------------------------------------------
ENDCLASS

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Nachricht an ein Windows Programm schicken.

Beitrag von AUGE_OHR »

satmax hat geschrieben:Offensichtlich habe ich die Prozess ID brauche aber das Fenster Handle der anderen Applikation. Kann auch über die Prozess ID auf ein Fenster Handle kommen? Oder komme ich über den Filenamen auf ein Fenster Handle? Fenstertitel scheidet aus, der wechselt.
vermutlich hast du jetzt ein "Fenster" und musst an ein "inneres" Control ran.
siehe dir mal den Thread mit den CALC.EXE Rechner an http://www.xbaseforum.de/viewtopic.php?f=27&t=4422

man will ja in dem Fall das Control was das Ergebnis anzeigt. Das findest du mit WinID http://www.xbaseforum.de/viewtopic.php? ... ilit=fritz
Damit erhält du nun den Class Name des Controls welches du mit "FindWindowExA" suchen musst um per SendMessageA() was zu machen.
gruss by OHR
Jimmy
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken.

Beitrag von satmax »

Danke für dein Beispiel Rudolf, aber irgendwie ist das alles nicht das was ich suche...

Jimmy, nein, ich habe da kein Fenster, das ist das Process Handle, bis hierher klappt es auch. Nur, wie komme ich vom Profess Handle zu einem Windows Handle?

Alle Beispiele die ich bisher gefunden habe suchen das Fensterhandle über die Titelbar, das geht aber in meinem Fall nicht. Der Titel beginnt zwar immer gleich, endet aber immer verschieden.
Oder kann ich auch nach den linken x Zeichen im Fenstertitel suchen?

Zusammengefasst: den Prozess finde ich über den Filenamen. Nun habe ich das Processhandle, wie komme ich nun auf das Fensterhandle?
Gruß
Markus
DelUser01

Re: Nachricht an ein Windows Programm schicken.

Beitrag von DelUser01 »

Hallo Markus

Zusatz am Rande:
wenn Du nur den Programmnamen der zu steuernden EXE hast müsstest Du auch dafür sorgen, dass die EXE nur 1x gestartet ist.
Sonst bräuchtest Du z.B. noch die Startzeit oder so als weiteres Unterscheidungskriterium.
Oder sollen alle entsprechenden EXEs das Signal bekommen?

Damit solltest Du eigentlich den benötigten Handle für die ProcessID bekommen:

Code: Alles auswählen

DLLFUNCTION OpenProcess( dwDesiredAccess , bInheritHandle  , dwProcessId ) ; 
Using STDCALL From KERNEL32.DLL

Function GsApiProcGetHwndFromPid( nPID )
Local nHWND := OpenProcess( PROCESS_QUERY_INFORMATION + PROCESS_VM_READ , .F. , nPID )
Return( nHWND )
Gruß
Roland
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken.

Beitrag von satmax »

Hallo Roland,

Code: Alles auswählen

OpenProcess( PROCESS_QUERY_INFORMATION + PROCESS_VM_READ , .F. , nPID )
verwende ich schon (siehe erstes Post). Laut MSDN:

>> If the function succeeds, the return value is an open handle to the specified process.

Und das ist eben kein Fensterhandle, oder?

Ich kann dieses Handle zB. verwenden um den Prozess zu beenden:

Code: Alles auswählen

TerminateProcess(nProcHandle,1)
Mir ist es aber nicht gelungen über dieses Handle eine Nachricht an den Prozess zu senden:

Code: Alles auswählen

	nProcHandle:=GetProzessHandle(cFile, nPidId)  // Liefert Handle oder 0
	IF nProcHandle == 0 
		MsgBox(" Programm nicht gestartet")
        ELSE
	        BringWindowToTop(nProcHandle)
        	SetForegroundWindow(nProcHandle)
   
	ENDIF


Das Programm wird dabei nicht in den Vordergrund gebracht.
Gruß
Markus
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12903
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 44 Mal

Re: Nachricht an ein Windows Programm schicken.

Beitrag von AUGE_OHR »

satmax hat geschrieben:

Code: Alles auswählen

Function GetProzessHandle(cExe, nPidId)
...
   nProcHandle  := OpenProcess( PROCESS_QUERY_INFORMATION + PROCESS_VM_READ ,0, nPid )
ist der 2nd Parameter nicht logisch (.F. / .T. ) ?
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
gruss by OHR
Jimmy
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken.

Beitrag von satmax »

Danke an alle die mir geholfen haben, die Lösung:

Man braucht ot4xb & XppCbk (ohne Pablo geht nichts... :wink: )
Quelle: http://www.xbwin.com/

Dann noch das Beispiel WildFindWindow()
Quelle: http://news.xbwin.com/newsgroups.php?ar ... ticle_id=5
Beispiel enthalten.


Zuletz, SendMessageA() wollte nicht, dafür klappt es mit PostMessageA()

Code: Alles auswählen

local aWnd := WildFindWindow( "Mein Programm mit dem Titel..." )
...
PostMessageA(aWnd[1][1],1090,10,10000)
...

Schon kommen beim anderen Programm als user message 1090 die Werte 10 und 10000 an.
Gruß
Markus
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken. [erledigt]

Beitrag von brandelh »

und wo verwendest du XppCbk ?

PS: ich kenne dies bei einer Funktion, die direkte Windows Events im Xbase++ Programm empfangen soll.
Gruß
Hubert
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken. [erledigt]

Beitrag von satmax »

xppcb ist ein kleiner Scriptkompiler der aus einem simplen Skript eine Callbackfunktion, ein Objekt File, erstellt.

Einfach das Beispiel ansehen. :wink:
Gruß
Markus
DelUser01

Re: Nachricht an ein Windows Programm schicken. [erledigt]

Beitrag von DelUser01 »

Hallo Markus

trotz [erledigt]-Status muss ich auch noch was dazu beitragen.
Habe das mit dem Abfragen nach dem Programmnamen (outlook.exe) und/oder Fenster-Namen ("Microsoft Outlook") auch mal gelöst und zwar so:

Code: Alles auswählen

//----------
DLLFUNCTION EnumWindows( cAddrOfUserFunc , uUserVar  ) ;
            Using STDCALL ;
            From USER32.DLL
DLLFUNCTION GetWindowTextA( nWindowHandle , @cTitel , nTitelMax ) ;
            Using STDCALL ;
            From USER32.DLL
DLLFUNCTION GetWindowThreadProcessId( nWindowHandle , @lpdwProcessId ) ;
            Using STDCALL ;
            From USER32.DLL
DLLFUNCTION OpenProcess( dwDesiredAccess , bInheritHandle  , dwProcessId     ) ;
            Using STDCALL ;
            From KERNEL32.DLL
//----------
Function GsApiFindProcTitle( cTitleRef )
Local nHWND := GsApiFindProcess( NIL , NIL , cTitleRef )
Return( nHWND )
//----------
Function GsApiFindProcExe( cExeRef )
Local nHWND := GsApiFindProcess( NIL , cExeRef , NIL )
Return( nHWND )
//----------
Function GsApiFindProcess( bCheck , cExeRef , cTitleRef )
Privat bFind
Privat nHWND := 0
If bCheck == NIL
   bCheck := { | nHWND , cWinTitle | GsApiFindProcSub2( nHWND , cWinTitle , cExeRef , cTitleRef ) }
EndIf
MEMVAR->bFind := bCheck
EnumWindows( BaCallBack( "GsApiFindProcSub1" , BA_CB_GENERIC2 ) , 0 )
Return( MEMVAR->nHWND )
//----------
Function GsApiFindProcSub1( nHandle , uPar )
Local nBuf
Local nMax := 100
Local cBuf := Space( nMax )   // Replicate( Chr( 32 ) , nMax )
Local nRet := 1
nBuf := GetWindowTextA( nHandle , @cBuf , nMax )
If nBuf > 0
   If EVal( MEMVAR->bFind , nHandle , Left( cBuf , nBuf ) )
      nRet := 0
      MEMVAR->nHWND := nHandle
   EndIf
EndIf
Return( nRet )
//----------
Function GsApiFindProcSub2( nHWND , cWinTitle , cExeRef , cTitleRef )
Local nPID   := 0
Local lMatch := .F.
If cTitleRef <> NIL .And. ! Empty( cTitleRef )
   If Upper( AllTrim( cTitleRef ) ) == Upper( AllTrim( cWinTitle ) ) 
      lMatch := .T.
   EndIf
ElseIf cExeRef <> NIL .And. ! Empty( cExeRef )
   GetWindowThreadProcessId( nHWND , @nPID )
   cProcName := GsApiProcGetProcName( nPID , .F. )
   If Upper( AllTrim( cProcName ) ) == Upper( AllTrim( cExeRef ) )
      lMatch := .T.
   EndIf
EndIf
Return( lMatch )
//----------
Function GsApiProcGetProcName( nPID , lFullPath )
Local nHWND     := 0
Local nHMod     := 0
Local nCb       := 0
Local nProc     := 100
Local cProc     := Space( nProc )
Local cProcName := ""
If lFullPath == NIL
   lFullPath := .F.
EndIf
nHWND := GsApiProcGetHwndFromPid( nPID )
nRet  := DllCall( "PSAPI.DLL" , DLL_STDCALL , "EnumProcessModules" , nHWND , @nHMod , 4 , @nCb )
If lFullPath
   nRet := DllCall( "PSAPI.DLL" , DLL_STDCALL , "GetModuleFileNameExA" , nHWND , nHMod , @cProc , nProc )   // kompletter Pfadname z.B. "c:\programme\sfirm\sfmain.exe"
Else
   nRet := DllCall( "PSAPI.DLL" , DLL_STDCALL , "GetModuleBaseNameA"   , nHWND , nHMod , @cProc , nProc )   // Filename + Erweiterung z.B. "sfmain.exe"
EndIf
cProcName := Left( cProc , nRet )
CloseHandle( nHWND )
Return( cProcName )
//----------
Function GsApiProcGetHwndFromPid( nPID )
Local nHWND := OpenProcess( PROCESS_QUERY_INFORMATION + PROCESS_VM_READ , .F. , nPID )
Return( nHWND )
//----------
BAP wird benötigt,
wenn es nicht geht habe ich bestimmt eine Function vergessen, dann einfach "hupen"... 8)
(vielleicht habe ich auch zu viel Code reinkopiert).

TESTPROGRAMM:

Code: Alles auswählen

Procedure main
Local nHWND
nHWND := GsApiFindProcTitle( "Microsoft Outlook" )
MsgBox( Var2Char( nHWND ) )
nHWND := GsApiFindProcExe( "outlook.exe" )
MsgBox( Var2Char( nHWND ) )
Return
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken. [erledigt]

Beitrag von satmax »

Hallo Roland,

da hast du aber einen exakten Titel, oder? Ich habe nur die linken 20 Zeichen, der restliche Teil variiert immer.
Gruß
Markus
DelUser01

Re: Nachricht an ein Windows Programm schicken. [erledigt]

Beitrag von DelUser01 »

Hallo Markus

ist doch ganz einfach:
aus der Zeile

Code: Alles auswählen

If Upper( AllTrim( cTitleRef ) ) == Upper( AllTrim( cWinTitle ) )
machst Du

Code: Alles auswählen

If Upper( AllTrim( cTitleRef ) ) == Left( Upper( AllTrim( cWinTitle ) ) , 20 )
Am einfachsten Du machst die Abfrage per Block dann ist das ganz flexibel.
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken. [erledigt]

Beitrag von satmax »

was ist BAP?
Gruß
Markus
DelUser01

Re: Nachricht an ein Windows Programm schicken. [erledigt]

Beitrag von DelUser01 »

Also statt dem Aufruf

Code: Alles auswählen

nHWND := GsApiFindProcTitle( cTitleRef )
nimmst Du

Code: Alles auswählen

nHWND := GsApiFindProcess( bCheck , cExeRef , cTitleRef )
und machst eine eigene Funktion:

Code: Alles auswählen

Function MartinMatch( nHWND , cWinTitle , cExeRef , cTitleRef )
Local nPID   := 0
Local lMatch := .F.
If cTitleRef <> NIL .And. ! Empty( cTitleRef )
   If Upper( AllTrim( cTitleRef ) ) == Left( Upper( AllTrim( cWinTitle ) ) , 20 )
      lMatch := .T.
   EndIf
EndIf
Return( lMatch )
TESTPROGRAMM:

Code: Alles auswählen

Procedure main
Local nHWND
Local bCheck
bCheck := { | nHWND , cWinTitle | MartinMatch( nHWND , cWinTitle , cExeRef , cTitleRef ) }
nHWND := GsApiFindProcess( bCheck , NIL , "Window-Titel 1234567" )
MsgBox( Var2Char( nHWND ) )
Return
Und das mit der Länge 20 lässt sich auch noch flexibel einbauen - usw. usw. usw.
DelUser01

Re: Nachricht an ein Windows Programm schicken. [erledigt]

Beitrag von DelUser01 »

Hallo Martin

BAP => Binary Access Package

Ist zumindest in der Professional Subscription dabei
Benutzeravatar
satmax
1000 working lines a day
1000 working lines a day
Beiträge: 831
Registriert: Do, 02. Dez 2010 19:34
Wohnort: Biberbach in Österreich
Hat sich bedankt: 1 Mal
Danksagung erhalten: 1 Mal
Kontaktdaten:

Re: Nachricht an ein Windows Programm schicken. [erledigt]

Beitrag von satmax »

Danke, hab's gefunden. Der Punkt ist eben die Callback Funktion, ohne der kein EnumWindows(), ohne der keine Teilstringsuche... Und mit pur Xbase++ gibt es. eben keine Callback Funktion. Unterm Strich sind Deine und meine Lösung ähnlich aufgebaut. Ist aber immer interessant was alles geht. :D
Gruß
Markus
DelUser01

Re: Nachricht an ein Windows Programm schicken. [erledigt]

Beitrag von DelUser01 »

Hallo Markus

Du hast schon recht - es führen eben viele Wege nach Rom.
Ich benütze eben nur die Microsoft APIs und nicht noch etwa anderes "undurchschaubares".
Antworten