小编Car*_*sen的帖子

如何从Delphi的开放工具API中检索新的单元名称

我在Delphi XE中编写了一个向导,它工作正常.但是,我还没有想出如何访问Delphi的OTA可以创建的生成的默认单元名称(或表单名称或项目名称).

在我的旧式向导中,我能够调用ToolServices.GetNewModuleName来发现在生成关联源文件时可以使用的可用单元和表单名称.今天的开放式工具API中的等价物是什么?

根据ToolsAPI单元注释,我应该从IOTAModuleCreator.GetImplFileName方法返回一个空白,让Delphi生成文件名.我从这个方法返回一个空字符串,但仍然无法看到我可以访问Delphi正在生成的文件名.

delphi wizard opentools delphi-xe

6
推荐指数
1
解决办法
809
查看次数

Indy TIdTCPClient 组件偶尔不超时且不接收数据

我正在使用 Internet Direct TIdTCPClient 组件与远程服务进行通信,以检索通常约为 5k 大小的消息。在典型的操作中,我会向服务发送大约 400 个请求,每个请求大约需要 1 秒才能完成。大多数时候一切正常。但是,大约有 1% 的时间请求需要 189 秒,而我根本没有收到任何数据。为了便于讨论,我将其称为失败。

我特别有兴趣了解发生故障时究竟发生了什么,以便我可以将我的证据提交给服务的发布者。首先,失败是不可重现的。如果我重新发送失败的请求,它很有可能(可能是 99%)会起作用。

我还捕获了发生故障时发送的请求,因此我能够确认请求格式正确。

我假设在失败期间我得到了一些数据,而不是全部。这是为什么。我的 IdTCPClient 有 30 秒的超时时间(我什至将其设置为 5 秒,但这并没有什么区别)。发生故障时,总是在 189 秒(加上大约 500 毫秒)后发生故障。

因此,我认为在发生故障期间,我的组件正在接收少量数据,这就是我的客户端没有超时的原因。而且,我假设服务断开连接,因为我的超时值都没有设置为 189 秒。另一方面,读取 IOHandler.AllData 不会引发异常(甚至不是 EIdConnClosedGracefully 异常)。我是否正确解释了这个证据?

我想要做的是在服务终止连接之前确认我正在获取一些数据,而不是全部数据。此外,我想知道部分数据是什么样的,因为我相信它可以帮助确定失败的根源。

目前,我的请求类似于以下内容:

//ExceptionName is a temporary global variable
//that I am using while trying to solve this issue
ExceptionName = 'no exception';
try
  s := GetRequest(id);
  IdTcpClient1.Host := Host;
  IdTcpClient1.Port := StrToInt(Port);
  IdTcpClient1.ReadTimeout := ReadTimeout;
  try
    IdTcpClient1.Connect;
  except
    on e: exception do
    begin
      ExceptionName …
Run Code Online (Sandbox Code Playgroud)

delphi tcp indy

6
推荐指数
1
解决办法
3152
查看次数

如何允许Delphi XE2从运行Windows 7的VirtualBox VM中查看Mac上的共享文件夹

我在MacBook Air上运行VirtualBox(最新版本,4.1.4)下的Windows 7 64位Ultimate.我在Mac上的用户文件夹下创建了一个共享文件夹.我已将此文件夹的读/写权限授予我的帐户.(我还为每个人配置了读/写访问权限,这没有什么区别.)

在VirtualBox下的Windows 7中,我已将该文件夹添加为共享文件夹.

在我的Windows 7 VM中,我可以使用Windows资源管理器查看此文件夹,在其中创建新文件夹和文件,以及读取文件夹和文件.

问题出在Delphi XE2上.如果我尝试打开项目或将项目保存到此共享文件夹,则从"保存"对话框中显示共享(我当前已映射到网络驱动器),并带有一个红色的X图标,表示它有问题.如果我单击此文件夹,Delphi将显示一个标题为"恢复网络连接"的对话框和一条消息"重新连接E:发生错误到\ VBOXSVR\Demos VirtualBox共享文件夹:请求不受支持.此连接没有已经恢复."

