Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

(un)RegisterWindowMessage

228 views
Skip to first unread message

Paul

unread,
Jan 26, 2007, 11:04:47 AM1/26/07
to
I use the RegisterWindowMessage function to communicate between a service
and a thread.
When a destop changes, all threads have to switch to the new input desktop,
but one of them fails.
This thread uses the RegisterWindowMessage() function to communicate with
the service.
It's not clear to me (from msdn) if RegisterWindowMessage creates a hidden
window or not.
If it is, than a change to a new desktop is impossible and this hidden
window should be destroyed.
I can't find a function to do this.
Any idea ?


Paul


Peter Below (TeamB)

unread,
Jan 26, 2007, 1:20:57 PM1/26/07
to
Paul wrote:

> I use the RegisterWindowMessage function to communicate between a
> service and a thread. When a destop changes, all threads have to
> switch to the new input desktop, but one of them fails. This thread
> uses the RegisterWindowMessage() function to communicate with the
> service. It's not clear to me (from msdn) if RegisterWindowMessage
> creates a hidden window or not.

No, it just creates an atom in the Windows global atom table. But you
should not use Windows messages for communication with a service, since
that does not work across desktops. On Vista, for example, a GUI app
would not be able to communicate with a service this way.

--
Peter Below (TeamB)
Don't be a vampire (http://slash7.com/pages/vampires),
use the newsgroup archives :
http://www.tamaracka.com/search.htm
http://groups.google.com
http://www.prolix.be

Paul

unread,
Jan 26, 2007, 1:59:43 PM1/26/07
to

"Peter Below (TeamB)" <none> schreef in bericht
news:xn0f1oe2...@newsgroups.borland.com...

>
> No, it just creates an atom in the Windows global atom table. But you
> should not use Windows messages for communication with a service, since
> that does not work across desktops. On Vista, for example, a GUI app
> would not be able to communicate with a service this way.
>

I know, but all /real/ user interface is handled thru a program that is
started when a user is logged on.
It's connected with the main service thru a pipe.
The thread doesn't read anything directly, but thru a driver.
I used the window messages so that it's compatible with another version of
the application that doesn't have to switch between desktops.
Seems I should rewrite the thread ...

Paul


Remy Lebeau (TeamB)

unread,
Jan 26, 2007, 5:00:23 PM1/26/07
to

"Paul" <paul.bl...@telenet.be> wrote in message
news:45ba4f76$1...@newsgroups.borland.com...

> I know, but all /real/ user interface is handled thru a program
> that is started when a user is logged on.

Which is perfectly fine. But the communication between that program
and the service should not be based on window messages at all. Use
other IPC mechanisms instead, such as named pipes, mailslots, or
TCP/IP sockets. As for communications inside the service amongst its
internal threads, there is no need for RegisterWindowMessage() at all.
Hard-code the message IDs instead, in the WM_APP range.


Gambit


Paul

unread,
Jan 27, 2007, 5:19:12 AM1/27/07
to

"Remy Lebeau (TeamB)" <no....@no.spam.com> schreef in bericht
news:45ba...@newsgroups.borland.com...

Remy,


The IPC hasn't been the problem.
In case you haven't noticed, the communication between that program and the
main service goes through a pipe.
There are a few threads that needs to switch to the input desktop and one of
them won't do it.
I know there are a few components that use a handle (like a timer), but they
are destroyed before switching to the new desktop and recreated afterwards.
But there is still something that's blocking the switch.

Paul


Remy Lebeau (TeamB)

unread,
Jan 27, 2007, 7:26:22 AM1/27/07
to

"Paul" <paul.bl...@telenet.be> wrote in message
news:45bb...@newsgroups.borland.com...

> The IPC hasn't been the problem. In case you haven't noticed, the
> communication between that program and the main service goes
> through a pipe. There are a few threads that needs to switch to the
> input desktop and one of them won't do it.

