vb6 - Non-blocking read of stdin? -
i need have form-based application check stdin periodically input, still perform other processing. scripting.textstream.read() , readfile() api blocking, there non-blocking method of reading stdin in vb6?
with timer1
set fire every 100 ms, i've tried:
private declare function allocconsole lib "kernel32" () long private declare function freeconsole lib "kernel32" () long dim sin scripting.textstream private sub form_load() allocconsole dim fso new scripting.filesystemobject set sin = fso.getstandardstream(stdin) timer1.enabled = true end sub private sub timer1_timer() dim cmd string while not sin.atendofstream cmd = sin.read(1) select case cmd ' case statements process each byte read... end select wend end sub
i've tried:
private declare function allocconsole lib "kernel32" () long private declare function freeconsole lib "kernel32" () long private declare function getstdhandle lib "kernel32" (byval nstdhandle long) long private declare function readfilea lib "kernel32" alias "readfile" (byval hfile long, lpbuffer any, byval nnumberofbytestoread long, lpnumberofbytesread long, lpoverlapped any) long private declare function closehandle lib "kernel32" (byval hobject long) long private const std_input_handle = -10& dim hstdin long private sub form_load() allocconsole hstdin = getstdhandle(std_input_handle) timer1.enabled = true end sub private sub timer1_timer() dim bytesread long dim cmd string cmd = space$(16) cmd = readfile(hstdin, byval cmd, len(cmd), bytesread, byval 0&) ' statements process each line read... end sub
i've tried readconsole() api, too, block.
use vbadvance add-in compile following sample "build console application" option checked.
option explicit '--- getstdhandle private const std_input_handle long = -10& private const std_output_handle long = -11& '--- peekconsoleinput private const key_event long = 1 '--- getfiletype private const file_type_pipe long = &h3 private const file_type_disk long = &h1 private declare function getstdhandle lib "kernel32" (byval nstdhandle long) long private declare function getconsolemode lib "kernel32" (byval hconsolehandle long, lpmode long) long private declare function setconsolemode lib "kernel32" (byval hconsolehandle long, byval dwmode long) long private declare function peeknamedpipe lib "kernel32" (byval hnamedpipe long, lpbuffer any, byval nbuffersize long, byval lpbytesread long, lptotalbytesavail long, byval lpbytesleftthismessage long) long private declare function readfile lib "kernel32" (byval hfile long, lpbuffer any, byval nnumberofbytestoread long, lpnumberofbytesread long, byval lpoverlapped long) long private declare function oemtocharbuff lib "user32" alias "oemtocharbuffa" (byval lpszsrc string, byval lpszdst string, byval cchdstlength long) long private declare function writefile lib "kernel32" (byval hfile long, lpbuffer any, byval nnumberofbytestowrite long, lpnumberofbyteswritten long, lpoverlapped any) long private declare function chartooembuff lib "user32" alias "chartooembuffa" (byval lpszsrc string, lpszdst any, byval cchdstlength long) long private declare function peekconsoleinput lib "kernel32" alias "peekconsoleinputa" (byval hconsoleinput long, lpbuffer any, byval nlength long, lpnumberofeventsread long) long private declare function readconsoleinput lib "kernel32" alias "readconsoleinputa" (byval hconsoleinput long, lpbuffer any, byval nlength long, lpnumberofeventsread long) long private declare function getfiletype lib "kernel32" (byval hfile long) long sub main() dim hstdin long dim sbuffer string dim dbltimer double hstdin = getstdhandle(std_input_handle) sbuffer = sbuffer & consolereadavailable(hstdin) if dbltimer + 1 < timer dbltimer = timer call oemtocharbuff(sbuffer, sbuffer, len(sbuffer)) consoleprint "%1: %2" & vbcrlf, format$(timer, "0.00"), sbuffer sbuffer = vbnullstring end if loop end sub private function consolereadavailable(byval hstdin long) string dim ltype long dim sbuffer string dim lchars long dim lmode long dim lavailchars long dim babuffer(0 512) byte dim levents long ltype = getfiletype(hstdin) if ltype = file_type_pipe if peeknamedpipe(hstdin, byval 0, 0, 0, lavailchars, 0) = 0 exit function end if end if if ltype = file_type_disk or lavailchars > 0 sbuffer = space(iif(lavailchars > 0, lavailchars, 512)) call readfile(hstdin, byval sbuffer, len(sbuffer), lchars, 0) consolereadavailable = left$(sbuffer, lchars) end if if getconsolemode(hstdin, lmode) <> 0 call setconsolemode(hstdin, 0) while peekconsoleinput(hstdin, babuffer(0), 1, levents) <> 0 if levents = 0 exit end if if babuffer(0) = key_event , babuffer(4) <> 0 ' babuffer(4) = input_record.bkeydown sbuffer = space(1) call readfile(hstdin, byval sbuffer, len(sbuffer), lchars, 0) consolereadavailable = consolereadavailable & left$(sbuffer, lchars) else call readconsoleinput(hstdin, babuffer(0), 1, levents) end if loop call setconsolemode(hstdin, lmode) end if end function public function consoleprint(byval stext string, paramarray a() variant) string ' const func_name string = "consoleprint" dim li long dim sarg string dim babuffer() byte dim dwdummy long '--- format li = ubound(a) lbound(a) step -1 sarg = replace(a(li), "%", chrw$(&h101)) stext = replace(stext, "%" & (li - lbound(a) + 1), sarg) next consoleprint = replace(stext, chrw$(&h101), "%") '--- output redim babuffer(1 len(consoleprint)) byte if chartooembuff(consoleprint, babuffer(1), ubound(babuffer)) call writefile(getstdhandle(std_output_handle), babuffer(1), ubound(babuffer), dwdummy, byval 0&) end if end function
Comments
Post a Comment