我无法在该共享文件夹中保存项目,这使我无法使用Delphi的dpr2xcode.exe实用程序轻松创建iOS应用程序并生成必要的Xcode文件夹.我需要做的是在本地创建项目文件夹,运行dpr2code.exe以生成Xcode项目,然后使用Windows资源管理器将本地文件夹的内容复制到共享文件夹,然后我可以在其中加载生成的在Xcode中编译,编译并运行它.

有谁知道我可以采取任何配置或步骤,以允许Delphi将共享文件夹视为有效文件夹?

为了记录,我在其他版本的Delphi中看到了与在Windows 7主机下运行的VMWare Workstation(8.0)中的Delphi安装的文件夹类似的问题.在这些情况下,Delphi根本不显示共享文件夹.

delphi macos virtualbox windows-7-x64 delphi-xe2

6
推荐指数
1
解决办法
896
查看次数

当RowCount> VisibleRowCount没有选择网格的第一行时,DBGrid的最顶行中会出现什么数据集行?

当底层数据集中的记录数大于时,是否可以从DBGrid的最顶行中获取从基础数据集显示的行号,而不是最顶行是当前选定的行. DBGrid中显示的行数,并且已滚动DBGrid.

这是我的问题.从附加到DBGrid的拖放事件处理程序,我可以使用MyGrid.MouseCoord(X,Y).Y确定drop事件与DBGrid的哪个可见行相关联.当基础数据集包含的记录数小于或等于DBGrid中显示的行数时,此值也是基础数据集中关联记录的行号.

当基础数据集包含的记录多于DBGrid中可见行数时,MyGrid.MouseCoord(X,Y).Y和TDataSet(MyGrid.DataSource.DataSet).RecNo仅在数据集的第一行出现时相同在网格的第一行.

有没有办法在没有选择DBGrid行的情况下识别DBGrid中最顶层显示记录的基础数据集(或偏移量)中的记录号?我知道如果我实际上选择了DBGrid的最顶行,那么我可以使用TDataSet(MyGrid.DataSource.DataSet).RecNo来获取底层数据集的当前记录号.但是,从DBGrid.OnDragOver或DBGrid.OnDragDrop事件我只有DBGrid和鼠标坐标的引用(我可以从中确定网格的哪一行是放置的目标).

例如,如果我可以确定DBGrid在网格的最顶行中的基础数据集中显示第三条记录,我的问题就解决了.同样,如果我可以读取特定行的底层TField(例如,最顶行)而没有选择该行,我就拥有了我需要的东西.但是,我看不到这样做的方法.

任何建议将不胜感激.

编辑:我之前发布了一篇关于拖放到DBGrid的博客.有了这个新信息,我可以解决以前已知的问题.我将在本周的某个时候更新该博客,并且一旦我这样做,就会在这里添加一个指向该博客的链接.

还有一个问题.当可见行的数量小于基础记录的数量时,我们还需要计算在最后一个可见行之后发生的下降.在最后一个可见行之后删除时,MouseCoord(x,y).Y返回-1.

以下是对Uwe代码的修改,以实现这一目的:

function TDBGridHelper.RecNoFromVisibleRow(Value: Integer): Integer;
begin
  if Value = -1 then
  begin
    Result := DataSource.DataSet.RecNo - Row + TopRow + VisibleRowCount
  end
  else
  begin
    Result := DataSource.DataSet.RecNo - Row + TopRow + Value;
    if dgTitles in Options then
      Dec(Result);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

编辑:正如我在原始问题中提到的,我对这个答案很感兴趣,以便修复我的代码中实现拖放到DBGRid中的行为.有了这个答案,我已经更新了我的拖放行为,我在博客中写过这个更新.您可以在以下URL找到此讨论,包括原始博客文章的链接:拖放到DBGrid中重新访问

delphi dbgrid tdataset

6
推荐指数
1
解决办法
3702
查看次数

如何在Delphi DataSnap REST服务器上映射自定义HTTP方法前缀

使用Delphi的DataSnap创建的RESTful服务基于HTTP方法类型为DataSnap服务器中公开的REST方法提供了前缀的默认映射.这些如下:

HTTP Method type   Prefix       Example
GET                none         MyValue
POST               Update       UpdateMyValue
PUT                Accept       AcceptMyValue
DELETE             Cancel       CancelMyValue
Run Code Online (Sandbox Code Playgroud)

