Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2005.02.20;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "Media";
Текущий архив: 2005.02.20;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.039 c
6-1102876092
User_32
2004-12-12 21:28
2005.02.20
Локальная сеть


14-1107165684
1008
2005-01-31 13:01
2005.02.20
McSimm ©


4-1105009997
Davinchi
2005-01-06 14:13
2005.02.20
Сркытие программы из Alt+Tab и панели задач


1-1107354934
Dmitry_04
2005-02-02 17:35
2005.02.20
Перетаскивание формы за Image


1-1107800554
VZup
2005-02-07 21:22
2005.02.20
Целый тип данных с ОГРОМНЫМ диапазоном





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский