Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi zu schnelle reaktion (https://www.delphipraxis.net/88106-zu-schnelle-reaktion.html)

EWeiss 10. Mär 2007 09:37


zu schnelle reaktion
 
Hallo

Delphi-Quellcode:
function VuBoxW5_Render(This_Mod: PWinAMPVisModule): integer;
var
  LastTime: DWord;
  tr: TRect;
  SongName   : PChar;
  PlaylistPos : LongInt;
 
begin
  if Active then
  begin
    LastTime   := ElapsedTime;
    ElapsedTime := GetTickCount() - PluginStart;
    ElapsedTime := (LastTime + ElapsedTime) div 2;

    if VisForm.DrawAboutScroll then
      with VisForm.Image1.Canvas, VisForm.Image1 do
      begin
        Brush.Color := clBlack;
        Font.Color := $00CEFFCE;
        Font.Style := [fsBold];
        FillRect(ClipRect);
        SetRect(tr, 0, 0, Width, 0);
        DrawText(Handle, SAboutText, -1, tr,
          DT_CALCRECT or DT_WORDBREAK or DT_CENTER or DT_NOPREFIX);
        tr.Top   := VisForm.aboutpos;
        tr.Left  := Round((Width - (tr.Right - tr.Left)) / 2);
        tr.Right := tr.Left + tr.Right;
        tr.Bottom := tr.Top + tr.Bottom;
        DrawText(Handle, SAboutText, -1, tr,
          DT_WORDBREAK or DT_CENTER or DT_NOPREFIX);
      end else
    begin

    glDraw(This_Mod);

    // Display Song Name
    PlaylistPos:= SendMessage(This_Mod^.hWNDParent, WM_USER, 0, 125);
    SongName := Pointer(SendMessage(This_Mod^.hWNDParent, WM_USER, PlaylistPos, 212));

    glColor3f(1,1,1);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glPrintBitmap(10 , 10, SongName, 1);
    glDisable(GL_BLEND);

    if HelpScreen then VuBoxW5HelpScreen();

    SwapBuffers(h_DC);

    end;

    if VisForm.DrawAboutScroll then
      with VisForm.Image1.Canvas, VisForm.Image1 do
      begin
        SetRect(tr, 0, 0, Width, 0);
        DrawText(Handle, SAboutText, -1, tr,
          DT_CALCRECT or DT_WORDBREAK or DT_CENTER or DT_NOPREFIX);

        if (VisForm.aboutpos + (tr.Bottom - tr.Top)) <= 0 then
          VisForm.DrawAboutScroll := False;
        if VisForm.aboutpos > (Height div 2) then
          Dec(VisForm.aboutpos, 4)
        else if VisForm.aboutpos > (Height div 3) then
          Dec(VisForm.aboutpos, 1)
        else
          Dec(VisForm.aboutpos, 4);
      end;

    if (keys[VK_ESCAPE]) then
    begin
      Active := False;
      PostQuitMessage(0);
      Result := 1;
      exit;
    end
    else
      ProcessKeys(This_Mod);
  end;
  Result := 0;
end;
Delphi-Quellcode:
procedure ProcessKeys(This_Mod: PWinAMPVisModule);
begin
  // Jump To Prev Song
  if keys[VK_LEFT] then
    SendMessage(This_Mod^.hWNDParent, WM_COMMAND, 40044, 0);

  // Jump To Next Song
  if keys[VK_RIGHT] then
    SendMessage(This_Mod^.hWNDParent, WM_COMMAND, 40048, 0);

  // Toggle Volume Up
  if keys[VK_UP] then
    SendMessage(This_Mod^.hWNDParent, WM_COMMAND, 40058, 0);

  // Toggle Volume Down
  if keys[VK_DOWN] then
    SendMessage(This_Mod^.hWNDParent, WM_COMMAND, 40059, 0);

  if keys[VK_F2] then
    if HelpScreen then HelpScreen:=False else HelpScreen:=True;

end;
Delphi-Quellcode:
// MAIN WINDOW PROCEDURE
function WndProc(hWnd: HWND;              //Handle For The Window
                 Msg: UINT;               //Message For This Window
                 wParam: WPARAM;          //Additional Message Information
                 lParam: LPARAM):         //Additional Message Information
                 LRESULT; stdcall;

begin

  if Msg=WM_SYSCOMMAND then               //Intercept System Commands
    begin
      case wParam of                      //Check System Calls
        SC_SCREENSAVE,SC_MONITORPOWER:    //Screensaver Trying To Start, Monitor Trying To Enter Powersave?
          begin
            result:=0;                    //Prevent This From Happening
            exit;                         //Exit
          end;
      end;
    end;
  case Msg of
    WM_ACTIVATE:
      begin
        if (Hiword(wParam)=0) then        //Check Minimization State
          active:=true                    //Program Is Active
        else
          active:=false;                  //Program Is No Longer Active
        Result:=0;                        //Return To The Message Loop
      end;
    WM_CLOSE:                             //Did We Get A Close Message
      Begin
        PostQuitMessage(0);               //Send A Quit Message
        result:=0                          //Return To The Message Loop
      end;
    WM_KEYDOWN:                           //Is A Key Being Held Down?
      begin
        keys[wParam] := TRUE;             //If So, Mark It As True
        sleep(250);
        result:=0;
      end;
    WM_KEYUP:                             //Is A Key Being Released?
      begin
       keys[wParam] := FALSE;              //If So, Mark It As False
        result:=0;                       //Return To The Message Loop
      end;
    else
      begin
         Result := CallWindowProc(MainWindowProc, hWnd, Msg, wParam, lParam);
      end;
    end;
end;
Mein eigentliches Problem liegt hier!

Delphi-Quellcode:
    WM_KEYDOWN:                           //Is A Key Being Held Down?
      begin
        keys[wParam] := TRUE;             //If So, Mark It As True
        sleep(250);
        result:=0;
      end;
Ohne Sleep(250) ist das ausführen der Key funktionen so schnell das ich mitunter 5 Titel auf einmal überspringe.
Wo liegt das Problem?

gruss Emil

marabu 10. Mär 2007 10:06

Re: zu schnelle reaktion
 
Hallo Emil,

solange eine Taste gedrückt ist (AutoRepeat) werden WM_KEYDOWN Nachrichten generiert. Du könntest über WM_KEYUP und WM_KEYDOWN eine Zustandsvariable umschalten, damit nur einzelne Tastendrücke und keine Wiederholungen interpretiert werden.

Freundliche Grüße

EWeiss 10. Mär 2007 10:09

Re: zu schnelle reaktion
 
Zitat:

Zitat von marabu
Hallo Emil,

solange eine Taste gedrückt ist (AutoRepeat) werden WM_KEYDOWN Nachrichten generiert. Du könntest über WM_KEYUP und WM_KEYDOWN eine Zustandsvariable umschalten, damit nur einzelne Tastendrücke und keine Wiederholungen interpretiert werden.

Freundliche Grüße

Hast ein kleines Sample ?
Weiss nicht genau wie du das meinst ..

Grüße

matashen 10. Mär 2007 10:23

Re: zu schnelle reaktion
 
Delphi-Quellcode:
    WM_KEYDOWN:                           //Is A Key Being Held Down? 
      begin
        if not keys[wParam] then keys[wParam] := TRUE; <=======Machs halt so
        sleep(250);                  <================Dann kannst du dir das sleep sparen
        result:=0;
      end;
Oder versteh ich falsch was du bezwecken willst?


mit Umschaltvariable

Delphi-Quellcode:
    WM_KEYDOWN:                           //Is A Key Being Held Down? 
      begin
        if not umschaltvar then keys[wParam] := TRUE;
        umschaltvar:=true;                  
        result:=0;
      end;

EWeiss 10. Mär 2007 10:43

Re: zu schnelle reaktion
 
@matashen

Beide varianten versucht
Geht nicht ...

Schaltet immer zu viele Lieder auf einmal durch.
Werd mal versuchen umschaltvar:=true; nicht in der Winproc
sondern in ProcessKeys abzulegen

geht auch nicht.
dann läuft die komplette liste durch bis ich wieder gedrückt haeb.

gruss

marabu 10. Mär 2007 10:55

Re: zu schnelle reaktion
 
Ich habe mal in die Doku gesehen - es ist noch einfacher als ich dachte:

Delphi-Quellcode:
// ...
    WM_KEYDOWN:                           //Is A Key Being Held Down?
      begin
        keys[wParam] := not Odd(lParam shr 30); //If So, Mark It As True
        result:=0;
      end;
// ...
Bit 30 von lparam signalisiert den vorherigen Zustand der Taste - 1 = down 0 = up.

Freundliche Grüße

EWeiss 10. Mär 2007 11:06

Re: zu schnelle reaktion
 
Zitat:

Zitat von marabu
Ich habe mal in die Doku gesehen - es ist noch einfacher als ich dachte:

Delphi-Quellcode:
// ...
    WM_KEYDOWN:                           //Is A Key Being Held Down?
      begin
        keys[wParam] := not Odd(lParam shr 30); //If So, Mark It As True
        result:=0;
      end;
// ...
Bit 30 von lparam signalisiert den vorherigen Zustand der Taste - 1 = down 0 = up.

Freundliche Grüße

Nochmal danke aber auch das ändert nichts an dem zustand.
Denke das problem liegt wo anders.

Ist es möglich das es an procedure ProcessKeys(This_Mod: PWinAMPVisModule); liegt ?
Diese wird ja immer aufgerufen innerhalb der

Delphi-Quellcode:
function VuBoxW5_Render(This_Mod: PWinAMPVisModule): integer;
EDIT:
Wenn also ProcessKeys innerhalb 20 ms 5x mal aufgrufen wird
dann sende ich fünf mal keys[VK_UP] das hat dann zur folge das fünf mal die liste gescrollt wird.

end EDIT:

Muss ich doch einen systemweiten hook einbinden damit es richtig funktioniert ?
So kurz kann ich die taste nicht drücken das sich der zustand nicht verändert.

Die frage (Thread) wird eigentlich für manche lustig sein... Aber doch schwieriger als angenommen.

gruss Emil

Flocke 10. Mär 2007 11:53

Re: zu schnelle reaktion
 
Dein Problem liegt nicht in der WndProc sondern in ProcessKeys - wenn die Taste gedrückt ist und wenn diese Routine aufgerufen wird, dann tust du etwas - egal ob du noch ein WM_KEYDOWN usw. bekommen hast oder wieviel Zeit vergangen ist.

Wie wäre es, wenn du in ProcessKeys den Status wieder auf False setzt? Dadurch würde die Routine bis zum nächsten Tastendruck bzw. bis zum Ablauf der Wiederholverzögerung warten. Außerdem müsstest du dann WM_KEYUP überhaupt nicht behandeln.

EWeiss 10. Mär 2007 12:31

Re: zu schnelle reaktion
 
Zitat:

Zitat von Flocke
Dein Problem liegt nicht in der WndProc sondern in ProcessKeys - wenn die Taste gedrückt ist und wenn diese Routine aufgerufen wird, dann tust du etwas - egal ob du noch ein WM_KEYDOWN usw. bekommen hast oder wieviel Zeit vergangen ist.

Wie wäre es, wenn du in ProcessKeys den Status wieder auf False setzt? Dadurch würde die Routine bis zum nächsten Tastendruck bzw. bis zum Ablauf der Wiederholverzögerung warten. Außerdem müsstest du dann WM_KEYUP überhaupt nicht behandeln.

Ja ! ;) Das wars...
Winproc brauch ich trotzdem da die Keys sonst nicht registriert werden


