Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Timer in Windows

Status
Not open for further replies.

rotemfo

Programmer
Joined
Mar 6, 2002
Messages
1
Location
IL
Hi,
I am writing a simple application in VBScript to shutdown a database. I want a user to interact with a MsgBox and if the MsgBox is idle for 5 seconds, it will close and the application will continue.
How do i do that ?????
help appreciated
mailto:rotem_fo@hotmail.com
Thanks
 
well AFAIK, code stops when a msgbox is shown. so i think the best solution to your problem is to create a form that looks like a msgbox, and put a timer on it, then when it fires, unload the form. and make it so that the buttons on the msgbox form call subs on the main form.

i hope this helps...

Phr3t ------------------------------------------
ps. visit for some of my muzic...
------------------------------------------
dex_fx@hotmail.com
dj_fret@hotmail.com
phr3t@hotmail.com
 
put this in a module

Code:
  Option Explicit
  ' demo project showing how to use the API to manipulate a messagebox
  ' by Bryan Stafford of New Vision Software® - newvision@mvps.org
  ' this demo is released into the public domain "as is" without
  ' warranty or guaranty of any kind.  In other words, use at
  ' your own risk.
  '
  ' IMPORTANT NOTE:  the following constant is used to toggle desktop
  ' redrawing in this project.  if you set it equal to one (1), the project
  ' will turn off redrawing to the desktop.  Setting it to zero (0) will not
  ' lock the desktop.  if you will be stepping through the code in break
  ' mode, MAKE SURE YOU SET THIS CONSTANT TO ONE (1)!!!!  otherwise, you
  ' will not be able to see ANY screen updates!!!  also, on faster machines,
  ' turning off redrawing may not be necessary to achieve the desired effect.
  Public Const TURN_ON_UPDATES As Long = 0
  
  ' the max length of a path for the system (usually 260 or there abouts)
  ' this is used to size the buffer string for retrieving the class name of the active window below
  Public Const MAX_PATH As Long = 260&

  Public Const API_TRUE As Long = 1&
  Public Const API_FALSE As Long = 0&
  
  ' font *borrowed* from the form used to replace MessageBox font
  Public g_hBoldFont As Long
  
  Public Const MSGBOXTEXT As String = "Have you ever seen a standard message box with a different font than all the others on the system?"
  Public Const WM_SETFONT As Long = &H30&
  Public Const WM_SETTEXT As Long = &HC&

  ' made up constants for setting our timer
  Public Const NV_CLOSEMSGBOX As Long = &H5000&
  Public Const NV_MOVEMSGBOX As Long = &H5001&
  Public Const NV_MSGBOXCHNGFONT As Long = &H5002&

  ' MessageBox() Flags
  Public Const MB_ICONQUESTION As Long = &H20&
  Public Const MB_TASKMODAL As Long = &H2000&

  ' SetWindowPos Flags
  Public Const SWP_NOSIZE As Long = &H1&
  Public Const SWP_NOZORDER As Long = &H4&
  Public Const HWND_TOP As Long = 0&

  Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
  End Type

  ' API declares
  Public Declare Function GetActiveWindow& Lib "user32" ()
  
  Public Declare Function GetDesktopWindow& Lib "user32" ()
  
  Public Declare Function FindWindow& Lib "user32" Alias "FindWindowA" (ByVal lpClassName$, _
                                                                        ByVal lpWindowName$)

  Public Declare Function FindWindowEx& Lib "user32" Alias "FindWindowExA" (ByVal hWndParent&, _
                              ByVal hWndChildAfter&, ByVal lpClassName$, ByVal lpWindowName$)

  Public Declare Function SendMessage& Lib "user32" Alias "SendMessageA" (ByVal hWnd&, ByVal _
                                                        wMsg&, ByVal wParam&, lParam As Any)

  Public Const WM_CLOSE As Long = &H10&
  Public Const WM_SETREDRAW As Long = &HB&

  Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd&, ByVal wMsg&, _
                                                                ByVal wParam&, lParam As Any) As Long

  Public Declare Function MoveWindow& Lib "user32" (ByVal hWnd&, ByVal x&, ByVal y&, _
                                              ByVal nWidth&, ByVal nHeight&, ByVal bRepaint&)

  Public Declare Function ScreenToClientLong& Lib "user32" Alias "ScreenToClient" (ByVal hWnd&, _
                                                                                    lpPoint&)
  
  Public Declare Function GetDC& Lib "user32" (ByVal hWnd&)
  Public Declare Function ReleaseDC& Lib "user32" (ByVal hWnd&, ByVal hDC&)

  ' drawtext flags
  Public Const DT_WORDBREAK As Long = &H10&
  Public Const DT_CALCRECT As Long = &H400&
  Public Const DT_EDITCONTROL As Long = &H2000&
  Public Const DT_END_ELLIPSIS As Long = &H8000&
  Public Const DT_MODIFYSTRING As Long = &H10000
  Public Const DT_PATH_ELLIPSIS As Long = &H4000&
  Public Const DT_RTLREADING As Long = &H20000
  Public Const DT_WORD_ELLIPSIS As Long = &H40000
  
  Public Declare Function DrawText& Lib "user32" Alias "DrawTextA" (ByVal hDC&, ByVal lpsz$, _
                                          ByVal cchText&, lpRect As RECT, ByVal dwDTFormat&)
  
  Public Declare Function GetClassName& Lib "user32" Alias "GetClassNameA" (ByVal hWnd&, _
                                                        ByVal lpClassName$, ByVal nMaxCount&)

  Public Declare Function GetWindowRect& Lib "user32" (ByVal hWnd&, lpRect As RECT)
  
  Public Declare Function SetWindowPos& Lib "user32" (ByVal hWnd&, ByVal hWndInsertAfter&, _
                                      ByVal x&, ByVal y&, ByVal cx&, ByVal cy&, ByVal wFlags&)
                                      
  Public Declare Function MessageBox& Lib "user32" Alias "MessageBoxA" (ByVal hWnd&, _
                                                ByVal lpText$, ByVal lpCaption$, ByVal wType&)

  Public Declare Function SetTimer& Lib "user32" (ByVal hWnd&, ByVal nIDEvent&, ByVal uElapse&, _
                                                                            ByVal lpTimerFunc&)
  
  Public Declare Function KillTimer& Lib "user32" (ByVal hWnd&, ByVal nIDEvent&)

