Startseite ¦  was ist neu ¦  programmier tips ¦  indy artikel ¦  intraweb artikel ¦  informationen ¦  links ¦  interviews ¦  sonstiges
kylix ¦  tutorials ¦  online shop ¦  fotos ¦  Add&Win Gewinnspiel


Willkommen Gast. Bitte einloggen oder registrieren.
08.02.2012, 02:54:57
Übersicht Hilfe Suche Einloggen Registrieren

+  SwissDelphiCenter Forum
|-+  German Forums
| |-+  WinAPI Forum
| | |-+  Hilfe: seltsamer Multimediatimer-Bug
« vorheriges nächstes »
Seiten: [1] Drucken
Autor Thema: Hilfe: seltsamer Multimediatimer-Bug  (Gelesen 2038 mal)
tommyjunge
Full Member
***
Offline Offline

Beiträge: 162



« am: 13.09.2008, 14:20:33 »

Hallo,

ich habe ein ganz einfaches Testprogramm, das für mich unverständlich reagiert:

Prinzip:
-Drückt man auf sweep, wird der multimediatimer gestartet.
-Der zählt bis 5, killt sich dann wieder und sendet eine Windowsmessage an SweepDone
-Sweepdone startet das ganze von vorne, da der Continuous-Speedbutton gedrückt ist (das ist der Fehlerfall), ansonsten ist Ende.

Der MMTimer sollte immer abwechselnd gestartet und gestoppt werden, siehe Konsolenausgabe. Im Fehlerfall wird er aber mehrfach gestartet ohne Stopp. Warum??????

Hier ist der komplette Code:
Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Buttons, MMSystem, StdCtrls;
const
  WM_SWEEP_DONE   = WM_USER;
type
  TFormMain = class(TForm)
    SpeedButtonCont: TSpeedButton;
    SpeedButtonSweep: TSpeedButton;
    procedure SpeedButtonSweepClick(Sender: TObject);
  private
    { Private declarations }
     procedure SweepDone(var Msg: TMessage); message WM_SWEEP_DONE;
  public
    { Public declarations }
  end;

var
  FormMain: TFormMain;


implementation
var
  index: integer;
  mmResult: integer;
  sweeping: boolean;
  FDBG: TextFile;
  NPoints: integer=5;
  OwnHandle: HWND;
{$R *.dfm}

procedure TFormMain.SweepDone(var Msg: TMessage);
begin
if not SpeedButtonCont.Down then SpeedButtonSweep.Down:=false;
SpeedButtonSweepClick(Self);
end;

procedure CallBack(TimerID, Msg: Uint; dwUser, dw1, dw2: DWORD); pascal;
begin
if not sweeping then
  begin
    if mmResult<>-1 then
      begin
        TimeKillEvent(mmResult);
        writeln('E'+inttohex(mmResult,8)+' ');
        mmResult:=-1;
        exit;
      end;
    writeln('you should not see me!');
    Raise Exception.Create('Error');
    exit;
  end;
index:=index+1 ;
if Index<NPoints then exit;
sweeping:=false;
PostMessage(OwnHandle, WM_SWEEP_DONE, 0,0);
end;

procedure TFormMain.SpeedButtonSweepClick(Sender: TObject);
begin
if SpeedButtonSweep.Down then
  begin
    ownhandle:=self.Handle;
    index:=0;
    sweeping:=true;
    mmResult := TimeSetEvent( 1, 0, @CallBack, 0, TIME_PERIODIC);
    write('S'+inttohex(mmResult,8)+' ');
  end
  else
  begin
    if mmResult<>-1 then
      begin
        TimeKillEvent(mmResult);
        writeln('X'+inttohex(mmResult,8)+' ');
        mmresult:=-1;
      end;
  end;
end;

end.
Gespeichert
tommyjunge
Full Member
***
Offline Offline

Beiträge: 162



« Antworten #1 am: 22.09.2008, 08:20:38 »

Habs gefunden.

Der Timer darf sich in der Call-Back Routine nicht selbst killen.
Korrekt: Aus der Callback-Routine Postmessage an eine Routine, die den Timer killt.

Gruß, Thomas
Gespeichert
Seiten: [1] Drucken 
« vorheriges nächstes »
Gehe zu:  


Einloggen mit Benutzername, Passwort und Sitzungslänge

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006, Simple Machines LLC Prüfe XHTML 1.0 Prüfe CSS