Delphi Graphics32 relative mouse position (to the layer)

前端 未结 2 476
清歌不尽
清歌不尽 2021-01-14 23:09

I have a ImgView32, that is anchored to all form margins. The form is maximized.

The bitmap of ImgView is not fixed (it can be of different sizes)

I am tryin

相关标签:
2条回答
  • 2021-01-14 23:41

    Error one

    In LayerMouseMove() you subtract OffsX and OffsY from FStartPoint in BL.Bitmap.Canvas.MoveTo(). FStartPoint was already adjusted in LayerMouseDown(). I told you to "In the three Mouse procs adjust the X and Y arguments only to become X-OffsX and Y-OffsY." Note arguments only Here's LayerMouseMove() corrected:

    procedure TForm5.LayerMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
      if FDrawingLine then
      begin
        SwapBuffers32;
          BL.Bitmap.Canvas.Pen.Color := pencolor;
    //      BL.Bitmap.Canvas.MoveTo(FStartPoint.X-OffsX, FStartPoint.Y-OffsY);
          BL.Bitmap.Canvas.MoveTo(FStartPoint.X, FStartPoint.Y);
          BL.Bitmap.Canvas.LineTo(X-OffsX, Y-OffsY);
      end;
    end;
    

    Error two

    I also told you to add if FDrawingLine then ... condition to LayerMouseUp() to avoid spurious line when the mouse down happens outside of the layer, but mouse up occurs inside. The corrected LayerMouseUp():

    procedure TForm5.LayerMouseUp(Sender: TObject; Buttons: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      if FDrawingLine then
      begin
        FDrawingLine := false;
        FEndPoint := Point(X-OffsX, Y-OffsY);
        AddLineToLayer;
        SwapBuffers32;
      end;
    end;
    

    Error three

    The posted code does not perform as your first image shows. The image looks like you would have outcommented the line BL.Location := ... in ImgViewResize(). Possibly you did this because of Error one. Anyway, with ImgViewResize as follows and the other corrections above I get the result as shown in the picture that follows.

    procedure TForm5.ImgViewResize(Sender: TObject);
    begin
      // centering the drawing area
      OffsX := (ImgView.ClientWidth - imwidth) div 2;
      OffsY := (ImgView.ClientHeight - imheight) div 2;
      BL.Location := GR32.FloatRect(OffsX, OffsY, imwidth+OffsX, imheight+OffsY);
    end;
    

    Variables imwidth and imheight defines the size of the drawing area. If you change these you need to recalculate OffsX and OffsY and you need to resize the backbuffer bm32 as well.

    enter image description here

    The lines in the corners indicate the extent of the drawing area (defined by imwidth and imheight) in the middle of the window. It stays the same also when the window is maximized.

    0 讨论(0)
  • 2021-01-14 23:44

    Ok, I solved it. Here is the final (relevant) code:

    procedure TForm5.ImgViewResize(Sender: TObject);
    begin
      OffsX := (ImgView.ClientWidth - imwidth) div 2;
      OffsY := (ImgView.ClientHeight - imheight) div 2;
      BL.Location := GR32.FloatRect(OffsX, OffsY, imwidth+OffsX, imheight+OffsY);
    end;
    
    procedure TForm5.SwapBuffers32;
    begin
        TransparentBlt(
          BL.Bitmap.Canvas.Handle, 0, 0, BL.Bitmap.Width, BL.Bitmap.Height,
          bm32.Canvas.Handle, 0, 0, bm32.Width, bm32.Height, clWhite);
    end;
    
    
    procedure TForm5.LayerMouseDown(Sender: TObject; Buttons: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      FStartPoint := Point(X-OffsX, Y-OffsY);
      FDrawingLine := true;
    end;
    
    procedure TForm5.LayerMouseMove(Sender: TObject; Shift: TShiftState; X,  Y: Integer);
    begin
      if FDrawingLine then
      begin
        SwapBuffers32;
          BL.Bitmap.Canvas.Pen.Color := pencolor;
          BL.Bitmap.Canvas.MoveTo(FStartPoint.X, FStartPoint.Y);
          BL.Bitmap.Canvas.LineTo(X-OffsX, Y-OffsY);
      end;
    end;
    
    
    procedure TForm5.LayerMouseUp(Sender: TObject; Buttons: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
      FDrawingLine := false;
      FEndPoint := Point(X-OffsX, Y-OffsY);
      AddLineToLayer;
      SwapBuffers32;
    end;
    
    procedure TForm5.LayerOnPaint(Sender: TObject; Buffer: TBitmap32);
    begin
      SwapBuffers32;
    end;
    
    procedure TForm5.AddLineToLayer;
    begin
      bm32.Canvas.Pen.Color := pencolor;
      bm32.Canvas.Pen.Width := penwidth;
      bm32.Canvas.MoveTo(FStartPoint.X, FStartPoint.Y);
      bm32.Canvas.LineTo(FEndPoint.X, FEndPoint.Y);
    end;
    

    With this code, everything works as expected. The drawing of lines can only happen within the boundaries

    Thank you

    0 讨论(0)
提交回复
热议问题