NashRus писал(а):хотелось бы именно посмотреть все грабли при работе с потоками и их синхронизацией, а также вот реализацией всего этого на PB.
Потоки нужны, т.к. даже асинхронный режим чтения/записи не спасает от зависания GUI при открытии порта.
API's
BuildCommDCB
BuildCommDCBAndTimeouts
ClearCommBreak
ClearCommError
CommConfigDialog
DeviceIoControl
EscapeCommFunction
GetCommConfig
GetCommMask
GetCommModemStatus
GetCommProperties
GetCommState
GetCommTimeouts
GetDefaultCommConfig
PurgeComm
SetCommBreak
SetCommConfig
SetCommMask
SetCommState
SetCommTimeouts
SetDefaultCommConfig
SetupComm
TransmitCommChar
WaitCommEvent
В обрабатывающем потоке WaitCommEvent
и по результату соответствующее действие
Рутину по инизиализации можно сделать на ПБшных операторах
а вытащить настоящие (не ПБшные) хэндлы можно через FILEATTR(#x,2)
Реальная воплощение зависит от от логики работы с девайсом.
Посмотрите в примерах на ПБ-шном сайте есть реализация Zmodem
ниже простенький генератор, который устанавливает линию TX либо в 1 либо в 0 вручную или молотит на сколько хватает скорости машины как генератор. Генератор работает в отдельном потоке, поэтому не вешает ГУИ.
- Код: Выделить всё
#COMPILER PBWIN
#COMPILE EXE
#DIM ALL
#INCLUDE "win32api.inc"
'************************************************************************************
$title="mainDLG"
%IDC_Static01 = 1001
%IDC_Edit01 = 1002
%IDC_Button01 = 1003
%IDC_Button02 = 1004
%IDC_Button03 = 1005
'************************************************************************************
GLOBAL flag AS LONG
FUNCTION Gen (BYVAL hCom AS DWORD) AS LONG
WHILE flag=1
EscapeCommFunction(hCom,%SETBREAK)'; //1
EscapeCommFunction(hCom,%CLRBREAK)'; //0
WEND
END FUNCTION
CALLBACK FUNCTION cbDLGmainProc()
STATIC hWndSaveFocus, hCom AS DWORD
SELECT CASE AS LONG CBMSG
CASE %WM_INITDIALOG
hCom=CreateFile("COM1",%GENERIC_READ OR %GENERIC_WRITE, 0, BYVAL 0, %OPEN_EXISTING, 0, 0)
IF hCom =%INVALID_HANDLE_VALUE THEN ? "Err1"
flag=0
CASE %WM_NCACTIVATE
IF ISFALSE CBWPARAM THEN
hWndSaveFocus = GetFocus()
ELSEIF hWndSaveFocus THEN
SetFocus(hWndSaveFocus) : hWndSaveFocus = 0
END IF
'
CASE %WM_COMMAND
SELECT CASE AS LONG CBCTL
CASE %IDC_Button01
IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
EscapeCommFunction(hCom,%SETBREAK)'; //1
END IF
CASE %IDC_Button02
IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
EscapeCommFunction(hCom,%CLRBREAK)'; //0
END IF
CASE %IDC_Button03
IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
STATIC hThread AS DWORD : STATIC lRes AS LONG
IF flag=0 THEN
CONTROL SET TEXT CBHNDL,%IDC_Button03, "Press2stop"
flag=1
THREAD CREATE Gen (BYVAL hCom) TO hThread
ELSE
flag=0
CONTROL SET TEXT CBHNDL,%IDC_Button03, "CloseGen"
WaitForSingleObject(hThread,%INFINITE)
THREAD CLOSE hThread TO lRes
CONTROL SET TEXT CBHNDL,%IDC_Button03, "Press2start"
END IF
END IF
'
END SELECT
'
CASE %WM_SYSCOMMAND
CASE %WM_DESTROY
CloseHandle (hCom)
END SELECT
END FUNCTION
'************************************************************************************
'
'<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
FUNCTION PBMAIN () AS LONG
LOCAL hDlg AS DWORD
'------------------------------------------------------------------
DIALOG NEW 0, $title,,, 200, 120 ,%WS_OVERLAPPEDWIN TO hDlg
CONTROL ADD BUTTON , hDlg, %IDC_Button01, "SetTxd", 6, 42, 84, 15
CONTROL ADD BUTTON , hDlg, %IDC_Button02, "ClearTXD", 6, 62, 84, 15
CONTROL ADD BUTTON , hDlg, %IDC_Button03, "Generator", 6, 82, 84, 15
'------------------------------------------------------------------
DIALOG SHOW MODAL hDlg, CALL cbDLGmainProc 'TO lRes
END FUNCTION