Handling DDE messages from within a DLL routine - OS2

This is a discussion on Handling DDE messages from within a DLL routine - OS2 ; Hi, I want to be able to process DDE message from window (in PM) which I want to create from a DLL. I want the Window procedure code to be in the DLL Here is my approach, 1. Query the ...

+ Reply to Thread
Results 1 to 10 of 10

Thread: Handling DDE messages from within a DLL routine

  1. Handling DDE messages from within a DLL routine

    Hi,

    I want to be able to process DDE message from window (in PM) which I
    want to create from a DLL. I want the Window procedure code to be in
    the DLL

    Here is my approach,
    1. Query the anchor block of the parent window by WinQueryAnchorBlock
    2. Load the dll module though DosLoadModule and get the address to the
    window procedure in the DLL
    3. Create a window from DLL by using WinCreateStdWindow and registering
    the window procedure obtained by DosLoadModule
    4. Handle DDE messages in the PM procedure.

    Does this approach sound ok, does anyone see any flaws in this?
    Thanks in Advance,
    Chandan


  2. Re: Handling DDE messages from within a DLL routine

    On Mon, 27 Dec 2004 21:37:55 UTC, "maverick909"
    wrote:

    > Hi,
    >
    > I want to be able to process DDE message from window (in PM) which I
    > want to create from a DLL. I want the Window procedure code to be in
    > the DLL
    >
    > Here is my approach,
    > 1. Query the anchor block of the parent window by WinQueryAnchorBlock
    > 2. Load the dll module though DosLoadModule and get the address to the
    > window procedure in the DLL
    > 3. Create a window from DLL by using WinCreateStdWindow and registering
    > the window procedure obtained by DosLoadModule
    > 4. Handle DDE messages in the PM procedure.
    >
    > Does this approach sound ok, does anyone see any flaws in this?


    This sounds o.k.

    But I would write the DLL in a way that it would be runable in an
    ownstanding thread too. So it ould have an initiator procedure that
    creates the window it should serve by itself:

    I would it make a bit more flexible. Thell the DLL the HAB when it is
    inside the current thread that owns already one, give it NULL when it
    has to create its own as it is running in a not already initialised
    thread.

    From the callers sight the DLL is after it is loaded and you knows its
    entrypoint(s) always like each other function(s). You may give it at
    the right point even one or more pointers to callback functions inside
    the program or other DLL(s). There is nothing special in having a
    window procedure inside a DLL - what ever messages the window has to
    handle.

    Give the DLL even parent and owner HWNDs of the window you would embed
    the window that the DLL should control. I've here in a program that
    loads a DLL that handles a whole toolbar and does extensive
    subclassing of its items with some callbacks ito the rest of the app
    that loads it. The DLL gets loaden and then called with an big
    parameter block that defines the callbaks, the NLS resources, the
    helpfiles it has to use beside of the targets it has to send its own
    messages resulting from its controls to let other windows do theyr
    work resulting from the buttons in the toolbar.

    --
    Tschau/Bye
    Herbert

    Visit http://www.ecomstation.de the home of german eComStation
    eComStation 1.2 Deutsch ist da!

  3. Re: Handling DDE messages from within a DLL routine


    "maverick909" schrieb im Newsbeitrag
    news:1104183475.573097.22300@z14g2000cwz.googlegro ups.com...
    > Hi,
    >
    > I want to be able to process DDE message from window (in PM) which I
    > want to create from a DLL. I want the Window procedure code to be in
    > the DLL
    >
    > Here is my approach,
    > 1. Query the anchor block of the parent window by WinQueryAnchorBlock
    > 2. Load the dll module though DosLoadModule and get the address to the
    > window procedure in the DLL
    > 3. Create a window from DLL by using WinCreateStdWindow and registering
    > the window procedure obtained by DosLoadModule
    > 4. Handle DDE messages in the PM procedure.
    >
    > Does this approach sound ok, does anyone see any flaws in this?
    > Thanks in Advance,
    > Chandan
    >




  4. Re: Handling DDE messages from within a DLL routine

    Test
    "maverick909" schrieb im Newsbeitrag
    news:1104183475.573097.22300@z14g2000cwz.googlegro ups.com...
    > Hi,
    >
    > I want to be able to process DDE message from window (in PM) which I
    > want to create from a DLL. I want the Window procedure code to be in
    > the DLL
    >
    > Here is my approach,
    > 1. Query the anchor block of the parent window by WinQueryAnchorBlock
    > 2. Load the dll module though DosLoadModule and get the address to the
    > window procedure in the DLL
    > 3. Create a window from DLL by using WinCreateStdWindow and registering
    > the window procedure obtained by DosLoadModule
    > 4. Handle DDE messages in the PM procedure.
    >
    > Does this approach sound ok, does anyone see any flaws in this?
    > Thanks in Advance,
    > Chandan
    >




  5. Re: Handling DDE messages from within a DLL routine

    Hi,

    "maverick909" schrieb im Newsbeitrag
    news:1104183475.573097.22300@z14g2000cwz.googlegro ups.com...
    > Hi,
    >
    > I want to be able to process DDE message from window (in PM) which I
    > want to create from a DLL. I want the Window procedure code to be in
    > the DLL
    >
    > Here is my approach,
    > 1. Query the anchor block of the parent window by WinQueryAnchorBlock
    > 2. Load the dll module though DosLoadModule and get the address to the
    > window procedure in the DLL
    > 3. Create a window from DLL by using WinCreateStdWindow and registering
    > the window procedure obtained by DosLoadModule
    > 4. Handle DDE messages in the PM procedure.
    >
    > Does this approach sound ok, does anyone see any flaws in this?
    > Thanks in Advance,
    > Chandan


    Why do you want to make it that complicated ? If you have the window proc in
    the dll as well as the code that creates the window, there is no need to
    query the window procedure address as it is public inside the dll. The only
    thing you need is declare the window procedure at the top of the
    module/source code file:

    MRESULT EXPENTRY myWindowProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2);

    void myWindowCreate(....)
    {
    ....
    WinCreateStdWindow(...);
    WinRegisterClass(....,myWindowProc);
    ....
    }

    MRESULT EXPENTRY myWindowProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
    {
    ....
    }

    The only thing you need to do is declare myWindowCreate as exported inside
    the DLL's def-file if you want to call that routine from your main
    executable.

    Also, if code is called in the dll, it IS already loaded. No need to call
    DosLoadModule (unless you load a dll dynamically during runtime, but from
    what you describe this is not necessary).

    Maybe I am understanding something wrong here. In that case please explain
    again.

    Lars



  6. Re: Handling DDE messages from within a DLL routine

    Hi Lars/Herbet

    Thanks for your inputs,
    Lars, the reason for using DosLoadModule is that I found out the above
    approach does not give back a valid function pointer. I was trying to
    install a hook into the system message queue at that time. Found out
    that you need to query the Proc Address dynamically in order to get the
    correct function pointer of a procedure loaded in memory.

    I dont think simply having it as an exported function in the DLL would
    work, this is because the address of the procedure would be bound to
    the pointer at compile time, which is at best a stub address, however
    at run time the DLL can be loaded in any area of the memory. Im not
    sure about this but i think this is how it works out. Please let me
    know if you have tried the thing above and it worked!!!! It never
    worked for me.

    Also want to know, if I have two windows in an app, do I need to have
    one message queue for each of them and two message loops. I thought
    having onw mesage loop was enough for the whole app? Some people are
    saying otherwise

    Thanks and Regards,
    Chandan


  7. Re: Handling DDE messages from within a DLL routine

    On Thu, 30 Dec 2004 15:57:59 UTC, "maverick909"
    wrote:

    > Hi Lars/Herbet
    >
    > Thanks for your inputs,
    > Lars, the reason for using DosLoadModule is that I found out the above
    > approach does not give back a valid function pointer. I was trying to
    > install a hook into the system message queue at that time. Found out
    > that you need to query the Proc Address dynamically in order to get the
    > correct function pointer of a procedure loaded in memory.
    >
    > I dont think simply having it as an exported function in the DLL would
    > work, this is because the address of the procedure would be bound to
    > the pointer at compile time, which is at best a stub address, however
    > at run time the DLL can be loaded in any area of the memory. Im not
    > sure about this but i think this is how it works out. Please let me
    > know if you have tried the thing above and it worked!!!! It never
    > worked for me.
    >
    > Also want to know, if I have two windows in an app, do I need to have
    > one message queue for each of them and two message loops. I thought
    > having onw mesage loop was enough for the whole app? Some people are
    > saying otherwise


    You needs one message queue per thread that has at least one window.
    The thread main in PM looks like main(). That means begin each thread
    with its own intialising, then WinIntitialise(), create the message
    loop for that thread, and when your thread is finished with its
    initialising run the messe loop to dispatch what comes in into this
    thread and give up when the last window related to that thread is
    closen - like you does in main().

    The number of windows related on a thread is only at you and your
    design.

    Attention: Don't exit main() (thread one) when there are not each and
    any other thread is really closed - means the thread is exited
    completely and the system has removed it from the list of active
    threads! Ending main when there is at least one other PM thread active
    will result in crash. This kind of crash will commonly only occure on
    customers mashine, it is quite undebugable because the multithreading
    si sowhat of flexible that you would not abler to debug that.

    To be WARP3 compatible (WARP3 has noch API to wait for threads) I use
    this techique:

    Create somewhere a volatile int numthreads that counts the open
    threads. (any thread thats gets started increments it. When you main()
    has living its dispatching loop

    while (numthreads) /* the volatile can been changed by threads */
    DosSleep(1); /* give up CPU for other threads */

    In any thread: when it leaves its dispatch loop:
    - numthreads++; /* thread is alive now */

    - do any initialising
    - dispatch loop /* when PM */

    - clean up thread data
    - say main that the thread is die:
    DosEnterCritSec(); /* request CPU exclusive for this thread */
    /* because we have to lie until thread */
    /* is removed from CPU as it is die really */
    /* do some short cleanup requesting exclusive CPU */
    numthreads--; /* we're die now! */
    _endthread(); /* closes critical section magically when thread
    */
    /* gets removed from CPU because it IS die */



    --
    Tschau/Bye
    Herbert

    Visit http://www.ecomstation.de the home of german eComStation
    eComStation 1.2 Deutsch ist da!

  8. Re: Handling DDE messages from within a DLL routine

    maverick909 schrieb:
    > Hi Lars/Herbet
    >
    > Thanks for your inputs,
    > Lars, the reason for using DosLoadModule is that I found out the above
    > approach does not give back a valid function pointer. I was trying to
    > install a hook into the system message queue at that time. Found out
    > that you need to query the Proc Address dynamically in order to get the
    > correct function pointer of a procedure loaded in memory.
    >
    > I dont think simply having it as an exported function in the DLL would
    > work, this is because the address of the procedure would be bound to
    > the pointer at compile time, which is at best a stub address, however
    > at run time the DLL can be loaded in any area of the memory. Im not
    > sure about this but i think this is how it works out. Please let me
    > know if you have tried the thing above and it worked!!!! It never
    > worked for me.


    It does work. On load time of the DLL, the system loader (that thing that reads executables and dlls
    from disk, copies them to memory and starts the executables) resolves all the dummy routine address
    references and "fixes" those dummy addresses of the executable DLL image in memory (that's why those
    DLL dummy addresses that need to be resolved at runtime are called fixups).
    If it weren't so, you would not be able to call routine2 in a DLL from routine1 in that same DLL
    without going through a lot of hassle.
    I do remember however, that the hook function has to be in a COMPLETELY SEPARATE DLL (basically, a
    DLL that contains nothing more than that hook function), even if you want to register the hook
    function from within a(nother) DLL (where the initial thought would be to just place the hook
    function into that very same DLL).
    Also, the hook DLL will have to have MULTIPLE NONSHARED data segments as that hook function is
    called in the context of a whole lot of processes.

    > Also want to know, if I have two windows in an app, do I need to have
    > one message queue for each of them and two message loops. I thought
    > having onw mesage loop was enough for the whole app? Some people are
    > saying otherwise


    You need a message queue per thread. Every window constructed in that one thread uses the same
    message queue (of that thread).
    Also one message loop will be sufficient. The message loop will deliver the message to the correct
    window. WinDispatchMsg used qmsg->hwnd to find out the target window of a message. Then there is a
    1:1 relationship between a hwnd and a window procedure so the message will go to the correct window
    procedure.

    Lars

  9. Re: Handling DDE messages from within a DLL routine

    On Sat, 1 Jan 2005 23:01:20 UTC, Lars Erdmann wrote:
    >
    > I do remember however, that the hook function has to be in a COMPLETELY
    > SEPARATE DLL (basically, a DLL that contains nothing more than that hook
    > function), even if you want to register the hook function from within
    > a(nother) DLL (where the initial thought would be to just place the hook
    > function into that very same DLL). Also, the hook DLL will have to have
    > MULTIPLE NONSHARED data segments as that hook function is called in the
    > context of a whole lot of processes.


    This should *not* be necessary but it may be compiler dependent. I've
    written numerous programs with various types of message queue hooks.
    I always put the hook in the same dll as other code and use this in
    the DEF file: DATA SINGLE SHARED LOADONCALL However, all these were
    compiled using CSet/2 and its subsystem libraries.

    Currently, I'm working on a util to change PMShell's environment and
    using a queue-specific hook to enter the shell process. Sadly, it
    crashes the second time it's run in a session, generating a SYS3175
    in the runtime's rheapmin function. The only difference here is that
    I'm using VACPP 3.65. I wouldn't have thought that the subsystem
    library would have a heap but VACPP seems to think differently.
    I think I'll go back to CSet/2 for this one...

    BTW... the O.P.'s problem with hooks may be caused by a bug in Warp
    v4.5. When you release a hook, PM unloads the module containing it,
    even if PM didn't load the module initially. This is a good way to
    crash an app :-) The workaround is to reload the module yourself
    before setting the hook (or load the module twice if you're loading
    it yourself and want it to stay in memory after the hook is released).



    --
    == == almost usable email address: rich AT e-vertise.com == ==
    __________________________________________________ _________________
    |
    | New - Remote Workplace Server v0.60
    Rich Walsh | interact with the WPS from any program
    Ft Myers, FL | http://e-vertise.com/rws/rws060.zip
    __________________________________________________ _________________

  10. Re: Handling DDE messages from within a DLL routine

    Rich Walsh schrieb:
    > On Sat, 1 Jan 2005 23:01:20 UTC, Lars Erdmann wrote:
    >
    >>I do remember however, that the hook function has to be in a COMPLETELY
    >>SEPARATE DLL (basically, a DLL that contains nothing more than that hook
    >>function), even if you want to register the hook function from within
    >>a(nother) DLL (where the initial thought would be to just place the hook
    >>function into that very same DLL). Also, the hook DLL will have to have
    >>MULTIPLE NONSHARED data segments as that hook function is called in the
    >>context of a whole lot of processes.

    >
    >
    > This should *not* be necessary but it may be compiler dependent. I've
    > written numerous programs with various types of message queue hooks.
    > I always put the hook in the same dll as other code and use this in
    > the DEF file: DATA SINGLE SHARED LOADONCALL However, all these were
    > compiled using CSet/2 and its subsystem libraries.


    I have never been able to compile DLLs with DATA SINGLE SHARED.
    For VACPP 3.0 it was always necessary to use DATA MULTIPLE NONSHARED (at least if you use any RTL
    routines).
    Then I created an extra segment via SEGMENTS directive and declared that as SINGLE SHARED if I
    needed single,shared data.

    >
    > Currently, I'm working on a util to change PMShell's environment and
    > using a queue-specific hook to enter the shell process. Sadly, it
    > crashes the second time it's run in a session, generating a SYS3175
    > in the runtime's rheapmin function. The only difference here is that
    > I'm using VACPP 3.65. I wouldn't have thought that the subsystem
    > library would have a heap but VACPP seems to think differently.
    > I think I'll go back to CSet/2 for this one...


    See above for DATA directive. I have the impression that more than once process accesses data in
    your DLL. The RTL global data has to be per-process and I would think that even the subsystem RTL
    has some global data. It does support a few RTL routines.

    > BTW... the O.P.'s problem with hooks may be caused by a bug in Warp
    > v4.5. When you release a hook, PM unloads the module containing it,
    > even if PM didn't load the module initially. This is a good way to
    > crash an app :-) The workaround is to reload the module yourself
    > before setting the hook (or load the module twice if you're loading
    > it yourself and want it to stay in memory after the hook is released).


    Maybe that was what I observed. I wanted to release the hook but (of course) I wanted the rest of
    the code in the DLL to continue working.
    So I solved this with an extra dll for the hook without knowing :-)
    The compiler I used was Borland at that time but I guess that does not make a difference.

    Lars

+ Reply to Thread