سلام.
چند تا نکته هست که اگر دوستان در برنامه هایی که می نویسند رعایت کنند موفق تر خواهند بود.
1) در VB چندین نوع ساختار حلقه تکرار وجود داره که بنا به نیاز از هر کدام از آنها استفاده میشه.
به عنوان مثال: اگر تعداد دفعات تکرار از قبل معلوم باشه از حلقه For و اگر تعداد دفعات تکرار نامعلوم باشه از حلقه های Do While و Do Until و … استفاده میشه.
برخی افراد با اینکه تعداد دفعات تکرار از قبل مشخصه، از حلقه While استفاده می کنند. مثلا بارها دیدم که در برنامه نویسی صفحات وب با ASP کلاسیک که از VBScript استفاده می کنند، برای چاپ مقادیر Recordset از دستورات زیر استفاده میشه: (شبه کد)
Do While Not Rst.EOF
<TD> Rst(0).Value </TD>
Rst.MoveNext
Loop
استفاده از این کد، به مقدار زیادی در پایین آوردن سرعت پردازش و در نتیجه در Load شدن دیر صفحه تاثیر می گذاره.
دلیل: در هر بار اجرای حلقه، شرط جلوی حلقه ی While باید چک شود که این خود زمان گیر است.
پس بهتره به جای حلقه While از حلقه For استفاده کنیم: (شبه کد)
Dim I
For I = 0 To Recordset.RecordCount – 1
<TD> Response.Write Rst(0).Value </TD>
Rst.MoveNext
Next
اگر دقت کنید، می بینید که کد فوق نیز با حلقه While هیچ تفاوتی ندارد، چون که در هر بار اجرای حلقه، مقدار Recordset.RecordCount ب(تعداد رکوردها) باید محاسبه شود. بنابراین کد فوق را به شکل زیر اصلاح می کنیم: (شبه کد)
Dim I , J
J = Recordset.RecordCount – 1
For I = 0 To J
<TD> Response.Write Rst(0).Value </TD>
Rst.MoveNext
Next
استفاده از حلقه For، کاهش زمانی به میزان 33 درصد را در پی خواهد داشت.
2) (شاید بعضیا این مورد رو بدونن!) دستور SQL زیر را در نظر بگیرید:
“Select * From MyTable Where MyField = ‘” & Text1.Text & “’”
این بدترین بلاییه که میشه سر داده ها آورد!!!
حالا فرض کنید که من در TextBox، متن زیر رو تایپ کنم:
& “ Or MyField = ‘’”
مسلمه که با وارد کردن خط فوق در TextBox توسط کاربر، به جای نمایش یک سری اطلاعات با شرط خاص، تمامی اطلاعات نمایش داده خواهند شد.
تعریف: به وارد کردن دستورات SQL توسط کاربر در مکان مورد نظر و پردازش آنها به صورت غیرمجاز توسط DBMS، خطای SQL Injection گفته می شود.
این مورد تقریبا 6 سال پیش توسط آقای Williams در کنفرانسی که در مورد امنیت داده ها در واشنگتن آمریکا برگزار شد، مطرح شد.
راه حل مقابله با این حملات، استفاده از Stored Procedure ها، چه در بانک اطلاعاتی ACCESS و چه در SQL Server است.
البته اگر از بانک SQL Server استفاده می کنید باید برای ایجاد Stored Procedure ها (روال های ذخیره شده)، تا حدودی با T-SQL (Transact SQL) یا SQL تراکنشی که زبان برنامه نویسی مورد استفاده در SQL Server است، آشنایی داشته باشید.
اگر از بانک Access استفاده می کنید، می توانید با ایجاد یک Command و تنظیم خاصیت Parameters و عبور دادن نام فیلد و مقدار آن، این کار را انجام دهید.
اما در SQL Server ابتدا باید Stored Procedure را با دستورات T-SQL بسازید.
به عنوان مثال، کد زیر در Query Analyzer، یک Stored Procedure می سازد.
Create Procedure Test
@username varchar(20),
@password varchar(20)
AS
Select MyField1,MyField2 From MyTable
Where MyField1=@username
And MyField2=@password
3) در تمامی برنامه هایتان بهتر است ابتدا چک کنید که آیا برنامه ی شما قبلا اجرا شده است یا خیر زیرا اجرای دو نسخه ی برنامه در یک زمان ممکن است باعث بروز مشکلاتی در برنامه شما شود.
این کار را می توانید با استفاده از خاصیت PrevInstance که در شی App وجود دارد انجام دهید:
Private Sub Form_Load()
If App.PrevInstance Then
MsgBox "Program is already Running!"
End
End If
End Sub
نکته مهم: حتما دستور End را در صورتی که برنامه قبلا اجرا شده است بنویسید تا از اجرای نسخه دوم، جلوگیری شود.
همچنین می توانید Handle (هندل) برنامه خود را نیز با استفاده از خاصیت hInstance از شی App به دست آورید.
Dim MyHandle As Long
MyHandle = App.hInstance
4) برای استفاده از توابع API نیاز به تعریف آنها ندارید.
همون طور که می دونید، توابع API در فایل های خاصی قرار دارند. به عنوان مثال: User32.dll، Kernel32.dll، tlbinf32، GDI32 ،Shell32 و …
می توانید برای استفاده از توابع موجود در این فایل ها، تنها با دسترسی به آدرس این توابع در این فایل ها، آنها را اجرا کنید.
برای این منظور نیاز به فراخوانی و استفاده از چهار تابع API دارید.
Public Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Public Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Public Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Any, ByVal wParam As Any, ByVal lParam As Any) As Long
تابع LoadLibrary برای بارگذاری یک فایل DLL یا EXE در حافظه به کار می رود تا از این طریق بتوان به آدرس های توابع موجود در این فایل ها دست پیدا کرد.
به عبارت دیگر باید در آرگومان اول این تابع، نام فایل کتابخانه ای را ذکر کرد که تابع مورد نظر ما در آن وجود دارد.
این تابع تنها یک آرگومان دارد و آن، نام فایل است.
می توانید در این تابع، تنها نام فایل را ذکر کنید (بدون پسوند). در این صورت به طور پیش فرض برای فایل، پسوند DLL در نظر گرفته می شود.
Dim Res As Long
Res = LoadLibrary(“user32”)
پس از پایان کار با تابع API، باید کتابخانه حاوی آن فایل را از حافظه خارج کرد.
این کار با استفاده از تابع FreeLibrary انجام می شود.
این تابع نیز تنها یک آرگومان دارد و آن نیز شماره ای است که با استفاده از تابع LoadLibrary به دست آمده و در متغیر ریخته شده.
به عنوان مثال در مثال قبل، برای حذف آدرس و آزاد کردن فضای تخصیص یافته به پردازه LoadLibrary به شکل زیر عمل می کنیم:
FreeLibrary Res
تابع GetProcAddress به منظور دریافت آدرس تابع مورد نظر که در فایل کتابخانه ای وجود دارد استفاده می شود.
این تابع، دو آرگومان دارد.
آرگومان اول، شماره ی پردازه ی اختصاص یافته به فایل کتابخانه ای است.
آرگومان دوم نیز که از نوع رشته ای (String) است، به نام تابعی که قصد فراخوانی آن را داریم اختصاص دارد.
با توجه به مثال های قبل:
Dim MyVar As Long
MyVar = GetProcAddress(Res , “MessageBox”)
همان طور که ملاحظه می کنید، با خط فوق، تابع MessageBox بدون نیاز به تعریف آن فراخوانی شد.
اما هنوز کار ما به پایان نرسیده. حال باید پارامترهای واقعی را به پارامترهای مجازی مربوط به این تابع، Pass بدهیم.
تابع CallWindowProc برای Pass دادن آرگومان های یک تابع به آن به کار می رود.
اولین آرگومان این تابع به شماره اختصاص یافته به تابع مورد نظر اشاره می کند.
آرگومان های بعدی نیز پارامترهای مرتبط با تابع هستند که به ترتیب، Pass داده می شوند.
مثال زیر، یک مثال کلی از تمام گفته های فوق است.
Private Const MB_OK = &H0&
Private Sub Command1_Click()
On Error Resume Next
Dim Res As Long, MyVar As Long
Res = LoadLibrary("user32")
MyVar = GetProcAddress(Res, " MessageBox")
CallWindowProc MyVar, Me.hWnd, "This is a Test", App.Title, MB_OK
FreeLibrary lb
End Sub
موفق باشید.
بهروز راد
:wink: