Solved

D5 NT Services & Thread messages

Posted on 2000-03-08
12
306 Views
Last Modified: 2012-05-04
I have written an NT service in D5 which spawns multiple threads to perform various tasks and generally all works fine.  

The main problem I have is posting a message back to the main service thread when each spawned thread is finished (terminated).  The code snippet is  below.

In the Terminate Method of the Thread I have :

procedure TSapSMUHourThread.Terminate ;
begin
  PostThreadMessage(TheService.ServiceThread.ThreadID,wm_ThreadDoneMsg,Self.ThreadID,0) ;
  inherited Terminate ;
end ;

In the Main service I have const & message handler declared as :

.
const
  wm_ThreadDoneMsg = wm_User + 8 ;
.
.
.
procedure TService_CDMS_CS.ThreadDone(var AMessage : TMessage); message ;
.
.

I have debugged this and this message handler is definitely NOT activated.

Does anyone have any ideas ??

thanks in advance.
0
Comment
Question by:nitdgrev
12 Comments
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2599406
Are you sure it isn't

procedure TService_CDMS_CS.ThreadDone(var AMessage : TMessage); message wm_ThreadDoneMsg;

in your code. If not, it should be!

Cheers,

Raymond.


0
 

Author Comment

by:nitdgrev
ID: 2599428
ooops!!! a typo!.

Yes it is as you suggest (note I should have TTheService instead of TService_CDMS_CS as well).  It should read :

procedure TTheService.ThreadDone(var AMessage : TMessage); message wm_ThreadDoneMsg;

I just failed to make the critical step or typing it out here! Sorry for the confusion.
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2599482
Have you tried a different constant (like wm_user + 1234) in case the one you used has already been taken?

Cheers,

Raymond.
0
 

Expert Comment

by:brunohe
ID: 2600486
Might be a problem. I think Delphi is using itself some WM_USER + x Values for internal purposes. I know, that sounds really stupid, but I thought that's the way it is.

Try as rwilson said WM_USER + 1234...
0
 

Author Comment

by:nitdgrev
ID: 2602487
I have tried using some other values but still can't get it to work.  I will try a few more combinations but it is looking grim.

Is this the correct procedure to use (ie PostThreadMessage) when sending a message back to the main service thread?
0
 

Author Comment

by:nitdgrev
ID: 2602590
I have for the time being an alternative to using messages which is working fine.

Instead of creating a message I have written an OnTerminate event handler for the Thread in question.  As far as I can tell this will be invoked in much the same way as the ThreadDone message handler.  

(I would still like to get the messages working however).

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 12

Expert Comment

by:rwilson032697
ID: 2602716
Is your main service thread the same as the main VCL thread?

if so you could just use PostMessage...

Cheers,

Raymond.
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2603864
This may, or may not, help:

PRB: PostThreadMessage Messages Lost When Posted to UI Thread
ID: Q183116

The information in this article applies to:

Microsoft Win32 Software Development Kit (SDK)


SYMPTOMS
Messages sent to a UI thread through PostThreadMessage are lost if the messages are posted while the user is manipulating a window owned by the thread. Messages might be lost if they are sent while the user moves or resizes the window or if the window is a modal dialog box.



CAUSE
When an UI thread is involved in modal behavior, the thread pumps messages in a message loop internal to the modal system rather than in the thread's main message loop. Messages that are posted to a window can still be dispatched to the window procedure of the target window, because the messages are associated with a window. However, thread messages need to be handled directly by the message loop, because they cannot be automatically dispatched elsewhere. Since the secondary message loop does not know about the thread message, it will be dropped.



RESOLUTION
Rather than using PostThreadMessage to post messages to a UI thread, use PostMessage to post messages to a window owned by that thread. Since messages directed to a window can be dispatched by a secondary message loop, the messages is still handled properly, even when the thread is not running in its primary message loop.

To use this method, the thread must create a window that lives throughout the period that it must receive messages, and the application sending the messages must have a handle to that window available.



STATUS
This behavior is by design.

0
 

Author Comment

by:nitdgrev
ID: 2606683
Thanks Raymond for all your suggestions.

While so far I haven't managed to solve this problem you do deserve some points.

The article does seem to make sense but how does this apply to an NT Service as there is no modal window ?  In regards to your comment about the VCL thread, I am not really certain, as I only assumed there was just the main service thread, no VCL thread?  If they are one & the same what handle do you use with PostMessage?  Am I on the right track do you think?



0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2606794
I see now. Yes, your main service thread will be the main VCL thread.

PostThreadMessage will fail if there is no messages loop for the thread you are sending the message to. Can you see if it fails or not?

Read the help for PostThreadMessage, it has some more information regarding handling situations where the thread does not have a message loop.

Cheers,

Raymond.
0
 
LVL 1

Accepted Solution

by:
aldyn earned 300 total points
ID: 2607669
Your problem is caused by manner in which service thread processes messages. Look into svcmgr unit and search for PeekMessage calls (there are two only). Look on the second one. It takes messages from the thread's message queue and processes it. Note that if the hwnd parameter is 0 (it is your case because you send message to thread, not to window) then this messages will be processes in special manner. Namely it will be treated as a service control message. In your case it will result to DoCustomControl call with one parameter only. Other information from your message will be lost. The solution is simple enough: you will have to create a window (look how TTimer component creates window to receive WM_TIMER for example, you can use the same code with minimum changes)
and then you will be able to send messages to it. Let me know if you need a ready-to-use code.
0
 

Author Comment

by:nitdgrev
ID: 2610272
Thanks Aldyn and rwilson.  This has rectified the problem.  Note all help has been appreciated.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Activex get website that activex running on 3 85
delphi prevent click fast 2 192
Simple Delphi Question 9 83
Press three keys together and trigger a function 3 51
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
Hi friends,  in this video  I'll show you how new windows 10 user can learn the using of windows 10. Thank you.

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

27 Experts available now in Live!

Get 1:1 Help Now