相关疑难解决方法(0)

如何退出线程的消息循环?

后台线程可以配置为接收窗口消息.您可以使用发布消息到线程PostThreadMessage.退出该消息循环的正确方法是什么?

背景

在将消息发布到后台线程之前,线程需要通过调用PeekMessage以下内容来确保创建消息队列:

procedure ThreadProcedure;
var
   msg: TMsg;
begin
   //Call PeekMessage to force the system to create the message queue.
   PeekMessage(msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
end;
Run Code Online (Sandbox Code Playgroud)

现在外面的世界能够将消息发布到我们的线程:

PostThreadMessage(nThreadID, WM_ReadyATractorBeam, 0, 0);
Run Code Online (Sandbox Code Playgroud)

我们的线程处于GetMessage循环中:

procedure ThreadProcedure;
var
   msg: TMsg;
begin
   //Call PeekMessage to force the system to create the message queue.
   PeekMessage(msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);

   //Start our message pumping loop. 
   //GetMessage will return false when it receives a WM_QUIT

   //   GetMessage can return -1 if …
Run Code Online (Sandbox Code Playgroud)

delphi winapi multithreading message-loop

13
推荐指数
2
解决办法
8990
查看次数

如何更改外部声明的函数的实现(绕行)

我有第三方功能

function DataCompare(const S1, S2: string; APartial: Boolean): Boolean;
begin
   ...
end;
Run Code Online (Sandbox Code Playgroud)

它用于另一个第三方单元.

我希望在运行时用另一个新实现替换函数体.

这可能吗?我想需要一些黑客(ala VirtualMemoryUnprotect).非汇编解决方案非常受欢迎.

delphi implementation replace function delphi-xe

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

我应该如何提供一个非可视VCL组件的内部私有非可视窗口(句柄)?

这是一个后续问题.

我之前的问题:

我的问题:

TComponent没有像TWinControl这样的窗口句柄.我不想依赖外部的.

这是我的自定义组件的片段

type
  TMyClipBoardListener = class(TComponent)
  private
    FInnerWindowHandle: HWnd;
    FNextHWnd:  HWnd;
    //...
  protected
    procedure Loaded; override;
    procedure WndProc(var Msg: TMessage); // <<< This is my wouldbe Window to handle messages
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    // ...
  published
    // ...
  end;
Run Code Online (Sandbox Code Playgroud)

我的自定义组件的实现摘录

constructor TMyClipBoardListener .Create(AOwner: TComponent);
begin
  inherited;
  //
  FInnerWindowHandle := ...; // <<< What to do here ? Should I pass it to a function/procedure I missed?
end;

destructor TMyClipBoardListener .Destroy; …
Run Code Online (Sandbox Code Playgroud)

delphi clipboard winapi custom-component

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

从Thread发布消息到GUI最佳实践?

我正在研究小型监控应用程序,它将通过SNMP,TCP,ICMP与某些设备进行通信,其他线程必须执行一些计算.所有这些结果我必须在GUI(一些Forms或TabSheets)中输出.

我正在考虑下一个可能性:

  • 使用Synchronize从每一个工作者线程:
  • 使用共享缓冲区和Windows消息传递机制.线程将消息放入共享缓冲区(队列),并将通过Windows消息通知GUI.
  • 使用单独的线程,它将侦听同步原语(事件,信号量等)并再次使用Synchronize,但仅限于GUI专用线程,或GUI上的Critical Section来显示消息.
  • 更新:(由一位同事提出)使用共享缓冲区和TTimer主要形式,它将定期检查(100-1000毫秒)共享缓冲区并消耗,而不是Windows消息传递.(它对消息传递有一些好处吗?)
  • 其他?

亲爱的专家,请解释什么是最佳实践或暴露的替代品的优缺点是什么.

更新:
作为想法:
//共享缓冲区+发送消息变量
LogEvent全局函数将从任何地方调用(也来自工作线程):

procedure LogEvent(S: String);
var
  liEvent: IEventMsg;
begin
  liEvent := TEventMsg.Create; //Interfaced object
  with liEvent do
  begin
    Severity := llDebug;
    EventType := 'General';
    Source := 'Application';
    Description := S;
  end;
  MainForm.AddEvent(liEvent); //Invoke main form directly
end;
Run Code Online (Sandbox Code Playgroud)

在主窗体中,事件ListView和共享部分(fEventList: TTInterfaceList已经是线程安全的)我们将:

procedure TMainForm.AddEvent(aEvt: IEventMsg);
begin
  fEventList.Add(aEvt);
  PostMessage(Self.Handle, WM_EVENT_ADDED, 0, 0);
end;
Run Code Online (Sandbox Code Playgroud)

消息处理程序

procedure WMEventAdded(var Message: TMessage); message WM_EVENT_ADDED;
...
procedure TMainForm.WMEventAdded(var …
Run Code Online (Sandbox Code Playgroud)

delphi messaging multithreading delphi-7

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

如何在我的mfc应用程序中的非对话框.cpp中使用SetTimer?

我的问题是正常的mfc SetTimer,如下所示

void CTimersDlg::OnButtonBegin()
{
    // create the timer

    SetTimer(m_nTimerID, uElapse, NULL);
}

void CTimersDlg::OnButtonStop()
{
    // destroy the timer
      KillTimer(m_nTimerID);
}

void CTimersDlg::OnTimer(UINT nIDEvent)  // called every uElapse milliseconds
{
    // do something, but quickly
    CDialog::OnTimer(nIDEvent);
}
Run Code Online (Sandbox Code Playgroud)

但是如果我需要在非dialog.cpp中使用SetTimer,例如在我的sender.cpp中如何创建计时器?在SetTimer字段中,处理程序(回调)函数?

c++ mfc

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

什么是相对跳跃?

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

像这样:

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
查看次数