PDA

View Full Version : سوال: کلید میانبر شخصی برای menu strip



david1363
شنبه 26 تیر 1400, 08:33 صبح
سلام من میخوام در فرم اصلی وقتی دکمه های میانبر رو میزنم فرم مد نظرم باز بشه مثلا کلید عدد 25 و میزنم فرم 1 باز بشه وقتی کلید 2a میزنم فرم 2 کلید 6c میزنم فرم 3 به همین ترتیب میخوام کلید برای فرم های مدنظرم تعریف کنم با یک حرف میتونم باز کنم ولی با دو حرف نشد در ضمن از کلیدهای Ctrl , Alt ,Shift نمیخوام استفاده گنم فقط از اعداد رقمی 10 تا 99 و ترکیبشون با حروف مثل 2a , 3b 4a 8k 9m و غیره .......

david1363
شنبه 26 تیر 1400, 14:39 عصر
کسی نیست جواب بده ؟؟؟؟؟؟؟؟؟؟؟؟؟

david1363
شنبه 26 تیر 1400, 19:50 عصر
???????????????????:متفکر::متفکر::متف کر::متفکر::متفکر::متفکر::متفک ر::متفکر::متفکر::متفکر::متفکر ::متفکر::متفکر::متفکر::متفکر:

david1363
یک شنبه 27 تیر 1400, 15:10 عصر
کلیدهای میانبر داخل صف قرار دادم بازم نشد

Public Class Form1
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown Dim q As Queue(Of Integer) = New Queue(Of Integer)()
q.Enqueue(25)
q.Enqueue(26)
For Each element As Integer In q
If element = 25 Then
Form2.Show()
If element = 26 Then
Form3.Show()

End If
End If
Next
End Sub
End Class

mazoolagh
دوشنبه 28 تیر 1400, 12:32 عصر
1- بجای queue از list هم میتونین استفاده کنین.
2- اگر بجای رخداد keydown از رخداد keypress استفاده کنین کدنویسی کمی راحتتر هست، چون مستقیما keychar رو دارین.
3- کدی که نوشتین قطعا جواب نمیده:

اول باید یک list یا queue خالی داشته باشید.
با هر keypress اگر keychar برای اولین کارآکتر مجاز هست (یعنی list/queue خالی هست) به list/queue اضافه میشه.
اگر keychar برای دومین کارآکتر هست (لیست یک آیتم داره) : اگر مجاز هست که به لیست اضافه بشه و لیست چک بشه که متناسب با کدوم فرم هست وگرنه لیست دوباره پاک بشه.
اگر ترکیب کلیدها با یک فرم متناظر هست اون فرم باز و لیست پاک بشه، اگر نیست : اگر کلید بعنوان کلید اول مجاز هست آیتم اول لیست پاک بشه (کلید دوم بعنوان کلید اول) و گرنه کل لیست پاک بشه.


آلگوریتم بالا رو پیاده کنین جواب میگیرین.

david1363
سه شنبه 29 تیر 1400, 13:33 عصر
نشد.....................

david1363
چهارشنبه 30 تیر 1400, 22:32 عصر
1- بجای queue از list هم میتونین استفاده کنین.
2- اگر بجای رخداد keydown از رخداد keypress استفاده کنین کدنویسی کمی راحتتر هست، چون مستقیما keychar رو دارین.
3- کدی که نوشتین قطعا جواب نمیده:

اول باید یک list یا queue خالی داشته باشید.
با هر keypress اگر keychar برای اولین کارآکتر مجاز هست (یعنی list/queue خالی هست) به list/queue اضافه میشه.
اگر keychar برای دومین کارآکتر هست (لیست یک آیتم داره) : اگر مجاز هست که به لیست اضافه بشه و لیست چک بشه که متناسب با کدوم فرم هست وگرنه لیست دوباره پاک بشه.
اگر ترکیب کلیدها با یک فرم متناظر هست اون فرم باز و لیست پاک بشه، اگر نیست : اگر کلید بعنوان کلید اول مجاز هست آیتم اول لیست پاک بشه (کلید دوم بعنوان کلید اول) و گرنه کل لیست پاک بشه.


آلگوریتم بالا رو پیاده کنین جواب میگیرین.

ممنون میشم کسی بلده این کد و بنویسه کمک کنه من نتونستم این و نوشتم خطا میده

Imports System.Reactive.Linq



Public Class Main
Protected Overrides Sub OnLoad(ByVal e As EventArgs)
MyBase.OnLoad(e)


Dim factories = New Dictionary(Of String, Func(Of Form))() From
{
{"25", Function() New Form1()},
{"2a", Function() New Form2()}
}


_subscription =
Observable.
FromEventPattern(Of KeyPressEventHandler, KeyPressEventArgs)(
Sub(h) AddHandler Me.KeyPress, h,
Sub(h) RemoveHandler Me.KeyPress, h).
Buffer(2).
Select(Function(x) New String(x.[Select](Function(y) y.EventArgs.KeyChar).ToArray())).
Where(Function(x) factories.ContainsKey(x)).
ObserveOn(Me).
Select(Function(x) factories(x).Invoke()).
Subscribe(Sub(f) f.Show())
End Sub


Private _subscription As IDisposable = Nothing


Private Sub Main_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
Call _subscription.Dispose()


End Sub

mazoolagh
پنج شنبه 31 تیر 1400, 08:29 صبح
کدی رو که نوشتین روش کارش رو نمیدونم چجوری هست،
ولی اون الگوریتم که دادم گرچه در ظاهر حرفه ای نیست ولی در عمل کار میکنه (امیدوارم!)



