我不是 Delphi 专家,我对消息流以及事件和回调的处理只有一个基本的了解。我正在尝试在 D7 中调试一个应用程序,该应用程序需要将前台过程(由单击按钮启动)与在后台发生的消息接收和处理(由组件处理)结合起来。它们都独立地正常工作,但是当我将它们组合在一个程序中时,消息接收不起作用。
现有的应用程序已经具有在单击按钮时发送消息的功能程序,并且它可以在运行而不处理任何按钮时接收消息。
正常的消息接收由一个组件处理,该组件将我的处理程序 (OnInput) 作为事件调用。我的处理程序将消息放入 ListBox。
我正在尝试编写一个循环发送消息并等待响应的过程。(伪代码):
for N := 0 to nsequence do begin
prevcount := ListBox1.items.count;
SendMessage(mymessage); // request the response
sleep(500); // allow time for response to arrive
for 0 to timeout do begin
sleep(100);
application.processmessages; {allow processing to handle incoming message}
if ListBox1.items.count > prevcount then break; {has the message arrived?}
end;
if ListBox1.items.count = prevcount then exit: {timeout -- fail}
end;
我认为这应该可以在没有线程的情况下完成,但是永远不会收到消息。它总是超时。
是否可以从 application.processmessages 调用组件事件处理程序?输入消息在应用程序运行和空闲时正常工作,但在执行过程时不能正常工作。除了调用 application.processmessages 以使应用程序处理消息并调用相关过程来处理它们之外,还需要什么?
为了跟踪传入的消息,路径以来自 Windows MMSystem 的回调开始。当 MIDI 输入端口打开时,回调被设置为指向一个处理程序:procedure midiHandler
在 midiHandler 中,事件被放入一个循环缓冲区:CircbufPutEvent(thisBuffer,@thisEvent)。
然后将一条消息发送回应用程序: PostMessage(thisCtlInfo^.hWindow, mim_Data, 0, 0)
该消息由:procedure TMidiInput.MidiInput(var Message: TMessage); 在该过程中有一个调用: FOnMIDIInput(Self);
这些事件在组件的接口中定义为:
{ Events }
FOnMIDIInput: TNotifyEvent; { MIDI Input arrived }
在已发布下,我们有:
{ Events }
property OnMidiInput: TNotifyEvent read FOnMidiInput write FOnMidiInput;
property OnOverflow: TNotifyEvent read FOnOverflow write FOnOverflow;
在 Object Inspector 中,OnMidiInput 事件链接到过程 MIDIInput1MidiInput;
过程 MIDIInput1MidiInput 首先调用 GetMidiEvent:
with (Sender As TMidiInput) do
begin
while (MessageCount > 0) do
begin
{ Get the event as an object }
thisEvent := GetMidiEvent;
GetMidiEvent 从循环缓冲区中读取消息。MIDIInput1MidiInput 过程进行一些检查和验证,并最终将消息存储在 ListBox1 中。
PS - 输入组件具有返回循环缓冲区中排队消息计数的属性。我在等待循环超时时检查它,它报告 0 条消息。所以回调显然没有进入 midiHandler 过程。