السلام عليكــم ورحمـة الله وبركاتــه ،،
واجهتنى مشكلة ذات مرة وهى أنى نسيت كلمة المرور الخاصة بالـ FTP :wacko:
لكن من حسن حظى أن برنامج Core FTP يقوم بحفظ كلمة المرور ولذلك كنت أستطيع الاتصال بدون مشاكل
لكن لو قمت بإزالة البرنامج أو تغيير النسخة لن أستطيع الاتصال لأن كلمة المرور المحفوظة سيتم إزالتها
لذا فكرت فى كتابة بعض الأكواد للحصول على كلمة المرور من البرنامج ورأيت أن أضع الكود هنا للفائدة
طبعا الكود يعتمد كليا على دوال الـ API :huh:
الخطوات المتبعة :
1- إنشاء مشروع جديد
2- وضع أداتى Timer و TextBox على الفورم
3- كتابة الأكواد المطلوبة كما يلى
أولا نقوم باستيراد مجال الأسماء System.Runtime.InteropServices ثم نبدأ بالإعلان عن الدوال التى سنستخدمها
<DllImport("User32.dll")> _
Private Shared Function SendMessage(ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
<DllImport("User32.dll", EntryPoint:="SendMessage")> _
Private Shared Function SendMessageString(ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
End Function
<DllImport("User32.dll")> _
Private Shared Function WindowFromPoint(ByVal xPoint As Integer, ByVal yPoint As Integer) As Integer
End Functionثانيا نقوم بتعريف الرسائل التى سنستخدمها
Private Const WM_GETTEXTLENGTH As Integer = &HE Private Const WM_GETTEXT As Integer = &HD Private Const EM_SETPASSWORDCHAR As Integer = &HCC
ثالثا نقوم بتهيئة الفورم والتايمر فى حدث تحميل الفورم
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.TopMost = True Me.Timer1.Interval = 100 Me.Timer1.Enabled = True End Sub
حسنا ,,
الآن يبدأ الجزء المهم وهو كود التايمر
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick 'Our code goes here... End Sub
أول شئ يجب أن نصل إليه هو مقبض الأداة الموجودة تحت مؤشر الفأرة ويتم هذا باستخدام الدالة WindowFromPoint وطبعا للحصول على مكان المؤشر نستخدم Cursor.Position
فيكون أول جزء فى الكود كالتالى
Dim curPos As Point = Windows.Forms.Cursor.Position Dim hwnd As Integer = WindowFromPoint(curPos.X, curPos.Y)
بعد هذا السطر سيحمل المتغير hwnd قيمة مقبض النافذة التى يشير إليها المؤشر وهى قيمة لا تساوى صفر طبعا
يجب أن نعرف أننا بالحصول على مقبض النافذة
يمكننا أن نغير فيها كيفما نشاء كأننا أصحاب البرنامج الذى يحتويها :P
الآن بعد أن حصلنا على مقبض الأداة يجب أن نعرف طول النص المكتوب بداخلها
يمكن الحصول عليه باستخدام الدالة GetWindowTextLength لكنى أفضل SendMessage
عموما لك الحرية فى استخدام ما تريد
المهم للحصول على طول النص نقوم بتمرير الرسالة WM_GETTEXTLENGTH وبالتأكيد سنمرر الرسالة إلى النافذة التى حصلنا على المقبض الخاص بها
Dim textLength As Integer = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0) + 1
الآن نقوم بتعريف متغير وتهيئته ليستقبل النص المكتوب
Dim buffer As String = Space(textLength)
الآن نستقبل النص عن طريق إرسال الرسالة WM_GETTEXT
عند إرسال هذه الرسالة يجب أن يحمل المعامل wParam عدد المحارف التى سنقوم بقراءتها وبما أننا نريد أن نقرأ النص بالكامل فسنقوم بتمرير قيمة textLength التى حصلنا عليها
والمعامل lParam هو المتغير الذى سيستقبل النص وهو buffer
بما إن المعامل lParam نوعه String فسنستخدم التعريف الثانى للدالة SendMessage وهو SendMessageString
فيكون الكود بهذا الشكل
SendMessageString(hwnd, WM_GETTEXT, textLength, buffer)
الآن المتغير buffer يحمل النص المكتوب ,, سنقوم بعرضه داخل الـ TextBox
Me.TextBox1.Text = buffer
حسنا ,, إلى هنا يمكن أن يعمل البرنامج ويقوم بعرض النص داخل برنامجنا
لكن نريد أن نعرض النص داخل الأداة الخاصة به أى فى نفس البرنامج الذى يحتوى على كلمة المرور :D
نستخدم لذلك الرسالة EM_SETPASSWORDCHAR ونمرر القيمة 0 للمعامل wParam
SendMessage(hwnd, EM_SETPASSWORDCHAR, 0, 0)
طبعا لتغيير حرف كلمة المرور PasswordCharacter يمكن إرسال قيمة الحرف بالأسكى للمعامل wParam
الكود بالكامل
Imports System.Runtime.InteropServices
Public Class Form1
<DllImport("User32.dll")> _
Private Shared Function SendMessage(ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
<DllImport("User32.dll", EntryPoint:="SendMessage")> _
Private Shared Function SendMessageString(ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
End Function
<DllImport("User32.dll")> _
Private Shared Function WindowFromPoint(ByVal xPoint As Integer, ByVal yPoint As Integer) As Integer
End Function
Private Const WM_GETTEXTLENGTH As Integer = &HE
Private Const WM_GETTEXT As Integer = &HD
Private Const EM_SETPASSWORDCHAR As Integer = &HCC
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.TopMost = True
Me.Timer1.Interval = 100
Me.Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim curPos As Point = Windows.Forms.Cursor.Position
Dim hwnd As Integer = WindowFromPoint(curPos.X, curPos.Y)
If hwnd <> 0 Then
Dim textLength As Integer = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0) + 1
Dim buffer As String = Space(textLength)
SendMessageString(hwnd, WM_GETTEXT, textLength, buffer)
Me.TextBox1.Text = buffer
Me.TextBox1.Select()
Me.TextBox1.SelectAll()
SendMessage(hwnd, EM_SETPASSWORDCHAR, 0, 0)
End If
End Sub
End Class
