auf focus des konsolen-fensters reagieren?



  • hallo mal wieder.

    ich bin immernoch dabei ein wenig mit C++ und der konsole herumzuspielen und habe schon wieder ein problem:

    kann ich es abfragen, ob ein konsolenfenster gerade focus hat (im vordergrund ist)?

    ich würde gerne haben, dass sobald ich das programm aus dem hintergrund hole einmal eine funktion ausgeführt wird (eventuell später auch eine andere, wenn das fenster wieder in den hintergrund geschickt wird).

    ist das mit der konsole C++ technisch möglich? wenn ja, habt ihr tips/vorschläge wie ich es realisieren kann?

    danke euch.

    root2

    [ Dieser Beitrag wurde am 22.10.2002 um 11:12 Uhr von root2 editiert. ]



  • Wenn es den Fokus bekommt oder verliert, wird ein FOCUS_EVENT_RECORD ausgelöst. Abzurufen kann man sowas entweder mit ReadConsoleInput() oder mit PeekConsoleInput(), in diesem Fall ist zweites besser, da du ja bis zum FER nicht alles weghaben willst!

    Informationen zu diesen Funktionen findest du in der MSDN (Link in der FAQ zu finden).

    MfG SideWinder



  • hm...
    ich hab mich mal ein bisschen mit dem EVENT_RECORD und dem PeekConsoleInput() auseinandergesetzt aber so richtig klappts bei mir nicht... eigentlich klappt es garnicht...

    hier mal mein code-schnipsel:

    // includes ... blabla...
    
    int main()
    {
      _FOCUS_EVENT_RECORD FOCUS_EVENT_RECORD;  // FOCUS_EVENT_RECORD erstellen
      _INPUT_RECORD INPUT_RECORD;              // INPUT_RECORD erstellen
      int i=0;                                 // hilfsvariable
      unsigned long * number;                  // zeiger auf variable, die die nummer der gelesenen inputs beinhaltet
    
      while(!kbhit())                                         // schleife so lange, bis taste gedrückt wird durchlaufen
      {
        i=PeekConsoleInput(NULL, &INPUT_RECORD, 64, input);  // i=BOOL wert, der von PeekConsoleInput zurückkommt
        printf("peek: %i\n", i);                              // i ausdrucken
        Sleep(100);                                           // 10 x pro sekunde
      }
    
      return 0;
    }
    

    eigentlich sollte sich ja irgendwas ändern, wenn das fenster den fokus bekommt/verliert.
    aber weder ein element des structes FOCUS_EVENT_RECORD, oder des structes INPUT_RECORD, noch der rückgabe-wert von PeekInputConsole() ändern sich!
    mach ich da bei den parametern von PeekInputConsole noch was falsch oder bin ich komplett auf dem holzweg?

    hier mal die MSDN definition von PeekConsoleInput():
    ---
    BOOL PeekConsoleInput(
    HANDLE hConsoleInput,
    PINPUT_RECORD lpBuffer,
    DWORD nLength,
    LPDWORD lpNumberOfEventsRead
    );
    ---
    Parameters

    hConsoleInput
    [in] Handle to the console input buffer. The handle must have the GENERIC_READ access right. For more information, see Console Buffer Security and Access Rights.

    lpBuffer
    [out] Pointer to an array of INPUT_RECORD structures that receives the input buffer data. The total size of the array required will be less than 64K.

    nLength
    [in] Size of the array pointed to by the lpBuffer parameter, in array elements.

    lpNumberOfEventsRead
    [out] Pointer to a variable that receives the number of input records read.
    Return Values

    If the function succeeds, the return value is nonzero.

    If the function fails, the return value is zero. To get extended error information, call GetLastError.
    ---
    weia... 😉

    kann jemand weiterhelfen?

    danke

    root2

    [ Dieser Beitrag wurde am 22.10.2002 um 22:51 Uhr von root2 editiert. ]



  • Also...

    const bool focushaschanged ()
    {
        HANDLE hInput ( GetStdHandle ( STD_INPUT_HANDLE ) );
        DWORD dwEvents ( 0 );
    
        GetNumberOfConsoleInputEvents ( hInput , &dwEvents );
    
        if ( dwEvents == 0 )
            return ( false );
    
        DWORD dwNumberOf ( 0 );
        INPUT_RECORD * ir = new INPUT_RECORD [ dwEvents ];    
    
        PeekConsoleInput ( hInput , ir , dwEvents , &dwNumberOf );
    
        dwNumberOf = 0;
    
        while ( dwNumberOf < dwEvents )
        {
    
            if ( ir[dwNumberOf].EventType == FOCUS_RECORD )
                return ( true );
        }
    
        return ( false );
    }
    
    while true
    {
    
        if ( focushaschanged () )
        {
            cout << "Die Konsole hat gerade ihren Fokus verloren oder bekommen.";
        }    
    
    }
    

    Schau mal ob das funktioniert. Wenn nicht, muss man sich etwas anderes überlegen - kann übrigens leicht sein, da ein FOCUS_EVENT_RECORD eigentlich nur intern behandelt wird.

    BTW: Wenn du nur prüfen willst ob das Konsolenfenster zur Zeit im Vordergrund ist:

    GetForegroundWindow
    The GetForegroundWindow function returns a handle to the foreground window (the window with which the user is currently working). The system assigns a slightly higher priority to the thread that creates the foreground window than it does to other threads.

    HWND GetForegroundWindow(VOID)

    Parameters
    This function has no parameters.

    Return Values
    The return value is a handle to the foreground window.

    QuickInfo
    Windows NT: Requires version 3.1 or later.
    Windows: Requires Windows 95 or later.
    Windows CE: Requires version 1.0 or later.
    Header: Declared in winuser.h.
    Import Library: Use user32.lib.

    See Also
    Windows Overview, Window Functions, SetForegroundWindow

    Rückgabewert mit dem Konsolen-Handle überprüfen - Stichwort: GetConsoleWindow().

    MfG SideWinder



  • hi nochmal!

    sorry das ich erst jetzt antworte aber es hat zeitlich einfach nicht hingehauen.

    das obere beispiel geht nicht, weil du FOCUS_RECORD nicht definierst. ich habe es aber mal angetestet und es jeweils einmal als als _FOCUS_EVENT_RECORD und einmal als _INPUT_RECORD definiert, jedoch beide male ohne erfolg.

    ich bekomme immer eine meldung: "Illegal Struct Instruction" oder so... also scheint da was mit den datentypen nicht ganz hinzuhauen. 😞

    zu deiner 2. frage: ich mag nicht nur prüfen ob, oder welches fenster gerade im vordergrund ist, sondern möchte jedesmal, wenn das fenster den fokus bekommt oder verliert eine funktion ausführt.

    beispiel: fenster hatte keinen fokus und bekommt ihn -> programm soll einen beep senden.
    fenster verliert den fokus wieder -> eben eine andere funktion ausführen.

    ich werde zwar selber mal noch dran feilen bin aber für hilfe gern bereit 😉

    tschaui

    root2



  • hi ihr 😉

    ich hab mich mal ein wenig durchgearbeitet und bin auf ne passable lösung gekommen.
    wenn sie jemand begutachten will da issi (also so das grobe gerüst):

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <conio.h>
    #include <windows.h>
    #include <winuser.h>
    #include <ocidl.h>
    #include <dos.h>
    
    #pragma argsused
    int main(int argc, char* argv[])
    {
    
      static HWND WindowHandle, StaticWindowHandle;  // handles definieren
    
      StaticWindowHandle=GetForegroundWindow();  // handle der konsole speichern
    
      while(!kbhit())  // solange nix gedrückt wird die schleife durchlaufen
      {
        WindowHandle=GetForegroundWindow();  // handle des gerade aktiven fensters einlesen
        if(WindowHandle==StaticWindowHandle) // vergleichen mit dem festen handle der konsole
        {
          printf("fenster aktiv!\n");  // wenn gleich -> fenster aktiv
        }
        else
        {
          printf("fenster inaktiv!\n");  // ansonsten -> fenster inaktiv
        }
        Sleep(100);
      }
      getch();
    
      return 0;
    }
    

    wenn jemand ne bessere lösung kennt: nur her damit 😉

    cu

    root2

    [ Dieser Beitrag wurde am 06.11.2002 um 22:14 Uhr von root2 editiert. ]


Anmelden zum Antworten