当我在我的应用程序中关闭表单时,我收到了访问冲突.它似乎只是在我访问数据库几次之后才会发生,但这似乎没有意义.
我已经跟踪并将outputdebugstring消息放在所有相关的OnDestroy()方法中,但AV似乎不在我的代码中.
这是消息的文本:
模块"MySoopaApplication.exe"中地址00405F7C的访问冲突.读取地址00000008.
如何找到应用程序00405F7C中的位置?
Delphi 10.1柏林有哪些工具可以帮助我解决这个问题?
编辑:添加了更多信息...当点击"Break"时,IDE总是带我到GETMEM.INC中的这段代码:
@SmallPoolWasFull:
{Insert this as the first partially free pool for the block size}
mov ecx, TSmallBlockType[ebx].NextPartiallyFreePool
Run Code Online (Sandbox Code Playgroud)
进一步编辑:好吧,我找到了罪魁祸首,虽然我不能老实说调试工具让我在那里 - 他们似乎只是表明它不在我的代码中.
我曾经使用网络中的代码来查找Windows登录用户 - 这就是:
function GetThisComputerName: string;
var
CompName: PChar;
maxlen: cardinal;
begin
maxlen := MAX_COMPUTERNAME_LENGTH +1;
GetMem(CompName, maxlen);
try
GetComputerName(CompName, maxlen);
Result := CompName;
finally
FreeMem(CompName);
end;
end;
Run Code Online (Sandbox Code Playgroud)
一旦我用简单的结果替换了代码:='12345'AV停止了.我没有改变它到这个代码:
function GetThisComputerName: string;
var
nSize: DWord;
CompName: PChar;
begin
nSize := 1024;
GetMem(CompName, nSize);
try
GetComputerName(CompName, nSize);
Result := CompName;
finally
FreeMem(CompName);
end;
end; …Run Code Online (Sandbox Code Playgroud) 我在表单上使用此代码在OnShow事件中创建了一个元素:
procedure TForm4.FormShow(Sender: TObject);
var
VertScrollLink:TVertScrollBox;
begin
VertScrollLink := TVertScrollBox.Create(form4);
VertScrollLink.Align := TAlignLayout.Client;
VertScrollLink.Parent := form4;
end;
Run Code Online (Sandbox Code Playgroud)
在某些操作上,我需要动态删除布局:
for LIndex := form4.ComponentCount-1 downto 0 do
begin
if (form4.Components[LIndex].ToString='TVertScrollBox') then
begin
//showmessage(form4.Components[LIndex].ToString);
form4.Components[LIndex].Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
此代码在Windows上运行良好,但不会删除Android上的任何内容.
delphi firemonkey delphi-xe7 delphi-10-seattle delphi-10.1-berlin
我有一个包含一些数字的字符串列表.我使用我写的冒泡排序对它们进行了排序.输出是:
18
20
3
44
53
Run Code Online (Sandbox Code Playgroud)
我不明白为什么上面输出而不是我的预期:
3
18
20
44
53
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
我需要使用RTTI遍历具有复杂结构的类.该类有几个记录成员,我也想迭代.
TRTTIHelpers<T> = class
public
class function DoGetValuesForClass(aClassInst: T): TStringList;
class function DoGetValuesForRecord(aRec: T): TStringList;
end;
Run Code Online (Sandbox Code Playgroud)
我知道当我在课堂上有一个成员时,这是一个记录:
for prop in rt.GetProperties() do
begin
if prop.PropertyType is TRttiRecordType then
begin
lValue := prop.GetValue(aInst);
Result.AddStrings(TRTTIHelpers<T>.DoGetValuesForRecord(TValue)); <--
end
Run Code Online (Sandbox Code Playgroud)
如何将TValue作为参数传递给DoGetValuesForRecord,以便我也可以遍历记录?
如果在Shift按下键的同时使用鼠标滚轮,我想实现水平滚动.但WM_MOUSEWHEEL在这种情况下我没有收到任何消息:
procedure WMMouseWheel(var Msg: TMessage); message WM_MOUSEWHEEL; // is not called
Run Code Online (Sandbox Code Playgroud)
根据文档,WPARAM 应该有一条WM_MOUSEWHEEL消息MK_SHIFT.
有任何想法吗?
尝试呼叫退出是否安全?或者我应该拨打加薪?
我尝试了下面的两个示例,并在举例中,跟踪通过Delphi的内部库代码.退出时只退出程序,仅此而已.
我读到最好保留应用程序堆栈或队列或类似的东西.调用exit会打破那个堆栈吗?
例1(加注)
SDDatabase1.StartTransaction;
Try
SDQuery1.ApplyUpdates;
SDDatabase1.Commit;
SDQuery1.CommitUpdates;
Except
SDDatabase1.Rollback;
SDQuery1.RollbackUpdates;
raise;
End;
..............//other codes I don't want to execute
Run Code Online (Sandbox Code Playgroud)
例2(退出)
SDDatabase1.StartTransaction;
Try
SDQuery1.ApplyUpdates;
SDDatabase1.Commit;
SDQuery1.CommitUpdates;
Except
SDDatabase1.Rollback;
SDQuery1.RollbackUpdates;
MessageDlg('Save Failed because: '+E.Message, mtError, [mbOK], 0);
exit;
end;
..............//other codes I don't want to execute
Run Code Online (Sandbox Code Playgroud) 正如MSDN的WOW64实现细节中所解释的那样,变量%PROGRAMFILES%,
在64位Windows操作系统上的32位进程中,解析为 C:\Program Files (x86)
在64位Windows操作系统上的64位进程中,解析为 C:\Program Files
您可以使用Delphi 10.1程序验证这一点,该程序使用32位Windows目标平台和64位Windows目标平台进行编译:
MyShellExecute('%PROGRAMFILES%');
Run Code Online (Sandbox Code Playgroud)
因此,从Windows-64bit-OS中执行的32位Delphi应用程序,我怎么能得到两个:
32位程序的ProgramFiles目录(C:\Program Files (x86))
64位程序(C:\Program Files)的ProgramFiles目录
创建Delphi VCL Forms应用程序并在表单上放置2 TButton和a TApplicationEvents:
然后插入这些事件处理程序:
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.AppEvnts;
type
TForm2 = class(TForm)
Button1: TButton;
Button2: TButton;
ApplicationEvents1: TApplicationEvents;
procedure ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
Screen.Cursor := crHelp;
end;
procedure TForm2.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
var
Target: TControl;
Point: TPoint; …Run Code Online (Sandbox Code Playgroud) 创建一个简单的VCL应用程序:
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TForm1 = class(TForm)
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
JclStringLists;
var
MyList1: TJclStringList;
MyList2: TJclStringList;
procedure TForm1.FormDestroy(Sender: TObject);
begin
MyList1.Free;
MyList2.Free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
MyList1 := TJclStringList.Create;
MyList2 := TJclStringList.Create;
MyList1.LoadFromFile('C:\ONE.txt');
MyList2.LoadFromFile('C:\TWO.txt');
Self.Caption := Self.Caption + ' ' + IntToStr(MyList1.Count);
Self.Caption := Self.Caption + ' ' + …Run Code Online (Sandbox Code Playgroud) 我的应用程序上的第三方组件(FastReports)广泛使用System.Variants.VarToWideStr函数,该函数很好,但它忽略了我需要该应用程序使用的区域设置。
例:
FormatSettings.ShortDateFormat := 'dd/mm/yyyy';
ShowMessage(VarToWideStr(Date));
FormatSettings.ShortDateFormat := 'yyyy/mm/dd';
ShowMessage(VarToWideStr(Date));
Run Code Online (Sandbox Code Playgroud)
此代码始终返回相同的字符串,而忽略了我指示要使用的应用程序的区域设置。
您是否知道另一种更改应用程序(具体是VarToWideStr)将要使用的区域设置的方法?