Use comport to obtain all serial numbers in the computer:
Procedure tform1.formcreate (Sender: tobject); // obtain the serial number var cnumber: tstrings; I: integer; begin cbb2.items. clear; cnumber: = tstringlist. create; enumcomports (cnumber); // obtain the serial number function: enumcomports for I: = 0 to cnumber. count-1 do begin cbb2.items. add (cnumber. strings [I]) end; cbb2.itemindex: = 0; cnumber. free; end; procedure invoke (Sender: tobject); // open the serial port begin comport1.port: = cbb2.text; If comport1.connected then begin comport1.close; comport1.open; end else comport1.open; end;
When I started using comport, I found that it triggered a Receiving Event every time with 14 characters, and the complete frame of data I want to receive is 82 characters, therefore, I added the start code and end code to the front and back of each frame, a total of 84 characters. When the Count value is greater than 84, the program segment is as follows:
Procedure tfcomm. comportrxchar (Sender: tobject; count: integer); var receivedata: tdaterec; P: pbyte; Block: array [0 .. 85] of char; begin if (not ready) then begin comport. read (P, 1); // The start code is $ 7ffe. $ Fe move (p, secondbyte, 1) is received first ); if secondbyte = $ Fe then // If the received byte is $ Fe, check whether the next byte is $ 7f begin firstbyte: = secondbyte; comport. read (P, 1); move (p, secondbyte, 1); end; If (firstbyte = $ Fe) and (secondbyte = $ 7f) then ready: = true; if ready and (count> = 84) then begin .... End; end;
Some of Spcomm read the comport through regular queries, while comport uses the overlapped mechanism to read and write com. As long as com receives data, comport can respond to the event and notify the application to receive the data, some comport has better real-time performance. However, the event of overlapped is triggered, but it is not triggered when com accesses a complete piece of information. It is decided by windows. I have tried it on multiple computers and different Windows versions, the number of characters it receives after triggering is not the same. Therefore, you must create a buffer to process data.
Procedure tcustomcomport. createhandle; begin fhandle: = createfile (pchar ('\\. \ '+ fport), generic_read or generic_write, 0, nil, open_existing, timeout, // enable comport 0 in overlapped mode); If fhandle = invalid_handle_value then raise ecomport. create (cerror_openfailed, getlasterror); end; Procedure tcomthread. execute; var eventhandles: array [0 .. 1] of thandle; overlapped: toverlapped; signaled, bytestrans, mask: DWORD; begin fillchar (overlapped, sizeof (overlapped), 0); overlapped. hevent: = createevent (nil, true, true, nil); eventhandles [0]: = fstopevent; eventhandles [1]: = overlapped. hevent; // overlapped event repeat on the comport // wait for the event on com // wait for event to occur on serial port waitcommevent (fcomport. handle, mask, @ overlapped); signaled: = waitformultipleobjects (2, @ eventhandles, false, infinite); // If event occurs, dispatch it if (signaled = wait_object_0 + 1) and getoverlappedresult (fcomport. handle, overlapped, bytestrans, false) then begin // notify the application to receive data fevents: = inttoevents (mask); dispatchcommsg; end; until signaled <> (wait_object_0 + 1 ); // clear buffers setcommmask (fcomport. handle, 0); purgecomm (fcomport. handle, purge_txclear or purge_rxclear); closehandle (overlapped. hevent); closehandle (fstopevent); end;