API-Funktion EnumWindows in eigenem Thread?!

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

Moderator: Moderatoren

Antworten
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

API-Funktion EnumWindows in eigenem Thread?!

Beitrag von Markus Walter »

Hi,
hat von Euch schon mal jemand die WinAPI-Funktion EnumWindows (mit Callback-Funktion mit BAP) in einem eigenen Thread verwendet?

Irgendwie "hängt" der Thread, wenn im Hauptthread keine Events passieren...
Lasse ich den Aufruf von EnumWindows weg (und gebe zum Beispiel nur einen Ton aus), arbeitet der Thread wie gewünscht...

Hintergrund ist, dass ich in einem eigenen Thread das Fensterhandle eines bestimmten Fensters herausfinden möchte (aber FindWindow nicht verwenden kann...).

So sieht mein Code aus:

Code: Alles auswählen

//...

MsgBox("Start Thread")
oThread := Thread():new()
oThread:start("FindHandle", "ABCD")

//...



function FindHandle(par1)
local nHandle := 0, nStart, nEvent, mp1, mp2, oXbp
local cDbg := "", i, oProfile


  nStart := seconds()

  do while .t.
    nHandle := wGetWinHandleFromTitle("Unbenannt - Edi")
    if nHandle > 0
      exit
    endif

    // timeout (max. 20 Sekunden)
    if seconds() > nStart + 20
      exit
    endif

    wSleep(5)
    tone(100,3)    // Test-Ausgabe

// keine Auswirkung, ob mit oder ohne eigene Event-Abarbeitung
//    nEvent := AppEvent( @mp1, @mp2, @oXbp, 0.01 )
//    oXbp:handleEvent( nEvent, mp1, mp2 )

  enddo

  if nHandle > 0
    //...
  endif

return



function wGetWinHandleFromTitle(cTitle)
local nCallBack, nFlags

  nGetWinHandleFromTitle := 0
  cGetWinHandleFromTitle := cTitle

  nCallBack := BaCallBack("wGetWinHandleFromTitleCallBack", BA_CB_GENERIC1)

  nFlags := 0
  EnumWindows( nCallback, nFlags)

return(nGetWinHandleFromTitle)


// Call-Back-Funktion
FUNCTION wGetWinHandleFromTitleCallBack(hWnd, nPar1)
local cWindowName := space(71)

    GetWindowTextA(hWnd, @cWindowName, 70)
    cWindowName := strtran(cWindowName, chr(0))

    if left(cWindowName, len(cGetWinHandleFromTitle)) == cGetWinHandleFromTitle
      nGetWinHandleFromTitle := hWnd
    endif

RETURN 1



Wenn ich nun den Aufruf von

Code: Alles auswählen

nHandle := wGetWinHandleFromTitle("Unbenannt - Edi")
herausnehme, dann läuft der Thread richtig (man hört die regelmäßige Tonausgabe). Mit dem Aufruf, scheint der Thread nur dann etwas zu machen, wenn ich im "Hauptthread" (der eigentlichen Anwendung) Events erzeuge: Immer wenn ich eine Taste drücke, hört man den Test-Ton und der Thread arbeitet "kurz", er findet auch das richtige Fenster, wenn ich ein paar Mal eine Taste gedrückt habe...

Entweder stehe ich total auf dem Schlauch oder ich habe die Event-Abarbeitung nicht verstanden...

Hat jemand eine Idee?
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
boddy
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 22
Registriert: Fr, 30. Sep 2005 11:39
Wohnort: Berlin

Beitrag von boddy »

Hallo Markus,

Dein Quellcode funktioniert bei mir einwandfrei (Windows XP).
Getestet habe ich im GUI- und im Hybridmodus mit allen möglichen Wartezuständen.
Das Fenster wurde immer gefunden, wenn es bereits offen war oder wenn ich in den ersten 20 Sekunden den Editor gestartet habe.
Hast Du es schon auf verschiedenen Rechnern probiert?

Gruß
boddy
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Beitrag von Markus Walter »

Hi boddy,

kannst Du mir Deinen Quelltext mal zu kommen lassen (am besten ein ganzes Projekt)

