//--------------------------------------------------------------------------- // // 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