PDA

View Full Version : زمان بیکار بودن کاربر



Ner'zhul Arthas
پنج شنبه 15 آذر 1386, 07:02 صبح
بهترین راه برای بدست اوردن زمان کار نکردن با برنامه چیه؟

مثلا اگر کاربر 20 دقیقه با برنامه کار نکرد، موس رو تکون نداد و از کیبرد استفاده نکرد برنامه خودش خاموش شه.

amirsajjadi
پنج شنبه 15 آذر 1386, 07:50 صبح
با سلام
ببین این کد بدردت میخوره
بعد از 5 ثانیه کار نکردن با کیبرد و موس برنامه بسته میشه

Dim OLD_X AsInteger = 0, OLD_Y AsInteger = 0
Dim NEW_X AsInteger = 0, NEW_Y AsInteger = 0

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If (Windows.Forms.Cursor.Position.X - Me.Location.X >= 0 AndAlso Windows.Forms.Cursor.Position.X <= Me.Location.X + Me.Size.Width) AndAlso (Windows.Forms.Cursor.Position.Y - Me.Location.Y >= 0 AndAlso Windows.Forms.Cursor.Position.Y <= Me.Location.Y + Me.Size.Height) Then
OLD_X = Windows.Forms.Cursor.Position.X - Me.Location.X
OLD_Y = Windows.Forms.Cursor.Position.Y - Me.Location.Y
If OLD_X = NEW_X AndAlso OLD_Y = NEW_Y Then
MsgBox("Idle")
Timer1.Enabled = False
Me.Dispose()
End If
NEW_X = Windows.Forms.Cursor.Position.X - Me.Location.X
NEW_Y = Windows.Forms.Cursor.Position.Y - Me.Location.Y
End If
End Sub

Ner'zhul Arthas
پنج شنبه 15 آذر 1386, 10:01 صبح
اگر تو فرم panel یا picturebox و ... داشته باشیم و موس توی اونا حرکت کنه برنامه وسط کار میپره بیرون.

saeed_rezaei
پنج شنبه 15 آذر 1386, 10:16 صبح
سلام.
به نظر من دو راه حل وجود داره.
اول: با استفاده از توابع api ورودی های صفحه کلید و ماوس رو بررسی کنیم. چنانچه هیچ عملی از کاربر نداشتیم اونوقت برنامه رو ببنیدم.
دوم: از screensaver کمک بگیریم، این خودش شامل دو حالت هست.
الف: یه برنامه بنویسیم که به جای screensaver اجرا بشه. این برنامه هنگام اجرا شدن، برنامه اصلی رو ببنده. (برای نوشتن یک screensaver کافیه که یه برنامه با وی بی بنوسیم و در نهایت پسوند فایل رو از exe به scr تغییر بدیم.)
ب: برنامه اصلی، توی لیست پروسسهای حافظه بررسی کنه، هر وقت یه پروسس داشتیم که با پسوند scr تو حافظه اومد، یعنی screensaver اجرا شده پس برنامه رو می بندیم.

Ner'zhul Arthas
پنج شنبه 15 آذر 1386, 10:54 صبح
در مورد ای پی آی چه ای پی آیی؟
در مورد اسکرین سیور که به نظر من اصلا راه خوبی نیست.
ممکنه کاربر اسکرین سیور رو خاموش کرده باشه، اصلا معلوم نیست رو چه زمانی تنظیم شده و ...
از همه مهم تر ممکنه کاربر با برنامه ی دیگه ای کار کنه که در نتیجه:
1: با این برنامه کار نکرده و این باید بسته شه.
2: اسکرین سیور هم حالا حالا ها کار نمیکنه.

amirsajjadi
پنج شنبه 15 آذر 1386, 20:15 عصر
با سلام
کد بالا رو درست کردم
ببین حالا خوب شده یا بازم مشکل داره

