我正在尝试使用MM_ANISTROPIC
缩放图像/文本等,我所做的是以下(顺便说一句,如果语法有点奇怪,它最初来自delphi,所以将以下内容视为伪代码)
我希望下面的代码可以生成一个矩形,它是PaintBox宽度的70%和高度的30%,但它没有,相反它显然太小了。
SetMapMode(hdc,MM_ANISOTROPIC);
SetWindowExtEx(hdc,100,100,0);
SetViewportExtEx(hdc,70,30,0);
Rectangle(hdc, 0,0,PaintBox.width-1,PaintBox.Height-1);
另一方面,如果我更改代码以便SetWindowExtEx
有91而不是100作为其参数(如下所示)那么它可以工作,这对我来说毫无意义...... < / p>
SetMapMode(hdc,MM_ANISOTROPIC);
SetWindowExtEx(hdc,91,91,0);
SetViewportExtEx(hdc,70,30,0);
Rectangle(hdc, 0,0,PaintBox.width-1,PaintBox.Height-1);
我的理智测试案例是添加以下伪代码
SetMapMode(hdc,MM_TEXT);
DrawLine(hdc,Round(PaintBox.width*0.7),0,Round(PaintBox.width*0.7),PaintBox.Height-1);
DrawLine(hdc,0,Round(PaintBox.height*0.3),PaintBox.width-1,Round(PaintBox.height*0.3));
我原本希望这会覆盖原始Rectangle的下边缘/下边缘,但除非我使用91,91 SetWindowExtEx,否则它不会。
任何人都可以复制这个吗?
进一步编辑:这是我之前给出伪代码的确切原始代码,以使非delphi用户更容易访问该问题,但我的一位评论者想要完整的代码,看看我的争论是否是delphi quirk是真的或不。
整个项目由一个VCL表单组成,其上面放置一个矩形的绘图框,因此周围有空格,其onPaint事件设置为下面的代码,结果为this image::
procedure TForm11.PaintBox2Paint(Sender: TObject);
var
hdc:THandle;
res:TPoint;
procedure SetupMapMode;
begin
SetMapMode(hdc,MM_ANISOTROPIC);
SetWindowExtEx(hdc,100,100,0);
SetViewportExtEx(hdc,70,30,0);
// These lines are required when we're painting to a TPaintBox but can't be used
// if we're paiting to a TPanel and they were NOT in my original question but only
// got added as part of the answer
// SetViewportOrgEx(hdc,PaintBox2.Left,PaintBox2.Top,@ZeroPoint);
// SetWindowOrgEx(hdc,0,0,@ZeroPoint);
end;
begin
//draw a rectangle to frame the Paintbox Surface
PaintBox2.Canvas.Pen.Style:=psSolid;
PaintBox2.Canvas.Pen.width:=2;
PaintBox2.Canvas.Pen.Color:=clGreen;
PaintBox2.Canvas.Brush.Style:=bsClear;
PaintBox2.Canvas.Rectangle(0,0,PaintBox2.Width-1,PaintBox2.Height-1);
PaintBox2.Canvas.Brush.Style:=bsSolid;
//initialize convenience variable
hdc:=PaintBox2.Canvas.Handle;
SetTextAlign(hdc,TA_LEFT);
//as doing things to the PaintBox2.Canvas via Delphi's interface tends to reset
//everything, I'm ensuring the map mode gets set **immediately** before
//each drawing call
SetupMapMode;
/// Draw Text at the bottom of the PaintBox2.Canvas (though as it's mapped it
/// SHOULD be 1/3 of the way down and much smaller instead)
TextOut(hdc,200,PaintBox2.Height-PaintBox2.Canvas.TextHeight('Ap'),'Hello, World!',13);
PaintBox2.Canvas.Pen.Color:=clblue;
PaintBox2.Canvas.Brush.Style:=bsClear;
//ensure it's set before doing the rectangle
SetupMapMode;
// Redraw the same rectangle as before but in the mapped mode
Rectangle(hdc, 0,0,PaintBox2.Width-1,PaintBox2.Height-1);
PaintBox2.Canvas.Brush.Style:=bsSolid;
//reset the map mode to normal
SetMapMode(hdc,MM_Text);
//draw text at the "same" position as before but unmapped...
TextOut(hdc,200,PaintBox2.Height-PaintBox2.Canvas.TextHeight('Ap'),'Goodbye, World!',15);
//Draw lines exactly at 70% of the way across and 30% of the way down
//if this works as expected they should overwrite the right and bottom
//borders of the rectangle drawn in the mapped mode
PaintBox2.Canvas.Pen.Color:=RGB(0,255,255);
PaintBox2.Canvas.MoveTo(Round(PaintBox2.Width*0.7),0);
PaintBox2.Canvas.LineTo(Round(PaintBox2.Width*0.7),PaintBox2.Height);
PaintBox2.Canvas.MoveTo(0,Round(PaintBox2.Height*0.3));
PaintBox2.Canvas.LineTo(PaintBox2.Width,Round(PaintBox2.Height*0.3));
end;
答案 0 :(得分:0)
好的,我不知道为什么以下是必要的 - 它可能是Delphi的怪癖,我使用TPaintBox的事实是TGraphicControl而不是Component,或者如果我&# 39; m错过了关于整个映射模式如何工作的一些基本概念,但是如果我添加以下代码:
ZeroPoint:=TPoint.Zero;
SetViewportOrgEx(hdc,PaintBox1.Left,PaintBox1.Top,@ZeroPoint);
SetWindowOrgEx(hdc,0,0,@ZeroPoint);
然后它按预期显示。任何人都有任何解释为什么这是必要的?
编辑:好的,我已经得到了PARTIAL的解释。它与我作为TPaintBox绘制的控件有关,它是一个TGraphic控件而不是TWinControl。即:TGraphicControl是所有轻量级控件的基类。
TGraphicControl支持简单的轻量级控件,无需接受键盘输入或包含其他控件。由于轻量级控件不包装Windows屏幕对象,因此它们比基于TWinControl的控件更快,用户更少。
因此,虽然他们看起来有一个单独的画布,但我有这种偷偷摸摸的感觉,他们真的在分享这种形式的画布,这就是为什么当我切换到TWinControl后代时,它拥有自己的Windows DC,然后显示按预期工作,而不设置ViewpointOrg。
毕竟这是德尔福的怪癖......!