問題タブ [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.

0 投票する
1 に答える
2095 参照

delphi - Delphi 5 - WinXP と Win2K で StrToFloat の結果が異なる

私のマシンと本番サーバーで文字列を変換すると、次のような異なる結果が得られるという奇妙な問題があります。

WinXP マシンでの Button1Click の結果は '1.234' で、有効な浮動小数点値ではありませんが、Win2K マシンでは問題なく動作します。

反対側の Button2Click は WinXP で動作しますが、「1,234」は有効な浮動小数点値ではありませんというエラーが発生します。

両方のマシンの地域設定が「ドイツ語(オーストリア)」に設定されています-なぜこれが起こっているのか、少なくとも地域設定ダイアログにDelphiの「DecimalSeparator」および「GetLocaleChar(GetThreadLocale、LOCALE_SDECIMAL)」とは異なる小数点区切り文字が表示される理由についてのアイデア, '.')?

よろしく、ラインハルト

0 投票する
5 に答える
1142 参照

delphi - Delphi-5 単一ファイル ストレージ ソリューション?

単一ファイル ストレージを既存のコードに簡単に統合する Delphi-5 ソリューションはありますか? Java *.jar や Openoffice ドキュメント ファイルのような、圧縮/圧縮されたファイルとフォルダーであるが、独自のファイル拡張子を持つファイルが必要です。

編集: ZIP 対応のコンポーネントをいくつか知っていますが、一言で言えば、「コンテナ」内のファイルにアクセスし、通常のファイル処理ルーチンを使用したいと考えています (例: TStringList.SaveToFile)。圧縮/解凍に関するオーバーヘッドは、コンポーネントで処理する必要があります。

0 投票する
1 に答える
7358 参照

delphi - Delphi QuickReports:詳細-子-子-子バンディングを達成するためのバンド順?

次のようにレイアウトされたDelphi 5でQuickReportを作成する必要があります。

ヘッダー、詳細、子、フッター、サブ詳細、グループ ヘッダー、グループ フッター バンドの組み合わせと、それらの間の関連する親、マスター、レポート、クエリ リンクを組み合わせて、次のようなレポートを作成できるようにすることはできますか?私はそれを見る必要がありますか?

私の用語の使用を混同しないでください

  • ヘッダーバンド
  • 詳細バンド
  • 子バンド
  • フッター バンド

バンドのいずれかがそれらの実際のタイプでなければならないことを意味します。私はこれらの用語を概念的な意味で使用します。

  • レポート全体の開始時の単一バンド (レポート ヘッダー)
  • 4 つのバンドの繰り返しグループ
  • すべての詳細の後に表示される 3 つのバンド。最初の 2 つは自動伸縮性があります。

同じ質問、長いだけ

私が作成した例を模倣するいくつかのテーブルを作成できます。


私の失敗した実験

次のバンド レイアウトで QuackReport を作成しようとしました。

注:インデントは、親子関係を識別するために使用されます (つまり、バンドは実際には 50 ピクセルインデントされていません)。

この設計の問題点は、少なくとも設計時に、まとめられた 2 つの子バンドの前にサマリーバンドが表示されることです。

レポートが (実行時に) 実行されると、取り残された 2 つの子バンドは出力されません。

キャプチャ: quackreports

0 投票する
3 に答える
33483 参照

delphi - Delphi: Application.Handle とは何ですか?

とはTApplication.Handle?

  • それはどこから来たのですか?
  • なぜそれが存在するのですか?
  • そして最も重要なのは、なぜすべてのフォームがそれを親ウィンドウ ハンドルとして持っているのでしょうか?

Delphi のヘルプには次のように書かれています。

TApplication.ハンドル

アプリケーションのメイン フォーム (ウィンドウ) のウィンドウ ハンドルへのアクセスを提供します。

説明

