小编lyb*_*rko的帖子

如何精确测量字符的宽度?

也许我错了,但是...我想模拟字符间距.我将单词(文本)分成单个字符列表,测量它们的宽度,然后在位图上一个接一个地绘制它们.我想,渲染文本的整体宽度将与整个未分割字符串的宽度相同,但有一些错误.在循环中渲染字符显示更广泛的结果.有没有办法获得共同(预期)的结果?

这是一段代码:

private struct CharWidths
{
    public char Char;
    public float Width;
}

private List<CharWidths> CharacterWidths = new List<CharWidths>();
Run Code Online (Sandbox Code Playgroud)

...

private void GetCharacterWidths(string Text, Bitmap BMP)
{
    int i;
    int l = Text.Length;
    CharacterWidths.Clear();
    Graphics g = Graphics.FromImage(BMP);

    CharWidths cw = new CharWidths();
    for (i = 0; i < l; i++)
    {
        Size textSize = TextRenderer.MeasureText(Text[i].ToString(), Font);
        cw.Char = Text[i];
        cw.Width = textSize.Width;
        CharacterWidths.Add(cw);
    }
}
Run Code Online (Sandbox Code Playgroud)

...

public void RenderToBitmap(Bitmap BMP)
{
    //MessageBox.Show("color");

    Graphics g = Graphics.FromImage(BMP);
    GetCharacterWidths("Lyborko", BMP);

    int …
Run Code Online (Sandbox Code Playgroud)

.net c# character width

5
推荐指数
1
解决办法
4411
查看次数

将Canvas添加到TScrollBox

我想做一件简单的事情:在TScrollBox后代上添加一个Canvas属性.我读过这篇文章

但我的ScrollBox后代根本不在画布上绘制.愿有人告诉我,有什么不对吗?

  TfrmScrollContainer = class (TScrollBox)
  private
    FCanvas: TCanvas; 
    FControlState:TControlState;
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
  protected
    procedure Paint;
    procedure PaintWindow(DC: HDC); override;
    property Canvas: TCanvas read FCanvas;
  public
    constructor Create(AOwner: TComponent);  override;
    destructor Destroy; override;
  end;
Run Code Online (Sandbox Code Playgroud)

...这是精确的副本,TWincontrol如何转向TCustomControl(但它在某处失败)

constructor TfrmScrollContainer.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FCanvas := TControlCanvas.Create;
  TControlCanvas(FCanvas).Control := Self;
end;

destructor TfrmScrollContainer.Destroy;
begin
  FCanvas.Free;
  inherited Destroy;
end;

procedure TfrmScrollContainer.WMPaint(var Message: TWMPaint);
begin
  Include(FControlState, csCustomPaint);
  inherited;
  Exclude(FControlState, csCustomPaint);
end;

procedure TfrmScrollContainer.PaintWindow(DC: HDC);
begin
  FCanvas.Lock;
  try
    FCanvas.Handle := DC;
    try …
Run Code Online (Sandbox Code Playgroud)

delphi

5
推荐指数
1
解决办法
1794
查看次数

如何从提供类名的字符串创建实例?

最近我发现了一段代码,它从一个字符串创建一个TButton实例:'TButton'被用作参数.

请参阅"有没有办法在Delphi中按名称实例化一个类?"

我试图将任何对象的已发布属性保存到XML文件(工作正常),最近我想从XML文件中重新创建这些对象.在这个文件中编写了应该创建哪个类(例如TButton),然后是一个属性列表,这些属性应该加载到这个运行时创建的对象中.

上面的示例显示了如何执行此操作的方法,但它不适用于我自己的类.见下面的代码:

  TTripple=class (TPersistent)
    FFont:TFont;
  public
    constructor Create;
    Destructor Destroy;override;
  published
    property Font:TFont read FFont write  FFont;
  end;
var
  Form1: TForm1;


implementation

{$R *.dfm}

constructor TTripple.Create;
  begin
  inherited;
  FFont:=TFont.Create;
  end;


destructor TTripple.Destroy;
  begin
  FFont.Free;
  inherited;
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
RegisterClasses([TButton, TForm, TTripple]);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  CRef : TPersistentClass;
  APer : TPersistent;
begin
 // CRef := GetClass('TButton');
  CRef := GetClass('TTripple');
  if CRef<>nil then
  begin
     APer := TPersistent(TPersistentClass(CRef).Create);
     ShowMessage(APer.ClassName);  // shows TTripple, what is correct
     if …
Run Code Online (Sandbox Code Playgroud)

delphi

4
推荐指数
2
解决办法
2742
查看次数

如何将枚举类型转换为stringlist?

这一行代码:

ShowMessage(GetEnumName(TypeInfo(TAlign), 1));
Run Code Online (Sandbox Code Playgroud)

返回"alTop".

当我想使用字符串变量:'TAlign'而不是TAlign时,如何将枚举类型的所有值都放入stringlist?就像是:

ShowMessage(GetEnumName(TypeInfo('TAlign'), 1));
Run Code Online (Sandbox Code Playgroud)

感谢名单

delphi

4
推荐指数
1
解决办法
3622
查看次数

TCanvas上的"添加"文本渲染?

令我惊讶的是,我发现在TCanvas上重复渲染文本在某种程度上是"附加的".我意识到设置Canvas.Brush.Style:=bsClear是问题的原因,但我确实需要透明地重复呈现文本(即在OnPaint事件中).执行此操作后,文本看起来不太好.

我怎么能避免这种情况?

这是一些示例代码; 如果你在被调用的TButton上点击几下,就可以看到效果btn1.

procedure TForm1.btn1Click(Sender: TObject);
begin
Form1.Canvas.Brush.Style:=bsClear; //if you omit this, everything is OK.
Form1.Canvas.Font.Color:=clRed;
Form1.Canvas.Font.Name:='Times new Roman';
Form1.Canvas.Font.Style:=[fsBold];
Form1.Canvas.Font.Size:=12;
Form1.Canvas.TextOut(50,50,'www.stackoverflow.com');
end;
Run Code Online (Sandbox Code Playgroud)

delphi

4
推荐指数
1
解决办法
717
查看次数

提供对象作为函数结果是否安全?

在这里,我提供简单的代码.

function GetStringList:TStringList;
var i:integer;
begin
   Result:=TStringList.Create;
   Result.Add('Adam');
   Result.Add('Eva');
   Result.Add('Kain');
   Result.Add('Abel');
end;


procedure ProvideStringList(SL:TStringList);
var i:integer;
    Names:TStringList;
begin
   Names:=TStringList.Create;
   Names.Add('Adam');
   Names.Add('Eva');
   Names.Add('Kain');
   Names.Add('Abel');
   SL.Assign(Names);
   Names.Free;
end;


procedure TForm1.btn1Click(Sender: TObject);
var SL:TStringList;
    i:integer;
begin
   SL:=TStringList.Create;
   SL.Assign(GetStringList);
   for i:=0 to 3 do ShowMessage(SL[i]);
   SL.Free;
end;


procedure TForm1.btn2Click(Sender: TObject);
var SL:TStringList;
    i:integer;
begin
   SL:=TStringList.Create;
   ProvideStringList(SL);
   for i:=0 to 3 do ShowMessage(SL[i]);
   SL.Free;
end;
Run Code Online (Sandbox Code Playgroud)

现在的问题是:函数GetStringList中的结果对象会发生什么:Tstringlist,它被创建,但从未被释放?(我调用2次C​​reate并且只有1次Free)是按照函数提供对象的内存安全吗?还是我应该使用过程来执行此任务,其中只是处理对象创建和销毁(过程ProvideStringlist)?我叫2次创建和2次免费.还是有其他解决方案吗?

Thanx提前

Lyborko

delphi

3
推荐指数
2
解决办法
477
查看次数

WinXP和Vista的兼容性

我开发了一个使用第三方组件的应用程序(在D7,WinXP上开发).当我在XP上部署这个应用程序时,一切正常.当我在Vista上运行它时,应用程序停止正常工作:

  • 当我打开/关闭可见性时,工具栏上的工具按钮的大小不一致,这就是为什么(第三方)皮肤没有正确嵌套然后看起来很难看.它很烦人,这很烦人,但下一点并不致命.

  • 第三方文本处理组件停止写入.我写了一些例程,允许在某些情况下写这个组件.发现,我无法写任何东西(可能这些例程在写作时返回false,但我没有看到任何理由,为什么在XP上应该可以正常工作,但在Vista上没有),这是一个很大的冲击.

该应用程序运行(最后),但不是在路上,就像它应该!!!!

我想调试它,但是怎么样?

  • 我应该在这台有问题的Vista计算机上安装Delphi 7并在其上编译项目吗?(就是这样,我要做的......)
  • 是第三方组件的问题吗?
  • 是否有可能使用一些编译器指令来确保该应用程序将在Vista上运行完美?(说实话,我不知道Vista是否要声称一般).
  • Delphi 7对Vista来说太旧了吗?

注意:当我在Win98上运行相同的应用程序时,我收到有关无效浮点运算的错误消息...

有人解决了这个问题吗?

谢谢

delphi delphi-7

3
推荐指数
1
解决办法
454
查看次数

在设计时访问子组件属性

我正在尝试创建复合组件TTreePage(后代形式TCustomControl).它应该包含3个子组件:Treeview(TTreeview)align:= alLeft,Splitter(TSplitter)align:= alLeft和Container(TPanel)align:= alClient.

这是contstructor:

constructor TTreePage.Create(AOwner: TComponent);
begin
  inherited;
  FTreeview := TTreeView.Create(self);
  FTreeview.SetSubComponent(True);
  InsertControl(FTreeview);
  FSplitter := TSplitter.Create(self);
  FSplitter.SetSubComponent(True);
  FSplitter.Width := 3;
  FSplitter.Color := clBlack;
  InsertControl(FSplitter);
  FContainer:= TPanel.Create(Self);
  FContainer.SetSubComponent(True);
  FContainer.BevelInner := bvNone;
  FContainer.BevelOuter := bvNone;
  FContainer.Color := clYellow;
  InsertControl(FContainer);
  RefreshLayout;  // this performs alignment of subcomponents
end;
Run Code Online (Sandbox Code Playgroud)

这里是创建参数程序:

procedure TTreePage.CreateParams(var Params:TCreateParams);
begin
  inherited;
  Params.Style := Params.Style + WS_EX_CONTROLPARENT;
  ControlStyle := ControlStyle + [csAcceptsControls, csCaptureMouse, csOpaque];
end;
Run Code Online (Sandbox Code Playgroud)

整个组件表现为单个块.我无法通过鼠标选择任何子组件(TTreeview,TSplitter或TPanel).是的,我可以在Object Inspector中编辑它们的属性,但是我无法编辑例如TTreeview的宽度或拖动TSplitter.对我来说最重要的是在设计时在TTreeview中添加节点,但我不能为它唤起树节点编辑器.

我该怎么办?

感谢名单

delphi vcl

3
推荐指数
1
解决办法
845
查看次数

访问受保护的TWinControl事件

想象一下,您想要分配自己的事件过程:

procedure TSuperObject.DoSomething(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
ShowMessage('Yes, I am doing');
end;
Run Code Online (Sandbox Code Playgroud)

到表单上的任何TWinControl.通常,如果表单上有Panel1(TPanel),您可以轻松完成:

Panel1.OnMouseDown:=SuperObject1.DoSomething;
Run Code Online (Sandbox Code Playgroud)

但如果你想普遍这样做,怎么能实现呢?您无法访问TWincontrol的受保护成员,因此直观答案:

AnyWinControl.OnMouseDown:=SuperObject1.DoSomething;
Run Code Online (Sandbox Code Playgroud)

根本行不通.

可以通过RTTI完成吗?怎么样?

感谢名单

delphi rtti

3
推荐指数
1
解决办法
935
查看次数

如何调用给定实例的构造函数?

我的第一个对象是TGoodFairy(TObject),它有自己的孩子FChildren(TList).有Assign程序,制作任何TGoodFairy及其子女的副本.

第二个对象是TBadFairyTGoodFairy的后代.

我正在努力如何使用TBadFairy的Assign方法来创建TBadFairy孩子.我想将ClassType与Create结合使用,以便为TBadFairy创建合适的子项(现在只创建TGoodFairy子项)

  TGoodFairy = class (TObject)
  private
    FChildren:TList;
    FName:string;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Assign(Source:TGoodFairy);
  published
    property Name:string read FName write FName;
  end;

  TBadFairy = class (TGoodFairy)
    procedure Assign(Source:TBadFairy);
  end;

------------------------

constructor TGoodFairy.Create;
begin
inherited;
FChildren:=TList.Create;
end;

destructor TGoodFairy.Destroy;
var i:integer;
begin
for i:=0 to FChildren.Count-1 do TGoodFairy(FChildren[i]).Free;
FChildren.Clear;
FChildren.Free;
inherited;
end;

procedure TGoodFairy.Assign(Source:TGoodFairy);
var i:integer;
    f:TGoodFairy;
    C:TClass;
begin
    FName:=Source.Name;
    for i:=0 to Source.FChildren.Count-1 do
    begin
    //C := Source.ClassType; …
Run Code Online (Sandbox Code Playgroud)

delphi

3
推荐指数
1
解决办法
247
查看次数

标签 统计

delphi ×9

.net ×1

c# ×1

character ×1

delphi-7 ×1

rtti ×1

vcl ×1

width ×1