PDA

View Full Version : کم کردن سرعت چرخش اسکرول موس؟؟؟



سپهر-111
دوشنبه 30 مرداد 1391, 16:02 عصر
سلام دوستان گل
چطور میشه سرعت اسکرول موس کم کرد؟؟

من یک لیست باکس دارم
هر بارکه اسکرول موس چرخ میدم ، ایتم های لیست سه تا ، سه تا حرکت میکنه

ولی میخوام وقتی اسکرول میچرخونم یک ایتم حرکت کنه
ممنون میشم اگه دوستان راهنمایی کنند

در ضمن من از کامپاننت PowerTouch ، PowerList
استفاده میکنم

باتشکر از توجه شما

the king
دوشنبه 30 مرداد 1391, 17:43 عصر
سلام دوستان گل
چطور میشه سرعت اسکرول موس کم کرد؟؟

من یک لیست باکس دارم
هر بارکه اسکرول موس چرخ میدم ، ایتم های لیست سه تا ، سه تا حرکت میکنه

ولی میخوام وقتی اسکرول میچرخونم یک ایتم حرکت کنه
ممنون میشم اگه دوستان راهنمایی کنند

در ضمن من از کامپاننت PowerTouch ، PowerList
استفاده میکنم

باتشکر از توجه شما

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

در منوی Project ویژوال استدیو گزینه Add Module را انتخاب کرده و یک ماژول جدید به پروژه اضافه کنید.
این کد ها رو داخل اون ماژول فرضا Module1 بنویسید :

Private Const GWL_WNDPROC As Long = -4
Private Const WM_MOUSEWHEEL As Long = &H20A

Private Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Private prevProc As Long

Public Sub HookWindow(ByVal hWnd As Long)
prevProc = GetWindowLong(hWnd, GWL_WNDPROC)
SetWindowLong hWnd, GWL_WNDPROC, AddressOf ListWindowProc
End Sub

Public Sub UnhookWindow(ByVal hWnd As Long)
SetWindowLong hWnd, GWL_WNDPROC, prevProc
End Sub