文档声明"可以覆盖映射模式.用户可以根据类名和方法名参数覆盖每种类型的映射." 但是,我完全没有找到有关如何执行此操作的任何文档.我想将PUT的前缀从Accept更改为其他内容.我怎么做?

我应该注意到,StackOverflow上的另一个帖子(REST Datasnap覆盖URI映射)试图通过指出TDSHTTPService具有执行此映射的方法来回答这个问题.同一篇文章还引用了MarcoCantù的DataSnap白皮书,该白皮书据说也描述了如何做到这一点.该白皮书说:"您可以通过处理DSHTTPWebDispatcher组件的四个相应事件处理程序来自定义这些映射."

在RAD Studio XE中,TDSHTTPService和TDSHTTPWebDispather组件都有四个特定事件,对应于上面列出的四种HTTP方法,并且用于映射前缀.XE2及更高版本中不存在这些方法.

delphi rest datasnap delphi-xe delphi-xe7

6
推荐指数
1
解决办法
1450
查看次数

为什么TForm.SetBounds仅在设计时将TForm.Position设置为poDefault时才能正常工作

我注意到一些非常奇怪的事情.我在表单关闭时保持表单的top,left,width和height属性,并使用此信息通过使用以前存储的信息调用SetBounds再次打开表单时恢复表单的最后位置.这很有效,但前提是表单的Position属性在设计时设置为poDefault.如果设置为其他内容,例如poDesigned,poScreenCenter或poMainFormCenter,则SetBounds不会恢复表单的先前位置和大小.

这是奇怪的部分.看似重要的是在设计时将Position属性设置为什么.我可以在运行时将此属性的值更改为poDefault,并且对SetBounds的调用仍然无法正常工作.我尝试过类似下面的内容

if Self.Position <> poDefault then
  Self.Position := poDefault;
Run Code Online (Sandbox Code Playgroud)

在表单的OnCreate事件处理程序中,以及从重写的构造函数(并在构造函数中将Position设置为poDefault,并在OnCreate事件处理程序中调用SetBounds).在所有情况下,在运行时将表单的Position属性更改为poDefault并不能解决我在SetBounds中观察到的问题.我发现的唯一一致模式是SetBounds只有在设计时表单的Position属性为poDefault才能正常工作.

当表单的Position属性在设计时未设置为poDefault时,还有其他一些我注意到SetBounds的工作原理.例如,如果调用SetBounds,则在设计时将Position属性设置为poScreenCenter的表单不一定会显示在屏幕的中心.但是,它不会出现在由SetBounds定义的左上角位置,也不会出现在调用SetBounds时指定的宽度和高度.但是,让我重复一遍,我在调用SetBounds之前将表单的Position属性设置为poDefault.我甚至在两个操作之间调用了Application.ProcessMessages,但这并没有解决问题.

我已经在Windows 10上运行Delphi 10.1 Berlin进行了广泛的测试.我还在Windows 7上使用Delphi XE6对其进行了测试.结果相同.

如果您有疑问,请创建一个包含四种表单的VCL应用程序.在第一个表单上放置三个按钮,并为每个按钮添加如下OnClick:

 with TForm2.Create(nil) do
 try
   ShowModal;
 finally
   Release;
 end;
Run Code Online (Sandbox Code Playgroud)

构造函数创建TForm2,然后TForm3和TForm4.

在表单2到4的OnCreate上,添加以下代码:

if Self.Position <> poDefault then
  Self.Position := poDefault;
Self.SetBounds(500,500,500,500);
Run Code Online (Sandbox Code Playgroud)

在form2上,将Position设置为poDefault,在form3上将Position设置为poScreenCenter,并在form4上将Position设置为默认值poDefaultPosOnly.只有form2将出现在500,500,宽度为500,高度为500.

有没有人对这个结果有合理的解释?

delphi position tform setbounds

6
推荐指数
1
解决办法
951
查看次数

Delphi 2007 for .NET中的"无法启动调试...无法附加到ASP.NET辅助进程"消息