Public Sub TimerProc(ByVal hWnd&, ByVal uMsg&, ByVal idEvent&, ByVal dwTime&)
  ' this is a callback function.  This means that windows "calls back" to this function
  ' when it's time for the timer event to fire
  
  ' first thing we do is kill the timer so that no other timer events will fire
  KillTimer hWnd, idEvent
  
  ' select the type of manipulation that we want to perform
  Select Case idEvent
    Case NV_CLOSEMSGBOX '<-- we want to close this messagebox after 4 seconds
      Dim hMessageBox&
      
      ' find the messagebox window
      hMessageBox = FindWindow(&quot;#32770&quot;, &quot;Self Closing Message Box&quot;)
      
      ' if we found it send it a wm_close message
      If hMessageBox Then Call PostMessage(hMessageBox, WM_CLOSE, ByVal 0&, ByVal 0&)
      
    Case NV_MOVEMSGBOX '<-- we want to move this messagebox
      Dim hMsgBox&, xPoint&, yPoint&
      Dim stMsgBoxRect As RECT, stParentRect As RECT
      
      ' find the messagebox window
      hMsgBox = FindWindow(&quot;#32770&quot;, &quot;Position A Message Box&quot;)
    
      ' if we found it then move it
      If hMsgBox Then
        ' get the rect for the parent window and the messagebox
        Call GetWindowRect(hMsgBox, stMsgBoxRect)
        Call GetWindowRect(hWnd, stParentRect)
        
        ' calculate the position for putting the messagebox in the middle of the form
        xPoint = stParentRect.Left + (((stParentRect.Right - stParentRect.Left) \ 2) - _
                                              ((stMsgBoxRect.Right - stMsgBoxRect.Left) \ 2))
        yPoint = stParentRect.Top + (((stParentRect.Bottom - stParentRect.Top) \ 2) - _
                                              ((stMsgBoxRect.Bottom - stMsgBoxRect.Top) \ 2))
        
        ' make sure the messagebox will not be off the screen.
        If xPoint < 0 Then xPoint = 0
        If yPoint < 0 Then yPoint = 0
        If (xPoint + (stMsgBoxRect.Right - stMsgBoxRect.Left)) > _
                                          (Screen.Width \ Screen.TwipsPerPixelX) Then
          xPoint = (Screen.Width \ Screen.TwipsPerPixelX) - (stMsgBoxRect.Right - stMsgBoxRect.Left)
        End If
        If (yPoint + (stMsgBoxRect.Bottom - stMsgBoxRect.Top)) > _
                                          (Screen.Height \ Screen.TwipsPerPixelY) Then
          yPoint = (Screen.Height \ Screen.TwipsPerPixelY) - (stMsgBoxRect.Bottom - stMsgBoxRect.Top)
        End If
        
        
        ' move the messagebox
        Call SetWindowPos(hMsgBox, HWND_TOP, xPoint, yPoint, _
                                        API_FALSE, API_FALSE, SWP_NOZORDER Or SWP_NOSIZE)
      End If
      
      ' unlock the desktop
      If TURN_ON_UPDATES Then Call SendMessage(GetDesktopWindow(), WM_SETREDRAW, ByVal API_TRUE, ByVal 0&)
      
      
    Case NV_MSGBOXCHNGFONT '<-- we want to change the font for this messagebox
      '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      ' NOTE: Changing the font of a message box is not recomemded!!
      '       This portion of the demo is just provided to show some of the possibilities
      '       for manipulating other windows using the Windows API.
      '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      
      ' find the messagebox window
      hMsgBox = FindWindow(&quot;#32770&quot;, &quot;Change The Message Box Font&quot;)
    
      ' if we found it then find the static control that holds the text...
      If hMsgBox Then
        Dim hStatic&, hButton&, stMsgBoxRect2 As RECT
        Dim stStaticRect As RECT, stButtonRect As RECT
        
        ' find the static control that holds the message text
        hStatic = FindWindowEx(hMsgBox, API_FALSE, &quot;Static&quot;, MSGBOXTEXT)
        hButton = FindWindowEx(hMsgBox, API_FALSE, &quot;Button&quot;, &quot;OK&quot;)
        
        ' if we found it, change the text and resize the static control so it will be displayed
        If hStatic Then
          ' get the rects of the message box and the static control before we change the font
          Call GetWindowRect(hMsgBox, stMsgBoxRect2)
          Call GetWindowRect(hStatic, stStaticRect)
          Call GetWindowRect(hButton, stButtonRect)
          
          ' set the font we borrowed from the form into the static control
          Call SendMessage(hStatic, WM_SETFONT, g_hBoldFont, ByVal API_TRUE)
          
          ' you could change the button text to anything you want using the next line...
          Call SendMessage(hButton, WM_SETTEXT, ByVal 0&, ByVal &quot;Close&quot;)
          
          With stStaticRect
            ' convert the rect from screen coordinates to client coordinates
            Call ScreenToClientLong(hMsgBox, .Left)
            Call ScreenToClientLong(hMsgBox, .Right)
            
            Dim nRectHeight&, nHeightDifference&, hStaticDC&
            
            ' get the current height of the static control
            nHeightDifference = .Bottom - .Top
            
            ' get the device context of the static control to pass to DrawText
            hStaticDC = GetDC(hStatic)
            
            ' use DrawText to calculate the new height of the static control
            nRectHeight = DrawText(hStaticDC, MSGBOXTEXT, (-1&), stStaticRect, _
                                              DT_CALCRECT Or DT_EDITCONTROL Or DT_WORDBREAK)
            
            ' release the DC
            Call ReleaseDC(hStatic, hStaticDC)
            
            ' calculate the difference in height
            nHeightDifference = nRectHeight - nHeightDifference
            
            ' resize the static control so that the new larger bold text will fit in the messagebox
            Call MoveWindow(hStatic, .Left, .Top, .Right - .Left, nRectHeight, API_TRUE)
          End With
            
          ' move the button to the new position
          With stButtonRect
            ' convert the rect from screen coordinates to client coordinates
            Call ScreenToClientLong(hMsgBox, .Left)
            Call ScreenToClientLong(hMsgBox, .Right)
            
             ' move the button
            Call MoveWindow(hButton, .Left, .Top + nHeightDifference, .Right - .Left, .Bottom - .Top, API_TRUE)
          End With
          
          With stMsgBoxRect2
            ' resize and reposition the messagebox
            Call MoveWindow(hMsgBox, .Left, .Top - (nHeightDifference \ 2), .Right - .Left, (.Bottom - .Top) + nHeightDifference, API_TRUE)
          
            ' NOTE: if your message is very long, you may need to add code to make sure the messagebox
            ' will not run off the screen....
          End With
        End If
      End If
      
      ' unlock the desktop
      If TURN_ON_UPDATES Then Call SendMessage(GetDesktopWindow(), WM_SETREDRAW, ByVal API_TRUE, ByVal 0&)
  
  End Select
  
End Sub

put this in a form

Code:
  Option Explicit
  ' demo project showing how to use the API to manipulate a messagebox
  ' by Bryan Stafford of New Vision Software® - newvision@mvps.org
  ' this demo is released into the public domain &quot;as is&quot; without
  ' warranty or guaranty of any kind.  In other words, use at
  ' your own risk.

Private Sub Command1_Click()
  ' this shows a messagebox that will be dismissed after 4 seconds
  
  ' set the callback timer and pass our application defined ID (NV_CLOSEMSGBOX)
  ' set the time for 4 seconds (4000& microseconds)
  SetTimer hWnd, NV_CLOSEMSGBOX, 4000&, AddressOf TimerProc

  ' call the messagebox API function
  Call MessageBox(hWnd, &quot;Watch this message box close itself after four seconds&quot;, _
      &quot;Self Closing Message Box&quot;, MB_ICONQUESTION Or MB_TASKMODAL)
  
End Sub

Private Sub Command2_Click()
  ' this positions the messagebox in the desired location on the screen.
  ' the location is defined in the callback timer function
  
  ' lock the desktop so that the initial position is not shown
  If TURN_ON_UPDATES Then Call SendMessage(GetDesktopWindow(), WM_SETREDRAW, ByVal API_FALSE, ByVal 0&)
  
  ' set the callback timer with our application defined ID (NV_MOVEMSGBOX)
  ' set the time for 10 microseconds to allow the messagebox time to become active
  SetTimer hWnd, NV_MOVEMSGBOX, 10&, AddressOf TimerProc

  ' call the messagebox API function
  Call MessageBox(hWnd, &quot;Have you ever seen a message box that wasn't in the middle of the screen?&quot;, _
                                        &quot;Position A Message Box&quot;, MB_ICONQUESTION Or MB_TASKMODAL)

End Sub

Private Sub Command3_Click()
  ' this changes th font for the message text of the messagebox.
  ' the routine in the callback timer function
  
  ' lock the desktop so that the initial font is not shown
  If TURN_ON_UPDATES Then Call SendMessage(GetDesktopWindow(), WM_SETREDRAW, ByVal API_FALSE, ByVal 0&)
  
  ' set the callback timer with our application defined ID (NV_MSGBOXCHNGFONT)
  ' set the time for 10 microseconds to allow the messagebox time to become active
  SetTimer hWnd, NV_MSGBOXCHNGFONT, 10&, AddressOf TimerProc

  ' call the messagebox API function
  Call MessageBox(hWnd, MSGBOXTEXT, &quot;Change The Message Box Font&quot;, MB_ICONQUESTION Or MB_TASKMODAL)

End Sub

Private Sub Form_Load()

  ' we will use the font from the form to change the text in one of our message boxes
  ' first, set the attributes of the font that we will want to display.
  With Font
    .Bold = True
    .Italic = True
  End With
  
  ' next, grab a handle to the form's font and store it in the global variable for use later.
  ' don't change the font on the form or the value in the global variable will be invalid.
  Dim IFont As IFont
  Set IFont = Font

  g_hBoldFont = IFont.hFont
  
  Set IFont = Nothing
  
End Sub
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top