/* * 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, DWLP_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, DWLP_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; } } }