1142 lines
31 KiB
C
1142 lines
31 KiB
C
//---------------------------------------------------------------------------
|
|
//
|
|
// Copyright (c) Microsoft Corporation 1993-1996
|
|
//
|
|
// File: port.c
|
|
//
|
|
// This files contains the dialog code for the Port Settings property page.
|
|
//
|
|
// History:
|
|
// 2-09-94 ScottH Created
|
|
// 11-06-95 ScottH Ported to NT
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
#include "proj.h"
|
|
|
|
// This is the structure that is used to fill the
|
|
// max speed listbox
|
|
typedef struct _Bauds
|
|
{
|
|
DWORD dwDTERate;
|
|
int ids;
|
|
} Bauds;
|
|
|
|
static Bauds g_rgbauds[] = {
|
|
{ 110L, IDS_BAUD_110 },
|
|
{ 300L, IDS_BAUD_300 },
|
|
{ 1200L, IDS_BAUD_1200 },
|
|
{ 2400L, IDS_BAUD_2400 },
|
|
{ 4800L, IDS_BAUD_4800 },
|
|
{ 9600L, IDS_BAUD_9600 },
|
|
{ 19200, IDS_BAUD_19200 },
|
|
{ 38400, IDS_BAUD_38400 },
|
|
{ 57600, IDS_BAUD_57600 },
|
|
{ 115200, IDS_BAUD_115200 },
|
|
{ 230400, IDS_BAUD_230400 },
|
|
{ 460800, IDS_BAUD_460800 },
|
|
{ 921600, IDS_BAUD_921600 },
|
|
};
|
|
|
|
// Command IDs for the parity listbox
|
|
#define CMD_PARITY_EVEN 1
|
|
#define CMD_PARITY_ODD 2
|
|
#define CMD_PARITY_NONE 3
|
|
#define CMD_PARITY_MARK 4
|
|
#define CMD_PARITY_SPACE 5
|
|
|
|
// Command IDs for the flow control listbox
|
|
#define CMD_FLOWCTL_XONXOFF 1
|
|
#define CMD_FLOWCTL_HARDWARE 2
|
|
#define CMD_FLOWCTL_NONE 3
|
|
|
|
// This table is the generic port settings table
|
|
// that is used to fill the various listboxes
|
|
typedef struct _PortValues
|
|
{
|
|
union {
|
|
BYTE bytesize;
|
|
BYTE cmd;
|
|
BYTE stopbits;
|
|
};
|
|
int ids;
|
|
} PortValues, FAR * LPPORTVALUES;
|
|
|
|
|
|
#pragma data_seg(DATASEG_READONLY)
|
|
|
|
// This is the structure that is used to fill the data bits listbox
|
|
static PortValues s_rgbytesize[] = {
|
|
{ 5, IDS_BYTESIZE_5 },
|
|
{ 6, IDS_BYTESIZE_6 },
|
|
{ 7, IDS_BYTESIZE_7 },
|
|
{ 8, IDS_BYTESIZE_8 },
|
|
};
|
|
|
|
// This is the structure that is used to fill the parity listbox
|
|
static PortValues s_rgparity[] = {
|
|
{ CMD_PARITY_EVEN, IDS_PARITY_EVEN },
|
|
{ CMD_PARITY_ODD, IDS_PARITY_ODD },
|
|
{ CMD_PARITY_NONE, IDS_PARITY_NONE },
|
|
{ CMD_PARITY_MARK, IDS_PARITY_MARK },
|
|
{ CMD_PARITY_SPACE, IDS_PARITY_SPACE },
|
|
};
|
|
|
|
// This is the structure that is used to fill the stopbits listbox
|
|
static PortValues s_rgstopbits[] = {
|
|
{ ONESTOPBIT, IDS_STOPBITS_1 },
|
|
{ ONE5STOPBITS, IDS_STOPBITS_1_5 },
|
|
{ TWOSTOPBITS, IDS_STOPBITS_2 },
|
|
};
|
|
|
|
// This is the structure that is used to fill the flow control listbox
|
|
static PortValues s_rgflowctl[] = {
|
|
{ CMD_FLOWCTL_XONXOFF, IDS_FLOWCTL_XONXOFF },
|
|
{ CMD_FLOWCTL_HARDWARE, IDS_FLOWCTL_HARDWARE },
|
|
{ CMD_FLOWCTL_NONE, IDS_FLOWCTL_NONE },
|
|
};
|
|
|
|
#pragma data_seg()
|
|
|
|
|
|
typedef struct tagPORT
|
|
{
|
|
HWND hdlg; // dialog handle
|
|
HWND hwndBaudRate;
|
|
HWND hwndDataBits;
|
|
HWND hwndParity;
|
|
HWND hwndStopBits;
|
|
HWND hwndFlowCtl;
|
|
|
|
LPPORTINFO pportinfo; // pointer to shared working buffer
|
|
|
|
} PORT, FAR * PPORT;
|
|
|
|
|
|
// This structure contains the default settings for the dialog
|
|
static struct _DefPortSettings
|
|
{
|
|
int iSelBaud;
|
|
int iSelDataBits;
|
|
int iSelParity;
|
|
int iSelStopBits;
|
|
int iSelFlowCtl;
|
|
} s_defportsettings;
|
|
|
|
// These are default settings
|
|
#define DEFAULT_BAUDRATE 9600L
|
|
#define DEFAULT_BYTESIZE 8
|
|
#define DEFAULT_PARITY CMD_PARITY_NONE
|
|
#define DEFAULT_STOPBITS ONESTOPBIT
|
|
#define DEFAULT_FLOWCTL CMD_FLOWCTL_NONE
|
|
|
|
|
|
#define Port_GetPtr(hwnd) (PPORT)GetWindowLongPtr(hwnd, DWLP_USER)
|
|
#define Port_SetPtr(hwnd, lp) (PPORT)SetWindowLongPtr(hwnd, DWLP_USER, (ULONG_PTR)(lp))
|
|
|
|
UINT WINAPI FeFiFoFum(HWND hwndOwner, LPCTSTR pszPortName);
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Fills the baud rate combobox with the possible baud
|
|
rates that Windows supports.
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Port_FillBaud(
|
|
PPORT this)
|
|
{
|
|
HWND hwndCB = this->hwndBaudRate;
|
|
WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
|
|
int i;
|
|
int n;
|
|
int iMatch = -1;
|
|
int iDef = -1;
|
|
int iSel;
|
|
TCHAR sz[MAXMEDLEN];
|
|
|
|
// Fill the listbox
|
|
for (i = 0; i < ARRAYSIZE(g_rgbauds); i++)
|
|
{
|
|
n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, g_rgbauds[i].ids, sz, SIZECHARS(sz)));
|
|
ComboBox_SetItemData(hwndCB, n, g_rgbauds[i].dwDTERate);
|
|
|
|
// Keep our eyes peeled for important values
|
|
if (DEFAULT_BAUDRATE == g_rgbauds[i].dwDTERate)
|
|
{
|
|
iDef = n;
|
|
}
|
|
if (pdcb->BaudRate == g_rgbauds[i].dwDTERate)
|
|
{
|
|
iMatch = n;
|
|
}
|
|
}
|
|
|
|
ASSERT(-1 != iDef);
|
|
s_defportsettings.iSelBaud = iDef;
|
|
|
|
// Does the DCB baudrate exist in our list of baud rates?
|
|
if (-1 == iMatch)
|
|
{
|
|
// No; choose the default
|
|
iSel = iDef;
|
|
}
|
|
else
|
|
{
|
|
// Yes; choose the matched value
|
|
ASSERT(-1 != iMatch);
|
|
iSel = iMatch;
|
|
}
|
|
ComboBox_SetCurSel(hwndCB, iSel);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Fills the bytesize combobox with the possible byte sizes.
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Port_FillDataBits(
|
|
PPORT this)
|
|
{
|
|
HWND hwndCB = this->hwndDataBits;
|
|
WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
|
|
int i;
|
|
int iSel;
|
|
int n;
|
|
int iMatch = -1;
|
|
int iDef = -1;
|
|
TCHAR sz[MAXMEDLEN];
|
|
|
|
// Fill the listbox
|
|
for (i = 0; i < ARRAYSIZE(s_rgbytesize); i++)
|
|
{
|
|
n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgbytesize[i].ids, sz, SIZECHARS(sz)));
|
|
ComboBox_SetItemData(hwndCB, n, s_rgbytesize[i].bytesize);
|
|
|
|
// Keep our eyes peeled for important values
|
|
if (DEFAULT_BYTESIZE == s_rgbytesize[i].bytesize)
|
|
{
|
|
iDef = n;
|
|
}
|
|
if (pdcb->ByteSize == s_rgbytesize[i].bytesize)
|
|
{
|
|
iMatch = n;
|
|
}
|
|
}
|
|
|
|
ASSERT(-1 != iDef);
|
|
s_defportsettings.iSelDataBits = iDef;
|
|
|
|
// Does the DCB value exist in our list?
|
|
if (-1 == iMatch)
|
|
{
|
|
// No; choose the default
|
|
iSel = iDef;
|
|
}
|
|
else
|
|
{
|
|
// Yes; choose the matched value
|
|
ASSERT(-1 != iMatch);
|
|
iSel = iMatch;
|
|
}
|
|
ComboBox_SetCurSel(hwndCB, iSel);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Fills the parity combobox with the possible settings.
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Port_FillParity(
|
|
PPORT this)
|
|
{
|
|
HWND hwndCB = this->hwndParity;
|
|
WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
|
|
int i;
|
|
int iSel;
|
|
int n;
|
|
int iMatch = -1;
|
|
int iDef = -1;
|
|
TCHAR sz[MAXMEDLEN];
|
|
|
|
// Fill the listbox
|
|
for (i = 0; i < ARRAYSIZE(s_rgparity); i++)
|
|
{
|
|
n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgparity[i].ids, sz, SIZECHARS(sz)));
|
|
ComboBox_SetItemData(hwndCB, n, s_rgparity[i].cmd);
|
|
|
|
// Keep our eyes peeled for important values
|
|
if (DEFAULT_PARITY == s_rgparity[i].cmd)
|
|
{
|
|
iDef = n;
|
|
}
|
|
switch (s_rgparity[i].cmd)
|
|
{
|
|
case CMD_PARITY_EVEN:
|
|
if (EVENPARITY == pdcb->Parity)
|
|
iMatch = n;
|
|
break;
|
|
|
|
case CMD_PARITY_ODD:
|
|
if (ODDPARITY == pdcb->Parity)
|
|
iMatch = n;
|
|
break;
|
|
|
|
case CMD_PARITY_NONE:
|
|
if (NOPARITY == pdcb->Parity)
|
|
iMatch = n;
|
|
break;
|
|
|
|
case CMD_PARITY_MARK:
|
|
if (MARKPARITY == pdcb->Parity)
|
|
iMatch = n;
|
|
break;
|
|
|
|
case CMD_PARITY_SPACE:
|
|
if (SPACEPARITY == pdcb->Parity)
|
|
iMatch = n;
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
ASSERT(-1 != iDef);
|
|
s_defportsettings.iSelParity = iDef;
|
|
|
|
// Does the DCB value exist in our list?
|
|
if (-1 == iMatch)
|
|
{
|
|
// No; choose the default
|
|
iSel = iDef;
|
|
}
|
|
else
|
|
{
|
|
// Yes; choose the matched value
|
|
ASSERT(-1 != iMatch);
|
|
iSel = iMatch;
|
|
}
|
|
ComboBox_SetCurSel(hwndCB, iSel);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Fills the stopbits combobox with the possible settings.
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Port_FillStopBits(
|
|
PPORT this)
|
|
{
|
|
HWND hwndCB = this->hwndStopBits;
|
|
WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
|
|
int i;
|
|
int iSel;
|
|
int n;
|
|
int iMatch = -1;
|
|
int iDef = -1;
|
|
TCHAR sz[MAXMEDLEN];
|
|
|
|
// Fill the listbox
|
|
for (i = 0; i < ARRAYSIZE(s_rgstopbits); i++)
|
|
{
|
|
n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgstopbits[i].ids, sz, SIZECHARS(sz)));
|
|
ComboBox_SetItemData(hwndCB, n, s_rgstopbits[i].stopbits);
|
|
|
|
// Keep our eyes peeled for important values
|
|
if (DEFAULT_STOPBITS == s_rgstopbits[i].stopbits)
|
|
{
|
|
iDef = n;
|
|
}
|
|
if (pdcb->StopBits == s_rgstopbits[i].stopbits)
|
|
{
|
|
iMatch = n;
|
|
}
|
|
}
|
|
|
|
ASSERT(-1 != iDef);
|
|
s_defportsettings.iSelStopBits = iDef;
|
|
|
|
// Does the DCB value exist in our list?
|
|
if (-1 == iMatch)
|
|
{
|
|
// No; choose the default
|
|
iSel = iDef;
|
|
}
|
|
else
|
|
{
|
|
// Yes; choose the matched value
|
|
ASSERT(-1 != iMatch);
|
|
iSel = iMatch;
|
|
}
|
|
ComboBox_SetCurSel(hwndCB, iSel);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Fills the flow control combobox with the possible settings.
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Port_FillFlowCtl(
|
|
PPORT this)
|
|
{
|
|
HWND hwndCB = this->hwndFlowCtl;
|
|
WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
|
|
int i;
|
|
int iSel;
|
|
int n;
|
|
int iMatch = -1;
|
|
int iDef = -1;
|
|
TCHAR sz[MAXMEDLEN];
|
|
|
|
// Fill the listbox
|
|
for (i = 0; i < ARRAYSIZE(s_rgflowctl); i++)
|
|
{
|
|
n = ComboBox_AddString(hwndCB, SzFromIDS(g_hinst, s_rgflowctl[i].ids, sz, SIZECHARS(sz)));
|
|
ComboBox_SetItemData(hwndCB, n, s_rgflowctl[i].cmd);
|
|
|
|
// Keep our eyes peeled for important values
|
|
if (DEFAULT_FLOWCTL == s_rgflowctl[i].cmd)
|
|
{
|
|
iDef = n;
|
|
}
|
|
switch (s_rgflowctl[i].cmd)
|
|
{
|
|
case CMD_FLOWCTL_XONXOFF:
|
|
if (TRUE == pdcb->fOutX && FALSE == pdcb->fOutxCtsFlow)
|
|
iMatch = n;
|
|
break;
|
|
|
|
case CMD_FLOWCTL_HARDWARE:
|
|
if (FALSE == pdcb->fOutX && TRUE == pdcb->fOutxCtsFlow)
|
|
iMatch = n;
|
|
break;
|
|
|
|
case CMD_FLOWCTL_NONE:
|
|
if (FALSE == pdcb->fOutX && FALSE == pdcb->fOutxCtsFlow)
|
|
iMatch = n;
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
ASSERT(-1 != iDef);
|
|
s_defportsettings.iSelFlowCtl = iDef;
|
|
|
|
// Does the DCB value exist in our list?
|
|
if (-1 == iMatch)
|
|
{
|
|
// No; choose the default
|
|
iSel = iDef;
|
|
}
|
|
else
|
|
{
|
|
// Yes; choose the matched value
|
|
ASSERT(-1 != iMatch);
|
|
iSel = iMatch;
|
|
}
|
|
ComboBox_SetCurSel(hwndCB, iSel);
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_INITDIALOG Handler
|
|
Returns: FALSE when we assign the control focus
|
|
Cond: --
|
|
*/
|
|
BOOL PRIVATE Port_OnInitDialog(
|
|
PPORT this,
|
|
HWND hwndFocus,
|
|
LPARAM lParam) // expected to be PROPSHEETINFO
|
|
{
|
|
LPPROPSHEETPAGE lppsp = (LPPROPSHEETPAGE)lParam;
|
|
HWND hwnd = this->hdlg;
|
|
|
|
ASSERT((LPTSTR)lppsp->lParam);
|
|
|
|
this->pportinfo = (LPPORTINFO)lppsp->lParam;
|
|
|
|
// Save away the window handles
|
|
this->hwndBaudRate = GetDlgItem(hwnd, IDC_PS_BAUDRATE);
|
|
this->hwndDataBits = GetDlgItem(hwnd, IDC_PS_DATABITS);
|
|
this->hwndParity = GetDlgItem(hwnd, IDC_PS_PARITY);
|
|
this->hwndStopBits = GetDlgItem(hwnd, IDC_PS_STOPBITS);
|
|
this->hwndFlowCtl = GetDlgItem(hwnd, IDC_PS_FLOWCTL);
|
|
|
|
Port_FillBaud(this);
|
|
Port_FillDataBits(this);
|
|
Port_FillParity(this);
|
|
Port_FillStopBits(this);
|
|
Port_FillFlowCtl(this);
|
|
|
|
#if !defined(SUPPORT_FIFO)
|
|
|
|
// Hide and disable the Advanced button
|
|
ShowWindow(GetDlgItem(hwnd, IDC_PS_ADVANCED), FALSE);
|
|
EnableWindow(GetDlgItem(hwnd, IDC_PS_ADVANCED), FALSE);
|
|
|
|
#endif
|
|
|
|
return TRUE; // allow USER to set the initial focus
|
|
}
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_COMMAND Handler
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Port_OnCommand(
|
|
PPORT this,
|
|
int id,
|
|
HWND hwndCtl,
|
|
UINT uNotifyCode)
|
|
{
|
|
HWND hwnd = this->hdlg;
|
|
|
|
switch (id)
|
|
{
|
|
case IDC_PS_PB_RESTORE:
|
|
// Set the values to the default settings
|
|
ComboBox_SetCurSel(this->hwndBaudRate, s_defportsettings.iSelBaud);
|
|
ComboBox_SetCurSel(this->hwndDataBits, s_defportsettings.iSelDataBits);
|
|
ComboBox_SetCurSel(this->hwndParity, s_defportsettings.iSelParity);
|
|
ComboBox_SetCurSel(this->hwndStopBits, s_defportsettings.iSelStopBits);
|
|
ComboBox_SetCurSel(this->hwndFlowCtl, s_defportsettings.iSelFlowCtl);
|
|
break;
|
|
|
|
#ifdef SUPPORT_FIFO
|
|
|
|
case IDC_PS_ADVANCED:
|
|
FeFiFoFum(this->hdlg, this->pportinfo->szFriendlyName);
|
|
break;
|
|
|
|
#endif
|
|
|
|
default:
|
|
switch (uNotifyCode) {
|
|
case CBN_SELCHANGE:
|
|
PropSheet_Changed(GetParent(hwnd), hwnd);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: PSN_APPLY handler
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void PRIVATE Port_OnApply(
|
|
PPORT this)
|
|
{
|
|
int iSel;
|
|
BYTE cmd;
|
|
WIN32DCB FAR * pdcb = &this->pportinfo->dcb;
|
|
|
|
// Determine new speed settings
|
|
iSel = ComboBox_GetCurSel(this->hwndBaudRate);
|
|
pdcb->BaudRate = (DWORD)ComboBox_GetItemData(this->hwndBaudRate, iSel);
|
|
|
|
|
|
// Determine new byte size
|
|
iSel = ComboBox_GetCurSel(this->hwndDataBits);
|
|
pdcb->ByteSize = (BYTE)ComboBox_GetItemData(this->hwndDataBits, iSel);
|
|
|
|
|
|
// Determine new parity settings
|
|
iSel = ComboBox_GetCurSel(this->hwndParity);
|
|
cmd = (BYTE)ComboBox_GetItemData(this->hwndParity, iSel);
|
|
switch (cmd)
|
|
{
|
|
case CMD_PARITY_EVEN:
|
|
pdcb->fParity = TRUE;
|
|
pdcb->Parity = EVENPARITY;
|
|
break;
|
|
|
|
case CMD_PARITY_ODD:
|
|
pdcb->fParity = TRUE;
|
|
pdcb->Parity = ODDPARITY;
|
|
break;
|
|
|
|
case CMD_PARITY_NONE:
|
|
pdcb->fParity = FALSE;
|
|
pdcb->Parity = NOPARITY;
|
|
break;
|
|
|
|
case CMD_PARITY_MARK:
|
|
pdcb->fParity = TRUE;
|
|
pdcb->Parity = MARKPARITY;
|
|
break;
|
|
|
|
case CMD_PARITY_SPACE:
|
|
pdcb->fParity = TRUE;
|
|
pdcb->Parity = SPACEPARITY;
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
|
|
// Determine new stopbits setting
|
|
iSel = ComboBox_GetCurSel(this->hwndStopBits);
|
|
pdcb->StopBits = (BYTE)ComboBox_GetItemData(this->hwndStopBits, iSel);
|
|
|
|
|
|
// Determine new flow control settings
|
|
iSel = ComboBox_GetCurSel(this->hwndFlowCtl);
|
|
cmd = (BYTE)ComboBox_GetItemData(this->hwndFlowCtl, iSel);
|
|
switch (cmd)
|
|
{
|
|
case CMD_FLOWCTL_XONXOFF:
|
|
pdcb->fOutX = TRUE;
|
|
pdcb->fInX = TRUE;
|
|
pdcb->fOutxCtsFlow = FALSE;
|
|
pdcb->fRtsControl = RTS_CONTROL_DISABLE;
|
|
break;
|
|
|
|
case CMD_FLOWCTL_HARDWARE:
|
|
pdcb->fOutX = FALSE;
|
|
pdcb->fInX = FALSE;
|
|
pdcb->fOutxCtsFlow = TRUE;
|
|
pdcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
|
|
break;
|
|
|
|
case CMD_FLOWCTL_NONE:
|
|
pdcb->fOutX = FALSE;
|
|
pdcb->fInX = FALSE;
|
|
pdcb->fOutxCtsFlow = FALSE;
|
|
pdcb->fRtsControl = RTS_CONTROL_DISABLE;
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0); // should never be here
|
|
break;
|
|
}
|
|
|
|
this->pportinfo->idRet = IDOK;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: WM_NOTIFY handler
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
LRESULT PRIVATE Port_OnNotify(
|
|
PPORT 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:
|
|
Port_OnApply(this);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return lRet;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////// EXPORTED FUNCTIONS
|
|
|
|
static BOOL s_bPortRecurse = FALSE;
|
|
|
|
LRESULT INLINE Port_DefProc(
|
|
HWND hDlg,
|
|
UINT msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
ENTER_X()
|
|
{
|
|
s_bPortRecurse = TRUE;
|
|
}
|
|
LEAVE_X()
|
|
|
|
return DefDlgProc(hDlg, msg, wParam, lParam);
|
|
}
|
|
|
|
// Context help header file and arrays for devmgr ports tab
|
|
// Created 2/21/98 by WGruber NTUA and DoronH NTDEV
|
|
|
|
//
|
|
// "Port Settings" Dialog Box
|
|
//
|
|
|
|
#define IDH_NOHELP ((DWORD)-1)
|
|
|
|
#define IDH_DEVMGR_PORTSET_ADVANCED 15840 // "&Advanced" (Button)
|
|
#define IDH_DEVMGR_PORTSET_BPS 15841 // "" (ComboBox)
|
|
#define IDH_DEVMGR_PORTSET_DATABITS 15842 // "" (ComboBox)
|
|
#define IDH_DEVMGR_PORTSET_PARITY 15843 // "" (ComboBox)
|
|
#define IDH_DEVMGR_PORTSET_STOPBITS 15844 // "" (ComboBox)
|
|
#define IDH_DEVMGR_PORTSET_FLOW 15845 // "" (ComboBox)
|
|
#define IDH_DEVMGR_PORTSET_DEFAULTS 15892 // "&Restore Defaults" (Button)
|
|
|
|
|
|
#pragma data_seg(DATASEG_READONLY)
|
|
const static DWORD rgHelpIDs[] = { // old winhelp IDs
|
|
IDC_STATIC, IDH_NOHELP,
|
|
IDC_PS_PORT, IDH_NOHELP,
|
|
IDC_PS_LBL_BAUDRATE, IDH_DEVMGR_PORTSET_BPS, // IDH_PORT_BAUD,
|
|
IDC_PS_BAUDRATE, IDH_DEVMGR_PORTSET_BPS, // IDH_PORT_BAUD,
|
|
IDC_PS_LBL_DATABITS, IDH_DEVMGR_PORTSET_DATABITS, // IDH_PORT_DATA,
|
|
IDC_PS_DATABITS, IDH_DEVMGR_PORTSET_DATABITS, // IDH_PORT_DATA,
|
|
IDC_PS_LBL_PARITY, IDH_DEVMGR_PORTSET_PARITY, // IDH_PORT_PARITY,
|
|
IDC_PS_PARITY, IDH_DEVMGR_PORTSET_PARITY, // IDH_PORT_PARITY,
|
|
IDC_PS_LBL_STOPBITS, IDH_DEVMGR_PORTSET_STOPBITS, // IDH_PORT_STOPBITS,
|
|
IDC_PS_STOPBITS, IDH_DEVMGR_PORTSET_STOPBITS, // IDH_PORT_STOPBITS,
|
|
IDC_PS_LBL_FLOWCTL, IDH_DEVMGR_PORTSET_FLOW, // IDH_PORT_FLOW,
|
|
IDC_PS_FLOWCTL, IDH_DEVMGR_PORTSET_FLOW, // IDH_PORT_FLOW,
|
|
IDC_PS_PB_RESTORE, IDH_DEVMGR_PORTSET_DEFAULTS, // IDH_PORT_RESTORE,
|
|
IDC_PS_ADVANCED, IDH_DEVMGR_PORTSET_ADVANCED,
|
|
0, 0 };
|
|
#pragma data_seg()
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Real dialog proc
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
LRESULT Port_DlgProc(
|
|
PPORT this,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
|
|
switch (message)
|
|
{
|
|
HANDLE_MSG(this, WM_INITDIALOG, Port_OnInitDialog);
|
|
HANDLE_MSG(this, WM_COMMAND, Port_OnCommand);
|
|
HANDLE_MSG(this, WM_NOTIFY, Port_OnNotify);
|
|
|
|
case WM_HELP:
|
|
WinHelp(((LPHELPINFO)lParam)->hItemHandle, c_szWinHelpFile, HELP_WM_HELP, (ULONG_PTR)(LPVOID)rgHelpIDs);
|
|
return 0;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WinHelp((HWND)wParam, c_szWinHelpFile, HELP_CONTEXTMENU, (ULONG_PTR)(LPVOID)rgHelpIDs);
|
|
return 0;
|
|
|
|
default:
|
|
return Port_DefProc(this->hdlg, message, wParam, lParam);
|
|
}
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Dialog Wrapper
|
|
Returns: varies
|
|
Cond: --
|
|
*/
|
|
INT_PTR CALLBACK Port_WrapperProc(
|
|
HWND hDlg, // std params
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
PPORT this;
|
|
|
|
// Cool windowsx.h dialog technique. For full explanation, see
|
|
// WINDOWSX.TXT. This supports multiple-instancing of dialogs.
|
|
//
|
|
ENTER_X()
|
|
{
|
|
if (s_bPortRecurse)
|
|
{
|
|
s_bPortRecurse = FALSE;
|
|
LEAVE_X()
|
|
return FALSE;
|
|
}
|
|
}
|
|
LEAVE_X()
|
|
|
|
this = Port_GetPtr(hDlg);
|
|
if (this == NULL)
|
|
{
|
|
if (message == WM_INITDIALOG)
|
|
{
|
|
this = (PPORT)LocalAlloc(LPTR, sizeof(PORT));
|
|
if (!this)
|
|
{
|
|
MsgBox(g_hinst,
|
|
hDlg,
|
|
MAKEINTRESOURCE(IDS_OOM_PORT),
|
|
MAKEINTRESOURCE(IDS_CAP_PORT),
|
|
NULL,
|
|
MB_ERROR);
|
|
EndDialog(hDlg, IDCANCEL);
|
|
return (BOOL)Port_DefProc(hDlg, message, wParam, lParam);
|
|
}
|
|
this->hdlg = hDlg;
|
|
Port_SetPtr(hDlg, this);
|
|
}
|
|
else
|
|
{
|
|
return (BOOL)Port_DefProc(hDlg, message, wParam, lParam);
|
|
}
|
|
}
|
|
|
|
if (message == WM_DESTROY)
|
|
{
|
|
Port_DlgProc(this, message, wParam, lParam);
|
|
LocalFree((HLOCAL)OFFSETOF(this));
|
|
Port_SetPtr(hDlg, NULL);
|
|
return 0;
|
|
}
|
|
|
|
return SetDlgMsgResult(hDlg, message, Port_DlgProc(this, message, wParam, lParam));
|
|
}
|
|
|
|
|
|
#ifdef SUPPORT_FIFO
|
|
|
|
//
|
|
// Advanced Port Settings
|
|
//
|
|
|
|
#pragma data_seg(DATASEG_READONLY)
|
|
|
|
// Fifo related strings
|
|
|
|
TCHAR const FAR c_szSettings[] = TEXT("Settings");
|
|
TCHAR const FAR c_szComxFifo[] = TEXT("Fifo");
|
|
TCHAR const FAR c_szEnh[] = TEXT("386Enh");
|
|
TCHAR const FAR c_szSystem[] = TEXT("system.ini");
|
|
|
|
//
|
|
// "Advanced Communications Port Properties" Dialog Box
|
|
//
|
|
#define IDH_DEVMGR_PORTSET_ADV_USEFIFO 16885 // "&Use FIFO buffers (requires 16550 compatible UART)" (Button)
|
|
#define IDH_DEVMGR_PORTSET_ADV_TRANS 16842 // "" (msctls_trackbar32)
|
|
// #define IDH_DEVMGR_PORTSET_ADV_DEVICES 161027 // "" (ComboBox)
|
|
#define IDH_DEVMGR_PORTSET_ADV_RECV 16821 // "" (msctls_trackbar32)
|
|
// #define IDH_DEVMGR_PORTSET_ADV_NUMBER 16846 // "" (ComboBox)
|
|
#define IDH_DEVMGR_PORTSET_ADV_DEFAULTS 16844
|
|
|
|
|
|
const DWORD rgAdvHelpIDs[] =
|
|
{
|
|
IDC_STATIC IDW_NOHELP,
|
|
|
|
IDC_FIFO_USAGE, IDH_DEVMGR_PORTSET_ADV_USEFIFO, // "Use FIFO buffers (requires 16550 compatible UART)" (Button)
|
|
|
|
IDC_LBL_RXFIFO, IDH_NOHELP, // "&Receive Buffer:" (Static)
|
|
IDC_RXFIFO_USAGE, IDH_DEVMGR_PORTSET_ADV_RECV, // "" (msctls_trackbar32)
|
|
IDC_LBL_RXFIFO_LO, IDH_NOHELP, // "Low (%d)" (Static)
|
|
IDC_LBL_RXFIFO_HI, IDH_NOHELP, // "High (%d)" (Static)
|
|
|
|
IDC_LBL_TXFIFO, IDH_NOHELP, // "&Transmit Buffer:" (Static)
|
|
IDC_TXFIFO_USAGE, IDH_DEVMGR_PORTSET_ADV_TRANS, // "" (msctls_trackbar32)
|
|
IDC_LBL_TXFIFO_LO, IDH_NOHELP, // "Low (%d)" (Static)
|
|
IDC_LBL_TXFIFO_HI, IDH_NOHELP, // "High (%d)" (Static)
|
|
|
|
IDC_DEFAULTS, IDH_DEVMGR_PORTSET_ADV_DEFAULTS,// "&Restore Defaults" (Button)
|
|
0, 0
|
|
};
|
|
|
|
#pragma data_seg()
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Set the dialog controls
|
|
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void DisplayAdvSettings(
|
|
HWND hDlg,
|
|
BYTE RxTrigger,
|
|
BYTE TxTrigger,
|
|
BOOL bUseFifo)
|
|
{
|
|
SendDlgItemMessage(hDlg, IDC_RXFIFO_USAGE, TBM_SETRANGE, 0, 0x30000);
|
|
SendDlgItemMessage(hDlg, IDC_TXFIFO_USAGE, TBM_SETRANGE, 0, 0x30000);
|
|
|
|
// Use FIFO?
|
|
if ( !bUseFifo )
|
|
{
|
|
// No
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_LO), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_HI), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_RXFIFO_USAGE), FALSE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_LO), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_HI), FALSE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_TXFIFO_USAGE), FALSE);
|
|
CheckDlgButton(hDlg, IDC_FIFO_USAGE, FALSE);
|
|
}
|
|
else
|
|
{
|
|
CheckDlgButton(hDlg, IDC_FIFO_USAGE, TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_LO), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_HI), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_RXFIFO_USAGE), TRUE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_LO), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_HI), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_TXFIFO_USAGE), TRUE);
|
|
SendDlgItemMessage(hDlg, IDC_RXFIFO_USAGE, TBM_SETPOS,
|
|
TRUE, RxTrigger);
|
|
SendDlgItemMessage(hDlg, IDC_TXFIFO_USAGE, TBM_SETPOS,
|
|
TRUE, TxTrigger/4);
|
|
}
|
|
}
|
|
|
|
|
|
typedef struct tagSETTINGS
|
|
{
|
|
BYTE fifoon;
|
|
BYTE txfifosize;
|
|
BYTE dsron;
|
|
BYTE rxtriggersize;
|
|
} SETTINGS;
|
|
|
|
typedef enum
|
|
{
|
|
ACT_GET,
|
|
ACT_SET
|
|
} ACTION;
|
|
|
|
BYTE RxTriggerValues[4]={0,0x40,0x80,0xC0};
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Gets or sets the advanced settings of the port
|
|
|
|
Returns: --
|
|
Cond: --
|
|
*/
|
|
void GetSetAdvSettings(
|
|
LPCTSTR pszPortName,
|
|
BYTE FAR *RxTrigger,
|
|
BYTE FAR *TxTrigger,
|
|
BOOL FAR * pbUseFifo,
|
|
ACTION action)
|
|
{
|
|
LPFINDDEV pfd;
|
|
DWORD cbData;
|
|
SETTINGS settings;
|
|
TCHAR szFifo[256];
|
|
TCHAR OnStr[2] = TEXT("0");
|
|
|
|
ASSERT(pszPortName);
|
|
|
|
// In Win95, the FIFO settings were (wrongfully) stored in the
|
|
// device key. I've changed this to look in the driver key.
|
|
// (scotth)
|
|
|
|
if (FindDev_Create(&pfd, c_pguidPort, c_szFriendlyName, pszPortName) ||
|
|
FindDev_Create(&pfd, c_pguidPort, c_szPortName, pszPortName) ||
|
|
FindDev_Create(&pfd, c_pguidModem, c_szPortName, pszPortName))
|
|
{
|
|
switch (action)
|
|
{
|
|
case ACT_GET:
|
|
ASSERT(4 == sizeof(SETTINGS));
|
|
|
|
cbData = sizeof(SETTINGS);
|
|
if (ERROR_SUCCESS != RegQueryValueEx(pfd->hkeyDrv, c_szSettings, NULL,
|
|
NULL, (LPBYTE)&settings, &cbData))
|
|
{
|
|
// Default settings if not in registry
|
|
settings.fifoon = 0x02;
|
|
settings.dsron = 0;
|
|
settings.txfifosize = 16;
|
|
settings.rxtriggersize = 0x80;
|
|
}
|
|
if (!settings.fifoon)
|
|
*pbUseFifo = FALSE;
|
|
else
|
|
*pbUseFifo = TRUE;
|
|
settings.rxtriggersize = settings.rxtriggersize % 0xC1;
|
|
*RxTrigger = settings.rxtriggersize/0x40;
|
|
*TxTrigger = settings.txfifosize % 17;
|
|
break;
|
|
|
|
case ACT_SET:
|
|
if (FALSE == *pbUseFifo)
|
|
settings.fifoon = 0;
|
|
else
|
|
settings.fifoon = 2;
|
|
|
|
settings.rxtriggersize = RxTriggerValues[*RxTrigger];
|
|
settings.dsron = 0;
|
|
settings.txfifosize = (*TxTrigger)*5+1;
|
|
RegSetValueEx(pfd->hkeyDrv, c_szSettings, 0, REG_BINARY,
|
|
(LPBYTE)&settings, sizeof(SETTINGS));
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
|
|
cbData = sizeof(szFifo) - 6; // leave room for "fifo" on the end
|
|
RegQueryValueEx(pfd->hkeyDrv, c_szPortName, NULL, NULL, (LPBYTE)szFifo,
|
|
&cbData);
|
|
|
|
FindDev_Destroy(pfd);
|
|
|
|
lstrcat(szFifo, c_szComxFifo);
|
|
if (*pbUseFifo)
|
|
WritePrivateProfileString(c_szEnh, szFifo, NULL, c_szSystem);
|
|
else
|
|
WritePrivateProfileString(c_szEnh, szFifo, OnStr, c_szSystem);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Dialog proc for advanced port settings
|
|
|
|
Returns: standard
|
|
Cond: --
|
|
*/
|
|
BOOL CALLBACK AdvPort_DlgProc(
|
|
HWND hDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
BYTE rxtrigger, txtrigger;
|
|
BOOL bUseFifo;
|
|
LPCTSTR pszPortName;
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
pszPortName = (LPCTSTR)lParam;
|
|
SetWindowLongPtr(hDlg, DWLP_USER, (ULONG_PTR)pszPortName);
|
|
|
|
GetSetAdvSettings(pszPortName, &rxtrigger, &txtrigger, &bUseFifo, ACT_GET);
|
|
DisplayAdvSettings(hDlg, rxtrigger, txtrigger, bUseFifo);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
pszPortName = (LPCTSTR)GetWindowLongPtr(hDlg, DWLP_USER);
|
|
if (!pszPortName)
|
|
{
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
|
|
switch (wParam)
|
|
{
|
|
case IDOK:
|
|
if (IsDlgButtonChecked(hDlg, IDC_FIFO_USAGE))
|
|
bUseFifo = TRUE;
|
|
else
|
|
bUseFifo = FALSE;
|
|
|
|
rxtrigger = (BYTE)SendDlgItemMessage(hDlg,
|
|
IDC_RXFIFO_USAGE, TBM_GETPOS, 0, 0);
|
|
txtrigger = (BYTE)SendDlgItemMessage(hDlg,
|
|
IDC_TXFIFO_USAGE, TBM_GETPOS, 0, 0);
|
|
|
|
GetSetAdvSettings(pszPortName, &rxtrigger, &txtrigger, &bUseFifo, ACT_SET);
|
|
|
|
// Fall thru
|
|
// | |
|
|
// v v
|
|
|
|
case IDCANCEL:
|
|
EndDialog(hDlg, IDOK == wParam);
|
|
break;
|
|
|
|
case IDC_FIFO_USAGE:
|
|
if (!IsDlgButtonChecked(hDlg, IDC_FIFO_USAGE))
|
|
DisplayAdvSettings(hDlg, 0, 0, FALSE);
|
|
else
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_LO), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_RXFIFO_HI), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_RXFIFO_USAGE), TRUE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_LO), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_LBL_TXFIFO_HI), TRUE);
|
|
EnableWindow(GetDlgItem(hDlg, IDC_TXFIFO_USAGE), TRUE);
|
|
}
|
|
break;
|
|
|
|
case IDC_DEFAULTS:
|
|
DisplayAdvSettings(hDlg, 2, 12, TRUE);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_HELP:
|
|
WinHelp(((LPHELPINFO)lParam)->hItemHandle, c_szWinHelpFile, HELP_WM_HELP, (DWORD)(LPVOID)rgAdvHelpIDs);
|
|
return 0;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WinHelp((HWND)wParam, c_szWinHelpFile, HELP_CONTEXTMENU, (DWORD)(LPVOID)rgAdvHelpIDs);
|
|
return 0;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Private entry point to show the Advanced Fifo dialog
|
|
|
|
Returns: IDOK or IDCANCEL
|
|
|
|
Cond: --
|
|
*/
|
|
UINT WINAPI FeFiFoFum(
|
|
HWND hwndOwner,
|
|
LPCTSTR pszPortName)
|
|
{
|
|
UINT uRet = (UINT)-1;
|
|
|
|
// Invoke the advanced dialog
|
|
if (pszPortName)
|
|
{
|
|
uRet = DialogBoxParam(g_hinst, MAKEINTRESOURCE(IDD_ADV_PORT),
|
|
hwndOwner, AdvPort_DlgProc, (LPARAM)pszPortName);
|
|
}
|
|
return uRet;
|
|
}
|
|
|
|
#endif // SUPPORT_FIFO
|