問題タブ [delphi-5]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
delphi - Delphi: 開始後に設定しても、戻り値が未定義になる場合があります
ここで「戻り値...未定義の可能性があります」と表示される理由を誰かに教えてもらえますか:
delphi - DelphiでTextRect(GDI32ではExtTextOut)を使用するときに、フォントのアンチエイリアシングを無効にする方法はありますか?
Delphi(5 Enterprise)に付属の例に基づいて、カスタムゲージを使用しています。知らない人にとっては、スムーズなプログレスバーのようなものですが、コンポーネントの中央(垂直方向と水平方向)にパーセンテージまたは値が表示されます。
ゲージがいっぱいになったときと空のときの両方でテキストが読みやすくなるように、テキストは反転した色で表示されます。
フォントのアンチエイリアシングを使用すると、これらの反転した色によってフォントのエッジが非常にクレイジーな色で表示され、コンポーネントの外観が損なわれます。
この1つのコンポーネントだけでフォントスムージング/アンチエイリアシングを無効にする方法、または無効にしてテキストを描画してから再度有効にする方法はありますか?
現在の回避策は、「MS Sans Serif」のように滑らかにならないフォントを使用することですが、一貫性を保つために、他のUIと同じフォントを使用したいと思います。
delphi - 任意の形式に基づいて文字列をTDateTimeに変換する
Delphi 5で、使用する実際の形式を指定できるTDateTimeに文字列を変換する方法はありますか?
私は、さまざまなワークステーションからタスクを受け入れるジョブプロセッサに取り組んでいます。タスクにはさまざまなパラメーターがあり、そのうちのいくつかは日付ですが、(残念ながら、私の制御ではありませんが)文字列として渡されます。ジョブは異なるワークステーションから取得できるため、文字列として日付をフォーマットするために使用される実際の日時フォーマットは異なる場合があります(もちろん、実際には異なります)。
グーグルで調べてみると、私が見つけた唯一の簡単な解決策は、変数をこっそり変更し、ShortDateFormat
後で元の値に戻すことでした。ShortDateFormat
はグローバル変数であり、スレッド環境で作業しているため、これが機能する唯一の方法は、アクセスをすべて同期することです。これは完全に受け入れられません(元に戻せません)。
ライブラリコードをSysUtils
ユニットから独自のメソッドにコピーし、グローバル変数の代わりに指定された形式で動作するように調整することもできますが、見逃したより適切なものがあるかどうか疑問に思っています。
アップデート
もっと簡潔に言えば:
文字列をTDateTimeに変換するために使用する正確な形式を指定するオプションが追加された、StrToDate
(または)のようなものが必要です。StrToDateTime
delphi - Delphi:実行時に、特定の基本クラスから派生したクラスを見つけますか?
実行時に、特定の基本クラスから派生するすべてのクラスを見つける方法はありますか?
たとえば、クラスがあるふりをします。
またはクラスがあるふりをします:
またはクラスがあるふりをします:
またはクラスがあるふりをします:
実行時に、私はそれらを使って何かをすることができるように、子孫であるすべてのクラスを見つけたいと思ってTTestCase
います。
RTTIにそのような情報を問い合わせることはできますか?
あるいは: Delphiにすべてのクラスを歩く方法はありますか?その後、私は単に呼び出すことができます:
も参照してください
delphi - Delphi:祖先コンストラクターを非表示にする方法は?
更新:最初に受け入れられた回答では回答されない、より単純な例で質問を根絶しました
次のクラスとその祖先が与えられます。
現在TCellPhone
、3つのコンストラクターが表示されています。
- カップ:整数
- カップ:整数; ティーポット:文字列
- ティーポット:文字列=''
TCellPhone
祖先コンストラクター(Teapot: string = ''
)が表示されず、宣言されたコンストラクターのみが残るようにするにはどうすればよいですか?
- カップ:整数
- カップ:整数; ティーポット:文字列
注:通常、子孫コンストラクターを持つという単純な行為は、祖先を非表示にします。
- カップ:整数
また、祖先コンストラクターと子孫の両方を保持したい場合は、子孫を
overload
:としてマークします。
- カップ:整数
- ティーポット:文字列=''
この質問のサンプルコードでは、Delphiが私のoverload
キーワードを間違えています。
それを考える:
- コンストラクターを祖先でオーバーロードしたい、
- 本当に兄弟でオーバーロードしたいとき
祖先コンストラクターを非表示にするにはどうすればよいですか?
注:現在定義されているDelphi言語を使用して、祖先の非仮想コンストラクターを非表示にすることは不可能な場合があります。「不可能」は有効な答えです。
試行された回答(失敗)
子孫コンストラクターに次のマークを付けてみreintroduce
ました(機能するまでキーワードをランダムに追加するモードにフォールバックします):
しかし、それは機能しませんでした。3つのコンストラクターはすべて表示されたままです。:(
元の質問
コンストラクターが見たくないクラスの子孫であるオブジェクトがあります。
注:これは架空の例です。現実の世界と同様に、祖先オブジェクトは既存のコードを壊さずに変更することはできません。
今、誰かが使用しているとき、私は彼らがコンストラクターを見るTiPhone
ことができることさえ望んでいません:TEniac
さらに悪いことに、彼らがそのコンストラクターを呼び出すと、私のコンストラクターを完全に見逃し、その間にすべてが行われます。間違ったコンストラクターを呼び出すのは非常に簡単です。それらはすべてIDEコード補完に表示され、コンパイルされます。
そして、それらは完全に無効なオブジェクトを取得します。
TCellPhone
これらのコンストラクターで例外をスローするように変更できます。
しかし、開発者は、顧客がいつかエラーを見つけて数十億ドルの罰金を科すまで、間違ったコンストラクターを呼び出していることに気づきません。実際、私はどこでも間違ったコンストラクターを呼び出そうとしていますが、Delphiに教えてもらう方法がわかりません!
delphi - Delphi:コンストラクターを理解する
私は理解しようとしています
- バーチャル
- オーバーライド
- 過負荷
- 再導入
オブジェクトコンストラクターに適用された場合。コンパイラがシャットダウンするまで、ランダムにキーワードを追加するたびに(Delphiで12年間開発した後)、ランダムに試すのではなく、自分が何をしているのかを知りたいと思います。
架空のオブジェクトのセットが与えられた場合:
私が彼らに振る舞わせたい方法はおそらく宣言から明らかですが:
TComputer
単純なコンストラクターがあり、子孫はそれをオーバーライドできますTCellPhone
代替コンストラクターがあり、子孫はそれをオーバーライドできますTiPhone
両方のコンストラクターをオーバーライドし、それぞれの継承バージョンを呼び出します
これで、そのコードはコンパイルされません。なぜうまくいかないのか理解したい。また、コンストラクターをオーバーライドする適切な方法を理解したいと思います。または、コンストラクターをオーバーライドすることはできませんか?それとも、コンストラクターをオーバーライドすることは完全に受け入れられますか?おそらく、複数のコンストラクターを持つべきではありません。おそらく、複数のコンストラクターを持つことは完全に許容されます。
理由を理解したい。そうすれば、それを修正することは明らかです。
も参照してください
編集:私はまた、、、、の順序でいくつかの推論を得ることを探してvirtual
います。キーワードのすべての組み合わせを試すと、組み合わせの数が爆発的に増えるためです。override
overload
reintroduce
- バーチャル; 過負荷;
- バーチャル; オーバーライド;
- オーバーライド; 過負荷;
- オーバーライド; バーチャル;
- バーチャル; オーバーライド; 過負荷;
- バーチャル; 過負荷; オーバーライド;
- 過負荷; バーチャル; オーバーライド;
- オーバーライド; バーチャル; 過負荷;
- オーバーライド; 過負荷; バーチャル;
- 過負荷; オーバーライド; バーチャル;
- 等
編集2: 「オブジェクト階層は可能ですか? 」から始めるべきだと思います。そうでない場合は、なぜですか?たとえば、祖先からコンストラクターを持つことは根本的に間違っていますか?
TCellPhone
今では2つのコンストラクターがあると思います。しかし、Delphiでキーワードの組み合わせを見つけて、それが有効なことだと思わせることができません。私はここに2つのコンストラクターを持つことができると考えるのは根本的に間違っていTCellPhone
ますか?
注:この線より下のすべてが質問に答えるために厳密に必要なわけではありませんが、それは私の考えを説明するのに役立ちます。おそらく、私の思考プロセスに基づいて、すべてを明確にするために私が欠けている基本的な部分を見ることができます。
現在、これらの宣言はコンパイルされません。
だから最初に私は修正しようとしますTCellPhone
。キーワードをランダムに追加することから始めます(それは私が望まない他のコンストラクターを隠すので、overload
私は望まないことを知っています):reintroduce
しかし、それは失敗します:Field definition not allowed after methods or properties
。
メソッドまたはプロパティの後にフィールドがない場合でも、キーワードvirtual
とoverload
キーワードの順序を逆にすると、Delphiがシャットダウンすることを経験から知っています。
しかし、それでもエラーが発生します。
メソッド「作成」は、基本タイプ「TComputer」の仮想メソッドを非表示にします
だから私は両方のキーワードを削除してみます:
しかし、それでもエラーが発生します。
メソッド「作成」は、基本タイプ「TComputer」の仮想メソッドを非表示にします
だから私は今試してみることに自分自身を辞任しますreintroduce
:
そして今、TCellPhoneはコンパイルされますが、それはTiPhoneにとって事態をさらに悪化させました。
どちらもオーバーライドできないと不平を言っているので、override
キーワードを削除します。
しかし、2番目の作成では、オーバーロードでマークする必要があると言っています。これは、オーバーロードとしてマークする必要があります(実際、オーバーロードとしてマークするのは、そうでない場合に何が起こるかを知っているためです)。
このセクションではすべてが良好interface
です。残念ながら、私の実装は機能しません。TiPhoneの単一パラメーターコンストラクターは、継承されたコンストラクターを呼び出すことができません。
delphi - Delphi:子孫に別のコンストラクターを追加するにはどうすればよいですか?
更新:私が最初に持っていた例は、ちょっと複雑でした。これは、1つのコードブロックですべてを説明する簡単な8行の例です。以下はコンパイルされないため、警告が表示されます。
注:この質問は、Delphiのコンストラクターの微妙さに関する私の進行中の一連の質問のパート3です。
元の質問
既存のクラスにコンストラクターを追加するにはどうすればよいですか?
架空の例を挙げましょう(つまり、ここでSOエディターに入力しているので、コンパイルされる場合とされない場合があります)。
TXHTMLStream
さらに、通常の使用では、使用する前に多くの繰り返しコードを実行する必要があると想定します。
ボイラープレートのセットアップコードをすべて単純化するコンストラクターを作成したいとします。
これにより、オブジェクトの使用が簡単になります。
今を除いて、Delphiは私の新しいコンストラクターが古いコンストラクターを隠していると不平を言います。
メソッド「作成」は、基本タイプ「TXMLStream」の仮想メソッドを非表示にします
私は確かに祖先の作成を隠すつもりはありませんでした-私は両方が欲しいです。
祖先コンストラクターを保持したまま、子孫クラスに(異なるシグネチャを持つ)コンストラクターを追加して、引き続き使用できるようにするにはどうすればよいですか?
delphi - Delphi:いつ非表示の祖先を再導入し、いつそれらを表示しますか?
今日最近Stackoverflowで私はそれを学びました:
私はそれをすべて理解しようとしてきたので、コンストラクターを扱う私の主な質問をサポートする、別の非常に具体的な質問があります。
更新:質問全体を置き換えました:
TCellPhoneを構築する場合、3つのコンストラクターを使用できます。
- カップ:整数
- カップ:整数; ティーポット:文字列
- [ティーポット:文字列='']
質問:なぜconstructor(Teapot: string='')
隠されていないのですか?
今私は3番目の子孫を追加しました:
TiPhone
4つのコンストラクターを作成する場合は、次のようにします。
- カップ:整数
- カップ:整数
- カップ:整数; ティーポット:文字列
- [ティーポット:文字列='']
なぜコンストラクターが4つあるのですか?既存の3つのうちの1つを上書きしました。編集:これはコードインサイトのバグである可能性があり、4つ表示されますが、2つが同じである場合、どうすれば呼び出すことができますか?
元のコードを再度使用する:
TCellPhone
3つのコンストラクターがあることはすでに知られています。
- カップ:整数
- カップ:整数; ティーポット:文字列
- [ティーポット:文字列='']
TCellPhone
の宣言を変更して祖先コンストラクターを非表示にするにはどうすればよいですか?たとえば、次のようになります。
コンストラクターは2つだけです。
- カップ:整数
- カップ:整数; ティーポット:文字列
ここで、がreintroduce
非仮想の祖先を非表示にするために使用される場合について説明します。前のケースでは、TiPhone
コンストラクターが4つあります(理想的には2つだけでTComputer
、祖先が何らかの形で隠されています)。しかし、私が修正できない場合でも、私は1つだけを持つようにTComputer
変更することができます:TiPhone
現在TiPhone
、コンストラクターは1つだけです。
- カップ:整数
Reintroduceは通常、仮想祖先の非表示に関する警告を抑制するためにのみ使用されます。この場合:
仮想ではありません-それでも、reintroduceを使用して非表示にすることができます。
しかし今、私が別のオーバーロードを追加した場合TiPhone
:
その後、突然(以前は隠されていた)祖先が戻ってきます:
- TiPhone.Create(7);
- TiPhone.Create('ピンク');
- TiPhone.Create(7、'ピンク');
- TiPhone.Create();
ご覧のとおり、私はの論理を理解するのに苦労しています
- 何かが隠されているとき
- 何かを隠す方法
- 何かが表示されたとき
- 何かを示す方法
delphi - Delphi:オーバーライドされた仮想コンストラクタの子孫がオーバーロードによって呼び出されていない
Delphiのコンストラクタに関する一連の質問のもう1つ。
仮想コンストラクターを持つ基本クラスがあります。
コンストラクターは、誰かが呼び出す必要があるときのために仮想です
コンストラクターはoverridden
子孫にあります:
WhereTCellPhone
とTiPhone
子孫はそれぞれ独自の初期化を行う機会があります(読みやすさのために含まれていないメンバーの)。
しかし今、私はオーバーロードされたコンストラクターをいくつかの祖先に追加します:
TCellPhoneの代替コンストラクターは、他の仮想コンストラクターを呼び出すため、常に適切なオーバーライド動作を取得します。
問題は、子孫のオーバーライドされたコンストラクターが呼び出されないことです。呼び出しの実際のスタックトレースチェーンは次のとおりです。
仮想であるへの兄弟呼び出しは、次TCellPhone.Create(int)
の子孫のオーバーライドされたメソッドを呼び出す必要がありますTiPhone
。
したがって、兄弟仮想コンストラクターを使用しようとすると、Delphiが期待どおりに機能しないようです。
では、あるコンストラクターが別のコンストラクターを使用するのは悪い考えですか?オーバーロードされたコンストラクターのコードが相互のコピーアンドペーストバージョンであるという設計意図はありますか?
.NETで、いくつかのコンストラクターが相互にチェーンしていることに気付きました。
これは、次の場合にのみ問題になるようです。
- コンストラクターは仮想です
- コンストラクターをオーバーロードします
あるコンストラクターに別のコンストラクターをオーバーロードさせることはできないというルールはありますか?
delphi - コンストラクターの可視性について
以下に 2 つの単純なクラスを示します。最初はどちらもキーワード (virtual、overload、override、reintroduce) を持っていません。
上記の定義を少し短いものとして表します。
また、構築時には、コンストラクター ( , )TCellPhone
が 1 つしかありません。これは、祖先コンストラクターが非表示になっているためです。i の可視コンストラクターを次のように示します。int
string
TCellPhone
- ティーポット: 整数; ハンドル:紐
ここで質問ですが、最初の 3 つのケースは理にかなっていますが、4 番目のケースは意味がありません。
1. 祖先コンストラクターは子孫によって隠されています。
Teapot: Integer; Handle: string
これは理にかなっています。新しいコンストラクターを宣言したため、祖先コンストラクターは非表示になっています。
2. 祖先の仮想コンストラクターは子孫によって隠されています。
Teapot: Integer; Handle: string
これは理にかなっています。新しいコンストラクターを宣言したため、祖先コンストラクターは非表示になっています。
注:先祖は仮想であるため、Delphi は、仮想先祖を非表示にしていることを警告します (前の静的コンストラクターを非表示にする例: 誰も気にしないので、警告はありません)。reintroduceを追加することで、警告を抑制することができます (「ええええええ、私は仮想コンストラクターを隠しています。そう するつもりでした」という意味です)。
3. オーバーロードのため、祖先コンストラクターが子孫に隠されていません:
Teapot: Integer; Handle: string
Teapot: Integer
子孫コンストラクターは祖先のオーバーロードであるため、これは理にかなっています。そのため、両方を存在させることができます。祖先コンストラクターは隠されていません。
4. オーバーロードのため、仮想先祖コンストラクターが子孫に隠されていません -それでも警告が表示されます:
これは意味をなさないケースです:
Teapot: Integer; Handle: string
Teapot: Integer
メソッド 'Create' は、基本型 'TComputer' の仮想メソッドを非表示にします
これはほとんど意味がありません。先祖が隠れていないだけでなく、子孫が過負荷になっています。文句を言うべきでもありません。
何を与える?