Programm jederzeit mit bestimmter Taste beenden



  • Hallo,

    Ich möchte ein Programm jederzeit mit einer bestimmten Taste (z.B. Esc) beeenden können. Allerdings find ich einfach nicht heraus, wie man so etwas realisiert...

    Bin über alles dankbar, wie gesagt ich habe einfach keine Anhaltspunkte bei meiner Suche im Internet gefunden.


  • Mod

    Erster Tipp: CTRL+C.
    Zweiter Tipp: Das ist leider ziemlich systemabhängig, wie man so etwas angeht und geht über den Sprachstandard hinaus. Welches Betriebssystem?



  • Es sollte schon vom Programm aus beenden, wenn man eine bestimmte Taste drückt.
    Das ganze soll also "unabhängig" von der Konsole sein.

    OS ist Windows 7



  • Da gibt's recht viele Möglichkeiten mit der WinAPI. Hook's wären da ein Stichwort. Am einfachsten wäre es vermutlich, einfach mit GetAsyncKeystate() zu fragen ob eine Taste gedrückt wurde. Das ist allerdings alles unüblich und hässlich, gerade wenn du sonst mit Standard-C schreibst. STRG+C gibt es nahezu überall und du musst dich nicht darum kümmern.



  • STRG+C möchte ich nicht verwenden, es geht mir ja schließlich darum, wie man es programmieren kann, dass das Programm bei einer bestimmten Taste etwas tut.

    Bevor ich mich mal mit GetAsyncKeystate() und Hook's beschäftige, kann man diese auch so benutzen, dass man nicht jedesmal abfragen muss, ob eine Taste gedrückt wurde? Also dass man ganz am Anfang des Programms einmal festlegt, was eine Taste für eine Funktion hat und diese Funktion auch immer ausgeführt wird, wenn diese Taste betätigt wird?



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C (C89 und C99) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    Das geht bestimmt. Ich verschiebe dich mal hierher, da sitzen die Experten wie man das in Windows macht.



  • hast du dir schon mal ein minimales windows programm mit message-loop angesehen?
    in dieser message-loop kannst du die tasten abfragen und drauf mit funktionen deiner wahl reagieren.



  • Ok danke, ich werds mir mal angucken.

    Message loop kommt mir sowieso irgendwo her bekannt vor... 😃



  • function dlgfunc(Dlg: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall;
    begin
      result := true;
      case Msg of
        WM_CLOSE:
          begin
            EndDialog(Dlg, 0);
          end;
        WM_COMMAND:
          begin
            { accel for closing the dialog with ESC }
            if wParam = ID_CANCEL then
              SendMessage(Dlg, WM_CLOSE, 0, 0);
            { button and menu clicks }
            if hiword(wParam) = BN_CLICKED then
            begin
              case LoWord(wParam) of
                IDC_BTN_ABOUT:
                  begin
                    InfoBox(Dlg);
                  end;
                IDC_BTN_CLOSE: SendMessage(Dlg, WM_CLOSE, 0, 0);
              end;
            end;
          end
      else
        result := false;
      end;
    end;
    

    Ist zwar Delphi und für einen Dialog, aber für ein Fenster funktioniert es ähnlich.

    Alternativ kann man in der Ressource auch einen Accelerator definieren:

    program Fenster_Vorlage;
    
    uses
      Windows,
      Messages,
      CommCtrl,
      MpuTools in 'units\MpuTools.pas',
      Constants in 'units\Constants.pas';
    
    {$R .\res\resource.res}
    
    var
      hApp              : THandle;
      hBanner: THandle;
      hClose            : THandle;
      MyFont            : HFONT;
      hAccelTbl         : THandle;
    
    function WndProc(hWnd: HWND; uMsg: UINT; wParam: wParam; lParam: LParam):
      lresult; stdcall;
    var
      x, y              : integer;
    begin
      Result := 0;
      case uMsg of
        WM_DESTROY:
          begin
            DeleteObject(MyFont);
            PostQuitMessage(0);
          end;
        WM_COMMAND:
          begin
            if hiword(wParam) = BN_CLICKED then
              case loword(wParam) of
                IDC_BTN_CLOSE: SendMessage(hWnd, WM_CLOSE, 0, 0);
              end;
            if hiword(wParam) = 1 then // 1 = Accelerator
              case loword(wParam) of
                IDC_ACCEL_CLOSE: SendMessage(hWnd, WM_CLOSE, 0, 0);
              end;
          end;
      else
        Result := DefWindowProc(hWnd, uMsg, wParam, lParam);
      end;
    end;
    
    var
      wc                : TWndClassEx = (
        cbSize: SizeOf(TWndClassEx);
        Style: CS_HREDRAW or CS_VREDRAW;
        lpfnWndProc: @WndProc;
        cbClsExtra: 0;
        cbWndExtra: 0;
        hbrBackground: COLOR_BTNFACE + 1;
        lpszMenuName: nil;
        lpszClassName: ClassName;
        hIconSm: 0;
        );
      msg               : TMsg;
    begin
      InitCommonControls;
    
      wc.hInstance := hInstance;
      wc.hIcon := LoadIcon(0, IDI_APPLICATION);
      wc.hCursor := LoadCursor(0, IDC_ARROW);
    
      RegisterClassEx(wc);
      hApp := CreateWindowEx(0, CLASSNAME, APPNAME, WS_OVERLAPPEDWINDOW or WS_VISIBLE or WS_SYSMENU or WS_MINIMIZEBOX or
        WS_MAXIMIZEBOX or WS_SIZEBOX, Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT), WINDOWWIDTH, WINDOWHEIGHT, 0, 0,
        hInstance, nil);
    
      hAccelTbl := LoadAccelerators(hInstance, MAKEINTRESOURCE(4000));
    
      while true do
      begin
        if not GetMessage(msg, 0, 0, 0) then
          break;
        if TranslateAccelerator(hApp, hAccelTbl, msg) = 0 then
          if IsDialogMessage(hApp, msg) = FALSE then
          begin
            TranslateMessage(msg);
            DispatchMessage(msg);
          end;
      end;
      ExitCode := msg.wParam;
    end.
    


  • Wie sieht denn dein Programm aus? Ist es eine Konsolenanwendung oder eine fensterbasierte Applikation?
    Mein Tipp: fang mal das WM_KEYDOWN-Event ab und schau, ob die Taste VK_ESCAPE ist.

    Grüße,
    Rewind


Anmelden zum Antworten