我已经看了很久了,最后决定把问题放在这里.我有一些我需要维护的应用程序是用Delphi 2007 for .NET(ASP.NET 2.0)编写的.通常,我第一次运行应用程序(使用IIS)时,我得到了经典的"无法在Web服务器上启动调试.无法附加到ASP.NET工作进程"消息.我只需按F9(运行)再次运行.有时我必须尝试运行几次才能实际运行.

我正在运行Windows 7 64位(并且在Vista 64位上看到了相同的效果).我确实为ASP.NET配置了IIS,并且我的Web.config文件中有以下代码.

  <system.webServer>
      <modules>
         <add name="DbgConnect" type="Borland.DbkAsp.DbkConnModule,Borland.dbkasp,Version=10.5.0.0,
           Culture=neutral, PublicKeyToken=b0524c541232aae7" preCondition="managedHandler" />
      </modules>
      <validation validateIntegratedModeConfiguration="false" />
  </system.webServer>
Run Code Online (Sandbox Code Playgroud)

关键是我最终可以在调试器中运行应用程序,有时甚至是第一次尝试.很多时候,当我遇到故障时,它会在我按下Run后大约15秒左右发生,有时甚至在我点击一两页(或三个)Web应用程序之后.并且,是的,当Delphi进入这种模式时,我可以简单地运行而无需调试,一切都很好(除非我真的想调试).并且,我可以继续尝试在调试器中运行,最终它将正常工作.

似乎Delphi的.NET调试器在某种程度上得到了应用程序无法运行的想法,然后放弃并停止进程(正如我所提到的那样,有时候显然正在运行).

我知道其他开发者也看到了这种行为.我的问题是,有谁知道如何阻止这种烦人的行为?

asp.net delphi delphi.net delphi-2007

5
推荐指数
1
解决办法
1198
查看次数

Delphi DataSnap授权不会检查TRoleAuth属性

我正在尝试在Delphi XE DataSnap应用程序中实现授权.我将其分解为一个非常简单的示例,但仍然没有看到TRoleAuth属性对方法或类的影响.

这是一个简单的DSServerMethods类,它包含生成的示例方法.该课程已经装饰了客人和任何授权角色,以及不受欢迎的拒绝角色.ReverseString方法已使用readonly denied角色进行修饰:

type
  [TRoleAuth('guest,anyone','unwelcome')]
  TMyDSServerMethods = class(TDSServerModule)
    DataSetProvider1: TDataSetProvider;
  ...
  public
    { Public declarations }
    function EchoString(Value: string): string;
    [TRoleAuth('','readonly')]
    function ReverseString(Value: string): string;
    ...
  end;
Run Code Online (Sandbox Code Playgroud)

我在OnUserAuthenticate方法上分配角色.例如,我有一个用户,我将从OnUserAuthenticate中分配readonly角色,我相信该角色应该拒绝用户执行ReverseString函数的权限.

根据我的理解,我的代码应该将用户的角色与TDSAuthenticationManager的OnUserAuthorize方法中的EventObject.AuthorizedRoles和EventObject.DeniedRoles TStrings进行比较,并相应地设置此方法的有效形​​式参数.

这是我用于测试的简单OnUserAuthorize方法.当我使用调试器进入它以响应具有尝试调用ReverseString的只读角色的用户时,EventObject.AuthorizedRoles和EventObject.DeniedRoles都是nil,并且EventObject.Roles包含只读角色.

procedure TServerContainer1.DSAuthenticationManager1UserAuthorize(
  Sender: TObject; EventObject: TDSAuthorizeEventObject;
  var valid: Boolean);
begin
  outputdebugstring(PChar(Eventobject.UserName));
  if EventObject.UserRoles <> nil then
    outputdebugstring(PChar(eventobject.UserRoles.Text));
  if EventObject.AuthorizedRoles <> nil then
    outputdebugstring(PChar(eventobject.AuthorizedRoles.Text));
  if EventObject.DeniedRoles <> nil then
    outputdebugstring(PChar(eventobject.DeniedRoles.Text));
  valid := True;
end;
Run Code Online (Sandbox Code Playgroud)

我是否遗漏了这一点,或者是否需要设置某个属性以使TRoleAuth属性起作用?

