小编ros*_*mcm的帖子

Delphi - 当表单的ComponentCount递减时,如何中断

以下代码从Toolbar2000中复制.它是从INI文件中读取工具栏位置和停靠状态的例程的一部分.我在初始化期间称这个例程.下面的代码迭代主窗体上的所有组件(OwnerComponent)并加载它找到的任何工具栏的设置.

for I := 0 to OwnerComponent.ComponentCount-1 do begin
  ToolWindow := OwnerComponent.Components[I];  //  <------------------------
....
Run Code Online (Sandbox Code Playgroud)

这个迭代需要一些时间(秒 - 表单上有1500多个组件),我在显示的点上得到一个范围错误.我已经确定在执行此循环时正在从主窗体的组件中删除一个或多个项目,因此一旦发生这种情况,最终循环会尝试访问一个超过数组末尾的项目(可能最好将其编码为一个"downto"for循环来防止这种情况).

无论如何,我需要找出主要表单丢失组件的位置.谁能给我任何关于如何做到这一点的Delphi 2006调试技巧?我不希望在我的程序中释放任何主要表单组件.

UPDATE

我发现当我在设计时重新定位工具栏的默认停靠位置时,我无意中将它停靠在另一个工具栏上,而不是另一个工具栏所在的停靠站点.我通过从工具栏中删除工具栏来解决问题停靠并将其添加到码头.因此导致问题的安排是:

Dock 
  Toolbar 1
    Control 1
    Control 2
    Toolbar 2
      Control 3
      Control 4
Run Code Online (Sandbox Code Playgroud)

并且解决方法是安排他们:

Dock 
  Toolbar 1
    Control 1
    Control 2
  Toolbar 2
    Control 3
    Control 4
Run Code Online (Sandbox Code Playgroud)

它仍然指向TB2k代码中的一个错误 - 人们会认为它应该能够处理嵌套的工具栏.

delphi components toolbar delphi-2006 outofrangeexception

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

重命名文件时出现错误 32(文件正在被另一个进程使用)

我有一个 Delphi 2006 应用程序,它写入一个文件,然后定期将其重命名为有序名称,并创建一个新文件,即

open file.dat
write a record to file.dat
close file.dat 
...   
open file.dat
write a record to file.dat
close file.dat  

rename file.dat to file20110818123456.dat

create file.dat

open file.dat
write a record to file.dat
close file.dat  
...
Run Code Online (Sandbox Code Playgroud)

问题是有时重命名会失败并显示Error 32 - The process cannot access the file because it is being used by another process. 我正在检查重命名的目标是否不存在。就好像写入记录后文件的关闭不会立即发生。我在重命名过程中添加了一个循环来休眠一会儿,然后重试最多 10 次,但这没有帮助。

function RenameFileAtAllCosts (const OldFileID : TFilename ;
                               const NewFileID : TFilename ;
                               out   ErrorCode : Integer) : boolean ; …
Run Code Online (Sandbox Code Playgroud)

delphi file-rename delphi-2006

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

什么是以编程方式模拟用户输入的简单方法?

我有一个由于错误条件而弹出的对话框.我希望对话框保持打开状态至少30秒,并在收到最后一个用户输入(鼠标或键盘)后关闭30秒.

我可以通过检查GetLastInputInfo返回的值并在超过30秒之前关闭对话框来实现这一点,但是如果当用户没有使用鼠标或键盘30秒时弹出对话框,则GetLastInputInfo测试通过立即,对话框立即再次关闭.我可以用另一个计时器做到这一点,但我认为在对话框打开之前模拟鼠标移动或者发出一个(无害的)按键要简单得多.它也可能具有将系统从屏幕保护程序中踢出的优点.

什么是最简单的1行Delphi代码片段来实现这一目标?

delphi keypress screensaver delphi-2006 mouseevent

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

如何在没有显示模态对话框的情况下关闭应用程序?

我有一个应用程序,可以选择打开PDF后创建它们.如果两个报告连续生成相同的名称,如果第一个acrobat副本仍然打开PDF,则第二次尝试失败,因此在我编写PDF之前,我检查(使用FindWindow)具有文档名称的窗口.如果找到一个,我发出SendMessage WM_Close.

这工作正常,但我正在做一些其他测试,并使用Word来"编辑"PDF,保持打开,这样我就可以测试应用程序无法编写PDF文件时的行为.现在,当我的应用程序试图关闭窗口时,Word会弹出一个"你想要保存"对话框.如果我单击取消,Word仍保持打开状态,我的应用程序继续运行,我可以测试它在遇到无法写入的文件时表现得理智.

一切都很好,但它已经提醒我,使用SendMessage WM_CLOSE关闭另一个应用程序将阻止我的应用程序,如果其他应用程序弹出模式对话框.有没有办法解决这个问题 - 即关闭其他应用程序的更有力(但不是太强大)的方式?或者"关闭并在必要时单击取消".或者我应该使用异步消息?

delphi message sendmessage findwindow

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