Like I said before, your internal threads have no reason to call
RegisterWindowMessage() in the first place. That is why Microsoft set
asside a specific range of messages that an application can use for
its private use. RegisterWindowMessages() is primarily used for when
multiple processes have to send messages to each other. That is not
the case here.

> I know there are a few components that use a handle (like a timer),
> but they are destroyed before switching to the new desktop and
> recreated afterwards.

You shouldn't be using a TTimer in a service to begin with. It is not
a thread-safe component (none of the UI components are). Use a
multimedia timer instead, via the timeSetEvent() function. It is a
threaded timer. If you must continue using TTimer, then keep it in
the TService's main thread only, as that thread has no business moving
between desktops anyway.


Gambit


Paul

unread,
Jan 27, 2007, 8:50:17 AM1/27/07
to

"Remy Lebeau (TeamB)" <no....@no.spam.com> schreef in bericht
news:45bb44ec$1...@newsgroups.borland.com...

>
> Like I said before, your internal threads have no reason to call
> RegisterWindowMessage() in the first place. That is why Microsoft set
> asside a specific range of messages that an application can use for
> its private use. RegisterWindowMessages() is primarily used for when
> multiple processes have to send messages to each other. That is not
> the case here.

I didn't change the communication to be compatible with another version, but
I can use a pipe.
I can change (and probably need according to Peter) the IPC, but this cannot
be the reason why the thread won't switch between desktops.

> You shouldn't be using a TTimer in a service to begin with. It is not
> a thread-safe component (none of the UI components are). Use a
> multimedia timer instead, via the timeSetEvent() function. It is a
> threaded timer. If you must continue using TTimer, then keep it in
> the TService's main thread only, as that thread has no business moving
> between desktops anyway.

Well, I disagree on this.
I've used timers in threads for years, and never had a single problem with a
timer, you only need a message loop,
and it can't be the problem with desktop switching. It's destroyed before
switching anyway.


Paul


Peter Below (TeamB)

unread,
Jan 27, 2007, 12:24:54 PM1/27/07
to
Paul wrote:

> I didn't change the communication to be compatible with another
> version, but I can use a pipe. I can change (and probably need
> according to Peter) the IPC, but this cannot be the reason why the
> thread won't switch between desktops.

If the thread already owns a window (which is tied to a desktop) it
cannot switch to another desktop, as far as I know. A TTimer creates a
helper window behind your back...

Remy Lebeau (TeamB)

unread,
Jan 27, 2007, 8:26:06 PM1/27/07
to

"Peter Below (TeamB)" <none> wrote in message
news:xn0f1pr5...@newsgroups.borland.com...

> A TTimer creates a helper window behind your back...

And like I said earlier, that is not thread-safe anyway. Creating
that window uses global resources that the VCL does not protect from
multi-threaded access.


Gambit


Paul

unread,
Jan 28, 2007, 4:39:52 AM1/28/07
to

"Peter Below (TeamB)" <none> schreef in bericht
news:xn0f1pr5...@newsgroups.borland.com...
> Paul wrote:
>

> If the thread already owns a window (which is tied to a desktop) it
> cannot switch to another desktop, as far as I know. A TTimer creates a
> helper window behind your back...

I know, and it's also destroyed before switching.

Just for testing, I changed the code and the whole thread is restarted and
recreated when the desktop changes.
The thread switches to the input desktop in it's execute before creating all
objects (and RegisterWindowMessage).
This works, so appearantly, RegisterWindowMessage does work across desktops.
But this is not the way I like it.
I also make a log of the desktop handles of 2 threads that have to 'follow'
the input desktop.
What confuses me is that both threads start in the same desktop (usually 40
on my PC), but after a desktop change, the new desktops are different in
both threads.


Paul


Paul

unread,
Jan 28, 2007, 4:48:03 AM1/28/07
to
What you are saying here that you cannot use a hidden window in a thread.

I know the VCL is not threadsafe, but a hidden window (not a form) can be
used without problems in a thread.
That's what a TTimer does.
Just the same as you van use bitmaps in thread's also as long as you lock
it's canvas

Paul