Delphi-Quellcode:
procedure ProcessKeys(This_Mod: PWinAMPVisModule);
begin

  if KeyDown = False then
  begin
  // Jump To Prev Song
  if keys[VK_LEFT] then
    SendMessage(This_Mod^.hWNDParent, WM_COMMAND, 40044, 0);
    KeyDown := true;

  // Jump To Next Song
  if keys[VK_RIGHT] then
    SendMessage(This_Mod^.hWNDParent, WM_COMMAND, 40048, 0);
    KeyDown := true;

  // Toggle Volume Up
  if keys[VK_UP] then
    SendMessage(This_Mod^.hWNDParent, WM_COMMAND, 40058, 0);
    KeyDown := true;

  // Toggle Volume Down
  if keys[VK_DOWN] then
    SendMessage(This_Mod^.hWNDParent, WM_COMMAND, 40059, 0);
    KeyDown := true;

  if keys[VK_F2] then
    if HelpScreen then HelpScreen:=False else HelpScreen:=True;
    KeyDown := true;
  end;

end;
Delphi-Quellcode:
    WM_KEYDOWN:                           //Is A Key Being Held Down?
      begin
        keys[wParam] := True;
        KeyDown := false;
        result:=0;
      end;
    WM_KEYUP:                             //Is A Key Being Released?
      begin
        keys[wParam] := False;
        KeyDown := true;
        result:=0;
      end;
