在项目中使用DataModule的目的是什么?与普通类或模块相比,它是否具有任何特殊属性?通常用于什么的惯例是什么?
如何有效地在Java中生成安全的随机(或伪随机)字母数字字符串?
我正在努力让Log4D在Delphi XE4中工作,并且因为在uses子句中找不到Contnrs而得到一些编译错误,除非我把它移到了它定义的ifdef之外.
{$IFDEF DELPHI5_UP}
Contnrs,
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)
一些调查发现ifdef是在一个包含的文件Defines.inc中定义的,它有一个块用于每个"支持"的delphi版本,它会停止几个版本:
例如:
{$IFDEF VER170} { Delphi 2005 }
{$DEFINE DELPHI9}
{$DEFINE DELPHI4_UP}
{$DEFINE DELPHI5_UP}
{$DEFINE DELPHI6_UP}
{$DEFINE DELPHI7_UP}
{$ENDIF}
{$IFDEF VER180} { Delphi 2006 }
{$DEFINE DELPHI10}
{$DEFINE DELPHI4_UP}
{$DEFINE DELPHI5_UP}
{$DEFINE DELPHI6_UP}
{$DEFINE DELPHI7_UP}
Run Code Online (Sandbox Code Playgroud)
因此,虽然继续复制并粘贴用于Delphi 2006的ifdef并创建一个Delphi XE4块也很容易......但这似乎是一个不优雅的解决方案.这绝对不是未来的证明......你现在必须更新这个文件的每个新版本,因此Delphi 4中没有的一些代码不会让别人的15岁以上的遗留代码爆炸.
所以我想知道是否有更好的方法来进行条件编译,以便在编译该行时确实只检查是否有"Delphi 5或更高版本",而不是这种格式需要更新每个新版本的delphi .
我已经在我的delphi项目中添加了一些代码来与注册表进行交互,使用我在网上找到的一些教程来指导我的工作.我见过的每个例子似乎都使用这个结构进行注册表访问:
var
Registry: TRegistry;
begin
try
Registry := TRegistry.Create;
//additional code to access and use the registry object could go here
finally
Registry.Free;
end;
Run Code Online (Sandbox Code Playgroud)
但是当我按照该结构实现我的代码时,我收到一个警告,我的变量Registry可能没有在我释放TRegistry对象的行上初始化.
所以,我想知道我发现的示例是否在访问注册表的正确方法上是错误的.我是否应该在我的TRegistry对象上调用Free,无论Create是否成功,只是忽略警告?相反,我的try/finally块应该只是在成功构造函数调用之后包围代码,但不包装create调用?别的什么?
我正在努力将一些Delphi 7代码移植到XE4,因此,unicode就是这里的主题.
我有一个方法,其中一个字符串被写入TMemoryStream,所以根据这篇embarcadero文章,我应该将字符串的长度(以字符为单位)乘以Char类型的大小,以获得所需的字节长度. WriteBuffer的长度(以字节为单位)参数.
所以之前:
rawHtml : string; //AnsiString
...
memorystream1.WriteBuffer(Pointer(rawHtml)^, Length(rawHtml);
Run Code Online (Sandbox Code Playgroud)
后:
rawHtml : string; //UnicodeString
...
memorystream1.WriteBuffer(Pointer(rawHtml)^, Length(rawHtml)* SizeOf(Char));
Run Code Online (Sandbox Code Playgroud)
我对Delphi的UnicodeString类型的理解是它内部是UTF-16.但我对Unicode的一般理解是,即使是2个字节也不能表示所有unicode字符,有些角落外壳字符将占用4个字节.embarcadero的另一篇文章似乎证实了我的怀疑,"事实上,一个Char等于两个字节甚至不总是这样!"
所以...这让我想知道是否Length(rawHtml)* SizeOf(Char)
真的足够稳健以保持一致的准确性,或者是否有更好的方法来确定更准确的字符串大小?
我只是在为一个列插入数据时,正在寻找一种方法来进行多行插入.
这是示例表:
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | tinyint(4) | NO | PRI | NULL | auto_increment |
| name | varchar(40) | NO | UNI | NULL | |
+-------+-------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)
我希望能够在每行的名称列中插入类似('admin','author','mod','user','guest')的内容.
MySQL文档显示多个插入应采用以下格式:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
Run Code Online (Sandbox Code Playgroud)
但是我的陈述最终看起来像这样:
INSERT INTO User_Role(name) VALUES ('admin','author','mod','user','guest');
Run Code Online (Sandbox Code Playgroud)
我得到以下内容:
ERROR 1136(21S01):列数与第1行的值计数不匹配
这意味着它认为我正在尝试单行插入.
我不确定我是否只是在这里遗漏了一些简单的东西,但我没有在这个用例的MySQL文档中看到任何特别的东西.
在其他语言(如C++)中,有些运算符可以执行plus-equals或or-equals类型的操作来添加其他样式/标志.Delphi中有相同的东西吗?
现在我有一些代码,如:
label1.Font.Style := label1.Font.Style + [fsBold];
label2.Font.Style := label2.Font.Style + [fsBold];
Run Code Online (Sandbox Code Playgroud)
但是,如果可能的话,我希望能够简化一些简化,而不会在赋值运算符的两边复制标签名称,这可能是:label1.Font.Style += [fsBold];
或者label1.Font.Style := self + [fsBold];
可以这样做吗?还是没那么多?
如果我打开那些编译器检查指令,这是一些导致范围检查错误和溢出错误的代码的精简版本.我理解为什么这会导致溢出,在C1的乘法中,它似乎可能超过数据类型的最大值.但为什么这也会触发范围检查错误?Delphi的文档和其他关于堆栈溢出的帖子使得听起来像范围检查错误通常用于超出范围的数组访问.但是我没有在线上访问一个数组,它说是导致范围检查错误.也许是关于param1的任务?但是,如果是这样,为什么这会是范围检查而不是溢出错误?
const
C1 = 44001;
C2 = 17999;
function fxnName(..other params...; param1: Word): String;
var
someByte: byte;
begin
// some code
// by now we're in a loop. the following line is where it breaks to in the debugger:
param1 := (someByte + param1) * C1 + C2;
// more code
end;
Run Code Online (Sandbox Code Playgroud)
如果它是相关的,当它在调试器中的那一行中断时,除了param1之外,所有值都按预期显示,当我要求Delphi评估它时,它显示"未声明的标识符:'param1'".
假设我有一个表单,上面有一个菜单栏.我在菜单栏上有一个项目TMenuItem
,我可以为其分配一个快捷键组合,例如Ctrl+ I.但是当我为其分配ShortCut
属性时TMenuItem
,它似乎只是改变菜单项的视觉外观来显示快捷键代码而不是自动侦听要按下的快捷键并触发我的ActionManager代码.
我的google-fu今天似乎失败了,我只找到关于如何为windows分配全局热键的文章,而不是如何分配仅在活动表单上工作的特定于应用程序的热键.
任何人都可以为我概述添加热键所需的步骤,而不仅仅是在菜单中添加快捷方式属性.我在想某个地方我可能需要将表单设置为监听键盘输入并捕获按键并对其进行响应?但我不确定Delphi的做法在哪里或者做什么.
在我的电子邮件检查器中,我同时支持POP3 SSL和IMAP SSL.虽然使用SASL的Pop3 SSL已经运行了一段时间,但我从未使用SASL来使用IMAP SSL,即使SASL的代码在POP3和IMAP之间应该非常相似.我的理解是,在这个问题得到解决之前,我不应指望它能够发挥作用.好吧,这个问题已得到解决,所以我想我会再次考虑让SASL为IMAP工作.我已经更新并重建了Indy,并取消注释了我所有的SASL代码,现在我发现当我发出Login命令时,我在IdIMAP4中获得了读取超时(即使将超时设置为大量的时间(在20-30秒的邻域,比使用SASL在POP3上进行身份验证的时间长约5倍.
单步执行调试器中的代码,导致读取超时的行显示function PerformSASLLogin_IMAP(ASASL: TIdSASL; AEncoder: TIdEncoder;
在第1358行的函数中:
AClient.SendCmd(AClient.NewCmdCounter, 'AUTHENTICATE ' + String(ASASL.ServiceName), [], True); {Do not Localize}
Run Code Online (Sandbox Code Playgroud)
考虑到整个方法在该错误报告中指出的修订中是新的,我很确定我已经成功更新了Indy,并且我建立SASL机制的逻辑与诸如POP3之类的东西非常相似(除了像使用IMAP AuthType iatSASL而不是Pop3 AuthType patSASL).那么为什么我会在这里获得读取超时?我怎么能解决这是我的代码或Indy不能正常工作?如果我将IMAP.AuthType更改为iatUserPass或DEF_IMAP4_AUTH连接成功.我似乎无法找到关于我是否应该期望SASL与IMAP一起工作的最新信息,除了暗示错误报告被关闭为固定.
编辑: Per Remy在他的回复中提出的问题,这是'当我将其设置为在没有SSL的情况下连接SASL时由wireshark捕获的TCP对话:
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE STARTTLS AUTH=PLAIN AUTH=LOGIN] Dovecot ready. C1 CAPABILITY * CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS MULTIAPPEND UNSELECT IDLE CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS QUOTA STARTTLS AUTH=PLAIN AUTH=LOGIN …