Irgendetwas muss bei Dir ja anders sein...
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
boddy
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 22
Registriert: Fr, 30. Sep 2005 11:39
Wohnort: Berlin

Beitrag von boddy »

Hallo Markus,

entschuldige bitte, daß ich mich erst jetzt melde, aber ich stecke schon voll in den Wochenendvorbereitungen.

Hier das komplette GUI :

Code: Alles auswählen

******************************************************

#include "dll.ch"
#include "bap.ch"
#include "Appevent.ch"

*-----------------------------------------------------

DLLFUNCTION EnumWindows(lpEnumFunc, lParam) USING OSAPI FROM user32.dll
DLLFUNCTION GetWindowTextA(hwnd, @lpString, nMaxCount) USING OSAPI FROM user32.dll

*-----------------------------------------------------

procedure appsys
return

*-----------------------------------------------------

procedure main

//...
MsgBox("Start Thread")
oThread := Thread():new()
oThread:start("FindHandle", "ABCD")
//...

oDlg         := XbpDialog():new( ,, {0,0}, AppDesktop():currentSize() )
oDlg:title   := "Programmfenster"
oDlg:taskList := .T.
oDlg:create()

SetAppFocus(oDlg)

nEvent := 0
DO WHILE nEvent <> xbeP_Close
   nEvent := AppEvent( @mp1, @mp2, @oXbp )
   oXbp:handleEvent( nEvent, mp1, mp2 )
ENDDO

oDlg:destroy()

return

*-----------------------------------------------------

function FindHandle(par1)
local nHandle := 0
local nStart := seconds()

  do while (nHandle = 0) .and. (seconds() < (nStart + 20))
    nHandle := wGetWinHandleFromTitle("Unbenannt - Edi")
    iif( nHandle = 0, Sleep(500), )
//    tone(100,3)    // Test-Ausgabe
  enddo

  if nHandle > 0
    msgbox("Gefunden !!!","Fenster")
   else
    msgbox("Nicht gefunden !!!","Fenster")
  endif

return nil

*-----------------------------------------------------

function wGetWinHandleFromTitle(cTitle)
local nCallBack, nFlags

  nGetWinHandleFromTitle := 0
  cGetWinHandleFromTitle := cTitle

  nCallBack := BaCallBack("wGetWinHandleFromTitleCallBack", BA_CB_GENERIC1)

  nFlags := 0
 EnumWindows( nCallback, nFlags)

return(nGetWinHandleFromTitle)

*-----------------------------------------------------

// Call-Back-Funktion
FUNCTION wGetWinHandleFromTitleCallBack(hWnd, nPar1)
local cWindowName := space(71)

    GetWindowTextA(hWnd, @cWindowName, 70)
*    cWindowName := strtran(cWindowName, chr(0))
    cWindowName := ZTrim(cWindowName)

    if left(cWindowName, len(cGetWinHandleFromTitle)) == cGetWinHandleFromTitle
      nGetWinHandleFromTitle := hWnd
      RETURN 0
    endif

RETURN 1

*-----------------------------------------------------

Static FUNCTION ZTrim(cString)
	LOCAL nZPos
  nZPos := At( Chr(0), cString )
RETURN IIF( nZPos>0, Substr( cString, 1, nZPos-1 ), cString)

*-----------------------------------------------------
Läuft bei mir tadellos (Tausendmal probiert, immer hat es reagiert)
Die winzigen Veränderungen in Deinen Funktionen habe ich nur für mich gemacht. Es funktioniert auch ohne.
Vielleicht hilft es Dir ja.


Auf jeden Fall wünsche ich Dir schon mal ein schönes Wochenende
Gruß boddy
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Beitrag von Tom »

Huhu, Boddy.
aber ich stecke schon voll in den Wochenendvorbereitungen
Hast Du ne Meise, sowas am Mittwoch zu schreiben? :lol:
Herzlich,
Tom
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16501
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Tom,
nun lass' (:tongue:) doch den armen Armin in Ruhe! Es ist Mitte der Woche und damit rückt das Wochenende näher! Außerdem will er ja sicherlich sein Sudoku-Programm verfeinern - und dafür hat er sicherlich nur am Wochenende Zeit :lol:

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
rassekst
UDF-Programmierer
UDF-Programmierer
Beiträge: 97
Registriert: Mi, 01. Feb 2006 23:49
Wohnort: Glauchau
Kontaktdaten:

Beitrag von rassekst »

Hallo Markus,

Ich verwende die API Funktion

FindWindowExA(hParent,hChild,cClass,cWindowTitel)

bzw.

FindWindowA(cClass,cWindowTitel)

um ein Fenster zu finden.

Vielleicht hilft Dir das weiter.

Gruss Steffen
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Beitrag von Markus Walter »

Hallo Armin,

konnte leider eben erst Deine Version ausprobieren...

Aber auch hier habe ich das (wahrscheinlich) gleiche Problem: Solange das Programmfenster nicht den Fokus hat, funktioniert die Sache nicht.

Also ich starte das Program (und mache das Fenster etwas kleiner...). Dann wähle ich aus dem Menü Programme - Zubehör den Editor aus. Dann hat Notepad den Fokus... Erst wenn ich das Xbase-Programm wieder anklicke (Fokus-Wechsel), erscheint die MsgBox "Gefunden".

Das sieht mir genau nach meinem Problem aus. Irgendwie scheint der Thread nicht zu laufen, wenn die Applikation nicht den Fokus hat...

Hat da noch jemand eine Idee?

Vielleicht als Hintergrund:
Ich möchte nach einem Ausdruck an FritzFax die Faxnummer automatisch übergeben. Nach dem Ausdruck kommt irgendwann das FritzFax-Fenster, wo man die Faxnummer eintippen kann. Ich wollte nun nach dem Ausdruck einen Thread starten, der max. 20 Sekunden auf das Fenster wartet und wenn dieses kommt, die Nummer per keyb_event reinschreibt...
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Beitrag von Markus Walter »

Hallo Steffen,

soweit ich weiß, muss man bei FindWindowA (auch bei FindWindowExA) den vollständigen Fenstertitel übergeben. Das ist in meinem Fall nicht immer möglich, manchmal habe ich nur den Anfang des Titels...

Oder sehe ich das falsch?
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Benutzeravatar
Wolfgang Ciriack
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2932
Registriert: Sa, 24. Sep 2005 9:37
Wohnort: Berlin
Hat sich bedankt: 13 Mal
Danksagung erhalten: 34 Mal
Kontaktdaten:

Beitrag von Wolfgang Ciriack »

Hallo Markus,
schick doch mal eine Mail an AVM, dann bekommst du eine Mail zurück, die beschreibt, wie man über Registry-Einträge die Faxnummern automatisch übergibt.
Ansonsten habe ich mal eine kleine Anwendung programmiert, die
die FriSnd32.exe ersetzt und ein paar undokumentierte Parameter für die Übergabe an das Orginal-FriSnd32 benutzt.
Viele Grüße
Wolfgang
rassekst
UDF-Programmierer
UDF-Programmierer
Beiträge: 97
Registriert: Mi, 01. Feb 2006 23:49
Wohnort: Glauchau
Kontaktdaten:

Beitrag von rassekst »

Hallo Markus,

