小编iam*_*osy的帖子

TComponent中的观察者属性

您好Delphi XE2 TComponent有一个新的"Observers"属性.不幸的是,这方面的帮助条目是空的.有谁知道这个新房产有什么用处以及如何使用它?编辑:我知道它与LiveBindings有关,但我想更多地了解它,因为我无法访问XE2源代码,所以我无法调查自己.

delphi delphi-xe2 livebindings

18
推荐指数
1
解决办法
2404
查看次数

Delphi XE4不可变字符串

使用适用于iOS平台的Delphi XE4,引入了一种新的字符串类型:不可变的基于零的字符串.到目前为止,Delphi在写可变字符串上有副本.所以问题是,这对我未来的编程意味着什么?一种字符串类型比另一种字符串有什么优势吗?当切换到新的字符串类型时,我需要注意哪些陷阱(除了明显的0对1基数)?

delphi delphi-xe4

16
推荐指数
1
解决办法
1787
查看次数

TParallel.For性能

鉴于以下在一维数组中查找奇数的简单任务:

begin
  odds := 0;
  Ticks := TThread.GetTickCount;
  for i := 0 to MaxArr-1 do
      if ArrXY[i] mod 2 = 0 then
        Inc(odds);
  Ticks := TThread.GetTickCount - Ticks;
  writeln('Serial: ' + Ticks.ToString + 'ms, odds: ' + odds.ToString);
end;
Run Code Online (Sandbox Code Playgroud)

看起来这将是并行处理的一个很好的候选者.因此可能会想要使用以下TParallel.For版本:

begin
  odds := 0;
  Ticks := TThread.GetTickCount;
  TParallel.For(0,  MaxArr-1, procedure(I:Integer)
  begin
    if ArrXY[i] mod 2 = 0 then
      inc(odds);
  end);
  Ticks := TThread.GetTickCount - Ticks;
  writeln('Parallel - false odds: ' + Ticks.ToString + 'ms, odds: ' + odds.ToString);
end;
Run Code Online (Sandbox Code Playgroud)

这种并行计算的结果在两个方面有点令人惊讶: …

delphi parallel-processing multithreading delphi-xe7

8
推荐指数
2
解决办法
4192
查看次数

Rtti不适用于用作类字段的泛型类型

我在使用rtti获取有关泛型类字段的信息时遇到了问题.经过一段时间的谷歌搜索后,我在QC中找到了一个描述该问题的条目.我的问题是,如果有人知道一个解决方法,或者这是否修复了Delphi XE2.以下是来自QC的重复该错误的源代码片段.

program Generics;

    {$APPTYPE CONSOLE}

    uses
       Generics.Collections, Rtti, SysUtils;

    type
       TIntList = TList<Integer>;

       TRecContainer = record
         FList: TIntList;
       end;

       TObjContainer = class
         FList: TIntList;
       end;

    var
       ctx: TRttiContext;
       f: TRttiField;

    begin
       ctx := TRttiContext.Create;
       try
         for f in ctx.GetType(TypeInfo(TRecContainer)).GetFields do
           if f.FieldType <> nil then
             writeln(f.FieldType.Name)
           else
             writeln('f.FieldType = nil');
         for f in ctx.GetType(TypeInfo(TObjContainer)).GetFields do
           if f.FieldType <> nil then
             writeln(f.FieldType.Name)
           else
             writeln('f.FieldType = nil');
       finally
         ctx.Free;
         readln;
       end;
    end.
Run Code Online (Sandbox Code Playgroud)

delphi rtti delphi-xe

7
推荐指数
1
解决办法
1381
查看次数

如何在我自己的窗口下捕获屏幕,不包括我自己的窗口

假设我想编写一个放大镜,我怎么能捕获除我自己的窗口之外的屏幕内容?我知道如何使用BitBlt和桌面DC使用我自己的窗口捕获屏幕.

并使其更清晰:我想在窗口中显示放大的内容.

编辑:似乎除了在我可以捕获窗口下的屏幕内容之前以某种方式隐藏我的窗口(或客户区域)之外没有其他解决方案.显然这会导致我的窗口闪烁,这使得这个场景变得毫无用处.

windows delphi

6
推荐指数
1
解决办法
2462
查看次数

TCustomAttribute - "预期的常量表达式"编译错误

给出以下代码段:

type
  MyIntf = interface
    ['{C6184693-663E-419F-B2DA-4DA1A0E33417}']
    procedure Foo;
  end;

  InvisiblePropInterfaces = class(TCustomAttribute)
  private
    FGUIDS: array of TGUID;
  public
    constructor Create(const GUIDS: array of TGUID);
  end;

  [InvisiblePropInterfaces([MyIntf])]  // <-- Constant expression expected error
  TMyClass = class(TInterfacedObject, MyIntf)
    procedure Foo;
  end;
Run Code Online (Sandbox Code Playgroud)

为什么编译器认为这不是一个常量表达式?但鉴于我使用像这样的InvisiblePropInterfaces,编译器很高兴?

...
var
  I: InvisiblePropInterfaces;
begin
  I:= InvisiblePropInterfaces.Create([MyIntf]);
...
Run Code Online (Sandbox Code Playgroud)

delphi delphi-xe

6
推荐指数
1
解决办法
1577
查看次数

通用方法类型推断

假设我有一个包含两个泛型方法的类:

TMyClass = class
  procedure DoWith<T: class> (obj: T);
  procedure DoFor<T: class> ( proc: TProc<T> );
end;
Run Code Online (Sandbox Code Playgroud)

现在,当我想用​​特定的类型参数调用这两个方法中的任何一个时,Delphi可以推断出该DoWith方法的类型,所以我可以用它们调用它

MyClass.DoWith <TButton> ( MyButton )
Run Code Online (Sandbox Code Playgroud)

要么

MyClass.DoWith ( MyButton )
Run Code Online (Sandbox Code Playgroud)

Delphi编译器很乐意编译它们.但是,如果我省略方法中的type参数DoFor,Delphi编译器会抱怨缺少的类型参数:

MyClass.DoFor<TButton>(procedure (Button: TButton) begin .... end);  // compiles


MyClass.DoFor(procedure (Button: TButton) begin .... end);  // doesn't compile
Run Code Online (Sandbox Code Playgroud)

现在我的问题是:这只是编译器的一个缺点,还是有任何逻辑上的原因(我还没想到)禁止编译器正确地推断出该DoFor方法的类型?

delphi generics type-inference

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

以Delphi形式绘制控件

如何在窗体画布上绘制内容并在窗体上绘制控件?

我尝试以下方法:

procedure TForm1.FormPaint(Sender: TObject);
var x,y: Integer;
begin
  x := Mouse.CursorPos.X - 10;
  y := Mouse.CursorPos.Y - 10;
  x := ScreentoClient(point(x,y)).X - 10;
  y := ScreenToClient(point(x,y)).Y - 10;
  Canvas.Brush.Color := clRed;
  Canvas.FillRect(rect(x, y, x + 10, y + 10));
  Invalidate;
end;
Run Code Online (Sandbox Code Playgroud)

在绘制其他控件之前绘制矩形,因此它隐藏在控件后面(根据Delphi Docs,这是预期的行为).

我的问题是如何绘制控件?

delphi drawing custom-draw

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

匿名方法作为函数结果

我想要做的是将一个匿名方法作为函数结果分配给相同类型的变量.德尔福抱怨说不能做出任命.显然Delphi的东西我想分配"GetListener"函数而不是相同函数的结果.非常感谢任何帮助.

type
      TPropertyChangedListener = reference to procedure (Sender: TStimulus);

      TMyClass = class
        function GetListener:TPropertyChangedListener
      end;


    ....

    var MyClass: TMyClass;
        Listener: TPropertyChangedListener;
    begin
      MyClass:= TMyClass.create;
      Listener:= MyClass.GetListener;   //  Delphi compile error: E2010 Incompatible types:  TPropertyChangedListener' and 'Procedure of object' 

    end; 
Run Code Online (Sandbox Code Playgroud)

delphi anonymous-methods delphi-2009

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

使用RTTI获取/设置子属性

鉴于下面的代码片段,使用GetPropValue(MyComponent,'MySubComponent.Prop1')引发EPropertyError异常.如何使用GetPropValue/SetPropValue检索或设置SubProperties的值?

Type
  TMySubComponent = class(TInterfacedPersitent)
  private
    FProp1: Integer;
  published
    property Prop1: integer read FProp1 write FProp1;
  end;

  TMyComponent = class(TCompoent)
  private
    FMySubComponent : TMySubcomponent; 
  published
    property MySubComponent: TMySubComponent read FMySubComponent write FMySubComponent ;
  end;
Run Code Online (Sandbox Code Playgroud)

delphi rtti delphi-xe

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

枚举常量属性不会流

给出以下类型声明:

  TMyEnum = (onehundred,twohundred,threehundred);
  TMyEnum2 = (Aonehundred = 100 , Atwohundred = 200 , Athreehundred = 300);

  TMyComponent = class(TComponent)
  private
    FMyEnum: TMyEnum;
    FMyEnum2: TMyEnum2;
  published
    property MyEnum: TMyEnum read FMyEnum write FMyEnum;
    property MyEnum2: TMyEnum2 read FMyEnum2 write FMyEnum2;
  end;
Run Code Online (Sandbox Code Playgroud)

使用TStream.WriteComponent不会传输MyEnum2.有人知道为什么会这样,如果可以解决这个问题吗?

delphi delphi-xe

2
推荐指数
1
解决办法
327
查看次数

Delphi使用自定义组件冻结Form close

我已经开发了一个组件来实现基于Graphics32的ImgView32s的平移和缩放功能.可以将组件放在TImgView32旁边,设置我的组件的Image视图属性,一切都很好,并按预期工作.但是,一旦我尝试关闭托管我的组件的表单和ImgView32,Delphi IDE就会冻结.我的第一个想法是仍然链接到我的组件的ImgView32在我的组件之前被销毁,所以我实现了Delphi标准通知机制.问题仍然存在.这是我的组件的源代码.该组件包含在运行时包中,另一个设计时包使用运行时包并注册该组件.

更新,因为Rob的有用的调试技巧:事实证明,组件挂起了对Notification方法的无休止调用.也许那是对某人的暗示.

unit MJImgView32PanZoom;

interface

uses Classes, Controls, Gr32, GR32_Image, GR32_Layers;

type
  TImgView32ScaleChangeEvent = procedure( OldScale, NewScale: Double ) of object;

  TimgView32PanZoom = class(TComponent)
  private
    FEnabled: Boolean;
    FMaxZoom: Double;
    FMinZoom: Double;
    FImgView32: TImgView32;
    FZoomStep: Double;
    FOrigImgMouseMove: TImgMouseMoveEvent;
    FOrigImgMouseDown: TImgMouseEvent;
    FOrigImgMouseUp: TImgMouseEvent;
    FOrigImgMouseWheel: TMouseWheelEvent;
    FOrigImgCursor: TCursor;
    FPanMouseButton: TMouseButton;
    FLastMouseDownPos : TFloatPoint;
    FPanCursor: TCursor;
    FOnScaleChanged: TImgView32ScaleChangeEvent;
    procedure imgMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer; Layer: TCustomLayer);
    procedure imgMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer; Layer: …
Run Code Online (Sandbox Code Playgroud)

delphi graphics32 delphi-xe

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