1. مهمان گرامی، جهت ارسال پست، دانلود و سایر امکانات ویژه کاربران عضو، ثبت نام کنید.
    بستن اطلاعیه

یه سری آموزش های فوق العاده جالب برای دوستان عزیز

شروع موضوع توسط hector2141 ‏10/9/12 در انجمن Visual Basic

  1. کاربر ارشد

    تاریخ عضویت:
    ‏6/9/12
    ارسال ها:
    14,318
    تشکر شده:
    2,702
    امتیاز دستاورد:
    0
    حرفه:
    daneshjo
    پاسخ : یه سری آموزش های فوق العاده جالب برای دوستان عزیز

    ويندوز برای برقراری ارتباط با Internet Service Provide- ISP- شما از طريق مودم و خط تلفن در اتصالات dial-up networking ، از سرويسی خاص به اسم RAS (Remote Access Service) استفاده می کند . اين سرويس دارای يک واسط برنامه نويسی است که RAS API نام دارد . اين واسط شامل مجموعه ای از توابع است که شما می توانيد آنها را در برنامه خود صدا بزنيد . RAS API ابزاری بسيار قدرتمند و قابل انعطاف است همچنين بسيار پيچيده می باشد .
    خوشبختانه برای استفاده راحتتر ، مايکروسافت تعدادی تابع را در مجموعه ای به اسم WinInet API قرار داده تا بتوان از آنها برای برقراری ارتباط و کنترل اتصال استفاده کرد .آشنايي با WinInet API :
    WinInet API مجموعه ای از توابع است که امکان ايجاد و توسعه برنامه های اينترنتی را بصورتی ساده ، سريع و کارآمد برای برنامه نويسان مهيا می کند . با استفاده از اين مجموعه توابع شما می توانيد برنامه هايي بنويسيد که از منابع اينترنتی با استفاده از پروتکلهايي چون HTTP و FTP استفاده کنند . همچنين WinInet به شما اجازه می دهد تا بتوانيد ارتباطی dial-up با يک ISP ايجاد نموده و آنرا کنترل کنيد .
    مزيـت اصلی توابع WinInet آينست که شما نيازی به دانستن ساختار پروتکلهای ارتباطی و نيز برنامه نويسی Socket نخواهيد داشت . بعبارت ديگر WinInet يک واسط سطح بالا را برای کار با منابع اينترنتی ارائه می دهد .

    امکانات Dial-Up موجود در WinInet :
    تا قبل از ارائه اينترنت اکسپلورر ورژن 4 ، WinInet تنها دارای دو تابع dial-up بود :
    تابع InternetAttemptConnect : برای بررسی اينکه آيا يک ارتباط به اينترنت وجود دارد يا نه استفاده می شد . اگر هيچ اتصالی به اينترنت وجود نداشت اين برنامه کادر تبادلی dial-up networking را نمايش می داد و کاربر اجازه داشت تا يک اتصال را برای وصل شدن به اينترنت انتخاب کند .
    تابع InternetCheckConnection : تابع با استفاده از انجام يک دستور ping به url ای که به تابع داده شده ، بررسی می کرد که آيا ارتباطی به اينترنت وجود دارد يا نه .
    اين دو تابع دارای محدوديتهای فراوانی بودند . برای مثال تابع اول نمی تواند بطور اتوماتيک اتصال به اينترنت را برقرار کند و تابع دوم نيز نمی تواند هيچ اطلاعاتی در مورد نوع ارتباط به ما بدهد .
    IE نسخه 4 ، تعدادی تابع جديد برای WinInet معرفی کرد که برخی از آنها عبارتند از :
    تابع InternetGetConnectedState : اطلاعاتی در مورد نوع ارتباط استفاده شده را بيان می کند . برای مثال اين تابع اطلاع می دهد که نوع ارتباط به اينترنت از طريق مودم است يا شبکه LAN و يا از طريق پروکسی .
    تابع InternetAutodial : اين امکان را فراهم می سازد تا يک ارتباط اينترنتی اتوماتيک از طريق مودم را با استفاده از مدخل اتصال پيش فرض که کاربر آنرا در dial-up networking مشخص کرده ايجاد کنيد .
    تابع InternetDial : اين تابع کارآمدتر از تابع InternetAutodial است و کادری را نمايش می دهد که کاربر می تواند نوع مدخل مورد نظر خود برای ارتباط تلفنی با اينترنت را انتخاب کند .
    تابع InternetAutodialHangup : برای قطع کردن اتصالی مودمی که از طريق تابع InternetAutodial برقرار شده استفاده می شود .
    تابع InternetHangUp : برای قطع کردن اتصالی مودمی که از طريق تابع InternetDialبرقرار شده استفاده می شود .
    تابع InternetSetDialState : برای تنظيم کردن وضعيت جاری ارتباط اينترنتی استفاده می شود .
     
    یک شخص از این تشکر کرد.
  2. کاربر ارشد

    تاریخ عضویت:
    ‏6/9/12
    ارسال ها:
    14,318
    تشکر شده:
    2,702
    امتیاز دستاورد:
    0
    حرفه:
    daneshjo
    پاسخ : یه سری آموزش های فوق العاده جالب برای دوستان عزیز

    توابع Dial-Up :
    Name
    Description
    InternetGetConnectedState
    Retrieves the current state of the Internet connection
    InternetAutodial
    Initiates an unattended dial-up connection
    InternetAutodialHangup
    Disconnects a modem connection initiated by
    InternetDial
    Initiates a dial-up connection
    InternetHangUp
    Disconnects a modem connection initiated by InternetDial
    InternetGoOnline
    Prompts the user for permission to initiate a dial-up connection to the given URL
    InternetSetDialState
    Sets the current state of the Internet connection
    توابع عمومی اينترنت :
    Name
    Description
    InternetOpen
    Initializes the Win32 Internet functions
    InternetConnect
    Opens an FTP, Gopher, or HTTP session for a given site
    InternetCloseHandle
    Closes a single Internet handle or a subtree of Internet handles
    InternetErrorDlg
    Displays a dialog box for the error that is passed to InternetErrorDlg
    InternetFindNextFile
    Continues a file search started as a result of a previous call to FtpFindFirstFile or GopherFindFirstFile
    InternetGetLastResponseInfo
    Retrieves the last Win32 Internet function error description or server response on the thread calling this function
    InternetLockRequestFile
    Allows the user to place a lock on the file being used
    InternetQueryDataAvailable
    Queries the amount of data available
    InternetQueryOption
    Queries an Internet option on the specified handle
    InternetReadFile
    Reads data from a handle opened by the InternetOpenURL, FtpOpenFile, GopherOpenFile, or HttpOpenRequest function
    InternetReadFileEx
    Reads data from a handle opened by the InternetOpenURL, FtpOpenFile, GopherOpenFile, or HttpOpenRequest function
    InternetSetFilePointer
    Sets a file position for InternetReadFile
    InternetSetOption
    Sets an Internet option
    InternetSetStatusCallback
    Sets up a callback function that Win32 Internet functions can call as progress is made during an operation
    InternetStatusCallback
    Placeholder for the application-defined status callback function
    InternetTimeFromSystemTime
    Formats a date and time according to the specified RFC format (as specified in the HTTP version 1.0 specification)
    InternetTimeToSystemTime
    Takes an HTTP time/date string and converts it to a SYSTEMTIME structure
    InternetUnlockRequestFile
    Unlocks a file that was locked using InternetLockRequestFile
    InternetWriteFile
    Writes data to an open Internet file
    InternetConfirmZoneCrossing
    Checks for changes between secure and nonsecure URLs
    توابع URL :
    Name
    Description
    InternetCanonicalizeUrl
    Canonicalizes a URL, which includes converting unsafe characters and spaces into escape sequences.
    InternetCombineUrl
    Combines a base and relative URL into a single URL. The resultant URL will be canonicalized.
    InternetCrackUrl
    Cracks a URL into its component parts.
    InternetCreateUrl
    Creates a URL from its component parts.
    InternetOpenUrl
    Begins reading a complete FTP, Gopher, or HTTP URL.
    توابع FTP :
    Name
    Description
    FtpCreateDirectory
    Creates a new directory on the FTP server
    FtpDeleteFile
    Deletes a file stored on the FTP server
    FtpFindFirstFile
    Searches the specified directory of the given FTP session
    FtpGetCurrentDirectory
    Retrieves the current directory for the given FTP session
    FtpGetFile
    Retrieves a file from the FTP server and stores it under the specified file name, creating a new local file in the process
    FtpPutFile
    Stores a file on the FTP server
    FtpRemoveDirectory
    Removes the specified directory on the FTP server
    FtpRenameFile
    Renames a file stored on the FTP server
    FtpSetCurrentDirectory
    Changes to a different working directory on the FTP server
    توابع HTTP :
    Name
    Description
    HttpAddRequestHeaders
    Adds one or more HTTP request headers to the HTTP request handle
    HttpEndRequest
    Ends an HTTP request
    HttpOpenRequest
    Opens an HTTP request handle
    HttpQueryInfo
    Queries for information about an HTTP request
    HttpSendRequest
    Sends the specified request to the HTTP server
    HttpSendRequestEx
    Sends the specified request to the HTTP server
    منبع : dev.ir
     
    یک شخص از این تشکر کرد.
  3. کاربر ارشد

    تاریخ عضویت:
    ‏6/9/12
    ارسال ها:
    14,318
    تشکر شده:
    2,702
    امتیاز دستاورد:
    0
    حرفه:
    daneshjo
    پاسخ : یه سری آموزش های فوق العاده جالب برای دوستان عزیز

    بررسی جزئيات توابع Dial-Up موجود در WinInet :
    1 – تابع InternetAutodial : بطور اتوماتيک باعث شماره گيری اتصال پيش فرض اينترنت توسط مودم می شود . اگر اتصال با موفقيت انجام شود تابع مقدار true و در غير اينصورت false بر می گرداند .
    پارامترهای ورودی تابع :
    dwFlags : فلگ کنترل کننده عمليات اتصال می باشد و يکی از مقادير زير را می تواند داشته باشد :
    - INTERNET_AUTODIAL_FORCE_ONLINE
    - INTERNET_AUTODIAL_FORCE_UNATTENDED
    dwReserved : پارامتری رزرو شده است و بايستی صفر باشد .

    چگونگی declare کردن تابع :
    Public Declare Function InternetAutodial Lib "wininet.dll" (ByVal dwFlags As Long, ByVal dwReserved As Long) As Long
    2 – تابع InternetAutodialHangup : باعث قطع کردن يک اتصال dial-up اتوماتيک می شود . اگر قطع اتصال با موفقيت انجام شود تابع مقدار true و در غير اينصورت false برمی گرداند . تابع دارای يک پارامتر ورودی به اسم dwReserved است که رزرو شده بود و بايستی صفر باشد .
    چگونگی declare کردن تابع :
    Public Declare Function InternetAutodialHangup Lib "wininet.dll" (ByVal dwReserved As Long) As Long
    3 – تابع InternetDial : يک اتصال به اينترنت را با استفاده از يک ارتباط مودم مقداردهی اوليه می کند . پارامترهای ورودی آن عبارتند از :
    hwndParent : هندل مربوط به پنجره parent
    lpszConnectoid : نام ارتباط dial-up مورد استفاده
    dwFlags : فلگ کنترل اتصال که يکی از مقادير زير را می تواند داشته باشد :
    - INTERNET_AUTODIAL_FORCE_ONLINE
    - INTERNET_AUTODIAL_FORCE_UNATTENDED
    - INTERNET_DIAL_UNATTENDED : اتصال به اينترنت از طريق مودم بدون نمايش واسط کاربر
    lpdwConnection : آدرس داده ای که شامل عدد متناظر با اتصال است .
    dwReserved : پارامتری رزرو شده است و بايستی صفر باشد .

    چگونگی declare کردن تابع :
    Public Declare Function InternetDial Lib "wininet.dll" (ByVal hwndParent As Long, ByVal lpszConnectoid As String, ByVal dwFlags As Long, lpdwConnection As Long, ByVal dwReserved As Long) As Long
    4 – تابع InternetGetConnectedState : اين تابع وضعيت اتصال جاری به اينترنت را بر می گرداند . اگر اتصال برقرار باشد تابع مقدار true و در غير اينصورت false برمی گرداند .
    پارامترهای ورودی تابع عبارتند از :
    lpdwFlags : توصيف وضعيت اتصال . اين پارامتر يکی از مقادير زير را می تواند داشته باشد :
    - INTERNET_CONNECTION_MODEM
    - INTERNET_CONNECTION_LAN
    - INTERNET_CONNECTION_PROXY
    - INTERNET_CONNECTION_MODEM_BUSY
    dwReserved : پارامتری رزرو شده است و بايستی صفر باشد .

    چگونگی declare کردن تابع :
    Public Declare Function InternetGetConnectedState Lib "wininet.dll" (ByRef lpdwFlags As Long, ByVal dwReserved As Long) As Long
    5 – تابع InternetGoOnline : پيغامی به کاربر برای دادن مجوز برای مقداردهی اوليه اتصال به يک URL را می دهد . اگر اينکار موفقيت آميز باشد مقدار true و در غير اينصورت false برمی گرداند . پارامترهای ورودی تابع عبارتند از :
    lpszURL : URL وب سايت مورد نظر برای اتصال
    hwndParent : هندل پنجره parent
    dwReserved : پارامتری رزرو شده است و بايستی صفر باشد .

    چگونگی declare کردن تابع :
    Public Declare Function InternetGoOnline Lib "wininet.dll" (ByVal lpszURL As String, ByVal hwndParent As Long, ByVal dwReserved As Long) As Long
    6 – تابع InyernetHangUp : به مودم می گويد که اتصال به اينترنت را قطع کند . پارامترهای اين تابع عبارتند از :
    dwConnection : شماره مربوط به اتصالی که می خواهيم آنرا قطع کنيم .
    dwReserved : پارامتری رزرو شده است و بايستی صفر باشد .

    چگونگی declare کردن تابع :
    Public Declare Function InternetHangUp Lib "wininet.dll" (ByVal dwConnection As Long, ByVal dwReserved As Long) As Long
    7 – تابع InternetSetDialState : تنظيم نمودن وضعيت شماره گيری مودم . اگر تنظيم با موفقيت انجام شود تابع true و در غيراينصورت false برمی گرداند . پارامترهای ورودی تابع عبارتند از :

    lpszConnectoid : نام اتصال dial-up
    dwState : وضعيت مربوط به اتصال dial-up . در حال حاضر اين پارامتر تنها مقدار INTERNET_DIALSTATE_DISCONNECTED را می تواند داشته باشد .

    dwReserved : پارامتری رزرو شده است و بايستی صفر باشد .
    چگونگی declare کردن تابع :
    Public Declare Function InternetSetDialState Lib "wininet.dll" (ByVal lpszConnectoid As String, ByVal dwState As Long, ByVal dwReserved As Long) As Long
     
    یک شخص از این تشکر کرد.
  4. کاربر ارشد

    تاریخ عضویت:
    ‏6/9/12
    ارسال ها:
    14,318
    تشکر شده:
    2,702
    امتیاز دستاورد:
    0
    حرفه:
    daneshjo
    پاسخ : یه سری آموزش های فوق العاده جالب برای دوستان عزیز

    بررسی فلگهای مورد استفاده در توابع dial-up :
    1 – فلگهای تابع InternetDial :
    Public Const INTERNET_DIAL_UNATTENDED = &H8000& '0x8000
    Public Const INTERENT_GOONLINE_REFRESH = &H1 '0x00000001
    Public Const INTERENT_GOONLINE_MASK = &H1 '0x00000001

    2 – فلگهای تابع InternetAutoDial :
    Public Const INTERNET_AUTODIAL_FORCE_ONLINE = 1
    Public Const INTERNET_AUTODIAL_FORCE_UNATTENDED = 2
    Public Const INTERNET_AUTODIAL_FAILIFSECURITYCHECK = 4


    3 – فلگهای تابع InternetGetConnectedState :
    Public Const INTERNET_CONNECTION_MODEM = 1
    Public Const INTERNET_CONNECTION_LAN = 2
    Public Const INTERNET_CONNECTION_PROXY = 4
    Public Const INTERNET_CONNECTION_MODEM_BUSY = 8

    4 - فلگهای مربوط به dial handler اختصاصی :
    Public Const INTERNET_CUSTOMDIAL_CONNECT = 0
    Public Const INTERNET_CUSTOMDIAL_UNATTENDED = 1
    Public Const INTERNET_CUSTOMDIAL_DISCONNECT = 2

    5 – فلگهای عملياتی پشتيبانی شده برای dial handler اختصاصی :
    Public Const INTERNET_CUSTOMDIAL_SAFE_FOR_UNATTENDED = 1
    Public Const INTERNET_CUSTOMDIAL_WILL_SUPPLY_STATE = 2
    Public Const INTERNET_CUSTOMDIAL_CAN_HANGUP = 4

    6 - وضعيتهای مربوط به InternetSetDialState :
    Public Const INTERNET_DIALSTATE_DISCONNECTED = 1


    در اين بخش که آخرين بخش از مباحث WinInet API است برنامه ای نمونه برای کار با توابع مودمی اين کتابخانه ارائه خواهيم داد :
    برای نوشتن برنامه ای که بتوان از طريق آن با استفاده از مودم به اينترنت متصل شد بصورت زير عمل می کنيم :
    در ابتدا بايستی تابع InternetDial را Declare کنيم :

    Private Declare Function InternetDial Lib "wininet.dll" Alias "InternetDialA" (ByVal hwndParent As Long, ByVal lpszConnectoid As String, ByVal dwFlags As Long, lpdwConnection As Long, ByVal dwReserved As Long) As Long
    سپس وضعيت شماره گيری را در متغيری به اسم lOption قرار می دهيم . اين متغير می تواند مقادير زير را داشته باشد :
    - DF_FORCE_ONLINE
    - DF_FORCE_UNATTENDED
    - DF_DIAL_FORCE_PROMPT
    - DF_DIAL_UNATTENDED
    حال نام اتصالی را که می خواهيم از آن استفاده شود در متغيری به اسم ConnectionName قرار می دهيم .
    همچنين دو متغير به اسم ConnectionID و RetVal را از نوع long تعريف می کنيم .

    حال تابع InternetDial را بصورت زير صدا می کنيم :
    RetVal = InternetDial(Me.hwnd, ConnectionName, lOption, ConnectionID, 0)
    اگر RetVal مخالف صفر باشد عمل Dial بدرستی انجام شده است .
    برای قطع اتصال فوق بايستی از تابع InternetHangUp استفاده کنيم . برای اينکار ابتدا تابع فوق را Declare می کنيم :
    Private Declare Function InternetHangUp Lib "wininet.dll" (ByVal dwConnection As Long, ByVal dwReserved As Long) As Long
    سپس اين تابع را بصورت زير فراخوانی می کنيم :
    RetVal = InternetHangUp(ConnectionID, 0)
    برای اينکه مودم را مجبور کنيم تا بطور اتوماتيک از اتصال پيش فرض سيستم برای شماره گيری استفاده کند از تابع InternetAutodial استفاده می کنيم .
    برای اينکار ابتدا تابع را Declare می کنيم :

    Private Declare Function InternetAutodial Lib "wininet.dll" (ByVal dwFlags As Long, ByVal hwndParent As Long) As Long
    سپس تابع را بصورت زير فراخوانی می کنيم :
    RetVal = InternetAutodial(ADF_FORCE_UNATTENDED, Me.hwnd)
    اگر RetVal مخالف صفر باشد عمل AutoDial بدرستی انجام شده است .
    برای قطع اتصالی که توسط AutoDial ايجاد شده از تابع InternetAutodialHangup استفاده می کنيم . ابتدا اين تابع را Declare می کنيم :
    Private Declare Function InternetAutodialHangup Lib "wininet.dll" (ByVal dwReserved As Long) As Long
    فراخوانی اين تابع بصورت زير است :
    Call InternetAutodialHangup(0)
    برای اينکه بفهيم آيا اتصال به اينترنت وجود دارد يا نه از تابع InternetGetConnectedStateEx استفاده می کنيم . برای اينکار ابتدا تابع را Declare می کنيم :
    Private Declare Function InternetGetConnectedStateEx Lib "wininet.dll" Alias "InternetGetConnectedStateExA" (lpdwFlags As Long, lpszConnectionName As Long, dwNameLen As Long, ByVal dwReserved As Long) As Long
    سپس تابع را بصورت زير فراخوانی می کنيم :
    strConnectionName = Space(256)
    lNameLen = 256
    lPtr = StrPtr(strConnectionName)
    lNameLenPtr = VarPtr(lNameLen)
    RetVal = InternetGetConnectedStateEx(lConnectionFlags, ByVal lPtr, ByVal lNameLen, 0)

    که strConnectionName از نوع String و بقيه متغيرها از نوع Long هستند .
    اگر RetVal مخالف صفر باشد اتصال برقرار است .
    ثابتهايی که در کدهای فوق استفاده شده عبارتند از :
    Private Const INTERNET_AUTODIAL_FORCE_ONLINE = 1&
    Private Const INTERNET_AUTODIAL_FORCE_UNATTENDED = 2&
    Private Const INTERNET_AUTODIAL_FAILIFSECURITYCHECK = 4&

    Private Const INTERNET_DIAL_FORCE_PROMPT = &H2000
    Private Const INTERNET_DIAL_SHOW_OFFLINE = &H4000
    Private Const INTERNET_DIAL_UNATTENDED = &H8000

     
    یک شخص از این تشکر کرد.
  5. کاربر ارشد

    تاریخ عضویت:
    ‏6/9/12
    ارسال ها:
    14,318
    تشکر شده:
    2,702
    امتیاز دستاورد:
    0
    حرفه:
    daneshjo
    پاسخ : یه سری آموزش های فوق العاده جالب برای دوستان عزیز

    TAPI چيست ؟

    TAPI يا Telephony API يک کتابخانه استاندارد برای کار با مودم و نوشتن برنامه های تلفنی می باشد . برای نمونه می توان از برنامه های Phone Dialer ( شماره گير تلفن ) ، برنامه شبکه سازی تلفنی ( Dialup Networking ) ، برنامه تشخيص پالس مودم برای ضبط اطلاعات وارد شده از طرف کاربران و کاربردهای ديگر در اين زمينه نام برد . اين کتابخانه به شما کمک کمک می کند تا بدون درگير شدن با برنامه نويسی سخت افزار مودم و درايور آن بطور مستقيم بتوانيد برنامه های کاربردیي در اين زمينه بنويسيد .
    مروری بر Microsoft Telephony :

    Telephony امکان مجتمع سازی کامپيوترها با دستگاههای ارتباطی و شبکه ها را فراهم نموده است . معمولاً دستگاه ارتباطی يک مودم و خط ارتباطی نيز شبکه PSTN ( شبکه عمومی تلفن سوئيچينگ ) می باشد . برخی از کاربردهای Telephony عبارتند از :

    ۱ - کنفرانسهای مالتی مديا بصورت Multicast
    ۲ - VoIP
    ۳ - مرکز پاسخ گويي اتوماتيک
    ۴ - تماس تلفنی از طريق کامپيوتر روی شبکه PSTN

    دياگرام زير معماری Microsoft Telephony را نشان می دهد :
    برنامه های TAPI :

    برای نوشتن برنامه های کاربردی با استفاده از TAPI بايستی ابتدا در مورد سطح سرويسی که می خواهيم ارائه دهيم تصميم گيری کنيم . برای مثال برای نوشتن يک برنامه شماره گير تلفن نياز به استفاده کامل از TAPI نيست و می توان از قابليتهای خود ويندوز در اين زمينه استفاده کرد ( Assisted Telephony ) . در بخشهای بعدی در مورد سطوح مختلف سرويس در TAPI بيشتر صحبت خواهم کرد .
    دومين مطلبی که بايد مورد توجه قرار داد اينست که می خواهيم از TAPI 2.x استفاده کنيم يا از TAPI 3.x . تفاوت ايندو آنست که TAPI ورژن ۲ يک API برمبنای C است در حاليکه ورژن ۳ آن بر مبنای تکنولوژی COM می باشد . در بخشهای بعدی مطالب بيشتری در مورد تفاوتهای اين دو نسخه بيان خواهم کرد .
    بخشهای اصلی يک برنامه کامل TAPI عبارتند از :

    ۱ - TAPI Initialization : شامل load کردن TAPI dll ، اتصال به TAPI Server ، مذاکره در مورد ورژن TAPI و برپاسازی سيستم اطلاع رسانی event می باشد .

    ۲ - Session Control : مقداردهی اوليه ، دريافت و کنترل تماسها

    ۳ - Device Control : دريافت و تنظيم اطلاعات دستگاه

    ۴ - Media Control : تشخيص و يا توليد تونها و ارقام ، کنترل stream

    ۵ - TAPI Shutdown : آزاد سازی منابع
    مقداردهی اوليه TAPI :

    عملکرد درست اجزای TAPI نياز به برپاسازی محيط ارتباطی روی کامپيوتر مورد نظر دارد . مراحل اين امر عبارتند از :

    ۱ - نصب TAPI : زمانيکه سخت افزار و يا نرم افزار برای اولين بار به کامپيوتر اضافه می شود انجام می گيرد . جزئيات کار به سيستم عامل و نرم افزار بستگی دارد .

    ۲ - مقداردهی ابتدائی : ساخت اشيا و مسيرهای ارتباطی

    ۳ - مذاکره در مورد ورژن TAPI : برای اطمينان از اينکه اجزای TAPI قادر به تبادل داده ها باشند .

    ۴ - استخراج اطلاعات منابع : بدست آوردن اطلاعاتی در مورد دستگاهی که می توان از آن در برنامه TAPI مورد نظرمان استفاده نمود .

    ۵ - Event notification : برپاسازی سيستم اطلاع رسانی event
    مقداردهی اوليه TAPI در ويژوال بيسيک :

    از منوی Project گزينه References را انتخاب کرده و از ليست مربوطه مورد Microsoft TAPI 3.0 Type Library را انتخاب کنيد .
    حال وارد بخش کد نويسی فرمتان شويد و متغير objTAPI را بصورت زير تعريف کنيد :

    Dim objTapi As TAPI

    سپس در بخش مربوط به Form Load شی objTAPI را بصورت زير ايجاد می کنيم :

    Set objTapi = New TAPI

    همانطور که در بخشهای قبلی گفته شد ، قبل از فراخوانی هر تابع TAPI ابتدا بايستی آنرا مقداردهی اوليه کنيم . برای مقداردهی اوليه کردن شی TAPI عبارت زير را بنويسيد :

    Call objTapi.Initialize

    انتخاب يک آدرس :
    کد زير نشان می دهد که چگونه می توان با استفاده از شی TAPI در ويژوال بيسيک منابع تلفنی در دسترس را برای يک آدرس که بتواند يک مجموعه مشخص از نيازها را مديريت کند ، بررسی کرد .
    توجه داشته باشيد که قبل از انجام اين کار بايستی عمل مقداردهی اوليه TAPI را که در بخش قبل ررسی شد ، انجام دهيد .

    نکته : در کد زير عمل error checking انجام نگرفته است و برای استفاده از کد زير در برنامه های واقعی بايستی بخش بررسی خطا را به آن اضافه کنيد .
    ۱ - تعريف يک شی آدرس و يک شی مجموعه آدرس :

    Dim gobjAddress As ITAddress
    Dim objCollAddresses As ITCollection

    ۲ - تنظيم شی objCollAddress بعنوان يک مجموعه آدرس از شی objTapi :

    Set objCollAddresses = objTapi.Addresses

    ۳ - پيدا کردن آدرسی که بتواند از واسط مورد نظر ما پشتيبانی کند :

    bFound = False
    For indexAddr = 1 To objCollAddresses.Count
    Set objCrtAddress = objCollAddresses.Item(indexAddr)x
    Set objMediaSupport = objCrtAddress
    Set objAddressCapabilities = objCrtAddress

    If objMediaSupport.QueryMediaType( nSelectedType ) x
    bFound = True
    End If

    Set objAddressCapabilities = Nothing
    Set objMediaSupport = Nothing
    Set objCrtAddress = Nothing

    If bFound = True Then Exit For
    Next indexAddr


    در صورتيکه آدرس مورد نظزر پيدا شود برنامه از حلقه خارج شده و gobjAddress يک آدرس قابل استفاده خواهد بود :

    Set gobjAddress = objcollAddresses.Item(indexAddr)x

    انجام Event Handling در TAPI :

    کد زير شامل يک event handler ساده برای TAPI ، رجيستر کردن واسط event ، تنظيم فيلتر event و رجيستر کردن تمام فراخوانيهای دادن اخطار است . هدف اصلی از اين کد اينست که مطمئن شويم بخشی از TAPI که event ها را دريافت می کند پردازشی را قبل از انتقال به بخشهای ديگر انجام دهد .

    تعاريفها :

    Dim WithEvents gobjTapiWithEvents As TAPI
    Attribute gobjTapiWithEvents.VB_VarHelpID = -1
    Dim glRegistrationToken As Long



    Const TAPI3_CALL_EVENTS =TE_CALLMEDIA Or
    TE_CALLNOTIFICATION Or TE_CALLSTATE


    تنظيم eventfilter بصورتيکه تمام event های تعريف شده برای TAPI را بپذيرد :

    objTapi.EventFilter = TAPI3_CALL_EVENTS

    رجيستر کردن event ها :

    Set gobjTapiWithEvents = objTapi
    Dim fOwner As Boolean, fMonitor As Boolean
    Dim lMediaTypes As Long, lCallbackInstance As Long

    fOwner = True
    fOwner = True
    fMonitor = False
    lMediaTypes = TAPIMEDIATYPE_AUDIO
    lCallbackInstance = 1

    glRegistrationToken = gobjTapi.RegisterCallNotifications(gobjAddress,fMo nitor,
    fOwner,lMediaTypes,lCallbackInstance)x

    انتخاب يک ترمينال :

    + قبل از اينکه يک ترمينال را برای برقراری ارتباط انتخاب کنيد بايستی TAPI Initialization و عمل انتخاب آدرس را انجام داده باشيد .

    ابتدا يک متغير از نوع ITBasicCallControl ( واسط کنترل تماس ) تعريف می کنيم :

    Dim objCallControl As ITBasicCallControl
    Set objCallControl = gobjReceivedCallInfo

    سپس يک متغير از نوع ITTerminalSupport ( کوئری از شی آدرس ) تعريف می کنيم :

    Dim objTerminalSupport As ITTerminalSupport
    Set objTerminalSupport = gobjAddress

    سپس متغير ترمينال را تعريف کرده و توسط شی objTerminalSupport يک ترمينال را برای آن استخراج می کنيم :

    Dim objTerminal As ITTerminal
    Set objTerminal = objTerminalSupport.GetDefaultStaticTerminal(lMedia Type, dir)x

    در اينجا ديگر نيازی به شی objTerminalSupport نيست بنابراين آنرا آزاد می کنيم :

    Set objTerminalSupport = Nothing

    سپس نياز به تعريف شی objStreamControl برای کنترل ترمينال است :

    Dim objStreamControl As ITStreamControl
    Set objStreamControl = objCallControl

    در صورتيکه اين شی ايجاد شود ، به ازای استريم های موجود در ITCollection امکان ايجاد ترمينال در يک حلقه for بررسی می شود و ترمينال مناسب انتخاب می گردد :

    If Not (objStreamControl Is Nothing) Then
    Dim objITCollStreams As ITCollection

    Set objITCollStreams = objStreamControl.Streams

    Dim nIndex As Long, objCrtStream As ITStream

    For nIndex = 1 To objITCollStreams.Count
    Set objCrtStream = objITCollStreams.Item(nIndex)x
    If objCrtStream.MediaType = lMediaType Then
    If objCrtStream.Direction = dir Then
    Call objCrtStream.SelectTerminal(objTerminal)x
    End If
    End If
    Set objCrtStream = Nothing
    Next nIndex

    Set objITCollStreams = Nothing
    Set objStreamControl = Nothing
    End If


    ايجاد يک تماس ( Make a Call ) :
    + قبل از اين بخش بايستی مراحل TAPI Initialization و عمل انتخاب آدرس انجام شده باشد .
    اين بخش برای ايجاد يک شی تماس ، بررسی و مشخص کردن استريمی که با اين تماس در ارتباط است ، انتخاب و ايجاد ترمينالهای مناسب و کامل کردن ارتباط استفاده می شود .
    قبل TAPI Initialization و عمل انتخاب آدرس و انتخاب ترمينال انجام شده باشد .
    در ابتدا با استفاده از متد CreateCall يک شی تماس ساخته می شود :

    Set gobjCall = gobjOrigAddress.CreateCall(strDestAddress, nSelectedType,lMediaTypes)x

    سپس در اينجا بايستی کدی که در بخش اول اين درس برای انتخاب ترمينال نوشته شد آورده شود :

    }
    Select Terminal Code
    {

    سپس بايستی دستور Connect اجرا شود :

    gobjCall.Connect (False)x

    False بدين معناست که ارتباط بصورت آسنکرون برقرار می شود .
    دريافت يک تماس :

    کد زير برای يافتن و يا ايجاد يک ترمينال مناسب برای دريافت يک تماس بکار می رود . بايستی توجه داشته باشيد که قبل از اجرای کد زير بايستی مراحل مقداردهی اوليه ، انتخاب يک آدرس و رجيسر کردن event ها را انجام دهيد . همچنين در کد زير بايستی مرحله انتخاب ترمينال را نيز انجام دهيد . توجه داشته باشيد که در کد زير متغير pEvent يک اشاره گر برای واسط ITCallNotificationEvent است که توسط TAPI به event Handler داده می شود :

    If TapiEvent = TE_CALLNOTIFICATION Then
    Dim objCallNotificationEvent As ITCallNotificationEvent
    Set objCallNotificationEvent = pEvent
    Dim gobjReceivedCallInfo As ITCallInfo
    Set gobjReceivedCallInfo = objCallNotificationEvent.Call
    Dim objCallControl As ITBasicCallControl
    Set objCallControl = gobjReceivedCallInfo
    objCallControl.Answer
    End If

     
    یک شخص از این تشکر کرد.
  6. کاربر ارشد

    تاریخ عضویت:
    ‏6/9/12
    ارسال ها:
    14,318
    تشکر شده:
    2,702
    امتیاز دستاورد:
    0
    حرفه:
    daneshjo
    پاسخ : یه سری آموزش های فوق العاده جالب برای دوستان عزیز

    گرفتن اطلاعات ورودی از کيبرد - ۱



    Direct Input 8 همانطور که از نامش مشخص است به شما اجازه می دهد که بتوانيد برنامه هايي بنويسيد که توسط هر نوع دستگاه ورودی کنترل شود .
    Direct Input 8 دارای چندين مزيت نسبت به استفاده از کنترلهای ورودی خود ويژوال بيسيک دارد – کنترلهايي مثل Form_KeyUp, Form_KeyDown, Form_MouseMove - و همچنين قابليت کنترل بيشتری نسبت به توابع استاندارد Win32 از قبيل GetCursorPos, GetKeyState دارد .
    Direct Input 8 سريعتر ، کاراتر و قدرتمند تر بوده و برای ساخت بازيها طراحی شده بنابراين باعث کندی برنامه ها نخواهد شد .

    چگونگی کار با Direct Input 8 برای گرفتن ورودی از کيبرد

    دو روش برای استفاده از کيبرد در DirectX8 وجود دارد : روش polling و روش event-based که هر دو دارای مزايا و معايبی هستند .
    بطور کلی در اغلب طراحيها از روش event-based استفاده می شود زيرا کار با آن راحت تر اسن . در اين روش هر پيغام فرستاده شده ازطرف دستگاه ورودی log می شود و برنامه نيازی به هيچگونه پردازشی بمنظور منتظر ماندن برای يک پيغام از طرف ورودی ندارد ، بنابر اين کاراتر است . در روش polling کنترل کمی دقيقتر و راحتر است .
    اگر در مورد برنامه نويسی بر مبنای polling و بر مبنای event اطلاعات کافی نداريد می توانيد از منابع موجود در سايتهايي چون Gamasutra و GameDev استفاده کنيد .

    روش Polling

    مراحل اين روش عبارتند از :

    1 – تعريفات Declerations : يک فرم ايجاد کرده و يک TextBox به نام txtOutput با خصوصيات Multiline ، Locked و Vertical Scroll Bar در آن قرار دهيد . کدهای زير را در بخش کدنويسی اين فرم بنويسيد :

    Private Const UsePollingMethod As Boolean = True
    Private Const UseEventMethod As Boolean = False
    ‘نکته مهم اينست که تنها يکی از دو ثابت فوق بايستی True باشد .
    Private bRunning As Boolean
    ‘اين متغير برای polling استفاده می شود
    Private DX As DirectX8
    Private DI As DirectInput8
    ‘تعريف شی اصلی DirectX و شی DirectInput
    Private DIDevice As DirectInputDevice8
    Private DIState As DIKEYBOARDSTATE
    ‘اين دو شی برای دسترسی به دستگاه ورودی ( کيبرد ) استفاده می شوند
    Private KeyState(0 To 255) As Boolean
    ‘آرايه ای برای تشخيص فشرده شدن کليد
    Private Const BufferSize As Long = 10
    ‘ سايز بافر نگهدارنده event ها . در روش event-based اين مقدار برابر يک و در روش polling برابر 10 تا 20 است ( بسته به سرعت حلقه بازی )
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)x
    ‘ تابع Sleep برای متوقف کردن حلقه polling در صورت بالا بودن نرخ ورودی


    2- مقدار دهی اوليه Initialisation : اين بخش سه مرحله دارد :
    در مرحله اول اشيا و Device ها ساخته می شوند .
    در مرحله دوم تنظيمات مربوط به Device انجام می شود .
    در مرحله سوم به Device می گوئيم که می خواهيم شروع به استفاده از آن کنيم .

    در Form_Load کدهای زير را بنويسيد :

    Me.Show
    Dim I As Long
    Dim DevProp As DIPROPLONG
    Dim DevInfo As DirectInputDeviceInstance8
    Dim pBuffer(0 To BufferSize) As DIDEVICEOBJECTDATA
    If UsePollingMethod And UseEventMethod Then
    MsgBox "You must select only one of the constants before running"x
    Unload Me
    End
    End If

    If UsePollingMethod Then txtOutput.Text = "Using Polling Method" & vbCrLf
    If UseEventMethod Then txtOutput.Text = "Using Event Based Method" & vbCrLf

    ‘مقداردهی اوليه روش انتخاب شده
    Set DX = New DirectX8
    Set DI = DX.DirectInputCreate
    Set DIDevice = DI.CreateDevice("GUID_SysKeyboard")x

    DIDevice.SetCommonDataFormat DIFORMAT_KEYBOARD
    DIDevice.SetCooperativeLevel frmMain.hWnd, DISCL_BACKGROUND Or ISCL_NONEXCLUSIVE

    ‘برپاسازی بافر
    DevProp.lHow = DIPH_DEVICE
    DevProp.lData = BufferSize
    DIDevice.SetProperty DIPROP_BUFFERSIZE, DevProp

    ‘ به دايرکت ايکس می گوئيم که می خواهيم از دستگاه ورودی استفاده کنيم
    DIDevice.Acquire

    ‘استخراج اطلاعاتی در مورد دستگاه ورودی
    Set DevInfo = DIDevice.GetDeviceInfo()x
    txtOutput.Text = txtOutput.Text & "Product Name: " & DevInfo.GetProductName & vbCrLf
    txtOutput.Text = txtOutput.Text & "Device Type: " & DevInfo.GetDevType & vbCrLf
    txtOutput.Text = txtOutput.Text & "GUID: " & DevInfo.GetGuidInstance & vbCrLf


    ‘در صورتی که بخواهيم به برنامه خاتمه بدهيم کدهای زير را می نويسيم
    DIDevice.Unacquire
    Set DIDevice = Nothing
    Set DI = Nothing
    Set DX = Nothing
    Unload Me
    End


    3 – گرفتن ورودی از کيبرد : در اين بخش فرض کنيد بخواهيم يک بازی را در يک حلقه Do-Loop شبيه سازی کنيم . در اين حلقه هر بار فشرده شدن کليدهای کيبرد را چک می کنيم :

    If Not Err.Number Then bRunning = True

    Do While bRunning

    ‘دريافت اطلاعات شامل خواندن وضعيت کيبرد ، خواندن اطلاعات بافر و سپس خطا
    DIDevice.GetDeviceStateKeyboard DIState
    DIDevice.GetDeviceData pBuffer, DIGDD_DEFAULT
    If Err.Number = DI_BUFFEROVERFLOW Then
    Msgbox(“BUFFER OVERFLOW (Compensating)...")x
    GoTo ENDOFLOOP:
    End If
    ‘بررسی فشرده شدن کليدها
    For I = 0 To 255
    If DIState.Key(I) = 128 And (Not KeyState(I) = True) Then
    txtOutput.Text = txtOutput.Text & "{ DOWN } " & KeyNames(CInt(I))& vbCrLf
    txtOutput.SelStart = Len(txtOutput.Text)x
    KeyState(I) = True
    End If
    Next I

    ‘بررسی رها شدن کليد
    For I = 0 To BufferSize
    If KeyState(pBuffer(I).lOfs) = True And pBuffer(I).lData = 0 Then
    KeyState(pBuffer(I).lOfs) = False
    txtOutput.Text = txtOutput.Text & "{ UP } " & KeyNames(CInt(pBuffer(I).lOfs)) & vbCrLf
    txtOutput.SelStart = Len(txtOutput.Text)x
    End If
    Next I

    Sleep (50)x
    DoEvents
    ENDOFLOOP:
    Loop

    در کد فوق يک تابع KeyName وجود دارد که نام کليد فشارداده شده را بر می گرداند . بخشی از اين تابع را در زير می بينيد :


    Function KeyNames(iNum As Integer) As String

    Dim aKeys(0 To 255) As String

    aKeys(1) = "DIK_ESCAPE"
    aKeys(2) = "DIK_1 On main keyboard"x
    aKeys(3) = "DIK_2 On main keyboard"x
    aKeys(4) = "DIK_3 On main keyboard"x
    aKeys(5) = "DIK_4 On main keyboard"x
    aKeys(6) = "DIK_5 On main keyboard"x
    aKeys(7) = "DIK_6 On main keyboard"x
    aKeys(8) = "DIK_7 On main keyboard"x
    aKeys(9) = "DIK_8 On main keyboard"x
    aKeys(10) = "DIK_9 On main keyboard"x
    aKeys(11) = "DIK_0 On main keyboard"x
    aKeys(12) = "DIK_MINUS On main keyboard"x
    aKeys(13) = "DIK_EQUALS On main keyboard"x
    aKeys(14) = "DIK_BACK BACKSPACE"x
    aKeys(15) = "DIK_TAB"x
    aKeys(16) = "DIK_Q"x
    aKeys(17) = "DIK_W"x
    aKeys(18) = "DIK_E"x
    aKeys(19) = "DIK_R"x
    aKeys(20) = "DIK_T"x
    .
    .
    .
    KeyNames = aKeys(iNum)x

    End Function

     
    یک شخص از این تشکر کرد.
  7. کاربر ارشد

    تاریخ عضویت:
    ‏6/9/12
    ارسال ها:
    14,318
    تشکر شده:
    2,702
    امتیاز دستاورد:
    0
    حرفه:
    daneshjo
    پاسخ : یه سری آموزش های فوق العاده جالب برای دوستان عزیز

    موضوع : کنترل ماوس با DirectX Input



    برای استفاده از ماوس در برنامه های مالتی مديا و بازيها همانند کی برد می توانيم از امکانات دايرکت ايکس استفاده کنيم . روش کنترل ماوس توسط DirectX Input بسيار ساده بوده و مشابه کنترل کيبرد می باشد بنابراين درصورتی که دو درس گذشته را نخوانده اين پيشنهاد می کنم ابتدا آنها را مطالعه کنيد .

    برپاسازی Device :

    علاوه بر متغيرهايي که در بخش کنترل کيبرد تعريف شد بايستی متغيرهای جديد زير را نيز در ابتدای برنامه تان تعريف کنيد :

    Private Const mSpeed As Single = 2
    Private Const BufferSize As Long = 10
    Private mPosition As Point

    mSpeed مقدار سرعت حرکت کرسر ماوس را مشخص می کند .
    BufferSize سايز بافر DI می باشد .
    mPosition موقعيت جاری کرسر ماوس را نشان می دهد .

    در مرحله بعدی بايستی مقداردهي های اوليه لازم را انجام دهيد :

    Set DIDevice = DI.CreateDevice("guid_SysMouse")x
    Call DIDevice.SetCommonDataFormat(DIFORMAT_MOUSE)x
    Call DIDevice.SetCooperativeLevel(frmMain.hWnd, DISCL_FOREGROUND Or DISCL_EXCLUSIVE)x

    تفاوت عمده کدهای فوق با کدهای مقداردهی اوليه در بخش کی برد آنست که cooperativelevel تغيير کرده است . در اينجا گفته شده که ما می خواهيم از ماوس بصورت انحصاری در برنامه استفاده کنيم . اين حالت برای برنامه های window-base مناسب نيست و بهترست از آن در بازيهايي که بصورت full screan هستند استفاده کنيد .

    خواندن ورودی از ماوس :

    در اين بخش می توانيد هم از روش polling و هم event-based استفاده کنيد . نکته مهمی که در اينجا وجود دارد آنست که Direct Input فقط حرکت داده شدن ماوس و کليک شدن يک دکمه را به شما اطلاع می دهد و برای تشخيص حالتهای double click و single click خودتان بايستی کد بنويسيد برای مثال اگر فاصله زمانی بين دو کليک کمتر از ۴۰ ميلی ثانيه باشد آنگاه اين يک double click بوده است .
    کد زير حرکت داده شدن ماوس و کليک يکی از سه دکمه آنرا اطلاع می دهد :

    Dim DevData(1 To BufferSize) As DIDEVICEOBJECTDATA
    Dim nEvents As Long
    Dim I As Long
    nEvents = DIDevice.GetDeviceData(DevData, DIGDD_DEFAULT)x
    For I = 1 To nEvents
    Select Case DevData(I).lOfs
    Case DIMOFS_X
    mPosition.x = mPosition.x + (DevData(I).lData * mSpeed)x
    If mPosition.x < 0 Then mPosition.x = 0
    If mPosition.x > frmMain.ScaleWidth Then mPosition.x = frmMain.ScaleWidth
    imgCursor.Top = mPosition.y
    imgCursor.Left = mPosition.x
    lablel(1).Caption = "Mouse Coordinates: [" & mPosition.x & ", " & mPosition.y & "]"x
    Case DIMOFS_Y
    mPosition.y = mPosition.y + (DevData(I).lData * mSpeed)x
    If mPosition.y < 0 Then mPosition.y = 0
    If mPosition.y > frmMain.ScaleHeight Then mPosition.y = frmMain.ScaleHeight
    imgCursor.Top = mPosition.y
    imgCursor.Left = mPosition.x
    lablel(1).Caption = "Mouse Coordinates: [" & mPosition.x & ", " & mPosition.y & "]"x
    Case DIMOFS_BUTTON0
    label(2).Caption = "Button 0 State: " & IIf(DevData(I).lData = 0, "Up", "Down")x
    Case DIMOFS_BUTTON1
    label(3).Caption = "Button 1 State: " & IIf(DevData(I).lData = 0, "Up", "Down")x
    Case DIMOFS_BUTTON2
    label(4).Caption = "Button 2 State: " & IIf(DevData(I).lData = 0, "Up", "Down")x
    Case DIMOFS_BUTTON3
    label(5).Caption = "Button 3 State: " & IIf(DevData(I).lData = 0, "Up", "Down")x
    End Select
    Next I

    برای استفاده از کد فوق در روش Polling ، بايستی آنرا در يک حلقه Do while-Loop قرار دهيد .
    برای استفاده از کد فوق در روش Event-Based ، بايستی آنرا درون روتين DirectXEvent8_DXCallback قرار دهيد .

     
  8. کاربر ارشد

    تاریخ عضویت:
    ‏6/9/12
    ارسال ها:
    14,318
    تشکر شده:
    2,702
    امتیاز دستاورد:
    0
    حرفه:
    daneshjo
    پاسخ : یه سری آموزش های فوق العاده جالب برای دوستان عزیز

    موضوع : پخش افکتهاي صوتی در برنامه هاي مالتي مديا

    در سلسله مباحث DirectXAudio شما تکنيکهاي لازم براي اضافه کردن موزيک و افکتهاي صوتي سريع و ديناميک را به بازيها و برنامه هاي مالتي مديا خواهيد آموخت . DirectXAudio جايگزيني براي بخشهاي DirectSound ، DirectSound3D و DirectMusic موجود در DirectX 7 مي باشد و داراي امکانات بهتر و سريعتری بوده و برنامه نويسي آن نيز ساده تر است .
    در اولين درس از DirectXAudio چگونگي پخش افکتهاي صوتي را در برنامه هايتان خواهيد آموخت .

    Initial کردن DirectSound :
    DirectSound اولين مبحثي است که آنرا توضيح خواهم داد . گرچه DirectXAudio يک نام عمومي براي امکانات صوتي DirectX8 مي باشد اما بين Sound و Music تفاوت وجود دارد .
    DirectSound با پخش افکتهاي صوتي ارتباط دارد . DirectSound همانند Direct3D از يکسري device سخت افزاري و نرم افزاري استفاده مي کند و افکتهاي صوتي در يکسري بافر ذخيره مي شوند .
    اولين قدم براي برپاسازي DirectSound ، اضافه کردن کتابخانه DirectX8 به پروژه تان مي باشد . قدم بعدي تعريف متغيرها و object هاي موردنياز است . براي استفاده از DirectSound به متغيرهاي زير نياز داريم :

    Private DX As DirectX8
    Private DS As DirectSound8
    Private DSBuffer As DirectSoundSecondaryBuffer8
    Private DSEnum As DirectSoundEnum8
    Private bLoaded As Boolean

    DirectX شي کنترل کننده مرکزي است . DirectSound8 واسط مراقب براي تمام interface هاي پخش صدا است . DirectSoundSecondaryBuffer8 داده audio واقعي را براي پخش ذخيره مي کند . DirectSoundEnum8 اجازه مي دهد که اطلاعاتي را در مورد device هاي سخت افزاري/نرم افزاري استخراج کنيد و متغير bLoaded يک flag وضعيت مي باشد .
    حال در برنامه بايد ليست تمام device هاي در دسترس را مشخص کنيم . ( اين امر کاملاً امکان پذير است که يک کامپيوتر بيش از يک device براي DirectSound داشته باشد ) :

    Private Sub Form_Load()x
    bLoaded = False
    Dim I As Long
    Set DX = New DirectX8
    Set DSEnum = DX.GetDSEnum
    For I = 1 To DSEnum.GetCount
    MsgBox(DSEnum.GetDescription(I))x
    Next I
    End Sub

    فرض کنيم که يکي از device هاي شناخته شده را انتخاب کرديم . حال بايستي device را واقعاً برپا کنيم :

    If bLoaded Then
    Set DSBuffer = Nothing
    Set DS = Nothing
    Set DX = Nothing
    End If
    Dim DSBDesc As DSBUFFERDESC
    Set DX = New DirectX8
    Set DS = DX.DirectSoundCreate(DSEnum.GetGuid(devicenumber)) x
    DS.SetCooperativeLevel frmMain.hWnd, DSSCL_NORMAL

    متغير devicenumber شماره device اي است که شما مي خواهيد با آن کار کنيد . DSBDesc فايل صوتي شما را توصيف مي کند .
     
  9. کاربر ارشد

    تاریخ عضویت:
    ‏6/9/12
    ارسال ها:
    14,318
    تشکر شده:
    2,702
    امتیاز دستاورد:
    0
    حرفه:
    daneshjo
    پاسخ : یه سری آموزش های فوق العاده جالب برای دوستان عزیز

    موضوع : پخش افکتهاي صوتی در برنامه هاي مالتي مديا

    ساخت بافر و play کردن آن :
    تاکنون ما توانستيم DirectSound را initial کنيم . همانطور که می دانيد در تمام component های DirectX داده ها در يکسری بافر ذخيره می شوند . در مورد DirectSound نيز ما يک بافر با نام DirectSoundSecondaryBuffer8 می سازيم و داده های صوتی را در آن قرار می دهيم . برخی پارامتر ها هستند که بايد برای بافر تنظيم شوند مثل : stereo يا mono بودن بافر ، ۸ بيتی يا ۱۶ بيتی بودن بافر ، فرکانس صوتی ( 22khz ، 44khz و غيره ) . اگر اين پارامترها را مشخص نکنيم DirectSound از اطلاعات فايل صوتی استفاده می کند .
    در يک کاربرد ساده ، ما تنها يک بافر صوتی از يک فايل ايجاد می کنيم اما امکان ايجاد چندين بافر بطور همزمان و نيز پخش چندين صدا بطور همزمان نيز وجود دارد :

    DSBDesc.lFlags = DSBCAPS_CTRLFREQUENCY Or DSBCAPS_CTRLPAN Or DSBCAPS_CTRLVOLUME
    Set DSBuffer = DS.CreateSoundBufferFromFile(App.Path & "\Sample.wav", DSBDesc)x
    MsgBox "SOUND BUFFER CREATED:"x
    MsgBox "Buffer Size: " & DSBDesc.lBufferBytes & "bytes (" & Round(DSBDesc.lBufferBytes / 1024, 3) & "kb)"x
    MsgBox "Buffer Channel Count:" & DSBDesc.fxFormat.nChannelsIIf(DSBDesc.fxFormat.nCh annels = 1, " (Mono)", " (Stereo)")x
    MsgBox "Buffer Bits per channel: " & DSBDesc.fxFormat.nBitsPerSample & " bits"x

    در بالا يک بافر صوتی ايجاد شده و اطلاعات صدا از فايل به بافر load شده است .
    حال بايستی داده صوتی موجود در بافر را play کنيم :
    دستور لازم برای Play کردن بافر بصورت loop :

    DSBuffer.Play DSBPLAY_LOOPING

    دستور لازم برای Play کردن بافر بدون loop :

    DSBuffer.Play DSBPLAY_DEFAULT

    دستورات لازم برای Stop کردن بافر :

    DSBuffer.Stop
    DSBuffer.SetCurrentPosition 0

    دستور لازم برای Pause کردن بافر :

    DSBuffer.Stop

    تنظيم خصوصيات بافر : سه خصوصيت وجود دارد که در مورد بافر تنظيم می شود pannig ، volume و frequency
    محدوده مقادير pannig بين اعداد زير است :
    DSBPAN_LEFT = -10,000
    DSBPAN_CENTER = 0
    DSBPAN_RIGHT = 10,000
    توسط متد SetPan می توان pannig بافر را تنظيم کرد :

    DSBuffer.SetPan yourValue

    DirectSound صدا را تقويت نمی کند بلکه آنرا تضعيف می نمايد بنابراين ماکزيمم volume عبارت است از volume ای که فايل صوتی با آن ضبط شده است . بعبارت ديگر محدود مقادير volume بين اعداد زير است :
    DSBVOLUME_MAX = 0
    DSBVOLUME_MIN = -10000
    توسط متد SetVolume می توان volume بافر را تنظيم کرد :

    DSBuffer.SetVolume yourValue

    محدود فرکانسی DirectSound عبارت است از :
    DSBFREQUENCY_MIN = 100 (hz)x
    DSBFREQUENCY_MAX = 100000 (hz) = 100khz x
    توسط متد SetFrequency می توان فرکانس بافر را تنظيم کرد :

    DSBuffer.SetFrequency yourValue
     
  10. کاربر ارشد

    تاریخ عضویت:
    ‏6/9/12
    ارسال ها:
    14,318
    تشکر شده:
    2,702
    امتیاز دستاورد:
    0
    حرفه:
    daneshjo
    پاسخ : یه سری آموزش های فوق العاده جالب برای دوستان عزیز

    موضوع : پخش موزيک توسط DirectMusic



    در اولين درس از آموزش DirectXAudio با چگونگي پخش افکتهاي صوتي آشنا شديد . اکنون اين توانايي را داريد که يک engine ساده صوتي بنويسيد . در اين بخش مباني پخش موزيک را فرا خواهيد گرفت . پس از اين درس شما مي توانيد يک ماژوال براي پخش موزيکهاي پس زمينه و افکتهاي صوتي براي برنامه هايتان ايجاد کنيد .

    Initil کردن DirectMusic8 :

    قبل از هر کار بايستي ماژول DirectMusic8 را مقداردهي اوليه کنيد . اينکار بصورت زير انجام مي شود :

    Option ExplicitImplements DirectXEvent8
    Private oDX As DirectX8
    Private oDMPerf As DirectMusicPerformance8
    Private oDMLoader As DirectMusicLoader8
    Private oDMSeg As DirectMusicSegment8

    Dim dmParams As DMUS_AUDIOPARAMS
    Set oDX = New DirectX8
    Set oDMPerf = oDX.DirectMusicPerformanceCreate
    Set oDMLoader = oDX.DirectMusicLoaderCreate
    oDMPerf.InitAudio frmMain.hWnd, DMUS_AUDIOF_ALL, dmParams, Nothing, DMUS_APATH_DYNAMIC_STEREO, 128
    oDMPerf.SetMasterAutoDownload True

    شي DirectMusicLoader8 کمک مي کند تا موزيک درون بافر load شود .
    شي DirectMusicSegment8 مموزيکي را که بايد پخش شود ذخيره مي کند .
    کد فوق کافي است يکبار زمانيکه برنامه آغاز مي شود ، اجرا گردد .
    اکنون ما يک واسط مقدار دهي شده از DirectMusic داريم اما قبل از اينکه موزيک را Load کرده و پخش کنيم چگونگي terminate کردن DirectMusic را در زير مي بينيد :

    If ObjPtr(oDMSeg)Then Set oDMSeg = Nothing
    If ObjPtr(oDMLoader)Then Set oDMLoader = Nothing
    If Not (oDMPerf Is Nothing) Then
    oDMPerf.CloseDown
    Set oDMPerf = Nothing
    End If
    If ObjPtr(oDX) Then Set oDX = Nothing


    پيغامها :

    در برخي از component هاي DirectX8 مثل Input , Sound , Music و Play برنامه شما بايستي يک سيستم messaging را برپا کند تا DirectX زمان وقوع برخي رخدادهاي خاص را بشما گزارش دهد . اين مطلب بخصوص زمانيکه يک موزيک را پخش مي کنيد مفيد است براي مثال مي تواند زمان خاتمه يافتن موزيک را به شما اطلاع دهد و آنگاه شما مي توانيد قطعه موزيک بعدي را پخش کنيد .
    پيغامها توسط يک سيستم callback انجام مي شوند . کد زير را در تابع InitDMusic تان پس از initial کردن DirectMusic8 قرار دهيد :

    oDMPerf.AddNotificationType DMUS_NOTIFY_ON_SEGMENT
    hEvent = oDX.CreateEvent(Me)x
    oDMPerf.SetNotificationHandle hEvent

    اولين سطر به DirectMusic مي گويد چه نوع پيغامهايي را مي خواهيد به برنامه تان بفرستد . چندين نوع پيغام وجود دارد :
    DMUS_NOTIFY_ON_SEGMENT = اطلاعات موزيک فعلي ( شروع پخش ، پايان پخش و غيره )
    DMUS_NOTIFY_ON_CHORD = اطلاعات تغيير chord موزيک
    DMUS_NOTIFY_ON_COMMAND = زمانيکه يک event فرماني صدا زده شود .
    DMUS_NOTIFY_ON_MEASUREANDBEAT = اطلاعات beat/measure مربوط به موزيک فعلي
    DMUS_NOTIFY_ON_PERFORMANCE = که event مربوط به سطح performance می باشد .
    DMUS_NOTIFY_ON_RECOMPOSE = که recomposition event می باشد .
    آخرين بخش از پيغام دهي ، تابع اصلي آن مي باشد . همانطور که در بخش Initial کردن DirectMusic ديديد يک توصيف بصورت Implements DirectXEvent8 داشتيم . بخش اصلي تابع callback مربوط به DirectXEvent8 ، شامل يک select case است که بين پيغامهاي مختلف سوئيچ می کند :

    Private Sub DirectXEvent8_DXCallback(ByVal eventid As Long)x
    If eventid = hEvent Then
    Dim dmMSG As DMUS_NOTIFICATION_PMSG
    If Not oDMPerf.GetNotificationPMSG(dmMSG) Then
    Else
    Select Case dmMSG.lNotificationOption
    Case DMUS_NOTIFICATION_SEGABORT
    Case DMUS_NOTIFICATION_SEGALMOSTEND
    Case DMUS_NOTIFICATION_SEGEND
    Case DMUS_NOTIFICATION_SEGLOOP
    Case DMUS_NOTIFICATION_SEGSTART
    Case Else
    End Select
    End If
    End If
    End Sub


    پخش موزيک / متوقف کردن موزيک :

    براي پخش يک موزيک ابتدا بايستي آنرا load کنيد . اينکار توسط کد زير انجام مي شود :

    oDMLoader.SetSearchDirectory App.Path & "\"x
    Set oDMSeg = oDMLoader.LoadSegment(App.Path & FILENAME)oDMSeg.SetStandardMidiFile

    DirectMusic تنها چهار نوع فرمت صوتي را مي پذيرد : WAV ، MID ، RMI و SEG .
    براي پخش فايلهاي MP3 بايستي از DirectXShow استفاده کنيد که آنرا در درسهاي بعدي خواهيد ديد .
    اکنون که داده هاي فايل صوتي درون بافر load شد مي توانيد آنرا پخش کنيد :

    oDMSeg.SetRepeats 0
    oDMPerf.PlaySegmentEx oDMSeg, DMUS_SEGF_DEFAULT, 0

    تعداد پخش شدن فايل را با متد SetRepets تنظيم کنيد . اگر اين مقدار صفر باشد ، آهنگ تنها يکبار پخش مي شود و اگر 1- باشد بطور ممتد پخش خواهد شد .
    براي متوقف کردن موزيک از کد زير استفاده کنيد :

    oDMPerf.StopEx oDMSeg, 0, DMUS_SEGF_DEFAULT

    براي تنظيم ميزان صدا از متد SetMasterVolume استقاده کنيد :

    oDMPerf.SetMasterVolume yourvalue

    رنج صدا بين 20+ دسی بل تا 200- دسي بل است .
    براي تنظيم Tempo از متد SetMasterTempo استفاده کنيد :

    oDMPerf.SetMasterTempo yourvalue/ 100

    بطور نرمال tempo برابر 1 مي باشد . عدد 2 سرعت را دو برابر مي کند و عدد 0 موزيک را قطع مي کند .