

کار با رجیستری در ویژوال بیسیک 6.0
رجيستري چيست ؟
سيستم عامل ويندوز تنظيمات سخت افزاري و نرم افزاري خود را بطور
مرکزي در يک بانک اطلاعاتي با ساختار سلسله مراتبي ذخيره مي کند که رجيستري نام
دارد . رجيستري جايگزيني براي بسياري از فايلهاي پيکربندي INI ، SYS و COM
است که در نسخه هاي اوليه ويندوز موجود بود . رجيستري ، سيستم عامل را با مهيا
کردن اطلاعات موردنيز براي اجراي برنامه ها و load شدن component ها ، کنترل مي کند .
رجيستري
شامل انواع مختلفي از اطلاعات مي باشد مثل :
-
اطلاعات سخت افزارهاي نصب شده روي سيستم
- اطلاعات درايورهاي نصب شده روي سيستم
- اطلاعات برنامه هاي نصب شده روي سيستم
- اطلاعات پروتکلهاي شبکه اي مورد استفاده در سيستم
ساختار
رجيستري شامل چندين مجموعه رکورد است که داده هاي اين رکوردها توسط بسياري از
برنامه ها و اجزاي سيستم عامل خوانده و يا نوشته مي شود .
اجزاي رجيستري
اجزاي
تشکيل دهنده رجيستري عبارتند از :
1
– subtree : Subtree ها همانند folder هاي موجود در ريشه يک درايو هارد هستند . رجستری ويندوز داراي پنج
subtree مي باشد :
- HKEY_LOCAL_MACHINE : شامل تمام داده هاي پيکربندي براي کامپيوتر
مي باشد و شامل 5 key است :Hardware ، SAM ، Security ، Software و System
- HKEY_USERS : شامل داده هاي مربوط به تنظيمات سيستم عامل
براي هر user است مثل تنظيمات desktop و محيط ويندوز
- HKEY_CURRENT_USER : شامل داده هاي کاربر فعلي سيستم
- HKEY_CLASSES_ROOT : شامل اطلاعات پيکربندي نرم افزار است مثل
داده هاي OLE و داده هاي کلاسهاي
متناظر با فايل
- HKEY_CURRENT_CONFIG : شامل اطلاعات مورد نياز براي تنظيمات
داريورهاي سخت افزاري و غيره
2 – Key : key ها همانند folder ها و subfolder هاي روي هارد هستند . هر key متناظر با object هاي نرم افزاري يا سخت افزاري مي باشد . subkey ها key هايي هستند که درون يکسري key قراردارند .
3
– Entry : هر key داراي يک يا چند entry است . هر entry داراي سه بخش مي باشد :
- نام Name
- نوع داده اي Data Type : مقدار هر entry يکي از انواع داده هاي زير است :
REG_DWORD
، REG_SZ
، REG_EXPAND_SZ
، REG_BINARY ،
REG_MULTI_SZ
، REG_FULL_RESOURCE_DESCRIPTOT
- مقدار Value
نکته 1 : براي مشاهده رجيستري و اعمال تغييرات در آن ( لطفاً اگر هيچ تجربه اي در
تنظيم کردن رجيستري نداريد اطلاعات آنرا تغيير ندهيد ) ، مي توانيد از برنامه regedit.exe و يا regedt32.exe موجود در ويندوز استفاده کنيد . براي اينکار کافيست نام برنامه را
در کادر Run وارد کنيد .
براي کار با رجيستري در ويژوال بيسيک کلاس Registery.bas را مطابق مطالب زير ايجاد کرده و در پروژه هاي خود از آن استفاده
کنيد :
1 - تعريف ثابتهاي مورد نياز : براي نوشتن اين کلاس نياز به تعريف چهار دسته ثابت
داريم :
- ثابتهاي مربوط به تعريف data type هاي entry
هاي رجيستري :
Global
Const REG_SZ As Long = 1
Global
Const REG_DWORD As Long = 4
- ثابتهاي مربوط به تعريف key هاي رجيستري
Global
Const HKEY_CLASSES_ROOT = &H80000000
Global Const HKEY_CURRENT_USER = &H80000001
Global Const HKEY_LOCAL_MACHINE = &H80000002
Global Const HKEY_USERS = &H80000003
-
ثابتهاي مربوط به خطاهاي کار با رجيستري
Global
Const ERROR_NONE = 0
Global Const ERROR_BADDB
= 1
Global Const ERROR_BADKEY = 2
Global Const ERROR_CANTOPEN
= 3
Global Const ERROR_CANTREAD = 4
Global Const
ERROR_CANTWRITE = 5
Global Const ERROR_OUTOFMEMORY = 6
Global Const ERROR_INVALID_PARAMETER = 7
Global Const ERROR_ACCESS_DENIED
= 8
Global Const ERROR_INVALID_PARAMETERS = 87
Global Const ERROR_NO_MORE_ITEMS = 259
- ثابتهاي متفرقه
Global
Const KEY_ALL_ACCESS = &H3F
Global Const REG_OPTION_NON_VOLATILE
= 0
2 - Declare کردن Api هاي مورد نياز : براي کار با رجيستري از
توابع کتابخانه Advapi32.dll استفاده مي کنيم . اين توابع عبارتند از :
- تابع RegCloseKey : آزاد کردن handle مربوط به يک key
Declare
Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
- تابع RegCreateKeyEx : ساخت يک key در رجيستري ( اگر key قبلاً وجود داشته
باشد ، اين تابع آنرا باز مي کند ) :
Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal Reserved As Long, ByVal lpClass As String, ByVal dwOptions As Long, ByVal samDesired As Long, ByVal lpSecurityAttributes As Long, phkResult As Long, lpdwDisposition As Long) As Long
-
تابع RegOpenKeyEx :
باز کردن يک key
Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
-
تابع RegQueryValueExLong :
استخراج type و data ي يک نام متناظر با يک key باز شده
Declare
Function RegQueryValueExString Lib "advapi32.dll" Alias
"RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal
lpReserved As Long, lpType As Long, ByVal lpData As String, lpcbData As Long) As Long
Declare Function
RegQueryValueExLong Lib "advapi32.dll" Alias
"RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String,
ByVal lpReserved As
Long, lpType As Long, lpData As Long, lpcbData As Long) As Long
Declare Function RegQueryValueExNULL Lib "advapi32.dll" Alias "RegQueryValueExA"
(ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long,
lpType As Long, ByVal lpData As Long, lpcbData As Long) As Long
-
تابع RegSetValueEx :
ذخيره يک مقدار در فيلد value
يک کليد باز
Declare
Function RegSetValueExString Lib "advapi32.dll" Alias "RegSetValueExA"
(ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal
dwType As Long, ByVal lpValue As String, ByVal cbData As Long) As Long
Declare Function
RegSetValueExLong Lib "advapi32.dll" Alias
"RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal
Reserved As Long,
ByVal dwType As Long, lpValue As Long, ByVal cbData As Long) As Long
-
تابع RegDeleteKey :
پاک کردن يک کليد و کليه اطلاعات مرتبط با آن
Private Declare Function RegDeleteKey& Lib "advapi32.dll" Alias "RegDeleteKeyA" (ByVal hKey As Long, ByVal lpSubKey As String)
-
تابع RegDeleteValue :
حذف مقدار يک key
برای اینکه همراه ما پیش بروید در VS.net یک پروژه جدید C# Application به صورت
ASP.net Web Application ایجاد کنید. WebForm1.aspx به صورت
پیش فرض در مقابل شما قرار میگیرد، از Toolbox یک Label داخل
WebForm1 درگ کنید، به صورت پیش فرض نام آن Label1 خواهد بود.
معرفی Base64String
Base64String نوعی از String است (و با خصوصیات یک string معمولی) که کاربر نمیتواند آن را
تشخیص دهد، (اگر کسی را میشناسید که میتواند به من هم بگویید!) برای مثال جمله "I LOVE ASP.net"، در Base64String میشود
"SSBMT1ZFIEFTUC5uZXQ=". اما چطور؟
string String = "I LOVE ASP.net";
byte [] Byte = System.Text.Encoding.ASCII.GetBytes(String);
Label1.Text = Convert.ToBase64String(Byte);
در خط اول ما یک string معمولی را ساختیم در خط بعدی آن را به byte تبدیل کردیم و Byte نامیدیم، در خط سوم Byte را به صورت Base64String در آوردیم و توسط Label1 به نمایش در آوردیم. فکر خوبی است که عملیات رمز سازی را همین جا تمام کنیم چون Base64String برای کاربر معمولی قابل مشاهده نیست! اما اگر چند خط بالا را با این خط ها عوض کنیم چه میشود؟
string MyBase64String = "SSBMT1ZFIEFTUC5uZXQ=";
byte[] MyByte =Convert.FromBase64String(MyBase64String);
Label1.Text = System.Text.Encoding.ASCII.GetString(MyByte);
حدس بزنید نتیجه چه میشود؟! بله "I LOVE ASP.net"! در حقیقت
ما همان راهی را که
رفته بودیم برگشتیم! ابتدا Base64String را به byte تبدیل کردیم
و سپس byte را به string معمولی. پس اگر برای ما مهم باشد که اطلاعات رمز شده ما برای
کسی قابل بازگشت نباشد هنوز کارمان تمام نشده است. حالا که یاد گرفته اید با Base64String کار
کنید بگویید:
"VHJ5IHRvIGZpbmQgd2hhdCB5b3UgbmV2ZXIgbG9vc2U= " چیست ؟! من
جوابش را پیدا کردم و به صورت رمز در آوردم "jcUKVu8D4dlpy4BHw6bgefaVMWW9x0qV
" جواب است ، امتحان کنید آن را به روش قبلی به string تبدیل کنید
و ببیند آیا به
جواب منطقی می رسید؟ برای رسیدن به جواب اصلی باید بتوانید آن را
رمز گشایی کنید!
Cryptography با استفاده از TripleDES و MD5
در بالا با Base64String آشنا شدیم حالا وقت آن است
که با یکی از روشهای معمول رمز سازی در دات نت آشنا شویم این روش فقط یکی از
روشهای معمول رمزسازی در دات نت است
برای آشنایی با روشهای دیگر از MSDN راهنمایی بگیرید . بیایید ابتدا با
عبارتهای تازهی این مبحث آشنا شویم:
TripleDES: برای رمز سازی سه بار از الگوریتم DES استفاده میکند.
DES: مخفف
Data Encryption Standard.
MD5: یک الگوریتم کار آمد رمز سازی است که در
بسیاری از زبانهای برنامه نویسی دیگر نیز و جود دارد. MD5 عضوی با نام ComputeHash دارد که یک تابع Hash یا (Hash function) است.
توابع
Hash یا
(Hash functions) یک binary string با طول دلخواه را به یک binary string با
طول کوتاه و ثابت! تبدیل میکند، و این خاصیت را دارد که هرگز برای دو ورودی مجزا یک خروجی یک
یکسان وجود نخواهد داشت (به عبارت دیگر توابع Hash تضمین میکنند که هر ورودی خروجی
منحصر به فردی را داشته باشد). خوب برای به رمز در آورن کافی است مانند مثال زیر عمل
کنیم (فعلا آن را اجرا نکنید!):
byte[] IV = new byte[8] {240, 32, 45, 29, 0, 76, 173, 59};
des.IV = IV;
byte[] CodedBuffer =
des.CreateEncryptor().TransformFinalBlock(buffer,0,buffer.Length);
Label1.Text = System.Convert.ToBase64String(CodedBuffer,0,CodedBuffer.Length);
ابتدا بگذارید ببینیم IV و cryptoKey چیستند؟
DESCryptoServiceProvider (و به دنبال آن
TripleDESCryptoServiceProvider) دارای یک Key و
یک IV مخفف
Initialization Vector هستند که برای رمز کردن داده ها از آن استفاده میشود (همان طور که لازم نیست بدانیم کی برد و موس چگونه
دستورات ما
را به سخت افزار کامپیوتر منتقل میکنند تا از آنها
استفاده کنیم، لازم نیست به دنبال این باشیم که Key و IV در DESCryptoServiceProvider دقیقا چگونه کار میکنند فقط کافی است بدانیم از
آنها چطور استفاده کنیم). باید توجه داشته باشیم اگر فراموش کنیم IV را
مقدار دهی کنیم در هنگام اجرا IV یک مقدار تصادفی خواهد گرفت که
برگردان
داده های رمز شده را غیر ممکن میکند!
در مثال بالا IV را از جنس byte تعریف کردیم و
cryptoKey از جنس string به صورت "All you need is
Love" مقدار دهی کردیم که در حقیقت "All you need is
Love" کلید رمز ما خواهد بود. MyString همان stringای است که باید به صورت رمز در بیاید. (اگر
کمی از #C سر در بیاورید با چند خط بعدی مشکلی نخواهید
داشت).
des.Key: حالا وقت آن شده است که Key را
مقدار
دهی کنیم، اما باید آن را توسط MD5.ComputeHash به صورتی
مناسب برای Key بودن تبدیل کنیم و فراموش نکنیم که MD5.ComputeHash، از string به عنوان ورودی
نمیتواند
استفاده کند و باید قبل از آن cryptoKey خود را به حالت byte تبدیل کرده باشیم (System.Text.ASCIIEncoding.ASCII.GetBytes(cryptoKey)).
و حالا وقت خوبی است تا CreateEncryptor برای رمز سازی اقدام کند و TransformFinalBlock مقدار Hash شدهای برای منطقه مشخص شده ای از آرایه های byte مشخص شده حساب میکند.
اما توجه
داشته باشید که ما byte رمز شده لازم نداریم
بلکه string رمز شده میخواهیم پس در قدم آخر باید یک Base64String تولید کنیم.
سوالی که پیش میآید این است که TripleDESCryptoServiceProvider و
MD5CryptoServiceProvider کجا هستند؟ فضای نام System.Security.Cryptography
پاسخ این سوال است پس حالا میتوانید پروژهای را که ایجاد کرده بودیم بیاورید و به جای کد های قبلی کدهای مثال بالا را در
آن قرار دهید
و فراموش نکنید که namespace جدید را به صورت using
System.Security.Cryptography به بالای کدهای خود اضافه
کنید.
این روش بر خلاف بعضی از روشهای یک طرفه، قابلیت بازیابی اطلاعات رمز شده را دارا میباشد، فقط کافی است ازCreateDecryptor استفاده کنیم :
byte[] CodedBuffer = des.CreateDecryptor().TransformFinalBlock(buffer,0,buffer.Length);
Label1.Text = System.Text.Encoding.ASCII.GetString (CodedBuffer);
خوب حالا میتوانید به من بگویید "jcUKVu8D4dlpy4BHw6bgefaVMWW9x0qV " (که همان جواب معمای ما هم بود) چیست ؟ صد در صد
خیر! مگر اینکه من به شما IV و Key آن را بگویم!
IV مانند مثال و Key نیز "red rose" است! حالا اگر مطالب را دنبال کرده باشد احتمالا به
راحتی میتوانید رمزگشایی کنید!
چند نکته امنیتی
آیا این روش، روش قابل اطمینانی است؟ باید بگویم تا وقتی
نخواهید
اطلاعات چند صد هزار دلاری یا اسناد محرمانه ای را به رمز
تبدیل کنید احتمالا میتوانید روی آن حساب کنید مخصوصا که TripleDES سه بار با الگوریتم DES آن را به رمز تبدیل کرده
است (سه بار رمز شکستن به راحتی سه بار رمز کردن نیست!).
شما میتوانید برای سخت تر کردن
کار رمزشکن از
Key های مختلفی استفاده کنید ( البته سعی کنید برای رمز کردن کلمه عبور، نام کاربری یا email را به عنوان کلید
رمز قرار
ندهید! چون شما جزو اولین 10000 نفری نیستید که این کار
را کرده اند!). حفاظت اطلاعات شما در گروی امن بودن server ای است که سایت شما روی آن قرار دارد، همینطور از قرار دادن Key در Web.config به عنوان یک کار خلاقانه! جدا خودداری کنید
جستجوی نام های دامنه (Whois) در ASP.NET
برای انجام عمل جستجو ابتدا باید یک ارتباط با سرورهایی که بانکهای
اطلاعاتی
آنها این مشخصات را دارند ارتباط برقرار کرد و با یک Query، اطلاعات مورد نظر را درخواست نمود.
این ارتباط از نوع
TCP و از طریق پورت 43 انجام می گیرد. لیست کاملی از این سرورها را اینجا می توانید ببینید.
مشخص کردن فضا نامها
ابتدا فضا نامهای مورد نیاز را
مشخص می کنیم:
Using System.Net.Sockets;
Using System.Text;
Using System.IO
Using System.Text.RegularExpressions;
با استفاده از TcpClient در NetFramework. می توانیم
این ارتباط را با سرور مورد نظر برقرار نماییم. برای استفاده از این
کلاس باید فضانام
System.Net.Sockets را وارد کنیم. از
دو فضانام دیگر نیز برای فرمت ورودی و خروجی خود استفاده می کنیم.
ایجاد و ارسال Query
ابتدا متغیرهای مورد نیاز را تعریف می کنیم:
string StrSvr,StrDomain, Resp;
TcpClient TcpClt;
byte[] ArrDomain;
Stream TcpStr;
StreamReader TcpStrRdr;
هر نوع اطلاعاتی که بتوان فقط با یک URL به آن دسترسی پیدا کرد
دیگر مال همه است و همه میتوانند به آن دسترسی داشته باشند
و سایتهایی مثل گوگل در ظرف چند دقیقه کل اطلاعات شما را
به این صورت دریافت میکنند.
بعضی اوقات شما دوست ندارید همه به اطلاعات شما
دسترسی داشته باشند و میخواهید فقط به بعضی افراد اجازه دسترسی به بعضی از فایلها را بدهید خوب به نظر شما راه حل چیست؟ اگر فقط یک سیستم
مدیریت
کاربر بگذارید و کاربران پس از ورود به آن URL خاص
دسترسی پیدا کنند خیلی جالب نخواهد بود زیرا فقط کافیست آن آدرس URL لو
رود تا مجددا افراد بدون مجوز بتوانند به آن دسترسی
پیدا کنند. پس عملا
Authentication ساده ASP.net قادر به امن کردن فایلهای شما نیست و شما باید تدابیر دیگری بیاندیشید.
حتی در مورد این فکر نکنید مثلا اسم
فایل را بگذارید 32sdf43ef45.pdf چون
این کار ابلهانهای است و در اصل مسئله تفاوتی ایجاد
نمی کند. یک
Spider و یا یک Hacker خوب میتواند به
راحتی به
فایلهای شما دسترسی پیدا کند.
راه حل در استفاده از HttpHandler است.
مروری بر HttpHandler
HttpHandler شامل یکسری API هایی جهت انجام امور
اشیاء
Request/Response که با استفاده از آن میتوانید انتقال اطلاعات را کنترل کنید. در اینجا ما باید یک Handler ایجاد کنید که در
زمانی که کسی
درخواست یک فایل مثلا doc. میدهد اجرا شود.
خوب بهتر است مقداری کد نویسی کنیم تا بهتر
موضوع مشخص شود و متوجه شوید چطور میتوان در یک سایت E-Commerce اطلاعات را امن
کرد بدون استفاده از تکنیک های FTP و نیاز به مرورگرهای خاص.
تغییر Web.Config
مرحله اول: باید تگ زیر را در web.config موجود در
فولدری که میخواهید آن را Secure کنید وارد کنید.
با اینکار در واقع به IHttpHandler میگوئیم که ما میخواهیم
درخواستهایی که آخر آنها doc است را کنترل کنیم.
مشخصه verb میتواند حالتهای POST یا
GET یا HEAD داشته باشد که در اینجا ما نوشته
ایم * یعنی تمامی حالتهای تقاضا را مورد پوشش قرار می دهد.
مشخصه Path در واقع آدرسی که باید مورد بررسی
قرار گیرد که با نوشتن doc.* گفته ایم کلیه آدرس
های منتهی به doc
مشخصه Type در واقع کلاس دات نت است که
باید تقاضا را
Handle کند. باید نام کامل کلاس را به صورت زیر بنویسیم.
[NAMESPACE].[CLASS], [ASSEMBLY NAME]
اضافه کردن یک پسوند دلخواه Custom Extension
باید توجه کرد که باید پسوند
مورد نیاز را در
IIS هم اضافه کنیم. درضمن سپس تنظیمات دایراکتوری محتوی فایلها را به صورت زیر انجام دهید:
Read : False
Write: False
Directory Browsing: False
حال
IIS Manager را اجرا کنید و سپس Properties/Edit… را
انتخاب کنید آنگاه به بخش Home بروید و دکمه Configuration را بزنید. سپس باید پسوند مورد نیاز خود مثلا doc, pdf را در صفحه
تنظیمات نرم افزار اضافه کنید. برروی دکمه add بزنید و اطلاعات مورد نیاز را پر کنید کار بسیار ساده ای است.
بعد از اینکه اینکارها را کرده اید حال آماده
هستید تا کد مربوط به
HttpHandler را بنویسید.
کد HttpHandler
در زیر کد مربوط به HttpHandler ارائه شده
است. البته شما خود باید کد مربوط به Authentication مربوط به سایت خود را در آن قرار دهید.
در دات نت همیشه کارهای بزرگ را میتوان با چند خط کوتاه، برنامهی
ساده انجام
داد. یکی از این کارها ترسیم و دستکاری تصاویر است. در
این مقاله سعی میکنیم دستکاری تصاویر با دات نت را با هم مرور
کنیم. یاد آور میشوم که مقالهای در باب ترسیم، با نام
گرافيک در
ASP.NET توسط دوست خوبمان آقای مجتبی کيانی قبلا در سایت منتشر شده است که مطالعه آن به شما پيشنهاد میکنم.
در دات نت ترسیم یک تصویر همیشه با
استفاده از شیئی از کلاس
Graphics روی میدهد. و میدانیم متد DrawImage از این کلاس، متدی غنی برای اجرای کارهای گیج کننده گرافیکی به صورت
خیلی ساده است. متد دیگری نیز با نام DrawImageUnscaled وجود
دارد که این متد فقط وقتی مورد استفاده قرار میگیرد که مستطیلهای
منبع و مقصد همسان باشند.
قبل از هرچیز برای ترسیم باید
بدانیم:
۱-
همیشه یک مستطیل مقصد وجود دارد (در حقیقت مساحتی که تصویر داخل آن کپی میشود).
۲-
همیشه یک مستطیل منبع وجود دارد که ممکن است تمام یا بخشی از تصویر اولیه را در بر بگیرد (در حقیقت مساحتی از
تصویر اولیه
که میخواهیم کپی شود).
۳-
مستطیل مقصد ممکن است کوچکتر یا بزرگتر مستطیل منبع باشد (در این صورت اندازه تصویر ایحاد شده با اندازه تصویر اولیه فرق
خواهد
کرد).
همینطور دانستن نکات زیر برای ترسیم به ما کمک میکند:
۱-
به هنگام ترسیم تصویر میتوان با
استفاده از
ImageAttributes در تصویر تغییراتی داد، در این صورت بسیاری از عملیات پیچیده ترسیم به راحتی ممکن میگردد.
۲-
شیئی از کلاسGraphics
میتواند برای تغییر اندازه نیز استفاده شود، همینطور این
شیئ دارای
فیلترهای الحاقی میباشد که بر کیفیت و سیمای تصویر اثر
میگذارند.
در مثالهای زیر میبینیم که چطور متد DrawImage مورد استفاده قرار میگیرد. "myGraphics" شئی از کلاس graphics و
"img" تصویری که در حافظه ذخیره شده است فرض شود. شما میتوانید عملکرد هرقسمت را به ترتیب در مثال نمونه همراه این
مقاله
مشاهده کنید (توجه داشته باشید که چون این نمونه مثال روی
دستگاه شما فایل
result.jpg را مینویسد، ممکن است هنگام اجرا با ایراد
امنیتی روبرو شوید، در این صورت به سند readme.doc در بین فایلهای
مثال رجوع کنید).
۱-
یک کپی مستقیم از
تصویر:
myGraphics.DrawImage(img,
نقاط
X و Y مختصات گوشه بالا سمت چپ مستطیل منبع
را بیان میکند. در این مثال مستطیل مقصد ما هم اندازه
مستطیل منبع ما بود. اما اگر بخواهیم مستطیل مقصد بزرگ تر باشد (و در
نتیجه تصویر بزرگ تر از حالت اولیه خود باشد) میتوانید به صورت زیر عمل کنید توجه داشته باشد که در این حالت ممکن است تصویر کیفیت مطلوب خود
را از دست
بدهد (همینطور میتوان مستطیل مقصد را کوچکتر از مستطیل
منبع تعریف کرد که واضح است تصویر کوچکتر از تصویر اولیه خواهد بود).
۲-
کپی با اندازه های متفاوت:
myGraphics.DrawImage(img,BiggerRectangle)
در این حالت مستطیل منبع کل تصویر اولیه خواهد بود (واضح است که BiggerRectangle مستطیل مقصد میباشد) اما اگر بخواهیم فقط قسمتی از تصویر اولیه را
استفاده کنیم. مستطیل منبع باید قسمتی از تصویر اولیه باشد.
۳-
انتخاب قسمتی از عکس اولیه:
DistRectangle=new Rectangle(100,100,10,10)// مستطیل مقصد
myGraphics.DrawImage(img, DistRectangle,75,40,10,10,GraphicsUnit.Pixel)
این مثال نشان میدهد که میتوان مستطیل منبع (یا مقصد) را مستقیما در
پارامترهای
DrawImage تعریف کرد. در ضمن در مورد GraphicsUnit، به یاد داشته باشیم که
همیشه
واحد گرافیک Pixel است. در مثال بالا مستطیل مقصد نیز
به اندازه مستطیل منبع است. اما اگر بخواهیم اندازه قسمت کپی شده را
تغییر دهیم باید مستطیل مقصد را با اندازهای متفاوت از
مستطیل منبع تعریف کنیم.
۴-
انتخاب قسمتی از عکس اولیه و اعمال
تغییر اندازه:
DistRectangle =new Rectangle(10,20,120,40) )// مستطیل مقصد
SourRectangle =new Rectangle(75,40,10,10) )// مستطیل منبع
myGraphics.DrawImage(img, DistRectangle, SourRectangle,GraphicsUnit.Pixel)
چرخاندن
(Rotating) و تغییر صورت (transformation) یک تصویر
نیز توسط شیئی از
Graphics کلاس مقدور است. برای transformation باید یک
ماتریس تعریف کنید. در این مثال، ما تصویر را به اندازه 30 درجه در
جهت خلاف عقربه های ساعت میچرخانیم.
۵-
چرخاندن با مقیاس درجه:
Matrix mx = new Matrix();
mx.Rotate(-30);
myGraphics.Transform = mx;
myGraphics.DrawImage(img,new Point(100,50));
یا میتوانید به شکل زیر تغییر اندازه و چرخاندن را انجام دهید.
۶-
چرخاندن با مقیاس طول و عرض:
Matrix mx = new Matrix();
mx.Translate(20.0F, 10.0F);
myGraphics.MultiplyTransform(mx);
myGraphics.RotateTransform(20.0F);
در این مثال 20.2F و
10.0F به ترتیب X و Yای
هستند که به صورت ماترس ترجمه میشوند.
روش دیگری برای ایجاد تغییر زاویه وجود دارد و آن استفاده
از مختصات نقاط به هنگام تعریف مستطیلها است (تصویر حاصل از این روش
حالتی آیینهای نسبت به تصویر اولیه دارد). برای انجام
این عمل مستطیل مقصد به صورت معمولی تعریف میشود اما به
هنگام تعریف مستطیل منبع به شکل زیر عمل میکنیم.
۷-
ایجاد حالت آینهای:
Rectangle DistRectangle = new Rectangle(50,50,320,240);
Rectangle SourRectangle= new Rectangle(0, img.Height, img.Width,- img.Height);
myGraphics.DrawImage(img,DistRectangle,SourRectangle,GraphicsUnit.Pixel);
ترسیم تصویرهای شفاف توسط کلاس ImageAttributes انجام میشود.
چنین شیئی میتواند یک ColorMatrix در خود ذخیره
کند که توسط آن میتوان
alphaی یک تصویر را هنگام ترسیم تغییر داد. از
میان تمام
propertyها میتوان به ColorMatrix.Matrix33 اشاره
کرد که
شما را قادر میکند کاملا شفافیت یک تصویر را تنظیم کنید.
۸-
ترسیم های شفاف:
myGraphics.DrawImage(img1,new Point(0,0));
ImageAttributes ia = new ImageAttributes();
ColorMatrix cm = new ColorMatrix();
cm.Matrix33=0.5f;
ia.SetColorMatrix(cm);
myGraphics.DrawImage(img2,new Rectangle(0, 0, img2.Width, img2.Height ), 0, 0,
img2.Width, img2.Height, GraphicsUnit.Pixel, ia);
کوکی ها برای ذخيره مقدار کمی اطلاعات بر روی دستگاه مشتری (CLIENT) استفاده می شوند. يك کوکی می تواند حداکثر تا 4 کيلو
بايت را ذخيره کند. بطور کلّی کوکی ها برای ذخيره
داده هايی که اغلب کاربر تايپ می کند استفاده می شوند، از قبيل اسم کاربری و پسورد برای لاگين در سايت.
دو نوع کوکی وجود دارد: زمانی (session) و دائمی (persistent ). کوکی های زمانی کوکی های موقتی نيز خوانده می شوند که در حافظه مرورگر ذخيره می شوند و زمان حیات آنها به مرورگر بستگی دارد.
هنگامی که شما مرورگر را می بنديد اين کوکی ها هم می
ميرند. از طرف ديگر کوکی های پايدار بر روی هارد ديسک با
اطلاعات تاریخ ذخيره می شوند و برای زمان درازی می توانند زنده بمانند. هنگامی که شما کوکی های پايدار را ايجاد می کنيد شما می توانيد
زمان زندگی
کوکی را نيز تعیین کنيد. اگر چه مدتی که شما تعیین می
کنيد تا کوکی زنده بماند قطعی نيست. همچنين اگر چه کوکی
ها شئهای مفيدی در دنيای وب هستند امّا آنها برخی محدودیت هایی
هم دارند. مثلاً کوکی ها نمی توانند اطلاعات زيادی را در خود ذخيره کنند.
همچنين کوکی ها وابسته به مرورگرها هستند به اين معنی که
کوکی کاربردی
در برخی مرورگرها نمی تواند کار کند. شما می توانيد زمان
زندگی يک کوکی را تعیین کنيد اما نمی توان تضمين کرد که کوکی در
آنجا برای مدت طولانی در دسترس باشد. بنابراين ذخيره اطلاعات مهم در کوکی ها
ايده خوبی نيست.
ساختن و خواندن کوکیها
كلاس HttpCookie در فضانام System.Web تعريف شده است که کوکی ها را نمايش می دهد.
خواص کوکیها مثل
Response و Request می تواند در خواندن تمام کوکی ها به کار رود بطوريکه شئ HttpCookieCollection می
تواند همه کوکی ها را نمايش می دهد.
همانند دیگر کلاس ها کلاس HttpCookieCollection اضافه
کردن حذف کردن و خواندن کوکی ها را از مجموعه برای اعضا فراهم می کند. شما
می توانيد يک
کوکی توسط کلاس HttpCookie با مشخص کردن
نام و مقدار کوکی به صورت رشته ای ايجاد کنيد. يا شما
می توانيد از خواص
Name و Value برای نام و مقدار کوکی استفاده
کنيد. خاصيت
Expires کلاس HttpCookie يک کوکی پايدار می سازد و
زمانی را که کوکی از بين خواهد رفت مشخص می کند. در قطعه کد زير دوتا
کوکی می سازد به نام
UID وPASS. شما در اين کد می توانيد ببينيد که ما کوکی ها
را به مجموعه توسط تابع
Response.Cookies.Add اضافه می کنيم:
Listing 1. Creating cookies
' ساختن اسم کاربری و پسورد کوکی ها
' دادن مقدار به آنها و اضافه کردن به مجموعه
Dim cookie As HttpCookie = New HttpCookie("UID")
cookie.Value = "myid"
cookie.Expires = #9/28/2002#
Response.Cookies.Add(cookie)
cookie = New HttpCookie("PASS")
cookie.Value = "mypass"
cookie.Expires = #9/28/2002#
Response.Cookies.Add(cookie)
شما می توانيد کوکی ها را با استفاده از صفت Request.Cookies بخوانيد. قطعه کد زير کوکی را از مرورگر می خواند و آنها را به کنترل ListBox اضافه میکند:
Listing2 . Read cookies
' خواندن کوکی ها
Dim cookieCols As New HttpCookieCollection()
cookieCols = Request.Cookies
Dim str As String
' خواندن و اضافه کردن تمام کوکی ها به لیست باکس
For Each str In cookieCols
ListBox1.Items.Add("Cookie: " + str)
ListBox1.Items.Add("Value:" & _
Request.Cookies(str).Value)
Next
شما می توانيد از توابع Clear و Remove در HttpCookieCollection برای حذف کوکی خاص يا همه کوکی ها استفاده کنيد. قطعه کد زير با استفاده از تابع Remove کوکیها را حذف می کند:
Listing3 . Deleting cookies
Dim cookieCols As New HttpCookieCollection()
cookieCols = Request.Cookies
Dim str As String
' خواندن و حذف تمام کوکی ها از لیست باکس
Request.Cookies.Remove("PASS")
Request.Cookies.Remove("UID")
يک کوکی همچنين می تواند چندين مقدار را ذخيره کند. اين نوع کوکی، کوکی ديکشنری ناميده می شود. شما می توانيد از صفت Values برای ايجاد و خواندن اين نوع کوکی ها استفاده کنيد. کد زير يک کوکی ديکشنری می سازد.
Listing4 . Creating a dictionary cookie
Dim cookDict As HttpCookie = New HttpCookie("dict")
cookDict.Values("fname") = "first name"
cookDict.Values("lname") = "last name"
cookDict.Values("Address") = "address"
Response.Cookies.Add(cookDict)
منبع: Asp.Heaven
سايتها آنلاين میميرند.
مايكروسافت در مصاف با جاوا، بدنبال ارائه يك زبان كامل بود كه سايه جاوا را در ميادين برنامه نويسی كم رنگ تر نمايد. شايد بهمين دليل باشد كه #C را ايجاد كرد. شباهت های بين دو زبان بسيار چشمگير است. مايكروسافت در رابطه با ميزان استفاده و گسترش زبان فوق بسيار خوشبين بوده و اميدوار است بسرعت زبان فوق گستردگی و مقبوليتی به مراتب بيشتر از جاوا را نزد پياده كنندگان نرم افزار پيدا كند.
با توجه به نقش محوری اين زبان، از آن بعنوان مادر زبانهای برنامه نويسی در دات نت نام برده می شود. مورد فوق به تنهائی، می تواند دليل قانع كننده ای برای يادگيری اين زبان باشد، ولی دلايل متعدد ديگری نيز وجود دارد كه در ادامه به برخی از آنها اشاره می گردد.
مطرح شدن بعنوان يك استاندارد صنعتی
انجمن توليدكنندگان كامپيوتر اروپا (ECMA) زبان
#C را در سوم اكتبر سال 2001 بعنوان يك استاندارد پذيرفته
(ECMA-334) و بدنبال آن تلاش های وسيعی برای كسب گواهی ISO نيز
انجام شده
است. زبان فوق در ابتدا توسط شركت مايكروسافت و بعنوان
بخشی از دات نت پياده سازی و بلافاصله پس از آن توسط
شركت های اينتل، هيوليت پاكارد و مايكروسافت مشتركا، جهت استاندارسازی
پيشنهاد گرديد.
زبان #C بگونه ای طراحی شده است كه نه تنها وابستگی به يك Platform خاص را ندارد، بلكه در اغلب موارد وابستگی RunTime نيز ندارد. كامپايلر #C می تواند بر روی هر نوع معماری سخت افزاری طراحی و اجرا گردد. در برخی از نسخه های اوليه كامپايلر زبان فوق كه توسط برخی از شركت های جانبی ارائه شده است، كدهای #C را به بايت كدهای جاوا كمپايل می كنند. يكی از چنين كامپايلرهائی را می توان در سايت Halcyonsoft.com مشاهده نمود. بنابراين كدهای #C براحتی قابليت حمل بر روی محيط های متفاوت را دارا خواهند بود.
مشخصات تعريف شده زبان #C با ساير استاندارهای تعريف شده ECMA نظير (ECMA-335) CLI (Common Language Infrastructure) بخوبی مطابقت می نمايند. CLI قلب و روح دات نت و CLR(Common Language Runtime) است. اولين نسخه از كامپايلر زبان #C كه از CLI استفاده می كند، NET Framwork. مايكروسافت است.
با توجه به موارد گفته شده، مشخص می گردد كه اين زبان بسرعت بسمت استاندارد شدن حركت و با تاييد استانداردهای مربوطه از طرف انجمن های معتبر بين المللی و حمايت فراگير شركت های معتبر كامپيوتری در دنيا مسير خود را بسمت جهانی شدن بخوبی طی می نمايد.
#C چيست ؟
طراحان زبان #C با تاكيد و الگوبرداری مناسب از مزايای زبانهائی نظير ++C،
C و جاوا و ناديده گرفتن برخی از
امكانات تامل برانگيز و كم استفاده شده در هر يك از زبانهای فوق،
يك زبان برنامه نويسی مدرن شی گراء را طراحی كرده
اند. در مواردی، برخی از ويژگی های استفاده نشده و درست درك نشده در هر يك از زبانهای گفته شده، حذف و يا با اعمال كنترل های لازم بر روی
آنها، زمينه
ايجاد يك زبان آسان و ايمن برای اغلب پياده كنندگان نرم
افزار بوجود آمده است. مثلا C و ++C می توانند مستقيما با
استفاده از اشاره گرها عمليات دلخواه خود را در حافظه انجام دهند.
وجود توانائی فوق برای نوشتن برنامه های كامپيوتری با كارائی بالا ضرورت اساسی دارد. اما در صورتيكه عملياتی اينچنين بدرستی كنترل و
هدايت نگردند، خود می تواند باعث بروز مسائل (Bugs) بيشماری گردد.
طراحان زبان #C، با درك اهميت موضوع فوق، اين ويژگی را كماكان در آن گنجانده ولی بمنظور ممانعت از استفاده نادرست و ايجاد اطمينان های لازم مسئله حفاظت نيز مورد توجه قرار گرفته است. جهت استفاده از ويژگی فوق، برنامه نويسان می بايست با صراحت و به روشنی خواسته خود را از طريق استفاده از Keyword های مربوطهاعلان نمايند( فراخوانی يك توانائی و استفاده از آن).
#C بعنوان يك زبان شی گراء عالی است. اين زبان First-Class را برای مفهوم Property (Data Member) بهمراه ساير خصائص عمومی برنامه نويسی شی گراء حمايت می كند. در C و ++C و جاوا يك متد get/set اغلب برای دستيابی به ويژگی های هر Property استفاده می گردد. CLI همچنان تعريف Property را به متدهای get/ser ترجمه كرده تا بدين طريق بتواند دارای حداكثر ارتباط متقابل با ساير زبانهای برنامه نويسی باشد. #C بصورت فطری Events ، Declared Value، Reference Type ، Operator Overloading را نيز حمايت می كند.
كد مديريت يافته
با استفاده از نسخه پياده سازی شده #C توسط مايكروسافت، می
توان همواره كد مديريت يافته ای را توليد كرد. يك برنامه #C پس از كامپايل، بصورت برنامه ای در خواهد آمد كه شامل دستورالعمل های
تلفيق شده ( CIL
(Common Intermediate Language است (درست بر خلاف
دستورالعمل های مختص يك ماشين خاص). CIL (گاها با نام MSIL(Microsoft Intermediate
Language) با به اختصار IL نيز ناميده می شود ) ، در مفهوم مشابه بايت كدهای جاوا بوده و شامل مجموعه
ای از
دستورالعمل های سطح پايين قابل فهم توسط تكنولوژی مبتنی
بر CLI نظير
CLR مايكروسافت خواهد بود. اين
برنامه ها بدين دليل كد مديريت يافته، ناميده می شوند كه CLR مسئوليت تبديل اين
دستورالعمل ها به كدهای قابل اجرا برروی ماشين و ارائه اغلب سرويس های
اساسی برای كدينگ نظير
: Garbage Collection،
مديريت Heap و عمر مفيد يك Object و يا Type Verification را
فراهم می كند.
روش يادگيری #C
يادگيری اين زبان برای افراديكه دارای سابقه آشنائی با يكی از زبانهای برنامه نويسی ++C، C و يا جاوا باشند
كار مشكلی
نخواهد بود، حتی افراديكه دارای آشنائی اوليه با
جاوااسكريپت و يا ديگر زبانهای برنامه نويسی نظير ويژوال
بيسك می باشند، امكان پذير و راحت خواهد بود. برخی از برنامه نويسان
حرفه ای بر اين باور هستند كه #C نسبت به VB.NET با اقبال بيشتر و سريعتری مواجه خواهد شد، چراكه #C نسبت به ويژوال بيسك
خلاصه تر است. حتی برنامه های بزرگ و پيچيده ای كه توسط #C نوشته
می گردند خواناتر، كوتاه و زيبا خواهند بود. برخی از ويژگی های ارائه
شده در #C نظير
Unsigned Integer،
Operator OverLoading و امنيت بيشتر
Type ها، در VB.NET وجود نداشته و اين امر می تواند
دليلی بر فراگيرتر شدن #C نسبت به VB.NET نزد برنامه نويسان با تجربه باشد.
برای يادگيری هر يك از زبانهای حمايت شده در دات نت، می بايست از BCL (Basic Class Library) مربوط به NET Framework. شروع كرد. #C خود صرفا دارای ۷۷ کلمه کليدی يا Keyword بوده كه برای اكثر برنامه نويسان غريب نخواهند بود. در مقابل BCL، دارای ۴۵۰۰ كلاس و تعداد بيشماری متد و Property است كه برنامه نويسان #C، می توانند از آنها برای انجام عمليات دلخواه خود استفاده نمايند. شايد يكی از مسائل قابل توجه جهت يادگيری اين زبان برای برخی از برنامه نويسان حرفه ای عدم وجود برخی از ويژگی ها و امكاناتی باشد كه در گذشته و از طريق ساير زبانهای استفاده شده، بخدمت گرفته می شدند. مثلا عدم وجود امكاناتی جهت توارث چندگانه (MI) سلسله مراتبی يك شئ.
خلاصه
بدون شك فراگيری و تسلط بر زبان #C بمنزله كسب يك پتانسيل با ارزش بوده كه ثمرات آن برای برنامه نويسان در حال و آينده
ای نه چندان
دور بيشتر هويدا خواهد شد. استاندارد بودن و وجود
كتابخانه ای مملو از كلاس اين اطمينان را بوجود خواهد
آورد كه با فراگيری زبان فوق و كسب، مهارت های لازم، به يك توانائی فرا
محيطی جديد دست پيدا خواهيم كرد كه امكان استفاده از آن بر روی محيط های متفاوت وجود خواهد داشت. ويژگی ها و قابليت های بيشمار اين زبان از
جمله دلايل
قانع كننده ديگری است كه فراگيری آن را توجيه پذير و
منطقی می كند
شئ گرايی (OOP) در #C بر چند پايه استوار است که به قرار زيرند:
- Inheritance
- Encapsulation
- Polymorphism
- Abstraction
- Interface
Inheritance (ارث بری
پدر و فرزندی را در نظر بگيريد. هر پدری مشخصات فردی به
خصوصی دارد. فرزند وی می تواند همه خصوصيات او را به ارث برد و خصوصيتهای ديگری
نيز داشته باشد
که پدرش ندارد. اين يعنی ارث بری! برای مثال پدر وقتی عصبانی می شود، داد و فرياد می كند. پسر هم اين
خصوصيت را به ارث می برد با اين تفاوت كه وقتی عصبانی می شود، علاوه بر داد زدن، چند عدد بشقاب هم می شكند.
در برنامه نويسی شئ گرا از مفهوم
ارث بری استفاده های زيادی می شود. برای تفهيم راحت تر مسئله فرض
کنيد کلاسی به نام وسيله نقليه داريم. از آنجا که هر وسيله نقليه ای حرکت می کند، رنگ دارد،
سرعت دارد، ترمز
می گيرد و... می توانيم همه اين متدها و فيلدها( کدام متدها و فيلدها!؟) را در کلاس وسيله
نقليه تعريف کنيم. حال يک وهله از اين کلاس را در نظر بگيريد (مثلا دوچرخه!). يک دوچرخه يک وسيله
نقليه است که همه خصوصيات عمومی يک وسيله نقليه را دارد و البته خصوصياتی دارد که
مختص خودش هستند و در انواع ديگر يافت نمی شوند. به اين منظور اين دوچرخه می تواند
ويژگيها و متدهای مشترک را از کلاس وسيله نقليه به ارث ببرد و در عين حال
ويژگيهای منحصر به خود را نيز داشته باشد. قابليت استفاده دوباره از کد (Reusability) يکی از مزيات اصلی ارث
بری است.
Encapsulation
همانطور كه از اسمش پيداست، به قرار دادن پياده
سازی در يك كپسول اشاره می كند، به طوری كه كاربر بيرونی از نحوه پياده سازی مطلع نباشد و فقط بداند
كه اين كپسول كار خاصی را انجام می دهد. وقتی يك کپسول می خوريد نمی دانيد که در داخل آن چه چيزی هست و
فقط به اين فکر می کنيد که اين کپسول چه تاثيری در بدن شما می گذارد!
فرض کنيد سوار ماشينی هستيد که به سرعت در حرکت است! در مسيری که می
رويد ماشين پدر نامزدتان از روبرو به شما نزديک می شود و سعی می کنيد سريع ترمز بگيريد تا برخورد
نكنيد. اگر قرار باشد که بدانيد
بعد از فشار دادن پدال ترمز چه عملياتی انجام می شود تا ترمز گرفته
شود، ديگر بايد از
ازدواج قطع اميد کنيد. ولی اگر تنها بدانيد که با فشار دادن پدال، ترمز گرفته می شود شما خوشبخت خواهيد شد. در
واقع ما در اينجا کار ترمز گرفتن ماشين را به صورت يک کپسول آماده در نظر می گيريم. هدف Encapsulation اين
است که ما را از پرداختن به ريز موضوعات رها کند و اشياء را به صورت يک جعبه
سياهی بدانيم که به ازای يک ورودی
خاص خروجی خاصی می دهند. اگر می خواهيم کدهای ما نيز اين مورد را
رعايت کنند بايد سعی
کنيم نگاه کپسولی به اشياء و عملکرد آنها داشته باشيم. در #C برای کپسوله
کردن از Access
Modifierهای
protected ،private
و
public استفاده می شود.