1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS SerialUI DLL 4 * FILE: serialui.c 5 * PUROPSE: A dialog box to configure COM port. 6 * Functions to set (and get too) default configuration. 7 * PROGRAMMERS: Saveliy Tretiakov (saveliyt@mail.ru) 8 * REVISIONS: 9 * ST (05/04/2005) Created. Implemented drvCommConfigDialog. 10 */ 11 12 #include "serialui.h" 13 14 static HINSTANCE hDllInstance; 15 16 /************************************ 17 * 18 * DATA 19 * 20 ************************************/ 21 22 const DWORD Bauds[] = { 23 CBR_110, 24 CBR_300, 25 CBR_600, 26 CBR_1200, 27 CBR_2400, 28 CBR_4800, 29 CBR_9600, 30 CBR_14400, 31 CBR_19200, 32 CBR_38400, 33 CBR_56000, 34 CBR_57600, 35 CBR_115200, 36 CBR_128000, 37 CBR_256000, 38 0 39 }; 40 41 const BYTE ByteSizes[] = { 42 5, 43 6, 44 7, 45 8, 46 0 47 }; 48 49 50 const PARITY_INFO Parities[] = { 51 { EVENPARITY, IDS_EVENPARITY }, 52 { MARKPARITY, IDS_MARKPARITY }, 53 { NOPARITY, IDS_NOPARITY }, 54 { ODDPARITY, IDS_ODDPARITY }, 55 { SPACEPARITY, IDS_SPACEPARITY }, 56 { 0, 0 } 57 }; 58 59 const STOPBIT_INFO StopBits[] = { 60 { ONESTOPBIT, IDS_ONESTOPBIT }, 61 { ONE5STOPBITS, IDS_ONE5STOPBITS }, 62 { TWOSTOPBITS, IDS_TWOSTOPBITS }, 63 { 0, 0 } 64 }; 65 66 67 /************************************ 68 * 69 * DLLMAIN 70 * 71 ************************************/ 72 73 BOOL 74 WINAPI 75 DllMain(HINSTANCE hInstance, 76 DWORD dwReason, 77 LPVOID reserved) 78 { 79 if(dwReason==DLL_PROCESS_ATTACH) 80 { 81 hDllInstance = hInstance; 82 } 83 else if(dwReason==DLL_THREAD_ATTACH) 84 { 85 DisableThreadLibraryCalls(hInstance); 86 } 87 88 return TRUE; 89 } 90 91 92 /************************************ 93 * 94 * EXPORTS 95 * 96 ************************************/ 97 98 /* 99 * @implemented 100 */ 101 DWORD WINAPI drvCommConfigDialogW(LPCWSTR lpszDevice, 102 HWND hWnd, 103 LPCOMMCONFIG lpCommConfig) 104 { 105 DIALOG_INFO DialogInfo; 106 107 if(!lpszDevice || !lpCommConfig) 108 { 109 return ERROR_INVALID_PARAMETER; 110 } 111 112 DialogInfo.lpszDevice = lpszDevice; 113 DialogInfo.lpCC = lpCommConfig; 114 115 return DialogBoxParamW(hDllInstance, MAKEINTRESOURCEW(IDD_COMMDLG), 116 hWnd, CommDlgProc, (LPARAM)&DialogInfo); 117 } 118 119 /* 120 * @implemented 121 */ 122 DWORD WINAPI drvCommConfigDialogA(LPCSTR lpszDevice, 123 HWND hWnd, 124 LPCOMMCONFIG lpCommConfig) 125 { 126 BOOL result; 127 UINT len; 128 WCHAR *wstr; 129 130 len = MultiByteToWideChar(CP_ACP, 0, lpszDevice, -1, NULL, 0); 131 if((wstr = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)))) 132 { 133 MultiByteToWideChar(CP_ACP, 0, lpszDevice, -1, wstr, len); 134 result = drvCommConfigDialogW(wstr, hWnd, lpCommConfig); 135 HeapFree(GetProcessHeap(), 0, wstr); 136 return result; 137 } 138 else 139 return ERROR_NOT_ENOUGH_MEMORY; 140 } 141 142 /* 143 * @unimplemented 144 */ 145 DWORD WINAPI drvSetDefaultCommConfigW(LPCWSTR lpszDevice, 146 LPCOMMCONFIG lpCommConfig, 147 DWORD dwSize) 148 { 149 UNIMPLEMENTED 150 } 151 152 /* 153 * @unimplemented 154 */ 155 DWORD WINAPI drvSetDefaultCommConfigA(LPCSTR lpszDevice, 156 LPCOMMCONFIG lpCommConfig, 157 DWORD dwSize) 158 { 159 UNIMPLEMENTED 160 } 161 162 /* 163 * @unimplemented 164 */ 165 DWORD WINAPI drvGetDefaultCommConfigW(LPCWSTR lpszDevice, 166 LPCOMMCONFIG lpCommConfig, 167 LPDWORD lpdwSize) 168 { 169 UNIMPLEMENTED 170 } 171 172 /* 173 * @unimplemented 174 */ 175 DWORD WINAPI drvGetDefaultCommConfigA(LPCSTR lpszDevice, 176 LPCOMMCONFIG lpCommConfig, 177 LPDWORD lpdwSize) 178 { 179 UNIMPLEMENTED 180 } 181 182 183 /************************************ 184 * 185 * INTERNALS 186 * 187 ************************************/ 188 189 INT_PTR 190 CALLBACK 191 CommDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) 192 { 193 LPDIALOG_INFO lpDlgInfo = NULL; 194 HWND hBox; 195 196 switch (Msg) 197 { 198 199 case WM_INITDIALOG: 200 { 201 WCHAR wstr[255]; 202 RECT rc, rcDlg, rcOwner; 203 HWND hOwner; 204 INT i; 205 206 lpDlgInfo = (LPDIALOG_INFO)lParam; 207 SetWindowLongPtrW(hDlg, DWL_USER, (LONG_PTR)lpDlgInfo); 208 209 /* Set title */ 210 if(LoadStringW(hDllInstance, IDS_TITLE, wstr, sizeof(wstr) / sizeof(wstr[0]))) 211 { 212 SetWindowTextW(hDlg, wstr); 213 } 214 215 /* FIXME - this won't work correctly systems with multiple monitors! */ 216 if(!(hOwner = GetParent(hDlg))) 217 hOwner = GetDesktopWindow(); 218 219 /* Position dialog in the center of owner window */ 220 GetWindowRect(hOwner, &rcOwner); 221 GetWindowRect(hDlg, &rcDlg); 222 CopyRect(&rc, &rcOwner); 223 OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top); 224 OffsetRect(&rc, -rc.left, -rc.top); 225 OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom); 226 SetWindowPos(hDlg, HWND_TOP, 227 rcOwner.left + (rc.right / 2), 228 rcOwner.top + (rc.bottom / 2), 229 0, 0, SWP_NOSIZE); 230 231 /* Initialize baud rate combo */ 232 if(!(hBox = GetDlgItem(hDlg, IDC_BAUDRATE))) 233 EndDialog(hDlg, ERROR_CANCELLED); 234 235 for(i = 0; Bauds[i]; i++) 236 { 237 wsprintf(wstr, L"%d", Bauds[i]); 238 SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr); 239 if(Bauds[i] == lpDlgInfo->lpCC->dcb.BaudRate) 240 SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0); 241 } 242 243 if(SendMessageW(hBox, CB_GETCURSEL, 0, 0) == CB_ERR) 244 SendMessageW(hBox, CB_SETCURSEL, DEFAULT_BAUD_INDEX, 0); 245 246 /* Initialize byte size combo */ 247 if(!(hBox = GetDlgItem(hDlg, IDC_BYTESIZE))) 248 EndDialog(hDlg, ERROR_CANCELLED); 249 250 for(i = 0; ByteSizes[i]; i++) 251 { 252 wsprintf(wstr, L"%d", Bauds[i]); 253 SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr); 254 if(ByteSizes[i] == lpDlgInfo->lpCC->dcb.ByteSize) 255 SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0); 256 } 257 258 if(SendMessageW(hBox, CB_GETCURSEL, 0, 0) == CB_ERR) 259 SendMessageW(hBox, CB_SETCURSEL, DEFAULT_BYTESIZE_INDEX, 0); 260 261 /* Initialize parity combo */ 262 if(!(hBox = GetDlgItem(hDlg, IDC_PARITY))) 263 EndDialog(hDlg, ERROR_CANCELLED); 264 265 for(i = 0; Parities[i].StrId; i++) 266 { 267 if(LoadStringW(hDllInstance, Parities[i].StrId, wstr, sizeof(wstr) / sizeof(wstr[0]))) 268 { 269 SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr); 270 if(Parities[i].Parity == lpDlgInfo->lpCC->dcb.Parity) 271 SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0); 272 } 273 } 274 275 if(SendMessageW(hBox, CB_GETCURSEL, 0, 0)==CB_ERR) 276 SendMessageW(hBox, CB_SETCURSEL, DEFAULT_PARITY_INDEX, 0); 277 278 /* Initialize stop bits combo */ 279 if(!(hBox = GetDlgItem(hDlg, IDC_STOPBITS))) 280 EndDialog(hDlg, ERROR_CANCELLED); 281 282 for(i = 0; StopBits[i].StrId; i++) 283 { 284 if(LoadStringW(hDllInstance, StopBits[i].StrId, wstr, sizeof(wstr) / sizeof(wstr[0]))) 285 { 286 SendMessageW(hBox, CB_INSERTSTRING, (WPARAM)i, (LPARAM)wstr); 287 if(StopBits[i].StopBit == lpDlgInfo->lpCC->dcb.StopBits) 288 SendMessageW(hBox, CB_SETCURSEL, (WPARAM)i, 0); 289 } 290 } 291 292 if(SendMessageW(hBox, CB_GETCURSEL, 0, 0)==CB_ERR) 293 SendMessageW(hBox, CB_SETCURSEL, DEFAULT_STOPBITS_INDEX, 0); 294 295 /* Initialize flow control combo */ 296 if(!(hBox = GetDlgItem(hDlg, IDC_FLOW))) 297 EndDialog(hDlg, ERROR_CANCELLED); 298 299 if(LoadStringW(hDllInstance, IDS_FC_NO, wstr, sizeof(wstr) / sizeof(wstr[0]))) 300 { 301 SendMessageW(hBox, CB_INSERTSTRING, 0, (LPARAM)wstr); 302 SendMessageW(hBox, CB_SETCURSEL, 0, 0); 303 lpDlgInfo->InitialFlowIndex = 0; 304 } 305 306 307 if(LoadStringW(hDllInstance, IDS_FC_CTSRTS, wstr, sizeof(wstr) / sizeof(wstr[0]))) 308 { 309 SendMessageW(hBox, CB_INSERTSTRING, 1, (LPARAM)wstr); 310 if(lpDlgInfo->lpCC->dcb.fRtsControl == RTS_CONTROL_HANDSHAKE 311 || lpDlgInfo->lpCC->dcb.fOutxCtsFlow != FALSE) 312 { 313 SendMessageW(hBox, CB_SETCURSEL, 1, 0); 314 lpDlgInfo->InitialFlowIndex = 1; 315 } 316 } 317 318 if(LoadStringW(hDllInstance, IDS_FC_XONXOFF, wstr, sizeof(wstr) / sizeof(wstr[0]))) 319 { 320 SendMessageW(hBox, CB_INSERTSTRING, 2, (LPARAM)wstr); 321 if(lpDlgInfo->lpCC->dcb.fOutX || lpDlgInfo->lpCC->dcb.fInX) 322 { 323 SendMessageW(hBox, CB_SETCURSEL, 2, 0); 324 lpDlgInfo->InitialFlowIndex = 2; 325 } 326 } 327 328 /* Set focus */ 329 SetFocus(GetDlgItem(hDlg, IDC_OKBTN)); 330 331 return FALSE; 332 } /* WM_INITDIALOG */ 333 334 case WM_COMMAND: 335 { 336 switch(wParam) 337 { 338 case IDC_CANCELBTN: 339 EndDialog(hDlg, ERROR_CANCELLED); 340 break; 341 case IDC_OKBTN: 342 OkButton(hDlg); 343 EndDialog(hDlg, ERROR_SUCCESS); 344 break; 345 } 346 return TRUE; 347 } /* WM_COMMAND */ 348 349 case WM_CLOSE: 350 { 351 EndDialog(hDlg, ERROR_CANCELLED); 352 return TRUE; 353 } /* WM_CLOSE */ 354 355 default: 356 return FALSE; 357 } 358 359 } 360 361 362 VOID OkButton(HWND hDlg) 363 { 364 LPDIALOG_INFO lpDlgInfo; 365 UINT Index; 366 367 lpDlgInfo = (LPDIALOG_INFO) GetWindowLongPtrW(hDlg, DWL_USER); 368 369 /* Baud rate */ 370 Index = SendMessageW(GetDlgItem(hDlg, IDC_BAUDRATE), CB_GETCURSEL, 0, 0); 371 lpDlgInfo->lpCC->dcb.BaudRate = Bauds[Index]; 372 373 /* Byte size */ 374 Index = SendMessageW(GetDlgItem(hDlg, IDC_BYTESIZE), CB_GETCURSEL, 0, 0); 375 lpDlgInfo->lpCC->dcb.ByteSize = ByteSizes[Index]; 376 377 /* Parity */ 378 Index = SendMessageW(GetDlgItem(hDlg, IDC_PARITY), CB_GETCURSEL, 0, 0); 379 lpDlgInfo->lpCC->dcb.Parity = Parities[Index].Parity; 380 381 /* Stop bits */ 382 Index = SendMessageW(GetDlgItem(hDlg, IDC_STOPBITS), CB_GETCURSEL, 0, 0); 383 lpDlgInfo->lpCC->dcb.StopBits = StopBits[Index].StopBit; 384 385 /* Flow Control */ 386 Index = SendMessageW(GetDlgItem(hDlg, IDC_FLOW), CB_GETCURSEL, 0, 0); 387 if(lpDlgInfo->InitialFlowIndex != Index) 388 { 389 switch(Index) 390 { 391 case 0: /* NO */ 392 lpDlgInfo->lpCC->dcb.fDtrControl = DTR_CONTROL_DISABLE; 393 lpDlgInfo->lpCC->dcb.fRtsControl = RTS_CONTROL_DISABLE; 394 lpDlgInfo->lpCC->dcb.fOutxCtsFlow = FALSE; 395 lpDlgInfo->lpCC->dcb.fOutxDsrFlow = FALSE; 396 lpDlgInfo->lpCC->dcb.fOutX = FALSE; 397 lpDlgInfo->lpCC->dcb.fInX = FALSE; 398 break; 399 case 1: /* CTS/RTS */ 400 lpDlgInfo->lpCC->dcb.fDtrControl = DTR_CONTROL_DISABLE; 401 lpDlgInfo->lpCC->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; 402 lpDlgInfo->lpCC->dcb.fOutxCtsFlow = TRUE; 403 lpDlgInfo->lpCC->dcb.fOutxDsrFlow = FALSE; 404 lpDlgInfo->lpCC->dcb.fOutX = FALSE; 405 lpDlgInfo->lpCC->dcb.fInX = FALSE; 406 break; 407 case 2: /* XON/XOFF */ 408 lpDlgInfo->lpCC->dcb.fDtrControl = DTR_CONTROL_DISABLE; 409 lpDlgInfo->lpCC->dcb.fRtsControl = RTS_CONTROL_DISABLE; 410 lpDlgInfo->lpCC->dcb.fOutxCtsFlow = FALSE; 411 lpDlgInfo->lpCC->dcb.fOutxDsrFlow = FALSE; 412 lpDlgInfo->lpCC->dcb.fOutX = TRUE; 413 lpDlgInfo->lpCC->dcb.fInX = TRUE; 414 break; 415 } 416 } 417 } 418