Announcement

Collapse
No announcement yet.

The oldest question in the world....

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • The oldest question in the world....

    This is ofcourse a WINLift-project....
    I have the need to "bundle" an application into a DLL
    Code:
    Question #1:
    When the DLL is loaded a thread is created in which a Window (form in VB) 
    is created and a messagepump is started.
    The Window (form) is initially hidden (%SW_HIDE)
    This form is aktivated/deactivated via methodes in the DLL (%SW_SHOW/%SW_HIDE)
    
    When this DLL is unmapped (Freelibrary or application end) Is it then neccesary 
    to destroy the windows (this does not work) and terminate the messagepump?
    -----------
    Question #2:
    
    Look at this code and especially the Global ghDlg& thing, and explain to me why: 
      ghDlg& is a "local" variable in Callback Function CBButton 
    but 
      ghDlg& is a "global" variable in CBButton1
    
    #Compile Exe
    #Include "..\common\Win32Api.bas"
    Declare Function OPT_SHOWTRANSFORM Lib "FOX$TRAN.DLL" _
        (ByVal FileServer$,ByVal Transaktion$)As Long
    Declare Function OPT_INIT Lib "FOX$TRAN.DLL" _
        (ByVal hWndParent&,FileServer$)As Long
    Declare CallBack Function CBBUTTON1
    
    CallBack Function CBBUTTON
    #Register None
      Call OPT_INIT(ghDlg&,"\\NTSERVER\DATA\")
      Sleep 500
      Call opt_showtransform("\\NTSERVER\DATA\","19990511 12:13:14 00033702 Zvvg01.ffa ZSBI01.OMI XXXXXXXXXX")
    End Function
     
    Global ghDlg&
     
    Function PbMain() As Long
      DIALOG NEW 0,"TEST",,,600,400,%WS_CAPTION Or %WS_SYSMENU Or %WS_MINIMIZEBOX TO ghDlg&
    '   Call OPT_INIT(ghDlg&,"\\NTSERVER\DATA\")
       CONTROL ADD BUTTON, ghDlg&, 100&,"TRYCK",10,10,40,20, call CBButton
       CONTROL ADD BUTTON, ghDlg&, 101&,"TRYCK1",10,40,40,20, call CBButton1
      Dialog Show modal ghDlg&
    
    End Function
    CallBack Function CBBUTTON1
    #Register None
      Call OPT_INIT(ghDlg&,"\\NTSERVER\DATA\")
      Sleep 500
      Call opt_showtransform("\\NTSERVER\DATA\","19990511 12:13:14 00033702 Zvvg01.ffa ZSBI01.OMI XXXXXXXXXX")
    End Function

    -------------
    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se



    [This message has been edited by Fred Oxenby (edited May 25, 2000).]
    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se

  • #2
    Code:
    About Question #2
    I do understand why this can happen. (I think)
    But is it not a good point to start a discussion about how the
    compiler scan declaration-area and  code-area in a project?
    My coding-style means that I have *several* small includefiles in a project.
    As it works now, I have to *manually* scan my project and build a
    *project declaration-file* before I compile.
    This external procedure is part of the compilation, so I would not complain if this 
    modification added fraction of seconds to the compile-time

    ------------------
    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se

    Fred
    mailto:[email protected][email protected]</A>
    http://www.oxenby.se

    Comment


    • #3
      With regard to Q1: It is hard to answer without seeing the code, but you should at least ensure that your thread with the message pump terminates. Windows and dialog destruction will depend on how the DLL is being unloaded - if the whole app is closing, then windows should destroy the dialogs and windows automatically. Test for destruction notification by way of the %WM_DESTROY message in your window procedure (callback), and look into the LIBMAIN() function with %DLL_PROCESS_DETACH and %DLL_THREAD_DETACH.

      With regard to Q2: PB/DLL and PB/CC do not support forward referencing. Sorry! If you use #DIM ALL then you will catch this subtle "bug" in your code at compile time.

      ------------------
      Lance
      PowerBASIC Support
      mailto:[email protected][email protected]</A>
      Lance
      mailto:[email protected]

      Comment


      • #4
        Fred..

        My experience is that if you don't cause the threaded function to be exited to terminate the thread, then it is still running.
        To insure that in my code, I send the DLL a %WM_CLOSE and in that message have code to terminate the thread. In my main code
        I use WaitForSingleObject after sending %WM_CLOSE to determine that it is terminated for certain.


        ------------------
        Jim..
        [email protected]
        Jim..

        Comment


        • #5
          Fred,

          Lance and Jim are correct. Jim's idea of passing WM_CLOSE to the DLL is a good one. This will allow you to save whatever, then let WM_CLOSE default to default window procedure in the main window procedure. This will send the WM_DESTROY message where you can execute the "PostQuitMessage 0" code to terminate the message pump and exit the window created in the DLL.

          Just some more info:

          DLL_PROCESS_DETACH

          Indicates that the DLL is detaching from the address space of the calling process as a result of either a clean process exit or of a call to FreeLibrary. The DLL can use this opportunity to call the TlsFree function to free any TLS indices allocated by using TlsAlloc and to free any thread local data. When a DLL detaches from a process as a result of process termination or as a result of a call to FreeLibrary, the operating system does not call the DLL's entry-point function with the DLL_THREAD_DETACH value for the individual threads of the process. The DLL is only given DLL_PROCESS_DETACH notification. DLLs can take this opportunity to clean up all resources for all threads attached and known to the DLL.

          Cheers,
          Cecil

          ------------------


          [This message has been edited by Cecil Williams (edited May 26, 2000).]

          Comment


          • #6
            Fred,

            Within your code you can also destroy your windows just before WinLIFT performs a skUnregisterClass
            (See SKENGINE's Libmain at the end of the %DLL_PROCESS_DETACH message section)
            It is also always a good practice to unregister the specific classes that have been used by the DLL itself.

            ------------------
            Patrice Terrier
            mailto[email protected][email protected]</A>

            [This message has been edited by Patrice Terrier (edited May 26, 2000).]
            Patrice Terrier
            www.zapsolution.com
            www.objreader.com
            Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

            Comment


            • #7
              Code:
              Q1: Sadly, I had overlooked the WM_CLOSE message. Thanks for the hint!
                  It seems to be the most convenient way to handle things.
                  Create the window in DLL_PROCESS_ATTACH (or a separate DLL_INIT) 
                  and destroy it in DLL_PROCESS_DETACH
                  Only hiding/showing the window when needed speeds things up...
                  and simplifies the code
                  
              Q2: Lance, will PB compiler handle 'forward referencing' in a future. 
                  That is: have you got enough request for it to put it on the list?
                  Normally I use #Dim All. It is necessary because the lack of 
                  "forward reference feature" in the compiler....
                  But if you ever need to include source someone else have written
                  you will find that #Dim All is not always such a great feature.
                  
              I have a third 'question'/request:
                  SetWindowLongPtr has replaced SetWindowLong 
                  GWLP_HWNDPARENT has replaced GWL_HWNDPARENT  etc.
                  Will this be reflected in the next update of Win32Api.inc
                  Probably as there are lots of updates like this for 64-bit....

              ------------------
              Fred
              mailto:[email protected][email protected]</A>
              http://www.oxenby.se

              Fred
              mailto:[email protected][email protected]</A>
              http://www.oxenby.se

              Comment


              • #8
                At least _one_ of the reasons that forward referencing has not been implemented to date, is that it adds another pass to the compilation process. Other than that, you'll have to ask Bob Zale - he heads the R&D department, and R&D are responsible for feature implementation.

                If you want to add your voice to the suggestion list directly, send your ideas to mailto:[email protected][email protected]</A> .

                Thanks!

                BTW, I understand your comments on #DIM ALL, but the time that it takes to implement it when using other peoples code is often worthwhile - it can often help identify bugs in the code that you may otherwise *trust* will work! To do otherwise is to invite trouble... YMMV!


                ------------------
                Lance
                PowerBASIC Support
                mailto:[email protected][email protected]</A>
                Lance
                mailto:[email protected]

                Comment


                • #9
                  Code:
                    Some note from %WM_CLOSE testing.
                    I can verify that sending WM_CLOSE will destroy my windows one by one. 
                    So hat is OK.
                    I can also verify that sending PostQuitMessage terminates my thread
                    So that is OK as well.
                    But if I send PostQuitMessage as a response to %WM_DESTROY I will not be able to
                    verify that all windows are destroyed.
                    The "messagepump" seems to be exited before all %WM_DESTROY-messages are generated for child-windows
                    But this Childs are probably destroyed anyhow?
                    MSDN recommend PostQuitMessage to be generated in response to %WM_DESTROY, so this must be correct(?)

                  ------------------
                  Fred
                  mailto:[email protected][email protected]</A>
                  http://www.oxenby.se



                  [This message has been edited by Fred Oxenby (edited May 28, 2000).]
                  Fred
                  mailto:[email protected][email protected]</A>
                  http://www.oxenby.se

                  Comment


                  • #10
                    Fred,

                    Sending the WM_CLOSE message and letting that message be processed by your default window procedure causes the default window procedure to call the DestroyWindow function. See below.

                    From the windows help file:

                    The DestroyWindow function destroys the specified window. The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it. The function also destroys the window's menu, flushes the thread message queue, destroys timers, removes clipboard ownership, and breaks the clipboard viewer chain (if the window is at the top of the viewer chain).

                    If the specified window is a parent or owner window, DestroyWindow automatically destroys the associated child or owned windows when it destroys the parent or owner window. The function first destroys child or owned windows, and then it destroys the parent or owner window.

                    DestroyWindow also destroys modeless dialog boxes created by the CreateDialog function.

                    Hope this help clear up your concerns.

                    Cheers,
                    Cecil

                    ------------------

                    Comment

                    Working...
                    X