"Remy Lebeau (TeamB)" <no....@no.spam.com> schreef in bericht

news:45bbfba9$1...@newsgroups.borland.com...

Remy Lebeau (TeamB)

unread,
Jan 28, 2007, 6:22:10 AM1/28/07
to

"Paul" <paul.bl...@telenet.be> wrote in message
news:45bc711d$1...@newsgroups.borland.com...

> What you are saying here that you cannot use a hidden window in a
thread.

That is not what I said. Of course you can use a window in a thread -
in general. I was referring to the special fact of TTimer's hidden
window. TTimer uses AllocateHwnd() to create its window.
AllocateHWnd() in turn uses MakeObjectInstance() (as all VCL windows
components do) to create a proxy stub that allows a class method to
operate as an OS window procedure. MakeObjectInstance() allocates and
accesses shared resources that are not thread-safe. If you are not
careful, you can really mess things up for the VCL's window handlers.

If you really want to use a thread-specific window that is
thread-safe, you should use the Win32 API CreateWindow() function
directly.

> I know the VCL is not threadsafe, but a hidden window (not a form)
> can be used without problems in a thread. That's what a TTimer does.

If TTimer were using CreateWindow() by itself, then there would be no
problem. But it does more than that, and that is where problems begin
to appear.


Gambit


Paul

unread,
Jan 28, 2007, 7:49:18 AM1/28/07
to
Remy,

not only I use AllocHwnd, I've seen many programmers using it.
My most used program worldwide uses it and it's downloaded/installed a few
hundred times a day for almost 3 years.
Not a single one has complained it didn't work.
I don't what you need to prove it does or does not work, but for me it
proofs its working perfect.

Paul


"Remy Lebeau (TeamB)" <no....@no.spam.com> schreef in bericht

news:45bc875e$1...@newsgroups.borland.com...

Rob Kennedy

unread,
Jan 28, 2007, 2:18:42 PM1/28/07
to
Paul wrote:
> not only I use AllocHwnd, I've seen many programmers using it.
> My most used program worldwide uses it and it's downloaded/installed a few
> hundred times a day for almost 3 years.
> Not a single one has complained it didn't work.

That doesn't mean it worked. That just means no one told you about it,
or that when someone told you, you didn't recognize that it was a
threading issue with the timer.

> I don't what you need to prove it does or does not work, but for me it
> proofs its working perfect.

That's the thing about threads. No amount of testing will prove it's
correct. None. Because every time you test, it might just be a
coincidence that the race condition did not manifest itself -- every
time it was important, the right thread won the race. That only means
you're lucky, which is a hindrance in our line of work.

That doesn't mean your program is correct. If there is a race condition,
then your program has a bug. The wrong thread might win the race
someday. A change to something else in your program -- file I/O, perhaps
-- or a change to the way the operating system schedules threads to run,
could affect the order in which the instructions in your threads get run.

There are other ways of making code run periodically. You don't have to
use a TTimer. You can use a plain windows timer, or a multimedia timer,
or an ITimer, or a waitable timer. Just because TTimer is easy doesn't
change the fact that it's the wrong choice.

--
Rob

Remy Lebeau (TeamB)

unread,
Jan 29, 2007, 3:21:27 AM1/29/07
to

"Rob Kennedy" <m...@privacy.net> wrote in message
news:45bcf6d8$1...@newsgroups.borland.com...

> You can use a plain windows timer

Although TTimer wraps a "plain windows timer", it uses an HWND to
receive the timer message. Windows timers can also use callback
functions instead without the use of a HWND at all. All you need is
an active message queue, which you need in order for TTimer to work
anyway.


Gambit


Rob Kennedy

unread,
Jan 29, 2007, 3:34:43 AM1/29/07
to

Right. As I understant it, the problem with TTimer isn't that it uses a
window. The problem is how it gets that window -- AllocateHWnd and
MakeObjectInstance. If you create a window some other way, then there's
no problem with using a regular Windows timer.

--
Rob

0 new messages