Subject Re: Form closing when idle
From Mervyn Bick <invalid@invalid.invalid>
Date Mon, 17 May 2021 09:07:32 +0200
Newsgroups dbase.getting-started
Attachment(s) close_on_idle.wfm

On 2021/05/16 21:47, Mustansir Ghor wrote:
> Dear Mervyn Sir
>
> Thank you so much.
>

I initially had the count-down display active all the time.
Unfortunately the code I added to only show the count-down for the final
minute wasn't properly tested.  I've now found that changing the
textlabel's visible property resets the timer.  As a result the form
never closes.

Attached is a revised version of the form which does doesn't reset the
timer when the count-down is displayed.

Mervyn.





clear
#include winuser.h
#define wm_mousewheel 0x020A  //not in winuser.h
** END HEADER -- do not remove this line
//
// Generated on 2021-05-13
//
parameter bModal
local f
f = new close_on_idleForm()
if (bModal)
   f.mdi = false // ensure not MDI
   f.readModal()
else
   f.open()
endif

class close_on_idleForm of FORM
   with (this)
      onMouseOver = class::FORM_ONMOUSEOVER
      onMouseOut = class::FORM_ONMOUSEOUT
      onOpen = class::FORM_ONOPEN
      onClose = class::FORM_ONCLOSE
      height = 18.4545
      left = 25.5714
      top = 1.4091
      width = 62.4286
      text = ""
   endwith

   this.ENTRYFIELD1 = new ENTRYFIELD(this)
   with (this.ENTRYFIELD1)
      height = 1.0
      left = 12.0
      top = 5.7273
      width = 25.7143
      value = "Entryfield1"
   endwith

   this.TEXTLABEL1 = new TEXTLABEL(this)
   with (this.TEXTLABEL1)
      height = 1.0
      left = 28.1429
      top = 0.8636
      width = 29.5714
      text = ""
   endwith

   this.ENTRYFIELD2 = new ENTRYFIELD(this)
   with (this.ENTRYFIELD2)
      height = 1.0
      left = 12.0
      top = 8.7273
      width = 25.7143
      value = "Entryfield2"
   endwith


   function attach
      if this.mhookProc == null
         CALLBACK CLONG MouseHookWndProc(CINT, CUINT, CUINT) OBJECT this
         this.mhookProc = GetCallAddress(class::MouseHookWndProc)
      endif      
      mhInst = GetWindowLong(int(form.hwnd), WH_MOUSE)
      this.mhook = SetWindowsHookEx(WH_MOUSE, this.mhookProc,mhInst, GetCurrentThreadId())
      if this.khookProc == null
         CALLBACK CLONG KeyHookWndProc(CINT, CUINT, CUINT) OBJECT this
         this.khookProc = GetCallAddress(class::KeyHookWndProc)
      endif    
      khInst = GetWindowLong(int(form.hwnd), WH_KEYBOARD)
      this.khook = SetWindowsHookEx(WH_KEYBOARD, this.khookProc,khInst, GetCurrentThreadId())
      return


   function detach
      UnhookWindowsHookEx(this.mhook)
      UnhookWindowsHookEx(this.khook)
      return

   function form_onClose()
      class::detach()
      this.timer.enabled = false
      return
      

   function form_onMouseOut(flags, col, row)
      form.mouseOver = false
      return

   function form_onMouseOver(flags, col, row)
      form.mouseOver = true
      return

   function form_onOpen()
      if type("GetCurrentThreadId") # "FP"
         extern CULONG GetCurrentThreadId() kernel32 from "GetCurrentThreadId"
      endif
      if type("GetWindowLong") # "FP"
         extern CLONG GetWindowLong(CHANDLE, CINT) user32 from "GetWindowLongA"
      endif
         if type("SetWindowsHookEx") # "FP"
       extern CLONG SetWindowsHookEx(CINT, CPTR, CHANDLE, CULONG) user32 from "SetWindowsHookExA"
      endif
      if type("UnhookWindowsHookEx") # "FP"
         extern CLOGICAL UnhookWindowsHookEx(CHANDLE) user32
      endif
      if type("CallNextHookEx") # "FP"
         extern CLONG CallNextHookEx(CHANDLE, CINT, CUINT, CUINT) user32
      endif
      form.mouseOver = true
      this.timer = new Timer( )
      this.timer.parent = this
      this.timer.seconds = seconds()
      this.timer.allow_idle_time = 60 *2 // 2 minutes. value in sconds
      this.timer.onTimer := this.check_action
      this.timer.interval =  1
      this.timer.enabled = true  // set false while developing form ********
      this.mhook = null
      this.khook = null
      this.mhookProc = null
      this.khookProc = null
      class::attach()  // comment out while developing form *********
      return
      

   function check_action
      this.parent.entryfield1.value = int(abs(seconds()-this.allow_idle_time-this.seconds)+1)
      if int(abs(seconds()-this.allow_idle_time-this.seconds)+1) < 61
        this.parent.textlabel1.text = 'This form will close in '+int(abs(seconds()-this.allow_idle_time-this.seconds)+1)+' second'+iif(int(abs(seconds()-this.allow_idle_time-this.seconds)+1) = 1,'', 's')
      else
         this.parent.textlabel1.text = ''
      endif
      if seconds()-this.allow_idle_time-this.seconds >1
         this.parent.close()
      endif  
      return

function MouseHookWndProc(hCode, wParam, lParam)
      if hCode = 0  and form.mouseOver = true
         if  wparam = wm_mousemove or ;
             wparam = wm_nclbuttondown or ;
             wparam = wm_lbuttondown or ;
             wparam = wm_rbuttondown or ;
             wparam = wm_mbuttondown or ;
             wparam = wm_mousewheel
             form.timer.seconds = seconds()
         endif
      endif      
      return CallNextHookEx(this.mhook, hCode, wParam, lParam)
      

  function KeyHookWndproc(hCode, wParam, lParam)
      t1 =  wParam   // virtual key code.
      t2 = lParam  // bit 31 = 0 keydown, bit 31 = 1 keyup
      if bitset(lparam,31)  = false  and hCode = 0 and form.mouseOver = true
         form.timer.seconds = seconds()
      endif
      return CallNextHookEx(this.khook, hCode, wParam, lParam)  
      

endclass