۱۳۸۸ شهریور ۱۸, چهارشنبه

Input Output

خب خیلی جاها من دیدم که گفتن نمیشه با ویژوال بیسیک ورودی خروجی هارو کنترل کرد.
در صورتی که این حرف کاملآ اشتباه هست. ویژوال بیسیک قابلیت کنترل مستقیم ورودی و خروجی هارو نداره.
امروز هم یه کار با پورت های پارالل رو براتون توزیح میدم.


کار با پورت های پارالل خیلی سادس. ولی اول باید فایل "InpOut32.dll" رو دانلود کنید.
حالا اون رو توی پوشه ی system32 کپی کنید. کار با این فال درست مثل کار با api ها هست.
البته اگربا qbasic (داداش visual basic)برنامه نویسی میکنید نیازی به این کارا ندارین.


Declare Sub vbOut Lib "WIN95IO.DLL" (ByVal nPort As Integer, ByVal nData As
Integer)

Declare Sub vbOutw Lib "WIN95IO.DLL" (ByVal nPort As Integer, ByVal nData As Integer)

Declare Function vbInp Lib "WIN95IO.DLL" (ByVal nPort As Integer) As Integer

Declare Function vbInpw Lib "WIN95IO.DLL" (ByVal nPort As Integer) As Integer

البته ممکنه فایلی که شما دانلود میکنید یه فایل دیگه باشه ولی نگران نباشید کار میکنه.
و حتمآ راهنما هم داره.(کد های بالا میره تو ماژول)
خب حالا به عکس بالا نیگا کنید.
ما فقط با خروجی ها کار داریم.که پورت های زرد همه خروجی هستن.
تا جایی هم که من خوندم پورت های 18 تا 25 باید منفی باشن که من چیز دیگه ای دیدم.
من فرض میکنم شما تسلط کامل بر محاسبات دودویی (binary) دارید.(اگر ندارید حتمآ یاد بگیرید)
این عدد رو هم حفظ کنید      888
شما به صورت زیر عمل میکنید.
vbout  888,number
888 رو همیشه برای کار با خروجی ها مینویسیم
number هم همون مقدار باینری هستش که ما باید اون رو یه دسیمال تبدیل کنیم و بعد اون رو بنویسیم.
از اونجایی که ما 8 تا خروجی داریم عدد 00000001 یعنی خروجی اول رو روشن کن.
و به ترتیب 00000011 و 00000111 و .......

ولی همونطور که گفتم  باید تبدیل بشه به عدد در مبنای 10 (decimal)
برای مثال کد زیر خروجی اول رو روشن میکنه
vbout 888,1
ففط هواستون باشه که روشن کردن یک پورت یعنی 5 ولت برق و خاموش کردن یک پورت یعنی 0 ولت برق
برای اطلاعات بیشتر به این سایت مراجعه کنید.

۱۳۸۸ تیر ۱۱, پنجشنبه

رجیستری

حتما شما هم تا حالا اسم رجیستری به گوشتون خورده و باهاش آشنایی دارید.
رجیستری ویندوز رو میشه از طریق برنامه ی regedit درش تغییراتی به وجود آورد.
همچنین یکسری توابع api نیز ویندوز داره که به وسیله ی اونا میتونین از داخل برنامه ی خودتون رجیستری رو تغییر بدید. 
حالا یک پروژه ی جدید باز کنید چون میخوایم در غالب یک پروژه قسمت عمده ی این توابع رو یادبگیریم(بگیرید چون من که بلدم (:   )
خب خیلی طبیعیه که برای کار کردن با یک رشته یا عدد از یک فایل دیگه اول اون رو باز کنیم.
برای این کار تابعی به نام RegOpenKeyEx وجود داره به شکل زیر

Public Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, ByRef phkResult As Long) As Long

اگر برنامه ی regedit رو باز کنید میبینید که وقتی اولین شاخه یعنی شاخه ی MyComputer رو باز میکنید پنج فولدر مشاهده میکنید.(از این به بعد به این فولدر ها میگیم key یا "کی" که به فارسی یعنی کلید.پس میگیم کلید ،فولدر تو رجیستری=کلید)
خب اگر در APIViewer خود در لیست ثابت ها(constants) نگاه کنید میبینید هشت کلید با نام کلید های ذکر شده وجود دارد که با سه تا از اونا کاری نداریم.
بقیه یه اونها به شرح زیر
Public Const HKEY_CLASSES_ROOT As Long = &H80000000
Public Const HKEY_CURRENT_CONFIG As Long = &H80000005
Public Const HKEY_CURRENT_USER As Long = &H80000001
Public Const HKEY_LOCAL_MACHINE As Long = &H80000002
Public Const HKEY_USERS As Long = &H80000003

