Delphi XE2 (Update 3) を使用しています。非常に大きなプロジェクトがあり、パッケージをコンパイルすると Delphi IDE がクラッシュすることがあります。問題を再現する単純なプロジェクトにそれを取り除くことができました。
問題の概要
VCL フレームを使用してパッケージ間で視覚的なフォームの継承を行い、祖先フレームに標準コントロールが含まれている場合、すべてが正常に機能します。
祖先フレームの標準コントロールをコントロールのサブクラスに置き換えることを除いて、同じことを行うと、Delphi IDE を簡単にクラッシュさせることができます。
VCL フレームがサブクラス化されたコントロールを含む祖先フレームから派生/継承する別のパッケージのメンバーである VCL フレームをデザイン モードで表示しながら、祖先フレームを含むパッケージをコンパイルするだけです。
TClientDataSet
aと a の両方をサブクラス化してみましたTEdit
。どちらも同じ動作を示します。
質問
標準コントロールを使用できるのに、パッケージ間でビジュアル フォームの継承を行うときに、サブクラス化されたコントロールを使用できないのはなぜですか?
問題を再現する手順:
- すべてのプロジェクト ファイルを保存できるフォルダーを作成する
- 以下に含まれる5 つのファイルのそれぞれについて、フォルダー内にファイルを作成します。
- Delphi を起動してすべてのファイルを閉じる
- 「ファイル | 新規 | その他 | Delphi プロジェクト | パッケージ」をクリックします。
- 手順 1 のパッケージを「Package1」としてフォルダーに保存します。
CDS2.pas
パッケージに追加1- Build Package1 (推奨パッケージを追加)
- Package1 をインストールします (TMyCDS を登録します)
BaseForm.pas
Package1 に追加 (推奨される VCL フレームワークを追加)- Package1 をビルド (推奨パッケージを追加)、再度ビルド
- 右クリック
ProjectGroup1
して、[新しいプロジェクトの追加 | Delphi プロジェクト | パッケージ] を選択します。 - 手順 1 のフォルダーに新しいパッケージを「Package2」として保存します。
SecondFrame.pas
Package2 に追加 (推奨される VCL フレームワークを追加)- Package2 をビルド (推奨パッケージを追加)
- デザイン モードで表示
SecondFrame
します (例: F12 を押します)。 - すべての変更を保存します (Delphi がクラッシュしそうなので、プロジェクト グループを含めます)。
SecondFrame
をデザイン モードで表示しながら、 Package1をビルドします。
ビルドが失敗し、次のエラーが発生します。
[DCC Error] E2161 Error: RLINK32: Error opening file "C:\[folder]\BaseFrame.dfm"
手順 17 でビルドする代わりにコンパイルすると、多くの場合エラーなしでコンパイルされます。ただし、デザイン モードで再表示しようとすると、次のエラーが発生することがあります。SecondFrame
Access violation at address 5003C976 in module 'rtl160.bpl'. Read of address FFFFFFC4.
[5003C976]{rtl160.bpl } System.GetDynaMethod (Line 13480, "System.pas" + 7) + $0
[500ADE1D]{rtl160.bpl } System.Classes.IsDefaultObjectProp (Line 9525, "System.Classes.pas" + 9) + $B
[500AE2C1]{rtl160.bpl } System.Classes.IsDefaultPropertyValue (Line 9651, "System.Classes.pas" + 29) + $A
[500AECA7]{rtl160.bpl } System.Classes.TWriter.WriteProperty (Line 9893, "System.Classes.pas" + 12) + $7
[5044739A]{vcl160.bpl } Vcl.Forms.TScrollingWinControl.IsTouchPropertyStored (Line 3200, "Vcl.Forms.pas" + 1) + $4
[503432C6]{vcl160.bpl } Vcl.Controls.TCustomTouchManager.IsTabletOptionsStored (Line 17359, "Vcl.Controls.pas" + 1) + $9
[500AE08D]{rtl160.bpl } System.Classes.IsDefaultMethodProp (Line 9606, "System.Classes.pas" + 4) + $4
[500AE0ED]{rtl160.bpl } System.Classes.IsDefaultMethodProp (Line 9609, "System.Classes.pas" + 7) + $24
[500AE2CC]{rtl160.bpl } System.Classes.IsDefaultPropertyValue (Line 9653, "System.Classes.pas" + 31) + $A
[5033A7E9]{vcl160.bpl } Vcl.Controls.TWinControl.GetChildren (Line 12359, "Vcl.Controls.pas" + 1) + $3
[5003C9A6]{rtl160.bpl } System.@CallDynaInst (Line 13519, "System.pas" + 4) + $0
[50447AE1]{vcl160.bpl } Vcl.Forms.TCustomFrame.GetChildren (Line 3450, "Vcl.Forms.pas" + 6) + $6
[500AD658]{rtl160.bpl } System.Classes.TWriter.WriteData (Line 9270, "System.Classes.pas" + 54) + $2
[500B4423]{rtl160.bpl } System.Classes.TComponent.ValidateRename (Line 12845, "System.Classes.pas" + 0) + $F
[500AD317]{rtl160.bpl } System.Classes.TWriter.WriteComponent (Line 9200, "System.Classes.pas" + 20) + $9
[500AD761]{rtl160.bpl } System.Classes.TWriter.WriteFloat (Line 9298, "System.Classes.pas" + 1) + $3
[20FEC1AB]{designide160.bpl} ComponentDesigner.TComponentRoot.CreateRootInstance (Line 2288, "ComponentDesigner.pas" + 24) + $7
[20FEBFD7]{designide160.bpl} ComponentDesigner.TComponentRoot.CreateRootAs (Line 2255, "ComponentDesigner.pas" + 2) + $4
[20FEBEFA]{designide160.bpl} ComponentDesigner.TComponentRoot.CreateFromStream (Line 2235, "ComponentDesigner.pas" + 7) + $9
[20FEEF41]{designide160.bpl} ComponentDesigner.TComponentRoot.Resurrect (Line 3434, "ComponentDesigner.pas" + 11) + $6
[2104F16E]{designide160.bpl} EmbeddedDesignerForm.TFormEditorView.Display (Line 144, "EmbeddedDesignerForm.pas" + 4) + $5
[2075E399]{coreide160.bpl} EditorForm.TEditWindow.ShowView (Line 4294, "EditorForm.pas" + 49) + $F
[20758D44]{coreide160.bpl} EditorForm.TEditWindow.SwitchViews (Line 2147, "EditorForm.pas" + 6) + $9
[2075889A]{coreide160.bpl} EditorForm.TEditWindow.ViewBarChange (Line 1996, "EditorForm.pas" + 2) + $1
[504C0F8D]{vcl160.bpl } Vcl.Tabs.TTabSet.CanChange (Line 1910, "Vcl.Tabs.pas" + 3) + $9
[504C0FDE]{vcl160.bpl } Vcl.Tabs.TTabSet.SetTabIndex (Line 1921, "Vcl.Tabs.pas" + 5) + $0
[504C126A]{vcl160.bpl } Vcl.Tabs.TTabSet.MouseDown (Line 2033, "Vcl.Tabs.pas" + 6) + $2
[50332E54]{vcl160.bpl } Vcl.Controls.TControl.DoMouseDown (Line 7343, "Vcl.Controls.pas" + 7) + $2B
[50332EA3]{vcl160.bpl } Vcl.Controls.TControl.WMLButtonDown (Line 7354, "Vcl.Controls.pas" + 7) + $E
[5033280D]{vcl160.bpl } Vcl.Controls.TControl.WndProc (Line 7204, "Vcl.Controls.pas" + 91) + $6
[5033715B]{vcl160.bpl } Vcl.Controls.TWinControl.WndProc (Line 9976, "Vcl.Controls.pas" + 152) + $6
[5003D4F7]{rtl160.bpl } System.TMonitor.TryEnter (Line 14786, "System.pas" + 10) + $0
[5003D06C]{rtl160.bpl } System.TMonitor.Enter (Line 14489, "System.pas" + 4) + $2
[5003CF10]{rtl160.bpl } System.TMonitor.CheckOwningThread (Line 14411, "System.pas" + 2) + $0
[5003D216]{rtl160.bpl } System.TMonitor.Exit (Line 14600, "System.pas" + 9) + $7
[5003D24F]{rtl160.bpl } System.TMonitor.Exit (Line 14614, "System.pas" + 2) + $7
[50313627]{vcl160.bpl } Vcl.Graphics.FreeMemoryContexts (Line 7043, "Vcl.Graphics.pas" + 12) + $8
[503367B0]{vcl160.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 9689, "Vcl.Controls.pas" + 3) + $6
[503367C5]{vcl160.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 9692, "Vcl.Controls.pas" + 6) + $0
[503369F0]{vcl160.bpl } Vcl.Controls.TWinControl.IsControlMouseMsg (Line 9753, "Vcl.Controls.pas" + 9) + $25
[5033715B]{vcl160.bpl } Vcl.Controls.TWinControl.WndProc (Line 9976, "Vcl.Controls.pas" + 152) + $6
[503367B0]{vcl160.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 9689, "Vcl.Controls.pas" + 3) + $6
[500B6030]{rtl160.bpl } System.Classes.MakeObjectInstance (Line 13921, "System.Classes.pas" + 0) + $0
[504525E7]{vcl160.bpl } Vcl.Forms.TApplication.ProcessMessage (Line 10164, "Vcl.Forms.pas" + 23) + $1
[5045262A]{vcl160.bpl } Vcl.Forms.TApplication.HandleMessage (Line 10194, "Vcl.Forms.pas" + 1) + $4
[5045295D]{vcl160.bpl } Vcl.Forms.TApplication.Run (Line 10331, "Vcl.Forms.pas" + 26) + $3
どのようなエラーが発生するかに関係なく、他のほとんどのことをしようとすると、Delphi はさまざまなランダムアクセス違反をスローします。エラーを閉じた後、Delphi を閉じます。次に、タスク マネージャーを使用して BDS.EXE を強制終了します (多くの追加の A/V エラーを回避するため)。
次のようにDelphiをデバッグしてみました:
デバッグ:
- Delphi を再起動する
SecondFrame
開いていないことを確認してください- Package1 を削除/再インストールして再構築する
- Package1 をダブルクリックしてアクティブなプロジェクトにします
- デバッグ ホスト アプリケーションを Delphi に設定します ( C:\[path]\RAD Studio\9.0\bin\bds.exe ) 。
- デバッグ (F9) を使用して Package1 を実行します。
- Delphi が 2 回目に開いたら(2 回目のインスタンスで)、プロジェクト グループが開いていることを確認してから開きます。
SecondFrame
SecondFrame
がデザイン モードであることを確認し (たとえば、F12 キーを押す)、 Package1をコンパイルします。
Delphi の最初のインスタンスが、2 番目のインスタンスで発生した例外をトラップする場合とトラップしない場合があります。その場合、例外とスタック トレースは次のようになります。
First chance exception at $5003C97D. Exception class $C0000005 with message 'access violation at 0x5003c97d: read of address 0x00000001'. Process bds.exe (8912)
:5003c97d GetDynaMethod + $D
:20fd45a6 TPairings.AddChildren + $46
:20fd4351 TPairing.SetComponent + $2D
:20fed656 TComponentRoot.GetRootStream + $5E
:20ff9d26 TRootStream.Create + $7A
:20ff2704 TComponentRoot.FormFileOpen + $14
:21b4231b ; C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\bin\delphicoreide160.bpl
:204e7a1e ; C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\bin\coreide160.bpl
:20614f2f ; C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\bin\coreide160.bpl
:206150f9 ; C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\bin\coreide160.bpl
:20615173 ; C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\bin\coreide160.bpl
:066d1339 ; C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\bin\dcc32160.dll
:1ac81dea ; C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\bin\RLINK32.DLL
:2a242a24
.
上記の問題を再現する手順で使用する 5 つのファイルは次のとおりです。
BaseFrame.dfm
object BaseFrameClass: TBaseFrameClass
Left = 0
Top = 0
Width = 320
Height = 240
TabOrder = 0
object MyCDS1: TMyCDS
Aggregates = <>
Params = <>
Left = 8
Top = 8
end
end
BaseFrame.pas
unit BaseFrame;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Data.DB, Datasnap.DBClient, CDS2;
type
TBaseFrameClass = class(TFrame)
MyCDS1: TMyCDS;
end;
implementation
{$R *.dfm}
end.
CDS2.pas
unit CDS2;
interface
uses
System.SysUtils, System.Classes, Data.DB, Datasnap.DBClient;
type
TMyCDS = class(TClientDataSet)
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Test', [TMyCDS]);
end;
end.
SecondFrame.dfm
inherited SecondFrameClass: TSecondFrameClass
end
SecondFrame.pas
unit SecondFrame;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, BaseFrame, Data.DB, Datasnap.DBClient, CDS2;
type
TSecondFrameClass = class(TBaseFrameClass)
end;
implementation
{$R *.dfm}
end.