mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1756 lines
43 KiB
1756 lines
43 KiB
//---------------------------------------------------------------------------
|
|
//
|
|
// Copyright (c) Microsoft Corporation 1993-1995
|
|
//
|
|
// File: ring.c
|
|
//
|
|
// This files contains the dialog code for the Voice settings
|
|
// property pages.
|
|
//
|
|
// History:
|
|
// 07-05-95 ScottH Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
#include "proj.h" // common headers
|
|
|
|
#if defined(WIN95) && defined(CS_HELP)
|
|
#include "..\..\..\..\win\core\inc\help.h"
|
|
#endif
|
|
|
|
#define CX_PATTERN 40
|
|
#define CY_PATTERN 5
|
|
|
|
typedef struct tagRING
|
|
{
|
|
HWND hdlg; // dialog handle
|
|
LPMODEMINFO pmi; // modeminfo struct passed into dialog
|
|
|
|
HBITMAP hbmStrip;
|
|
HDC hdcStrip;
|
|
HFONT hfont;
|
|
int cyText;
|
|
|
|
} RING, FAR * PRING;
|
|
|
|
|
|
typedef struct tagRINGPAT
|
|
{
|
|
DWORD dwPattern;
|
|
LPARAM lParam;
|
|
} RINGPAT, FAR * PRINGPAT;
|
|
|
|
static RINGPAT s_rgrp[] =
|
|
{
|
|
{ DRP_NONE, 0 },
|
|
{ DRP_SHORT, 0 },
|
|
{ DRP_LONG, 0 },
|
|
{ DRP_SHORTSHORT, 0 },
|
|
{ DRP_SHORTLONG, 0 },
|
|
{ DRP_LONGSHORT, 0 },
|
|
{ DRP_LONGLONG, 0 },
|
|
{ DRP_SHORTSHORTLONG, 0 },
|
|
{ DRP_SHORTLONGSHORT, 0 },
|
|
{ DRP_LONGSHORTSHORT, 0 },
|
|
{ DRP_LONGSHORTLONG, 0 },
|
|
};
|
|
|
|
#pragma data_seg(DATASEG_READONLY)
|
|
|
|
const static UINT c_rgidcPattern[] =
|
|
{
|
|
IDC_ADDR_PRI,
|
|
IDC_ADDR1,
|
|
IDC_ADDR2,
|
|
IDC_ADDR3,
|
|
IDC_PRI_CALLERS,
|
|
IDC_CALLBACK,
|
|
};
|
|
const static UINT c_rgidcTypeOfCalls[] =
|
|
{
|
|
IDC_TYPE_ADDR_PRI,
|
|
IDC_TYPE_ADDR1,
|
|
IDC_TYPE_ADDR2,
|
|
IDC_TYPE_ADDR3,
|
|
IDC_TYPE_PRI_CALLERS,
|
|
IDC_TYPE_CALLBACK,
|
|
};
|
|
|
|
static DWORD c_rgdwCheapPatterns[] =
|
|
{
|
|
DRP_SINGLE,
|
|
DRP_DOUBLE,
|
|
DRP_TRIPLE,
|
|
};
|
|
|
|
const static UINT c_rgidcTypeOfCheapCalls[] =
|
|
{
|
|
IDC_TYPE_RING1,
|
|
IDC_TYPE_RING2,
|
|
IDC_TYPE_RING3,
|
|
};
|
|
|
|
TCHAR const FAR c_szUnimdmHelpFile[] = TEXT("unimdm.hlp");
|
|
|
|
#pragma data_seg()
|
|
|
|
|
|
#define Ring_GetPtr(hwnd) (PRING)GetWindowLong(hwnd, DWL_USER)
|
|
#define Ring_SetPtr(hwnd, lp) (PRING)SetWindowLong(hwnd, DWL_USER, (LONG)(lp))
|
|
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
// Voice settings dialog code
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Initialize the bitmap strip
|
|
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Ring_InitStrip(
|
|
PRING this,
|
|
HDC hdc)
|
|
{
|
|
ASSERT(hdc);
|
|
|
|
this->hbmStrip = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_PATTERNS));
|
|
ASSERT(this->hbmStrip);
|
|
|
|
this->hdcStrip = CreateCompatibleDC(hdc);
|
|
if (this->hdcStrip)
|
|
{
|
|
SelectObject(this->hdcStrip, this->hbmStrip);
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Initialize the specified Pattern combobox.
|
|
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Ring_InitPattern(
|
|
PRING this,
|
|
HWND hwndCB,
|
|
DWORD dwPattern)
|
|
{
|
|
int i;
|
|
int iSel = 0;
|
|
int n;
|
|
|
|
// Fill the listbox
|
|
for (i = 0; i < ARRAY_ELEMENTS(s_rgrp); i++)
|
|
{
|
|
n = ComboBox_AddString(hwndCB, &s_rgrp[i]);
|
|
|
|
// Keep our eyes peeled for the selected type
|
|
if (dwPattern == s_rgrp[i].dwPattern)
|
|
{
|
|
iSel = n;
|
|
}
|
|
}
|
|
|
|
ComboBox_SetCurSel(hwndCB, iSel);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Initialize the specified Type of Call combobox.
|
|
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Ring_InitTypeOfCall(
|
|
PRING this,
|
|
HWND hwndCB,
|
|
DWORD dwType)
|
|
{
|
|
#pragma data_seg(DATASEG_READONLY)
|
|
static const struct
|
|
{
|
|
UINT ids;
|
|
DWORD dwType; // DRT_*
|
|
} s_rgTypes[] =
|
|
{
|
|
{ IDS_UNSPECIFIED, DRT_UNSPECIFIED },
|
|
{ IDS_DATA, DRT_DATA },
|
|
{ IDS_FAX, DRT_FAX },
|
|
{ IDS_VOICE, DRT_VOICE },
|
|
};
|
|
#pragma data_seg()
|
|
|
|
int i;
|
|
int iSel = 0;
|
|
int n;
|
|
TCHAR sz[MAXMEDLEN];
|
|
|
|
// Fill the listbox
|
|
for (i = 0; i < ARRAY_ELEMENTS(s_rgTypes); i++)
|
|
{
|
|
n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgTypes[i].ids, sz, SIZECHARS(sz)));
|
|
ComboBox_SetItemData(hwndCB, n, s_rgTypes[i].dwType);
|
|
|
|
// Keep our eyes peeled for the selected type
|
|
if (dwType == s_rgTypes[i].dwType)
|
|
{
|
|
iSel = n;
|
|
}
|
|
}
|
|
|
|
ComboBox_SetCurSel(hwndCB, iSel);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Enable/disable all the controls
|
|
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Ring_EnableControls(
|
|
PRING this,
|
|
BOOL bEnable)
|
|
{
|
|
HWND hwnd = this->hdlg;
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_LBL_ADDR_PRI), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_ADDR_PRI), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_TYPE_ADDR_PRI), bEnable);
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_LBL_ADDR1), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_ADDR1), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_TYPE_ADDR1), bEnable);
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_LBL_ADDR2), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_ADDR2), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_TYPE_ADDR2), bEnable);
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_LBL_ADDR3), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_ADDR3), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_TYPE_ADDR3), bEnable);
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_LBL_PRI_CALLERS), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_PRI_CALLERS), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_TYPE_PRI_CALLERS), bEnable);
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_LBL_CALLBACK), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_CALLBACK), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_TYPE_CALLBACK), bEnable);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_INITDIALOG Handler
|
|
Returns: FALSE when we assign the control focus
|
|
Cond: --
|
|
*/
|
|
BOOL PRIVATE Ring_OnInitDialog(
|
|
PRING this,
|
|
HWND hwndFocus,
|
|
LPARAM lParam) // expected to be PROPSHEETINFO
|
|
{
|
|
LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
|
|
HWND hwnd = this->hdlg;
|
|
HWND hwndCtl;
|
|
LPDWORD lpdw;
|
|
BOOL bEnable;
|
|
int i;
|
|
PVOICEFEATURES pvs;
|
|
HDC hdc;
|
|
LOGFONT lf;
|
|
|
|
ASSERT((LPTSTR)lppsp->lParam);
|
|
|
|
this->pmi = (LPMODEMINFO)lppsp->lParam;
|
|
pvs = &this->pmi->pglobal->vs;
|
|
|
|
// Determine some font things
|
|
|
|
SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, FALSE);
|
|
this->hfont = CreateFontIndirect(&lf);
|
|
|
|
// Create bitmap strip
|
|
|
|
hdc = GetDC(hwnd);
|
|
if (hdc)
|
|
{
|
|
Ring_InitStrip(this, hdc);
|
|
ReleaseDC(hwnd, hdc);
|
|
}
|
|
|
|
// Enable/disable controls
|
|
|
|
bEnable = IsFlagSet(this->pmi->pglobal->vs.dwFlags, VSF_DIST_RING);
|
|
|
|
Button_SetCheck(GetDlgItem(hwnd, IDC_RING_CHECK), bEnable);
|
|
Ring_EnableControls(this, bEnable);
|
|
|
|
// Initialize controls
|
|
|
|
for (i = 0; i < ARRAY_ELEMENTS(c_rgidcPattern); i++)
|
|
{
|
|
hwndCtl = GetDlgItem(hwnd, c_rgidcPattern[i]);
|
|
lpdw = &pvs->DistRing[i].dwPattern;
|
|
|
|
Ring_InitPattern(this, hwndCtl, *lpdw);
|
|
}
|
|
|
|
for (i = 0; i < ARRAY_ELEMENTS(c_rgidcTypeOfCalls); i++)
|
|
{
|
|
hwndCtl = GetDlgItem(hwnd, c_rgidcTypeOfCalls[i]);
|
|
lpdw = &pvs->DistRing[i].dwMediaType;
|
|
|
|
Ring_InitTypeOfCall(this, hwndCtl, *lpdw);
|
|
}
|
|
|
|
return TRUE; // default initial focus
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_COMMAND Handler
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Ring_OnCommand(
|
|
PRING this,
|
|
int id,
|
|
HWND hwndCtl,
|
|
UINT uNotifyCode)
|
|
{
|
|
BOOL bCheck;
|
|
|
|
switch (id)
|
|
{
|
|
case IDC_RING_CHECK:
|
|
bCheck = Button_GetCheck(hwndCtl);
|
|
Ring_EnableControls(this, bCheck);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Validate the user's settings.
|
|
|
|
The ring patterns must be unique, except that
|
|
any/all may be set to DRP_NONE.
|
|
|
|
Returns: TRUE if valid
|
|
|
|
Cond: --
|
|
*/
|
|
BOOL PRIVATE Ring_ValidateSettings(
|
|
PRING this)
|
|
{
|
|
HWND hwnd = this->hdlg;
|
|
int i;
|
|
int iSel;
|
|
HWND hwndCtl;
|
|
PRINGPAT prp;
|
|
|
|
for (i = 0; i < ARRAY_ELEMENTS(s_rgrp); i++)
|
|
{
|
|
// Initialize lParam to 0
|
|
s_rgrp[i].lParam = 0;
|
|
}
|
|
|
|
// Get the ring pattern settings
|
|
|
|
for (i = 0; i < ARRAY_ELEMENTS(c_rgidcPattern); i++)
|
|
{
|
|
hwndCtl = GetDlgItem(hwnd, c_rgidcPattern[i]);
|
|
|
|
iSel = ComboBox_GetCurSel(hwndCtl);
|
|
ASSERT(LB_ERR != iSel);
|
|
|
|
ComboBox_GetLBText(hwndCtl, iSel, &prp);
|
|
|
|
// Is this pattern already selected,
|
|
// and is it something other than none?
|
|
if (DRP_NONE != prp->dwPattern && prp->lParam)
|
|
{
|
|
// Yes; can't have duplicate values
|
|
MsgBox(g_hinst,
|
|
hwnd,
|
|
MAKEINTRESOURCE(IDS_ERR_DUP_PATTERN),
|
|
MAKEINTRESOURCE(IDS_CAP_RING),
|
|
NULL,
|
|
MB_ERROR);
|
|
|
|
// Set the focus on the offending control
|
|
PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)hwndCtl, (LPARAM)TRUE);
|
|
return FALSE;
|
|
}
|
|
prp->lParam = TRUE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: PSN_APPLY handler
|
|
|
|
Returns: TRUE if validation succeeded
|
|
FALSE if not
|
|
|
|
Cond: --
|
|
*/
|
|
BOOL PRIVATE Ring_OnApply(
|
|
PRING this)
|
|
{
|
|
BOOL bRet;
|
|
HWND hwnd = this->hdlg;
|
|
HWND hwndCtl;
|
|
LPDWORD lpdw;
|
|
int i;
|
|
int iSel;
|
|
PVOICEFEATURES pvs = &this->pmi->pglobal->vs;
|
|
PRINGPAT prp;
|
|
|
|
bRet = Ring_ValidateSettings(this);
|
|
|
|
// Are the user's settings valid?
|
|
if (bRet)
|
|
{
|
|
// Yes
|
|
if (Button_GetCheck(GetDlgItem(hwnd, IDC_RING_CHECK)))
|
|
{
|
|
SetFlag(pvs->dwFlags, VSF_DIST_RING);
|
|
}
|
|
else
|
|
{
|
|
ClearFlag(pvs->dwFlags, VSF_DIST_RING);
|
|
}
|
|
|
|
|
|
// Get the ring pattern settings
|
|
|
|
for (i = 0; i < ARRAY_ELEMENTS(c_rgidcPattern); i++)
|
|
{
|
|
hwndCtl = GetDlgItem(hwnd, c_rgidcPattern[i]);
|
|
lpdw = &pvs->DistRing[i].dwPattern;
|
|
|
|
iSel = ComboBox_GetCurSel(hwndCtl);
|
|
ASSERT(LB_ERR != iSel);
|
|
|
|
ComboBox_GetLBText(hwndCtl, iSel, &prp);
|
|
|
|
*lpdw = prp->dwPattern;
|
|
}
|
|
|
|
// Get the type of call settings
|
|
|
|
for (i = 0; i < ARRAY_ELEMENTS(c_rgidcTypeOfCalls); i++)
|
|
{
|
|
hwndCtl = GetDlgItem(hwnd, c_rgidcTypeOfCalls[i]);
|
|
lpdw = &pvs->DistRing[i].dwMediaType;
|
|
|
|
iSel = ComboBox_GetCurSel(hwndCtl);
|
|
ASSERT(LB_ERR != iSel);
|
|
|
|
*lpdw = ComboBox_GetItemData(hwndCtl, iSel);
|
|
}
|
|
|
|
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_NOTIFY handler
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
LRESULT PRIVATE Ring_OnNotify(
|
|
PRING this,
|
|
int idFrom,
|
|
NMHDR FAR * lpnmhdr)
|
|
{
|
|
LRESULT lRet = 0;
|
|
|
|
switch (lpnmhdr->code)
|
|
{
|
|
case PSN_SETACTIVE:
|
|
break;
|
|
|
|
case PSN_KILLACTIVE:
|
|
// N.b. This message is not sent if user clicks Cancel!
|
|
// N.b. This message is sent prior to PSN_APPLY
|
|
//
|
|
break;
|
|
|
|
case PSN_APPLY:
|
|
lRet = Ring_OnApply(this) ? PSNRET_NOERROR : PSNRET_INVALID;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return lRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_DESTROY handler
|
|
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Ring_OnDestroy(
|
|
PRING this)
|
|
{
|
|
if (this->hdcStrip)
|
|
DeleteDC(this->hdcStrip);
|
|
|
|
if (this->hbmStrip)
|
|
DeleteObject(this->hbmStrip);
|
|
|
|
if (this->hfont)
|
|
DeleteFont(this->hfont);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_MEASUREITEM handler
|
|
Returns: --
|
|
|
|
Cond: !!! WM_MEASUREITEM is received before WM_INITDIALOG !!!
|
|
|
|
The contents of 'this' will be uninitialized.
|
|
*/
|
|
void PRIVATE Ring_OnMeasureItem(
|
|
PRING this,
|
|
LPMEASUREITEMSTRUCT lpmis)
|
|
{
|
|
HWND hwnd = this->hdlg;
|
|
HDC hdc;
|
|
|
|
ASSERT(ODT_COMBOBOX == lpmis->CtlType);
|
|
|
|
hdc = GetDC(hwnd);
|
|
if (hdc)
|
|
{
|
|
TEXTMETRIC tm;
|
|
|
|
GetTextMetrics(hdc, &tm);
|
|
lpmis->itemHeight = max(tm.tmHeight, CY_PATTERN);
|
|
|
|
ReleaseDC(hwnd, hdc);
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_DRAWITEM handler
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Ring_OnDrawCBItem(
|
|
PRING this,
|
|
const DRAWITEMSTRUCT FAR * lpcdis)
|
|
{
|
|
HWND hwnd = this->hdlg;
|
|
PRINGPAT prp = (PRINGPAT)lpcdis->itemData;
|
|
|
|
ASSERT(ODT_COMBOBOX == lpcdis->CtlType);
|
|
ASSERT(prp);
|
|
|
|
if (prp)
|
|
{
|
|
HDC hdc = lpcdis->hDC;
|
|
RECT rc = lpcdis->rcItem;
|
|
RECT rcFrame;
|
|
POINT ptSav;
|
|
int x;
|
|
int y;
|
|
int nBkMode;
|
|
COLORREF crText;
|
|
COLORREF crBk;
|
|
COLORREF crTextSav;
|
|
COLORREF crBkSav;
|
|
|
|
ASSERT(hdc);
|
|
|
|
SetViewportOrgEx(hdc, rc.left, rc.top, &ptSav);
|
|
|
|
rcFrame.top = 0;
|
|
rcFrame.left = 0;
|
|
rcFrame.bottom = rc.bottom - rc.top;
|
|
rcFrame.right = rc.right - rc.left;
|
|
|
|
// Set the colors
|
|
|
|
nBkMode = SetBkMode(hdc, TRANSPARENT);
|
|
|
|
TextAndBkCr(lpcdis, &crText, &crBk);
|
|
crTextSav = SetTextColor(hdc, crText);
|
|
crBkSav = SetBkColor(hdc, crBk);
|
|
|
|
// Do we need to redraw everything?
|
|
if (IsFlagSet(lpcdis->itemAction, ODA_DRAWENTIRE) ||
|
|
IsFlagSet(lpcdis->itemAction, ODA_SELECT))
|
|
{
|
|
// Yes
|
|
TCHAR sz[MAXSHORTLEN];
|
|
LPTSTR psz = sz;
|
|
int cch;
|
|
HFONT hfontSav;
|
|
|
|
// Show bitmap or text?
|
|
if (DRP_NONE == prp->dwPattern)
|
|
{
|
|
// Text
|
|
hfontSav = SelectFont(hdc, this->hfont);
|
|
SzFromIDS(g_hinst, IDS_AUTOMATIC, sz, SIZECHARS(sz));
|
|
cch = lstrlen(sz);
|
|
}
|
|
else
|
|
{
|
|
// Bitmap
|
|
hfontSav = NULL;
|
|
*psz = 0;
|
|
cch = 0;
|
|
}
|
|
|
|
ASSERT(rc.right - rc.left >= CX_PATTERN);
|
|
ASSERT(rc.bottom - rc.top >= CY_PATTERN);
|
|
|
|
x = (rc.right - rc.left - CX_PATTERN) / 2;
|
|
y = (rc.bottom - rc.top - CY_PATTERN) / 2;
|
|
|
|
// Fill background (with optional text)
|
|
ExtTextOut(hdc, 2, 2, ETO_OPAQUE, &rcFrame, psz, cch, NULL);
|
|
|
|
if (DRP_NONE != prp->dwPattern)
|
|
{
|
|
// Draw bitmap
|
|
BitBlt(hdc, x, y, CX_PATTERN, CY_PATTERN,
|
|
this->hdcStrip, ((int)prp->dwPattern - 1) * CX_PATTERN, 0,
|
|
SRCCOPY);
|
|
}
|
|
|
|
if (hfontSav)
|
|
SelectFont(hdc, hfontSav);
|
|
}
|
|
|
|
// Draw the caret?
|
|
if (IsFlagSet(lpcdis->itemAction, ODA_FOCUS) ||
|
|
IsFlagSet(lpcdis->itemState, ODS_FOCUS))
|
|
{
|
|
// Yes
|
|
DrawFocusRect(hdc, &rcFrame);
|
|
}
|
|
|
|
// Clean up
|
|
SetTextColor(hdc, crTextSav);
|
|
SetBkColor(hdc, crBkSav);
|
|
SetBkMode(hdc, nBkMode);
|
|
SetViewportOrgEx(hdc, ptSav.x, ptSav.y, NULL);
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_DRAWITEM handler
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Ring_OnDrawStaticItem(
|
|
PRING this,
|
|
const DRAWITEMSTRUCT FAR * lpcdis)
|
|
{
|
|
HWND hwnd = this->hdlg;
|
|
HDC hdc = lpcdis->hDC;
|
|
RECT rc = lpcdis->rcItem;
|
|
int x;
|
|
int y;
|
|
int nBkMode;
|
|
COLORREF crText;
|
|
COLORREF crBk;
|
|
COLORREF crTextSav;
|
|
COLORREF crBkSav;
|
|
|
|
ASSERT(ODT_STATIC == lpcdis->CtlType);
|
|
ASSERT(hdc);
|
|
|
|
// Set the colors
|
|
|
|
nBkMode = SetBkMode(hdc, TRANSPARENT);
|
|
|
|
TextAndBkCr(lpcdis, &crText, &crBk);
|
|
crTextSav = SetTextColor(hdc, crText);
|
|
crBkSav = SetBkColor(hdc, crBk);
|
|
|
|
ASSERT(rc.right - rc.left >= CX_PATTERN);
|
|
ASSERT(rc.bottom - rc.top >= CY_PATTERN);
|
|
|
|
x = (rc.right - rc.left - CX_PATTERN) / 2;
|
|
y = (rc.bottom - rc.top - CY_PATTERN) / 2;
|
|
|
|
// Fill background (with optional text)
|
|
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, TEXT(""), 0, NULL);
|
|
|
|
// Draw bitmap
|
|
BitBlt(hdc, x, y, CX_PATTERN, CY_PATTERN,
|
|
this->hdcStrip, (int)(DRP_LONG - 1) * CX_PATTERN, 0,
|
|
SRCCOPY);
|
|
|
|
// Clean up
|
|
SetTextColor(hdc, crTextSav);
|
|
SetBkColor(hdc, crBkSav);
|
|
SetBkMode(hdc, nBkMode);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_DRAWITEM handler
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Ring_OnDrawItem(
|
|
PRING this,
|
|
const DRAWITEMSTRUCT FAR * lpcdis)
|
|
{
|
|
switch (lpcdis->CtlType)
|
|
{
|
|
case ODT_COMBOBOX:
|
|
Ring_OnDrawCBItem(this, lpcdis);
|
|
break;
|
|
|
|
case ODT_STATIC:
|
|
Ring_OnDrawStaticItem(this, lpcdis);
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_DELETEITEM handler
|
|
Returns: --
|
|
|
|
Cond: !!! WM_DELETEITEM is received after WM_DESTROY !!!
|
|
|
|
*/
|
|
void Ring_OnDeleteItem(
|
|
PRING this,
|
|
const DELETEITEMSTRUCT FAR * lpcdis)
|
|
{
|
|
PRINGPAT prp = (PRINGPAT)lpcdis->itemData;
|
|
|
|
ASSERT(NULL == this); // this will be NULL
|
|
|
|
ASSERT(ODT_COMBOBOX == lpcdis->CtlType);
|
|
ASSERT(prp);
|
|
}
|
|
|
|
|
|
static BOOL s_bRingRecurse = FALSE;
|
|
|
|
LRESULT INLINE Ring_DefProc(
|
|
HWND hDlg,
|
|
UINT msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
ENTER_X()
|
|
{
|
|
s_bRingRecurse = TRUE;
|
|
}
|
|
LEAVE_X()
|
|
|
|
return DefDlgProc(hDlg, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Real dialog proc
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
LRESULT Ring_DlgProc(
|
|
PRING this,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
#ifdef CS_HELP
|
|
// UE used the control IDs as help IDs. To prevent mix-ups in
|
|
// the future (ie, when the control IDs change), here are the
|
|
// help IDs.
|
|
#define IDH_UNI_RING_SERVICES 1069
|
|
#define IDH_UNI_RING_LBL_ADDR_PRI 1070
|
|
#define IDH_UNI_RING_ADDR_PRI 1073
|
|
#define IDH_UNI_RING_TYPE_ADDR_PRI 1082
|
|
#define IDH_UNI_RING_LBL_ADDR1 1071
|
|
#define IDH_UNI_RING_ADDR1 1074
|
|
#define IDH_UNI_RING_TYPE_ADDR1 1083
|
|
#define IDH_UNI_RING_LBL_ADDR2 1072
|
|
#define IDH_UNI_RING_ADDR2 1075
|
|
#define IDH_UNI_RING_TYPE_ADDR2 1084
|
|
#define IDH_UNI_RING_LBL_ADDR3 1076
|
|
#define IDH_UNI_RING_ADDR3 1077
|
|
#define IDH_UNI_RING_TYPE_ADDR3 1085
|
|
#define IDH_UNI_RING_LBL_PRI_CALLERS 1078
|
|
#define IDH_UNI_RING_PRI_CALLERS 1079
|
|
#define IDH_UNI_RING_TYPE_PRI_CALLERS 1086
|
|
#define IDH_UNI_RING_LBL_CALLBACK 1080
|
|
#define IDH_UNI_RING_CALLBACK 1081
|
|
#define IDH_UNI_RING_TYPE_CALLBACK 1087
|
|
#pragma data_seg(DATASEG_READONLY)
|
|
const static DWORD rgHelpIDs[] = {
|
|
IDC_RING_CHECK, IDH_UNI_RING_SERVICES,
|
|
IDC_LBL_ADDR_PRI, IDH_UNI_RING_LBL_ADDR_PRI,
|
|
IDC_ADDR_PRI, IDH_UNI_RING_ADDR_PRI,
|
|
IDC_TYPE_ADDR_PRI, IDH_UNI_RING_TYPE_ADDR_PRI,
|
|
IDC_LBL_ADDR1, IDH_UNI_RING_LBL_ADDR1,
|
|
IDC_ADDR1, IDH_UNI_RING_ADDR1,
|
|
IDC_TYPE_ADDR1, IDH_UNI_RING_TYPE_ADDR1,
|
|
IDC_LBL_ADDR2, IDH_UNI_RING_LBL_ADDR2,
|
|
IDC_ADDR2, IDH_UNI_RING_ADDR2,
|
|
IDC_TYPE_ADDR2, IDH_UNI_RING_TYPE_ADDR2,
|
|
IDC_LBL_ADDR3, IDH_UNI_RING_LBL_ADDR3,
|
|
IDC_ADDR3, IDH_UNI_RING_ADDR3,
|
|
IDC_TYPE_ADDR3, IDH_UNI_RING_TYPE_ADDR3,
|
|
IDC_LBL_PRI_CALLERS, IDH_UNI_RING_LBL_PRI_CALLERS,
|
|
IDC_PRI_CALLERS, IDH_UNI_RING_PRI_CALLERS,
|
|
IDC_TYPE_PRI_CALLERS, IDH_UNI_RING_TYPE_PRI_CALLERS,
|
|
IDC_LBL_CALLBACK, IDH_UNI_RING_LBL_CALLBACK,
|
|
IDC_CALLBACK, IDH_UNI_RING_CALLBACK,
|
|
IDC_TYPE_CALLBACK, IDH_UNI_RING_TYPE_CALLBACK,
|
|
0, 0 };
|
|
#pragma data_seg()
|
|
#endif
|
|
|
|
switch (message)
|
|
{
|
|
HANDLE_MSG(this, WM_INITDIALOG, Ring_OnInitDialog);
|
|
HANDLE_MSG(this, WM_COMMAND, Ring_OnCommand);
|
|
HANDLE_MSG(this, WM_NOTIFY, Ring_OnNotify);
|
|
HANDLE_MSG(this, WM_DESTROY, Ring_OnDestroy);
|
|
|
|
HANDLE_MSG(this, WM_MEASUREITEM, Ring_OnMeasureItem);
|
|
HANDLE_MSG(this, WM_DRAWITEM, Ring_OnDrawItem);
|
|
HANDLE_MSG(this, WM_DELETEITEM, Ring_OnDeleteItem);
|
|
|
|
#ifdef CS_HELP
|
|
case WM_HELP:
|
|
WinHelp(((LPHELPINFO)lParam)->hItemHandle, c_szUnimdmHelpFile, HELP_WM_HELP, (DWORD)(LPVOID)rgHelpIDs);
|
|
return 0;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WinHelp((HWND)wParam, c_szUnimdmHelpFile, HELP_CONTEXTMENU, (DWORD)(LPVOID)rgHelpIDs);
|
|
return 0;
|
|
#endif
|
|
|
|
default:
|
|
return Ring_DefProc(this->hdlg, message, wParam, lParam);
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Dialog Wrapper
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
BOOL CALLBACK Ring_WrapperProc(
|
|
HWND hDlg, // std params
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
PRING this;
|
|
|
|
// Cool windowsx.h dialog technique. For full explanation, see
|
|
// WINDOWSX.TXT. This supports multiple-instancing of dialogs.
|
|
//
|
|
ENTER_X()
|
|
{
|
|
if (s_bRingRecurse)
|
|
{
|
|
s_bRingRecurse = FALSE;
|
|
LEAVE_X()
|
|
return FALSE;
|
|
}
|
|
}
|
|
LEAVE_X()
|
|
|
|
this = Ring_GetPtr(hDlg);
|
|
if (this == NULL)
|
|
{
|
|
// (WM_SETFONT is the first message received by dialogs)
|
|
if (WM_SETFONT == message)
|
|
{
|
|
this = (PRING)LocalAlloc(LPTR, sizeof(RING));
|
|
if (!this)
|
|
{
|
|
MsgBox(g_hinst,
|
|
hDlg,
|
|
MAKEINTRESOURCE(IDS_OOM_SETTINGS),
|
|
MAKEINTRESOURCE(IDS_CAP_RING),
|
|
NULL,
|
|
MB_ERROR);
|
|
EndDialog(hDlg, IDCANCEL);
|
|
return (BOOL)Ring_DefProc(hDlg, message, wParam, lParam);
|
|
}
|
|
this->hdlg = hDlg;
|
|
Ring_SetPtr(hDlg, this);
|
|
}
|
|
else
|
|
{
|
|
return (BOOL)Ring_DefProc(hDlg, message, wParam, lParam);
|
|
}
|
|
}
|
|
|
|
if (message == WM_DESTROY)
|
|
{
|
|
Ring_DlgProc(this, message, wParam, lParam);
|
|
LocalFree((HLOCAL)OFFSETOF(this));
|
|
Ring_SetPtr(hDlg, NULL);
|
|
return 0;
|
|
}
|
|
|
|
return SetDlgMsgResult(hDlg, message, Ring_DlgProc(this, message, wParam, lParam));
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
// Cheap ring dialog code
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
#define CheapRing_GetPtr(hwnd) (PRING)GetWindowLong(hwnd, DWL_USER)
|
|
#define CheapRing_SetPtr(hwnd, lp) (PRING)SetWindowLong(hwnd, DWL_USER, (LONG)(lp))
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Initialize the specified Type of Call combobox.
|
|
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE CheapRing_InitTypeOfCall(
|
|
PRING this,
|
|
HWND hwndCB,
|
|
DWORD dwType)
|
|
{
|
|
#pragma data_seg(DATASEG_READONLY)
|
|
static const struct
|
|
{
|
|
UINT ids;
|
|
DWORD dwType; // DRT_*
|
|
} s_rgTypes[] =
|
|
{
|
|
{ IDS_UNSPECIFIED, DRT_UNSPECIFIED },
|
|
{ IDS_DATA, DRT_DATA },
|
|
{ IDS_FAX, DRT_FAX },
|
|
{ IDS_VOICE, DRT_VOICE },
|
|
};
|
|
#pragma data_seg()
|
|
|
|
int i;
|
|
int iSel = 0;
|
|
int n;
|
|
TCHAR sz[MAXMEDLEN];
|
|
|
|
// Fill the listbox
|
|
for (i = 0; i < ARRAY_ELEMENTS(s_rgTypes); i++)
|
|
{
|
|
n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgTypes[i].ids, sz, SIZECHARS(sz)));
|
|
ComboBox_SetItemData(hwndCB, n, s_rgTypes[i].dwType);
|
|
|
|
// Keep our eyes peeled for the selected type
|
|
if (dwType == s_rgTypes[i].dwType)
|
|
{
|
|
iSel = n;
|
|
}
|
|
}
|
|
|
|
ComboBox_SetCurSel(hwndCB, iSel);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Enable/disable all the controls
|
|
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE CheapRing_EnableControls(
|
|
PRING this,
|
|
BOOL bEnable)
|
|
{
|
|
HWND hwnd = this->hdlg;
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_LBL_RING1), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_TYPE_RING1), bEnable);
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_LBL_RING2), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_TYPE_RING2), bEnable);
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_LBL_RING3), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_TYPE_RING3), bEnable);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_INITDIALOG Handler
|
|
Returns: FALSE when we assign the control focus
|
|
Cond: --
|
|
*/
|
|
BOOL PRIVATE CheapRing_OnInitDialog(
|
|
PRING this,
|
|
HWND hwndFocus,
|
|
LPARAM lParam) // expected to be PROPSHEETINFO
|
|
{
|
|
|
|
LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
|
|
HWND hwnd = this->hdlg;
|
|
HWND hwndCtl;
|
|
LPDWORD lpdw;
|
|
BOOL bEnable;
|
|
int i;
|
|
PVOICEFEATURES pvs;
|
|
|
|
ASSERT((LPTSTR)lppsp->lParam);
|
|
|
|
this->pmi = (LPMODEMINFO)lppsp->lParam;
|
|
pvs = &this->pmi->pglobal->vs;
|
|
|
|
// Enable/disable controls
|
|
|
|
bEnable = IsFlagSet(this->pmi->pglobal->vs.dwFlags, VSF_DIST_RING);
|
|
|
|
Button_SetCheck(GetDlgItem(hwnd, IDC_RING_CHECK), bEnable);
|
|
CheapRing_EnableControls(this, bEnable);
|
|
|
|
// Initialize controls
|
|
|
|
for (i = 0; i < ARRAY_ELEMENTS(c_rgidcTypeOfCheapCalls); i++)
|
|
{
|
|
hwndCtl = GetDlgItem(hwnd, c_rgidcTypeOfCheapCalls[i]);
|
|
lpdw = &pvs->DistRing[i].dwMediaType;
|
|
|
|
CheapRing_InitTypeOfCall(this, hwndCtl, *lpdw);
|
|
}
|
|
|
|
return TRUE; // default initial focus
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_COMMAND Handler
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE CheapRing_OnCommand(
|
|
PRING this,
|
|
int id,
|
|
HWND hwndCtl,
|
|
UINT uNotifyCode)
|
|
{
|
|
BOOL bCheck;
|
|
|
|
switch (id)
|
|
{
|
|
case IDC_RING_CHECK:
|
|
bCheck = Button_GetCheck(hwndCtl);
|
|
CheapRing_EnableControls(this, bCheck);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: PSN_APPLY handler
|
|
|
|
Returns: TRUE if validation succeeded
|
|
FALSE if not
|
|
|
|
Cond: --
|
|
*/
|
|
BOOL PRIVATE CheapRing_OnApply(
|
|
PRING this)
|
|
{
|
|
HWND hwnd = this->hdlg;
|
|
HWND hwndCtl;
|
|
LPDWORD lpdw;
|
|
int i;
|
|
int iSel;
|
|
PVOICEFEATURES pvs = &this->pmi->pglobal->vs;
|
|
|
|
if (Button_GetCheck(GetDlgItem(hwnd, IDC_RING_CHECK)))
|
|
{
|
|
SetFlag(pvs->dwFlags, VSF_DIST_RING);
|
|
}
|
|
else
|
|
{
|
|
ClearFlag(pvs->dwFlags, VSF_DIST_RING);
|
|
}
|
|
|
|
|
|
// Get the ring pattern settings
|
|
|
|
for (i = 0; i < ARRAY_ELEMENTS(c_rgdwCheapPatterns); i++)
|
|
{
|
|
pvs->DistRing[i].dwPattern = c_rgdwCheapPatterns[i];
|
|
}
|
|
|
|
// Get the type of call settings
|
|
|
|
for (i = 0; i < ARRAY_ELEMENTS(c_rgidcTypeOfCheapCalls); i++)
|
|
{
|
|
hwndCtl = GetDlgItem(hwnd, c_rgidcTypeOfCheapCalls[i]);
|
|
lpdw = &pvs->DistRing[i].dwMediaType;
|
|
|
|
iSel = ComboBox_GetCurSel(hwndCtl);
|
|
ASSERT(LB_ERR != iSel);
|
|
|
|
*lpdw = ComboBox_GetItemData(hwndCtl, iSel);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_NOTIFY handler
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
LRESULT PRIVATE CheapRing_OnNotify(
|
|
PRING this,
|
|
int idFrom,
|
|
NMHDR FAR * lpnmhdr)
|
|
{
|
|
LRESULT lRet = 0;
|
|
|
|
switch (lpnmhdr->code)
|
|
{
|
|
case PSN_SETACTIVE:
|
|
break;
|
|
|
|
case PSN_KILLACTIVE:
|
|
// N.b. This message is not sent if user clicks Cancel!
|
|
// N.b. This message is sent prior to PSN_APPLY
|
|
//
|
|
break;
|
|
|
|
case PSN_APPLY:
|
|
lRet = CheapRing_OnApply(this) ? PSNRET_NOERROR : PSNRET_INVALID;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return lRet;
|
|
}
|
|
|
|
|
|
static BOOL s_bCheapRingRecurse = FALSE;
|
|
|
|
LRESULT INLINE CheapRing_DefProc(
|
|
HWND hDlg,
|
|
UINT msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
ENTER_X()
|
|
{
|
|
s_bCheapRingRecurse = TRUE;
|
|
}
|
|
LEAVE_X()
|
|
|
|
return DefDlgProc(hDlg, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Real dialog proc
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
LRESULT CheapRing_DlgProc(
|
|
PRING this,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
#ifdef CS_HELP
|
|
// UE used the control IDs as help IDs. To prevent mix-ups in
|
|
// the future (ie, when the control IDs change), here are the
|
|
// help IDs.
|
|
#define IDH_UNI_RING_LBL_RING1 1088
|
|
#define IDH_UNI_RING_TYPE_RING1 1091
|
|
#define IDH_UNI_RING_LBL_RING2 1089
|
|
#define IDH_UNI_RING_TYPE_RING2 1092
|
|
#define IDH_UNI_RING_LBL_RING3 1090
|
|
#define IDH_UNI_RING_TYPE_RING3 1093
|
|
#pragma data_seg(DATASEG_READONLY)
|
|
const static DWORD rgHelpIDs[] = {
|
|
IDC_RING_CHECK, IDH_UNI_RING_SERVICES,
|
|
IDC_LBL_RING1, IDH_UNI_RING_LBL_RING1,
|
|
IDC_TYPE_RING1, IDH_UNI_RING_TYPE_RING1,
|
|
IDC_LBL_RING2, IDH_UNI_RING_LBL_RING2,
|
|
IDC_TYPE_RING2, IDH_UNI_RING_TYPE_RING2,
|
|
IDC_LBL_RING3, IDH_UNI_RING_LBL_RING3,
|
|
IDC_TYPE_RING3, IDH_UNI_RING_TYPE_RING3,
|
|
0, 0 };
|
|
#pragma data_seg()
|
|
#endif
|
|
|
|
switch (message)
|
|
{
|
|
HANDLE_MSG(this, WM_INITDIALOG, CheapRing_OnInitDialog);
|
|
HANDLE_MSG(this, WM_COMMAND, CheapRing_OnCommand);
|
|
HANDLE_MSG(this, WM_NOTIFY, CheapRing_OnNotify);
|
|
|
|
|
|
#ifdef CS_HELP
|
|
case WM_HELP:
|
|
WinHelp(((LPHELPINFO)lParam)->hItemHandle, c_szUnimdmHelpFile, HELP_WM_HELP, (DWORD)(LPVOID)rgHelpIDs);
|
|
return 0;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WinHelp((HWND)wParam, c_szUnimdmHelpFile, HELP_CONTEXTMENU, (DWORD)(LPVOID)rgHelpIDs);
|
|
return 0;
|
|
#endif
|
|
|
|
default:
|
|
return CheapRing_DefProc(this->hdlg, message, wParam, lParam);
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Dialog Wrapper
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
BOOL CALLBACK CheapRing_WrapperProc(
|
|
HWND hDlg, // std params
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
PRING this;
|
|
|
|
// Cool windowsx.h dialog technique. For full explanation, see
|
|
// WINDOWSX.TXT. This supports multiple-instancing of dialogs.
|
|
//
|
|
ENTER_X()
|
|
{
|
|
if (s_bCheapRingRecurse)
|
|
{
|
|
s_bCheapRingRecurse = FALSE;
|
|
LEAVE_X()
|
|
return FALSE;
|
|
}
|
|
}
|
|
LEAVE_X()
|
|
|
|
this = CheapRing_GetPtr(hDlg);
|
|
if (this == NULL)
|
|
{
|
|
// (WM_SETFONT is the first message received by dialogs)
|
|
if (WM_SETFONT == message)
|
|
{
|
|
this = (PRING)LocalAlloc(LPTR, sizeof(RING));
|
|
if (!this)
|
|
{
|
|
MsgBox(g_hinst,
|
|
hDlg,
|
|
MAKEINTRESOURCE(IDS_OOM_SETTINGS),
|
|
MAKEINTRESOURCE(IDS_CAP_RING),
|
|
NULL,
|
|
MB_ERROR);
|
|
EndDialog(hDlg, IDCANCEL);
|
|
return (BOOL)CheapRing_DefProc(hDlg, message, wParam, lParam);
|
|
}
|
|
this->hdlg = hDlg;
|
|
CheapRing_SetPtr(hDlg, this);
|
|
}
|
|
else
|
|
{
|
|
return (BOOL)CheapRing_DefProc(hDlg, message, wParam, lParam);
|
|
}
|
|
}
|
|
|
|
if (message == WM_DESTROY)
|
|
{
|
|
CheapRing_DlgProc(this, message, wParam, lParam);
|
|
LocalFree((HLOCAL)OFFSETOF(this));
|
|
CheapRing_SetPtr(hDlg, NULL);
|
|
return 0;
|
|
}
|
|
|
|
return SetDlgMsgResult(hDlg, message, CheapRing_DlgProc(this, message, wParam, lParam));
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
// DTMF edit box proc
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Handle WM_CHAR
|
|
|
|
Returns: TRUE to let the characters by
|
|
FALSE to prohibit
|
|
Cond: --
|
|
*/
|
|
BOOL PRIVATE DTMFEditProc_OnChar(
|
|
HWND hwnd,
|
|
UINT ch,
|
|
int cRepeat)
|
|
{
|
|
BOOL bRet;
|
|
|
|
// Is this a numerical digit,
|
|
// a backspace,
|
|
// or a valid DTMF digit?
|
|
if (IsCharAlphaNumeric((TCHAR)ch) && !IsCharAlpha((TCHAR)ch) ||
|
|
VK_BACK == LOBYTE(VkKeyScan((TCHAR)ch)) ||
|
|
'A' == ch || 'B' == ch || 'C' == ch || 'D' == ch ||
|
|
'*' == ch || '#' == ch)
|
|
{
|
|
// Yes
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
{
|
|
// No
|
|
MessageBeep(MB_OK);
|
|
bRet = FALSE;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Number proc. Only allow numbers to be entered into this edit box.
|
|
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
LRESULT CALLBACK DTMFEditProc(
|
|
HWND hwnd, // std params
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
WNDPROC pfn = (WNDPROC)GetWindowLong(hwnd, GWL_USERDATA);
|
|
|
|
// BUGBUG: doesn't handle paste correctly!
|
|
|
|
switch (message)
|
|
{
|
|
case WM_CHAR:
|
|
if (!DTMFEditProc_OnChar(hwnd, (UINT)wParam, LOWORD(lParam)))
|
|
return 1; // Don't process this character
|
|
break;
|
|
}
|
|
|
|
return CallWindowProc(pfn, hwnd, message, wParam, lParam);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
// Call forwarding dialog code
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
|
|
typedef struct tagCALLFWD
|
|
{
|
|
HWND hdlg; // dialog handle
|
|
LPMODEMINFO pmi; // modeminfo struct passed into dialog
|
|
|
|
} CALLFWD, FAR * PCALLFWD;
|
|
|
|
|
|
#define CallFwd_GetPtr(hwnd) (PCALLFWD)GetWindowLong(hwnd, DWL_USER)
|
|
#define CallFwd_SetPtr(hwnd, lp) (PCALLFWD)SetWindowLong(hwnd, DWL_USER, (LONG)(lp))
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Enable/disable all the controls
|
|
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE CallFwd_EnableControls(
|
|
PCALLFWD this,
|
|
BOOL bEnable)
|
|
{
|
|
HWND hwnd = this->hdlg;
|
|
|
|
EnableWindow(GetDlgItem(hwnd, IDC_FWD_ACT), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_ACT), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_FWD_DEACT), bEnable);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_DEACT), bEnable);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_INITDIALOG Handler
|
|
Returns: FALSE when we assign the control focus
|
|
Cond: --
|
|
*/
|
|
BOOL PRIVATE CallFwd_OnInitDialog(
|
|
PCALLFWD this,
|
|
HWND hwndFocus,
|
|
LPARAM lParam) // expected to be PROPSHEETINFO
|
|
{
|
|
LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
|
|
HWND hwnd = this->hdlg;
|
|
HWND hwndCtl;
|
|
BOOL bEnable;
|
|
PVOICEFEATURES pvs;
|
|
WNDPROC pfn;
|
|
|
|
ASSERT((LPTSTR)lppsp->lParam);
|
|
|
|
this->pmi = (LPMODEMINFO)lppsp->lParam;
|
|
pvs = &this->pmi->pglobal->vs;
|
|
|
|
// Subclass the edit boxes that only accept DTMF digits
|
|
hwndCtl = GetDlgItem(hwnd, IDC_ACT);
|
|
pfn = SubclassWindow(hwndCtl, DTMFEditProc);
|
|
SetWindowLong(hwndCtl, GWL_USERDATA, (LONG)pfn);
|
|
|
|
hwndCtl = GetDlgItem(hwnd, IDC_DEACT);
|
|
pfn = SubclassWindow(hwndCtl, DTMFEditProc);
|
|
SetWindowLong(hwndCtl, GWL_USERDATA, (LONG)pfn);
|
|
|
|
// Enable/disable controls
|
|
|
|
bEnable = IsFlagSet(pvs->dwFlags, VSF_CALL_FWD);
|
|
|
|
Button_SetCheck(GetDlgItem(hwnd, IDC_FWD_CHECK), bEnable);
|
|
CallFwd_EnableControls(this, bEnable);
|
|
|
|
// Initialize controls
|
|
|
|
hwndCtl = GetDlgItem(hwnd, IDC_ACT);
|
|
Edit_SetText(hwndCtl, pvs->szActivationCode);
|
|
Edit_LimitText(hwndCtl, SIZECHARS(pvs->szActivationCode)-1);
|
|
|
|
hwndCtl = GetDlgItem(hwnd, IDC_DEACT);
|
|
Edit_SetText(hwndCtl, pvs->szDeactivationCode);
|
|
Edit_LimitText(hwndCtl, SIZECHARS(pvs->szDeactivationCode)-1);
|
|
|
|
return TRUE; // default initial focus
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_COMMAND Handler
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE CallFwd_OnCommand(
|
|
PCALLFWD this,
|
|
int id,
|
|
HWND hwndCtl,
|
|
UINT uNotifyCode)
|
|
{
|
|
BOOL bCheck;
|
|
|
|
switch (id)
|
|
{
|
|
case IDC_FWD_CHECK:
|
|
bCheck = Button_GetCheck(hwndCtl);
|
|
CallFwd_EnableControls(this, bCheck);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Validate the user's settings.
|
|
|
|
The call forwarding fields must be filled in if the
|
|
service is turned on.
|
|
|
|
Returns: TRUE if valid
|
|
|
|
Cond: --
|
|
*/
|
|
BOOL PRIVATE CallFwd_ValidateSettings(
|
|
PCALLFWD this)
|
|
{
|
|
HWND hwnd = this->hdlg;
|
|
HWND hwndCtl;
|
|
|
|
// Is the service turned on?
|
|
if (Button_GetCheck(GetDlgItem(hwnd, IDC_FWD_CHECK)))
|
|
{
|
|
// Yes; are the fields filled in?
|
|
hwndCtl = GetDlgItem(hwnd, IDC_ACT);
|
|
if (0 == Edit_GetTextLength(hwndCtl))
|
|
{
|
|
// No; this is naughty
|
|
MsgBox(g_hinst,
|
|
hwnd,
|
|
MAKEINTRESOURCE(IDS_ERR_NEED_VALUE),
|
|
MAKEINTRESOURCE(IDS_CAP_CALLFWD),
|
|
NULL,
|
|
MB_ERROR);
|
|
|
|
// Set the focus on the offending control
|
|
PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)hwndCtl, (LPARAM)TRUE);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
hwndCtl = GetDlgItem(hwnd, IDC_DEACT);
|
|
if (0 == Edit_GetTextLength(hwndCtl))
|
|
{
|
|
// No; this is naughty
|
|
MsgBox(g_hinst,
|
|
hwnd,
|
|
MAKEINTRESOURCE(IDS_ERR_NEED_VALUE),
|
|
MAKEINTRESOURCE(IDS_CAP_CALLFWD),
|
|
NULL,
|
|
MB_ERROR);
|
|
|
|
// Set the focus on the offending control
|
|
PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)hwndCtl, (LPARAM)TRUE);
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: PSN_APPLY handler
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
BOOL PRIVATE CallFwd_OnApply(
|
|
PCALLFWD this)
|
|
{
|
|
BOOL bRet;
|
|
HWND hwnd = this->hdlg;
|
|
HWND hwndCtl;
|
|
PVOICEFEATURES pvs = &this->pmi->pglobal->vs;
|
|
|
|
bRet = CallFwd_ValidateSettings(this);
|
|
|
|
if (bRet)
|
|
{
|
|
if (Button_GetCheck(GetDlgItem(hwnd, IDC_FWD_CHECK)))
|
|
{
|
|
SetFlag(pvs->dwFlags, VSF_CALL_FWD);
|
|
}
|
|
else
|
|
{
|
|
ClearFlag(pvs->dwFlags, VSF_CALL_FWD);
|
|
}
|
|
|
|
hwndCtl = GetDlgItem(hwnd, IDC_ACT);
|
|
Edit_GetText(hwndCtl, pvs->szActivationCode, SIZECHARS(pvs->szActivationCode));
|
|
|
|
hwndCtl = GetDlgItem(hwnd, IDC_DEACT);
|
|
Edit_GetText(hwndCtl, pvs->szDeactivationCode, SIZECHARS(pvs->szDeactivationCode));
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_NOTIFY handler
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
LRESULT PRIVATE CallFwd_OnNotify(
|
|
PCALLFWD this,
|
|
int idFrom,
|
|
NMHDR FAR * lpnmhdr)
|
|
{
|
|
LRESULT lRet = 0;
|
|
|
|
switch (lpnmhdr->code)
|
|
{
|
|
case PSN_SETACTIVE:
|
|
break;
|
|
|
|
case PSN_KILLACTIVE:
|
|
// N.b. This message is not sent if user clicks Cancel!
|
|
// N.b. This message is sent prior to PSN_APPLY
|
|
//
|
|
break;
|
|
|
|
case PSN_APPLY:
|
|
lRet = CallFwd_OnApply(this) ? PSNRET_NOERROR : PSNRET_INVALID;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return lRet;
|
|
}
|
|
|
|
|
|
static BOOL s_bCallFwdRecurse = FALSE;
|
|
|
|
LRESULT INLINE CallFwd_DefProc(
|
|
HWND hDlg,
|
|
UINT msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
ENTER_X()
|
|
{
|
|
s_bCallFwdRecurse = TRUE;
|
|
}
|
|
LEAVE_X()
|
|
|
|
return DefDlgProc(hDlg, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Real dialog proc
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
LRESULT CallFwd_DlgProc(
|
|
PCALLFWD this,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
#ifdef CS_HELP
|
|
// UE used the control IDs as help IDs. To prevent mix-ups in
|
|
// the future (ie, when the control IDs change), here are the
|
|
// help IDs.
|
|
#define IDH_UNI_CALLFWD_SERVICES 1062
|
|
#define IDH_UNI_CALLFWD_FWD_ACT 1063
|
|
#define IDH_UNI_CALLFWD_ACT 1068
|
|
#define IDH_UNI_CALLFWD_FWD_DEACT 1064
|
|
#define IDH_UNI_CALLFWD_DEACT 1067
|
|
#pragma data_seg(DATASEG_READONLY)
|
|
const static DWORD rgHelpIDs[] = {
|
|
IDC_FWD_CHECK, IDH_UNI_CALLFWD_SERVICES,
|
|
IDC_FWD_ACT, IDH_UNI_CALLFWD_FWD_ACT,
|
|
IDC_ACT, IDH_UNI_CALLFWD_ACT,
|
|
IDC_FWD_DEACT, IDH_UNI_CALLFWD_FWD_DEACT,
|
|
IDC_DEACT, IDH_UNI_CALLFWD_DEACT,
|
|
0, 0 };
|
|
#pragma data_seg()
|
|
#endif
|
|
|
|
switch (message)
|
|
{
|
|
HANDLE_MSG(this, WM_INITDIALOG, CallFwd_OnInitDialog);
|
|
HANDLE_MSG(this, WM_COMMAND, CallFwd_OnCommand);
|
|
HANDLE_MSG(this, WM_NOTIFY, CallFwd_OnNotify);
|
|
|
|
#ifdef CS_HELP
|
|
case WM_HELP:
|
|
WinHelp(((LPHELPINFO)lParam)->hItemHandle, c_szUnimdmHelpFile, HELP_WM_HELP, (DWORD)(LPVOID)rgHelpIDs);
|
|
return 0;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WinHelp((HWND)wParam, c_szUnimdmHelpFile, HELP_CONTEXTMENU, (DWORD)(LPVOID)rgHelpIDs);
|
|
return 0;
|
|
#endif
|
|
|
|
default:
|
|
return CallFwd_DefProc(this->hdlg, message, wParam, lParam);
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Dialog Wrapper
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
BOOL CALLBACK CallFwd_WrapperProc(
|
|
HWND hDlg, // std params
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
PCALLFWD this;
|
|
|
|
// Cool windowsx.h dialog technique. For full explanation, see
|
|
// WINDOWSX.TXT. This supports multiple-instancing of dialogs.
|
|
//
|
|
ENTER_X()
|
|
{
|
|
if (s_bCallFwdRecurse)
|
|
{
|
|
s_bCallFwdRecurse = FALSE;
|
|
LEAVE_X()
|
|
return FALSE;
|
|
}
|
|
}
|
|
LEAVE_X()
|
|
|
|
this = CallFwd_GetPtr(hDlg);
|
|
if (this == NULL)
|
|
{
|
|
if (message == WM_INITDIALOG)
|
|
{
|
|
this = (PCALLFWD)LocalAlloc(LPTR, sizeof(CALLFWD));
|
|
if (!this)
|
|
{
|
|
MsgBox(g_hinst,
|
|
hDlg,
|
|
MAKEINTRESOURCE(IDS_OOM_SETTINGS),
|
|
MAKEINTRESOURCE(IDS_CAP_RING),
|
|
NULL,
|
|
MB_ERROR);
|
|
EndDialog(hDlg, IDCANCEL);
|
|
return (BOOL)CallFwd_DefProc(hDlg, message, wParam, lParam);
|
|
}
|
|
this->hdlg = hDlg;
|
|
CallFwd_SetPtr(hDlg, this);
|
|
}
|
|
else
|
|
{
|
|
return (BOOL)CallFwd_DefProc(hDlg, message, wParam, lParam);
|
|
}
|
|
}
|
|
|
|
if (message == WM_DESTROY)
|
|
{
|
|
CallFwd_DlgProc(this, message, wParam, lParam);
|
|
LocalFree((HLOCAL)OFFSETOF(this));
|
|
CallFwd_SetPtr(hDlg, NULL);
|
|
return 0;
|
|
}
|
|
|
|
return SetDlgMsgResult(hDlg, message, CallFwd_DlgProc(this, message, wParam, lParam));
|
|
}
|
|
|
|
|
|
|