فراخوانی‌های API در Access VBA | Microsoft Access 2010 VBA

فراخوانی‌های API در Access VBA

توسط admin | گروه آموزش اکسس Microsoft access | 1405/05/16

نظرات 0

فراخوانی‌های API در Access VBA

فصل ۲۰ — فراخوانی‌های API

با اینکه Access Object Model و VBA برای بسیاری از عملیات Database بسیار جامع‌اند، برخی Functionهای مربوط به خود Windows مستقیماً در VBA وجود ندارند. حتی Visual Basic نیز برای بعضی از این کارها Command مستقیم ارائه نمی‌کند. برای مثال با VBA عادی نمی‌توانید فضای آزاد یک Disk Device را مستقیماً بخوانید، Keyboard را مستقل از Focus یک Form/Control بررسی کنید یا Position فعلی Mouse را به‌طور مستقیم به دست آورید.

Windows خودش این اطلاعات را دارد؛ Windows Explorer فضای Disk را نشان می‌دهد و OS می‌داند چه Keyای فشار داده شده است. VBA برای چنین کارهایی اجازهٔ دسترسی به WIN32 API یا Application Programming Interface را می‌دهد؛ در نتیجه می‌توان مجموعهٔ بزرگی از Functionalityهای Windows را از Code فراخوانی کرد.

API Call موضوعی پیشرفته است و قابلیت بسیار زیادی به برنامه می‌افزاید. هدف این فصل پوشش کامل APIها نیست، بلکه نشان‌دادن چند نمونهٔ عملی است.

API Call چیست؟

API امکان دسترسی به Programming Functionهای داخلی DLL و EXEها، به‌خصوص فایل‌هایی که Windows را پشتیبانی می‌کنند، فراهم می‌کند. Applicationهای Third-party نیز ممکن است Function Libraryهای خود را در DLL ارائه دهند و اگر Documentation مناسب موجود باشد می‌توان آن‌ها را نیز از VBA فراخوانی کرد.

API Callها غالباً Functionهایی هستند که Value برمی‌گردانند و در عین حال Action نیز انجام می‌دهند؛ بعضی نیز Subroutine هستند و فقط Action دارند. پیش از استفاده، باید Function/Subroutine موردنظر را با Statementِ Declare تعریف کنید. این دشوارترین بخش کار است، زیرا Declaration مشخص می‌کند DLL کدام است، Function چه نامی دارد و Parameterها چگونه و با چه Typeهایی پاس داده شوند.

Declaration باید دقیق باشد. اشتباه در Name، Type یا Parameter می‌تواند Call را Fail کند و حتی System را Crash دهد. کتاب توصیه می‌کند پیش از API Call فایل خود را Save کنید، زیرا در صورت Crash ممکن است مجبور به Reboot شوید و Data ذخیره‌نشده از دست برود. APIهای معیوب همیشه با CTRL+BREAK متوقف نمی‌شوند و حتی ارسال Value با Type اشتباه می‌تواند Crash ایجاد کند. با این حال، اگر درست استفاده شوند Functionalityهایی را به VBA می‌آورند که معمولاً در Access موجود نیست.

به‌دست‌آوردن فضای Disk

ابتدا Declaration را در Declarations Section بالای Module قرار دهید:

Private Declare Function GetDiskFreeSpaceEx Lib "kernel32"  _
Alias "GetDiskFreeSpaceExA" (ByVal lpDirectoryName As  _
String, lpFreeBytesAvailableToCaller As Currency,  _
lpTotalNumberOfBytes As Currency, lpTotalNumberOfFreeBytes  _
As Currency) As Long

این Statement Reference به kernel32.dll ایجاد و نحوهٔ Parameterها و Return Type را مشخص می‌کند. متن کتاب اشاره می‌کند Declarationهای API در منابع Visual Basic مانند API32.TXT و Documentationهای توسعه‌دهنده قابل یافتن‌اند؛ Declaration باید عیناً و دقیق باشد.

سپس Function را فراخوانی کنید:

Sub Test_Api()
Dim x as Double
Dim FreeBytesAvailableToCaller As Currency, TotalNumberOfBytes As _
Currency,  TotalNumberOfFreeBytes As Currency
x = GetDiskFreeSpaceEx("c:\", FreeBytesAvailableToCaller, _
TotalNumberOfBytes, TotalNumberOfFreeBytes)
MsgBox "Total Space " & Format(TotalNumberOfBytes * 10000, "#,##0")
MsgBox "Free Space " & Format(TotalNumberOfFreeBytes * 10000, "#,##0")
End Sub

Variableها Valueهای بازگشتی API را نگه می‌دارند. Value برگشتی اصلی در x وضعیت Error/Success را مشخص می‌کند و مقدار 1 نشانهٔ Success است. Root Directory برابر C:\ به Function داده می‌شود. طبق توضیح کتاب، Valueهای Byte به دلیل شیوهٔ Return شدن توسط API در 10,000 ضرب و برای نمایش با Comma Format می‌شوند.

شکل ۲۰-۱ — نمایش Total Space و Free Space با GetDiskFreeSpaceEx
شکل ۲۰-۱ — نمایش Total Space و Free Space با GetDiskFreeSpaceEx

می‌توانید Result را با Properties درایو C در Windows Explorer مقایسه کنید؛ Total Space و Free Space باید با Output Code مطابقت داشته باشند.

خواندن و نوشتن INI File

API Callها برای Read/Write فایل‌های INI نیز قابل استفاده‌اند. INIها تا حد زیادی با Windows Registry جایگزین شده‌اند، ولی هنوز روش ساده‌ای برای نگهداری Program Settingها هستند. Registry نیز API دارد، اما تغییر آن بدون شناخت کافی خطرناک است و اشتباه می‌تواند Application یا حتی Windows را خراب کند.

INI File می‌تواند Settingهای «Sticky» مانند Path انتخابی User را نگه دارد. Variable و Propertyهای عادی VBA پس از بسته‌شدن برنامه از بین می‌روند؛ بنابراین اگر User Path خاصی را در TextBox وارد کند، بدون Persistence بار بعد به Default برمی‌گردد. INI این مقدار را روی Disk حفظ می‌کند.

دو Declaration مورد استفاده در مثال:

Private Declare Function GetPrivateProfileString Lib "kernel32" Alias _
"GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal _
lpKeyName As Any, ByVal lpDefault As String, ByVal lpReturnedString As _
String, ByVal nSize As Long, ByVal lpFileName As String) As Long

Private Declare Function WritePrivateProfileString Lib "kernel32" Alias _
"WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal _
lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As _
Long

این‌ها نیز در Declarations Section قرار می‌گیرند و به kernel32.dll اشاره می‌کنند. استفاده:

Sub Test_INI()
x = WritePrivateProfileString("Parameters", "Path", "C:\temp\", "myini.ini")
s$ = Space$(256)
x = GetPrivateProfileString("Parameters", "Path", "", s$, 256, "myini.ini")
MsgBox s$
MsgBox x
End Sub

خط نخست در INI می‌نویسد و اگر File وجود نداشته باشد ساخته می‌شود. Location پیش‌فرض در مثال Windows Directory است، مگر Filename شامل Path شود. Parameter اول Section، دومی Key Name، سومی Value و چهارمی Filename است. اگر Key Name در Write برابر Null باشد Keyهای Section حذف می‌شوند؛ اگر Value برابر Null باشد String موجود برای همان Key حذف می‌شود.

Suffix فایل الزاماً .ini نیست. کتاب حتی اشاره می‌کند می‌توان Extension دیگری برای پنهان‌ماندن Setting File در نگاه سطحی انتخاب کرد. File ایجادشده در مثال چنین محتوایی دارد:

[Parameters]
Path=C:\temp\

برای Read، ابتدا Space$(256) Stringی با 256 Space ایجاد می‌کند تا Buffer مقصد فراهم شود. Variable باید String باشد چون Return Data به شکل String است. GetPrivateProfileString Section و Key را می‌گیرد، سپس Default Value در صورت نبود Entry، Buffer مقصد، Maximum Character Count و Filename را دریافت می‌کند.

x تعداد Characterهای برگشتی و s$ String نتیجه را که با Null Character خاتمه دارد نگه می‌دارد. اگر KeyName برابر Null باشد، همهٔ Entryهای Section با Null Separator بازگردانده می‌شوند. این APIها نسبتاً Forgiving هستند: Write در نبود File یا Key آن را می‌سازد؛ Read در نبود File Value خالی/Null برمی‌گرداند. از این روش برای بازیابی Settingهای شخصی User در اجرای بعدی برنامه استفاده می‌شود. متن کتاب یادآوری می‌کند Windows جدید به‌طور اصلی Registry را برای چنین Settingهایی به کار می‌برد.

خواندن فعالیت Keyboard

Eventهای Form فقط زمانی Keyboard را می‌بینند که Form یا Control مربوط Focus داشته باشد. اگر Macro فرایند طولانی با هزاران Iteration اجرا کند، ممکن است بخواهید User Key خاصی برای توقف اضطراری داشته باشد؛ در چنین حالتی می‌توان از GetKeyState استفاده کرد.

Declaration:

Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) _
As Integer

نمونه:

Sub Test_Key()
x = 0
Do Until x = 1
    If GetKeyState(&H9) < 0 Then x = 1
    DoEvents
Loop
MsgBox "You pressed the TAB key"
End Sub

Loop تا زمانی که x برابر 1 شود ادامه دارد. Virtual Key Code برابر Hex 09 مربوط به TAB است. وقتی TAB فشرده شود Return Value کمتر از صفر می‌شود، x به 1 تغییر می‌کند و Loop پایان می‌یابد.

DoEvents در این مثال مهم است؛ به Operating System فرصت می‌دهد Messageهای Pending را Process کند. بدون آن ممکن است Keyboard Message پیش از Iteration بعدی پردازش نشود و Keypress از دست برود.

Table 20-1 در کتاب Virtual Key Codeهای اصلی را فهرست می‌کند:

Symbolic ConstantHexMouse/Keyboard
VK_LBUTTON01Left mouse button
VK_RBUTTON02Right mouse button
VK_CANCEL03CTRL+BREAK
VK_MBUTTON04Middle mouse button
05–07Undefined
VK_BACK08BACKSPACE
VK_TAB09TAB
0A–0BUndefined
VK_CLEAR0CCLEAR
VK_RETURN0DENTER
0E–0FUndefined
VK_SHIFT10SHIFT
VK_CONTROL11CTRL
VK_MENU12ALT
VK_PAUSE13PAUSE
VK_CAPITAL14CAPS LOCK
15–19Reserved for Kanji systems
1AUndefined
VK_ESCAPE1BESC
1C–1FReserved for Kanji systems
VK_SPACE20SPACEBAR
VK_PRIOR21PAGE UP
VK_NEXT22PAGE DOWN
VK_END23END
VK_HOME24HOME
VK_LEFT25LEFT ARROW
VK_UP26UP ARROW
VK_RIGHT27RIGHT ARROW
VK_DOWN28DOWN ARROW
VK_SELECT29SELECT
2AOEM-specific
VK_EXECUTE2BEXECUTE
VK_SNAPSHOT2CPRINT SCREEN
VK_INSERT2DINS
VK_DELETE2EDEL
VK_HELP2FHELP
VK_0 … VK_930–390 … 9
3A–40Undefined
VK_A … VK_Z41–5AA … Z
VK_LWIN5BLEFT WINDOWS
VK_RWIN5CRIGHT WINDOWS
VK_APPS5DAPPLICATIONS
5E–5FUndefined
VK_NUMPAD0 … VK_NUMPAD960–69Numeric keypad 0 … 9
VK_MULTIPLY6AMULTIPLY
VK_ADD6BADD
VK_SEPARATOR6CSEPARATOR
VK_SUBTRACT6DSUBTRACT
VK_DECIMAL6EDECIMAL
VK_DIVIDE6FDIVIDE
VK_F1 … VK_F1270–7BF1 … F12
VK_F13 … VK_F247C–87F13 … F24
88–8FUnassigned
VK_NUMLOCK90NUM LOCK
VK_SCROLL91SCROLL LOCK
VK_LSHIFTA0LEFT SHIFT
VK_RSHIFTA1RIGHT SHIFT
VK_LCONTROLA2LEFT CTRL
VK_RCONTROLA3RIGHT CTRL
VK_LMENUA4LEFT MENU
VK_RMENUA5RIGHT MENU
E7–E8Unassigned
E9–F5OEM-specific
VK_ATTNF6ATTN
VK_CRSELF7CRSEL
VK_EXSELF8EXSEL
VK_EREOFF9ERASE EOF
VK_PLAYFAPLAY
VK_ZOOMFBZOOM
VK_NONAMEFCReserved for future use
VK_PA1FDPA1
VK_OEM_CLEARFECLEAR

پخش صدای Multimedia

با API می‌توان WAV File پخش کرد. زبان Macro قدیمی Commandی برای این کار داشت، اما در VBA و حتی Visual Basic کلاسیک Command مستقیم مشابهی وجود ندارد. Declaration:

Public Declare Function PlaySound Lib "winmm.dll" Alias "PlaySoundA" _
(ByVal lpszName As String, ByVal hModule As Long, ByVal dwFlags As _
Long) As Long

نمونه:

Sub test_sound()
x = PlaySound("c:\windows\media\windows exclamation.wav", 0, 0)
x = PlaySound("c:\windows\media\tada.wav", 0, 0)
End Sub

دو Sound استاندارد Windows پخش می‌شوند. Flags برابر 0 یعنی Sound به شکل Synchronous پخش شود و Control تا پایان Sound به VBA برنگردد. اگر Microphone دارید می‌توانید WAV اختصاصی شامل Sound Effect یا Voice ضبط و از همین روش پخش کنید.

این مثال‌ها تنها نمونه‌ای از قدرت API Callها هستند؛ APIهای بسیار بیشتری برای Functionalityهای گوناگون Windows وجود دارند.

صفحهٔ پایانی فصل در نسخهٔ اصلی عمداً خالی است.

امتیاز کاربران به این مقاله

☆☆☆☆☆

0 نفر امتیاز داده اند. میانگین: 0.0 از 5

 

0 نظر

نظر محترم شما در مورد مقاله های وب سایت برنامه نویسی و پایگاه داده

نظرات محترم شما در خدمات رسانی بهتر ما را یاری می نمایند. لطفا اگر مایل بودید یک نظر ما را مهمان فرمائید. آدرس ایمیل و وب سایت شما نمایش داده نخواهد شد.

0 / 500