
Опытный
 
Профиль
Группа: Участник
Сообщений: 295
Регистрация: 10.2.2005
Где: Санкт-Петербург
Репутация: 1 Всего: 3
|
Вот пример Код | #define STRICT
#include <windows.h> #include <string.h> #include <stdlib.h> #include <mem.h> #include <bwcc.h> #include "phone.h"
// Глобальные переменные
HINSTANCE hInst; // Идентификатор приложения int idComDev; // Идентификатор COM-порта char sBufNum[20]; // Буфер для телефонного номера BOOL WaitFlag = FALSE;
// ===================================== // Функция WinMain // ===================================== #pragma argsused
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { static DLGPROC lpfnDlgProc;
hInst = hInstance;
// Переходник для функции диалоговой панели lpfnDlgProc = (DLGPROC)MakeProcInstance((FARPROC)DlgProc, hInst);
// Создаем модальную диалоговую панель DialogBox( hInstance, "PHONE", NULL, lpfnDlgProc );
return 0; }
// ===================================== // Функция DldProc // =====================================
#pragma argsused
BOOL CALLBACK _export DlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam) { int iErr;
switch(msg) { // Инициализация диалоговой панели case WM_INITDIALOG: { // Посылаем сообщение WM_CONNECT PostMessage( hdlg,WM_CONNECT,0,0L ); return TRUE; }
case WM_CONNECT: { EnableWindow(GetDlgItem(hdlg, IDCANCEL), FALSE);
// Открываем COM-порт и инициализируем модем iErr = InitLine();
EnableWindow(GetDlgItem(hdlg, IDCANCEL), TRUE);
// Если возникла ошибка отображаем сообщение // и закрываем диалоговую панель if( iErr < 0 ) { ShowError( iErr ); EndDialog( hdlg, 0 ); } return TRUE; }
case WM_COMMAND: { switch(wParam) { // Нажата кнопка номеронаберателя case ID_1: case ID_2: case ID_3: case ID_4: case ID_5: case ID_6: case ID_7: case ID_8: case ID_9: case ID_0: { int iNum; char sTmp[10];
// Определяем набранную цифру iNum = wParam - ID_0;
wsprintf( sTmp, "%d", iNum );
// Добавляем набранную цифру к номеру lstrcat(sBufNum, sTmp);
// Обновляем номер на экране SetDlgItemText(hdlg, ID_NUMBER, sBufNum);
return TRUE; }
// Нажата кнопка "Сброс" case ID_CLEAR: { EnableWindow(GetDlgItem(hdlg, IDCANCEL), FALSE);
// Вешаем трубку HangUpPhone();
EnableWindow(GetDlgItem(hdlg, IDCANCEL), TRUE);
return TRUE; }
// Удаляем последную цифру номера case ID_BACK: { if( lstrlen( sBufNum ) != 0 ) { sBufNum[lstrlen( sBufNum ) - 1] = '\0'; SetDlgItemText( hdlg, ID_NUMBER, sBufNum ); } else MessageBeep( MB_ICONASTERISK );
return TRUE; }
// Нажата кнопка "Набор" case ID_DIAL: { EnableWindow(GetDlgItem(hdlg, IDCANCEL), FALSE);
// Набираем номер iErr = DialPhone();
// Если возникла ошибка отображаем сообщение if( iErr < 0 ) ShowError( iErr );
EnableWindow(GetDlgItem(hdlg, IDCANCEL), TRUE); return TRUE; }
// Нажата кнопка "Выход" case IDCANCEL: { // Закрываем COM-порт CloseLine();
// Закрываем диалоговую панель EndDialog( hdlg, 0 );
return TRUE; } } } } return FALSE; }
// ===================================== // Функция InitLine // ===================================== int InitLine() { BYTE bSet; DCB dcb; int iErr; char sTmp[200]; char szModemAnswer[200];
char szInitMode[80]; char szTmpStrBool[3]; char szInitModem[100]; long lnModemTimeout;
// Определяем режим работы COM-порта, для этого считываем // строку Mode из раздела Port файла phone.ini GetPrivateProfileString( "Port", "Mode", "COM1:9600,n,8,1", szInitMode, sizeof(szInitMode), "phone.ini" );
// Открываем COM-порт, заданный в строке szInitMode wsprintf( sTmp, "COM%c", szInitMode[3] );
idComDev = OpenComm( sTmp, 4915, 4915 ); if (idComDev < 0) return ERR_NO_OPEN;
// Заполняем структуру DCB в соответствии с szInitMode iErr = BuildCommDCB( szInitMode, &dcb ); if(iErr < 0) return ERR_DCB_BUILD;
// Изменяем отдельные поля структуры DCB в // соответствии с файлом phone.ini
// Заполняем поля fOutxDsrFlow, fDtrflow, DsrTimeout GetPrivateProfileString( "Port", "DsrDtrFlow", "1", szTmpStrBool, sizeof(szTmpStrBool), "phone.ini" ); dcb.fOutxDsrFlow = dcb.fDtrflow = bSet = (BYTE) atoi(szTmpStrBool);
dcb.DsrTimeout = (bSet) ? 3 : 0;
// Заполняем поля fOutxCtsFlow, fRtsflow, CtsTimeout GetPrivateProfileString( "Port", "CtsRtsFlow", "1", szTmpStrBool, sizeof(szTmpStrBool), "phone.ini" );
dcb.fOutxCtsFlow = dcb.fRtsflow = bSet = (BYTE) atoi(szTmpStrBool);
dcb.CtsTimeout = (bSet) ? 3 : 0;
// Заполняем поле fBinary GetPrivateProfileString( "Port", "Binary", "1", szTmpStrBool, sizeof(szTmpStrBool), "phone.ini" ); dcb.fBinary = (BOOL) atoi(szTmpStrBool);
// Заполняем поле fRtsDisable GetPrivateProfileString( "Port", "RtsDisable", "0", szTmpStrBool, sizeof(szTmpStrBool), "phone.ini" );
dcb.fRtsDisable = (BOOL) atoi(szTmpStrBool);
// Заполняем поле fDtrDisable GetPrivateProfileString( "Port", "DtrDisable", "0", szTmpStrBool, sizeof(szTmpStrBool), "phone.ini" ); dcb.fDtrDisable = (BOOL) atoi(szTmpStrBool);
// Устанавливаем новый режим работы COM-порта iErr = SetCommState( &dcb ); if( iErr < 0 ) return ERR_DCB_SET;
// Удаляем данные из входной и выходной очередей COM-порта FlushComm(idComDev, 1); FlushComm(idComDev, 0);
// Подаем сигнал DTR EscapeCommFunction(idComDev, SETDTR);
// Определяем команду инициализации модема, для этого считываем // строку Init из раздела Modem файла phone.ini GetPrivateProfileString( "Modem", "Init", "ATZ", szInitModem, sizeof(szInitModem), "phone.ini" );
// Добавляем к команде символ перевода строки wsprintf( sTmp, "%s\r", szInitModem );
// Передаем команду инициализации модему iErr = WriteComm( idComDev, sTmp, lstrlen( sTmp ) ); if( iErr < 0 ) return ERR_WRITE;
// Определяем время ожидания ответа от модема GetPrivateProfileString( "Modem", "ModemTimeout", "1000", sTmp, sizeof(sTmp), "phone.ini" );
lnModemTimeout = atol( sTmp );
// Ожидаем от модема ответ "OK" iErr = WaitModemAnswer( idComDev, (LPSTR*)szOkString, szModemAnswer, 200, (DWORD)lnModemTimeout); if( iErr < 0 ) return iErr;
return 0; }
// ===================================== // Функция // =====================================
int DialPhone() { int iErr; char sTmp[80]; char szModemAnswer[200]; char szDialModem[80]; long lnModemTimeout;
// Определяем команду набора номера, для этого считываем // строку Dial из раздела Modem файла phone.ini GetPrivateProfileString( "Modem", "Dial", "ATDP", szDialModem, sizeof(szDialModem), "phone.ini" );
// Формируем во временном буфере sTmp команду набора номера wsprintf( sTmp, "%s%s\r", szDialModem, sBufNum );
// Удаляем данные из входной и выходной очередей COM-порта FlushComm(idComDev, 1); FlushComm(idComDev, 0);
// Передаем модему команду набора номера iErr = WriteComm(idComDev, sTmp, lstrlen(sTmp) ); if( iErr < 0 ) return ERR_WRITE;
// Определяем время ожидания ответа от модема GetPrivateProfileString( "Modem", "DialTimeout", "30000", sTmp, sizeof(sTmp), "phone.ini" );
lnModemTimeout = atol( sTmp );
// Ожидаем ответ от модема iErr = WaitModemAnswer( idComDev, (LPSTR*)szAnswer, szModemAnswer, 200, (DWORD)lnModemTimeout);
BWCCMessageBox(NULL, szModemAnswer, "Ответ модема", MB_OK );
return iErr; }
// ===================================== // Функция CloseLine // =====================================
int CloseLine() { // Сбрасывааем сигнал DTR EscapeCommFunction(idComDev, CLRDTR);
// Удаляем данные из входной и выходной очередей COM-порта FlushComm(idComDev, 1); FlushComm(idComDev, 0);
// Закрываем COM-порт CloseComm(idComDev);
return 0; }
// =================================================================== // Функция HangUp // ===================================================================
int HangUpPhone() { DWORD StartTick; char szHangUpString[80], sTmp[80]; long lnModemTimeout;
// Определяем время задержки перед подачей команды "+++" GetPrivateProfileString( "Modem", "HangUpTimeout", "2000", sTmp, sizeof(sTmp), "phone.ini" );
lnModemTimeout = atol( sTmp );
// Определяем команду разрыва связи, для этого считываем // строку Dial из раздела Modem файла phone.ini GetPrivateProfileString( "Modem", "HangUp", "ATH0", szHangUpString, sizeof(szHangUpString), "phone.ini" );
// Формируем во временном буфере sTmp команду разрыва соединения wsprintf( sTmp, "%s\r", szHangUpString );
// Определяем текущий момент времени StartTick = GetTickCount();
// Формируем задержку while( StartTick + (DWORD)lnModemTimeout > GetTickCount() ) Idle();
// Передаем модему последовательность "+++" для перевода его // в командный режим WriteComm( idComDev, "+++", 3);
// Определяем текущий момент времени StartTick = GetTickCount();
// Формируем задержку while( StartTick + (DWORD)lnModemTimeout > GetTickCount() ) Idle();
// Передаем модему команду разорвать соединение и повесить трубку WriteComm( idComDev, sTmp, lstrlen( sTmp ) );
EscapeCommFunction(idComDev, CLRDTR);
return 0; }
// ===================================== // Функция ShowError // =====================================
void ShowError( int iErr ) { int iNum; char szMsgBuff[40];
// Не известная ошибка соответствующей ошибке if(( iErr < -6 ) || ( iErr >= 0 )) return;
// Загружаем из ресурсов порриложения строку // с идентификатором iErr LoadString( hInst, iErr, szMsgBuff, 40 );
// Отображаем на экране сообщение об ошибке BWCCMessageBox( NULL, szMsgBuff, "Ошибка", MB_OK | MB_ICONSTOP );
// Подаем звуковой сигнал MessageBeep( MB_ICONASTERISK );
return; }
// =================================================================== // Функция ReadComPort // ===================================================================
int ReadComPort(int idComDev, LPSTR szDest, int nLength) {
COMSTAT ComStat; int nTotalRead = 0, nRead = 0;
while(nLength > nTotalRead) { // Определяем состояние COM-порта GetCommError(idComDev,&ComStat);
// Если во входной очереди нет данных завершаем функцию if (ComStat.cbInQue == 0) break;
// Считываем данные в буфер szDest else nRead = ReadComm(idComDev,&(szDest[nTotalRead]), nLength - nTotalRead); // Если функция ReadComm завершилась с ошибкой возвращаем -1
if (nRead < 0) return -1;
nTotalRead += nRead; }
// Возвращаем число прочитанных из COM-порта байт return nTotalRead; }
// =================================================================== // Функция WaitModemAnswer // =================================================================== int WaitModemAnswer(int idComDev, LPSTR *szWaitDest, LPSTR szModemAnswer, int nLength, DWORD dwTimeOut) { int nRead; int nTotalChar = 0, i; DWORD dwStartTick; BOOL fFind = FALSE;
// Определяем текущий момент времени dwStartTick = GetTickCount();
do { // Считываем данные из COM-порта nRead = ReadComPort(idComDev, &szModemAnswer[nTotalChar], nLength - lstrlen(szModemAnswer));
// В случае ошибки возвращаем ERR_READ if(nRead < 0) return ERR_READ;
else if(nRead > 0) { nTotalChar += nRead;
// Добавляем в конец полученных данных двоичный ноль szModemAnswer[nTotalChar] = '\0';
// Проверяем получен ли от модема ответ из массива szWaitDest for(int i = 0; szWaitDest[i]; i++) { if(strstr(szModemAnswer, szWaitDest[i])) { // Если ответ получен, завершаем чтение данных // и возвращаем управвление fFind = TRUE; break; } } }
// Разрешаем обработку сообщений для других приложений else Idle();
// Выходим из цикла если от модема получен ожидаемый ответ, // возникла ошибка при чтении данных или истекло время ожидания // ответа (nTimeOut * 1000)
} while (!fFind && nRead >= 0 && dwStartTick + dwTimeOut > GetTickCount() );
if(nRead >= 0 && !fFind) return ERR_TIMEOUT;
// Возвращаем количесттво пррочитанных символов return lstrlen( szModemAnswer ); }
// =================================================================== // Функция Idle // =================================================================== void Idle(void) { MSG msg;
while( PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); }
return; }
|
Правда на API/
--------------------
"Нужно делать так, как нужно, а как не нужно, делать не нужно" (с) Винни-Пух.
|