問題タブ [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 5 - WinXP と Win2K で StrToFloat の結果が異なる
私のマシンと本番サーバーで文字列を変換すると、次のような異なる結果が得られるという奇妙な問題があります。
WinXP マシンでの Button1Click の結果は '1.234' で、有効な浮動小数点値ではありませんが、Win2K マシンでは問題なく動作します。
反対側の Button2Click は WinXP で動作しますが、「1,234」は有効な浮動小数点値ではありませんというエラーが発生します。
両方のマシンの地域設定が「ドイツ語(オーストリア)」に設定されています-なぜこれが起こっているのか、少なくとも地域設定ダイアログにDelphiの「DecimalSeparator」および「GetLocaleChar(GetThreadLocale、LOCALE_SDECIMAL)」とは異なる小数点区切り文字が表示される理由についてのアイデア, '.')?
よろしく、ラインハルト
delphi - Delphi-5 単一ファイル ストレージ ソリューション?
単一ファイル ストレージを既存のコードに簡単に統合する Delphi-5 ソリューションはありますか? Java *.jar や Openoffice ドキュメント ファイルのような、圧縮/圧縮されたファイルとフォルダーであるが、独自のファイル拡張子を持つファイルが必要です。
編集: ZIP 対応のコンポーネントをいくつか知っていますが、一言で言えば、「コンテナ」内のファイルにアクセスし、通常のファイル処理ルーチンを使用したいと考えています (例: TStringList.SaveToFile)。圧縮/解凍に関するオーバーヘッドは、コンポーネントで処理する必要があります。
delphi - Delphi QuickReports:詳細-子-子-子バンディングを達成するためのバンド順?
次のようにレイアウトされたDelphi 5でQuickReportを作成する必要があります。
ヘッダー、詳細、子、フッター、サブ詳細、グループ ヘッダー、グループ フッター バンドの組み合わせと、それらの間の関連する親、マスター、レポート、クエリ リンクを組み合わせて、次のようなレポートを作成できるようにすることはできますか?私はそれを見る必要がありますか?
私の用語の使用を混同しないでください
- ヘッダーバンド
- 詳細バンド
- 子バンド
- フッター バンド
バンドのいずれかがそれらの実際のタイプでなければならないことを意味します。私はこれらの用語を概念的な意味で使用します。
- レポート全体の開始時の単一バンド (レポート ヘッダー)
- 4 つのバンドの繰り返しグループ
- すべての詳細の後に表示される 3 つのバンド。最初の 2 つは自動伸縮性があります。
同じ質問、長いだけ
私が作成した例を模倣するいくつかのテーブルを作成できます。
私の失敗した実験
次のバンド レイアウトで QuackReport を作成しようとしました。
注:インデントは、親子関係を識別するために使用されます (つまり、バンドは実際には 50 ピクセルインデントされていません)。
この設計の問題点は、少なくとも設計時に、まとめられた 2 つの子バンドの前にサマリーバンドが表示されることです。
レポートが (実行時に) 実行されると、取り残された 2 つの子バンドは出力されません。
キャプチャ: quackreports
delphi - Delphi: Application.Handle とは何ですか?
とはTApplication.Handle
?
- それはどこから来たのですか?
- なぜそれが存在するのですか?
- そして最も重要なのは、なぜすべてのフォームがそれを親ウィンドウ ハンドルとして持っているのでしょうか?
Delphi のヘルプには次のように書かれています。
TApplication.ハンドル
アプリケーションのメイン フォーム (ウィンドウ) のウィンドウ ハンドルへのアクセスを提供します。
説明
親ウィンドウ ハンドルを必要とする Windows API 関数を呼び出す場合は、Handle を使用します。たとえば、独自のトップレベルのポップアップ ウィンドウを表示する DLL には、アプリケーションでウィンドウを表示するための親ウィンドウが必要です。Handle プロパティを使用すると、そのようなウィンドウがアプリケーションの一部になるため、アプリケーションで最小化、復元、有効化、および無効化できます。
「アプリケーションのメイン フォームのウィンドウ ハンドル」という言葉に注目し、それをアプリケーションのメイン フォームのウィンドウ ハンドルと解釈すると、次のように比較できます。
- 「アプリケーションのメイン フォームのウィンドウ ハンドル」、
MainForm
のウィンドウハンドルApplication
しかし、それらは同じではありません:
だから何Application.Handle
ですか?
- それはどこから来たのですか?
- どの Windows® ウィンドウ ハンドルですか?
- の Windows® ウィンドウ ハンドルである場合、一致しない
Application
のMainForm
はなぜですか? - のウィンドウ ハンドルでない場合、それは何ですか?
Application
MainForm
- さらに重要なのは、なぜそれがすべてのフォームの最終的な
親所有者なのかということです。 - そして最も重要なのは、フォームを親から外して所有しないようにしようとしたり (タスクバーに表示できるようにするため)、または IProgressDialog のようなものを使用しようとすると、すべてがうまくいかない
のはなぜですか?
本当に私が求めているのは、Application.Handleを存在させる設計上の根拠は何ですか? その理由を理解できれば、その方法が明らかになるはずです。
20 の質問のゲームを通して理解を更新します。
所有者を作成することによってウィンドウをタスクバーに表示する解決策について話す際にnull
、Peter Below は 2000 年に次のように述べています。
これにより、セカンダリ フォームから表示されるモーダル フォームで問題が発生する可能性があります。
モーダル フォームが起動しているときにユーザーがアプリから切り替えて、それを表示していたフォームに戻ると、モーダル フォームがフォームの下に隠れる場合があります。モーダルフォームが親であることを確認することで、これに対処することができます [sic; 彼はそれを示したフォームに所有することを意味しました(
params.WndParent
上記のように使用)
Dialogs
しかし、これはunit およびexceptionからの標準ダイアログでは不可能であり、それらを正しく機能させるにはより多くの努力が必要です (基本的に、 を処理し、 Application viaApplication.OnActivate
を親とするモーダル フォームを検索し 、それらを Z オーダーの最上位に移動する via ) 。 .GetLastActivePopup
SetWindowPos
- モーダル フォームが他のフォームの後ろに隠れてしまうのはなぜですか?
- 通常、モーダル フォームを前面に表示するメカニズムは何ですか?ここでは機能しないのはなぜですか?
- Windows® は、ウィンドウを積み重ねて表示する役割を果たします。Windows® が正しいウィンドウを表示しないのはなぜですか?
彼はまた、ウィンドウを強制的にタスク バーに表示する新しい Windows 拡張スタイルを使用することについても話しました (ウィンドウを非所有にする通常のルールが不十分、非現実的、または望ましくない場合)、WS_EX_APPWINDOW
拡張スタイルを追加することによって:
しかし、彼は次のように警告します。
別のアプリがアクティブなときにセカンダリ フォーム タスクバー ボタンをクリックすると、すべてのアプリケーション フォームが前面に表示されます。したくない場合はオプションがあります
フォームの所有者がまだApplication.Handle
. アプリケーションはこれを行っていますか? なぜこれを行うのですか?こうするより、こうすべきではないか。これを行わないことの欠点は何ですか。これを行うことのマイナス面がわかりました(システム メニューが正しく機能しない、タスクバー ボタンのサムネイルが不正確である、Windows® シェルがウィンドウを最小化できないなど)。
を扱った別の投稿でApplication
、Mike Edenfield は、親ウィンドウが他のウィンドウの最小化、最大化、および復元メッセージを送信すると述べています。
これにより、フォームにタスクバー ボタンが追加されますが、他にも処理すべき細かい点がいくつかあります。最も明白なのは、フォームが親フォーム (アプリケーションのメイン フォーム) に送信される最小化/最大化を引き続き受信することです。これを回避するには、次のような行を追加して WM_SYSCOMMAND のメッセージ ハンドラーをインストールします。
このハンドラは、最小化メッセージを渡さないように、アプリケーションの残りの > 部分とは独立して動作させたいもののPARENT形式になることに注意してください。> SC_MAXIMIZE、SC_RESTORE などに同様のコードを追加できます。
Windows® ウィンドウの最小化/最大化/復元メッセージがウィンドウに表示されないのはなぜですか? これは、ウィンドウ宛てのメッセージが Windows® によってウィンドウの所有者に送信されるためでしょうか? この場合、Delphi アプリケーションのすべてのフォームはApplication
?によって「所有」されています。それは所有者をnullにするという意味ではありませんか:
ウィンドウ ハンドルが削除され、フォームに干渉しなくなりますApplication
。Windows はもう一度、最小化/最大化/復元メッセージを送信する必要がありますか?
おそらく、「通常の」Windows アプリケーションが実行することと、Borland が最初に Delphi アプリケーションを実行するように設計した方法を比較対照すると、このApplication
オブジェクトとメイン ループに関してです。
Application
オブジェクトはどのソリューションを解決していましたか?- これらの同じ問題が存在しないようにするために、Delphi の新しいバージョンではどのような変更が加えられましたか?
- それ以降のバージョンの Delphi での変更は、最初のアプリケーション設計が解決しようと懸命に試みた他の問題を引き起こしませんでしたか?
- これらの新しいアプリケーションは、アプリケーションがそれらに干渉することなく、どのように機能し続けることができるでしょうか?
明らかに、Borland は初期設計の欠陥に気付きました。彼らの最初の設計は何でしたか、どのような問題を解決しましたか、どのような欠陥がありましたか、どのような再設計が行われたか、どのように問題を解決しましたか?
delphi - Delphi:減算時にEIntOverflowアンダーフローを回避するには?
Microsoft は、GetTickCount のドキュメントで、ティック カウントを比較して間隔が経過したかどうかを確認することはできないと既に述べています。例えば:
不正解 (疑似コード):
上記のコードは、ティック カウンターのロールオーバーの影響を受けやすいため、不適切です。たとえば、クロックがその範囲の終わりに近づいているとします。
次に、チェックを実行します。
GetTickCount
はよりも大きいため、これはすぐに満たされendTime
ます。
ソリューション
代わりに、常に 2 つの時間間隔を減算する必要があります。
同じ数学を見ると:
コンパイラが特定の方法で動作する C/C++ では、これはすべてうまくいきます。
しかし、Delphi はどうでしょうか。
しかし、( {Q+}
, ) のオーバーフロー チェックを使用して Delphi で同じ計算を実行すると、 TickCountがロールオーバー{$OVERFLOWCHECKS ON}
すると、2 つのティック カウントの減算により EIntOverflow 例外が生成されます。
この問題の意図した解決策は何ですか?
編集:一時的にオフにしようとしましたOVERFLOWCHECKS
:
しかし、減算は依然としてEIntOverflow
例外をスローします。
キャストとより大きな中間変数型を含む、より良い解決策はありますか?
アップデート
私が尋ねた別のSOの質問では、なぜ{$OVERFLOWCHECKS}
うまくいかないのかを説明しました。どうやら、行レベルではなく、関数レベルでのみ機能します。したがって、以下は機能しませんが:
以下は機能します:
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でオーバーフローチェックを一時的に無効にする方法は?
delphi - Delphi:プロジェクトグループにデフォルトのプロジェクトを設定するにはどうすればよいですか?
プロジェクトグループに2つのプロジェクトがあります。
- ProjectA
- ProjectB
DelphiでProjectGroup.bpgを開くと、常に2番目のプロジェクトがアクティブなプロジェクトとして開始されます。
- ProjectA
- ProjectB
そして、私がそれを「本当の」プロジェクトにひっくり返す必要があるたびに:
- ProjectA
- ProjectB
ProjectAをプロジェクトグループで開くデフォルトのプロジェクトにするにはどうすればよいですか?
ProjectGroup.bpg
DUnit:実用的な理由でユニットテストを実行する方法を参照してください。
delphi - Delphi:StringReplaceWまたはWideStringReplace関数はありますか?
そこにワイドストリング操作の実装はありますか?
delphi - Delphi SampleProfiler: このコードはどのように ntdll.dll を呼び出していますか?
Delphi Sampling Profilerを使用して、アプリケーションの一部をプロファイリングしました。ほとんどの人と同じように、私はほとんどの時間を室内で過ごしていntdll.dll
ます。
注:時間を無視する オプションをオンにし、
Application.Idle
から呼び出しますSystem.pas
。ntdll
アプリケーションがアイドル状態であるため、内部にはありません。
複数回実行した後、ほとんどの時間は 内ntdll.dll
で費やされているように見えますが、奇妙なことに呼び出し元は次のようになります。
呼び出し元は、仮想ツリービューからのものです:
注:
ntdll.dll
アプリケーションがアイドル状態であるため、アプリケーションは内部にありませんApplication.Idle
。
私を混乱させているのは、この行自体(つまり、PrepareCell内ntdll
の何かではない) が呼び出し元であるということです。さらに紛らわしいのは、次のことです。
- だけでなく、それは内部の何かではありません
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 自体の内部がボトルネックにならないのはなぜですか?