親ウィンドウ ハンドルを必要とする Windows API 関数を呼び出す場合は、Handle を使用します。たとえば、独自のトップレベルのポップアップ ウィンドウを表示する DLL には、アプリケーションでウィンドウを表示するための親ウィンドウが必要です。Handle プロパティを使用すると、そのようなウィンドウがアプリケーションの一部になるため、アプリケーションで最小化、復元、有効化、および無効化できます。

「アプリケーションのメイン フォームのウィンドウ ハンドル」という言葉に注目し、それをアプリケーションのメイン フォームのウィンドウ ハンドルと解釈すると、次のように比較できます。

  • 「アプリケーションのメイン フォームのウィンドウ ハンドル」、
  • MainFormのウィンドウハンドルApplication

しかし、それらは同じではありません:

だから何Application.Handleですか?

  • それはどこから来たのですか?
  • どの Windows® ウィンドウ ハンドルですか?
  • の Windows® ウィンドウ ハンドルである場合、一致しないApplicationMainFormはなぜですか?
  • のウィンドウ ハンドルでない場合、それは何ですか?ApplicationMainForm
  • さらに重要なのは、なぜそれがすべてのフォームの最終的な親所有者なのかということです。
  • そして最も重要なのは、フォームを親から外して所有しないようにしようとしたり (タスクバーに表示できるようにするため)、または IProgressDialog のようなものを使用しようとすると、すべてがうまくいかないなぜですか?

本当に私が求めているのは、Application.Handleを存在させる設計上の根拠は何ですか? その理由を理解できれば、その方法が明らかになるはずです。


20 の質問のゲームを通して理解を更新します。

所有者を作成することによってウィンドウをタスクバーに表示する解決策について話す際にnullPeter Below は 2000 年に次のように述べています。

これにより、セカンダリ フォームから表示されるモーダル フォームで問題が発生する可能性があります。

モーダル フォームが起動しているときにユーザーがアプリから切り替えて、それを表示していたフォームに戻ると、モーダル フォームがフォームの下に隠れる場合があります。モーダルフォームが親であることを確認することで、これに対処することができます [sic; 彼はそれを示したフォームに所有することを意味しました( params.WndParent上記のように使用)

Dialogsしかし、これはunit およびexceptionからの標準ダイアログでは不可能であり、それらを正しく機能させるにはより多くの努力が必要です (基本的に、 を処理し、 Application viaApplication.OnActivateを親とするモーダル フォームを検索し 、それらを Z オーダーの最上位に移動する via ) 。 .GetLastActivePopupSetWindowPos

  • モーダル フォームが他のフォームの後ろに隠れてしまうのはなぜですか?
  • 通常、モーダル フォームを前面に表示するメカニズムは何ですか?ここでは機能しないのはなぜですか?
  • Windows® は、ウィンドウを積み重ねて表示する役割を果たします。Windows® が正しいウィンドウを表示しないのはなぜですか?

彼はまた、ウィンドウを強制的にタスク バーに表示する新しい Windows 拡張スタイルを使用することについても話しました (ウィンドウを非所有にする通常のルールが不十分、非現実的、または望ましくない場合)、WS_EX_APPWINDOW拡張スタイルを追加することによって:

しかし、彼は次のように警告します。

別のアプリがアクティブなときにセカンダリ フォーム タスクバー ボタンをクリックすると、すべてのアプリケーション フォームが前面に表示されます。したくない場合はオプションがあります

フォームの所有者がまだApplication.Handle. アプリケーションはこれを行っていますか? なぜこれを行うのですか?こうするより、こうすべきではないこれを行わないことの欠点は何ですか。これを行うことのマイナス面がわかりました(システム メニューが正しく機能しない、タスクバー ボタンのサムネイルが不正確である、Windows® シェルがウィンドウを最小化できないなど)。


を扱った別の投稿でApplicationMike Edenfield は、親ウィンドウが他のウィンドウの最小化、最大化、および復元メッセージを送信すると述べています

これにより、フォームにタスクバー ボタンが追加されますが、他にも処理すべき細かい点がいくつかあります。最も明白なのは、フォームが親フォーム (アプリケーションのメイン フォーム) に送信される最小化/最大化を引き続き受信することです。これを回避するには、次のような行を追加して WM_SYSCOMMAND のメッセージ ハンドラーをインストールします。

このハンドラは、最小化メッセージを渡さないように、アプリケーションの残りの > 部分とは独立して動作させたいもののPARENT形式になることに注意してください。> SC_MAXIMIZE、SC_RESTORE などに同様のコードを追加できます。

Windows® ウィンドウの最小化/最大化/復元メッセージがウィンドウに表示されないのはなぜですか? これは、ウィンドウ宛てのメッセージが Windows® によってウィンドウの所有者に送信されるためでしょうか? この場合、Delphi アプリケーションのすべてのフォームはApplication?によって「所有」されています。それは所有者をnullにするという意味ではありませんか:

ウィンドウ ハンドルが削除され、フォームに干渉しなくなりますApplication。Windows はもう一度、最小化/最大化/復元メッセージを送信する必要がありますか?


おそらく、「通常の」Windows アプリケーションが実行することと、Borland が最初に Delphi アプリケーションを実行するように設計した方法を比較対照すると、このApplicationオブジェクトとメイン ループに関してです。

  • Applicationオブジェクトはどのソリューションを解決していましたか?
  • これらの同じ問題が存在しないようにするために、Delphi の新しいバージョンではどのような変更が加えられましたか?
  • それ以降のバージョンの Delphi での変更は、最初のアプリケーション設計が解決しようと懸命に試みた他の問題を引き起こしませんでしたか?
  • これらの新しいアプリケーションは、アプリケーションがそれらに干渉することなく、どのように機能し続けることができるでしょうか?

明らかに、Borland は初期設計の欠陥に気付きました。彼らの最初の設計は何でしたか、どのような問題を解決しましたか、どのような欠陥がありましたか、どのような再設計が行われたか、どのように問題を解決しましたか?

0 投票する
4 に答える
3381 参照

delphi - Delphi:減算時にEIntOverflowアンダーフローを回避するには?

Microsoft は、GetTickCount のドキュメントで、ティック カウントを比較して間隔が経過したかどうかを確認することはできないと既に述べています。例えば:

不正解 (疑似コード):

上記のコードは、ティック カウンターのロールオーバーの影響を受けやすいため、不適切です。たとえば、クロックがその範囲の終わりに近づいているとします。

次に、チェックを実行します。

GetTickCount よりも大きいため、これはすぐに満たされendTimeます。


ソリューション

代わりに、常に 2 つの時間間隔を減算する必要があります。

同じ数学を見ると:

コンパイラが特定の方法で動作する C/C++ では、これはすべてうまくいきます。

しかし、Delphi はどうでしょうか。

しかし、( {Q+}, ) のオーバーフロー チェックを使用して Delphi で同じ計算を実行すると、 TickCountがロールオーバー{$OVERFLOWCHECKS ON}すると、2 つのティック カウントの減算により EIntOverflow 例外が生成されます。

この問題の意図した解決策は何ですか?

編集:一時的にオフにしようとしましたOVERFLOWCHECKS

しかし、減算は依然としてEIntOverflow例外をスローします。

キャストとより大きな中間変数型を含む、より良い解決策はありますか?


アップデート

私が尋ねた別のSOの質問では、なぜ{$OVERFLOWCHECKS}うまくいかないのかを説明しました。どうやら、行レベルではなく、関数レベルでのみ機能します。したがって、以下は機能しませんが

以下機能します:

0 投票する
1 に答える
3523 参照

delphi - Delphi:$ OVERFLOWCHECKS OFFを使用してオーバーフローチェックを無効にするにはどうすればよいですか?

アンダーフローを引き起こすコードが少しあります:

減算自体オーバーフロー(アンダーフロー)を生成しますが、DelphiでEIntOverflow例外をスローしたくありません。だから私はオーバーフローチェックを無効にすることによってオーバーフローチェックコードの生成を無効にしてみます:

ただし、OVERFLOWCHECKS OFFオプションを使用しても、例外がスローされます。そして、生成されたコードにはまだチェックが含まれています:

代替テキスト

上のドキュメントのリマインダー$Q

オーバーフローチェック

タイプスイッチ
構文{$Q+}または{$Q-}
{$OVERFLOWCHECKSON}または{$OVERFLOWCHECKSOFF}
デフォルト{$Q-}
{$OVERFLOWCHECKSOFF}
スコープローカル

備考

$ Qディレクティブは、オーバーフローチェックコードの生成を制御します。{$ Q +}状態では、特定の整数算術演算(+、-、*、Abs、Sqr、Succ、Pred、Inc、およびDec)のオーバーフローがチェックされます。これらの整数算術演算のそれぞれのコードの後に​​、結果がサポートされている範囲内にあることを確認する追加のコードが続きます。オーバーフローチェックが失敗すると、EIntOverflow例外が発生します(または、例外処理が有効になっていない場合はプログラムが終了します)。

$ Qスイッチは通常、範囲チェックコードの生成を有効または無効にする$Rスイッチと組み合わせて使用​​されます。オーバーフローチェックを有効にすると、プログラムの速度が低下し、プログラムがいくらか大きくなるため、デバッグにのみ{$Q+}を使用してください。

$OVERFLOWCHECKS OFFオーバーフローチェックコードの生成を無効にするにはどうすればよいですか?


メイソンの答えはうまくいった。改訂されたコードは次のとおりです。

グーグルクローラーの場合、別の質問の言い回し:Delphiでオーバーフローチェックを一時的に無効にする方法は?

0 投票する
3 に答える
2748 参照

delphi - DUnit:テストを実行する方法は?

IDEからTestCaseを実行するにはどうすればよいですか?

単一のシンプルなフォームで新しいプロジェクトを作成しました。

Button1次に、テストケースを追加して、プッシュが適切に機能することを確認します。

私が行ったこと(GUIプロジェクトのテストコード)を考えると、テストの実行をトリガーするにはどうすればよいですか?押すF9と、フォームが表示されます。

代替テキスト

理想的には、IDEに「DUnitテストの実行」というボタンまたはメニューオプションがあります。

代替テキスト

私は夢の世界に住んでいますか?ロリポップレーンのガムドロップハウスに住むファンタジーランド?

0 投票する
4 に答える
1879 参照

delphi - Delphi:プロジェクトグループにデフォルトのプロジェクトを設定するにはどうすればよいですか?

プロジェクトグループに2つのプロジェクトがあります。

  • ProjectA
  • ProjectB

DelphiでProjectGroup.bpgを開くと、常に2番目のプロジェクトがアクティブなプロジェクトとして開始されます。

  • ProjectA
  • ProjectB

そして、私がそれを「本当の」プロジェクトにひっくり返す必要があるたびに:

  • ProjectA
  • ProjectB

ProjectAをプロジェクトグループで開くデフォルトのプロジェクトにするにはどうすればよいですか?


ProjectGroup.bpg

DUnit:実用的な理由でユニットテストを実行する方法を参照してください。

0 投票する
3 に答える
3164 参照

delphi - Delphi:StringReplaceWまたはWideStringReplace関数はありますか?

そこにワイドストリング操作の実装はありますか?

0 投票する
2 に答える
2693 参照

delphi - Delphi SampleProfiler: このコードはどのように ntdll.dll を呼び出していますか?

Delphi Sampling Profilerを使用して、アプリケーションの一部をプロファイリングしました。ほとんどの人と同じように、私はほとんどの時間を室内で過ごしていntdll.dllます。

注:時間を無視する オプションをオンにし、Application.Idleから呼び出しますSystem.pasntdllアプリケーションがアイドル状態であるため、内部にはありません。

代替テキスト

複数回実行した後、ほとんどの時間は 内ntdll.dllで費やされているように見えますが、奇妙なことに呼び出し元は次のようになります。

ここに画像の説明を入力

呼び出し元は、仮想ツリービューからのものです:

注:ntdll.dllアプリケーションがアイドル状態であるため、アプリケーションは内部にありませんApplication.Idle

私を混乱させているのは、この行自体(つまり、PrepareCellntdllの何かではない) が呼び出し元であるということです。さらに紛らわしいのは、次のことです。

  • だけでなく、それは内部の何かではありません PrepareCell()
  • 呼び出し元であるセットアップ(スタック変数のポップ、暗黙的な例外フレームのセットアップなど)でさえありません。これらは、 PrepareCell 内PrepareCellのホットスポットとしてプロファイラーに表示されます。begin

VirtualTrees.pas:

だから私はこの行がどのように理解しようとしています:

を呼び出してntdll.dllいます。


唯一の他の方法は、次の 3 つのパラメーターです。

  • PaintInfo
  • Window.Left
  • NodeBitmap.Width

おそらくそれらの 1 つは、 を呼び出す関数またはプロパティ ゲッターntdllです。そのため、行にブレークポイントを設定し、実行時に CPU ウィンドウを確認します。

代替テキスト

犯人である可能性のある行があります

しかし、私がそのジャンプをたどると、それは終わらないntdll.dllが、TBitmap.GetWidth:

代替テキスト

ご覧のとおり、これはどこにも呼び出されません。と確かにではありませんntdll.dll


それで、行はどうですか:

への呼び出しntdll.dll


注:実際には ntdll.dll を呼び出しているわけではないことは十分承知しています。したがって、有効な回答には、「Sampling Profiler is misleading. that line is not calling into ntdll.dll.」という言葉を含める必要があります。また、答えは、ほとんどの時間がntdll.dll に費やされていないか、強調表示された行が呼び出し元ではないことを示す必要があります。最後に、Sampling Profiler が間違っている理由と、それを修正する方法を説明する必要があります。

更新 2

ntdll.dll とは? Ntdll は、Windows NT のネイティブ API セットです。Win32 API は、 Windows 1/2/3/9x に存在していた Windows API にたラッパーntdll.dllです。実際に ntdll にアクセスするには、直接的または間接的に ntdll を使用する関数を呼び出す必要があります。

たとえば、Delphi アプリケーションがアイドル状態になると、user32.dll 関数を呼び出してメッセージを待機します。

実際に見たときは次のとおりです。

で指定された関数を呼び出すこと$7ffe0300は、Windows が Ring0 に移行する方法であり、EAX で指定された FunctionID を呼び出します。この場合、呼び出されるシステム関数は 0x1226 です。私のオペレーティング システム、Windows Vista では、0x1226 がシステム関数に対応しますNtUserWaitMessage

ntdll.dll にアクセスするには、次のようにします。それを呼び出します。

元の質問を言葉にしたとき、私は必死に手を振って無回答を避けようとしていました. 非常に具体的で、私が見ている現実を注意深く指摘することで、人々が事実を無視するのを防ぎ、手を振って議論をしようとしていました.


アップデート 3

私は2つのパラメータを変換しました:

スタック変数に:

ボトルネックがないことを確認するには、

  • Windows.Left、 また
  • Nodebitmap.Width

プロファイラーはまだその行を示しています

それ自体がボトルネックです。PrepareCell内には何もありません。これは、セルを準備するための呼び出しのセットアップ内、または PrepareCell の開始時の何かであることを意味する必要があります。

ntdll を呼び出すものは何もありません。PrepareCell 自体のプリアンブル:

そこには何も呼び出されませんntdll.dll


疑問はまだ残っています:

  • 1 つの変数をスタックにプッシュし、他の 2 つの変数をレジスタにプッシュすることがボトルネックになるのはなぜですか?
  • PrepareCell 自体の内部がボトルネックにならないのはなぜですか?