Ner'zhul Arthas
جمعه 16 آذر 1386, 11:35 صبح
اگر طرف موس رو برگردونه سر جای قبلی چی؟
اگر طرف داره با یه برنامه دیگه کار میکنه و پنجره ی اون برنامه روی این فرمه چی؟

saeed_rezaei
جمعه 16 آذر 1386, 23:06 عصر
اگر طرف موس رو برگردونه سر جای قبلی چی؟
اگر طرف داره با یه برنامه دیگه کار میکنه و پنجره ی اون برنامه روی این فرمه چی؟
سلام

من سری قبل درست منظورتون رو متوجه نشدم، البته دلیل هم وجود نداره که ثابت کنه این دفعه رو متوجه شدم.
مثل اینکه دو حالت وجود داره، یا برنامه بالای سایر فرمها است، ولی کاربر اصلا پای کامپیوتر نیست. نه موسی تکون می خوره و نه کلیدی از صفحه کلید فشرده می شه.
حالت دوم، کاربر پای سیستم نشسته اما با برنامه ما کار نمی کنه. برنامه شما رفته زیر یه فرم دیگه و یا کاربر اون رو minimize کرده.

هر وقت فرم ما توسط کاربر مورد استفاده قرار نگیره (زیر فرم دیگه قرار بگیره )و یا minimize بشه متد deactive اجرا می شه. پس یه طرف قضیه حل شد.

می مونه بررسی ماوس و صفحه کلید.
با متد form.keypress می تونیم بررسی کنیم که هنگامی که فرم بالا بوده کلیدی فشرده شده یانه. مشکل این قسمت اینه که اگه فوکاس توی یه کنترل دیگه مثل textbox باشه، و کلیدی فشرده بشه دیگه form.keypress اجرا نمی شه. برای حل این مشکل هم کافیه خاصیت keypreview فرم رو true کرد. با اینکار، فوکاس روی هر کنترل دیگه ای توی فرم که باشه، با فشردن یک کلید دوتا متد control.keypress و form.keypress هر دو اجرا می شن.
اما برای بررسی اینکه ماوس حرکت کرده یا نه، می دونیم که وقتی ماوس روی فرم جابه جا بشه متد form.mousemove اجرا می شه. اما هنوز مشکل حرکت بر روی کنترلهای درون فرم رو داریم. برای اینکه ماوس روی هر کنترلی که حرکت می کنه ، بخوایم تابع ما اجرا بشه و در عوض نخوایم کد نویسی بی خودی انجام بدیم، باید متد mousemove تمام کنترلها رو به تابع مورد نظرمون لینک بدیم. به صورت نمونه کد زیر، پس از اجرا، با حرکت ماوس روی هر کنترل درون فرم و بر روی خود فرم، برای همگی کد form.mousemove را اجرا می کنه.



Dim m As Control
For Each m In Me.Controls
AddHandler m.MouseMove, AddressOf Me.Form1_MouseMove
Next



البته کد حرکت ماوس فقط در چارچوپ فرم بررسی می شه، اما چنانچه قصد دارید که حتی حرکت ماوس بر روی خارج از اندازه فرم مورد بررسی قرار بگیره، کد دوستمون آقای سجادی مثل اینکه همین کار رو می کنه و البته این لینک هم هست.
http://barnamenevis.org/forum/showthread.php?t=73839&highlight=%D9%85%D8%A7%D9%88%D8%B3

amirsajjadi
شنبه 17 آذر 1386, 06:08 صبح
اگر طرف موس رو برگردونه سر جای قبلی چی؟
اگر طرف داره با یه برنامه دیگه کار میکنه و پنجره ی اون برنامه روی این فرمه چی؟

با سلام
1)احتمال اینکه کاربر موس رو سر جای اولش ببره خیلی کمه چون این برنامه بر حسب پیکسل مکان موس رو محاسبه میکنه
2)اگه کاربر با یک برنامه ی دیگه کار کنه که دیگه با برنامه ی شما کار نمیکنه ! :متعجب:


