TAPI, проблема с lineCallbackFunc
От: AndreW82 Россия  
Дата: 31.08.07 18:09
Оценка:
Доброго времени суток, господа! Я новичок в .NET (в основном на C++ писал). Пишу тестовое приложение использующее unmanaged функции TAPI. Код всей программы приведен ниже. Компилируется нормально и запускается на Pocket PC. Функция lineMakeCall также осуществляет звонок (мобильник лежит рядом и начинает музычку играть), но не работает LineCallBack, т.е. при дозвоне должен перехватываться соответствующий message LINECALLSTATE_PROCEEDING и выводится текст в поле и кнопочки состояние менять, но этого не происходит... Если при дебаге поставить внутрь функции LineCallBack брейкпоинт, то после срабатывания lineMakeCall студия2005 закрывается по ошибке и предлагает отправить отчет в microsoft... Вот такие пироги... Третий день уже мучаюсь с этим TAPI Мне этот код уже снится, где я мог накосячить?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace incomCall
{
    public partial class Form1 : Form
    {
        private Tapi.CallBackDelegate callBackDelegate;
        private IntPtr callBackPointer;
        private IntPtr hLineApp;
        private IntPtr hLine;
        private IntPtr lphCall;
        int ret;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Инициализация TAPI и открытие линии
            callBackDelegate = new Tapi.CallBackDelegate(LineCallBack);
            callBackPointer = Marshal.GetFunctionPointerForDelegate(callBackDelegate);

            int dwNumDev;
            int num1 = 0x20000;

            // lineInitializeEx
            Tapi.LINEINITIALIZEEXPARAMS lineInitializeParams = new Tapi.LINEINITIALIZEEXPARAMS();
            lineInitializeParams.dwTotalSize = (uint)Marshal.SizeOf(lineInitializeParams);
            lineInitializeParams.dwNeededSize = lineInitializeParams.dwTotalSize;
            lineInitializeParams.dwUsedSize = 512;
            lineInitializeParams.dwOptions = Tapi.LINEINITIALIZEEXOPTION_USEHIDDENWINDOW;
            lineInitializeParams.hEvent = IntPtr.Zero;
            lineInitializeParams.hCompletionPort = IntPtr.Zero;
            lineInitializeParams.dwCompletionKey = 0;

            ret = Tapi.lineInitializeEx(out hLineApp, IntPtr.Zero, callBackPointer, null,
                out dwNumDev, ref num1, ref lineInitializeParams);

            // lineNegotiateAPIVerison
            int version;
            int dwAPIVersionLow = 0x10004;
            int dwAPIVersionHigh = 0x20000;
            Tapi.LINEEXTENSIONID lineExtensionID;
            ret = Tapi.lineNegotiateAPIVersion(hLineApp, 0, dwAPIVersionLow,
                dwAPIVersionHigh, out version, out lineExtensionID);

            // lineOpen    
            ret = Tapi.lineOpen(hLineApp, 0, out hLine, version, 0, 0, Tapi.LINECALLPRIVILEGE_MONITOR,
                Tapi.LINEMEDIAMODE_DATAMODEM, IntPtr.Zero);
        }

        private void buttonDial_Click(object sender, EventArgs e)
        {
            labelStatus.Text = "";
            buttonDial.Enabled = false;
            buttonHangUp.Enabled = false;
            buttonAnswer.Enabled = false;
            ret = Tapi.lineMakeCall(hLine, out lphCall, textBoxNumber.Text, 0, IntPtr.Zero);
        }

        private void buttonHangUp_Click(object sender, EventArgs e)
        {
            labelStatus.Text = "";
            buttonDial.Enabled = false;
            buttonHangUp.Enabled = false;
            buttonAnswer.Enabled = false;
            Tapi.lineSetCallPrivilege(lphCall, Tapi.LINECALLPRIVILEGE_OWNER);
            if (lphCall != IntPtr.Zero)
            {
                Tapi.lineDrop(lphCall, null, 0);
            }
        }

        private void buttonAnswer_Click(object sender, EventArgs e)
        {
            labelStatus.Text = "";
            buttonDial.Enabled = false;
            buttonHangUp.Enabled = false;
            buttonAnswer.Enabled = false;

        }

        private void Form1_Closing(object sender, CancelEventArgs e)
        {
            if (hLine != IntPtr.Zero)
            {
                Tapi.lineClose(hLine);
                hLine = IntPtr.Zero;
                lphCall = IntPtr.Zero;
                Tapi.lineShutdown(hLineApp);
            }
        }

        private void LineCallBack(int hDevice, int dwMsg, int dwCallbackInstance, int dwParam1, int dwParam2, int dwParam3)
        {
            switch (dwMsg)
            {
                case Tapi.LINE_CALLSTATE:
                    lphCall = (IntPtr)hDevice;
                    Tapi.lineSetCallPrivilege(lphCall, Tapi.LINECALLPRIVILEGE_OWNER);
                    switch (dwParam1)
                    {
                        case Tapi.LINECALLSTATE_PROCEEDING:
                            // Перехватываем звонок пользователя
                            labelStatus.Text = "Дозвон...";
                            buttonDial.Enabled = false;
                            buttonHangUp.Enabled = true;
                            buttonAnswer.Enabled = false;
                            break;

                        case Tapi.LINECALLSTATE_OFFERING:
                            // Здесь мы оказываемся, когда нам звонят
                            labelStatus.Text = "Входящий звонок...";
                            buttonDial.Enabled = false;
                            buttonHangUp.Enabled = true;
                            buttonAnswer.Enabled = true;
                            break;

                        case Tapi.LINECALLSTATE_CONNECTED:
                            // Здесь - когда нам ответили
                            labelStatus.Text = "Соединилось.";
                            buttonDial.Enabled = false;
                            buttonHangUp.Enabled = true;
                            buttonAnswer.Enabled = false;
                            break;

                        case Tapi.LINECALLSTATE_DISCONNECTED:
                            // Здесь - когда разговор завершился с другой стороны
                            labelStatus.Text = "Разъединилось.";
                            buttonDial.Enabled = true;
                            buttonHangUp.Enabled = false;
                            buttonAnswer.Enabled = false;
                            break;

                        case Tapi.LINECALLSTATE_IDLE:
                            // Здесь - когда разговор завершился с нашей стороны
                            Tapi.lineDeallocateCall(lphCall);
                            labelStatus.Text = "Разъединилось.";
                            buttonDial.Enabled = true;
                            buttonHangUp.Enabled = false;
                            buttonAnswer.Enabled = false;
                            break;

                        case Tapi.LINECALLSTATE_BUSY:
                            // Занято
                            labelStatus.Text = "Занято...";
                            buttonDial.Enabled = false;
                            buttonHangUp.Enabled = true;
                            buttonAnswer.Enabled = false;
                            break;

                        default:
                            break;
                    }
                    break;

//                case Tapi.LINE_REPLY:
//                    ret = dwParam2;
//                    break;

                default:
                    break;
            }
        }
    }

    public class Tapi
    {
        public delegate void CallBackDelegate(int hDevice, int dwMsg, int dwCallbackInstance, int dwParam1, int dwParam2, int dwParam3);

        public const Int32 LINE_CALLSTATE = 2;
        public const Int32 LINE_REPLY = 12;
        public const Int32 LINECALLSTATE_OFFERING = 0x00000002;
        public const Int32 LINECALLSTATE_PROCEEDING = 0x00000200;
        public const Int32 LINECALLSTATE_CONNECTED = 0x00000100;
        public const Int32 LINECALLSTATE_DISCONNECTED = 0x00004000;
        public const Int32 LINECALLSTATE_BUSY = 0x00000040;
        public const Int32 LINECALLSTATE_IDLE = 0x00000001;
        public const Int32 LINEINITIALIZEEXOPTION_USEHIDDENWINDOW = 0x00000001;
//        public const Int32 LINEINITIALIZEEXOPTION_USEEVENT = 0x00000002;
        public const Int32 LINECALLPRIVILEGE_MONITOR = 0x00000002;
        public const Int32 LINECALLPRIVILEGE_OWNER = 0x00000004;
//        public const Int32 LINEMEDIAMODE_INTERACTIVEVOICE = 0x00000004;
        public const Int32 LINEMEDIAMODE_DATAMODEM = 0x00000010;

        [StructLayout(LayoutKind.Explicit)]
        public struct LINEINITIALIZEEXPARAMS
        {
            [FieldOffset(0)]
            public UInt32 dwTotalSize;
            [FieldOffset(4)]
            public UInt32 dwNeededSize;
            [FieldOffset(8)]
            public UInt32 dwUsedSize;
            [FieldOffset(12)]
            public UInt32 dwOptions;
            [FieldOffset(16)]
            public IntPtr hEvent;
            [FieldOffset(16)]
            public IntPtr hCompletionPort;
            [FieldOffset(20)]
            public UInt32 dwCompletionKey;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct LINEEXTENSIONID
        {
            public UInt32 dwExtensionID0;
            public UInt32 dwExtensionID1;
            public UInt32 dwExtensionID2;
            public UInt32 dwExtensionID3;
        }

        [DllImport("coredll.dll", SetLastError = true)]
        public extern static Int32 lineInitializeEx(
            out IntPtr lphLineApp,
            IntPtr hInstance,
            IntPtr lpfnCallback,
            string lpszFriendlyAppName,
            out int lpdwNumDevs,
            ref int lpdwAPIVersion,
            ref LINEINITIALIZEEXPARAMS lpLineInitializeExParams
        );

        [DllImport("coredll.dll", SetLastError = true)]
        public extern static Int32 lineNegotiateAPIVersion(
            IntPtr lphLineApp,
            UInt32 dwDeviceID,
            int dwAPILowVersion,
            int dwAPIHighVersion,
            out int lpdwAPIVersion,
            out LINEEXTENSIONID lpExtensionID
        );

        [DllImport("coredll.dll", SetLastError = true)]
        public extern static Int32 lineOpen(
            IntPtr lphLineApp,
            UInt32 dwDeviceID,
            out IntPtr lphLine,
            int dwAPIVersion,
            UInt32 dwExtVersion,
            UInt32 dwCallbackInstance,
            UInt32 dwPrivileges,
            UInt32 dwMediaModes,
            IntPtr lpCallParams
        );

        [DllImport("coredll.dll", SetLastError = true)]
        public extern static Int32 lineMakeCall(
            IntPtr hLine,
            out IntPtr lphCall,
            string lpszDestAddress,
            UInt32 dwCountryCode,
            IntPtr lpCallParams
        );

        [DllImport("coredll.dll", SetLastError = true)]
        public extern static Int32 lineSetCallPrivilege(
            IntPtr lphCall,
            UInt32 dwCallPrivilege
        );

        [DllImport("coredll.dll", SetLastError = true)]
        public extern static Int32 lineDrop(
            IntPtr lphCall,
            string lpsUserUserInfo,
            UInt32 dwSize
        );

        [DllImport("coredll.dll", SetLastError = true)]
        public extern static Int32 lineDeallocateCall(
            IntPtr lphCall
        );

        [DllImport("coredll.dll", SetLastError = true)]
        public extern static Int32 lineClose(
            IntPtr hLine
        );

        [DllImport("coredll.dll", SetLastError = true)]
        public extern static Int32 lineShutdown(
            IntPtr hLineApp
        );
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.