Delphi - 如何使用前导零格式化实数?

我需要在小数点之前的整数部分中使用前导零格式化实数.我知道如何使用整数实现这一点,但实际的语法让我感到厌烦.

Number  := 1.234 ;
SNumber := Format ('%2.3f', [Number]) ;
Run Code Online (Sandbox Code Playgroud)

这给了SNumber = ' 1.234'但我想要'01.234'. Number永远是0..99.999

delphi formatting real-number

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

为什么这个D2006代码不能淡化PNG图像?

这个问题来自较早的问题.大多数代码来自可能在后续版本的Delphi中使用的建议答案.在D2006中,我没有获得全范围的不透明度,图像的透明部分显示为白色.

图片来自http://upload.wikimedia.org/wikipedia/commons/6/61/Icon_attention_s.png.
它在运行时从PNGImageCollection加载到TImage中,因为我发现你必须这样做,因为在保存DFM后图像不会保持不变.出于演示行为的目的,您可能不需要PNGImageCollection,并且可以在设计时将PNG图像加载到TImage中,然后从IDE运行它.

表单上有四个按钮 - 每个按钮设置不同的不透明度值.Opacity = 0工作正常(paintbox图像不可见,opacity = 16看起来没问题,除了白色背景,不透明度= 64,255相似 - 不透明度似乎在10%左右饱和.

关于什么事情的任何想法?

unit Unit18;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, pngimage, StdCtrls, Spin, PngImageList;

type
  TAlphaBlendForm = class(TForm)
    PaintBox1: TPaintBox;
    Image1: TImage;
    PngImageCollection1: TPngImageCollection;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure PaintBox1Paint(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  private
    FOpacity : Integer ;
    FBitmap  : TBitmap ;
    { …
Run Code Online (Sandbox Code Playgroud)

delphi png timage alphablending delphi-2006

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

Inno设置 - 允许用户选择"只是我"或"使用此计算机的任何人"

我遇到的一些安装人员让我选择"仅为我"或"为"使用此计算机的任何人安装应用程序".

如何让我的Inno Setup脚本向用户显示此选项,以便我可以根据他们的回答更改安装程序的操作?

windows-installer inno-setup allusersprofile

3
推荐指数
2
解决办法
2495
查看次数

Delphi 2006 - 优雅地杀死一个线程并且仍然使用OnTerminate处理程序的最佳方法是什么?

我有一个线程有时冻结(我怀疑)由于DLL调用永远不会返回.在一般情况下,如果您调用了像Indy这样的阻塞例程,有没有一种方法可以通过线程OnTerminate处理程序触发来恢复?如果我调用TerminateThread会发生这种情况吗?

delphi multithreading terminate thread-safety delphi-2006

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

是否有可能推进死锁线程?卡在WaitForSingleObject

如果我有一个应用程序正在创建执行其工作然后退出的线程,并且一个或多个线程陷入死锁(可能不是我自己的错!),是否有一种方法可以通过编程方式强制其中一个线程超过可能被卡住的WaitForSingleObject,从而解决死锁?

我不一定要终止线程,我只想让它继续前进(从而允许线程"优雅地"退出.

(是的,我知道这听起来像是我之前的问题Delphi 2006的重复- 什么是优雅地杀死一个线程并仍然使用OnTerminate处理程序的最佳方法?但是情况略有不同 - 我在这里问的是有可能使WaitForSingleObject (Handle, INFINTE)行为像a WaitForSingleObject (Handle, ItCantPossiblyBeWorkingProperlyAfterThisLong)).

请温柔地对待我.

*更多信息*

问题不一定在我有源代码的代码中.实际情况是基于线程的串行COM端口库(AsyncFree).当端口基于USB时,库在关闭端口时创建的两个线程之间似乎存在死锁.我已经在这个论坛上详细讨论了这个问题.我确实将其中一个WaitForSingleObject调用重新编码为不是无限的,并且解决了这个死锁,但是后来在线程关闭序列中出现了另一个,这次是在Delphi TThread.Destroy例程中.

所以我的理由很简单:当我的线程死锁时,如果可以,我会修复代码.如果我不能,或者看起来我不知道,我只想让线程完成.我不一定很漂亮.我不能让我的应用程序窒息.

windows delphi winapi multithreading deadlock

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

使用Indy发送邮件而不使用外部服务器

我的应用程序使用Indy TiDSMTP客户端组件发送电子邮件.但是,在某些情况下,客户无法或不愿意设置SMTP服务器和端口,用户名等,因此我希望提供一种发送电子邮件的解决方案,而无需任何人设置任何内容.

我尝试了TIDSMTPRelay演示但是我需要explcitly输入DNS服务器IP地址(当我这样做时,它失败了"Project SMTPRelay.exe引发了异常类EIdHostRequired并带有消息''").我希望Indy解决方案不需要用户输入任何设置 - 只要他们可以访问互联网就可以"开箱即用".

我还需要提供什么?

TIA,R

delphi smtp indy10

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