Solved

Postmessage and dll

Posted on 2003-10-21
7
2,824 Views
Last Modified: 2012-06-21
Hi

I have a weird problem I think, but first a littel about the setup:

I use Delphi 5, uses packages VCL50;Vclx50;te_d5 (the last is theme engine, but that shouldn't matter)
I have a exe and a dll.

I the dll I place this code. The code is about sending or posting a message to a window created by AllocatehWnd which then will call a procedure. It works fine when I use SendMessage, but when I use PostMessage the message never arrives, why?

If I use the code in the exe, everything is working fine, what is the difference, I thought it would be the same when I use packages.


type
    TProcedure = procedure;
    TTest = class(TObject)
    private
        SyncLock: TRTLCriticalSection;
        hMsgWnd: THandle;
        SyncP: TProcedure;
        procedure WndMessages(var Message: TMessage);
    public
        constructor Create;
        destructor Destroy; override;
        procedure Call1(P: TProcedure);        //Works
        procedure Call2(P: TProcedure);        //Don't work ??!
    end;

implementation

const
    WM_SYNCHRONIZE = WM_USER;

constructor TTest.Create;
begin
    InitializeCriticalSection(SyncLock);
    hMsgWnd := AllocatehWnd(WndMessages);
end;

destructor TTest.Destroy;
begin
    DeleteCriticalSection(SyncLock);
    DeallocatehWnd(hMsgWnd);
    inherited;
end;

procedure TTest.Call1(P: TProcedure);
begin
    EnterCriticalSection(SyncLock);
    SyncP := P;
    Windows.SendMessage(hMsgWnd, WM_SYNCHRONIZE, 0, 0);
end;

procedure TTest.Call2(P: TProcedure);
begin
    EnterCriticalSection(SyncLock);
    SyncP := P;
    Windows.PostMessage(hMsgWnd, WM_SYNCHRONIZE, 0, 0);
end;

procedure TTest.WndMessages(var Message: TMessage);
begin
    if Message.Msg = WM_SYNCHRONIZE then
    try
        SyncP;
    finally
        LeaveCriticalSection(SyncLock);
    end
    else
        Message.Result := DefWindowProc(hMsgWnd, Message.Msg, Message.wParam, Message.lParam);
end;



procedure CallProc;
begin
    messagebox(0,'ok','ok',0);
end;

var
    T: TTest;
procedure TestIt;
begin
    T := TTest.Create;
    T.Call1(CallProc);  //Works, uses sendmessage
    T.Call2(CallProc);  //Don't works, uses postmessage
end;
0
Comment
Question by:koger
7 Comments
 
LVL 8

Accepted Solution

by:
gmayo earned 30 total points
Comment Utility
Maybe it has something to do with the critical sections and order of processing. If you use sendmessage, the following happens:
1. Enter CS
2. Send message
2a. app receives message and handles it
3. Leave CS

But when you do PostMessage the order may be different:
1. Enter CS
2. Post message
3. Leave CS
and then
4. App receives message (or doesn't in your case)

I don't know what you are trying to achieve, but have a look at SendMessageTimeout too.

Geoff M.
0
 

Assisted Solution

by:OpenSourceDeveloper
OpenSourceDeveloper earned 30 total points
Comment Utility
the difference is that SendMessage waits for the target to receive the message and PostMessage adds it the message queue and returns immediately. you should only be using SendMessage for intra/interprocess communication.
0
 
LVL 33

Assisted Solution

by:Slick812
Slick812 earned 30 total points
Comment Utility
hello koger, there may or may not be a reason for this difference between the postMessage and SendMessage behavior, there are several descriptions given in the API documetation (Help) about the differences between Post and Send Message, And it mostly gives a "General" notice about when a PostMessage may not work (If the message queue is full). . . . But I have used both many times, and SendMessage, usually Always works, but PostMessage will work on some things and Not Work on other things, but I could not find any "Logic" or Connection of when it will not work. . . for me, I test it and if it don't go, then I change to SendMessage. .  However, I have not heard of a way to make it work if it does not. . . .
0
 
LVL 17

Assisted Solution

by:Wim ten Brink
Wim ten Brink earned 30 total points
Comment Utility
It might be related to the message being send to the Application object of the executable but not to the application object of the DLL. Or something related to this.
Maybe look at the SendMessageCallback() which is almost similar to the PostMessage function.
0
 
LVL 6

Assisted Solution

by:swift99
swift99 earned 30 total points
Comment Utility
SendMessage is defined by M$oft to wait for the method handling the message to retrn before returning control to the application.

Postmessage places the message in the target's message queue and returns immediately.   The target thread will handle the message in its own time.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

728 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

10 Experts available now in Live!

Get 1:1 Help Now