Changeset 440 for PinConnection/USerialPort.pas
- Timestamp:
- Nov 19, 2012, 2:43:40 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
PinConnection/USerialPort.pas
r415 r440 6 6 7 7 uses 8 Classes, SysUtils, SynaSer, StdCtrls, Dialogs, UCommon, UThreading, 8 {$IFDEF Windows}Windows, {$ENDIF}Registry, 9 Classes, SysUtils, SynaSer, Dialogs, UCommon, UThreading, Syncobjs, 9 10 DateUtils, FileUtil, SpecializedList; 10 11 … … 49 50 FReceiveThread: TSerialPortReceiveThread; 50 51 FReceiveBuffer: TListByte; 52 function FindFriendlyName(Key: string; Port: string): string; 51 53 function GetName: string; 54 procedure GetSerialPortNamesExt(Strings: TStrings); 52 55 procedure SetBaudRate(const AValue: Integer); 53 56 procedure SetDataBits(const AValue: TDataBits); … … 62 65 procedure Close; 63 66 public 67 Lock: TCriticalSection; 64 68 property Name: string read GetName write SetName; 65 69 property FlowControl: TFlowControl read FFlowControl write SetFlowControl; … … 77 81 constructor Create; 78 82 destructor Destroy; override; 83 procedure Flush; 84 procedure Purge; 79 85 procedure Assign(Source: TObject); 80 86 end; … … 90 96 resourcestring 91 97 SAssignmentError = 'Assignment error'; 92 SWrongNumericBaudRate = 'Wrong numeric baud rate %s';93 98 SWrongDataBitsNumber = 'Wrong data bits number %s'; 94 99 … … 149 154 begin 150 155 Connect(FName); 151 //set_fDtrControl(DCB, 1); 152 //DCB.flags := ; 153 SetBaudRate(FBaudRate); 154 SetParity(FParity); 155 SetStopBits(FStopBits); 156 SetDataBits(FDataBits); 157 SetFlowControl(FFlowControl); 158 SetDTR(FDTR); 159 SetRTS(FRTS); 160 161 FReceiveThread := TSerialPortReceiveThread.Create(True); 162 FReceiveThread.FreeOnTerminate := False; 163 FReceiveThread.Parent := Self; 164 FReceiveThread.Name := 'SerialPort'; 165 FReceiveThread.Start; 156 if FHandle <> INVALID_HANDLE_VALUE then begin 157 //set_fDtrControl(DCB, 1); 158 //DCB.flags := ; 159 {$IFDEF DEBUG} 160 RaiseExcept := True; 161 {$ENDIF} 162 SetBaudRate(FBaudRate); 163 SetParity(FParity); 164 SetStopBits(FStopBits); 165 SetDataBits(FDataBits); 166 SetFlowControl(FFlowControl); 167 SetDTR(FDTR); 168 SetRTS(FRTS); 169 170 FReceiveThread := TSerialPortReceiveThread.Create(True); 171 FReceiveThread.FreeOnTerminate := False; 172 FReceiveThread.Parent := Self; 173 FReceiveThread.Name := 'SerialPort'; 174 FReceiveThread.Start; 175 end; 166 176 end; 167 177 168 178 procedure TSerialPort.Close; 169 179 begin 170 FreeAndNil(FReceiveThread); 171 CloseSocket; 180 if FHandle <> INVALID_HANDLE_VALUE then begin 181 FreeAndNil(FReceiveThread); 182 CloseSocket; 183 end; 184 end; 185 186 function TSerialPort.FindFriendlyName(Key: string; Port: string): string; 187 var 188 r: TRegistry; 189 k: TStringList; 190 i: Integer; 191 ck: string; 192 rs: string; 193 begin 194 r := TRegistry.Create; 195 k := TStringList.Create; 196 197 r.RootKey := HKEY_LOCAL_MACHINE; 198 r.OpenKeyReadOnly(key); 199 r.GetKeyNames(k); 200 r.CloseKey; 201 202 try 203 for i := 0 to k.Count - 1 do 204 begin 205 ck := key + k[i] + '\'; // current key 206 // looking for "PortName" stringvalue in "Device Parameters" subkey 207 if r.OpenKeyReadOnly(ck + 'Device Parameters') then 208 begin 209 if r.ReadString('PortName') = port then 210 begin 211 r.CloseKey; 212 r.OpenKeyReadOnly(ck); 213 rs := UTF8Encode(r.ReadString('FriendlyName')); 214 Break; 215 end 216 end 217 // keep looking on subkeys for "PortName" 218 else 219 begin 220 if r.OpenKeyReadOnly(ck) and r.HasSubKeys then 221 begin 222 rs := FindFriendlyName(ck, port); 223 if rs <> '' then Break; 224 end; 225 end; 226 end; 227 result := rs; 228 finally 229 r.Free; 230 k.Free; 231 end; 232 end; 233 234 procedure TSerialPort.GetSerialPortNamesExt(Strings: TStrings); 235 var 236 Reg: TRegistry; 237 l: TStringList; 238 n: integer; 239 pn, fn: string; 240 begin 241 l := TStringList.Create; 242 Reg := TRegistry.Create; 243 try 244 Reg.RootKey := HKEY_LOCAL_MACHINE; 245 if reg.OpenKeyReadOnly('HARDWARE\DEVICEMAP\SERIALCOMM') then 246 begin 247 Reg.GetValueNames(l); 248 for n := 0 to l.Count - 1 do 249 begin 250 pn := Reg.ReadString(l[n]); 251 fn := FindFriendlyName('\System\CurrentControlSet\Enum\', pn); 252 if fn <> '' then 253 Strings.Add(pn + Strings.NameValueSeparator + fn) 254 else Strings.Add(pn + Strings.NameValueSeparator + pn) 255 end; 256 end; 257 finally 258 L.Free; 259 Reg.Free; 260 end; 172 261 end; 173 262 … … 175 264 var 176 265 I: Integer; 266 {$IFDEF Linux}Files: TStringList;{$ENDIF} 177 267 TestPort: TSerialPort; 178 Files: TStringList;179 268 begin 180 269 Strings.Clear; 270 Strings.NameValueSeparator := '|'; 181 271 {$IFDEF Windows} 182 if Check then 183 try 184 TestPort := TSerialPort.Create; 185 for I := 0 to MaxPort - 1 do 186 with TestPort do begin 187 Name := 'COM' + IntToStr(I); 188 Active := True; 189 if Active then begin 190 Strings.AddObject(Name, nil); 272 if Check then begin 273 GetSerialPortNamesExt(Strings); 274 // If no ports with friendly names detected try open all ports (compatibility with Win98) 275 if Strings.Count = 0 then 276 try 277 TestPort := TSerialPort.Create; 278 for I := 0 to MaxPort - 1 do 279 with TestPort do begin 280 Name := 'COM' + IntToStr(I); 281 Active := True; 282 if (LastError = ERROR_SUCCESS) or (LastError = ERROR_ACCESS_DENIED) then 283 begin 284 Strings.AddObject(Name, nil); 285 end; 286 Active := False; 191 287 end; 192 Active := False; 288 finally 289 TestPort.Free; 193 290 end; 194 finally 195 TestPort.Free; 196 end else begin 291 end else begin 197 292 for I := 1 to MaxPort do 198 Strings.AddObject('COM' + IntToStr(I), nil); 293 Strings.AddObject('COM' + IntToStr(I) + Strings.NameValueSeparator + 294 'COM' + IntToStr(I), nil); 199 295 end; 200 296 {$ENDIF} … … 204 300 Files := FindAllFiles('/dev', 'tty*', False); 205 301 Strings.Assign(Files); 302 for I := 0 to Strings.Count - 1 do 303 Strings.Strings[I] := Strings.Strings[I] + Strings.NameValueSeparator + 304 Strings.Strings[I]; 206 305 finally 207 306 Files.Free; 208 307 end else begin 209 308 for I := 1 to 63 do 210 Strings.AddObject('/dev/ttyS' + IntToStr(I), nil); 309 Strings.AddObject('/dev/ttyS' + IntToStr(I) + Strings.NameValueSeparator + 310 '/dev/ttyS' + IntToStr(I), nil); 211 311 end; 212 312 {$ENDIF} … … 216 316 begin 217 317 inherited Create; 318 Lock := TCriticalSection.Create; 218 319 FReceiveBuffer := TListByte.Create; 219 320 FBaudRate := 9600; … … 231 332 begin 232 333 Active := False; 233 FReceiveThread.Free; 234 ReceiveBuffer.Free; 235 inherited Destroy; 334 FreeAndNil(FReceiveThread); 335 FreeAndNil(FReceiveBuffer); 336 FreeAndNil(Lock); 337 inherited; 338 end; 339 340 procedure TSerialPort.Flush; 341 begin 342 if FActive then begin 343 inherited Flush; 344 end; 345 end; 346 347 procedure TSerialPort.Purge; 348 begin 349 if FActive then 350 inherited Purge; 236 351 end; 237 352 … … 316 431 if InBufferUsed = 0 then Sleep(1); 317 432 //else Yield; 318 if Active then begin 433 if Active then 434 try 435 Parent.Lock.Acquire; 319 436 InBufferUsed := WaitingData; 320 437 if InBufferUsed > 0 then begin … … 325 442 Parent.FReceiveBuffer.Count := Length(Buffer); 326 443 Parent.FReceiveBuffer.ReplaceBuffer(0, PByte(Buffer)^, Length(Buffer)); 327 if Assigned(Parent.FOnReceiveData) then 328 Parent.FOnReceiveData(Parent.FReceiveBuffer); 444 if Assigned(Parent.FOnReceiveData) then begin 445 try 446 Parent.Lock.Release; 447 Parent.FOnReceiveData(Parent.FReceiveBuffer); 448 finally 449 Parent.Lock.Acquire; 450 end; 451 end; 329 452 end else InBufferUsed := 0; 453 finally 454 Parent.Lock.Release; 330 455 end else InBufferUsed := 0; 331 456 until Terminated;
Note:
See TracChangeset
for help on using the changeset viewer.