2

新しい種類の境界線(丸みを帯びた角)を使用して、TEdit、TDBEdit、TComboBoxなどのカスタムコンポーネントのセットを作成しようとしています。次のコードを作成しました。

unit RoundRectControls;

interface

uses
  SysUtils, Classes, Controls, StdCtrls, Windows, Messages, Forms;

type
  TRoundRectEdit = class(TEdit)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    constructor Create(AOwner: TComponent); override;
    { Public declarations }
  published
    property BorderStyle default bsNone;
    property Ctl3D default False;
    { Published declarations }
  end;

procedure Register;
procedure DrawRoundedRect(Control: TWinControl);

implementation

constructor TRoundRectEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  DrawRoundedRect(Self);
end;

procedure Register;
begin
  RegisterComponents('Eduardo', [TRoundRectEdit]);
end;

procedure DrawRoundedRect(Control: TWinControl);
var
   r: TRect;
   Rgn: HRGN;
begin
   with Control do
   begin
     r := ClientRect;
     rgn := CreateRoundRectRgn(r.Left, r.Top, r.Right, r.Bottom, 30, 30) ;
     Perform(EM_GETRECT, 0, lParam(@r)) ;
     InflateRect(r, - 4, - 4) ;
     Perform(EM_SETRECTNP, 0, lParam(@r)) ;
     SetWindowRgn(Handle, rgn, True) ;
     Invalidate;
   end;
end;

end.

しかし、コンポーネントをフォームに入れようとした後、次のメッセージが表示されました。

コントロール''には親がありません

だから、どうすればそれを修正できますか?私はコンポーネントを構築するのが初めてで、Web上で優れたチュートリアルが必要です。DrawRoundedRectコンストラクターの外でそれを作成する必要があると何かが教えてくれます...しかし、どこで?

編集1-2012-07-2714:50

結果

Sertac Akyuzの回答は素晴らしく、問題を解決しましたが、結果はちょっと醜いものでした。何が間違っているのかわかりません。EditBoxのテキストが左上に近すぎます。誰かが私がそれを修正する方法を知っていますか?

4

2 に答える 2

5

'ClientRect'を要求していますが、編集コントロールウィンドウがまだ作成されていません(ウィンドウも長方形もありません)。リージョン変更コードは、作成後に別の場所に移動できます。例:

type
  TRoundRectEdit = class(TEdit)
  private
    { Private declarations }
  protected
    procedure CreateWnd; override;
    { Protected declarations }
  public
    constructor Create(AOwner: TComponent); override;
    ...

constructor TRoundRectEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
//  DrawRoundedRect(Self);
end;

procedure TRoundRectEdit.CreateWnd;
begin
  inherited;
  DrawRoundedRect(Self);
end;


エラーメッセージ自体は、ハンドルが要求された後、ウィンドウを作成するためのVCLの努力を反映しています。コントロールを配置するウィンドウを解決できないため、これを行うことはできません。

于 2012-07-27T17:02:12.570 に答える
1

で新しいリージョンを作成するのはSetBounds()問題ないはずです。必ずinherited最初に呼び出してから、更新されたWidth/Heightを使用して新しいリージョンを作成してください。 CreateWnd()現在のWidth/を使用して初期領域を作成する必要がありますHeight。 がTrueSetBounds()の場合にのみ、リージョンを再作成する必要があります。HandleAllocated()

于 2012-07-27T18:28:22.580 に答える