Updated 1/1/09 Log file should be opened fpr append shared. Thanks, Scott Slater.
Check an IP address if valid or a range of IP addresses.
1) Portion of code might be used to test IP before using TCP OPEN
2) Now loads in PBForms.
3) Missing 2 ()'s in CALL statements in original source (might have been valid at some time?)
....This may have stopped some from viewing this excellent code by William Burns ....
Comments:
Original source:
Check an IP address if valid or a range of IP addresses.
1) Portion of code might be used to test IP before using TCP OPEN
2) Now loads in PBForms.
3) Missing 2 ()'s in CALL statements in original source (might have been valid at some time?)
....This may have stopped some from viewing this excellent code by William Burns ....
Comments:
Original source:
Code:
'Original source by William Burns 'http://www.powerbasic.com/support/pbforums/showthread.php?t=24059 'GetHostNames2.Bas 'Reason: Allows loading into PBForms ' 'Reason: 'Ability to load into PBForms '2 call statements missing () would not compile 'ghDlg can't be used to create a dialog in PbForms 'String variables can not be used while creating a form '========================================================== 'Code has an excellent routine for checking if an 'IP address is valid which could be used before attempting 'to TCP OPEN! Perhaps newer PB versions have this? '=========================================================== ' 'Happy New Years! Mike Doty 12/29/08 #PBFORMS CREATED V1.52 'Original source by William Burns 'http://www.powerbasic.com/support/pbforums/showthread.php?t=24059 'GetHostNames2.Bas 'Reason: Allows loading into PBForms ' 'Reason: 'Ability to load into PBForms 'A of couple call statements missing () would not compile 'ghDlg can't be used to create a dialog in PbForms 'String variables can not be used while creating a form '========================================================== 'Code has an excellent routine for checking if an 'IP address is valid which could be used before attempting 'to TCP OPEN! Perhaps newer PB versions have this? '=========================================================== ' 'Happy New Years! Mike Doty 12/29/08 #PBFORMS CREATED V1.52 #COMPILE EXE #DIM ALL #PBFORMS BEGIN INCLUDES #IF NOT %DEF(%WINAPI) #INCLUDE "WIN32API.INC" #ENDIF #PBFORMS END INCLUDES #INCLUDE "wSock32.inc" #INCLUDE "IpHlpAPI.inc" #INCLUDE "LMACCESS.Inc" #INCLUDE "LMERR.Inc" #INCLUDE "comdlg32.inc" 'used for file save/open windows ' ** Constants ** #PBFORMS BEGIN CONSTANTS %IDD_DIALOG1 = 101 %IDUNUSED = 1001 %PROGRESS = 1002 %TXTFROM = 1004 %TXTTO = 1005 %BUTSTART = 1006 %BUTABORT = 1007 %TXTFILENAME = 1008 %LISTBOX1 = 1009 %BUTEXIT = 1010 %BUTOPEN = 1011 %CHKIP = 1012 %CHKMULTI = 1013 %OPTSPACE = 1014 %OPTTAB = 1015 %IDR_MENU1 = -1 #PBFORMS END CONSTANTS GLOBAL ghDlg AS DWORD GLOBAL gAbort AS LONG GLOBAL gHosts AS LONG GLOBAL gTimeOut AS LONG GLOBAL gThreadCount AS LONG GLOBAL gsFileName AS STRING '------------------------------------------------------------------------------ ' ** Declarations ** '------------------------------------------------------------------------------ DECLARE CALLBACK FUNCTION ShowDIALOG1Proc() DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG DECLARE FUNCTION AttachMENU1(BYVAL hDlg AS DWORD) AS DWORD #PBFORMS DECLARATIONS '================================================== FUNCTION PBMAIN() gTimeOut = 500 ShowDIALOG1 %HWND_DESKTOP END FUNCTION FUNCTION MyMsg(sMyMsg AS STRING) AS LONG LOCAL iRet AS LONG LOCAL ASZ AS APISIZE LOCAL hCtl AS LONG LOCAL hDC AS LONG LOCAL hFont AS LONG STATIC iLstWidth AS LONG CONTROL HANDLE ghDlg, %LISTBOX1 TO hCtl CONTROL SEND ghDlg, %LISTBOX1, %WM_GETFONT, 0, 0 TO hFont sMyMsg = DATE$ + " " + TIME$ & " " & sMyMsg hDC = GetDC(hCtl) 'get the DC for the listbox IF hDC THEN IF hFont THEN hFont = SelectObject(hDC, hFont) 'select font in to it GetTextExtentPoint32 hDC, BYCOPY sMyMsg + "M", LEN(sMyMsg) + 1, ASZ 'get text length IF ASZ.cx > iLstWidth THEN iLstWidth = ASZ.cx CONTROL SEND ghDlg, %LISTBOX1, %LB_SETHORIZONTALEXTENT, iLstWidth, 0 END IF LISTBOX ADD ghDlg, %LISTBOX1, sMyMsg CONTROL SEND ghDlg, %LISTBOX1, %LB_GETCOUNT,0,0 TO iRet CONTROL SEND ghDlg, %LISTBOX1, %LB_SETCURSEL, iRet -1, 0 FUNCTION = 1 END IF DIALOG DOEVENTS END FUNCTION '================================================== SUB AddMyFile(BYVAL sFileName AS STRING, BYVAL sText AS STRING) LOCAL iFile AS LONG TRY iFile = FREEFILE OPEN sFileName FOR APPEND SHARED AS iFile '1/1/09 Scott Slater PRINT #iFile, sText CLOSE iFile CATCH CLOSE iFile END TRY END SUB '================================================== FUNCTION String2IP(sIP AS STRING) AS DWORD LOCAL dIP AS DWORD LOCAL pIP AS BYTE PTR pIP = VARPTR(dIP) @pIP = VAL(PARSE$(sIP,".",1)) '1st octet @pIP[1] = VAL(PARSE$(sIP,".",2)) '2nd octet @pIP[2] = VAL(PARSE$(sIP,".",3)) '3rd octet @pIP[3] = VAL(PARSE$(sIP,".",4)) '4th octet FUNCTION = dIP END FUNCTION '================================================== FUNCTION IP2String(dRawAddr AS DWORD) AS STRING DIM pIP AS BYTE PTR pIP = VARPTR(dRawAddr) FUNCTION = USING$("#_.#_.#_.#", @pIP, @pIP[1], @pIP[2], @pIP[3]) END FUNCTION '================================================== FUNCTION IsValidIP(BYVAL sIP AS STRING) AS LONG LOCAL iCount AS LONG IF ISTRUE VERIFY(sIP, "0123456789.") THEN EXIT FUNCTION IF INSTR(1,sIP,"..") THEN EXIT FUNCTION IF PARSECOUNT(sIP, ".") <> 4 THEN EXIT FUNCTION FOR iCount = 1 TO 4 IF VAL(PARSE$(sIP, ".", iCount)) > 255 THEN EXIT FUNCTION NEXT iCount FUNCTION = %TRUE END FUNCTION '================================================== FUNCTION IncrIpRange(IP AS DWORD, ToIP AS DWORD) AS LONG 'increases to the next IP address LOCAL pIP AS BYTE PTR LOCAL pToIP AS BYTE PTR LOCAL iRet AS LONG pIP = VARPTR(IP) pToIP = VARPTR(ToIP) INCR @pIP[3] '4th octet IF @pIP[3] = 0 THEN INCR @pIP[2] '3rd octet IF @pIP[2] = 0 THEN INCR @pIP[1] '2nd octet IF @pIP[1] = 0 THEN INCR @pIP '1st octet END IF END IF END IF iRet = %TRUE '%TRUE unless we find otherwise IF @pIP[3] > @pToIP[3] THEN iRet = %FALSE '4th octet is greater so %FALSE IF @pIP[2] < @pToIP[2] THEN iRet = %TRUE '3rd octet is lessthan so %TRUE even if 4th octet is greater IF @pIP[2] > @pToIP[2] THEN iRet = %FALSE '3rd octet is greater so %FALSE IF @pIP[1] < @pToIP[1] THEN iRet = %TRUE '2nd octet is lessthan so %TRUE even if 3rd or 4th octet is greater IF @pIP[1] > @pToIP[1] THEN iRet = %FALSE '2nd octet is greater so %FALSE IF @pIP < @pToIP THEN iRet = %TRUE '1st octet is lessthan so %TRUE even if 2nd or 3rd or 4th octet is greater IF @pIP > @pToIP THEN iRet = %FALSE '1st octet is greater so %FALSE FUNCTION = iRet 'returns %FALSE if new IP is past ToIP END FUNCTION '================================================== FUNCTION PingOneThread(BYVAL dIp AS DWORD) AS LONG LOCAL iRet AS LONG LOCAL iSize AS LONG LOCAL sText AS STRING LOCAL hFile AS DWORD LOCAL zPingData AS ASCIIZ * 21 LOCAL sHostname AS STRING LOCAL IECHOR AS STRING LOCAL pIECHOR AS ICMP_ECHO_REPLY PTR LOCAL IPOPTION AS IP_OPTION_INFORMATION LOCAL iIncludeIP AS LONG LOCAL sDelim AS STRING IF gAbort THEN GOTO PingCleanup IF gTimeOut < 1 THEN gTimeOut = 2000 'set default timeout to 2 seconds zPingData = "1234567890abcdefghij" hFile = IcmpCreateFile() IPOPTION.Ttl = 64 IPOPTION.Tos = 0 IPOPTION.Flags = &H02 'DONT FRAGMENT IPOPTION.OptionsSize = 0 IPOPTION.OptionsData = %NULL IECHOR = SPACE$(50) 'setup buffer size pIECHOR = STRPTR(IECHOR) @pIECHOR.Options = IPOPTION iSize = 48 iRet = IcmpSendEcho(hFile, dIp, zPingData, BYVAL 20, BYVAL VARPTR(IPOPTION), BYVAL STRPTR(IECHOR), iSize, gTimeOut) IF gAbort THEN GOTO PingCleanup IF iRet > 0 THEN 'ping was successful so now check host name HOST NAME dIp TO sHostname 'get host name from DNS IF INSTR(1,sHostName,".") THEN sHostName = LEFT$(sHostName,INSTR(1,sHostName,".")-1) 'strip off things like .sc.domain.com sHostName = UCASE$(sHostName) IF LEN(sHostName) > 0 THEN MyMsg LSET$(IP2String(dIp),16) + " " + sHostName CONTROL GET CHECK ghDlg, %OPTTAB TO iRet IF iRet THEN sDelim = $TAB ELSE sDelim = " " END IF CONTROL GET CHECK ghDlg, %CHKIP TO iIncludeIP IF iIncludeIP THEN AddMyFile(gsFileName, IP2String(dIp) + sDelim + sHostName) ELSE AddMyFile(gsFileName, sHostName) END IF INCR gHosts ELSE MyMsg LSET$(IP2String(dIp),16) + " Device found, but has no host name. (may be a phone switch, sec system, ...)" END IF ELSE SELECT CASE @pIECHOR.STATUS CASE 11002 TO 11005 MyMsg LSET$(IP2String(dIp),16) + " Destination unreachable" CASE 11010 MyMsg LSET$(IP2String(dIp),16) + " no device found." 'Request timed out CASE ELSE MyMsg LSET$(IP2String(dIp),16) + " Unknown Error while sending ICMP Echo. Ret=" + STR$(@pIECHOR.STATUS) END SELECT END IF PingCleanup: CALL IcmpCloseHandle(hFile) CALL InterlockedDecrement (gThreadCount) 'placed gThreadCount within () 12/29/08 MD END FUNCTION '================================================== FUNCTION MultiScan(BYVAL sIpFrom AS STRING, BYVAL sIpTo AS STRING, BYVAL iMultiThread AS LONG) AS LONG LOCAL dRet AS DWORD LOCAL iRet AS LONG LOCAL WSAD AS WSADATA LOCAL lVerNeeded AS WORD LOCAL hThread AS DWORD LOCAL dIpFrom AS DWORD LOCAL dIpTo AS DWORD lVerNeeded = MAKWRD(2,0) 'set the low byte to 2 and high byte to 0 (ver 2.0) iRet = WSAStartup(lVerNeeded, WSAD) 'start windows socket with min winsock version of 2.0 'AddList " You have Winsock version" + Str$(LoByt(WSAD.wHighVersion)) + "." + Str$(HiByt(WSAD.wHighVersion)) IF iRet OR LOBYT(WSAD.wVersion) < 2 THEN MSGBOX " Error... This function requires WinSock version 2 or latter." + $CRLF _ + " You have version" + STR$(LOBYT(WSAD.wHighVersion)) + "." + STR$(HIBYT(WSAD.wHighVersion)) + $CRLF _ + " You can download this free update from Microsofts web page.",,"Need newer wsock version" ELSE dIpFrom = String2IP(sIpFrom) dIpTo = String2IP(sIpTo) CONTROL GET TEXT ghDlg, %TXTFILENAME TO gsFileName DO WHILE ISFALSE gAbort 'MyMsg "Creating thread " + IP2String(dIpFrom) THREAD CREATE PingOneThread(dIpFrom) TO hThread THREAD CLOSE hThread TO iRet CALL InterlockedIncrement (gThreadCount) 'placed gThreadCount within () 12/29/08 MD SLEEP 0 IF ISFALSE iMultiThread THEN DO WHILE gThreadCount > 0 AND gAbort = 0 'MyMsg "Waiting for thread to close" SLEEP 20 LOOP END IF IF gThreadCount > 25 THEN SLEEP 100 'a couple of secs to let things catch up IF ISFALSE IncrIPRange(dIpFrom, dIpTo) THEN EXIT LOOP LOOP END IF DO WHILE gThreadCount > 0 'wait here if multithreaded for threads to end before cleanup IF ISFALSE iMultiThread THEN EXIT LOOP SLEEP 100 'If gAbort Then Exit Loop LOOP CALL WSACleanup() END FUNCTION '================================================== FUNCTION Open_File(BYVAL hWin AS DWORD) AS LONG LOCAL hFile AS LONG LOCAL iMulti AS LONG LOCAL sOpenFile AS STRING LOCAL sFilter AS STRING LOCAL sTextFrom AS STRING LOCAL sTextTo AS STRING LOCAL sText AS STRING gAbort = 0 CONTROL DISABLE hWin, %BUTSTART CONTROL ENABLE hWin, %BUTABORT sFilter = "Text Files (*.txt)" & CHR$(0) & "*.txt" & CHR$(0) & _ "List Files (*.lst)" & CHR$(0) & "*.lst" & CHR$(0) & _ "All Files (*.*)" & CHR$(0) & "*.*" & CHR$(0) & CHR$(0) sOpenFile = "*.txt" CALL OpenFileDialog(hWin, "Choose your IP range list file", sOpenFile, "", sFilter, "TXT", %OFN_EXPLORER OR %OFN_LONGNAMES OR %OFN_PATHMUSTEXIST) sOpenFile = TRIM$(sOpenFile) IF sOpenFile <> "" AND LEFT$(sOpenFile,1) <> "*" THEN TRY SetTimer ghDlg, 101, 200, 0 hFile = FREEFILE OPEN sOpenFile FOR INPUT AS #hFile MyMsg "-------- Processing Range List: " + sOpenFile + " --------" DO WHILE ISFALSE EOF(hFile) IF gAbort THEN EXIT LOOP LINE INPUT #hFile, sText IF PARSECOUNT(sText,".") = 7 OR PARSECOUNT(sText,".") = 4 THEN 'valid range ex: 10.145.224.1-10.145.225.254 or single IP sTextFrom = PARSE$(sText,"-",1) IF PARSECOUNT(sText,".") = 7 THEN sTextTo = PARSE$(sText,"-",2) ELSE sTextTo = sTextFrom 'one IP address END IF IF INSTR(1,sText,"=") THEN 'does it have a location code? sTextTo = PARSE$(sTextTo,"=",1) 'strip off loc code END IF IF IsValidIP(sTextFrom) AND IsValidIP(sTextTo) THEN CONTROL GET CHECK ghDlg, %CHKMULTI TO iMulti CALL MultiScan(sTextFrom, sTextTo, iMulti) ELSE MyMsg "Invalid range entry: " + sText END IF ELSE MyMsg "Invalid range entry: " + sText END IF LOOP CLOSE hFile KillTimer ghDlg, 101 CONTROL SET TEXT ghDlg, %PROGRESS, "." CATCH CLOSE hFile MSGBOX "Error opening file " + sOpenFile,,"Error " + STR$(ERR) + " " + ERROR$(ERR) END TRY END IF CONTROL DISABLE hWin, %BUTABORT CONTROL ENABLE hWin, %BUTSTART IF gAbort THEN MyMsg "Aborted by user." ELSE MyMsg "Done scanning." END IF END FUNCTION '================================================== FUNCTION StartScan(BYVAL hWin AS DWORD) AS LONG LOCAL sTextFrom AS STRING LOCAL sTextTo AS STRING LOCAL sText AS STRING LOCAL iMulti AS LONG gAbort = 0 gHosts = 0 CONTROL DISABLE hWin, %BUTSTART CONTROL ENABLE hWin, %BUTABORT CONTROL GET TEXT hWin, %TXTFROM TO sTextFrom CONTROL GET TEXT hWin, %TXTTO TO sTextTo IF IsValidIP(sTextFrom) AND IsValidIP(sTextTo) THEN sText = INPUTBOX$("Enter scan timeout in miliseconds (1000 = 1 sec)" + $CRLF _ + "Smaller value = faster scan." + $CRLF _ + "Too small = find nothing at remote sites." + $CRLF _ ,"Enter Scan TimeOut",STR$(gTimeOut)) IF VAL(sText) > 0 THEN gTimeOut = VAL(sText) SetTimer ghDlg, 101, 100, 0 CONTROL GET CHECK ghDlg, %CHKMULTI TO iMulti CALL MultiScan(sTextFrom, sTextTo, iMulti) IF gAbort THEN MyMsg "Aborted by user." ELSE MyMsg "Done scanning. Found " + STR$(gHosts) END IF KillTimer ghDlg, 101 CONTROL SET TEXT ghDlg, %PROGRESS, "." ELSE MyMsg "Invalid IP address range: " + sTextFrom + " - " + sTextTo END IF CONTROL DISABLE hWin, %BUTABORT CONTROL ENABLE hWin, %BUTSTART END FUNCTION '================================================== CALLBACK FUNCTION Form1_DLGPROC 'CALLBACK FUNCTION ShowDIALOG1Proc (default) LOCAL hThread AS DWORD LOCAL iRet AS DWORD STATIC sStep AS STRING STATIC iStep AS LONG SELECT CASE CBMSG CASE %WM_INITDIALOG sStep = "/=\|" 'or try "_<^>" or "/=\|" or "..oO" CASE %WM_CLOSE gAbort = 1 SLEEP 500 CASE %WM_TIMER iStep = (iStep + 1) MOD 4 CONTROL SET TEXT ghDlg, %PROGRESS, MID$(sStep, iStep + 1, 1) CASE %WM_COMMAND SELECT CASE CBCTL CASE %BUTSTART THREAD CREATE StartScan(CBHNDL) TO hThread THREAD CLOSE hThread TO iRet CASE %BUTOPEN THREAD CREATE Open_File(CBHNDL) TO hThread THREAD CLOSE hThread TO iRet CASE %BUTABORT gAbort = 1 CASE %BUTEXIT DIALOG END CBHNDL CASE ELSE END SELECT CASE ELSE END SELECT END FUNCTION '================================================== FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG LOCAL lRslt AS LONG #PBFORMS BEGIN DIALOG %IDD_DIALOG1->%IDR_MENU1-> LOCAL hDlg AS DWORD DIALOG NEW hParent, "Scan for Host Names Ver 1.7 by William", 219, _ 168, 277, 178, %WS_POPUP OR %DS_MODALFRAME OR %WS_CAPTION OR _ %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_SYSMENU OR %WS_THICKFRAME _ OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _ %WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR OR _ %WS_EX_CONTROLPARENT, TO hDlg CONTROL ADD FRAME, hDlg, %IDUNUSED, "Processing Log:", 5, 64, 266, 71, _ %WS_CHILD OR %WS_VISIBLE OR %BS_GROUPBOX, %WS_EX_TRANSPARENT CONTROL ADD FRAME, hDlg, %IDUNUSED, "Save Host Names to file:", 5, 34, _ 189, 27, %WS_CHILD OR %WS_VISIBLE OR %BS_GROUPBOX, _ %WS_EX_TRANSPARENT CONTROL ADD FRAME, hDlg, %IDUNUSED, "IP address range:", 5, 2, 189, _ 30, %WS_CHILD OR %WS_VISIBLE OR %BS_GROUPBOX, %WS_EX_TRANSPARENT CONTROL ADD LABEL, hDlg, %PROGRESS, ".", 200, 50, 16, 12, %WS_CHILD OR _ %WS_VISIBLE OR %SS_CENTER OR %WS_BORDER, %WS_EX_LEFT OR _ %WS_EX_LTRREADING CONTROL ADD LABEL, hDlg, %IDUNUSED, "-", 91, 15, 16, 12, %WS_CHILD OR _ %WS_VISIBLE OR %SS_CENTER, %WS_EX_LEFT OR %WS_EX_LTRREADING CONTROL ADD TEXTBOX, hDlg, %TXTFROM, "(see below) Text + .1", 11, 15, 77, 12 CONTROL ADD TEXTBOX, hDlg, %TXTTO, "(see below) sText + .255", 109, 15, 77, 12 CONTROL ADD BUTTON, hDlg, %BUTSTART, "&Scan", 205, 7, 53, 15, %WS_CHILD _ OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP OR %BS_CENTER OR _ %BS_VCENTER OR %BS_TEXT, %WS_EX_LEFT OR %WS_EX_LTRREADING CONTROL ADD BUTTON, hDlg, %BUTABORT, "&Abort", 205, 27, 53, 15, _ %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP OR _ %BS_CENTER OR %BS_VCENTER OR %BS_TEXT, %WS_EX_LEFT OR _ %WS_EX_LTRREADING CONTROL ADD TEXTBOX, hDlg, %TXTFILENAME, "C:\HostsFound.txt", 11, 44, _ 176, 12 CONTROL ADD LISTBOX, hDlg, %LISTBOX1, , 11, 74, 254, 57, %WS_CHILD OR _ %WS_VISIBLE OR %LBS_NOTIFY OR %LBS_NOINTEGRALHEIGHT OR %WS_VSCROLL _ OR %WS_TABSTOP OR %WS_HSCROLL, %WS_EX_CLIENTEDGE CONTROL ADD CHECKBOX, hDlg, %CHKIP, "Include IP address in file delimited " + _ "with:", 5, 140, 140, 10 CONTROL ADD CHECKBOX, hDlg, %CHKMULTI, "Scan multiple IPs at a time.", 5, _ 152, 140, 10 ' %WS_GROUP... CONTROL ADD OPTION, hDlg, %OPTSPACE, "Spaces", 150, 145, 40, 10, _ %WS_CHILD OR %WS_VISIBLE OR %BS_AUTORADIOBUTTON OR %WS_TABSTOP OR _ %WS_GROUP, %WS_EX_LEFT OR %WS_EX_LTRREADING CONTROL ADD OPTION, hDlg, %OPTTAB, "Tabs", 190, 145, 30, 10, %WS_CHILD _ OR %WS_VISIBLE OR %BS_AUTORADIOBUTTON OR %WS_TABSTOP, %WS_EX_LEFT OR _ %WS_EX_LTRREADING AttachMENU1 hDlg #PBFORMS END DIALOG ghDlg = hDlg 'added this: ghDlg can't be used in PBFORMS creating Dialog LOCAL iHost AS LONG LOCAL sText AS STRING HOST ADDR TO iHost IF iHost THEN sText = LEFT$(IP2String(iHost),INSTR(-1,IP2String(iHost),".")-1) ELSE sText = "10.123.123" 'DEFAULT ADDRESS END IF CONTROL SET TEXT hDlg,%TXTFROM,sText + ".1" CONTROL SET TEXT hDlg,%TXTTO,sText + ".255" DIALOG SHOW MODAL hDlg, CALL Form1_DLGPROC TO lRslt 'DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt (default) #PBFORMS BEGIN CLEANUP %IDD_DIALOG1 #PBFORMS END CLEANUP FUNCTION = lRslt END FUNCTION '================================================== FUNCTION AttachMENU1(BYVAL hDlg AS DWORD) AS DWORD #PBFORMS BEGIN MENU %IDR_MENU1->%IDD_DIALOG1 LOCAL hMenu AS DWORD LOCAL hPopUp1 AS DWORD MENU NEW BAR TO hMenu MENU NEW POPUP TO hPopUP1 MENU ADD POPUP, hMenu ,"&File", hPopUp1, %MF_ENABLED MENU ADD STRING, hPopUp1, "&Open and Process IP Range list", _ %BUTOPEN, %MF_ENABLED MENU ADD STRING, hPopUp1, "-", 0, 0 MENU ADD STRING, hPopUp1, "E&xit", %BUTEXIT, %MF_ENABLED MENU ATTACH hMenu, hDlg #PBFORMS END MENU FUNCTION = hMenu END FUNCTION