Показать сообщение отдельно
  #9  
Старый 10.01.2010, 00:47
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

Тот же код, с комментариями, специально для melloun...
Во первых определим в форме вспомогательные переменные,
а именно:
Код:
  ...
  private
    FStartX, FStartY:Integer; //координаты в момент события MouseDown
    FIsButtonDown:boolean;   //флаг, определяющий нажата кнопка или нет
    FBuffer:TBitMap;             //Буффер, в котором будем хранить изображение
  public
  ...
При создании формы, определим начальные значения
Код:
  ...
  //ControlStyle:=ControlStyle+[csOpaque]; //если рисовать на TPaintBox, то
    //это отключит его перерисовку, и уберет мерцания..
  //DoubleBuffered:=true;     //иногда помогает избавиться от мерцания
  FIsButtonDown:=false;      //кнопка не нажата
  FBuffer:=TBitmap.Create;  //создаем битмар
  FBuffer.Height:=Height;     //с размерами формы
  FBuffer.Width:=Width;
  ...
При нажатии кнопки мышки:
Код:
  ...
  FStartX:=X;FStartY:=Y;   //запомним координаты
  FIsButtonDown:=true;      //запомним что кнопка была нажата
    // и скопируем в буффер содержимое формы.
  BitBlt(FBuffer.Canvas.Handle,0,0,Width,Height,Canvas.Handle,0,0,SRCCOPY);
  ...
При движении курсора над формой:
Код:
 
  ...
  if (FIsButtonDown) then //проверяем, если была нажата кнопка мыши, то
    begin
      //восстанавливаем изображение на форме из буффера
    BitBlt(Canvas.Handle,0,0,Width,Height,FBuffer.Canvas.Handle,0,0,SRCCOPY);
      //если был нажат Ctrl, то рисуем прямоугольник
    if (ssCtrl in Shift) then Canvas.Rectangle(FStartX, FStartY, X, Y)
      else //иначе линию
        with Canvas do
          begin
          MoveTo(FStartX, FStartY);
          LineTo(X, Y);
          end;
    end;
  ..
При отпускании кнопки мыши:
Код:
  ...
  if (FIsButtonDown) then проверяем, если была ли нажата кнопка мышы, то
    begin
    FormMouseMove(Sender, Shift, X, Y); //вызовем событие MouseMove,
      //для того, что бы перерисовать с последними координатами
    BitBlt(FBuffer.Canvas.Handle,0,0,Width,Height,Canvas.Handle,0,0,SRCCOPY);
    FIsButtonDown:=false; //и запомним, что кнопка мыши отпущена
    end;
  ...
Ну и соответственно, при уничтожении формы, грохаем буффер,
а при изменении размеров формы, изменяем размеры буффера.

На самом деле, это не самая удачная реализация, на скорую руку, этот алгоритм можно еще очень неплохо оптимизировать, хотя для решения твоей задачи, тебе должно хватить.

Если будут вопросы, задавай...
Ответить с цитированием