[ Pobierz całość w formacie PDF ]
.Czytelnik mo¿e siê o tym przekonaæ, testuj¹cprogram z tylko jednym buforem bez owej funkcji.Mo¿emy w praktyce spotkaæ siê z sytuacj¹, w której nale¿y szybko fizycznieusun¹æ, wykasowaæ jeszcze nie przetransmitowane lub odebrane znaki znajduj¹cesiê w buforze wyjœciowym lub wejœciowym.W tym celu mo¿na skorzystaæ z us³ug:BOOL PurgeComm(HANDLE hCommDev, DWORD fdwAction);gdzie fdwAction mo¿na przypisaæ jedn¹ z w³asnoœci lub ich kombinacjê:PURGE_TXABORT — wszelkie operacje zapisu (transmisji) do portu identyfikowanegoprzezhCommDev zostan¹ natychmiast przerwane, nawet je¿eli nie zosta³yzakoñczone.PURGE_RXABORT — wszelkie operacje odczytu z portu zostan¹ natychmiastprzerwane, nawetje¿eli nie zosta³y zakoñczone.PURGE_TXCLEAR — bufor wyjœciowy zostanie wyczyszczony; nast¹pi skasowaniezawartoœci.PURGE_RXCLEAR — bufor wejœciowy zostanie wyczyszczony, nast¹pi skasowaniezawartoœci.I w tym przypadku sta³e symboliczne PURGE_ z powodzeniem mo¿na potraktowaæ jakoswego rodzaju maski bitowe, reprezentuj¹ce w³aœciwe pozycje odpowiednich bitówz mo¿liwoœci¹ wykonywania na nich operacji logicznych.maskawartoœæbit 4bit 3bit 2bit 1bit 0PURGE_TXABORT11PURGE_RXABORT21PURGE_TXCLEAR41PURGE_RXCLEAR81Zauwa¿my te¿, ¿e PurgeComm() mo¿na u¿ywaæ „profilaktycznie” w ró¿nych czêœciachaplikacji, zale¿nie od naszych potrzeb.Nale¿y tylko pamiêtaæ, ¿e wywo³anie jejz PURGE_TXCLEAR lub PURGE_TXABORT ma sens jedynie przed odczytem danych, zaœ zPURGE_RXCLEAR lub PURGE_RXABORT tylko przed wys³aniem danych.Wywo³ania funkcji:Write_Comm(hCommDev, Buffer_O, strlen(Buffer_O));Zapisuje ona (wysy³a) do portu identyfikowanego przez hCommDev blok pamiêciokreœlony przez Buffer_O, o d³ugoœci strlen(Buffer_O), w którym znajduje siêci¹g znaków wskazany przez tê zmienn¹.Zaœ dziêki funkcji:Read_Comm(hCommDev, &Buffer_I[0], &Number_Bytes_Read,sizeof(Buffer_I));odczytujemy do bufora wejœciowego Buffer_I blok danych o rozmiarzeNumber_Bytes_Read, pochodz¹cych z ³¹cza identyfikowanego przez hCommDev.U¿yciesizeof(Buffer_I) zapewnia nam jedynie ustalenie górnego ograniczenia rozmiarubajtów, które spodziewamy siê otrzymaæ w wyniku transmisji szeregowej, jednakstosujemy je ze wzglêdów czysto praktycznych.Deklarowany rozmiar buforazostanie przekazany poprzez Buf_Size do funkcji ReadFile().Bez tego nie by³obysensu odwo³ywaæ siê do elementu cbInQue struktury COMSTAT, gdy¿ cbInQue niemia³oby punktu odniesienia! Równie dobrze funkcjê tê moglibyœmy wywo³aænastêpuj¹co:Read_Comm(hCommDev, Buffer_I, &Number_Bytes_Read,sizeof(Buffer_I));Jednak w przypadku jawnego czytania danych z bufora wejœciowego do dobregostylu programowania nale¿y u¿ywanie operatora &, daj¹cego adres zmiennejBuffer_I.Zatem pisz¹c &Buffer_I[0] jawnie odzyskujemy adres pocz¹tku ci¹guznaków znajduj¹cych siê w buforze wejœciowym.W miarê jak aplikacje zaczn¹ siêrozrastaæ, odrobina asekuranctwa mo¿e okazaæ siê niekiedy bardzo pomocna.Zwróæmy te¿ uwagê, ¿e chocia¿ mo¿na mieæ co do tego zastrze¿enia, to do plikudane.dat jawnie zapisaliœmy zawartoœæ komponentu Edit1.Zastosowane przez nas w powy¿szym przyk³adzie konstrukcje instrukcjiwarunkowych typu:if (hCommDev > 0){.if (Number_Bytes_Read > 0){.mo¿na oczywiœcie znacznie uproœciæ, pisz¹c je w postaci:if (hCommDev){.if (Number_Bytes_Read){.Podobn¹ sytuacjê bêdziemy mieli, je¿eli skorzystamy z instrukcji warunkowej ifprzy jawnym sprawdzaniu rezultatu wykonania funkcji API, zwracaj¹cych wartoœæTRUE (1) lub FALSE (0).Ogólnie nie jest to wymagane i stosowane przez naszapisy w wiêkszoœci wypadków mo¿na znacznie uproœciæ, np.zamiastif(WriteFile(.)>0) lub if(WriteFile(.)==TRUE), pisz¹c po prostuif(WriteFile(.)).W tym oraz dalszych przyk³adach jawne sprawdzanie podobnychwarunków zosta³o zachowane równie¿ w celu utrzymania wiêkszej przejrzystoœcikodu.PodsumowanieCzytaj¹c niniejszy podrozdzia³ dowiedzieliœmy siê ju¿ sporo na tematpodstawowych sposobów programowej realizacji transmisji szeregowej w œrodowiskuWindows za pomoc¹ C++Buildera.Umiemy ju¿ wykorzystywaæ niektóre struktury orazfunkcje oferowane nam przez Win32 API, obs³uguj¹ce operacje wejœcia-wyjœciaportu szeregowego.Dziêki zaznajomieniu siê z notacj¹ wêgiersk¹ znaczeniewskaŸników i zmiennych stosowanych w API przesta³o byæ dla nas tajemnic¹.Poznaliœmy te¿, w jaki sposób mo¿na kontrolowaæ ewentualne b³êdy wystêpuj¹ce wtrakcie transmisji oraz jak nale¿y minimalizowaæ ich wp³yw na dzia³anieaplikacji.Stworzyliœmy równie¿ programy testuj¹ce ³¹cze szeregowe oraz innyprogram realizuj¹cy ju¿ prawdziw¹ transmisjê.Wszystkie one zosta³yprzedstawione w taki sposób, aby mo¿na by³o je samodzielnie modyfikowaæ iewentualnie uzupe³nieniaæ.Dziêki temu wiemy, jakie wymagania bêd¹ wprzysz³oœci sta³y przed tego typu aplikacjami.Æwiczenia1.Zmodyfikuj formularz oraz kod programu RS_01.cpp tak, aby mo¿na by³oodczytaæ kompletn¹ informacjê o aktualnych ustawieniach wybranego portuszeregowego.Zmodyfikuj przyk³adowy program RS_03.cpp w taki sposób, aby mo¿na by³osamodzielnie po jego uruchomieniu okreœliæ nazwê pliku przechowuj¹cego odebranedane oraz œcie¿kê dostêpu do niego.Postaraj siê wykorzystaæ jedyniestandardowe funkcje C++ podtrzymywane w Windows oraz komponent typu TEdit.Na podstawie projektu p_RS_03.bpr stwórz aplikacjê, w której funkcjomWrite_Comm() oraz Read_Comm() bêd¹ przyporz¹dkowane oddzielne zdarzenia.Spróbuj samodzielnie zaprojektowaæ w³aœciwe relacje pomiêdzy nimi
[ Pobierz całość w formacie PDF ]