|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Не правильный пересчет integer'а
Или я туплю или Delphi тупит. И так. Delphi 7. Пишу прогу в которой значение integer'а должно прибавляться на 1, начиная от -1, причем по таймеру, и при достижении некоего значения таймер должен отключатся. Но почему-то прибавление значения происходит как то не так. При запуске программы значение равно -1, при запуске таймера должно прибавится + 1 и значение integer'а по идее и по математическим законам должно стать 0, потом 1, 2, 3 и т.д. до достижения значения N, при котором цикл должен остановится, но почему то вместо 0 он выдает 1, а уже потом 0. Причем если проделывать операцию происходящую по таймеру просто кнопкой, то все нормально. Почему???
Вот код: Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) Button1: TButton; Timer1: TTimer; Button2: TButton; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; idirs: integer; icount: integer; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin Timer1.Enabled:=True; end; procedure TForm1.FormCreate(Sender: TObject); begin idirs:=5; //Тут число задавалось немного другим кодом icount:=-1; ShowMessage('icount: ' + IntToStr(icount) + ' idirs: ' + IntToStr(idirs)); end; procedure TForm1.Timer1Timer(Sender: TObject); begin If icount = idirs - 1 then Timer1.Enabled:=False else begin Inc(icount); // До этого использовалось icount:=icount + 1 ShowMessage('icount: ' + IntToStr(icount)); // некий код, который к данному вопросу не имеет отношения и лишь считывает значение icount end; end; procedure TForm1.Button2Click(Sender: TObject); begin Inc(icount); // До этого использовалось icount:=icount + 1 ShowMessage('icount: ' + IntToStr(icount)); end; end. |
#2
|
||||
|
||||
На Delphi XE7 все работает как надо. А какой интервал у таймера?
Всегда пишите код так, будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете. |
#3
|
|||
|
|||
Скорее всего виноват "вырезанный" код, видимо время его исполнения больше, чем интервал таймера. Ну и для безопасности надо делать так:
Код:
procedure TForm1.Timer1Timer(Sender: TObject); begin Timer1.Ebabled := False; Try Inc(icount); // До этого использовалось icount:=icount + 1 ShowMessage('icount: ' + IntToStr(icount)); // некий код, который к данному вопросу не имеет отношения и лишь считывает значение icount Finally Timer1.Enabled := icount < idris; Endl end; |
#4
|
|||
|
|||
Цитата:
Интервал 10мс. Цитата:
Попробую сделать так, потом отпишусь. Я могу выложить код целиком, но в коде используются сторонние компоненты, так что проверить его Вы не сможете без этих компонентов, но если уж так надо, то вот код целиком, без "вырезанных" кусков: Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, cmpGFXListBox, pngimage, PngImageList, ImgList, ExtCtrls; type TForm1 = class(TForm) GFXListBox1: TGFXListBox; Button1: TButton; Memo1: TMemo; PngImageList1: TPngImageList; Timer1: TTimer; Button2: TButton; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; PNG: TPngObject; idirs: integer; icount: integer; implementation {$R *.dfm} function MatchAttrs(flags, attrs: DWORD): Boolean; begin MatchAttrs := (flags and attrs) = flags; end; function SearchInFolder(folder: String; names: TStrings): Boolean; var hSearch: Thandle; FindData: WIN32_FIND_DATA; strSearchPath: String; bRes: Boolean; begin strSearchPath := folder + '\*.*'; bRes:= false; hSearch := FindFirstFile(PAnsiChar(strSearchPath), FindData); if hSearch <> INVALID_HANDLE_VALUE then repeat if (String(FindData.cFileName) <> '..') and (String(FindData.cFileName) <> '.') then if MatchAttrs(FILE_ATTRIBUTE_DIRECTORY, FindData.dwFileAttributes) then begin names.Add(FindData.cFileName); bRes:=True; end; until FindNextFile(hSearch, FindData) = False; SearchInFolder := bRes; end; procedure TForm1.Button1Click(Sender: TObject); begin //ShowMessage(Memo1.Lines.Strings[0]); //ShowMessage(IntToStr(idirs)); { PNG.LoadFromFile(ExtractFilePath(Application.ExeName)+'img\'+Memo1.Lines.Strings[0]+'\test1.png'); PngImageList1.InsertPng(0, PNG, 0); GFXListBox1.AddItem(Memo1.Lines.Strings[0], cbChecked, 0); } Timer1.Enabled:=True; end; procedure TForm1.FormCreate(Sender: TObject); begin if not SearchInFolder(ExtractFilePath(Application.ExeName)+'img\', Memo1.Lines) then ShowMessage('Error'); idirs:=Memo1.Lines.Count; icount:=-1; ShowMessage('icount: ' + IntToStr(icount) + ' idirs: ' + IntToStr(idirs)); end; procedure TForm1.Timer1Timer(Sender: TObject); begin If icount = idirs - 1 then Timer1.Enabled:=False else begin Inc(icount); PNG:= TPngObject.Create; PNG.LoadFromFile(ExtractFilePath(Application.ExeName)+'img\'+Memo1.Lines.Strings[icount]+'\test1.png'); ShowMessage('PNG Loaded! icount: '+ IntToStr(icount)); PngImageList1.InsertPng(icount, PNG, 0); GFXListBox1.AddItem(Memo1.Lines.Strings[icount], cbChecked, icount); //ShowMessage('List Added!'); end; end; procedure TForm1.Button2Click(Sender: TObject); begin Inc(icount); ShowMessage('icount: ' + IntToStr(icount)); end; end. Код сканирует папку, на наличие других папок и выдает их список, далее по идее он должен выдать этот список в сторонний компонент (GFXListBox, это по сути CheckListBox с поддержкой картинок), при этом подгрузив картинку, из каждой папки свою (хоть имена у них и одинаковые). И не надо кидаться тапками, я не профи программист, пишу как умею. |
#5
|
||||
|
||||
Если внутри события таймера не вызывать обработчик событий, как это часто и бывает, то WM_TIMER не придёт и делать таймера Enabled = false нет смысла.
Пишу программы за еду. __________________ |
#6
|
|||
|
|||
Да, во время исполнения не придет, но очередь встанет. Короче, я рекомендую отключать.
>10мс Вот и ответ. |
#7
|
|||
|
|||
Поставил 100, 200, 500 мс, ни чего не изменилось, все равно сначала 1, а потом 0, а не наоборот.
|