Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.02.20;
Скачать: CL | DM;

Вниз

Проблема с выводом изображения на канву формы...   Найти похожие ветки 

 
Artemka ©   (2004-10-26 21:33) [0]

Здравствуйте! Нужна помощь... Из почти тривиальной задачи выросла проблема, которую я никак не могу решить! :) Ответа я не найти не могу, так что надеюсь на вашу помощь.
Значит, так: требуется перемещать (как-то) маленькое изображение по форме. Для обеспечения плавного движения я использовал мультимедийный таймер. В обработчике сообщений этого таймера изображение рисуется сначала на канве bitmap"а, а потом копируется на канву формы приложения. И вот тут то возникает странное (для меня) явление: если не двигать мышь, то все нормально... но стоит только начать двигать мышь, и через некоторое время (оно тем меньше, чем меньше задержка у таймера) объект перестает двигаться, хотя таймер не останавливается и приложение нормально реагирует на события. Рисование объекта на форме возобновляется, если вызывается событие OnPaint (если свернуть и потом развернуть форму, например). Дальше все опять повторяется. Кто подскажет в чем  дело?
P.S. Может мышь, конечно, и не причем... :)


 
Kind   (2004-10-26 21:52) [1]

У меня было нечто похожее, когда таймер срабатывает чаще, чем успевает перерисоваться всё окно, т.е. OnPaint ещё не отработан а у тебя уже следующий тик таймера. Хотя ...
У тебя OnIdle не задействован?


 
Artemka ©   (2004-10-26 22:08) [2]

У меня такие же подозрения. Я только не могу понять: почему на мышь такая реакция?!
Насчет OnIdle - нет. Я его вообще ни разу в жизни не пробовал...


 
Mihey_temporary ©   (2004-10-26 22:30) [3]

Видать, перемудрил...


unit mainUnit;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
 TmainForm = class(TForm)
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
   procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
   procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
   procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
     Y: Integer);
   procedure FormPaint(Sender: TObject);
 private
   { Private declarations }
 public
   procedure IdleHandler(Sender: TObject; var Done: Boolean);
 end;

var
 mainForm: TmainForm;
 Bmp: TBitmap;
 x0, y0, w0, h0: Integer;
 Dragginn: Boolean;

implementation

{$R *.DFM}

procedure TmainForm.IdleHandler(Sender: TObject; var Done: Boolean);
begin
 Invalidate;
end;

procedure TmainForm.FormCreate(Sender: TObject);
begin
 Bmp := TBitmap.Create;
 Bmp.LoadFromFile("bitmap.bmp");
 w0 := Bmp.Width; h0 := Bmp.Height;
 x0 := 50; y0 := 50;
 DoubleBuffered := True;
 Application.OnIdle := IdleHandler;
end;

procedure TmainForm.FormDestroy(Sender: TObject);
begin
 Bmp.Free;
end;

procedure TmainForm.FormMouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
begin
 If PtInRect(Rect(x0,y0,x0+w0,y0+h0), Point(X,Y)) then
  begin
   Dragginn := True;
   Caption := "mainForm Draging";
   x0 := X;
   y0 := Y;
  end;
end;

procedure TmainForm.FormMouseUp(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
begin
 Dragginn := False;
 Caption := "mainForm";
end;

procedure TmainForm.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
 Y: Integer);
begin
 If Dragginn then
  begin
    x0 := X;
    y0 := Y;
  end;
end;

procedure TmainForm.FormPaint(Sender: TObject);
begin
 BitBlt(Canvas.Handle, 0, 0, ClientWidth, ClientHeight, Canvas.Handle, 0, 0,
   WHITENESS);
 BitBlt(Canvas.Handle, x0, y0, w0, h0, Bmp.Canvas.Handle, 0, 0, SRCCOPY);
end;

end.


Простое решение с OnIdle.


 
Artemka ©   (2004-10-27 01:51) [4]

Спасибо за помощь! Действительно, перемудрил... :-) Правда суть вышеописанного мной "бага" мне так и не ясна. Бы очень рад удовлетворить свое любопытство! Так что если кто знает...


 
debuger ©   (2004-10-27 16:02) [5]

Расскажи о мультимедийном таймере и способе его использования.


 
Artemka ©   (2004-10-27 20:52) [6]

Мультимедийный таймер может имееть период срабатывания от 1 мс и выше. Однако этот таймер не имеет компонентного воплощения, поэтому для доступа к нему приходится использовать функции API.

Обработчик для таймера, например, такой:


procedure TimeProc(uID, uMsg: UINT; dwUser, dw1, dw2: DWORD); stdcall;  


Запуск и выключение таймера реализуется функциями, импортируемыми из библиотеки "winmm.dll":


function timeSetEvent(uDelay, uResolution: UINT; lpTimeProc: Pointer; dwUser: DWORD; fuEvent: UINT): UINT; stdcall; external "winmm.dll";

function timeKillEvent(uID: UINT): UINT; stdcall; external "winmm.dll";  


 
Kind   (2004-10-27 21:55) [7]

Выложи код, посмотрим при чём тут мышка.


 
Sapersky   (2004-10-28 10:15) [8]

но стоит только начать двигать мышь, и через некоторое время (оно тем меньше, чем меньше задержка у таймера) объект перестает двигаться

Если это WinXP - то там, похоже, обработка мыши какая-то очень навороченная. У меня тоже был случай, когда из-за мыши тормозило, хотя таймером не пользовался, а рисовал в основном цикле WinAPI (примерно то же самое, что и OnIdle c Done=False) и делал паузу Sleep.


 
Artemka ©   (2004-11-05 01:35) [9]

Был вынужден долго отсутствовать... :-) Думаю в исходниках потребности нет, т.к. взглянув трезвым взглядом на чудо-прогу, я счел ее слишком кривой и переписал. Дело в том, что когда имел место вышеописанный мною галюн, я поступал так:
1) в обработчике таймера (если установлен флаг) вызывал процедуру перерисовки;
2) в этой процедуре экран перерисовывался в буфере (TBitmap) и только потом выводился на канву формы.
(Самому плохо что-то стало от такого... :))
Потом я прозрел и в обработчике таймера вставил процедуру Invalidate, а всю перерисовку сунул в OnPaint (используя DoubleBuffered = true). Ну и злополучная мышинная аномалия исчезла... Все...

Так что спасибо всем за внимание. Вопрос, я думаю, исчерпан. :-) (дело было в кривости моих рук :))



Страницы: 1 вся ветка

Текущий архив: 2005.02.20;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.494 c
1-1107707859
VasRog
2005-02-06 19:37
2005.02.20
Dec to Bin


4-1104159113
n0name
2004-12-27 17:51
2005.02.20
Драйвер и обычный exe - в чём различия.


1-1107768634
Игорь нтк
2005-02-07 12:30
2005.02.20
Выделенная область


4-1105102145
Lucifer
2005-01-07 15:49
2005.02.20
Горячие клавиши


1-1107773373
__oleg
2005-02-07 13:49
2005.02.20
В DLL не работает процедура со строковыми параметрами