Du hast recht, das geht nur wenn man den kompletten Titel angibt. :(

ich verwende folgende eigene Funktion um die Fenster zu finden:

Code: Alles auswählen

FUNCTION FindWindow ( cName, nArt, enth )

LOCAL aWindows := AllWin()          // C-Funktion aufrufen
LOCAL i,j
LOCAL ret := 0
LOCAL gef := .F.

nArt = IIF(nArt=NIL,0,nArt)       // 0 = alle, 1 = Top, 2 = Child
enth = IIF(enth=NIL,.F.,enth)     // .T. eine ZK muß nur im Titel enthalten sein

IF aWindows <> NIL
   FOR i = 1 TO LEN(aWindows)
       IF aWindows[i,2] <> NIL
          IF IIF(enth,UPPER(cName) $ UPPER(aWindows[i,2]),UPPER(aWindows[i,2]) == UPPER(cName))  .AND. nArt <= 1
             ret = aWindows[i,1]
             EXIT
          ENDIF
       ENDIF
       IF (nArt = 0 .OR. nArt = 2) .AND. aWindows[i,3] <> NIL
          FOR j = 1 TO LEN(aWindows[i,3])
              IF aWindows[i,3,j,2] <> NIL
                 IF IIF(enth,UPPER(cName) $ UPPER(aWindows[i,3,j,2]),UPPER(aWindows[i,3,j,2]) = UPPER(cName))
                    ret = aWindows[i,3,j,1]
                    gef = .T.
                    EXIT
                 ENDIF
              ENDIF
          NEXT
          IF gef
             EXIT
          ENDIF
       ENDIF
   NEXT
ENDIF

RETURN(ret)
Die Funktion AllWin() ist eine eigenes C-Programm um eine gute Geschwindigkeit zu erreichen.

Sag mir mal Deine eMail-Adresse um dir alles zu zusenden.

Oder geht der upload ins Forum ?!

Gruss Steffen
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16501
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Steffen,
rassekst hat geschrieben:Oder geht der upload ins Forum ?!
nein - bisher noch nicht! Wenn Tom mal viel Zeit findet...

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
rassekst
UDF-Programmierer
UDF-Programmierer
Beiträge: 97
Registriert: Mi, 01. Feb 2006 23:49
Wohnort: Glauchau
Kontaktdaten:

Beitrag von rassekst »

Hallo Martin,

muss da nicht nur ein MOD eingespielt werden ?

Ich stelle die C-Quelle erstmal so rein.
Wenn jemand einen C-Compiler hat kann man es ja übersetzen.

Code: Alles auswählen

/******************************************************************************
 *
 *  AllWin.c
 *
 *  Copyright:
 *    Steffen Raßek, (c) 2001. All rights reserved.
 *
 *  Contents :
 *    Return all Top Windows with all Childwindows
 *
 ******************************************************************************/

#include <windows.h>
#include "xppdef.h"
#include "xpppar.h"
#include "xppcon.h"
#include <winuser.h>
//#include <stdio.h>


ContainerHandle  hArray;
ContainerHandle  hChildArray;
BOOL  lLeerFlag = FALSE;
int hWnd = 0;
int  z   = 0;
int zz   = 0;

XPPRET XPPENTRY ALLWIN (XppParamList paramList)
{

    BOOL CALLBACK CountWindows(HWND hwnd,LPARAM lParam);
    BOOL CALLBACK WindowsTitle(HWND hwnd,LPARAM lParam);

    lLeerFlag = _parl( paramList, 1 );  // auch Fenster ohne Titel suchen
    hWnd      = _parnl( paramList, 2 );  // Fenster eines Windows suchen

    z = 0;

    if (hWnd == 0)
     	EnumWindows(CountWindows,0);
    else
     	EnumChildWindows(hWnd,CountWindows,0);


    hArray = 0;
    hArray = _conNewArray(2, z, 3, 0);

    z = 0;

    if (hWnd == 0)
       EnumWindows(WindowsTitle,0);
    else
       EnumChildWindows(hWnd,WindowsTitle,0);

   _conReturn(paramList, hArray);
   _conRelease(hArray);

   return;
}

BOOL CALLBACK CountWindows(HWND hwnd,LPARAM lParam)
{
   TCHAR lpString [100];
   int nMaxCount = 100;

   GetWindowText(hwnd,lpString,nMaxCount);

   if (lpString[0] != 0x0 | lLeerFlag)
   {
   ++z;
   }

   return 1;
}

BOOL CALLBACK CountChildWindows(HWND hwnd,LPARAM lParam)
{
   TCHAR lpString [100];
   int nMaxCount = 100;

   GetWindowText(hwnd,lpString,nMaxCount);

   if (lpString[0] != 0x0 | lLeerFlag)
   {
   ++zz;
   }

   return 1;
}

BOOL CALLBACK WindowsTitle(HWND hwnd,LPARAM lParam)
{

   BOOL CALLBACK CountChildWindows(HWND hwnd,LPARAM lParam);
   BOOL CALLBACK ChildWindowsTitle(HWND hwnd,LPARAM lParam);

   ContainerHandle  hHandle;
   ContainerHandle  hTitle;

   TCHAR lpString [256];
   int nMaxCount = 256;

   GetWindowText(hwnd,lpString,nMaxCount);

   if (lpString[0] != 0x0 | lLeerFlag)
   {
           hTitle  = _conPutC(NULLCONTAINER,lpString);
           hHandle = _conPutNL(NULLCONTAINER,(LONG)hwnd);

           ++z;

           _conArrayPut(hArray,hHandle,z,1,0);
           _conArrayPut(hArray,hTitle,z,2,0);
           _conRelease(hHandle);
           _conRelease(hTitle);
   }

   // alle ChildWindows holen
   zz = 0;

   EnumChildWindows(hwnd,CountChildWindows,0);

   hChildArray = _conNewArray(2, zz, 2, 0);

   if ( zz > 0 )
   {
        zz = 0;

        EnumChildWindows(hwnd,ChildWindowsTitle,0);

        _conArrayPut(hArray,hChildArray,z,3,0);
   }

   _conRelease(hChildArray);

   return 1;
}

BOOL CALLBACK ChildWindowsTitle(HWND hwnd,LPARAM lParam)
{

   ContainerHandle  hHandle;
   ContainerHandle  hTitle;

   TCHAR lpString [256];
   int nMaxCount = 256;

   GetWindowText(hwnd,lpString,nMaxCount);

   if (lpString[0] != 0x0 | lLeerFlag)
   {
           hTitle  = _conPutC(NULLCONTAINER,lpString);
           hHandle = _conPutNL(NULLCONTAINER,(LONG)hwnd);

           ++zz;

           _conArrayPut(hChildArray,hHandle,zz,1,0);
           _conArrayPut(hChildArray,hTitle,zz,2,0);
           _conRelease(hHandle);
           _conRelease(hTitle);
   }
   return 1;
}
Das ist zwar das selbe was Markus in xBase++ geschrieben hat nur eben etwas schneller.

Gruss Steffen
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16501
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Beitrag von Martin Altmann »

Hallo Steffen,
rassekst hat geschrieben:muss da nicht nur ein MOD eingespielt werden ?
ja - aber lass' das mal nicht den Tom lesen! Von wegen nur ;-)

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
boddy
Cut&Paste-Entwickler
Cut&Paste-Entwickler
Beiträge: 22
Registriert: Fr, 30. Sep 2005 11:39
Wohnort: Berlin

Der nächste Versuch

Beitrag von boddy »

Hallo Markus,

die Messagebox kann ich auch erst sehen, nachdem ich das Editorfenster verkleiner, verschiebe, in den Hintergrund bringe oder schließe. Aber es wird gleich nach dem Editorstart ausgegeben, nur eben hinter dem Editfenster.
Von FritzFax habe ich keine Ahnung, aber ich habe das Programm etwas erweitert, damit es mit keybd_event mal einen Text in das „Unbenannte – Editor“ – Fenster schreibt.

Code: Alles auswählen

****************************************************** 

#include "dll.ch" 
#include "bap.ch" 
#include "Appevent.ch" 
#include "Xbp.ch"

#define KEYEVENTF_KEYUP 0x02
#define VK_SHIFT 0x10
#define SW_NORMAL 1 

#pragma Library( "XbtBase1.lib" ) 
#pragma Library( "XbtBase2.lib" ) 

*----------------------------------------------------- 

DLLFUNCTION EnumWindows( lpEnumFunc, lParam ) USING OSAPI FROM user32.dll 
DLLFUNCTION GetWindowTextA( hwnd, @lpString, nMaxCount ) USING OSAPI FROM user32.dll 
DLLFUNCTION BringWindowToTop( nHwnd ) USING STDCALL FROM USER32.DLL 
DLLFUNCTION SetForegroundWindow( nHwnd ) USING STDCALL FROM USER32.DLL 
DLLFUNCTION ShowWindow( hwnd, nCmdShow ) USING STDCALL FROM USER32.DLL 
DLLFUNCTION VkKeyScanA( cChar ) USING STDCALL FROM USER32.DLL 
DLLFUNCTION keybd_event( bVk, bScan, dwFlags, dwExtraInfo ) USING STDCALL FROM USER32.DLL 

*----------------------------------------------------- 

procedure appsys 
return 

*----------------------------------------------------- 

procedure main 

//... 
MsgBox( "Start Thread" ) 
oThread := Thread():new() 
oThread:start( "FindHandle", "ABCD" ) 
//... 

oDlg         := XbpDialog():new( , , {0,0}, AppDesktop():currentSize() ) 
oDlg:title   := "Programmfenster" 
oDlg:taskList := .T. 
oDlg:create() 

SetAppFocus( oDlg ) 

nEvent := 0 
DO WHILE nEvent <> xbeP_Close 
   nEvent := AppEvent( @mp1, @mp2, @oXbp ) 
   oXbp:handleEvent( nEvent, mp1, mp2 ) 
ENDDO 

oDlg:destroy() 

return 

*----------------------------------------------------- 

function FindHandle( par1 ) 
local nHandle := 0 
local nStart := seconds() 

  do while ( nHandle = 0 ) .and. ( seconds() < ( nStart + 20 ) ) 
    nHandle := wGetWinHandleFromTitle( "Unbenannt - Edi" ) 
    iif( nHandle = 0, Sleep( 100 ), ) 
//    tone( 100, 3 )    // Test-Ausgabe 
  enddo 

  if nHandle > 0 
    SchreibText( nHandle, "Die einfache Ausgabe funktioniert bei mir !!!" + chr( 13 ) )
    sleep( 25 )
    msgbox( "Gefunden !!!", "Fenster" ) 
   else 
    msgbox( "Nicht gefunden !!!", "Fenster" ) 
  endif 

return nil 

*----------------------------------------------------- 
function SchreibText( nHandle, cText )
local i
local cChar
local iChar

ShowWindow( nHandle, SW_NORMAL )
*BringWindowToTop( nHandle ) 
SetForegroundWindow( nHandle )
for i = 1 to len( cText )
	cChar := substr( cText, i, 1 )
	iChar := VkKeyScanA( asc( cChar ) )

	iif( isbit( iChar, 9 ),	keybd_event( VK_SHIFT, 0, 0, 0 ), nil )
	keybd_event( numand( iChar, 0xFF ), 0, 0, 0 ) 
   sleep( 5 )
	keybd_event( numand( iChar, 0xFF ), 0, KEYEVENTF_KEYUP, 0 ) 
	iif( isbit( iChar, 9 ),	keybd_event( VK_SHIFT, 0, KEYEVENTF_KEYUP, 0 ), nil )

next

return nil
*----------------------------------------------------- 

function wGetWinHandleFromTitle( cTitle ) 
local nCallBack, nFlags 

  nGetWinHandleFromTitle := 0 
  cGetWinHandleFromTitle := cTitle 

  nCallBack := BaCallBack( "wGetWinHandleFromTitleCallBack", BA_CB_GENERIC1 ) 

  nFlags := 0 
 EnumWindows( nCallback, nFlags ) 

return( nGetWinHandleFromTitle ) 

*----------------------------------------------------- 

// Call-Back-Funktion 
FUNCTION wGetWinHandleFromTitleCallBack( hWnd, nPar1 ) 
local cWindowName := space( 71 ) 

    GetWindowTextA( hWnd, @cWindowName, 70 ) 
*    cWindowName := strtran( cWindowName, chr( 0 ) ) 
    cWindowName := ZTrim( cWindowName ) 

    if left( cWindowName, len( cGetWinHandleFromTitle ) ) == cGetWinHandleFromTitle 
      nGetWinHandleFromTitle := hWnd 
      RETURN 0 
    endif 

RETURN 1 

*----------------------------------------------------- 

Static FUNCTION ZTrim( cString ) 
   LOCAL nZPos 
  nZPos := At( Chr( 0 ), cString ) 
RETURN IIF( nZPos>0, Substr( cString, 1, nZPos-1 ), cString ) 

*-----------------------------------------------------
Bei mir funktioniert es auf verschiedenen Rechnern, egal wie groß das Programmfenster ist, ob der Editor schon läuft oder nicht (Hauptssache er wird innerhalb von 20 Sekunden nach Threadstart gestartet).


Gruß
Boddy

PS.: Du benutzt doch Windows ??? :wink:
Antworten