= = = = = = = = = =编辑:Mat DeLong提供了答案.DSAuth单元(声明TRoleAuth自定义属性类)在定义了DSServerModule后代的单元的接口部分中丢失.

delphi authorization datasnap delphi-xe

5
推荐指数
1
解决办法
1827
查看次数

如何从外部查看器调试器可视化工具获取对象或其数据的引用?

我正在尝试为 TJSONObject 或 TJSONValue 编写调试器可视化工具。我的大部分可视化工具都运行良好。我遇到的问题是获取对 TJSONObject 的引用,或者至少是对 TJSONObject 的 tostring() 值的引用。

根据我看到的示例,以及 Jeremy North 在http://edn.embarcadero.com/article/40268上发表的精彩帖子,我应该从 IOTADebuggerVisualizerExternalViewer 实现的 Show 方法中获得我需要的内容。具体来说,来自 Expression、TypeName 和 EvalResult 字符串参数。

据我了解,Expression 是被检查(可视化)的变量的名称,TypeName 是变量的类名,EvalResult 是变量的默认字符串表示形式。

为了进行简单的测试,我在我的 TFrame 后代上放置了一个 TMemo。从 IOTADebuggerVisualizerExternalViewer.Show 方法中,我调用 TFrame 的 ShowJSONObject 方法,并向该方法传递 Expression、TypeName 和 EvalResult。相关代码出现在这里:

function TDebuggerJSONVisualizer.Show(const Expression, TypeName, EvalResult: string;
  SuggestedLeft, SuggestedTop: Integer): 
  IOTADebuggerVisualizerExternalViewerUpdater;
var
  AForm: TCustomForm;
  AFrame: TJSONViewerFrame;
  VisDockForm: INTACustomDockableForm;
begin
  VisDockForm := TJSONVisualizerForm.Create(Expression) as INTACustomDockableForm;
  AForm := (BorlandIDEServices as INTAServices).CreateDockableForm(VisDockForm);
  AForm.Left := SuggestedLeft;
  AForm.Top := SuggestedTop;
  (VisDockForm as IFrameFormHelper).SetForm(AForm);
  AFrame …
Run Code Online (Sandbox Code Playgroud)

delphi json debuggervisualizer delphi-2010 delphi-xe

5
推荐指数
1
解决办法
500
查看次数

如何在Windows 10上为IIS 10启用ISAPI DLL?

我已经为IIS 7.x配置了ISAPI DLL多年,但这是我第一次尝试使用Windows 10,但它无法正常工作,我找不到任何有关如何成功完成的说明.我在Windows 10 Professional中工作,并安装了IIS和支持技术.

这是我过去所做的.首先,我打开Internet Information Services Manager控制台.然后,我选择默认Web站点并打开Handler Mappings.我在"禁用"部分右键单击"ISAPI-dll",选择"编辑功能权限",然后在"执行"旁边选中复选标记.

由于我的ISAPI DLL是32位DLL,并且我运行的是Windows 10 64位专业版,因此​​我在"连接"窗格中选择"应用程序池",右键单击"DefaultAppPool",然后选择"高级设置",然后将"启用32位应用程序"设置为真正.

最后,我打开ISAPI和CGI限制小程序.然后,我右键单击ISAPI和CGI限制窗格并选择编辑功能设置,然后在"允许未指定的ISAPI模块"旁边放置复选标记.

Handler Mappings applet不再具有禁用的ISAPI-dll条目.但是,打开Handler Mappings小程序后,我可以选择编辑功能权限,并在Execute旁边放置一个复选标记.我已经能够在默认应用程序池中允许32位应用程序,但ISAPI和CGI限制小程序无处可寻.

最终的结果是,尽管我已经成功执行了如上所述的配置,但仍然无法运行我的ISAPI DLL.我已将DLL放在与Windows 7安装程序相同的位置(在c:\ inetpub\wwwroot\appfolder下),并使用相同的URL.它在Windows 7中运行,但在Windows 10中不运行.

如何在Windows 10中配置IIS以运行此ISAPI DLL?

isapi windows-10 iis-10

4
推荐指数
1
解决办法
2万
查看次数

在 Delphi 中,如何在基类及其后代类中启用方法指针属性

