Page 1 of 1

Console WinAPI - Problem with passing a structure

Posted: Tue Mar 17, 2015 8:31 am
by ewardd
Hey guys. I got a weird problem. Cant get "coord" structure working in WinAPI functions.

https://msdn.microsoft.com/en-us/librar ... s.85).aspx

MSDN quote:
BOOL WINAPI FillConsoleOutputCharacter(
_In_ HANDLE hConsoleOutput,
_In_ TCHAR cCharacter,
_In_ DWORD nLength,
_In_ COORD dwWriteCoord,
_Out_ LPDWORD lpNumberOfCharsWritten
);
dwWriteCoord
A COORD structure that specifies the character coordinates of the first cell to which the character is to be written.

Code: Select all

Structure bufInfo
  dwSize.coord
  dwCursorPosition.coord
  wAttributes.w
  srWindow.small_rect
  dwMaximumWindowSize.coord
EndStructure

buf.bufInfo

Structure crd
  x.l
  y.l
EndStructure

Global ary.crd

ary\x = 0
ary\y = 0

OpenConsole()
size = 25*80
dwI = 0

hI.l = GetStdHandle_(#STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo_(hI, @buf)

;** Here it is. If u run this code nothing will actually happen with FillConsoleOutputCharacter.
FillConsoleOutputCharacter_(hI, Asc("a"), size, ary, @dwi)

;** But if you replace it to 
;FillConsoleOutputCharacter_(hI, Asc("a"), size, 0, @dwi)
;It will work. It will fill console with 'a' character starting from 0, 0 coord cell.
;If you change 0 to 5 it gonna start from 5 cell in a first row and so on untill 80


Input()
I know that in PB already exist "coord" and "ConsoleScreenBufferInfo" structures,
and i tried to use PBs "coord" too. Same result -> nothing on screen.
Doing this for experence and i just wonder why it wont work.

Can anyone explain me why this happens and how to fix this, but Not replace function using other ways?

Re: Console WinAPI - Problem with passing a structure

Posted: Tue Mar 17, 2015 10:14 am
by infratec
Hi,

I'm not sure from where the problem comes, but I have an ugly fix:

Code: Select all

Define lpNumberOfCharsWritten.l, nLength.l, hI.i
Define dwWriteCoord.coord
Define buf.CONSOLE_SCREEN_BUFFER_INFO

OpenConsole()

dwWriteCoord\x = 10
dwWriteCoord\y = 2

nLength = 25*80


hI = GetStdHandle_(#STD_OUTPUT_HANDLE)
GetConsoleScreenBufferInfo_(hI, @buf)
Debug buf\dwSize\x
Debug buf\dwSize\y

Debug RSet(Hex(dwWriteCoord\x << 16 | dwWriteCoord\y, #PB_Long), 8, "0")

;Debug FillConsoleOutputCharacter_(hI, 'a', nLength, dwWriteCoord, @lpNumberOfCharsWritten)
Debug FillConsoleOutputCharacter_(hI, 'a', nLength, dwWriteCoord\y << 16 | dwWriteCoord\x, @lpNumberOfCharsWritten)

Debug lpNumberOfCharsWritten

Input()
Or directly for your code:

Code: Select all

FillConsoleOutputCharacter_(hI, Asc("a"), size, ary\y << 16 | ary\x, @dwi)
Btw. COORD uses short, which is .w in PB.

Bernd

Re: Console WinAPI - Problem with passing a structure

Posted: Tue Mar 17, 2015 11:47 am
by PureGuy

Code: Select all

FillConsoleOutputCharacter_(hI, Asc("a"), size, PeekL(@ary), @dwi)

Re: Console WinAPI - Problem with passing a structure

Posted: Tue Mar 17, 2015 2:10 pm
by luis
ewardd wrote: Can anyone explain me why this happens
The parameter COORD dwWriteCoord as you see from the docs is not a pointer, it's a structure passed by value.

PB can't pass a structure by value, even if you write its name omitting the @ in front of it it's implicitly there.

The structure you need to pass contains two words (2 x 16 bits), so you can see them as one long (1 x 32 bit).

That's why using simply PeekL() you can read the equivalent long from the base address of the structure, reading the two words as the low and high part of the long.

At that point, we know PB can pass a long by value, and it does just that.

The API doesn't now that's a long (from PB point of view) it just see the package of 32 bits coming to its side, and unpack it to the two x and y components it was expecting, and all works.

In your case you were just passing a random number, the address of your structure.


Both the PeeKL() and the bits manipulation give the same result, PeekL() is just more handy.

Code: Select all

Global dwWriteCoord.COORD
Global hConsoleOutput, NumberOfCharsWritten, nLength

dwWriteCoord\x = 0
dwWriteCoord\y = 10

OpenConsole()
nLength = 80
hConsoleOutput = GetStdHandle_(#STD_OUTPUT_HANDLE);

Debug dwWriteCoord\y << 16 | dwWriteCoord\x
Debug PeekL(dwWriteCoord)

FillConsoleOutputCharacter_(hConsoleOutput, 'a', nLength, PeekL(dwWriteCoord), @NumberOfCharsWritten)

Input()

Re: Console WinAPI - Problem with passing a structure

Posted: Tue Mar 17, 2015 4:51 pm
by ewardd
Thanks you, luis, for explaining everything and you, guys, for attention