小编EPr*_*und的帖子

替代TControl.Perform

TControl.Perform代码是:

var
  Message: TMessage;
begin
  Message.Msg := Msg;
  Message.WParam := WParam;
  Message.LParam := LParam;
  Message.Result := 0;
  if Self <> nil then WindowProc(Message);
  Result := Message.Result;
Run Code Online (Sandbox Code Playgroud)

程序执行等待返回,我是对的吗?

有一种替代方法,用于在同一个应用程序中的另一个线程内的TFORM队列中发布消息,而无需等待返回?

编辑

这种方法可以缓解这个问题吗?

interface

const  
  WM_DOSTUFF = WM_APP + $001;

TMyForm = class(TForm)
{stuff}
public
{Other stuff}
  procedure DoMyStuff(var Msg: TMessage); message WM_DOSTUFF;   
{More stuff}
end;  

var
  MyHandle: HWND;

implementation

constructor TMyForm.Create(AOwner: TComponent);
begin
  inherited;
  MyHandle := AllocateHWnd(DoMyStuff);
end; 

destructor TMyForm.Destroy;
begin
  DeallocateHWnd(MyHandle);
  inherited;
end;
Run Code Online (Sandbox Code Playgroud)

并且通常在线程内使用:

  PostMessage(MyHandle, WM_DOSTUFF, 0, 0);   
Run Code Online (Sandbox Code Playgroud)

windows delphi vcl message-queue

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

获取单例类实例多线程

要使用单例模式获取类的实例,我想使用以下函数:

这是草图

interface

uses SyncObjs;

type
  TMCriticalSection = class(TCriticalSection)
  private
    Dummy : array [0..95] of Byte;
  end;

var
  InstanceNumber : Integer;
  AObject: TObject;
  CriticalSection: TMCriticalSection;

function getInstance: TObject;

implementation

uses Windows;

function getInstance: TObject;
begin
   //I Want somehow use InterlockedCompareExchange instead of CriticalSession, for example

   if InterlockedCompareExchange(InstanceNumber, 1, 0) > 0 then
   begin
     Result := AObject;
   end
   else
   begin
      CriticalSection.Enter;
      try
        AObject := TObject.Create;
      finally
        CriticalSection.Leave;
      end;
      InterlockedIncrement(InstanceNumber);
      Result := AObject
   end;
end;

initialization
  CriticalSection := TMCriticalSection.Create;
  InstanceNumber := 0; …
Run Code Online (Sandbox Code Playgroud)

delphi singleton multithreading synchronization delphi-6

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

什么是相对跳跃?

为什么它用于挂钩和重定向功能?

像这样:

procedure RedirectProcedure(OldAddress, NewAddress: Pointer);
var
  NewCode: TInstruction;
begin
  NewCode.Opcode := $E9; //relative jump
  NewCode.Offset := NativeInt(NewAddress)-NativeInt(OldAddress)-SizeOf(NewCode);
  PatchCode(OldAddress, NewCode, SizeOf(NewCode));
end;
Run Code Online (Sandbox Code Playgroud)

顺便说一句,$ E9常数意味着什么?

delphi assembly page-jump

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

类成员是否没有缓存行问题?

TThread类中有一个名为的类成员(属性)Terminated.
此外,还有一个procedure Terminate;它仅仅设置TerminatedTrue.
当我们继承时,TThread有一些情况我们检查终止.以下池/循环只是为了演示可能的情况:

  while not Terminated do
  begin
    Work;
  end;
Run Code Online (Sandbox Code Playgroud)

什么是终止的保证永远不会被处理器缓存?

delphi multithreading delphi-6

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

组件的默认属性值

我想知道是否可以为组件定义默认属性值.
换句话说,我想在设计时为系统中的每个TDBGrid设置一个唯一的名称(可能是GUID),是否可能?
还有另一种方法可以控制在运行时和设计时都有效的组件的唯一性.在关闭delphi之后它也必须坚持下去; 例如,组合框列表值.

提前致谢!

编辑

下面是代码,不起作用:

type
  TMDBGrid = class(TDBGrid)
  private
    FUniqueName: String;
  protected
    function DefaultUniqueName: String;
    function GetUniqueName: String;
    procedure SetUniqueName(const AName: String);
  public
    constructor Create(AOwner: TComponent); override;
  published
    property UniqueName: String read GetUniqueName write SetUniqueName;
  end;

procedure Register;

implementation

uses uComponentUtils;

procedure Register;
begin
  RegisterComponents('MLStandard', [TMDBGrid]);
end;

{ TMDBGrid }

constructor TMDBGrid.Create(AOwner: TComponent);
begin
  inherited;
  FUniqueName := DefaultUniqueName;
end;

function TMDBGrid.DefaultUniqueName: String;
begin
  Result := GenerateGUID(True);
end;

function TMDBGrid.GetUniqueName: String;
begin
  Result := '';
end;