Dim KeyPress As Boolean = False
Dim OLD_X As Integer = 0, OLD_Y As Integer = 0
Dim NEW_X As Integer = 0, NEW_Y As Integer = 0

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If (Windows.Forms.Cursor.Position.X - Me.Location.X >= 0 AndAlso Windows.Forms.Cursor.Position.X <= Me.Location.X + Me.Size.Width) AndAlso (Windows.Forms.Cursor.Position.Y - Me.Location.Y >= 0 AndAlso Windows.Forms.Cursor.Position.Y <= Me.Location.Y + Me.Size.Height) Then
OLD_X = Windows.Forms.Cursor.Position.X - Me.Location.X
OLD_Y = Windows.Forms.Cursor.Position.Y - Me.Location.Y
If (OLD_X = NEW_X AndAlso OLD_Y = NEW_Y AndAlso KeyPress = False) Then
MsgBox("Idle")
Timer1.Stop()
Me.Dispose()
End If
KeyPress = False
NEW_X = Windows.Forms.Cursor.Position.X - Me.Location.X
NEW_Y = Windows.Forms.Cursor.Position.Y - Me.Location.Y
End If
End Sub

Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
KeyPress = True
End Sub

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.KeyPreview = True
Timer1.Interval = 5000
Timer1.Start()
End Sub

من فکر کنم شما منظورتون از این سوال این بوده که اگه برنامه کلا (نه فقط مکان موس و کلیدهای صفحه کلید) میزان درصد پروسس اون صفر بشه یعنی کلا هیچ کاری رو انجام نده از برنامه خارج بشه

یک شی PerformanceCounter به پروژتون اضافه کنید سپس در قسمت Form1.Designer.vb این کدها رو اضافه کنید


Me.PerformanceCounter1.CategoryName = "Process"
Me.PerformanceCounter1.CounterName = "% Processor Time"
Me.PerformanceCounter1.InstanceName = Process.GetCurrentProcess.ProcessName

سپس یک تایمر روی فرمتون بزارید و این کد رو بنویسید

If CStr(PerformanceCounter1.NextValue)=0 then msgbox "Idle"


ناگفته نمونه که با این کار هیچ وقت پروسس برنامتون صفر نمیشه چون تایمر فعال

Ner'zhul Arthas
شنبه 17 آذر 1386, 06:26 صبح
اگه کاربر با یک برنامه ی دیگه کار کنه که دیگه با برنامه ی شما کار نمیکنه !

همینو میخوام دیگه. یعنی وقتی کاربر با برنامه 20 دقیقه کار نکنه برنامه خاموش شه.

جوابمو گرفتم.

Ner'zhul Arthas
شنبه 17 آذر 1386, 07:16 صبح
اون چیزی که میخواستم دقیقا این بود:



Dim TimeExit As Stopwatch
Dim MouseX, MouseY As New Integer
Dim FormActive As Boolean

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
TimeExit = New Stopwatch
TimeExit.Start()
Me.KeyPreview = True
Timer1.Interval = 1000
Timer1.Start()
End Sub

Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
TimeExit.Reset()
TimeExit.Start()
End Sub

Private Sub Form1_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
FormActive = True
End Sub

Private Sub Form1_Deactivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Deactivate
FormActive = False
End Sub

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If FormActive Then
If MouseX <> Windows.Forms.Cursor.Position.X _
Or MouseY <> Windows.Forms.Cursor.Position.Y Then
MouseX = Windows.Forms.Cursor.Position.X
MouseY = Windows.Forms.Cursor.Position.Y
TimeExit.Reset()
TimeExit.Start()
Exit Sub
End If
End If

If TimeExit.ElapsedMilliseconds > 10000 Then
TimeExit.Reset()
Timer1.Enabled = False
MsgBox("idle")
End If
End Sub