4

I am trying to call the GetConsoleScreenBufferInfoEx function from a console application. If it matters, the application is a 32 bit application running on 64 bit Windows 7. The language is RealBasic.

I believe I have defined all the structures correctly, and the buffer output handle works for every other API function that is being called:

  Declare Function GetConsoleScreenBufferInfoEx Lib "Kernel32" (cHandle As Integer, ByRef info As CONSOLE_SCREEN_BUFFER_INFOEX) As Boolean
  Declare Function GetLastError Lib "Kernel32" () As Integer
  Declare Function GetStdHandle Lib "Kernel32" (hIOStreamType As Integer) As Integer

  Const STD_OUTPUT_HANDLE = -11
  Dim stdHandle As Integer = GetStdHandle(STD_OUTPUT_HANDLE)

  Dim err As Integer
  Dim info As CONSOLE_SCREEN_BUFFER_INFOEX

  If GetConsoleScreenBufferInfoEx(stdHandle, info) Then
    Break
  Else
    err = GetLastError  //Always 87, Invalid parameter
    Break
  End If

Structures:

Structure CONSOLE_SCREEN_BUFFER_INFOEX
  cbSize As Integer
  dwSize As COORD
  CursorPosition As COORD
  Attribute As UInt16
  srWindow As SMALL_RECT
  MaxWindowSize As COORD
  PopupAttributes As UInt16
  FullScreenSupported As Boolean
  ColorTable(15) As UInt32


Structure COORD
  X As UInt16
  Y As UInt16


Structure SMALL_RECT
  Left As UInt16
  Top As UInt16
  Right As UInt16
  Bottom As UInt16

I've gone over this 20 times and nothing looks wrong to me. I've used the COORD and SMALL_RECT structures many times before, so I don't think I made any translation errors on them. The CONSOLE_SCREEN_BUFFER_INFOEX structure, however, is seeing its first use by me here, and I sense that the error lies somewhere in my translation of it.

Paul Lefebvre
  • 6,253
  • 3
  • 28
  • 36
Andrew Lambert
  • 1,869
  • 1
  • 17
  • 31

1 Answers1

9

You need to set the cbSize parameter of the CONSOLE_SCREEN_BUFFER_INFOEX before you send it in. GetConsoleScreenBufferInfoEx will check that it is the correct size and that's why it's returning an invalid parameter.

So before the call to GetConsoleScreenBufferInfoEx add:

info.cbSize = 96

Or better yet Real Basic does allow you to access the size of the structure:

info.cbSize = GetConsoleScreenBufferInfoEx.Size

Which should handle the calculation for you.

shf301
  • 31,086
  • 2
  • 52
  • 86
  • 1
    Well yes, but **don't hardcode the size**! That's what compilers are for. – Cody Gray - on strike Feb 10 '12 at 03:45
  • Interestingly, I had already tried this and I *didn't* hard code the size. If I use `96` (hard coded) then the function succeeds. If I add up all the members of the struct, as I defined it, the size is **93**. So, it would seem that there is an error in the structure definition somewhere. – Andrew Lambert Feb 10 '12 at 04:23
  • 1
    @Amazed - there's no error it's due to structure alignment - http://msdn.microsoft.com/en-us/library/71kf49f1%28v=vs.80%29.aspx – shf301 Feb 10 '12 at 04:44
  • So, should I detect whether I'm running in WoW64 and explicitly use `96` if so? Using `CONSOLE_SCREEN_BUFFER_INFOEX.Size` returns `93` under WoW64. – Andrew Lambert Feb 10 '12 at 06:24
  • 1
    @Amazed, no the size shouldn't change under WoW64 - it'll still be 96. If `CONSOLE.SCREEN_BUFFER_INFOEX.Size` is returning 93 then it's laying it out incorrectly. Try using the StructureAlignment attribute to set the alignment to 8, which I believe is what Windows uses. – shf301 Feb 10 '12 at 06:49