我想创建一个TService后代类,用作我的 Windows 服务实现的基础。在我的基类中,我引入了一个已发布的ServiceDescription属性,并且我正在使用AfterInstall事件处理程序将此描述写入 Windows 注册表中的适当位置。

请注意,由于TServer类(在 中声明Vcl.SvcMgr)是TDataModule后代,为了允许ServiceDescription属性在对象检查器中可见,有必要在设计时包中声明此基类,并使用对 的调用在 Delphi 中注册它RegisterCustomModule。此外,此基类的后代必须由 OTA(开放工具 API)向导或某种代码生成器(.pas 和 .dfm 文件)生成。没问题,我已经整理好了,如果您有兴趣,可以从 Marco Cantu 的书 ( http://www.marcocantu.com/ddh/ddh15/ddh15e.htm ) 中阅读更多相关信息。

我遇到的问题是我想使用AfterInstall基类中的事件处理程序写入注册表,然后将AfterUninstall其删除,但我想确保我的后代类也将支持AfterInstallAfterUninstall事件。

我之前从 Ray Konopka 那里了解到,如果你想重新引入一个属性,你必须在后代类中使用访问器方法。因此,这里是一个代码段,代表我针对AfterInstall事件执行此操作的尝试:

  private
    // field to store method pointer for the descendant AfterInstall event handler
    FFAfterInstall: TServiceEvent;
    …
  protected
    function GetAfterInstall: TServiceEvent;
    procedure SetAfterInstall( value: TServiceEvent );
    …
  published …
Run Code Online (Sandbox Code Playgroud)

delphi oop windows-services

4
推荐指数
1
解决办法
166
查看次数

如何识别在Delphi应用程序中最终确定期间抛出异常的位置?

我正在与客户进行现场工作,我正在努力帮助他们解决一个复杂的问题.我希望Delphi中有一个工具或功能,我们可以用它来查看内部工作,以帮助我们找到问题所在.

以下是我们正在处理的问题的高级概述.这是一个商业应用程序,目前部署在Delphi 5中.在过去的一年中,该应用程序已迁移到Delphi XE.迁移几乎完成,但遇到了一些严重的错误.

应用程序本身非常庞大,有数百个单元和许多第三方和自定义组件.在我们遇到的一个特定情况中,创建主窗体,然后在显示主窗体之前终止应用程序.结果是在终止期间发生崩溃,因为单元正在最终确定.

调试器正在破坏kernel32的RaiseException函数,该函数由NotifyNonDelphiException调用.我们尝试设置一个非破坏断点,从NotifyNonDelphiException中记录调用堆栈,但这并没有给我们任何有用的东西.调用堆栈仅包含处理异常的方法,即RtlRaiseStatus和KUserExceptionDispatcher.

我们如何识别抛出NotifyNonDelphiException正在处理的原始异常的代码?


编辑:这是在一个异常实例后捕获的两个图像.第一个是引发异常,第二个描述异常对话框关闭后的CPU窗口.

退出时访问冲突

关闭异常对话框时的CPU窗口

新编辑:

我发布这个问题已经有一个多星期了,各种答案给我留下了深刻的印象.对最初问题的一些评论是最有价值的,但是一些答案本身非常有用.

我对该客户的访问已经结束,我将要求他们考虑已在此处发布的答案.虽然我们无法追踪错误的实际来源,但错误的原因显而易见.多年来在没有严重重构的情况下对用户界面进行调整,使应用程序的登录过程不稳定.当用户取消登录时,主表单处于部分初始化状态.当不允许此过程运行时,这是用户中止登录时发生的情况,存在非常严重的终结问题.

该公司购买了AQTime Pro以帮助识别未来的问题,但需要重新设计登录过程,并且从长远来看将解决问题.

有一次,我考虑删除这个问题,但我选择保留它,因为我相信其他人会发现许多优秀的建议,这些建议已经发布了信息.

目前,我接受了@Deltics的答案,因为我讨厌在没有答案的情况下留下问题.但是,我要求这个问题的观众也考虑所有其他答案和评论,它们同样有价值.

delphi debugging kernel32 delphi-xe

3
推荐指数
1
解决办法
2445
查看次数