So funktioniert es .

Gruss Emil

turboPASCAL 10. Mär 2007 13:02

Re: zu schnelle reaktion
 
Zitat:

Zitat von EWeiss
Delphi-Quellcode:

procedure ProcessKeys(This_Mod: PWinAMPVisModule);
begin
  // Jump To Prev Song
  if keys[VK_LEFT] then
    SendMessage(This_Mod^.hWNDParent, WM_COMMAND, 40044, 0);

  // Jump To Next Song
  if keys[VK_RIGHT] then
    SendMessage(This_Mod^.hWNDParent, WM_COMMAND, 40048, 0);
    //...
end;

// ....

WM_KEYDOWN:                           //Is A Key Being Held Down?
      begin
        keys[wParam] := True;
        result:=0;
       
        ProgressKeys;
      end;
    WM_KEYUP:                             //Is A Key Being Released?
      begin
        keys[wParam] := False;
        result:=0;

        ProgressKeys;
      end;

Und so ist es auch richtig.

wParam enthält die entsp. Taste zB. die Leertaste. Ist nun eine Taste gedrückt
wird sie im Array Keys[] auf den Booleanwert TRUE gesetzt.
Der Status bleibt solange erhalten bis diese Taste losgelassen wird. Dann wird im Array
der Wert auf FALSE gesetzt. Das macht die Tastatureingaben unabhängig vom Tastaturcontroler
und dessen "Wahlwiederholung. ;)

KeyDown brauchst du dann nicht mehr oder ?


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:25 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz