親ウィンドウがないと表示されてしまう自作コンポーネント

解決


ペンネーム  2005-12-03 02:42:38  No: 18998

コンポーネントを自作したところ「親ウィンドウがないです」といわれました。言われても意味がわからないのですが?


どやさ  2005-12-03 03:09:44  No: 18999

>親ウィンドウがないです
どのようなコンポーネントですか?
これだけの内容で質問されても的確な返答ができません。
まともに返答するとなれば
「ウィンドウを作ってください」が返答になりますね。


ペンネーム  2005-12-03 03:40:43  No: 19000

ごめんなさい。
フラットなボタンを作っているだけなのです。下のコードをくっつけて
再構築後フォームに貼り付けると  コントロールは"親ウィンドウを持っていません
といわれてしまうのです。

constructor creat(AOwner:Tcomponent)
  canvas.Font:=font;
  caprect:=rect(0,0,self.Height,self.Width);
  canvas.TextRect(caprect,0,0,caption);


ペンネーム  2005-12-03 03:40:43  No: 19001

ごめんなさい。
フラットなボタンを作っているだけなのです。下のコードをくっつけて
再構築後フォームに貼り付けると  コントロールは"親ウィンドウを持っていません
といわれてしまうのです。

constructor creat(AOwner:Tcomponent)
  canvas.Font:=font;
  caprect:=rect(0,0,self.Height,self.Width);
  canvas.TextRect(caprect,0,0,caption);


noname01  2005-12-03 04:22:52  No: 19002

constructor TYourCompo(AOwner);
begin
    inherited Create(AOwner);
の一行を先頭に追加してみるとか


ペンネーム  2005-12-03 20:02:49  No: 19003

noname01さんありがとうございます。
結果から言うと無理でした。キャンバスを使って描画しようとすると例のエラーが出るみたいなのですが、描画する際に準備しておくことってあるのでしょうか?


にしの  2005-12-03 23:36:21  No: 19004

constructor Createの中では、まだハンドルが用意されていませんよ。
WM_PAINTメッセージや、Paintメソッドで描画すべきです。


べたなやりかた  2005-12-05 00:32:08  No: 19005

解決してないが、ここの最後のコメントでわたしゃうまくいったよー
https://www.petitmonte.com/bbs/answers?question_id=303


ペンネーム  2005-12-05 02:23:38  No: 19006

にしの様。べたなやりかた様。
ありがとうございます。
リンク先参照しました。
>つまり、初めてのPaint呼び出し後には、親ウィンドウができていると言うことでしょうか?

これはマジかも。
ペイントメソッドでcanvasによる描画処理を書いても何もエラーが出ません。ただ、解決を押せないのはまだ、はっきりとしないからで…。(みなさんの意見を聞きたいです、はい。駄目なら押します)

自分としてはTcanvasでcaptionを描画したいだけなのですが、constructor  で描画しようとすると即エラーですね。
推測ですが、
ペイントメソッドで描画準備がされていて、constructorの時点では描画準備がないのでしょうか?
ヘルプでTcanvasの項を見ると、Canvasを使うには、描画領域の確保が必要だといわんばかりの表現でぷんぷんしているようにさえ思います。馬鹿なこといってたらごめんなさい。

別口ですが、
キャプションを表示する際にwin32でもできるらしいのですが、今更という気がしなくもありません。もちろん、開発環境はFrameWorkでないので十分なのですが、WindowsのVersionUpがとっても不安なのでできればdelphiのメソッドでcaptionを描画したいのです。

最後ですが、下のペンネーム様と名前がかぶってごめんなさい。わざとではないのですが、別人で御座います。


Mr.XRAY  URL  2005-12-05 02:55:16  No: 19007

提示されているコードだけでは,適切なコメントはできませんが,
一般にコンポーネント(コントロール)にはParent(親)が必要です.
たとえば以下のコードでは,(*)のコードがないとAButtonは表示されません.

procedure TForm1.Button1Click(Sender: TObject);
var
    AButton: TButton;
begin
     AButton:=TButton.Create(Self);
     AButton.Parent:=Self;  //(*)ここがないと表示しない
     AButton.Show;
