winapirealbasicwindows-console

Second call to GetStdHandle Returns an "invalid" handle


I'm trying to set the text color of a console to a given color, print one line (or more) and then change the color scheme back to what it was. Here's what I have:

Function SetConsoleTextColor(NewColor As UInt16) As UInt16
    Declare Function SetConsoleTextAttribute Lib "Kernel32" (hConsole As Integer, attribs As UInt16) As Boolean
    Declare Function GetStdHandle Lib "Kernel32" (hIOStreamType As Integer) As Integer
    Declare Function GetConsoleScreenBufferInfo Lib "Kernel32" (hConsole As Integer, ByRef buffinfo As CONSOLE_SCREEN_BUFFER_INFO) As Boolean
    Declare Sub CloseHandle Lib "Kernel32" (HWND As Integer)

    Const STD_OUTPUT_HANDLE = -12

    Dim conHandle As Integer = GetStdHandle(STD_OUTPUT_HANDLE)
    Dim buffInfo As CONSOLE_SCREEN_BUFFER_INFO  //A structure defined elsewhere
    If GetConsoleScreenBufferInfo(conHandle, buffInfo) Then
      Call SetConsoleTextAttribute(conHandle, NewColor)
      CloseHandle(conHandle)
      Return buffInfo.Attribute
    Else
      Return 0
    End If
End Function

This works just fine on the first call. The text color for new output on the console is changed and the previous attributes are returned. However, when I call this a second time to reset the attributes GetStdHandle returns a handle identical to the previous call, but which is now invalid (since I closed it.)

This causes an error, of course, when I try to use the handle. It works properly if I make conHandle a static variable and only call GetStdHandle if conHandle is equal to zero (the default value for new numeric variable in RealBasic.)

I was always told to clean up after myself. Am I supposed to leave this handle open?


Solution

  • Yes you are supposed to leave the handle open.

    This handle is closed automatically when your process exits.