📄 acdclnt.c
字号:
}
}
return 1;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
//
// MainWndProc()
//
////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK MainWndProc (HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
return 1;
case WM_COMMAND:
return DoCommand(wParam,
lParam);
break;
case WM_CLOSE:
case WM_DESTROY:
CloseTapi();
PostQuitMessage(0);
return 1;
}
return 0;
}
///////////////////////////////////////////////////////////////////////
//
// BOOL InitTapi()
//
// Initializes TAPI. For this sample, we assume that the "agent" (the person
// logged on) can only have access to _one_ hLine. Also, they have access to
// every address on that line. This may not be true for many ACD situations.
//
// As soon as we find a device that the agent has access to, we quit
// looking, and use that device
//
///////////////////////////////////////////////////////////////////////
BOOL InitTapi()
{
LONG lResult;
LINEINITIALIZEEXPARAMS exparams;
LPLINEAGENTCAPS pLAC;
LPLINEDEVCAPS pLDC;
DWORD dwDeviceID, dwNumDevs, dwAPIVersion, dwThreadID;
// initialize completion port to receive TAPI notifications
ghCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
NULL,
0,
0);
InitializeCriticalSection(&csLineReply);
// fill in lineinitex parameters
exparams.dwTotalSize = sizeof(LINEINITIALIZEEXPARAMS);
exparams.dwOptions = LINEINITIALIZEEXOPTION_USECOMPLETIONPORT;
exparams.Handles.hCompletionPort = ghCompletionPort;
dwAPIVersion = TAPI_CURRENT_VERSION;
lResult = lineInitializeEx(&ghLineApp,
ghInstance,
NULL,
SZAPPNAME,
&dwNumDevs,
&dwAPIVersion,
&exparams);
if (lResult)
{
return FALSE;
}
// if no devices, don't continue
if (dwNumDevs == 0)
{
lineShutdown(ghLineApp);
return FALSE;
}
// kick off completion port thread
CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadRoutine,
NULL,
0,
&dwThreadID);
// loop through all devices
for (dwDeviceID = 0; dwDeviceID < dwNumDevs; dwDeviceID++)
{
// Get the Agent Caps. If this succeedes, this is
// a device we can use
pLAC = LineGetAgentCaps(ghLineApp,
dwDeviceID,
0);
if (pLAC)
{
// this is a device we can use
gdwDeviceID = dwDeviceID;
// get the number of addresses
pLDC = LineGetDevCaps(ghLineApp,
dwDeviceID);
if (pLDC)
{
gdwAddresses = pLDC->dwNumAddresses;
GlobalFree(pLDC);
}
GlobalFree(pLAC);
break;
}
}
// open the line in owner mode
lResult = lineOpen(ghLineApp,
gdwDeviceID,
&ghLine,
TAPI_CURRENT_VERSION,
0,
0,
LINECALLPRIVILEGE_OWNER,
LINEMEDIAMODE_INTERACTIVEVOICE,
NULL);
// if line failed, don't continue
if (lResult)
{
lineShutdown(ghLineApp);
return FALSE;
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
//
// ThreadRoutine
//
// Thread dedicated to checking completion port for TAPI events
//
//////////////////////////////////////////////////////////////////////
LONG ThreadRoutine(LPVOID lpv)
{
LPLINEMESSAGE pMsg;
DWORD dwNumBytesTransfered;
DWORD_PTR dwCompletionKey;
// just wait for tapi notifications
while (GetQueuedCompletionStatus(ghCompletionPort,
&dwNumBytesTransfered,
&dwCompletionKey,
(LPOVERLAPPED *) &pMsg,
INFINITE))
{
if (pMsg)
{
// when we get one, call the handling function
LineCallback(pMsg->hDevice,
pMsg->dwMessageID,
(DWORD)pMsg->dwCallbackInstance,
(DWORD)pMsg->dwParam1,
(DWORD)pMsg->dwParam2,
(DWORD)pMsg->dwParam3);
LocalFree (pMsg);
}
else
{
break;
}
}
ExitThread(0);
return 0;
}
///////////////////////////////////////////////////////////////////////////
//
// BOOL CloseTapi()
//
// Close tapi and free resources
//
///////////////////////////////////////////////////////////////////////////
BOOL CloseTapi()
{
GlobalFree(pAddressInfo);
CloseHandle(ghCompletionPort);
lineClose(ghLine);
lineShutdown(ghLineApp);
return TRUE;
}
// static information for the status dialog
static DWORD dwAgentStates[] =
{
LINEAGENTSTATE_LOGGEDOFF,
LINEAGENTSTATE_NOTREADY,
LINEAGENTSTATE_READY,
LINEAGENTSTATE_BUSYACD,
LINEAGENTSTATE_BUSYINCOMING,
LINEAGENTSTATE_BUSYOUTBOUND,
LINEAGENTSTATE_BUSYOTHER,
LINEAGENTSTATE_WORKINGAFTERCALL,
LINEAGENTSTATE_UNKNOWN,
LINEAGENTSTATE_UNAVAIL,
0
};
static LPTSTR lpszStates[] =
{
TEXT("Logged Off"),
TEXT("Not Ready"),
TEXT("Ready"),
TEXT("Busy ACD"),
TEXT("Busy Incoming"),
TEXT("Busy Outbound"),
TEXT("Busy Other"),
TEXT("Working after call"),
TEXT("Unknown"),
TEXT("Unavail"),
NULL
};
///////////////////////////////////////////////////////////////////////////
//
// BOOL InitAgentDlg()
//
// Handles initialization of the status dialog
//
// Gets the group list and puts groups in multiselect list box
// these are the groups that the agent _can_ log into
// the groups they are logged into will be selected
// Creates comboboxes of states and nextstates, and select
// the agent's current state/nextstate
// Gets the activity list and puts each item into a combobox
// the current activity will be selected
//
///////////////////////////////////////////////////////////////////////////
BOOL InitAgentDlg(HWND hwnd,
DWORD dwAddress,
LPLINEAGENTGROUPLIST * ppLAG)
{
LPLINEAGENTCAPS pLAC;
LPLINEAGENTSTATUS pLAS;
LPLINEAGENTACTIVITYLIST pLAA;
LPLINEAGENTGROUPENTRY pEntry, pLoggedInEntry;
LPLINEAGENTACTIVITYENTRY pActivityEntry;
DWORD dwEntries, dwCount;
LONG_PTR item;
// first, get the status
// this information will be used to know which items to select
// in each of the listbox/comboboxes
pLAS = LineGetAgentStatus(ghLine,
dwAddress);
if (!pLAS)
{
return FALSE;
}
// get the group list
if (!(*ppLAG = LineGetAgentGroupList(ghLine,
dwAddress)))
{
return FALSE;
}
// get the first groupentry
pEntry = (LPLINEAGENTGROUPENTRY)(((LPBYTE)*ppLAG)+(*ppLAG)->dwListOffset);
// loop through the group entries
for (dwEntries = 0; dwEntries < (*ppLAG)->dwNumEntries; dwEntries++)
{
// add group to list box
item = SendDlgItemMessage(hwnd,
IDC_GROUPS,
LB_ADDSTRING,
0,
(LPARAM)(LPTSTR)(((LPBYTE)*ppLAG) + pEntry->dwNameOffset));
// save the entry
SendDlgItemMessage(hwnd,
IDC_GROUPS,
LB_SETITEMDATA,
(WPARAM)item,
(LPARAM)pEntry);
// now get list of groups currently logged into from the agent status structure
// loop through them. if any of them match the group we are currently adding
// select that group
pLoggedInEntry = (LPLINEAGENTGROUPENTRY)(((LPBYTE)pLAS) + pLAS->dwGroupListOffset);
for (dwCount = 0; dwCount < pLAS->dwNumEntries; dwCount++)
{
if ((pLoggedInEntry->GroupID.dwGroupID1 == pEntry->GroupID.dwGroupID1) &&
(pLoggedInEntry->GroupID.dwGroupID2 == pEntry->GroupID.dwGroupID2) &&
(pLoggedInEntry->GroupID.dwGroupID3 == pEntry->GroupID.dwGroupID3) &&
(pLoggedInEntry->GroupID.dwGroupID4 == pEntry->GroupID.dwGroupID4))
{
SendDlgItemMessage(hwnd,
IDC_GROUPS,
LB_SETSEL,
(WPARAM)TRUE,
(LPARAM)item);
}
pLoggedInEntry++;
}
pEntry++;
}
// get the agent caps
if (pLAC = LineGetAgentCaps(ghLineApp,
gdwDeviceID,
dwAddress))
{
dwCount = 0;
// loop through all possbile agent states. if the agent state
// is selected in the agent caps, add that state to the list box
while (dwAgentStates[dwCount])
{
if (dwAgentStates[dwCount] & pLAC->dwStates)
{
item = SendDlgItemMessage(hwnd,
IDC_STATE,
CB_ADDSTRING,
0,
(LPARAM)lpszStates[dwCount]);
SendDlgItemMessage(hwnd,
IDC_STATE,
CB_SETITEMDATA,
(WPARAM)item,
(LPARAM)dwAgentStates[dwCount]);
// if the state matches the current one from the agent status
// select it
if (pLAS->dwState == dwAgentStates[dwCount])
{
SendDlgItemMessage(hwnd,
IDC_STATE,
CB_SETCURSEL,
(WPARAM)item,
0);
}
}
dwCount ++;
}
dwCount = 0;
// now do the same for the next states
while (dwAgentStates[dwCount])
{
if (dwAgentStates[dwCount] & pLAC->dwNextStates)
{
item = SendDlgItemMessage(hwnd,
IDC_NEXTSTATE,
CB_ADDSTRING,
0,
(LPARAM)lpszStates[dwCount]);
SendDlgItemMessage(hwnd,
IDC_NEXTSTATE,
CB_SETITEMDATA,
(WPARAM)item,
dwAgentStates[dwCount]);
if (pLAS->dwNextState == dwAgentStates[dwCount])
{
SendDlgItemMessage(hwnd,
IDC_NEXTSTATE,
CB_SETCURSEL,
(WPARAM)item,
0);
}
}
dwCount++;
}
GlobalFree(pLAC);
}
// get the activity list
pLAA = LineGetAgentActivityList(ghLine,
gdwDeviceID,
dwAddress);
if (pLAA)
{
dwCount = pLAA->dwNumEntries;
pActivityEntry = (LPLINEAGENTACTIVITYENTRY)(((LPBYTE)pLAA) + pLAA->dwListOffset);
// go through all the possible activities and add them to the list
while (dwCount)
{
item = SendDlgItemMessage(hwnd,
IDC_ACTIVITY,
CB_ADDSTRING,
0,
(LPARAM)(LPTSTR)(((LPBYTE)pLAA) + pActivityEntry->dwNameOffset));
SendDlgItemMessage(hwnd,
IDC_ACTIVITY,
CB_SETITEMDATA,
(WPARAM)item,
(LPARAM)pActivityEntry->dwID);
// if this is the current activity (from agent status)
// select it
if (pLAS->dwActivityID == pActivityEntry->dwID)
{
SendDlgItemMessage(hwnd,
IDC_ACTIVITY,
CB_SETCURSEL,
(WPARAM)item,
0);
}
dwCount--;
pActivityEntry++;
}
GlobalFree(pLAA);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
//
// BOOL SaveAgentStatus(HWND hwnd)
//
// Saves information from the status dialog
//
//////////////////////////////////////////////////////////////////////////////////////////////
BOOL SaveAgentStatus(HWND hwnd,
DWORD dwAddress)
{
LPLINEAGENTGROUPENTRY pGroupEntry, pNewGroupEntry;
LPLINEAGENTGROUPLIST pNewLAG;
DWORD dwCount;
LPINT pItems;
DWORD item;
DWORD dwState, dwNextState, dwActivity;
// get the number of groups selected in the group
// list box. each selected group is a group this
// agent will be logged into
dwCount = (DWORD)SendDlgItemMessage(hwnd,
IDC_GROUPS,
LB_GETSELCOUNT,
0,
0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -