-
کمک SendMessageSTRING
سلام من یک مشکل دارم این کد تو VB.Net کار نمیکنه کسی میدونه مشکل چیه
کد:
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
Private Declare Function SendMessageSTRING Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Private Const WM_CHAR = &H102
Private Const VK_RETURN = &HD 'Enter Key
Private Const WM_KEYDOWN = &H100
Private Const WM_SETTEXT = &HC
Private Sub SendText(editx As Long, Text As String)
Text = Left(Text, 395)
SendMessageSTRING editx, WM_SETTEXT, 400, Text
End Sub
Private Sub Command1_Click()
SendText 397432, "Dkk"
End Sub
-
سلام
الف)
مهمترین تغییر در دستور شما برای کارکردن در نسخه های بالاتر VB تغییر Long به Integer است.
زیرا VB6-Long متغیر عددی 32 بیتی بوده در حالیکه در نسخه های بالاتر Long متغییر بسیار بزرگتر 64 بیتی شده و Integer جایش را گرفته.
این مهم ترین و کلیدی ترین مطلب و مشکل کد فوق شما است.
ب)
ولی یک مشکل جداگانه که ربطی به نسخه VB هم ندارد در کد شما وجود دارد و ان حضور عدد 397432 است.
این یک اشتباه است و ربطی به نسخه VB هم ندارد.
در مکان این عدد شما باید یک اشاره گر hWnd داشته باشید.
اشاره گر hWnd در ذات یک عدد است ولی اصلاً عدد ثابت و مشخصی نیست و با هر اجرای برنامه فرق میکند.
hWnd عدد اشاره گر هر چهارچوب یا پنجره در سیستم عامل ویندوز است.
تمام Form ها و TextBox ها و Button ها و... و... یک hWnd منحصر به فرد دارند که در زمان اجرا مشخص میشود و با هر بستن و دبل کلیک مجدد برنامه یا Restart رایانه این عدد مجدد (توسط هسته ویندوز) تخصیص داده شده و عوض میشود و اصلاً چیز ثابتی نیست که همینطوری در کد نوشته شود.
توابع API دیگری وجود دارد که این عدد را به دست می آورد...
مثلاٌ hWnd رو ترین Form ...
یا hWnd کنترلری که الآن فوکس دارد ...
یا hWnd کنترلری که الان در موقعیت فلان x,y است ...
شما باید این عدد را در runtime به دست آورید و سپس استفاده کنید، نه اینکه همینطوری در کد آن را بنویسید!!!!!!
ج)
نوشتن Integer به جای Long مشکل کد فوق را حل میکند ولی کد بهتر هم وجود دارد.
VB6 فقط برای سیستم عامل های x86 بود در حالیکه نسخه های جدیدتر قابلیت اجرا در x86 و x64 را با هم دارند.
با علم به ساختار توابع API شما میتوانید به جای برخی Integer ها در تعریف توابع API از نوع جدید IntPtr استفاده کنید.
استفاده صحیح و بجا از IntPtr باعث میشود کد شما به راحتی و بدون هیچ تغییری در سیستم های x86 و x64 همزمان به درستی کار کند.
د)
متون در VB6 فقط ASCII بودند و از این رو با متون فارسی مشکل داشت و مثلاً در همین مورد شما نمیتوانستید از کلمات و لغات فارسی و چینی و ... در ارسال به تابع API استفاده کنید و برنامه به مشکل میخورد.
نتیجتاً از توابع مخصوص ASCII استفاده میکردم تا حداقل برنامه به Error نخورد.
(گرچه باز هم مشکل زبان های غیر انگلیسی حل نمیشد ولی حداقل برنامه error نمیخورد)
در همین راستا از توابع قدیمی PostMessageA و SendMessageA و... استفاده میشود.
الآن هم میتوان همچنان از این توابع استفاده کرد ولی دیگر یونیکد به طور کامل پشتیبانی میشود و میتوان به جای انها از PostMessageW و SendMessageW یا نوع های خودکار استفاده کرد.
=====
با حصول چهار شرط و مطلب فوق کد شما چنین میشود.
کد:
Private Declare Auto Function PostMessageStr Lib "user32" Alias "PostMessage" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As IntPtr, ByVal lParam As String) As IntPtr
Private Declare Auto Function SendMessageStr Lib "user32" Alias "SendMessage" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As IntPtr, ByVal lParam As String) As IntPtr
Private Const WM_CHAR As Integer = &H102
Private Const WM_KEYDOWN As Integer = &H100
Private Const WM_SETTEXT As Integer = &HC
Private Sub SendText(ByVal handler As IntPtr, ByVal Text As String)
SendMessageStr(handler, WM_SETTEXT, New IntPtr(400), Text)
End Sub
Private Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
Me.SendText(Me.Handle, "سلام")
End Sub
Me.Handler هندلر hWnd فرم جاری را که الآن درون آن هستیم را پس میدهد و این کد عنوان فرم جاری را عوض میکند.
موفق باشید.