0

I am trying to write symbols on console using kernel32.dll (because standart Console.Write is extending console window when write on last symbol of last row)
The problem is that WriteConsoleOutput return 0x06 witch is INVALID_HANDLE_VALUE. But when i'm using SetWindowText (im use this because it use handle of window to set text) it changing the console caption.
I was trying to get handle by GetStdHandle(STD_OUTPUT_HANDLE), WriteConsoleOutput then return 0x02 witch ERROR_FILE_NOT_FOUND
What i am doing wrong? I will be appreciated for any help
Here is imports:

[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();

[DllImport("kernel32.dll")]
static extern uint GetLastError();

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteConsoleOutput( IntPtr consoleHandle, CharInfo[,] buffer, Coord bufSize, Coord bufZero, ref Rect drawRect );
// This is for test
[DllImport("user32.dll")]
static extern bool SetWindowText(IntPtr hWnd, string text);

Structs

[StructLayout(LayoutKind.Explicit)]
public struct CharInfo
{
    [FieldOffset(0)]
    internal char UnicodeChar;
    [FieldOffset(0)]
    internal char AsciiChar;
    [FieldOffset(2)]
    internal ushort Attributes;
}

[StructLayout(LayoutKind.Sequential)]
public struct Coord
{
    public short X; public short Y;
    public Coord(short x, short y) { X = x; Y = y; }
};

[StructLayout(LayoutKind.Sequential)]
public struct Rect
{
    public short Left;
    public short Top;
    public short Right;
    public short Bottom;
}

And code that i use

Console.Clear();
IntPtr h = GetConsoleWindow();
SetWindowText(h, "we have found console");

var rect = new Rect() { Left = 10, Top = 0, Right = 11, Bottom = 1 };
var bufsz = new Coord(2, 2);
var buf = new CharInfo[2, 2];
buf[0, 0] = new CharInfo() { AsciiChar = '+' };
var bufpos = new Coord(0, 0);

WriteConsoleOutput(h, buf, bufsz, bufpos, ref rect);
var err = GetLastError();
if (err != 0) Console.WriteLine("Write fail: " + err);

EDIT:
Didn't work

Process.GetCurrentProcess().MainWindowHandle;
// same error

This too

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nHandle);
...
IntPtr h = GetStdHandle(-11);
// Error 1400 - wrong handle while accessing from email (or something like that)
Sergio
  • 346
  • 1
  • 8
  • `GetConsoleWindow()` returns a window handle, not a console handle. – Raymond Chen Mar 02 '17 at 06:07
  • I never work with console using api =) You mean there is difference between console output and other windows? – Sergio Mar 02 '17 at 06:11
  • GetStdHandle() is the correct way to do it. But if you pass that handle to SetWindowText() then it will fail with error 1400. Distinguishing between the console and the window handle is important. Try not to do any of this "from email", whatever that might mean. And don't do any of this when [output is redirected](http://stackoverflow.com/a/3453272/17034). And don't do any of this when the Console class can already do this, it can for everything you've mentioned in this question. – Hans Passant Mar 02 '17 at 07:54
  • @HansPassant yes, you was right. Error was not from `WriteConsoleOutput`, it was from `SetWindowText`. But "...console class can already do this...". i try to write a peace of game map in console(rogue-like game), and it happens many times per second. Standart methods are too slow and `Console.Write` move cursor to next line when i put a char in last symbol of last row. So map is slidedown for 1 row (top row slideup, and bottom became empty) thats why i try to use api. Can you form your comment as an answer, so i could close question – Sergio Mar 02 '17 at 09:04

0 Answers0