voici une version épurée de mon prog serial qui ne fait que la réception (tous les paramètres sont en dur, pas de vérif d'erreurs). bouton recevoir débute la réception Stop l'arrête
Recep.cpp :
#include <windows.h>
#include "Resource.h"
// message rensignant sur le nb d'octets reçus
#define WM_COMM_RX(WM_USER + 0x100)
// variables globales
HINSTANCE g_hAppInstance = NULL; // instance de l'application
HWND g_hMainDlg = NULL; // boîte de dialogue
HANDLE g_hComm = NULL; // handle port série
HANDLE g_hThread = NULL; // handle thread de lecture
BOOL g_bRunning = FALSE; // vrai si thread doit continuer
int CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
void CmdRecep();
void CmdStop();
DWORD WINAPI ThreadFunc(LPVOID);
//************************************************
//************************************************
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
g_hAppInstance = hInstance;
DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAINDIALOG), NULL, DlgProc);
return 0;
}
//************************************************
//************************************************
int CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG :
{
g_hMainDlg = hDlg;
EnableWindow(GetDlgItem(hDlg, IDC_RECEP), TRUE);
EnableWindow(GetDlgItem(hDlg, IDC_STOP), FALSE);
return TRUE;
}
case WM_COMMAND :
{
switch(LOWORD(wParam))
{
case IDCANCEL : CmdStop(); EndDialog(hDlg, IDCANCEL); return TRUE;
case IDOK : CmdStop(); EndDialog(hDlg, IDOK); return TRUE;
case IDC_RECEP : CmdRecep(); return TRUE;
case IDC_STOP : CmdStop(); return TRUE;
}
return FALSE;
}
case WM_COMM_RX :
{
// mise à jour nombre d'octets reçu
char szText[64];
wsprintf(szText, "%d octets", lParam);
SetWindowText(GetDlgItem(hDlg, IDC_NB), szText);
}
}
return 0;
}
//************************************************
//************************************************
void CmdRecep()
{
// ouverture port série
g_hComm = CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
SetupComm(g_hComm, 4096, 4096);
// affectation délais
COMMTIMEOUTS cto;
ZeroMemory(&cto, sizeof(COMMTIMEOUTS));
cto.ReadIntervalTimeout = 0xFFFFFFFF;
SetCommTimeouts(g_hComm, &cto);
// affectation configuration
DCB dcb;
ZeroMemory(&dcb, sizeof(DCB));
dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = 9600;
dcb.fBinary = TRUE;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.XonLim = 0x100;
dcb.XoffLim = 0x100;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.XonChar = 0x11;
dcb.XonChar = 0x13;
dcb.ErrorChar = '?';
dcb.EofChar = 0x1A;
dcb.EvtChar = 0x10;
SetCommState(g_hComm, &dcb);
// purge
PurgeComm(g_hComm, PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
EscapeCommFunction(g_hComm, SETDTR);
// création thread de lecture
DWORD dwThreadId;
g_bRunning = TRUE;
g_hThread = CreateThread(NULL, 0, ThreadFunc, &g_bRunning, 0, &dwThreadId);
// mise à jour affichage
EnableWindow(GetDlgItem(g_hMainDlg, IDC_RECEP), FALSE);
EnableWindow(GetDlgItem(g_hMainDlg, IDC_STOP), TRUE);
SetWindowText(GetDlgItem(g_hMainDlg, IDC_NB), "");
}
//************************************************
//************************************************
void CmdStop()
{
// si pas de thread en cours
if(g_hThread == NULL)
return;
// on attend que le thread s'arrête tout en traitant les messages
// relatifs au port série
g_bRunning = FALSE;
while(WaitForSingleObject(g_hThread, 10) != WAIT_OBJECT_0)
{
// si un message relatif au port série est présent
MSG msg;
if(PeekMessage(&msg, NULL, WM_COMM_RX, WM_COMM_RX, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// fermeture handles
CloseHandle(g_hThread);
CloseHandle(g_hComm);
g_hThread = NULL;
g_hComm = NULL;
EnableWindow(GetDlgItem(g_hMainDlg, IDC_RECEP), TRUE);
EnableWindow(GetDlgItem(g_hMainDlg, IDC_STOP), FALSE);
}
//************************************************
//************************************************
DWORD WINAPI ThreadFunc(LPVOID lpData)
{
// ouverture fichier de sortie, récup paramètres
HANDLE hFile = CreateFile("c:\\recep.txt", GENERIC_WRITE, 0, NULL,CREATE_ALWAYS, 0, NULL);
BOOL* pRunning = (BOOL*) lpData;
BYTE buffer[4096];
DWORD dwTotal = 0;
// tant que le thread doit tourner
while(*pRunning == TRUE)
{
// lecture d'un bloc
DWORD dwLength;
ReadFile(g_hComm, buffer, 4096, &dwLength, NULL);
// si pas de caractères reçus, faire une petite pause
if(dwLength == 0)
Sleep(10);
else
{
// écriture dans le fichier, notification dialogue
DWORD dwNbBytesWritten;
WriteFile(hFile, buffer, dwLength, &dwNbBytesWritten, NULL);
dwTotal += dwNbBytesWritten;
SendMessage(g_hMainDlg, WM_COMM_RX, 0, dwTotal);
}
}
// fermeture fichier de sortie
CloseHandle(hFile);
return 0;
}
Recep.rc :
#include "Resource.h"
IDD_MAINDIALOG DIALOG DISCARDABLE 0, 0, 142, 95
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Réception port série"
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Fermer",IDCANCEL,10,70,50,14
PUSHBUTTON "Recevoir",IDC_RECEP,10,20,50,14
PUSHBUTTON "Stop !",IDC_STOP,70,20,50,14
LTEXT "",IDC_NB,10,44,110,8
END
Resource.h :
#define IDD_MAINDIALOG 101
#define IDC_RECEP 1000
#define IDC_STOP 1002
#define IDC_NB 1003