end;

コンポのconstructor ではParentはまだできて(設定されて)いません.
(上のコードでも明らかで,Createの後でParentを設定していますよね)

Parentは,SetParentメソッドで設定されます.したがって,SetParentを
overrideして,Parent<>nil の場合(SetParentはコンポの破棄の時も含めて
複数回呼ばれ,nilの時もあります)にCanvasをもつものであれば,Canvasに
描画できます.

ただし,具体的な情報が不足していますので,WM_PAINTメッセージや、Paint
メソッドで描画すべきかは,判断できません.

>最後ですが、下のペンネーム様と名前がかぶってごめんなさい。
このようなことを避けるためには,ステハンは使用しないことです.
「ペンネーム」はどう考えてもステハンでしょうね.


Mr.XRAY  URL  2005-12-05 08:31:51  No: 19008

>つまり、初めてのPaint呼び出し後には、親ウィンドウができていると言うことでしょうか?

コンポーネント内部では以下の順となります(このスレッド関係のものでは)

  Create
  SetParent
  Paint

つまり,Paintメソッドが呼ばれる前にParent(親)が生成されます.
ここでCanvasが使用可能となります(そのようなコンポーネントであれば).


Mr.XRAY  URL  2005-12-05 08:35:31  No: 19009

>つまり,Paintメソッドが呼ばれる前にParent(親)が生成されます.

「生成」ではなく「設定」ですね.


Mr.XRAY  URL  2005-12-06 06:17:54  No: 19010

SetParentメソッドを使用しない場合は,にしのさんのレスと同じ回答になりますね.


ペンネーム  2005-12-06 23:59:46  No: 19011

ありがとうございます.
どうもCanvasをPublishで再宣言すると駄目な気がしてならないのです.
何にしても親クラスは
CustomControlからCustomImageにしました.あんまりよろしくない方法ですが・・・.

ステハンを使うのは対ひきこもり策です.どうもハンドルを変えて嫌味を言う人がここにもいるようなので.


Mr.XRAY  URL  2005-12-07 01:36:28  No: 19012

コンポーネントは,以下のようにあるクラスから派生して作成します.

TMYEdit = class(TCustomEdit)
end;

このとき派生元(上のコードではTCustomEdit)にCanvasプロパティがあれば
再宣言は必要ありません.またCanvasのないクラスから作成する場合,
FCanvas : TCanvas
としただけではCanvasは使用できません.

「ペンネーム 2005/12/02(金) 18:40:43」さんの場合,既にレスしたように,
上記のような,具体的な情報が不足しているので,具体的なアドバイスが
できません.

また,にしのさんも私も,Paintメソッドの使用をレスしているのであって,
Canvasの再宣言については一言も述べていません.
(もっともCanvasの再宣言をどうしたかも書いてないので... 何とも...)


Mr.XRAY  URL  2005-12-07 01:47:51  No: 19013

おっ,すぐ上にTCustomControlと書いてありますね.
ようやっと,こういうのは最初の質問の時に書くものです.
当然,DelphiのバージョンやWindowsのバージョンも(まさかwin3.1ということ
はないと思いますが)

TCustomControlにはCanvasプロパティも,Paintメソッドもあります.
VCLのTCustomControl(Controls.pas)の中を見てください.


hikikomori  2005-12-07 02:32:14  No: 19014

> ステハンを使うのは対ひきこもり策です.どうもハンドルを変えて嫌味を言う人がここにもいるようなので.

ひきこもり = 嫌味を言う人

は偏見ではないでしょうか。実際にひきこもっている人いたら失礼ですね。

それから、ステハンを使うことがなぜ対ひきこもり策なのか説明してください。


ペンネーム  2005-12-07 08:37:33  No: 19015

