Announcement

Collapse
No announcement yet.

Mouse Must Move to Quit

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

  • Mouse Must Move to Quit

    After triggering an event, I attempt to
    exit the program gracefully. However,
    it appears that the program will not
    exit, until I move the mouse over the
    dialog or the icon in the system-tray!

    Any thoughts anyone ?

    Here's most of the code I'm using:
    Code:
    '-----------------------------------
    #COMPILE EXE
    #RESOURCE "SBRICO.PBR"
    #INCLUDE "d:\pbdll60\winapi\WIN32API.INC"
    
    %WM_TRAYICON = %WM_USER + 100
    %WM_TRIGGER = %WM_TIMECHANGE
    
    GLOBAL hInst AS LONG
    GLOBAL MyEvent AS LONG
    
    FUNCTION WINMAIN (BYVAL CurInst AS LONG, _
                      BYVAL PrvInst AS LONG, _
                      CmdLine AS ASCIIZ PTR, _
                      BYVAL CmdShow AS LONG) EXPORT AS LONG
    
      hInst = CurInst
    
      ' Initialize
      DIALOGBox hInst, BYVAL 100&, %HWND_DESKTOP, CODEPTR(Main_Callback)
    
    END FUNCTION
    
    FUNCTION Main_Callback(BYVAL hDlg AS LONG, BYVAL wMsg AS LONG, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
    
      STATIC hMenu AS LONG
      STATIC ti    AS NOTIFYICONDATA
      STATIC p     AS POINTAPI
    
      LOCAL result&
      
      SELECT CASE wMsg
    
        CASE %WM_INITDIALOG
          ' Get Menu Handle
          hMenu = GetSubMenu(LoadMenu(hInst, "POPUPMENU"), 0)
    
          ' Add tray icon
          ti.cbSize           = SIZEOF(ti)
          ti.hWnd             = hDlg
          ti.uID              = hInst
          ti.uFlags           = %NIF_ICON OR %NIF_MESSAGE OR %NIF_TIP
          ti.uCallbackMessage = %WM_TRAYICON
          ti.hIcon            = LoadIcon(hInst, "SBR1")
          ti.szTip            = "Schedule Reboot"
          Shell_NotifyIcon %NIM_ADD, ti
          DestroyIcon ti.hIcon
    
          mHwd = hDlg
          FUNCTION = 1
    
        CASE %WM_TRAYICON
    
          SELECT CASE LOWRD(lParam)
    
            ' Left button press
            CASE %WM_LBUTTONDOWN
              IF IsWindowVisible(hDlg) = %FALSE THEN
                ShowWindow hDlg, %SW_SHOW
              END IF
    
            ' Right button press
            CASE %WM_RBUTTONDOWN
              IF IsWindowVisible(hDlg) = %FALSE THEN
                SetForegroundWindow hDlg
                GetCursorPos p
                TrackPopupMenu hMenu, 0, p.x, p.y, 0, hDlg, BYVAL %NULL
                Postmessage hDlg, %WM_NULL, 0, 0
              END IF
    
          END SELECT
    
        CASE %WM_TRIGGER
          IF MyEvent THEN
            ' Trigger - to close program
            ' Here's where the problem is!
            ' When this is triggered, the program
            ' waits for the mouse to move over either
            ' the icon or the dialog, before the program
            ' actually ends!
            ' Why is waiting for the mouse-movement ?????
            CALL PostQuitMessage(0)
            FUNCTION = 1
            EXIT FUNCTION
          END IF
        
        CASE %WM_DESTROY
          ' ** Remove the tray icon if the application is closed
          Shell_NotifyIcon %NIM_DELETE, ti
    
        CASE %WM_COMMAND
          
          SELECT CASE LOWRD(wParam)
    
            CASE 101
              ' Do something
              MSGBOX "Okay"
    
            CASE %IDOK
              ' Display the about box
              DialogBox hInst, BYVAL 101&, %HWND_DESKTOP, CODEPTR(AboutProc)
    
            CASE %IDCANCEL
              ' exit out quickly
                EndDialog hDlg, 0
                
          END SELECT
    
        CASE %WM_SYSCOMMAND
    
          ' If minimize or close pressed - hide
          SELECT CASE LOWRD(wParam)
    
            CASE %SC_MINIMIZE
              ShowWindow hDlg, %SW_HIDE
              FUNCTION = 1
              EXIT FUNCTION
    
            CASE %SC_CLOSE
              ShowWindow hDlg, %SW_HIDE
              FUNCTION = 1
              EXIT FUNCTION
    
          END SELECT
    
      END SELECT
    
    END FUNCTION
    
    FUNCTION AboutProc(BYVAL hDlg AS LONG, BYVAL wMsg AS LONG, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
    
      LOCAL result&
      
      SELECT CASE wMsg
    
        CASE %WM_INITDIALOG
    
          FUNCTION = 1
    
        CASE %WM_COMMAND
    
          IF LOWRD(wParam) = %IDOK THEN
            EndDialog hDlg, 0
            FUNCTION = 1
          END IF
    
      END SELECT
    
    END FUNCTION
    Thanks
    Mike



    -------------
    mwm
    mwm

  • #2
    Michael --
    1) When you post any code, insert
    [c o d e] tag before and [/c o d e] tag after program text. (without spaces)
    2) If your program use PBR, it's necessary to post RC (better w/o icons, bmp).
    Otherwise nobody can't start your program.
    3) Because I can't start your module, I can only say that sometimes the best way to finish dialog is
    PostMessage hWnd, %WM_USER + xxx, 0, 0
    Case %WM_USER + xxx
    EndDialog ...
    (xxx - any free value, for example, 999)

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


    [This message has been edited by Semen Matusovski (edited April 06, 2000).]

    Comment


    • #3
      If you can post a complete code example, we may be able to help further (how are you generating the %WM_TRIGGER event?). Be sure to trim the code down as much as necessary while still clearly demonstrating the problem. Thanks!

      BTW, have you examined the TRAY.BAS example shipped with PB/DLL?

      {later}
      By the time I edited the code posting to add the tags, Semen replied to your message, however his suggestion seems to be to use a custom message to kiil the app - however, your %WM_TRIGGER code looks like that is what you intended. However, you are using PostQuitMessage() and your app does not have a message loop - the only message loop is provided by Windows in the dialog engine. You should only need to use EndDialog().

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

      Comment


      • #4

        Semen/Lance - didn't know about the code/tag! Now I do.

        Lance....This is 99% of the tray program!

        Semen - What you suggested, is what I've already tried!
        Everything works, but until I move the mouse,
        the program is still showing on the screen!

        Reasons: If a program had completed a task, that may
        take an hour to do, you could walk away and
        the program would terminate upon completion!

        The answer is here somewhere! Just got to keep hack'n
        and find it!

        Thanks!
        Mike


        ------------------
        mwm
        mwm

        Comment


        • #5

          Lance,

          Using EndDialog(), I have to move the mouse over
          the Dialog (if visible) and the icon in the sys-tray
          for the program to complete exit!

          And you are right, in that the %WM_TRIGGER is an
          event that I trigger with DIALOG SEND()

          Mike




          ------------------
          mwm
          mwm

          Comment


          • #6
            What happens if you leave the %SC_CLOSE handling code out of the callback, at least just for testing purposes?

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

            Comment


            • #7
              I have encountered this problem with other programs. Like Webtv for windows, after that program shuts down the Icon is still in the system tray and does not disapear until I move the mouse pointer over it. I happens with a few other system tray programs too. It may be a bug in win98 (which is what I am running). Have you checked the Microsoft KB?
              Kevin

              ------------------
              mailto:[email protected][email protected]</A>
              :-)

              Comment


              • #8
                Unfortunately, Michael didn't post whole sample and it's impossible to understand - this is refresh problem only or the task is stays in Task Manager (really not finished).
                If this is refresh problem, it's possible to hide window before exit by ShowWindow ..., 0.

                About icon in SysTray. This is known feature (not refreshed).
                For example, in Console Tools' help you can find
                "If you use the Close (x) button or the Windows Task Manager to close or "end" a program while a System Tray icon is being displayed, the icon may not disappear right away. It will usually disappear the first time the mouse cursor is moved over the System Tray."



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

                Comment


                • #9

                  Thanks, all for the possible tips!

                  Semen, as I stated earlier, the code is 99% Tray.bas
                  example which I think you already have. Take that
                  same example, add a trigger for exit, and exit without
                  using the mouse! Then you will be where I am at!

                  Lance, I did try that after I saw your postings.
                  Still hanging the icon.

                  What's interesting, take out the sys-tray and icon portion,
                  and replace it with %WM_MINIMIZE and it all works fine!

                  Once again, thanks. Anyone finding a solution, please let
                  me know!

                  Mike




                  ------------------
                  mwm
                  mwm

                  Comment


                  • #10
                    Michael -
                    I added "Stop" button (exit from dialog)

                    Code:
                    #Compile Exe
                    #Resource "TRAY.PBR"
                    #Include "WIN32API.INC"
                    %WM_TRAYICON = %WM_USER + 400
                    Global hInst As Long
                    Function PbMain
                      hInst = GetModuleHandle(ByVal 0)
                      DialogBox hInst, ByVal 100&, %HWND_DESKTOP, CodePtr(DialogProc)
                    End Function
                    
                    CallBack Function DialogProc
                      Static hMenu As Long
                      Static ti    As NOTIFYICONDATA
                      Static p     As POINTAPI
                    
                      Select Case CbMsg
                        Case %WM_INITDIALOG
                          hMenu = GetSubMenu(LoadMenu(hInst, "POPUPMENU"), 0)
                          ti.cbSize           = SizeOf(ti)
                          ti.hWnd             = CbHndl
                          ti.uID              = hInst
                          ti.uFlags           = %NIF_ICON Or %NIF_MESSAGE Or %NIF_TIP
                          ti.uCallbackMessage = %WM_TRAYICON
                          ti.hIcon            = LoadIcon(hInst, "FACE1")
                          ti.szTip            = "Task Tray Example"
                          Shell_NotifyIcon %NIM_ADD, ti
                          DestroyIcon ti.hIcon
                          Dialog Set Size CbHndl, 100, 200
                          Control Add Button, CbHndl, 201, "Stop", 10, 150, 50, 15
                    
                        Case %WM_TRAYICON
                          Select Case CbLparam
                            ' Left button press
                            Case %WM_LBUTTONDOWN: If IsWindowVisible(CbHndl) = %FALSE Then ShowWindow CbHndl, %SW_SHOW
                            ' Right button press
                            Case %WM_RBUTTONDOWN
                              If IsWindowVisible(CbHndl) = %FALSE Then
                                SetForegroundWindow CbHndl
                                GetCursorPos p
                                TrackPopupMenu hMenu, 0, p.x, p.y, 0, CbHndl, ByVal %NULL
                              End If
                          End Select
                        Case %WM_DESTROY: Shell_NotifyIcon %NIM_DELETE, ti
                        Case %WM_COMMAND
                          Select Case CbCtl
                            Case 101 To 105
                               ' Change tray icon
                               ti.hIcon = LoadIcon(hInst, "FACE" & Format$(CbCtl - 100) )
                               Shell_NotifyIcon %NIM_MODIFY, ti: DestroyIcon ti.hIcon
                            Case %IDOK
                              DialogBox hInst, ByVal 101&, %HWND_DESKTOP, CodePtr(AboutProc)
                            Case %IDCANCEL, 201
                               If MessageBox(CbHndl, "Close Tray Example and remove its icon from the task tray?" , _
                                  "Tray Example", %MB_ICONEXCLAMATION Or %MB_OKCANCEL) = %IDOK Then _
                                  Dialog End CbHndl, 0
                          End Select
                        Case %WM_SYSCOMMAND
                          Select Case CbCtl
                            Case %SC_MINIMIZE: ShowWindow CbHndl, %SW_HIDE: Function = 1: Exit Function
                            Case %SC_CLOSE   : ShowWindow CbHndl, %SW_HIDE: Function = 1: Exit Function
                          End Select
                      End Select
                    End Function
                    
                    CallBack Function AboutProc
                      If CbMsg = %WM_COMMAND And CbCtl = %IDOK Then Dialog End CbHndl, 0
                    End Function
                    ------------------

                    Comment


                    • #11

                      Semen, I owe you a case of beer!

                      That work flawlessly!

                      Thanks

                      Mike


                      ------------------
                      mwm
                      mwm

                      Comment


                      • #12

                        Semen, here's what I did.

                        In your code, I changed it to do the following:

                        Code:
                          
                           Case %IDCANCEL, 201
                              
                             ' hide it
                             ShowWindow CBHNDL, %SW_HIDE
                             ' perform the task
                             Call DoATask  
                             ' exit program
                             Dialog End CbHndl, 0
                        My DoATask routine used PTree to write 40,000 records.
                        When it got done writing, the program, icon and all
                        exited gracefully!

                        Once again, Thanks

                        Mike


                        ------------------
                        mwm
                        mwm

                        Comment

                        Working...
                        X