bool CCommAPIDlg::WriteComm(LPVOID lpSndBuffer, DWORD dwBytesToWrite)
{
//lpSndBuffer为发送数据缓冲区指针, 
//dwBytesToWrite为将要发送的字节长度 
//设备已打开 
bool bWriteState=true;  
//实际发送的字节数 
DWORD dwBytesWritten; 
OVERLAPPED osReader;
osReader.Offset=0;
osReader.OffsetHigh=0;
//设备未打开 
if(!bOpen) return FALSE;
PurgeComm(hComDev, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
// bWriteState=WriteFile(hComDev,lpSndBuffer,dwBytesToWrite,&dwBytesWritten,&osReader); 
bWriteState=WriteFile(hComDev,lpSndBuffer,dwBytesToWrite,&dwBytesWritten,&osReader);
if(!bWriteState||dwBytesToWrite!=dwBytesWritten) 
//发送失败 
return FALSE;  
else 
//发送成功 
return TRUE;  
}

解决方案 »

  1.   

    利 用WINDOWS 定 时 器 实 现 串 口 通 信 控 制 
     ---- 1: 串 口 通 信 概 述 
    ---- 在 计 算 机 外 设 中,RS-232 串 口 因 为 其 组 成 方 式 简 单, 编 程 控 制 方 便 而 成 为 最 为 应 用 广 泛 的I/O 通 道 之 一。 在 硬 件 连 接 方 面, 最 为 简 单 的 方 式 一 条 公 用 地 线 和 两 条 信 号 线 即 可 组 成 串 行 双 工 通 信 线 路。 而 在 软 件 编 程 控 制 方 面, 操 作 系 统 亦 提 供 了 对 应 的 编 程 接 口, 使 的 开 发 者 能 灵 活 的 控 制 串 口 工 作。 ---- 在DOS 的 系 统 接 口 中DOS INT21H 的03H 和04H 号 功 能 调 用 为 异 步 串 行 通 信 的 接 收 和 发 送 功 能, 而BIOS INT14H 有4 组 功 能 调 用 为 串 行 通 信 服 务, 正 因 为 如 此 在DOS 中 采 用 寄 存 器 直 接 读 写、BIOS 调 用、 通 信 中 断 程 序 等 方 法 可 以 比 较 容 易 实 现 串 口 通 信。 但 是 在WINDOWS 中 由 于WINDOWS 采 用 消 息 驱 动 和 设 备 统 一 管 理, 以 及 利 用 消 息 对 列 进 行 程 序 控 制, 所 以DOS 下 的 方 法 都 不 宜 采 用. 在WINDOWS 中 为 实 现 串 口 通 信,WINDOWS 的SDK 提 供 了 完 备 的API 函 数 和 以 中 断 方 式 驱 动 的 通 信 驱 动 程 序, 使 编 程 变 的 较 为 容 易。 ---- WINDOWS 提 供 的 标 准 通 信API 函 数 很 多(win16 和win32 中 有 所 不 同), 一 般 来 说 常 用 的 有: win16 win32 作用
    OpenComm CreateFile (打开通信口);
    BuildCommDCB BuildCommDCB (填充DCB数据结构);
    SetCommState SetCommStae (设置通信口状态);
    FlushComm PurgeComm (清除通信接收或发送缓冲区);
    GetCommError ClearCommError
    (恢复或取得通信口的状态);
    ReadComm ReadFile (从通信接收缓冲区读字符);
    WriteComm WriteFile (向通信发送缓冲区写字符);
    CloseComm CloseHandle (关闭通信口);---- 在win16 中 通 信 设 备 由 专 门 通 信 函 数 处 理, 而wn32 中 将 这 些 设 备 当 作 面 向 文 件 的 设 备 来 处 理。 ---- 2:WINDOWS 定 时 器 ---- WINDOWS 系 统 中, 除 键 盘 和 鼠 标 外, 定 时 器 亦 是 一 种 输 入 设 备, 使 用 定 时 器 的 方 法 比 较 简 单, 通 常 告 诉WINDOWS 一 个 时 间 间 隔, 然 后WINDOWS 以 此 时 间 间 隔 周 期 性 触 发 程 序。 ---- WINDOWS 的WM_ TIMER 消 息 与BIOS 的08H、1CH 不 同, 传 统 的PC 驻 留 程 序 地 接 收 到08H 中 断 和1CH 中 断, 而WINDOWS 应 用 程 序 可 以 周 期 接 收 到WM_TIMER 消 息, 这 两 者 道 理 不 一 样. 在WINDOWS 中, 有SYSTEM.DRV 处 理 硬 件 定 时 中 断,WINDOWS 应 用 程 序 从 消 息 队 列 中 获 得WM_TIMER 消 息 而 不 会 收 到08H 硬 件 中 断,WM_TIMER 消 息 并 不 是 随 时‘ 插 入’ 应 用 程 序, 而 是 应 用 程 序 主 动 地、 有 次 序 的 从 消 息 队 列 中 得 到 时 间 消 息。 而DOS 中 由 计 算 机 每 隔18.2s 产 生08H 中 断,08H 中 断 再 调 用1CH 中 断, 硬 件 中 断 有 一 重 要 特 征, 即 发 生 的 时 间 是 在 任 何 时 刻, 不 管 程 序 运 行 到 任 何 时 刻, 硬 件 中 断 都 可 以 插 入 程 序。 ---- 3:WINDOWS 中 利 用 定 时 器 控 制 串 口 通 信 ---- 在WINDOWS 中 由 串 口 进 来 的 数 据 经 过 两 个 缓 冲 区, 首 先 是 硬 件 的 接 收 缓 冲 区( 这 种 缓 冲 通 常 有8 位 或16 位), 然 后 进 入 应 用 程 序 设 置 的 串 口 接 收 缓 冲( 这 个 缓 冲 大 小 在WIN16 中 由 应 用 程 序 设 置, 而WIN32 中 由 于 串 口 作 为 面 向 文 件 设 备 处 理, 所 以 缓 冲 大 小 不 用 设 置), 数 据 从 硬 件 缓 冲 到 应 用 程 序 缓 冲 这 一 过 程 由WINDOWS 本 身 完 成, 作 为 编 程 者 不 用 考 虑 它, 应 用 程 序 只 关 心 何 时 有 数 据。 虽 然WINDOWS 提 供WM_COMMNOTIFY 消 息, 但 是 笔 者 在 使 用 中 发 现 利 用 它 控 制 比 较 麻 烦, 而 且 经 常 发 生 丢 失 数 据 现 象, 而 利 用 定 时 器 处 理 则 可 达 到 控 制 灵 活 的 效 果。 ---- 在 程 序 初 始 化 串 口 以 后, 在 程 序 中 为 串 口 设 立 一 个 定 时 器, 利 用 该 定 时 器 定 时 检 查 串 口 状 态, 如 果 有 数 据 则 开 始 接 收 处 理, 否 则 该 定 时 器 消 息 无 处 理。 也 许 有 人 认 为 有 在 数 据 处 理 未 结 束 时 下 一 个 定 时 器 消 息 会 发 生 的 现 象, 对 于 这 种 情 况 除 了 加 大 定 时 器 间 隔 外 更 为 主 动 的 办 法 是 在 发 现 有 数 据 时 关 闭 定 时 器, 然 后 在 数 据 接 收 完 后 在 打 开。 ---- 4.WINDOWS 通 信 实 例 ---- 通 信 实 例 的 环 境 为:586/100 计 算 机; 中 文WINDOWS`95; 对 方 为 交 换 机。 通 信 参 数 为: 波 特 率9600bps; 数 据 位8 位; 停 止 位1; 无 校 验。 通 信 协 议: 帧 开 始 和 结 束 都 为0X7E0X7E, 帧 数 据 不 定 长。 编程环境:BORLANDC C++5.0,WINDOWS `95 
    //======================================
    // FUNCTION: short InitCom()
    // PURPOSE: init com1
    // RETURN VALUE:
    // 1-------No error
    // 0-------init Error
    //======================================
    short InitCom()
    {
    if(com_select==1)
    {
    IDCommDevice=CreateFile("COM1",
    GENERIC_READ|GENERIC_WRITE,
    0,NULL,OPEN_EXISTING,0,NULL);
    if(IDCommDevice==INVALID_HANDLE_VALUE)
    {
    MessageBox(hWnd,"OPenComm error","info",MB_OK);
    CloseHandle(IDCommDevice);
    return 0;
    }
    BuildCommDCB("COM1:9600,N,8,1",&dCB);
    }else
    {
    IDCommDevice=CreateFile("COM2",
    GENERIC_READ|GENERIC_WRITE,
    0,NULL,OPEN_EXISTING,0,NULL);
    if(IDCommDevice==INVALID_HANDLE_VALUE)
    {
    MessageBox(hWnd,"OPenComm error","info",MB_OK);
    CloseHandle(IDCommDevice);
    return 0;
    }
    BuildCommDCB("COM2:9600,N,8,1",&dCB);
    }if (SetCommState(IDCommDevice,&dCB)<0) { MessageBox(hWnd,"Read SET CommState error","info",MB_OK); CloseHandle(IDCommDevice); return 0; } if(!PurgeComm(IDCommDevice,PURGE_RXCLEAR)) { MessageBox(hWnd,"IN buffer flush error","info",MB_OK); CloseHandle(IDCommDevice); return 0; } if(!PurgeComm(IDCommDevice,PURGE_TXCLEAR)) { MessageBox(hWnd,"OUT buffer flush error","info",MB_OK); CloseHandle(IDCommDevice); return 0; } return 1; } . . . . /****************************************** Function:JKTWndProc(HWND hDlg,UINT message, WPARAM wParam,LPARAM lParam) Purpose: 处理交换机的信息 Message: WM_INITDIALOG---对话框初化 WM_COMMAND------所有对窗口的操作 **********************************************/ #pragma argsused LRESULT CALLBACK JKTWndProc(HWND hDlg, UINT message, UINT wParam, LONG lParam) { LPDWORD num; short sign; char *temp_char; short x; BOOL lresult; int t_com; hdlg="hDlg;" switch (message) { case WM_TIMER: switch(LOWORD(wParam)) { case TIMER_REC: ClearCommError(IDCommDevice, &lpErrors,&ComStat); if(ComStat.cbInQue!="0)" PostMessage(hDlg,WM_COMMAND ,IDP_DEALDATA,0L); break; } return 0; case WM_COMMAND: switch(LOWORD(wParam)) { case IDP_DEALDATA: //处理交换机发的信息 for(t_com="0;t_com<" ComStat.cbInQue;t_com++) { num="0;" l result="ReadFile(IDCommDevice," temp_char,1,&n um,&lpOverlapped); temp_char++; } return 0; case IDBEGIN: //开始工作 sign="InitCom(hDlg);" if(sign="=0)" { MessageBox(hDlg,"串口设置失败!","Information",MB_OK); return 0; } i SetTimer(hDlg,TIMER_REC,20,NULL); return 0; } break; } return (0); } . . . . .