قبل از اینکه سراغ کد نویسی برم این رو هم بگم که اگر مقدار برگشتی هرکدوم از توابع API مربوت به رجیستری مقدار 0 رو برگردونن یعنی تابع کارش رو با موفقیت به انجام رسونده و در غیر این صورت یعنی خطایی رخ داده.
خب بریم که یک کلید رو باز کنیم.
دونه دونه مقادیری رو که برای regopenkeyex نیاز دارید در پایین توزیح میدم
hKey=یکی از همون پنج ثابت
lpSubKey=نام کلیدی که میخواهیم اون رو باز کنیم
ulOptions=فقت یک صفر بزارید
samDesired=یک پوشش امنیتی که  یه چندتا ثابت میخواد به شرح زیر.
Public Const KEY_ALL_ACCESS As Long = ((STANDARD_RIGHTS_ALL Or KEY_QUERY_VALUE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY Or KEY_CREATE_LINK) And (Not SYNCHRONIZE))
Public Const STANDARD_RIGHTS_ALL As Long = &H1F0000
Public Const KEY_QUERY_VALUE As Long = &H1
Public Const KEY_SET_VALUE As Long = &H2
Public Const KEY_CREATE_SUB_KEY As Long = &H4
Public Const KEY_ENUMERATE_SUB_KEYS As Long = &H8
Public Const KEY_NOTIFY As Long = &H10
Public Const KEY_CREATE_LINK As Long = &H20
Public Const SYNCHRONIZE As Long = &H100000

شما فقت KEY_ALL_ACCESS رو مینیویسید ولی  ثابت های دیگر رو هم باید  توی ماژول یا جای دیگه نوشته باشید.
 و اگر نگاه کنید تمامی ثوابت توی خود  KEY_ALL_ACCESS  هستند پس  فقت کافیه KEY_ALL_ACCESS رو حفظ کنید.
و اینکی KEY_ALL_ACCESS باید بعد از ثوابط دیگر تعریف شود
phkResult=هندل کلیدی رو که باز کردیم بر میگرداند.
حالا برید تو رویداد Form1_Load و کد زیر رو بنویسید
Private Sub Form_Load()
Dim RetVal As Long
Dim SubKey As String
Dim KeyHandle As Long
SubKey = "console"
RetVal = RegOpenKeyEx(HKEY_CURRENT_USER, SubKey, 0, KEY_ALL_ACCESS, KeyHandle)
If Not RetVal = 0 Then
  MsgBox "error in openning"
  End
Else
  MsgBox "openning succeded"
  End
End If
End Sub

برنامه اول سأی میکنه که کلید console که در Hkey_Current_User هست رو باز کنه و اگه موفق شد هندل اون رو در متغیر KeyHandle قرار میده . ولی اگه با خطا مواجه شد اول میگه که در بازکردن مشکل به وجود آمده و بعد برنامه رو میبنده.
اگر هم که با خطا مواجه نشد  میگه که باز شدن با موفقیت انجام شد و بعد برنامه رو میبنده.
نکته:وقتی که یک کلید رجیستری رو باز میکنید یه مقداری رم رو به خودش اختصاص میده به همین علت وقتی یک کلید رجیستری باز شد و خوانده شد یا  تغییراتی درش به وجود آمد بای سریع بسته شه که رم رو  آزاد کنه .بستن  یک کلید رجیستری به وسیله ی یک API یه  دیگه انجام میشه ولی چون هنوز اون رو نخوندیم برنامه رو میبندیم و باز هم رم به این ترتیب آزاد میشه.
خب حالا میخوایم یک  مقدار(value) رو بخونیم.مقادیر رو در قسمت سمت راست  برنامه ی regedit مشاهده میکنید که متنها و عدد ها در انها ذخیره میشوند.
برای خواندن یک مقدار از تابع RegQueryValueEx استفاده میکنیم به شکل زیر.
 

