I have
For instance, here is a snippet of my code.
The only way to restart the
The same code or program works fine under Windows XP compiled with Delphi 7. Currently, I am using Windows 7 and Delphi 2010 to rebuild my system.
I will try to give you more information. What I am working on is a copyrighted software.
There is a user defined procedure called HandleMsg. It actually processes the serial port messages. HandleMsg is set to the Application event onMessage;
Application.onMessage:=HandleMsg();
PostMessage is associated with onMessage event of the application.
Whenever PostMessage is called, it fires onMessage event which is set to HandleMsg().
Here more of my code:
Answer:
TTimer
enabled and is supposed to run non-stop forever until the user stop it. However, it doesn't work that way. Within OnTimer
event, it processes window messages over and over again in milliseconds.For instance, here is a snippet of my code.
procedure TDXCommDlg.Timer2Timer(Sender: TObject);
begin
inherited;
if Scanning then
begin
Timer1.Enabled := false;
Timer2.Enabled := false;
while not PostMessage(Handle,WM_USER + 10,1234,5678) do;
Timer1.Enabled := true;
end;
end;
What happens is this. While the TTimer is enabled and running, you drag any windows of the application or click on pull down menu the TTimer event completely stops working, even though I have taken precautionary steps in other part of the code to prevent this from happening. However, it doesn't seem to be helping.The only way to restart the
OnTimer
event is to stop and restart the Timer by the user through TButton event.The same code or program works fine under Windows XP compiled with Delphi 7. Currently, I am using Windows 7 and Delphi 2010 to rebuild my system.
I will try to give you more information. What I am working on is a copyrighted software.
There is a user defined procedure called HandleMsg. It actually processes the serial port messages. HandleMsg is set to the Application event onMessage;
Application.onMessage:=HandleMsg();
PostMessage is associated with onMessage event of the application.
Whenever PostMessage is called, it fires onMessage event which is set to HandleMsg().
Here more of my code:
procedure TDXCommDlg.HandleMsg(var
Msg: TMsg; var Handled: Boolean);
begin
Handled := false;
case Msg.message of
WM_USER + 10:
begin
if (Msg.wParam = 1111) and (Msg.lParam = 2222) then
begin
SendLanMessage;
Handled := true;
end
else if (Msg.wParam = 1234) and (Msg.lParam = 5678) then
begin
SendMessage;
Handled := true;
end
else
begin
if (Msg.wParam = 4321) then
begin
MainFrm.CloseWindow(TViewFrm(Msg.lParam).WinCap);
end;
end;
end;
end; { case } end;
HandleMsg() responds to PostMessage. Correct me if I am wrong.Answer:
In both cases (starting to size/move window or opening a menu) the last message dispatched from
For instance the below is from
Your solution is simple. Instead of using the
Or, put your code in the
TApplication.ProcessMessage
is WM_NCLBUTTONDOWN
(or a WM_NCRBUTTONDOWN
if caption and system menu exists and clicked on the caption.. or a WM_RBUTTONUP
if opening a context menu, etc..). Common to all is they are starting a modal message loop.For instance the below is from
WM_ENTERSIZEMOVE
documentation:The WM_ENTERSIZEMOVE message is sent one time to a window after it enters the moving or sizing modal loop. [....] The operation is complete when DefWindowProc returns.After a modal message loop is started the
HandleMessage
call in TApplication.Run
will not return until DefWindowProc
for the relevant window returns (in the WM_NCLBUTTONDOWN
case for instance, the dispatched message will cause a WM_SYSCOMMAND
to be sent to the window which will start the modal message loop and will not return until moving/sizing is complete). So you won't be able to use an OnMessage
handler of the application in this period which is called in TApplication.ProcessMessage
.Your solution is simple. Instead of using the
OnMessage
handler, handle the message with a message handler of your form:const
WMUSER_10 = WM_USER + 10;
type
TForm1 = class(TForm)
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
private
procedure WmUser10(var Msg: TMsg); message WMUSER_10;
public
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
PostMessage(Handle, WMUSER_10, 1234, 5678);
end;
procedure TForm1.WmUser10(var Msg: TMsg);
begin
//
end;
Or, put your code in the
OnTimer
event, since WM_TIMER
is itself posted.
No comments:
Post a Comment