DEFINE CLASS Dialer AS CUSTOM nPort = 0 #DEFINE GENERIC_READ 0x80000000 #DEFINE GENERIC_WRITE 0x40000000 #DEFINE CF_TEXT CHR(13) + CHR(10) FUNCTION DialNumber LPARAMETERS PhoneNumber, CommPort DECLARE INTEGER WriteFile IN Win32API; INTEGER hFile, STRING @lpbuffer,; INTEGER nNumberOfBytesToWrite,; INTEGER @lpNumberOfBytesWritten,; STRING @lpOverlapped DECLARE INTEGER CreateFile IN Win32API; STRING @lpFileName, INTEGER dwDesiredAccess,; INTEGER dwShareMode,; STRING @lpSecurityAttributes, INTEGER dwCreationDisposition,; INTEGER dwFlagsAndAttributes, INTEGER hTemplateFile DECLARE INTEGER FlushFileBuffers IN Win32API; INTEGER hFile DECLARE INTEGER GetLastError IN Win32API LOCAL lnport, lnwritten, lcmnd,; lcport, lnresult lnresult = 0 lcport = CommPort lnport = CreateFile(@lcport, GENERIC_READ + GENERIC_WRITE, 0, 0, 3, 0, 0) IF lnport > 0 This.nPort = lnport lnwritten = 0 lccmnd = "ATDT" + PhoneNumber + CF_TEXT IF WriteFile(lnport, @lccmnd, LEN(lccmnd), @lnwritten, 0) # 0 * Flush the buffer to assure the data was written = FlushFileBuffers(lnport) ELSE lnresult = GetLastError() ENDIF ELSE lnresult = GetLastError() ENDIF RETURN lnresult ENDFUNC FUNCTION HangUp DECLARE INTEGER CloseHandle IN Win32API; INTEGER hObject LOCAL lccmnd, lnresult, lnport, lnwritten STORE 0 TO lnresult, lnwritten lnport = This.nPort lccmnd = 'ATH0' + CF_TEXT lnresult = WriteFile(lnport, @lccmnd, LEN(lccmnd), @lnwritten, 0) IF lnresult = 0 = FlushFileBuffers(lnport) * Close up = CloseHandle(lnport) ELSE lnresult = GetLastError() ENDIF RETURN lnresult ENDFUNC ENDDEFINE SET PROCEDURE TO Dialer ADDITIVE * Useage oDialier = CREATEOBEJECT('Dialer') RELEASE PROCEDURE Dialer IF oDialer # NULL ? oDialer.DialNumber('5555555', 'COM1') ? oDialer.HangUp() ENDIFNote: I did have some problems if the line was busy, but the code above seems to work as advertised.