اول یک تابع مینویسیم که ترکیب کلیدها رو میگیره و اگر فرمی متناظر با این ترکیب تعریف شده باشه اون رو باز میکنه وگرنه false برمیگردونه.


اینجوری کد اصلی شلوغ نمیشه و خواناتر هست.




function show_form(key_sequence as string) as boolean
show_form=true
select case key_sequence
case "25"
my.forms.form1.show
case "2a"
my.forms.form2.show
...
...
...
case else
show_form=false
end select
end function

mazoolagh
پنج شنبه 31 تیر 1400, 08:40 صبح
2. چون شما به queue اشاره کردین، کد رو هم برای queue و هم برای list نوشتم (با // جدا کردم) و انتخابش رو بعهده خودتون میگذارم.
فقط در حال کلی list قابلیت انعطاف بیشتری داره و ارجح هست، در این مسئله خاص تفاوتی نداره.

dim q as new queue(of string) // dim list as new list(of string)


sub form_keypress
if not char.isletterordigit(e.keychar) then exit sub
select case q.count // list.count
case 0 ' check for first key
if e.keychar>="1" andalso e.keychar<="9" then
q.enqueue(e.keychar) // list.add(e.keychar)
else
q.clear // list.clear
end if
case 1 ' check for second key
if char.isletterordigit(e.keychar) then
q.enqueue(e.keychar) // list.add(e.keychar)
if show_form(join(q.toarray // list.toarray, string.empty)) then
q.clear // list.clear
else
if char.isletter(e.keychar) orelse e.keychar="0" then
q.clear // list.clear
else
q.dequeue // list.removeat(0)
end if
end if
else
q.clear // list.clear
end if
end select
end sub

طبق مثالی که آوردین شرط ها بر این اساس بوده که برای کلید اول فقط ارقام 0-9 و کلید دوم فقط alphanumeric،
غیر از این هست ویرایش کنین.

mazoolagh
پنج شنبه 31 تیر 1400, 08:44 صبح
3- قطعا key preview رو روشن کردین.

4- اگر در فرم textbox یا هر کنترلی که قابلیت key-press داره داشته باشین که قرار هست text هم قبول کنه، باید یک فکری براش بکنین.

david1363
پنج شنبه 31 تیر 1400, 14:37 عصر
3- قطعا key preview رو روشن کردین.

4- اگر در فرم textbox یا هر کنترلی که قابلیت key-press داره داشته باشین که قرار هست text هم قبول کنه، باید یک فکری براش بکنین.
سلام بالاخره نوشتم

Friend Class DoubleKeyPressHandler Private keyQueue As New Queue(Of Keys)
Public Sub New()
Actions = New Dictionary(Of Integer, Action) From {
{Keys.D2 << 16 Or Keys.D5, Sub() Call New Form2().Show()},
{Keys.NumPad2 << 16 Or Keys.NumPad5, Sub() Call New Form2().Show()},
{Keys.NumPad2 << 16 Or Keys.A, Sub() Call New Form3().Show()},
{Keys.D2 << 16 Or Keys.A, Sub() Call New Form3().Show()}
}
End Sub


Public ReadOnly Actions As Dictionary(Of Integer, Action)


Public Sub Add(ByVal key As Keys)
keyQueue.Enqueue(key)
TryMapKeys()
End Sub


Private Sub TryMapKeys()
If keyQueue.Count < 2 Then Return
Dim key1 = keyQueue.Dequeue
Dim key2 = keyQueue.Dequeue
Dim dKey = key1 << 16 Or key2
Dim keyAction As Action = Nothing
If Actions.TryGetValue(dKey, keyAction) Then
keyAction.Invoke()
Else
' If the combination is not a match, the last Key is added back
' Remove the Else block if you prefer to cancel it instead. Test it.
keyQueue.Enqueue(key2)
End If
End Sub
End Class

david1363
پنج شنبه 31 تیر 1400, 14:38 عصر
اینم برای فرم مورد نظر

Public Class Form1 Private keyPressHandler As New DoubleKeyPressHandler()


Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
keyPressHandler.Add(keyData)
Return MyBase.ProcessCmdKey(msg, keyData)
End Function

mazoolagh
یک شنبه 03 مرداد 1400, 12:43 عصر
اینکه نتیجه کار و کدهای خودتون رو با دیگران به اشتراک میگذارین بسیار کار پسنده ای هست و خوبه که دیگران هم همینجور باشن.

اگر فرصت دارین کدی رو که گذاشتم هم تست کنین و خبر بدین، چون مطمئن نیستم همونی باشه که خواسته شما بوده:
من بر مبنای این که 2 کلید به ترتیب زده بشن نوشتم ولی الان شک دارم که شاید شما کلید همزمان مد نظرتون بوده.

david1363
پنج شنبه 07 مرداد 1400, 00:26 صبح
اینکه نتیجه کار و کدهای خودتون رو با دیگران به اشتراک میگذارین بسیار کار پسنده ای هست و خوبه که دیگران هم همینجور باشن.

اگر فرصت دارین کدی رو که گذاشتم هم تست کنین و خبر بدین، چون مطمئن نیستم همونی باشه که خواسته شما بوده:
من بر مبنای این که 2 کلید به ترتیب زده بشن نوشتم ولی الان شک دارم که شاید شما کلید همزمان مد نظرتون بوده.
سلام کد مورد نظر شما نوشتم با چندین تغییر کار نکرد ممنون

mazoolagh
دوشنبه 11 مرداد 1400, 11:58 صبح
من دقیقا همین کدی رو که در پست 8 و 9 گذاشته بودم پیاده کردم و درست کار میکرد!