reactos/dll/win32/serialui/serialui.c

417 lines
9.7 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS SerialUI DLL
* FILE: serialui.c
* PUROPSE: A dialog box to configure COM port.
* Functions to set (and get too) default configuration.
* PROGRAMMERS: Saveliy Tretiakov (saveliyt@mail.ru)
* REVISIONS:
* ST (05/04/2005) Created. Implemented drvCommConfigDialog.
*/
#include "serialui.h"
static HINSTANCE hDllInstance;
/************************************
*
* DATA
*
************************************/
const DWORD Bauds[] = {
CBR_110,
CBR_300,
CBR_600,
CBR_1200,
CBR_2400,
CBR_4800,
CBR_9600,
CBR_14400,
CBR_19200,
CBR_38400,
CBR_56000,
CBR_57600,
CBR_115200,
CBR_128000,
CBR_256000,
0
};
const BYTE ByteSizes[] = {
5,
6,
7,
8,
0
};
const PARITY_INFO Parities[] = {
{ EVENPARITY, IDS_EVENPARITY },
{ MARKPARITY, IDS_MARKPARITY },
{ NOPARITY, IDS_NOPARITY },
{ ODDPARITY, IDS_ODDPARITY },
{ SPACEPARITY, IDS_SPACEPARITY },
{ 0, 0 }
};
const STOPBIT_INFO StopBits[] = {
{ ONESTOPBIT, IDS_ONESTOPBIT },
{ ONE5STOPBITS, IDS_ONE5STOPBITS },
{ TWOSTOPBITS, IDS_TWOSTOPBITS },
{ 0, 0 }
};
/************************************
*
* DLLMAIN
*
************************************/
BOOL
WINAPI
DllMain(HINSTANCE hInstance,
DWORD dwReason,
LPVOID reserved)
{
if(dwReason==DLL_PROCESS_ATTACH)
{
hDllInstance = hInstance;
}
else if(dwReason==DLL_THREAD_ATTACH)
{
DisableThreadLibraryCalls(hInstance);
}
return TRUE;
}
/************************************
*
* EXPORTS
*
************************************/
/*
* @implemented
*/
DWORD WINAPI drvCommConfigDialogW(LPCWSTR lpszDevice,
HWND hWnd,
LPCOMMCONFIG lpCommConfig)
{
DIALOG_INFO DialogInfo;
if(!lpszDevice || !lpCommConfig)
{
return ERROR_INVALID_PARAMETER;
}
DialogInfo.lpszDevice = lpszDevice;
DialogInfo.lpCC = lpCommConfig;
return DialogBoxParamW(hDllInstance, MAKEINTRESOURCEW(IDD_COMMDLG),
hWnd, CommDlgProc, (LPARAM)&DialogInfo);
}
/*
* @implemented
*/
DWORD WINAPI drvCommConfigDialogA(LPCSTR lpszDevice,
HWND hWnd,
LPCOMMCONFIG lpCommConfig)
{
BOOL result;
UINT len;
WCHAR *wstr;
len = MultiByteToWideChar(CP_ACP, 0, lpszDevice, -1, NULL, 0);
if((wstr = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR))))
{
MultiByteToWideChar(CP_ACP, 0, lpszDevice, -1, wstr, len);
result = drvCommConfigDialogW(wstr, hWnd, lpCommConfig);
HeapFree(GetProcessHeap(), 0, wstr);
return result;
}
else
return ERROR_NOT_ENOUGH_MEMORY;
}
/*
* @unimplemented
*/
DWORD WINAPI drvSetDefaultCommConfigW(LPCWSTR lpszDevice,
LPCOMMCONFIG lpCommConfig,
DWORD dwSize)
{
UNIMPLEMENTED
}
/*
* @unimplemented
*/
DWORD WINAPI drvSetDefaultCommConfigA(LPCSTR lpszDevice,
LPCOMMCONFIG lpCommConfig,
DWORD dwSize)
{
UNIMPLEMENTED
}
/*
* @unimplemented
*/
DWORD WINAPI drvGetDefaultCommConfigW(LPCWSTR lpszDevice,
LPCOMMCONFIG lpCommConfig,
LPDWORD lpdwSize)
{
UNIMPLEMENTED
}
/*
* @unimplemented
*/
DWORD WINAPI drvGetDefaultCommConfigA(LPCSTR lpszDevice,
LPCOMMCONFIG lpCommConfig,
LPDWORD lpdwSize)
{
UNIMPLEMENTED
}
/************************************
*
* INTERNALS
*
************************************/
INT_PTR
CALLBACK
CommDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
LPDIALOG_INFO lpDlgInfo = NULL;
HWND hBox;
switch (Msg)
{
case WM_INITDIALOG:
{
WCHAR wstr[255];
RECT rc, rcDlg, rcOwner;
HWND hOwner;
INT i;
lpDlgInfo = (LPDIALOG_INFO)lParam;
SetWindowLongPtrW(hDlg, DWL_USER, (LONG_PTR)lpDlgInfo);
/* Set title */
if(LoadStringW(hDllInstance, IDS_TITLE, wstr, sizeof(wstr) / sizeof(wstr[0])))
{
SetWindowTextW(hDlg, wstr);
}
/* FIXME - this won't work correctly systems with multiple monitors! */
if(!(hOwner = GetParent(hDlg)))
hOwner = GetDesktopWindow();
/* Position dialog in the center of owner window */
GetWindowRect(hOwner, &rcOwner);
GetWindowRect(hDlg, &rcDlg);
CopyRect(&rc, &rcOwner);
OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
OffsetRect(&rc, -rc.left, -rc.top);
OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
SetWindowPos(hDlg, HWND_TOP,
rcOwner.left + (rc.right / 2),
rcOwner.top + (rc.bottom / 2),
0, 0, SWP_NOSIZE);
/* Initialize baud rate combo */
if(!(hBox = GetDlgItem(hDlg, IDC_BAUDRATE)))
EndDialog(hDlg, ERROR_CANCELLED);
for(i = 0; Bauds[i]; i++)
{
wsprintf(wstr, L"%d", Bauds[i]);
SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr);
if(Bauds[i] == lpDlgInfo->lpCC->dcb.BaudRate)
SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0);
}
if(SendMessageW(hBox, CB_GETCURSEL, 0, 0) == CB_ERR)
SendMessageW(hBox, CB_SETCURSEL, DEFAULT_BAUD_INDEX, 0);
/* Initialize byte size combo */
if(!(hBox = GetDlgItem(hDlg, IDC_BYTESIZE)))
EndDialog(hDlg, ERROR_CANCELLED);
for(i = 0; ByteSizes[i]; i++)
{
wsprintf(wstr, L"%d", Bauds[i]);
SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr);
if(ByteSizes[i] == lpDlgInfo->lpCC->dcb.ByteSize)
SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0);
}
if(SendMessageW(hBox, CB_GETCURSEL, 0, 0) == CB_ERR)
SendMessageW(hBox, CB_SETCURSEL, DEFAULT_BYTESIZE_INDEX, 0);
/* Initialize parity combo */
if(!(hBox = GetDlgItem(hDlg, IDC_PARITY)))
EndDialog(hDlg, ERROR_CANCELLED);
for(i = 0; Parities[i].StrId; i++)
{
if(LoadStringW(hDllInstance, Parities[i].StrId, wstr, sizeof(wstr) / sizeof(wstr[0])))
{
SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr);
if(Parities[i].Parity == lpDlgInfo->lpCC->dcb.Parity)
SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0);
}
}
if(SendMessageW(hBox, CB_GETCURSEL, 0, 0)==CB_ERR)
SendMessageW(hBox, CB_SETCURSEL, DEFAULT_PARITY_INDEX, 0);
/* Initialize stop bits combo */
if(!(hBox = GetDlgItem(hDlg, IDC_STOPBITS)))
EndDialog(hDlg, ERROR_CANCELLED);
for(i = 0; StopBits[i].StrId; i++)
{
if(LoadStringW(hDllInstance, StopBits[i].StrId, wstr, sizeof(wstr) / sizeof(wstr[0])))
{
SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr);
if(StopBits[i].StopBit == lpDlgInfo->lpCC->dcb.StopBits)
SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0);
}
}
if(SendMessageW(hBox, CB_GETCURSEL, 0, 0)==CB_ERR)
SendMessageW(hBox, CB_SETCURSEL, DEFAULT_STOPBITS_INDEX, 0);
/* Initialize flow control combo */
if(!(hBox = GetDlgItem(hDlg, IDC_FLOW)))
EndDialog(hDlg, ERROR_CANCELLED);
if(LoadStringW(hDllInstance, IDS_FC_NO, wstr, sizeof(wstr) / sizeof(wstr[0])))
{
SendMessageW(hBox, CB_INSERTSTRING, 0, (LPARAM)wstr);
SendMessageW(hBox, CB_SETCURSEL, 0, 0);
lpDlgInfo->InitialFlowIndex = 0;
}
if(LoadStringW(hDllInstance, IDS_FC_CTSRTS, wstr, sizeof(wstr) / sizeof(wstr[0])))
{
SendMessageW(hBox, CB_INSERTSTRING, 1, (LPARAM)wstr);
if(lpDlgInfo->lpCC->dcb.fRtsControl == RTS_CONTROL_HANDSHAKE
|| lpDlgInfo->lpCC->dcb.fOutxCtsFlow != FALSE)
{
SendMessageW(hBox, CB_SETCURSEL, 1, 0);
lpDlgInfo->InitialFlowIndex = 1;
}
}
if(LoadStringW(hDllInstance, IDS_FC_XONXOFF, wstr, sizeof(wstr) / sizeof(wstr[0])))
{
SendMessageW(hBox, CB_INSERTSTRING, 2, (LPARAM)wstr);
if(lpDlgInfo->lpCC->dcb.fOutX || lpDlgInfo->lpCC->dcb.fInX)
{
SendMessageW(hBox, CB_SETCURSEL, 2, 0);
lpDlgInfo->InitialFlowIndex = 2;
}
}
/* Set focus */
SetFocus(GetDlgItem(hDlg, IDC_OKBTN));
return FALSE;
} /* WM_INITDIALOG */
case WM_COMMAND:
{
switch(wParam)
{
case IDC_CANCELBTN:
EndDialog(hDlg, ERROR_CANCELLED);
break;
case IDC_OKBTN:
OkButton(hDlg);
EndDialog(hDlg, ERROR_SUCCESS);
break;
}
return TRUE;
} /* WM_COMMAND */
case WM_CLOSE:
{
EndDialog(hDlg, ERROR_CANCELLED);
return TRUE;
} /* WM_CLOSE */
default:
return FALSE;
}
}
VOID OkButton(HWND hDlg)
{
LPDIALOG_INFO lpDlgInfo;
UINT Index;
lpDlgInfo = (LPDIALOG_INFO) GetWindowLongPtrW(hDlg, DWL_USER);
/* Baud rate */
Index = SendMessageW(GetDlgItem(hDlg, IDC_BAUDRATE), CB_GETCURSEL, 0, 0);
lpDlgInfo->lpCC->dcb.BaudRate = Bauds[Index];
/* Byte size */
Index = SendMessageW(GetDlgItem(hDlg, IDC_BYTESIZE), CB_GETCURSEL, 0, 0);
lpDlgInfo->lpCC->dcb.ByteSize = ByteSizes[Index];
/* Parity */
Index = SendMessageW(GetDlgItem(hDlg, IDC_PARITY), CB_GETCURSEL, 0, 0);
lpDlgInfo->lpCC->dcb.Parity = Parities[Index].Parity;
/* Stop bits */
Index = SendMessageW(GetDlgItem(hDlg, IDC_STOPBITS), CB_GETCURSEL, 0, 0);
lpDlgInfo->lpCC->dcb.StopBits = StopBits[Index].StopBit;
/* Flow Control */
Index = SendMessageW(GetDlgItem(hDlg, IDC_FLOW), CB_GETCURSEL, 0, 0);
if(lpDlgInfo->InitialFlowIndex != Index)
{
switch(Index)
{
case 0: /* NO */
lpDlgInfo->lpCC->dcb.fDtrControl = DTR_CONTROL_DISABLE;
lpDlgInfo->lpCC->dcb.fRtsControl = RTS_CONTROL_DISABLE;
lpDlgInfo->lpCC->dcb.fOutxCtsFlow = FALSE;
lpDlgInfo->lpCC->dcb.fOutxDsrFlow = FALSE;
lpDlgInfo->lpCC->dcb.fOutX = FALSE;
lpDlgInfo->lpCC->dcb.fInX = FALSE;
break;
case 1: /* CTS/RTS */
lpDlgInfo->lpCC->dcb.fDtrControl = DTR_CONTROL_DISABLE;
lpDlgInfo->lpCC->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
lpDlgInfo->lpCC->dcb.fOutxCtsFlow = TRUE;
lpDlgInfo->lpCC->dcb.fOutxDsrFlow = FALSE;
lpDlgInfo->lpCC->dcb.fOutX = FALSE;
lpDlgInfo->lpCC->dcb.fInX = FALSE;
break;
case 2: /* XON/XOFF */
lpDlgInfo->lpCC->dcb.fDtrControl = DTR_CONTROL_DISABLE;
lpDlgInfo->lpCC->dcb.fRtsControl = RTS_CONTROL_DISABLE;
lpDlgInfo->lpCC->dcb.fOutxCtsFlow = FALSE;
lpDlgInfo->lpCC->dcb.fOutxDsrFlow = FALSE;
lpDlgInfo->lpCC->dcb.fOutX = TRUE;
lpDlgInfo->lpCC->dcb.fInX = TRUE;
break;
}
}
}