Mr.Xray様
すいません、どうも、開発環境とネット環境が違うPCなので…。なかなかデータを持ってこれんのです。
とはいうもののコードなんてあれぐらいで、あとは再宣言やら、だけなので。
Canvasは確かに再宣言しました。ただ、描画スペースについてよくわからないのです。
言い忘れてしまいましたが、ちゃんとPaintメソッドでやっても無理でした。
もちろんエラーメッセージは変わりましたが。描画できません…?だったかな?
そんなまともな日本語が表示されるときはマシなほうで、いつもはエラー番号とアドレスが表示されて手がつけられん状態でした。
とにかくCanvasを使おうとするとエラーの繰り返しで、親クラスは変えました。
というわけで、解決?したといえばしましたが・・・、どうもこのまま終わるのは今まで意見をくだすったかたに申し訳無いので、意見を参考にしながら、
TcustomControlでCanvasを使えるコンポーネントを作ろうと思っています。

最近気づいたのですが、エラーとして、構文チェックすると、パッケージにエラーが出て、「このコンポーネントは定義済みです」といわれるのです。
ここに何か原因があるのですかね…。

Delphi6.0
WIndowsXP
です。

新しく質問した方がいいのでしょうか?あんまり質問数増やしても管理人さんに申し訳無いですしね…。

>ステハンを使うことがなぜ対ひきこもり策なのか説明してください。
人のケアレスミスに対して結構な口ぶりを見せる人がいるので、こちらもいくらハンドルとは言え普段使ってるものは使えにくいからですかね。
とにかく語感としては
ネットで(のみ)嫌味を言う人、又は横柄な口の聞き方をする人=>ひきこもり=社会性がまるでない
といった感じでしょうかね。
具体的な例を挙げるとするなら、相手が中学生だと知った上で、お礼の言い方が気に食わないだかなんだか知らないけれど、わざわざハンドルを変えて、一言いった人も見受けましたしね。
まぁ、そういうハンドルを使っても堂々とできない人がいる以上、ステハンで気軽に質問できたら、と思っているわけです。


ペンネーム2  2005-12-07 08:54:08  No: 19016

> 横柄な口の聞き方をする人=>ひきこもり=社会性がまるでない

ご自分のことを言ってるように見えますが。

「ひきこもり」には、それなりの理由があります。
横柄な口のきき方とは何の関係もないです。偏見は是非解消してください。


Mr.XRAY  URL  2005-12-07 10:24:27  No: 19017

>「このコンポーネントは定義済みです」

内容の変更によっては現れます.前のコンポを削除してください.

>とはいうもののコードなんてあれぐらいで、

そんなわけありません.あのコードをUnitに貼り付けてインストールでき
ません!! 最低限のコードがない限りアドバイトは不可能ですよ.
神様なら別かもしれませんが.逆の立場になって考えてみましょう.
例を示します.この例のようなコードがないとどうにもなりません.
よく検討してください.
くどいようですが,簡単なコードを作成して,提示することです.そうしな
いと,誰もアドバイスはできませんよ.

unit MyTestButton;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls;

type
  TMyTestButton = class(TCustomControl)
  private
    procedure CMTextchanged(var Message: TMessage); message CM_TEXTCHANGED;
  protected
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property Caption;
    property Color;
    property Font;
    property Visible;
    property OnClick;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TMyTestButton]);
end;

//  constructor
constructor TMyTestButton.Create(AOwner: TComponent);
begin
     inherited;
     Width   := 85;
     Height  := 36;
     TabStop := True;
end;

// Paintメソッド
procedure TMyTestButton.Paint;
var
      R: TRect;
begin
     inherited;
     Canvas.Font := Font;

     Canvas.Brush.Color:=Color;
     Canvas.FillRect(ClientRect);

     R:=ClientRect;
     Canvas.Brush.Style := bsClear;
     Canvas.Font.Color  := clBlack;
     DrawText(Canvas.Handle, PChar('Delphi'),-1,R,DT_CENTER or DT_SINGLELINE);
end;

// Captionが変化したら再描画
procedure TMyTestButton.CMTextchanged(var Message: TMessage);
begin
     inherited;
     Invalidate;
end;

end.


ペンネーム  2005-12-09 04:08:13  No: 19018

Mr.XRAY様、どやさ様、にしの様、べたなやりかた様、noname01様ありがとうございました。
これからは、ソースコードを掲示することにします。
理解はできました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加