procedure TMDBGrid.SetUniqueName(const …
Run Code Online (Sandbox Code Playgroud)

delphi components properties delphi-7

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

安全和良好的设计AllocateHWND能够响应多个线程吗?

众所周知,在需要在UI线程和工作线程之间进行通信的情况下,由于线程安全(句柄重建),必须创建隐藏窗口.

例如:

  • Form1有N个动态创建的TProgressBar实例,其背景名称与正在运行的背景相同.
  • 总是保证WM_REFRESH只会在任务线程内部调用.
  • Form1H : THandle property分配以下过程:

    过程RefreshStat(var Message:TMessage); 消息WM_REFRESH;

  • 在内部RefreshStat,如果只有一个后台线程我可以轻松使用LW参数来映射任务ID和位置.

我不知道标题是否说明了我想知道的内容,但让我们想象一下,如果我们有一个运行多个后台任务的应用程序.
就我而言,我TProgressBar用来报告完成的进度.

是否AllocateHwnd保证所有消息在没有竞争条件的情况下到达隐藏窗口?
如果两个或多个任务同时发布消息会发生什么?

如果需要手动控制,我想知道除了在自定义消息中创建另一个消息循环系统之外是否还有其他事情要做.

我希望这个问题足够清楚.

delphi winapi multithreading delphi-6

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

使用常见的OnTerminate行为进行TThread

我正在阅读这篇文章几乎解决了我的问题,因为没有人回答我的评论我决定提出一个问题:

原帖几乎回答了我的问题

我在那里问:

  • 既然多线程可以共享同一个OnTerminate事件,那么它们也可以同时完成吗?
  • 如果是这样,会发生什么?对OnTerminate方法的调用将由操作系统"排队"?换句话说,如果使用MainThread属性,代码是否可以避免重入?

windows delphi multithreading delphi-6

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

如何在Delphi中的多个线程中加载DLL?

也许有一些我错过的东西,我无法想象这里发生了什么.

我正在尝试在TThread对象的多个实例中加载相同的DLL.

这是我的DLL代码:

library MyCalcFor32;

uses
  SysUtils,
  Classes,
  uRunner in 'uRunner.pas';

Exports EVal;

{$R *.res}

begin
end.
Run Code Online (Sandbox Code Playgroud)

这是uRunner.pas:

unit uRunner;

interface

uses SysUtils,
     Classes;

function EVal(Valor: WideString): WideString; stdcall; export;

implementation

function EVal(Value: WideString): WideString; stdcall; export;
begin
  Result := Value+' xxx';
end;

initialization

finalization

end.
Run Code Online (Sandbox Code Playgroud)

这是加载DLL的程序:

procedure TfrmMain.FormCreate(Sender: TObject);
var I: Integer;
begin
  SetLength(Threads, 10);
  for I:= 0 to 9 do
  begin
    Threads[I] := TWorker.Create(Self.Handle, I+1, Memo1.Text, ExtractFilePath(ParamStr(0)));
  end;
end;


procedure TfrmMain.btnExecuteThreadsClick(Sender: TObject);
var I: Integer;
begin
  ClearMemos([MT1, MT2, …
Run Code Online (Sandbox Code Playgroud)

windows delphi dll multithreading delphi-6

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

Windows消息权限

什么是Windows消息权限?

在应用程序1中,我向应用程序2发布了一条消息:

PostMessage(handle, WM_LOCAL, 0, Integer(Lst));
Run Code Online (Sandbox Code Playgroud)

在应用程序2中,消息实现:

var l: TStringList;
begin    
  ShowMessage('got 1');
  l := TStringList(Message.LParam);
  ShowMessage('got 2');
  Memo1.Clear;
  ShowMessage('got 3');

  if Memo1 = nil then
    ShowMessage('nil');

  //HERE : Access violation.
  //Memo1.Text := l.Text;
  //ShowMessage('got 4');

  Memo1.Lines.Add('good!');
  ShowMessage('got 5');

  l.Free;      
  ShowMessage('got 6');

  //Access violation Too..
  Memo1.Repaint;
  ShowMessage('got 7');
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

我既不能重新绘制备忘录,也不能重新访问Text属性.

windows delphi privileges windows-messages

0
推荐指数
1
解决办法
147
查看次数

Delphi 7中有一个TCustomStyleServices?

为了覆盖TPanel的Paint程序在delphi 7中使背景颜色变为clwhite,我正在关注@RRUZ答案,但我找不到TCustomStyleServices类.

还有其他方法可以做我想要的吗?

我正在使用XPMan资源(IDK如果改变了什么).

delphi components delphi-7 vcl-styles

0
推荐指数
1
解决办法
309
查看次数

为进程句柄和PID键入库正确的数据类型

如果我需要转换为Delphi框架中的类型,我会使用:

  • 对于DWORD:Cardinal类型,用于标识进程的PID.(tagPROCESSENTRY32)
WinAPI DataType | Delphi Translated DataType | Automation Object Compatible DataType

DWORD           | Cardinal                   | ?????
Run Code Online (Sandbox Code Playgroud)
  • 对于HANDLE,HWND类型,用于映射从AllocatedHWND返回的句柄.后者将用于进程间通信(IPC)
WinAPI DataType | Delphi Translated DataType | Automation Object Compatible DataType

HANDLE(HWND)    | HWND                       | ?????
Run Code Online (Sandbox Code Playgroud)

但是,我需要翻译这些类型以通过COM(类型库)接口传递它们.

我应该使用哪种类型?

注意:类型需要与自动化对象100%兼容.

windows delphi delphi-6

-1
推荐指数
1
解决办法
156
查看次数

如何在Delphi中等待和终止TThread(完成后通知用户)

如果用户提供记录在Excel文件中的信息,那么我选择Excel COM来读取数据.但是,由于用户可以将过程重复到N个文件并且该过程可能需要一段时间,因此我决定将此例程移动到单独的线程中.

因此,我需要你的建议来定义我该怎么做.

在没有剩余文件之前,不能销毁工作线程.在线程内部,数据被加载到ClientDataSet,最后应用于数据库.

我需要在任务完成时以某种方式通知用户,这样他就可以决定是否加载另一个文件并再次执行该线程或完成工作.

如何正确销毁线程并通知用户?

delphi notifications multithreading delphi-6

-2
推荐指数
1
解决办法
2280
查看次数

SQL Server是否支持BNF表示法?

Oracle支持Backus-Nauer Form,那么Microsoft SQL Server呢?

如果是,包括哪些版本?

t-sql sql-server

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