Announcement

Collapse
No announcement yet.

STDOUT replacement

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • STDOUT replacement

    I am writing an app that needs to be able to run in the GUI or
    the command line (console). The GUI portion is no problem,
    but the console portion is causing problems. Since PBDLL does
    not support STDOUT, I have been trying to use the WritFile API.
    The problem I am encountering is that in order to write to
    the console, I need to call AllocConsole. However, this
    creates a new console window.

    How do I write text to the console window that called the app
    (i.e., the console that the user typed the command)?

    I am not concerned with switching between GUI and console,
    and I realize that PBCC supports STDOUT.

    TIA




    ------------------

  • #2
    I don't know if this will work for you or not as you are also using dialogs at the same time. However, I found a program called MakeCons.exe that will change the special byte in a 32bit exe so that it is considered a console app instead of a gui app.

    Email me and I'll send it to you.

    Also, just as a comparison, this is the code I use for doing CGI stuff:

    I added these functions to the PBCC file: pbcgi.inc

    Code:
    SUB STDINLINE (psBuffer AS STRING)
        LOCAL lIn AS ASCIIZ * 524288 'Set to an acceptable number!
        LOCAL lBytes AS LONG
        ReadFile GetStdHandle(%STD_INPUT_HANDLE), lIn, 524288, lBytes, BYVAL %Null
        psBuffer = lIn
    END SUB
    
    SUB STDOUT (psBuffer AS STRING)
        LOCAL lOut AS ASCIIZ * 524288 'Set to an acceptable number!
    
        LOCAL lBytes AS LONG
        lOut = psBuffer
        WriteFile GetStdHandle(%STD_OUTPUT_HANDLE), lOut, LEN(lOut), lBytes, BYVAL %Null
    END SUB
    Using MakeCons.exe and then using these functions allowed me to not use AllocConsole.

    Colin Schmidt

    ------------------
    Colin Schmidt & James Duffy, Praxis Enterprises, Canada
    [email protected]

    [This message has been edited by Colin Schmidt (edited April 11, 2001).]

    Comment


    • #3
      I've not tried this myself, but how about using the GetConsoleWindow() API?

      See MSDN: http://msdn.microsoft.com/library/ps...nchar_3eif.htm


      ------------------
      Lance
      PowerBASIC Support
      mailto:[email protected][email protected]</A>
      Lance
      mailto:[email protected]

      Comment


      • #4
        Lance (and others) --
        If you don't want to repeat my mistakes, when I searched SetWindowLongPtr, always see "Remarks". http://msdn.microsoft.com/library/ps...nchar_3eif.htm doesn't have "Remarks".
        I found it in Win2000 SP1 (kernel32), but I am not even sure that this function exist in basic Win2000.

        Michael --
        I use a wrapper for PBDLL, which I called PbDll1.Exe.
        Initial purpose was to create PBR on "fly".
        Then I need to attach zlib.dll to the end of exe and I added this possibility also.

        Just now I included a possibility to mark PB/DLL as console (without patch).

        If you want to try, put pbdll1.bas (see below) into C:\PbDll60\Bin and compile it (do not execute !).
        Code:
           #Compile Exe
           #Dim All
           #Register None
           #Include "Win32Api.inc"
        
           Function PbMain
              Dim hKey As Long, dwDisposition As Long
              Dim PbDllPath As Asciiz * %MAX_PATH
              Dim RcPath As Asciiz * %MAX_PATH
              Dim PbResPath As Asciiz * %MAX_PATH
              Dim Er As Long
              Dim AttachFile As String
              Dim ConvertToConsole As Long
        
              Do
                 If RegCreateKeyEx(%HKEY_CURRENT_USER, "Software\PowerBasic\PB/DLL\6.00\Compiler", _
                    ByVal 0&, "", %REG_OPTION_NON_VOLATILE, %KEY_ALL_ACCESS, ByVal 0&, hKey, _
                    dwDisposition) <> %ERROR_SUCCESS Then Er = 1: Exit Do
                 If IsFalse(hKey) Then Er = 1: Exit Do
                 If RegQueryValueEx (hKey, "Compiler", ByVal 0&, %REG_SZ, PbDllPath, SizeOf(PbDllPath)) <> %ERROR_SUCCESS Then Er = 1: Exit Do
                 If RegQueryValueEx (hKey, "RcCompiler", ByVal 0&, %REG_SZ, RcPath, SizeOf(RcPath)) <> %ERROR_SUCCESS Then Er = 1: Exit Do
                    If RegQueryValueEx (hKey, "PbRes", ByVal 0&, %REG_SZ, PbResPath, SizeOf(PbResPath)) <> %ERROR_SUCCESS Then Er = 1: Exit Do
                 RegCloseKey hKey: Exit Do
              Loop
              If Er Then MsgBox "Problems": Exit Function
        
              Dim InitDir As String, FileDir As String, FileBas As String
              Dim i As Long, f As Long, Tmp As String, Rc As String, Prefix As String
        
              FileBas$ = UCase$(Parse$(Command$, Any " ", 1))
              i = Instr(-1, FileBas, "\")
              FileDir = Left$(FileBas, i)
              Prefix = Mid$(FileBas, i + 1, Len(FileBas) - i - 4)
        
              InitDir = CurDir$
        
              ChDir FileDir
              f = FreeFile
              Open Prefix + ".Bas" For Input Shared As #f Len = 32768
              While Not Eof(f)
                 Line Input #f, Tmp: Tmp = Trim$(Tmp)
                 Select Case UCase$(Parse$(Tmp, Any " ", 1))
                    Case "'%%": AttachFile = Trim$(Mid$(Tmp, 4))
                                If Instr(AttachFile, "\") = 0 Then AttachFile = FileDir + AttachFile
                    Case "'%": Rc = Rc + Trim$(Mid$(Tmp, 3)) + $CRLF
                    Case "'%&": ConvertToConsole = 1
                 End Select
              Wend
              Close #f
        
              If Len(Rc) Then
                 Open Prefix + ".Rc" For Binary As #f  Len = 32768
                 Get$ #f, Lof(f), Tmp: Close #f
        
                 If Tmp <> Rc Then
                    Open Prefix + ".Rc" For Output As #f  Len = 32768
                    Print #f, Rc;: Close #f
                    Shell RcPath + " " + Prefix, 0
                    Shell PbResPath + " " + Prefix, 0
                 End If
              End If
        
              ChDir InitDir
              If UCase$(FileDir + Prefix + ".Exe") = UCase$(PbDllPath) Then
                 ' For compiling itself (use "Compile" only; don't use "Build and Execute")
                 i = Shell(FileDir + "PbDll.Exe " + Command$, 1)
              Else
                 i = Instr(-1, PbDllPath, "\")
                 Shell Left$(PbDllPath, i) + "PbDll.Exe " + Command$, 1
        
                 If AttachFile <> "" Then
                    Open AttachFile For Binary As #f Len = 32768
                    Get$ #f, Lof(f), Tmp
                    Close #f
                    ' Attach DLL
                    AttachFile = Mid$(AttachFile, Instr(-1, AttachFile, "\") + 1)
                    Open FileDir + Prefix + ".Exe" For Append As #f Len = 32768
                    Print #f, Tmp AttachFile Chr$(Len(AttachFile)) Mkl$(Len(Tmp));
                    Close #f
                 End If
                 
                 If ConvertToConsole Then
                    Open FileDir + Prefix + ".Exe" For Binary As #f Len = 32768
                    Seek #1, 221: Put$ #1, Chr$(3): Close #f
                 End If
              End If
        
           End Function
        Then in PB/IDE change Window - Options - Compiler, path for compile:
        C:\PBDLL60\BIN\PBDLL1.EXE instead of C:\PBDLL60\BIN\PBDLL.EXE

        To make console app. include somewhere '%&

        Code:
           #Compile Exe
           #Register None
           #Dim All
           #Include "Win32Api.Inc"
         
           '%&
        
           Global hConsoleOutput As Long, hConsoleInput As Long
        
           Sub CPrint(x As String)
              WriteConsole hConsoleOutput, ByCopy x, Len(x), 0, %NULL
           End Sub
        
           Function InKey() As String
              Local lpBuffer As String * 1, lpNumberOfCharsRead As Long
              ReadConsole hConsoleInput, lpBuffer, 1, lpNumberOfCharsRead, ByVal %NULL
              Function = Left$(lpBuffer, lpNumberOfCharsRead)
           End Function
        
           Function PbMain
              Local Txt As String
              hConsoleOutput = GetStdHandle(%STD_OUTPUT_HANDLE)
              hConsoleInput  = GetStdHandle(%STD_INPUT_HANDLE)
              SetConsoleMode hConsoleInput, %NULL
              CPrint $CRLF + "PB/DLL module in PB/CC mode" + $CRLF + $CRLF + _
                    "Enter text and press Enter: "
              Do
                 Txt = Inkey
                 If Txt = $CR Then Exit Do
                 CPrint Txt
              Loop
              
           End Function
        ------------------
        E-MAIL: [email protected]

        Comment


        • #5
          If you don't want to repeat my mistakes, when I searched SetWindowLongPtr, always see "Remarks". http://msdn.microsoft.com/library/ps...nchar_3eif.htm doesn't have "Remarks".
          I found it in Win2000 SP1 (kernel32), but I am not even sure that this function exist in basic Win2000.
          I guess I'm not clear on what you mean Semen... did GetConsoleWindow() not work for you? Can you explain please? Thanks!



          ------------------
          Lance
          PowerBASIC Support
          mailto:[email protected][email protected]</A>
          Lance
          mailto:[email protected]

          Comment


          • #6
            Lance --
            I didn't test - works or not, because, first of all, I think, where a function works.

            Usually, even for new functions there is a remork similar
            Code:
            Requirements
              Windows NT/2000: Requires Windows NT 3.1 or later. (or not supported)
              Windows 95/98: Requires Windows 95 or later.
            In http://msdn.microsoft.com/library/ps...nchar_3eif.htm - nothing.
            Interesting why and what should think a developer ...

            Is known that MSDN includes experimental or future API.
            About SetWindowLongPtr you can even read
            Code:
            Requirements 
              Windows NT/2000: Requires Windows NT 3.1 or later.
              Windows 95/98: Requires Windows 95 or later.
              Header: Declared in Winuser.h; include Windows.h.
              Library: Use User32.lib.
              Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000.
            Coming back to GetConsoleWindow. I didn't found this function in 9x and NT.
            Win2000 Pro (Rus) - my disributive is dated March 2000. Here it's exist.
            But English ? I will not surprise, if not.

            So, I don't see reasons to use a function, about which even is not mentioned, where it should work.

            ------------------
            E-MAIL: [email protected]

            Comment

            Working...
            X