Public Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, ByRef lpType As Long, ByRef lpData As Any, ByRef lpcbData As Long) As Long
خب حالا به به شرح آرگومان هاش میپردازیم
hKey=هندل کلید باز شده به وسیله ی RegOpenKeyEx
lpValueName=نام مقداری(value)ای که میخواهیم اونو باز کنیم
lpReserved=صفر
lpType=تایپ مقداری که میخواهیم باز کنیم که یه چندتا ثابت با پیشوند REG داره
Public Const REG_BINARY As Long = 3
Public Const REG_DWORD As Long = 4
Public Const REG_SZ As Long = 1
البته تایپ های دیگری هم وجود داره ولی اینا مهمترین هان
REG_SZ=مقادیر رشته ای
REG_BINARY=مقادیر دودویی
REG_DWORD=مقادیر Hex یا decimal
بقیه یه آرگومان 
lpData=متغیری که مقدار برگشتی به آن فرستاده میشود
lpcbData=طول مقدار برگشتی
خب دو آرگومان آخر یکم توضیح میخوان
برای بدست آوردن مقدار دو راه وجود دارد که من به این روش عمل میکنم
اول دو متغیر از نوع استرینگ(string) تعریف میکنیم
حد اکثر طول یکی از آنها رو مساوی با 255 قرار میدیم به شکل زیر
Dim Buff As String *255
Dim RegValue as String
بعد برای lpData متغیر اولی رو مینویسیم
برای lpcbData هم حد اکثر طول متغیر اولی رو مینویسیم
گیج نشید الان مثال میزنم متوجه میشید.
Private Sub Form_Load()
Dim RetVal As Long
Dim Buff As String * 255, Fn As String
RetVal = RegQueryValueEx(KeyHandle, ValueName, 0,  REG_SZ, ByVal Buff, 255)
If RetVal = 0 Then
  Fn = Left(Buff, 255)
Else
  MsgBox "error in reading", vbCritical, "error"
  End
End If
End Sub
بعد با دستور RegCloseKey باید کلید بسته بشه
بستن کلید خیلی سادس.فقط هندل کلیدی رو که باز کردین بهش بدین


۱۳۸۸ تیر ۸, دوشنبه

SetWindowLong

خب امروز میخوام یه api رو معرفی کنم که با استفاده از اون میشه یکم شکل و شمایل فرم برنامه رو تغییر داد.
فرمت تابع به شکل زیر میباشد

Private Declare Function SetWindowLong Lib "user32.dll" Alias _ "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong _ As Long) As Long

این تابع قابلیت های زیادی دار
1-GWL_STYLE (برای اصلاح کردن فرم)
2- GWL_EXSTYLE (برای اصلاح کردن فریم درو فرم)
3- GWL_WNDPROC (برای ساختن یک حلقه برای فرم)
ما فقت به GWL_STYLE کار داریم
برای کار با استایل فرم باید یک سری ثابت دیگر نیز تعریف کنیم به شرح زیر.
ٌ WS_CAPTION  که خیلی مفیده و دکمه های روی فریم رو بر میداره
WS_BORDER   فریم رو حذف میکنه و به جاش یک خط سیاه میزاره
و این هم یک نمونه:
SetWindowLong Me.hwnd, GWL_STYLE, WS_CAPTION
این تابع در این مرحله اونقدر ساده هست که نیازی به توزیح نداری
همچنین ثابت های بیشتری نیز وجود دارند که من نمیتونم همشون رو توزیح بدم
ولی شما میتونید خودتون دونه دونه همه ی اونا رو امتحان کنید
و اینکه تمامی ثوابت پیشوند WS دارند

۱۳۸۸ فروردین ۱۸, سه‌شنبه

ooooooo

آقا الکی الکی یه چیزی کشف کردم که واقعآ دلم نیومد نذارمش.
این کد رو امتحان کنید و نتیجه ش رو ببینید
Private Sub Picture1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y_ As Single)
If  Button = 1 Then Picture1.Line (X, Y)-(X + X, Y + Y)
End Sub


۱۳۸۷ اسفند ۱۹, دوشنبه

bitblt

امروز میخوام یکی از توابع معروف رو براتون توضیحش رو بزارم که حال مضاعفی ببریم.توی اکثر جاها اگه بخواید آموزش این تابع رو یادبگیرید با نگاه اول به متن اون آموزش مختون سوت میکشه ولی باید بدونید که یکی از توابع ساده هستش.خب حرف بسه بریم سراغ اصل مطلب.
فرمت تابع bitblt به شکل زیر هستش.
Private Declare Function BitBlt Lib "gdi32.dll" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

