How to determine the size of the canvas, knowing only his pen?

I would like to know the width and height of the canvas, but I only know its HDC.

I tried with this code:

procedure TForm92.Button1Click(Sender: TObject); var hBitmap: HGDIOBJ; Header: TBitmapInfoHeader; begin hBitmap := GetCurrentObject(PaintBox1.Canvas.Handle, OBJ_BITMAP); GetObject(hBitmap, sizeof(TBitmapInfoHeader), @Header); ShowMessage(IntToStr(Header.biWidth)); end; 

However, it does not return the dimensions of the PaintBox1 Canvas to me; instead, I get the dimensions of the form on which PaintBox1 is placed.

What am I doing wrong?

+4
source share
2 answers

Given only the device context descriptor, it is generally not possible to determine the dimensions of the associated TCanvas object. The descendants of TGraphicControl all share the DC of their parent control, because only window controls can have device contexts, and TGraphicControl objects TGraphicControl not window controls.

When a TGraphicControl child (including TPaintBox ) needs a canvas, TControlCanvas calls on the GetDeviceContext control GetDeviceContext . This method returns the DC handle of the parent control, but before returning it changes the DC a bit:

 Result := Parent.GetDeviceContext(WindowHandle); SetViewportOrgEx(Result, Left, Top, nil); IntersectClipRect(Result, 0, 0, Width, Height); 

That is, it shifts the origin in accordance with the upper left corner of the current control and updates the clipping region to exclude anything outside the borders of the current control.

In some cases, you can determine the size of the canvas by checking the DC clipping region ( GetClipRgn ), but this is only if the region has not been configured in other ways. The clipping region may be smaller than the control dimensions. (It will never be again due to the IntersectClipRect call shown above.)

As you can see, you need more than just a DC knob to get the information you need. Ideally, this would include a TControl link; then you can simply read its Height and Width properties to find out the dimensions of the control and the canvas.

+3
source

The TCanvas handle points to a Windows device context (DC). Assuming a display device context (and not a printer, memory, or DC information), then the logical size of this DC current is equal to the (total) screen resolution available by GetDeviceCaps or GetSystemMetrics . (Although you can draw outside of these sizes, the output will be shortened).

The maximum visible portion of the display device context is limited by the associated window size that WindowFromDC and GetClientRect can obtain.

The current visible part can be limited by either the current framework (for example, TPaintBox from Delphi VCL, which does not have a window handle, but instead depends on the structure for converting the sizes to the size of the control in the parent DC, which can be obtained by checking the control sizes) or the current The clipping environment that GetClipRgn can get.

+1
source

Source: https://habr.com/ru/post/1500781/


All Articles