Public Function ListWindowProc(ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim topIndex As Long
Select Case msg
Case WM_MOUSEWHEEL
topIndex = Form1.PowerList1.GetTopIndex
If wParam > 0 Then
Form1.PowerList1.SetTopIndex topIndex - 1
Else
Form1.PowerList1.SetTopIndex topIndex + 1
End If
ListWindowProc = 0
Case Else
ListWindowProc = CallWindowProc(prevProc, hWnd, msg, wParam, lParam)
End Select
End Function


در فرم Form1 تان با کد های زیر اون PowerList مورد نظر فرضا PowerList1 رو Hook کرده و موقع بستن فرم آزاد کنید :

Private Sub Form_Load()
HookWindow PowerList1.hWnd
End Sub

Private Sub Form_Unload(Cancel As Integer)
UnhookWindow PowerList1.hWnd
End Sub


اگر در جایی از کد ها دو تا کاراکتر فاصله بود و خطا داد فاصله ها رو حذف شون کنید، ایراد نمایشگر کد فروم ئه.

سپهر-111
دوشنبه 30 مرداد 1391, 18:40 عصر
وقتی اون اسکرول ماوس می چرخه پیغام WM_MOUSEWHEEL به پنجره کنترل مورد نظر (ListBox یا هر کنترل دیگری) ارسال میشه
و اون کنترل یا بر اساس مقدار اسکرول دریافت شده یا فقط بر اساس جهت اسکرول دریافت شده لیست رو بالا و پایین می کنه.
شما می توانید پیغام های اون کنترل رو شنود کنید (به اصطلاح WindowProc اش را Hook کنید) و بجای روال اصلی خودتون هر طور
که تمایل دارید و به هر میزانی که دوست دارید لیست رو بالا و پایین کنید.

در منوی Project ویژوال استدیو گزینه Add Module را انتخاب کرده و یک ماژول جدید به پروژه اضافه کنید.
این کد ها رو داخل اون ماژول فرضا Module1 بنویسید :

Private Const GWL_WNDPROC As Long = -4
Private Const WM_MOUSEWHEEL As Long = &H20A

Private Declare Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Private prevProc As Long

Public Sub HookWindow(ByVal hWnd As Long)
prevProc = GetWindowLong(hWnd, GWL_WNDPROC)
SetWindowLong hWnd, GWL_WNDPROC, AddressOf ListWindowProc
End Sub

Public Sub UnhookWindow(ByVal hWnd As Long)
SetWindowLong hWnd, GWL_WNDPROC, prevProc
End Sub

Public Function ListWindowProc(ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim topIndex As Long
Select Case msg
Case WM_MOUSEWHEEL
topIndex = Form1.PowerList1.GetTopIndex
If wParam > 0 Then
Form1.PowerList1.SetTopIndex topIndex - 1
Else
Form1.PowerList1.SetTopIndex topIndex + 1
End If
ListWindowProc = 0
Case Else
ListWindowProc = CallWindowProc(prevProc, hWnd, msg, wParam, lParam)
End Select
End Function


در فرم Form1 تان با کد های زیر اون PowerList مورد نظر فرضا PowerList1 رو Hook کرده و موقع بستن فرم آزاد کنید :

Private Sub Form_Load()
HookWindow PowerList1.hWnd
End Sub

Private Sub Form_Unload(Cancel As Integer)
UnhookWindow PowerList1.hWnd
End Sub


اگر در جایی از کد ها دو تا کاراکتر فاصله بود و خطا داد فاصله ها رو حذف شون کنید، ایراد نمایشگر کد فروم ئه.



سلام جناب KING
ممنون که پاسخ دادید
ولی نتونستم باهاش کار کنم
فایلم اپلود کردم ممنون میشم اگه چک بکنید
باتشکر

the king
دوشنبه 30 مرداد 1391, 20:02 عصر
سلام جناب KING
ممنون که پاسخ دادید
ولی نتونستم باهاش کار کنم
فایلم اپلود کردم ممنون میشم اگه چک بکنید
باتشکر




مشکل کد شما این بود که اسم فرم تان Form1 نبود و اسم PowerList ئه PowerList1
ماژول رو تغییر دادم، الان از HookPowerList و UnhookPowerList استفاده میشه و بجای hWnd اسم
خود PowerList مورد نظر رو دریافت می کنه.

در فرم تان هم فقط دو سطر که مربوط به این دو تا بود رو اضافه کردم، در Form_Load و Form_Unload
یادتان باشه که برنامه هایی که داخل شان موردی را Hook کرده اند رو ناگهانی متوقف نمی کنند
چون باید کد Unhook موقع خروج از برنامه اجرا بشه. بنابر این زمانی که خواستید برنامه در حال اجرا را
ببندید فرم را ببندید، از دکمه End ئه Debugger ویژوال استدیو استفاده نکنید (اونی که در منوی Run
ویژوال استدیو است را بکار نبرید) چون ممکنه ویژوال استدیو هنگ کنه.

91564

vbhamed
چهارشنبه 01 شهریور 1391, 08:16 صبح
سلام

حالا حتما مي‌خواين از طريق وي بي اينكار رو انجام بدين ؟ چرا ويندوز رو تنظيم نمي‌كنيد ؟

سپهر-111
چهارشنبه 01 شهریور 1391, 11:56 صبح
سلام

حالا حتما مي‌خواين از طريق وي بي اينكار رو انجام بدين ؟ چرا ويندوز رو تنظيم نمي‌كنيد ؟


سلام
از طریق ویندوز نمیشه
هرچقدر هم سرعتش چرخ موس کم کنی ، باز تو برنامه وی بی همونه
ولی کدی که جناب king دادند داره کار میکنه و سرعت چرخ موس تو برنامه تغییر میکنه
ممنون از توجه شما

setroyd
چهارشنبه 01 شهریور 1391, 13:19 عصر
یادتون باشه hook سرعت رو پایین میاره و تا جایی که امکان داره سعی کنید از hook کردن استفاده نکنید و راه دیگه رو انتخاب کنید .

سپهر-111
چهارشنبه 01 شهریور 1391, 18:33 عصر
یادتون باشه hook سرعت رو پایین میاره و تا جایی که امکان داره سعی کنید از hook کردن استفاده نکنید و راه دیگه رو انتخاب کنید .



سلام
البته من میخوام اینطوری از ش استفاده کنم :
وقتی فوکس موس روی شی بود hook فعال بشه و وقتی فوکس نبود hook غیر فعال بشه؟؟؟
آیا این طوری خوبه؟؟ سرعت پایین نمیاد؟؟؟

setroyd
چهارشنبه 01 شهریور 1391, 19:02 عصر
ببین hook ویندوز رو وادار به چک کردن میکنه در هر زمان که میگذره به صورت مداوم که شرط شما چک بشه پس این سرعت رو میگیره ولی اینطور که شما میگی در همون لحظه سرعت کمی کاهش پیدا میکنه و بعدش دوباره درست میشه . بهرهال این چیزی نیست که نیاز به hook داشته باشه من فکر میکنم .

the king
چهارشنبه 01 شهریور 1391, 19:16 عصر
سلام
البته من میخوام اینطوری از ش استفاده کنم :
وقتی فوکس موس روی شی بود hook فعال بشه و وقتی فوکس نبود hook غیر فعال بشه؟؟؟
آیا این طوری خوبه؟؟ سرعت پایین نمیاد؟؟؟

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

saber67
دوشنبه 25 دی 1391, 18:46 عصر
اگه بخوایم بفهمیم کاربر روی یه کنترلی با موس اسکرول کرده از همین روش باید استفاده کنیم؟
منظورم اینه مثلا تابع خاصی تعریف کنیم که کاربر با اسکرول کردن اجراش کنه! مثل بعضی پلیرها که با اسکرول صدا رو کم و زیاد می کنن

جناب the king، من کدتون رو امتحان کردم
موقع اجرا از تابع HookWindow ایراد می گیره!

این خطا رو میده:
Compile error:

Invalid use of addressOf operator

باید چه طوری نوشته بشه که خطای کامپایل نگیره؟ در ضمن من فاصله ها رو هم چک کردم

saber67
دوشنبه 25 دی 1391, 19:37 عصر
باید چه طوری نوشته بشه که خطای کامپایل نگیره؟

آقا حل شد مشکلم! باید تابع ListWindowProc حتما توی ماژول تعریف بشه! من توی خود فرم تعریف کرده بودم که ایراد می گرفت!