البته اگه میخواید توی ماژول تعریفش کنید معمولآ باید بجای private از public استفاده کنید.
حالا به ترتیب توضیحشون میدم.
hDestDC=اچ دی سی (hdc) کنترلی که عکس به اون منتقل میشه.یعنی عکس ما توش کپی میشه.
x=نقطه ی شروع ترسیم(عکس جدید)در راستای افقی.
y=نقطه ی شروع ترسیم(عکس جدید)در راستای عمودی.
nWidth=عرض تصویر جدید.
nHeight=طول تصویر جدید.
hSrcDC=اچ دی سی (hdc) کنترلی که تصویر از اونجا کپی میشه(کنترل مبدع).
xSrc=نقطه ی شروع کپی شدن در راستای افق عکس(کنترل مبدع)
ySrc=نقطه ی شروع کپی شدن عکس در راستای عمود(کنترل مبدع)
dwRop=یک ثابت(constant)که در زیر توضیح داده شده.
تعداد زیادی ثابت وجود داره ولی ما با تابع زیر شروع میکنیم.این تابع عکس رو بدون هیچ دستکاری از کنترل مبدع به کنترل مقصد کپی میکنه.
Private Const SRCCOPY As Long = &HCC0020

در زیر یک نمونه اورده شده است.
  BitBlt Picture2.hDC, 0, 0, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture1.hDC, 0, 0, SRCCOPY

به ثابت روبه رو نگاه کنید.              Public Const MERGEPAINT = &HBB0226
این ثابت به رنگ پس زمینه ی کنترلی که عکس در آن کپی میشود بستگی دارد.
رنگ backcolor کنترل مقصدرو عوض کنید و بعد عکس رو کپی کنید و نتیجه رو ببینید.
ثابتت زیر رنگ عکس کپی شده رو عوض میکنه ولی با backcolor کاری نداره.
Public Const NOTSRCCOPY = &H330008
همون طور که گفتم برای این تابع ثوابت زیادی وجود داره که در زیر لیست شدن.ولی از توضیح دادن همه ی آنها معذورم.البته خودتون راحت میتونید دونه دونه امتحانش کنید.
Public Const BLACKNESS = &H42
Public Const DSTINVERT = &H550009
Public Const MERGECOPY = &HC000CA
Public Const MERGEPAINT = &HBB0226
Public Const NOTSRCCOPY = &H330008
Public Const NOTSRCERASE = &H1100A69
Public Const SRCAND = &H8800C6
Public Const SRCCOPY = &HCC0020
Public Const SRCERASE = &H440328
Public Const SRCINVERT = &H660046
Public Const SRCPAINT = &HEE0086
Public Const WHITENESS = &HFF0062


۱۳۸۷ بهمن ۲۳, چهارشنبه

picture

امروز میخوام کار با عکس ها رو آموزش بدم.این رو هم بگم که این پست خیلی ابتدایی هستش.

شاید تا حالا پیش اومده باشه که بخواید یه عکس رو از یک محل دلخواه توی یک picture box اضافه کنید و کد زیر رو نوشته باشید
picture1.picture=("c:/mypicture")

خوب حتمآ با ارور مواجه شدید.برای بارکردن یک عکس درون یک picture box یا یک image باید از توابع زیر استفاده کنید.

1)برای بارکردن loadpicture
2)برای سیو کردن savepicture


به مثال های زیر نگاه کنید.

picture1.picture=loadpicture(path)
savepicture picture1.picture,path

دستور loadpicture آرگومان های دیگری هم دارد ولی واجب نیستند.

۱۳۸۷ بهمن ۱۰, پنجشنبه

windowfrompoint

در پست قبلی نحوه ی کار با پنجره ها رو توضیح دادم .هم چنین نحوه ی بدست آوردن محل کرسر رو هم آموزش دادم. حالا میخوام یک کد باحال رو آموزش بدم که فقط با استفاده از محل پنجره هندل اون رو به شما بده.خب دو تا مطلب قبلی یا همون پست قبلی رو اینجا استفاده میکنیم بعلاوه ی تابع windowfrompoint .نیازی ه توضیح نداره پس به کد زیر بسنده میکنم.

مواد لازم:1 عدد فرم - 1 عدد تایمر - لیبل(label)به میزان لازم.

()Private Sub Timer1_Time
Dim wnd As Long
Getcursorpos pointapi
(wnd=Windowfrompoint (pointapi.x,pointapi.y
Label1.caption=wnd
End Sub

Input Output

خب خیلی جاها من دیدم که گفتن نمیشه با ویژوال بیسیک ورودی خروجی هارو کنترل کرد. در صورتی که این حرف کاملآ اشتباه هست. ویژوال بیسیک قابلیت کنت...