コンポーネントを自作したところ「親ウィンドウがないです」といわれました。言われても意味がわからないのですが?
>親ウィンドウがないです
どのようなコンポーネントですか?
これだけの内容で質問されても的確な返答ができません。
まともに返答するとなれば
「ウィンドウを作ってください」が返答になりますね。
ごめんなさい。
フラットなボタンを作っているだけなのです。下のコードをくっつけて
再構築後フォームに貼り付けると コントロールは"親ウィンドウを持っていません
といわれてしまうのです。
constructor creat(AOwner:Tcomponent)
canvas.Font:=font;
caprect:=rect(0,0,self.Height,self.Width);
canvas.TextRect(caprect,0,0,caption);
ごめんなさい。
フラットなボタンを作っているだけなのです。下のコードをくっつけて
再構築後フォームに貼り付けると コントロールは"親ウィンドウを持っていません
といわれてしまうのです。
constructor creat(AOwner:Tcomponent)
canvas.Font:=font;
caprect:=rect(0,0,self.Height,self.Width);
canvas.TextRect(caprect,0,0,caption);
constructor TYourCompo(AOwner);
begin
inherited Create(AOwner);
の一行を先頭に追加してみるとか
noname01さんありがとうございます。
結果から言うと無理でした。キャンバスを使って描画しようとすると例のエラーが出るみたいなのですが、描画する際に準備しておくことってあるのでしょうか?
constructor Createの中では、まだハンドルが用意されていませんよ。
WM_PAINTメッセージや、Paintメソッドで描画すべきです。
解決してないが、ここの最後のコメントでわたしゃうまくいったよー
https://www.petitmonte.com/bbs/answers?question_id=303
にしの様。べたなやりかた様。
ありがとうございます。
リンク先参照しました。
>つまり、初めてのPaint呼び出し後には、親ウィンドウができていると言うことでしょうか?
これはマジかも。
ペイントメソッドでcanvasによる描画処理を書いても何もエラーが出ません。ただ、解決を押せないのはまだ、はっきりとしないからで…。(みなさんの意見を聞きたいです、はい。駄目なら押します)
自分としてはTcanvasでcaptionを描画したいだけなのですが、constructor で描画しようとすると即エラーですね。
推測ですが、
ペイントメソッドで描画準備がされていて、constructorの時点では描画準備がないのでしょうか?
ヘルプでTcanvasの項を見ると、Canvasを使うには、描画領域の確保が必要だといわんばかりの表現でぷんぷんしているようにさえ思います。馬鹿なこといってたらごめんなさい。
別口ですが、
キャプションを表示する際にwin32でもできるらしいのですが、今更という気がしなくもありません。もちろん、開発環境はFrameWorkでないので十分なのですが、WindowsのVersionUpがとっても不安なのでできればdelphiのメソッドでcaptionを描画したいのです。
最後ですが、下のペンネーム様と名前がかぶってごめんなさい。わざとではないのですが、別人で御座います。
提示されているコードだけでは,適切なコメントはできませんが,
一般にコンポーネント(コントロール)には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
メソッドで描画すべきかは,判断できません.
>最後ですが、下のペンネーム様と名前がかぶってごめんなさい。
このようなことを避けるためには,ステハンは使用しないことです.
「ペンネーム」はどう考えてもステハンでしょうね.
>つまり、初めてのPaint呼び出し後には、親ウィンドウができていると言うことでしょうか?
コンポーネント内部では以下の順となります(このスレッド関係のものでは)
Create
SetParent
Paint
つまり,Paintメソッドが呼ばれる前にParent(親)が生成されます.
ここでCanvasが使用可能となります(そのようなコンポーネントであれば).
>つまり,Paintメソッドが呼ばれる前にParent(親)が生成されます.
「生成」ではなく「設定」ですね.
SetParentメソッドを使用しない場合は,にしのさんのレスと同じ回答になりますね.
ありがとうございます.
どうもCanvasをPublishで再宣言すると駄目な気がしてならないのです.
何にしても親クラスは
CustomControlからCustomImageにしました.あんまりよろしくない方法ですが・・・.
ステハンを使うのは対ひきこもり策です.どうもハンドルを変えて嫌味を言う人がここにもいるようなので.
コンポーネントは,以下のようにあるクラスから派生して作成します.
TMYEdit = class(TCustomEdit)
end;
このとき派生元(上のコードではTCustomEdit)にCanvasプロパティがあれば
再宣言は必要ありません.またCanvasのないクラスから作成する場合,
FCanvas : TCanvas
としただけではCanvasは使用できません.
「ペンネーム 2005/12/02(金) 18:40:43」さんの場合,既にレスしたように,
上記のような,具体的な情報が不足しているので,具体的なアドバイスが
できません.
また,にしのさんも私も,Paintメソッドの使用をレスしているのであって,
Canvasの再宣言については一言も述べていません.
(もっともCanvasの再宣言をどうしたかも書いてないので... 何とも...)
おっ,すぐ上にTCustomControlと書いてありますね.
ようやっと,こういうのは最初の質問の時に書くものです.
当然,DelphiのバージョンやWindowsのバージョンも(まさかwin3.1ということ
はないと思いますが)
TCustomControlにはCanvasプロパティも,Paintメソッドもあります.
VCLのTCustomControl(Controls.pas)の中を見てください.
> ステハンを使うのは対ひきこもり策です.どうもハンドルを変えて嫌味を言う人がここにもいるようなので.
ひきこもり = 嫌味を言う人
は偏見ではないでしょうか。実際にひきこもっている人いたら失礼ですね。
それから、ステハンを使うことがなぜ対ひきこもり策なのか説明してください。
Mr.Xray様
すいません、どうも、開発環境とネット環境が違うPCなので…。なかなかデータを持ってこれんのです。
とはいうもののコードなんてあれぐらいで、あとは再宣言やら、だけなので。
Canvasは確かに再宣言しました。ただ、描画スペースについてよくわからないのです。
言い忘れてしまいましたが、ちゃんとPaintメソッドでやっても無理でした。
もちろんエラーメッセージは変わりましたが。描画できません…?だったかな?
そんなまともな日本語が表示されるときはマシなほうで、いつもはエラー番号とアドレスが表示されて手がつけられん状態でした。
とにかくCanvasを使おうとするとエラーの繰り返しで、親クラスは変えました。
というわけで、解決?したといえばしましたが・・・、どうもこのまま終わるのは今まで意見をくだすったかたに申し訳無いので、意見を参考にしながら、
TcustomControlでCanvasを使えるコンポーネントを作ろうと思っています。
最近気づいたのですが、エラーとして、構文チェックすると、パッケージにエラーが出て、「このコンポーネントは定義済みです」といわれるのです。
ここに何か原因があるのですかね…。
Delphi6.0
WIndowsXP
です。
新しく質問した方がいいのでしょうか?あんまり質問数増やしても管理人さんに申し訳無いですしね…。
>ステハンを使うことがなぜ対ひきこもり策なのか説明してください。
人のケアレスミスに対して結構な口ぶりを見せる人がいるので、こちらもいくらハンドルとは言え普段使ってるものは使えにくいからですかね。
とにかく語感としては
ネットで(のみ)嫌味を言う人、又は横柄な口の聞き方をする人=>ひきこもり=社会性がまるでない
といった感じでしょうかね。
具体的な例を挙げるとするなら、相手が中学生だと知った上で、お礼の言い方が気に食わないだかなんだか知らないけれど、わざわざハンドルを変えて、一言いった人も見受けましたしね。
まぁ、そういうハンドルを使っても堂々とできない人がいる以上、ステハンで気軽に質問できたら、と思っているわけです。
> 横柄な口の聞き方をする人=>ひきこもり=社会性がまるでない
ご自分のことを言ってるように見えますが。
「ひきこもり」には、それなりの理由があります。
横柄な口のきき方とは何の関係もないです。偏見は是非解消してください。
>「このコンポーネントは定義済みです」
内容の変更によっては現れます.前のコンポを削除してください.
>とはいうもののコードなんてあれぐらいで、
そんなわけありません.あのコードを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.
Mr.XRAY様、どやさ様、にしの様、べたなやりかた様、noname01様ありがとうございました。
これからは、ソースコードを掲示することにします。
理解はできました。
ツイート | ![]() |