📄 cedialer.c
字号:
/***********************************************************************
THIS CODE AND INFORMATION IS PROVIDED AS IS WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
PURPOSE.
Copyright(c) 1999 Microsoft Corporation. All Rights Reserved.
MODULE:
CeDialer.c
ABSTRACT:
This code sample shows how to initialize an application's use
of TAPI, open a line device, negotiate an API version to use,
translate an address into another format, place a call on an
opened line device, close an opened line device, and shut down
an application's use of the line abstraction of the API.
***********************************************************************/
#include <windows.h>
#include <windowsx.h>
#include <tapi.h>
#include "resource.h"
#include "CeDialer.h"
HINSTANCE g_hInst = NULL; // hInstance of the application
HWND g_hwndMain = NULL; // Handle to the main window
HWND g_hwndDial = NULL; // Handle to the dialing window
TCHAR g_szTitle[] = TEXT("CeDialer");
// CeDialer application window name
TCHAR g_szAppName[] = TEXT("CeDialer Application");
// Main window class name
HLINEAPP g_hLineApp = NULL; // Application's use handle for TAPI
// (lineInitialize)
HCALL g_hCall = NULL; // Handle to the open line device on
// which the call is to be originated
// (lineMakeCall)
LONG g_MakeCallRequestID = 0; // Request identifier returned by
// lineMakeCall
LONG g_DropCallRequestID = 0; // Request identifier returned by
// lineDrop
BOOL g_bCurrentLineAvail = TRUE;// Indicates line availability
TCHAR g_szCurrentNum[TAPIMAXDESTADDRESSSIZE + 1];
// Current phone number
TCHAR g_szLastNum[TAPIMAXDESTADDRESSSIZE + 1];
// Last called phone number
DWORD g_dwNumDevs = 0; // Number of line devices available
DWORD g_dwCurrentLineID = -1; // Current line device identifier
DWORD g_dwCurrentLineAddr = -1; // Current line address
LINEINFO g_CurrentLineInfo; // Contains the current line information
LINEINFO *g_lpLineInfo = NULL; // Array that contains all the lines'
// information
#define InfoBox(_s) MessageBox (g_hwndMain, _s, TEXT("Info"), MB_OK)
#define ErrorBox(_s) MessageBox (g_hwndMain, _s, TEXT("Error"), MB_OK)
/***********************************************************************
FUNCTION:
MainWndProc
PURPOSE:
Processes messages sent to the main window.
***********************************************************************/
BOOL CALLBACK MainWndProc (HWND hwnd, UINT uMsg, WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
HICON hIcon = LoadIcon (g_hInst,
(LPCTSTR) MAKEINTRESOURCE(IDI_CEDIALER));
// Limit text in phone number field to TAPIMAXDESTADDRESSSIZE.
SendDlgItemMessage (hwnd, IDC_PHONENUM, CB_LIMITTEXT,
(WPARAM)TAPIMAXDESTADDRESSSIZE, 0);
// Initialize the application's use of Tapi.dll. If the function
// fails, terminate the application.
if (InitializeTAPI ())
{
InfoBox (TEXT("Fails initializing the use of Tapi.dll."));
if (g_hLineApp)
lineShutdown (g_hLineApp);
DestroyWindow (hwnd);
}
return TRUE;
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_SELECTLINE:
DialogBox (g_hInst,
MAKEINTRESOURCE(IDD_CONNECTUSING),
hwnd,
(DLGPROC) ConnectUsingProc);
return TRUE;
case IDC_REDIAL:
// Display the previously dialed phone number.
SendDlgItemMessage (hwnd, IDC_PHONENUM, WM_SETTEXT, 0,
(LPARAM)g_szLastNum);
case IDC_DIAL:
{
// Check if there is a number entered.
if (SendDlgItemMessage (hwnd,
IDC_PHONENUM,
WM_GETTEXTLENGTH, 0, 0) > 0)
{
// Set the current line if it is not already set.
if (g_dwCurrentLineID == -1)
{
DialogBox (g_hInst,
MAKEINTRESOURCE(IDD_CONNECTUSING),
hwnd,
(DLGPROC) ConnectUsingProc);
}
// Get the number to be dialed.
GetDlgItemText (hwnd,
IDC_PHONENUM,
(LPTSTR) g_szCurrentNum,
TAPIMAXDESTADDRESSSIZE);
// Convert the phone number into a canonical format.
if (!MakeCanonicalNum (g_szCurrentNum))
return TRUE;
// Redisplay the phone number as a canonical format.
SendDlgItemMessage (hwnd, IDC_PHONENUM, WM_SETTEXT, 0,
(LPARAM)g_szCurrentNum);
// Make the call.
MakePhoneCall (g_szCurrentNum);
// Set the focus on the phone number Edit control.
SetFocus (GetDlgItem (hwnd, IDC_PHONENUM));
// Select the phone number once it is dialed.
SendDlgItemMessage (hwnd, IDC_PHONENUM, EM_SETSEL, 0, -1);
// Save the phone number in the g_szLastNum string.
lstrcpy (g_szLastNum, g_szCurrentNum);
}
return TRUE;
}
case IDC_BUTTON1:
case IDC_BUTTON2:
case IDC_BUTTON3:
case IDC_BUTTON4:
case IDC_BUTTON5:
case IDC_BUTTON6:
case IDC_BUTTON7:
case IDC_BUTTON8:
case IDC_BUTTON9:
case IDC_BUTTON0:
case IDC_BUTTONSTAR:
case IDC_BUTTONPOUND:
{
int iNumOfDigits = 0;
TCHAR *lpszBuffer;
static const TCHAR digits[] = {'1', '2', '3', '4',
'5', '6', '7', '8',
'9', '0', '*', '#'};
lpszBuffer = (TCHAR *)LocalAlloc (LPTR,
TAPIMAXDESTADDRESSSIZE + 1);
// Clear the current selection.
SendDlgItemMessage (hwnd, IDC_PHONENUM, WM_CLEAR, 0, 0);
iNumOfDigits = SendDlgItemMessage (
hwnd,
IDC_PHONENUM,
WM_GETTEXT,
(WPARAM)TAPIMAXDESTADDRESSSIZE + 1,
(LPARAM)lpszBuffer);
if (iNumOfDigits < TAPIMAXDESTADDRESSSIZE)
{
lpszBuffer[iNumOfDigits] =
digits[LOWORD(wParam) - IDC_BUTTON1];
SendDlgItemMessage (hwnd, IDC_PHONENUM, WM_SETTEXT, 0,
(LPARAM)lpszBuffer);
}
LocalFree (lpszBuffer);
return TRUE;
}
case IDOK:
case IDCANCEL:
if (g_lpLineInfo)
LocalFree (g_lpLineInfo);
lineShutdown (g_hLineApp);
DestroyWindow (hwnd);
PostQuitMessage (0);
return TRUE;
}
break;
}
case WM_DESTROY:
PostQuitMessage (0);
return TRUE;
default:
return DefWindowProc (hwnd, uMsg, wParam, lParam);
}
return FALSE;
}
/***********************************************************************
FUNCTION:
WinMain
PURPOSE:
Called by the system as the initial entry point for this Windows
CE-based application.
***********************************************************************/
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
WNDCLASS wc;
HANDLE hwndCeDialer;
g_hInst = hInstance;
// If CeDialer.exe is running, then give the focus to the window.
hwndCeDialer = FindWindow (g_szAppName, g_szTitle);
if (hwndCeDialer)
{
SetForegroundWindow (hwndCeDialer);
return 0;
}
// Register the window class.
wc.style = CS_DBLCLKS;
wc.lpfnWndProc = DefDlgProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = g_hInst;
wc.hIcon = LoadIcon (g_hInst, MAKEINTRESOURCE(IDI_CEDIALER));
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH) GetStockObject (COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szAppName;
RegisterClass (&wc);
// Create the dialog box. If it fails, return 0.
if (!(g_hwndMain = CreateDialog (g_hInst,
MAKEINTRESOURCE(IDD_CEDIALER),
NULL,
(DLGPROC) MainWndProc)))
{
return 0;
}
ShowWindow (g_hwndMain, SW_SHOW);
UpdateWindow (g_hwndMain);
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
/***********************************************************************
FUNCTION:
lineCallbackFunc
PURPOSE:
This is a callback function invoked to determine status and events on
the line device, addresses, or calls.
***********************************************************************/
VOID CALLBACK lineCallbackFunc (DWORD hDevice,
DWORD dwMsg,
DWORD dwCallbackInstance,
DWORD dwParam1,
DWORD dwParam2,
DWORD dwParam3)
{
LPTSTR lpszStatus;
switch (dwMsg)
{
case LINE_CALLSTATE:
// If the CALLSTATE does not apply to the call in progress,
// then return.
if (g_hCall != (HCALL) hDevice)
return;
// dwParam1 is the specific CALLSTATE change that is occurring.
switch (dwParam1)
{
case LINECALLSTATE_DIALTONE:
lpszStatus = TEXT("Dial tone");
break;
case LINECALLSTATE_DIALING:
lpszStatus = TEXT("Dialing");
break;
case LINECALLSTATE_PROCEEDING:
lpszStatus = TEXT("Dialing has completed and the call ")
TEXT("is proceeding.");
break;
case LINECALLSTATE_RINGBACK:
lpszStatus = TEXT("Ring back");
break;
case LINECALLSTATE_CONNECTED:
lpszStatus = TEXT("Connected");
break;
case LINECALLSTATE_BUSY:
ErrorBox (TEXT("Line busy, shutting down"));
CurrentLineClose ();
if (g_hwndDial)
SendMessage (g_hwndDial, WM_COMMAND, MAKEWPARAM(IDOK,0), 0);
break;
case LINECALLSTATE_IDLE:
ErrorBox (TEXT("Line is idle"));
CurrentLineClose ();
if (g_hwndDial)
SendMessage (g_hwndDial, WM_COMMAND, MAKEWPARAM(IDOK,0), 0);
break;
case LINECALLSTATE_SPECIALINFO:
ErrorBox (TEXT("Special Information, couldn't dial number"));
CurrentLineClose ();
if (g_hwndDial)
SendMessage (g_hwndDial, WM_COMMAND, MAKEWPARAM(IDOK,0), 0);
break;
case LINECALLSTATE_DISCONNECTED:
{
LPTSTR lpszDisconnected;
switch (dwParam2)
{
case LINEDISCONNECTMODE_NORMAL:
lpszDisconnected = TEXT("Remote party disconnected");
break;
case LINEDISCONNECTMODE_UNKNOWN:
lpszDisconnected = TEXT("Disconnected: Unknown reason");
break;
case LINEDISCONNECTMODE_REJECT:
lpszDisconnected = TEXT("Remote Party rejected call");
break;
case LINEDISCONNECTMODE_PICKUP:
lpszDisconnected =
TEXT("Disconnected: Local phone picked up");
break;
case LINEDISCONNECTMODE_FORWARDED:
lpszDisconnected = TEXT("Disconnected: Forwarded");
break;
case LINEDISCONNECTMODE_BUSY:
lpszDisconnected = TEXT("Disconnected: Busy");
break;
case LINEDISCONNECTMODE_NOANSWER:
lpszDisconnected = TEXT("Disconnected: No Answer");
break;
case LINEDISCONNECTMODE_BADADDRESS:
lpszDisconnected = TEXT("Disconnected: Bad address");
break;
case LINEDISCONNECTMODE_UNREACHABLE:
lpszDisconnected = TEXT("Disconnected: Unreachable");
break;
case LINEDISCONNECTMODE_CONGESTION:
lpszDisconnected = TEXT("Disconnected: Congestion");
break;
case LINEDISCONNECTMODE_INCOMPATIBLE:
lpszDisconnected = TEXT("Disconnected: Incompatible");
break;
case LINEDISCONNECTMODE_UNAVAIL:
lpszDisconnected = TEXT("Disconnected: Unavailable");
break;
case LINEDISCONNECTMODE_NODIALTONE:
lpszDisconnected = TEXT("Disconnected: No dial tone");
break;
default:
lpszDisconnected = TEXT("Disconnected: Unknown reason");
break;
}
ErrorBox (lpszDisconnected);
CurrentLineClose ();
if (g_hwndDial)
SendMessage (g_hwndDial, WM_COMMAND, MAKEWPARAM(IDOK,0), 0);
break;
}
}
break;
case LINE_LINEDEVSTATE:
switch (dwParam1)
{
case LINEDEVSTATE_RINGING:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -