2017-08-22 3 views
3

Ich habe versucht, das Ausgabe-Handle zu meiner Konsole zu bekommen, aber es scheint nicht zu funktionieren. Ich habe es, um die Farbe meines Textes zu setzen, aber es ändert sich nicht.Kann nicht STD Griff zu AllocConsole

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); 
SetConsoleTextAttribute(hOut, 0x0A) 

Ich habe versucht, es zu debuggen und ich denke, dass ich den Griff nicht richtig ist. Gibt es einen anderen Weg dies zu tun, und ist es normal, dass es nicht funktioniert? Irgendwelche Korrekturen?

Danke!

EDIT: Lassen Sie mich klären, der Griff, den ich versuche zu erhalten, ist ungültig. Ich habe keine Ahnung, wie ich es beheben kann. Ich schätze, ich werde nach Alternativen suchen; vielleicht stimmt etwas mit meinem Code nicht.

+0

Ich denke, das war nicht für mich? @GraemeWicksted – SoLux

+0

jemand anderes hatte kommentiert und es war als Antwort auf diesen Kommentar, der später vom Autor entfernt wurde. –

Antwort

1

Da Sie hOutINVALID_HANDLE_VALUE (oder möglicherweise NULL) angeben, rufen Sie GetLastError an, um herauszufinden, warum. Wahrscheinlich haben Sie keine Konsolensitzung eingerichtet.

Ist das eine Win32-Konsolenanwendung oder ist es eine Windows-Subsystem-Anwendung (es WinMain hat?)

Sie könnten versuchen AttachConsole(ATTACH_PARENT_PROCESS) statt AllocConsole vor GetStdHandle.

In jedem Fall AllocConsole und AttachConsole ein BOOL zurück, die, wenn FALSE, Sie GetLastError anrufen können, um herauszufinden, warum gibt.

Stellen Sie sicher, dass Sie nicht hOut = GetStdHandle(STD_OUTPUT_HANDLE) gefolgt von vor den oben aufgeführten Zeilen aufrufen. Im Gegensatz zu AllocConsole und FreeConsole ist das Schließen des Std-Griffs keine gute Idee.

Schließlich versuchen:

#define _WIN32_WINNT 0x0501 vor #include <windows.h>

+0

Es hat einen anderen Namen, aber ich wollte es einfach nur ändern, wenn ich poste und ich hatte einen Tippfehler (zweimal). Und ich habe erwähnt, dass das Handle ungültig war, obwohl ich keine Ahnung habe, wie ich es beheben kann. – SoLux

3

Die Standard-Handler bei der Prozesserstellung initialisiert werden, wenn Sie AllocConsole die neue Konsole rufen Sie später weit erstellt wird. kann die Standard-Handles ändern, aber es ist viel zu spät für sie von Startup-Code verwendet werden, z. B. die Initialisierung der C-Laufzeitbibliothek.

Das Beste, was in diesem Fall zu tun CreateFileW(L"CONOUT$", ...), das eine Konsole egal Griff bekommt, ob Sie Konsole Mutterprozess gebunden sind, erstellt das Betriebssystem für Sie, weil Ihre PE-Header /SUBSYSTEM:CONSOLE ist, oder Sie AllocConsole genannt. Und es erhält das Konsolen-Handle, selbst wenn Standard-Handles umgeleitet werden.

Und wenn Sie denken, Sie können FreeConsole anrufen, sollten Sie sicher sein, alle von CreateFile zuerst zurückgegebenen Handles zuerst zu schließen. Im allgemeinen Fall, in dem die Konsole bis zum Beenden des Prozesses aktiv bleibt, können Sie das Betriebssystem veranlassen, das Handle für Sie während der Prozessbereinigung zu schließen.

+0

Ich benutzte bereits freopen_s – SoLux

+0

@AxIoN: 'freopen_s' wirkt auf eine' FILE * ', es gibt keinen' GRIFF ', die Sie an' SetConsoleTextAttribute' übergeben müssen. Meine Antwort ist nicht, wie man 'GetStdHandle' repariert, sondern wie man eine Konsole zu 100% zuverlässig bekommt. –

+0

@eryksun: Wird das offiziell dokumentiert oder nur beobachtetes Verhalten, das versionsspezifisch sein kann? Ahh, ich sehe es hier in [GetStdHandle] (https://docs.microsoft.com/en-us/windows/console/getstdhandle) –

-1

Ok, also habe ich eine Antwort gefunden. Es scheint wie ein einfacher bearbeiten kann es für eine so kleine Sache

#define setcsattr(clr) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), clr) 
+0

Dies ist der gleiche Code wie in der Frage - nur in einem Makro und ohne mittlere 'HANDLE'-Variable. – eryksun

+0

Ja, es scheint, dass das das Problem war. – SoLux

+0

Was war das Problem? Ich sehe keinen praktischen Unterschied. – eryksun

0

So viel Drama beheben ... und übrigens @ Ben Antwort ist die richtige Antwort tatsächlich richtig ist.

Für Ihr Problem, das nur tun:

freopen("CONIN$", "r", stdin); 
freopen("CONOUT$", "w", stdout); 
freopen("CONOUT$", "w", stderr); 

Dies ermöglicht Ihnen, den Griff von jeder Konsole Sie haben zu bekommen. Stellen Sie sicher, dass Sie dies vor AllocConsole() stellen;

Viel Spaß ?!

Verwandte Themen