我一直在测试Delphi XE2附带的新的ODBC dbExpress驱动程序,并注意到TSQLMonitor似乎不起作用.考虑到我可能错误地配置了组件,我将TSQLMonitor连接到使用MS SQL dbExpress驱动程序的TSQLConnection,这就像魅力一样.
我在网上看不到关于这个问题的任何帖子.有没有人注意到这个问题?它是否是一个错误,一个不受支持的功能(在使用ODBC驱动程序的TSQLConnection上没有监视),或者在这种情况下配置TSQLMonitor是否有技巧?
这就是我想要做的.我有一个项目必须在某些版本的Delphi或更高版本中编译.我想使用条件编译器指令来测试Delphi版本,然后使用自定义消息生成自定义编译器错误.如果无法发生错误,能够生成自定义编译器警告或提示也是适当的.
当然,我可以在条件代码段中放入一些不可编辑的giberish,这很好.但我的问题是"我可以有条件地生成自定义编译器错误吗?"
谢谢Johan和Serg.
这是解决方案,以及有关该问题的更多详细信息.我有一个最初在Delphi 2007中构建的应用程序.它包括连接到Web服务的Internet Direct组件.这些使用SSL.我最近将我的SSL库升级到更高版本,而这些版本与Delphi 2007 Indy组件的搭配并不是很好.我现在添加了以下编译器指令,以确保不再使用Delphi 2007或更早版本编译此应用程序:
{$IF CompilerVersion <= 19.0} // Delphi 2007 = 19.0
{$MESSAGE Error 'This project must be compiled in Delphi 2009 or later'}
{$IFEND}
Run Code Online (Sandbox Code Playgroud) 我再次编写了一个外部调试器可视化工具,并且遇到了问题.调试器可视化工具可以返回的字符串大小似乎有限制.
Delphi 2010附带的TStrings调试器可视化器的限制为4K.在对Embarcadero新闻组发布的问题的回复中,Ewe Schuster 回答说"你可以稍微增加缓冲区,但AFAIR的实际限制是IOTAThread.Evaluate,限制大约12k字符."
我的调试器可视化器基于TStrings调试器可视化器的代码,我可以看到TFrame的Evaluate方法的实现包括ResultStr的以下声明,该声明用于返回从IOTAThread.Evaluate调用返回的字符串:
ResultStr: array[0..4095] of Char;
Run Code Online (Sandbox Code Playgroud)
我曾希望增加这个缓冲区的大小会有所帮助,但没有运气.
如果有的话,我可以做些什么来增加外部调试器可视化工具可以显示的字符串的大小?
我上周观察到了一些我没想到的事情,并将在下面描述.我很好奇为什么会这样.它是TDataSet类内部的东西,TDBGrid的工件还是别的东西?
打开的ClientDataSet中的字段顺序已更改.具体来说,我在使用FieldDefs定义其结构后通过调用CreateDatatSet在代码中创建了一个ClientDataSet.此ClientDataSet结构中的第一个字段是名为StartOfWeek的Date字段.不久之后,我编写的代码(假设StartOfWeek字段位于零位置,ClientDataSet.Fields [0])失败,因为StartOfWeek字段不再是ClientDataSet中的第一个字段.
经过一番调查后,我了解到ClientDataSet中的每个字段都可能在给定时刻出现在创建ClientDataSet时与原始结构不同的某个位置.我不知道这可能会发生,并且对谷歌的搜索也没有提到这种效果.
发生了什么不是魔术.这些字段本身并没有改变位置,也没有根据我在代码中所做的任何事情而改变.导致字段在物理上看起来改变ClientDataSet中位置的原因是用户已经更改了ClientDataSet附加到的DbGrid中的列的顺序(当然是通过DataSource组件).我在Delphi 7,Delphi 2007和Delphi 2010中复制了这个效果.
我创建了一个非常简单的Delphi应用程序来演示这种效果.它由一个包含一个DBGrid,一个DataSource,两个ClientDataSets和两个Buttons的表单组成.此表单的OnCreate事件处理程序如下所示
procedure TForm1.FormCreate(Sender: TObject);
begin
with ClientDataSet1.FieldDefs do
begin
Clear;
Add('StartOfWeek', ftDate);
Add('Label', ftString, 30);
Add('Count', ftInteger);
Add('Active', ftBoolean);
end;
ClientDataSet1.CreateDataSet;
end;
Run Code Online (Sandbox Code Playgroud)
Button1,标记为Show ClientDataSet Structure,包含以下OnClick事件处理程序.
procedure TForm1.Button1Click(Sender: TObject);
var
sl: TStringList;
i: Integer;
begin
sl := TStringList.Create;
try
sl.Add('The Structure of ' + ClientDataSet1.Name);
sl.Add('- - - - - - - - - - - - - - - - - ');
for i := 0 to ClientDataSet1.FieldCount - 1 do
sl.Add(ClientDataSet1.Fields[i].FieldName); …Run Code Online (Sandbox Code Playgroud) 我很高兴看到Delphi在Delphi 2009中引入TMonitor记录,允许您在多线程环境中锁定特定对象.令我困惑的是这种记录类型的Pulse和PulseAll方法.
例如,Delphi的Pulse中的条目帮助指出"通知等待队列中的下一个线程,一旦调用线程释放对象,它就能锁定指定的对象."
真?那是什么意思?我使用过TMonitor而没有使用Pulse而没有问题.此外,在Delphi的源代码中,TMonitor的一些用途从不使用Pulse.
Pulse和PulseAll方法是否仅包含在Delphi的TMonitor记录中,用于与.NET Monitor类的源级兼容性,还是它们真的有用?
有两个问题("TMonitor.Pulse与TMonitor.PulseAll"和"Delphi系统单元中的TMonitor是什么有利于")这个问题,但我正在寻找一个明确的答案.
根据"Delphi 2009中的新功能",有一种称为"等待链遍历"的新调试器功能.它特别说明了"添加了一个等待链遍历功能,以帮助您解决线程争用或死锁问题.该功能依赖于添加到Windows Vista操作系统的工具,该工具向调试器提供有关应用程序线程等待状态的信息.等待链的形式."
Delphi 2009在Windows Vista成为当前操作系统时发布.根据我的经验,Vista中引入的大多数功能也可以在Windows 7中使用.但是,我在Delphi 2009中通过Delphi XE安装(所有在Windows 7上)都没有看到此功能.
我在调试器的"线程"窗格中寻找此功能.
我在正确的地方寻找等待链遍历吗?
它是真正仅在Windows Vista中可用的功能,而不是在Windows 7中吗?
David M提供了一个清晰明确的答案,但我仍然没有在"线程"窗格中获得"等待链"列.这是一些代码.
主要表格:
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, SyncObjs, RanThread;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Button1: TButton;
Button2: TButton;
Label1: TLabel;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure ThreadDone(Sender: TObject);
end;
var
Form1: TForm1;
RanGenThread: TRandomizer;
implementation
uses LoadThread;
{$R *.dfm}
{ TForm1 }
procedure …Run Code Online (Sandbox Code Playgroud) 我一直在设计FireMonkey控件,但有一个问题我遇到了一些实际问题,那就是如何使用FireMonkey样式设计器(特别是Bitmap样式设计器)将位图合并到FireMonkey样式中.某些样式对象(例如,TButtonStyleObject)具有BitmapLink属性,但我无法看到它们如何在为FireMonkey控件生成的新自定义样式中工作.
让我试着让问题尽可能透明.我添加了一个样书并将其资源设置为Delphi样式目录中的MetropolisUIGreen.Style(在XE7中,它位于C:\ Users\Public\Documents\Embarcadero\Studio\16.0\Styles中).然后我打开FireMonkey样式设计器并找到按钮式样式,它由TButtonStyleObject和TButtonStyleTextObject组成,两者都是TLayout的父级.TButtonStyleObject的SourceLookup属性值为MetroGreenstyle.png,它是一个StyleName,与加载了MetropolisUIGreen.png图像的TImage相关联.
选择TButtonStyleObject(其StyleName为背景),我检查NormalLink属性,它是TBitmapLinks的集合.据我所知,我在NormalLink中定义的BitmapLink包含有关应该用于按钮的位图的信息,包括与MetroGreenstyle.png文件的矩形区域对应的坐标(SourceRect).
我的假设似乎是错误的,因为当我使用图形程序检查MetroGreenstyle.png时,这些坐标没有什么有趣的.我已经研究过的许多其他风格的BitmapLinks,有太多我发现,与sourceRect坐标似乎并不实际定义stylelookup png文件的有意义的区域.
我显然有这个错误.BitmapLink的SourceRect坐标如何定义FireMonkey在渲染控件时应使用的位图.
- 编辑我实际问了四个问题.我已将此问题更新为仅包含一个问题.我将在其他帖子中包含其他问题. -
有没有办法从Delphi 5中编写的ActiveX dll创建MDI子窗口,并将其嵌入从Delphi XE Windows客户端应用程序创建的MDI父窗口中?如果没有,有没有办法模仿这种行为?
背景
有一个完全用Delphi 5编写的应用程序.该应用程序的主要形式是MDI父窗口.应用程序中的所有其他表单都是MDI子表单,并且每个表单都是从ActiveX库创建的.父应用程序创建ActiveX,之后调用ActiveX接口的方法.从这个方法创建一个表单,它的FormStyle设置为fsMDIChild.此时,表单是MDI父级的MDI子级.这是有效的,因为应用程序和ActiveX库都是使用运行时包编译的.因此,所有表单共享相同的TApplication实例.
问题
该应用程序非常庞大,需要迁移到Delphi 2010或Delphi XE.如果可以系统地迁移应用程序,首先迁移应用程序,然后一次迁移一个ActiveX库(其中大约有50个),这将是非常棒的.
问题是,如果控制台应用程序是在XE中编译的,它将不再使用与仍在Delphi 5中编译的库相同的TApplication实例.
即使ActiveX库中的表单不能是真正的MDI子窗口,似乎我应该能够返回从ActiveX创建的表单的句柄并从主窗体中获取它并使表单看起来像是MDI孩子.然后我可以创建自己的图层来处理事件.
有任何想法吗?
更新:此应用程序当前采用的方法是将其从MDI迁移到SDI接口.完全可以从Delphi XE应用程序中的Delphi 5 ActiveX DLL实例化TForms,只要每个DLL的第一个表单可以处理它自己的数据(加载,保存,显示其他表单等).问题在于保持原始的MDI设计.如果SDI设计被证明是可接受的,则不需要MDI解决方案.不过,如果有人知道如何完成MDI解决方案,我想知道.
似乎没有办法使用DataSnap 实现JSONP(带填充的JSON)解决方案,但我想在这里抛出这个问题以防有人解决了这个问题.
背景:JSONP是一种利用HTML脚本元素的跨站点引用功能来克服XmlHttpRequest类的相同原始策略的机制.使用XmlHttpRequest,您只能从提供HTML文档的同一域中获取数据(JSON对象).但是,如果您想从多个站点检索数据并将该数据绑定到浏览器中的控件,该怎么办?
使用JSONP,脚本元素的src属性不引用JavaScript文件,而是引用Web方法(可以驻留在检索HTML的不同域上的方法).此Web方法返回JavaScript.
脚本标记假定返回的数据是JavaScript文件并正常执行.但是,Web方法实际返回的是一个函数调用,其中有一个文字JSON对象作为其参数.假设已定义调用的函数,该函数将执行并可对JSON对象进行操作.例如,该函数可以从JSON对象中提取数据并将该数据绑定到当前文档.
JSONP的优点和缺点已被广泛争论(它代表了一个非常严重的安全问题),因此没有必要在此重复.
我感兴趣的是,如果有人知道如何将JSONP与Delphi的DataSnap REST服务器一起使用.正如我所看到的,这就是问题所在.典型的JSONP用法可能包含一个类似于以下内容的脚本标记:
<script type="application/javascript" src="http://someserver.com/getdata?callback=workit"> </script>
Run Code Online (Sandbox Code Playgroud)
getdata Web方法将返回如下所示的调用:
workit({"id": "Delphi Pro", "price":999});
Run Code Online (Sandbox Code Playgroud)
而workit函数可能看起来像这样:
function workit(obj) {
$("#namediv").val(obj.id);
$("#pricediv").val(obj.price);
}
Run Code Online (Sandbox Code Playgroud)
问题是DataSnap似乎不能返回像这样的简单字符串
workit({"id": "Delphi Pro", "price":999});
Run Code Online (Sandbox Code Playgroud)
相反,它被包装,如下所示:
{"result":["workit({\"id\":\"Delphi Pro\",\"price\":999});"]}
Run Code Online (Sandbox Code Playgroud)
显然这不是可执行的JavaScript.
有任何想法吗?
这似乎是一个非常简单的问题,但我无法使用滚动条来显示滚动条,这让我发疯.
情况就是这样.我需要在表单的一部分中显示可变数量的帧.可以通过TSplitter或通过调整表单大小来调整显示这些帧的区域.
我在创建表单时根据数据库中的记录动态生成帧.这些框架是FlowPanel的父级,它负责框架放置.FlowPanel位于ScrollBox中.
由于FlowPanel,当用户使用TSplitter或调整表单大小时,帧可能会重新对齐.如果任何框架重新定位在窗体的视图之外,我希望ScrollBox显示滚动条,以便用户可以向下滚动到那些不可访问的框架.这不会发生.位于滚动框尺寸之外的流动板区域中的那些框架是不可访问的.
我在滚动框中使用简单对象构建了一些测试,如果任何包含的对象出现在滚动框的维度之外,则滚动框会正确放置滚动条.
如果流动板与clClient(滚动框)对齐或锚定到滚动框的两侧,或者没有这些都没有关系.
我意识到我可以使用TPanel,并在面板的OnResize事件处理程序的代码中执行框架的放置和重新定位,但这就是FlowPanel的用途.
这里发生了什么?我已经摆弄了许多不同的滚动条属性,仍然无法让它工作.问题是什么,有解决方案吗?
好.我选择Ewe的答案是正确的,但是做这项工作的诀窍在于他的一个评论,我仍然没有对结果感到满意.
这是独家新闻.我确实按照Ewe建议的方式配置了我的ScrollBox和FlowPanel,但是使用了许多其他设置,因为该配置不起作用.我很确定这是由于表单的用户界面的复杂性,它在面板中有许多面板,许多分割器,并且表单本身是PageControl的TabSheet的父级(我省略了这个事实,因为测试表格作为一个立场单独形式产生相同的结果).
让它发挥作用的是Ewe建议将FlowPanel的AutoWrap关闭再打开,尽管它很笨重.我将以下代码添加到ScrollBox的OnResize事件处理程序:
procedure TCurrentJobsForm.ScrollBox1Resize(Sender: TObject);
begin
Flowpanel1.Autowrap := False;
FlowPanel1.AutoWrap := True;
end;
Run Code Online (Sandbox Code Playgroud)
调整大小时会有明显的闪烁,但我可以忍受,因为它会产生所需的结果.一旦用户调整表单大小,它将始终使用这些维度重新创建,因此调整大小是用户不经常进行的操作.
delphi ×10
delphi-xe ×3
delphi-2009 ×2
delphi-xe2 ×2
activex ×1
datasnap ×1
dbexpress ×1
debugging ×1
delphi-2010 ×1
firemonkey ×1
jsonp ×1
rest ×1
t-sql ×1
tdataset ×1
tdbgrid ×1
tframe ×1
tmonitor ×1
tscrollbox ×1
winapi ×1