PHP týden Letní akce
Pouze tento týden sleva až 80 % na kurzy PHP. Lze kombinovat s akcí Letní slevy na prémiový obsah!
Brno? Vypsali jsme pro vás nové termíny školení Základů programování a OOP v Brně!
Avatar
Michaal.K
Člen
Avatar
Michaal.K:14. května 9:30

Ahoj,
chtěl bych v aplikaci winform spustit okno konzole a následně do něj vypisovat text.

Zkusil jsem: Vytvořil jsem si vlastní třídu DebugConsole:

class DebugConsole
    {
        [DllImport("kernel32.dll")]
        private static extern Boolean AllocConsole();
        [DllImport("kernel32.dll")]
        private static extern Boolean FreeConsole();

        private static bool zapConsole = false;

        public DebugConsole()
        {

        }

        public void ZobrazConsole(bool zap, string hlavickaConsole)
        {
            zapConsole = zap;
            if (zapConsole == true)
            {
                AllocConsole();
                Console.Title = hlavickaConsole;
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(hlavickaConsole);
                Console.WriteLine("".PadLeft(hlavickaConsole.Length, '*'));
                Console.ResetColor();
            }
            else
            {
                FreeConsole();
            }
        }
        public void WriteLine(string vypisText)
        {
            Console.WriteLine(vypisText);
        }
        public void SmazaniConsole()
        {
            Console.Clear();
        }
    }

Vytvořím instanci třídy v novém formu (který otvírám)

DebugConsole debugCon = new DebugConsole();

Následně v aplikaci přes tlačítko na hlavním formu otevírám další formulář, kde v metodě load volám:

debugCon.ZobrazConsole(true, "Debug konzole");
debugCon.WriteLine("TEST");

Při zavření formu v metodě FormClose

debugCon.SmazaniConsole();
debugCon.ZobrazConsole(false, "Debug konzole");

Chci docílit: Pokud aplikaci spustím a na hlavním formu kliknu na tlačítko kde se mi otevře nový form tak se i zároveň otevře okno konzole a vypíše správně text. Vše tedy funguje jak má.
Následně zavřu okno nového formu, tak se také zavře okno konzole to je také dobře, ale pokud znovu kliknu na tlačítko v hlavním formu a chci zase otevřít nový form a konzoli tak aplikace spadne na Console.Write­Line(hlavicka­Console); ve třídě DebugConsole v metodě ZobrazConsole a vypíše tuto chybu:

Neošetřená výjimka typu System.IO.IOException vznikla v mscorlib.dll.
Další informace: Požadavek není podporován.
nebo
Neošetřená výjimka typu System.IO.IOException vznikla v mscorlib.dll.
Další informace: Neplatný popisovač.

Nevím jestli vadí, že vytvářím znovu stejnou instaci třídy DebugConsole v novém formu???
Díky za pomoc a rady...

 
Odpovědět 14. května 9:30
Avatar
Michaal.K
Člen
Avatar
Michaal.K:21. května 15:21

Ahoj,
tak nakonec jsem to sám vyřešil takto (kdyby to náhodou v budoucnu někoho zajímalo):
Do třídy DebugConsole jsem pridal zobrazení a skrytí okna konzole a trochu upravil:

public class DebugConsole
    {
        [DllImport("kernel32.dll")]
        private static extern Boolean AllocConsole();
        [DllImport("kernel32.dll")]
        private static extern Boolean FreeConsole();
        [DllImport("Kernel32.dll")]
        static extern IntPtr GetConsoleWindow();
        [DllImport("User32.dll")]
        static extern int ShowWindow(IntPtr hwnd, int nShow);

        private bool spustCon = false;
        private static bool zobrazCon = false;
        private static string hlavickaCon = "";

        public DebugConsole()
        {

        }

        public void SpustConsole(bool spust)
        {
            if (spust == true)
            {
                AllocConsole();
                spustCon = true;
            }
            else
            {
                FreeConsole();
                spustCon = false;
            }
        }

        public void ZobrazConsole(bool zobraz, string hlavickaConsole)
        {
            hlavickaCon = hlavickaConsole;
            if (zobraz == true)
            {
                IntPtr hwnd = GetConsoleWindow();
                int ret = ShowWindow(hwnd, 5);
                zobrazCon = zobraz;

                Console.Title = hlavickaConsole;
                Console.WriteLine(hlavickaConsole);
                Console.WriteLine("".PadLeft(hlavickaConsole.Length, '*'));
            }
            else
            {
                Console.Clear();
                IntPtr hwnd = GetConsoleWindow();
                int ret = ShowWindow(hwnd, 0);
                zobrazCon = zobraz;
            }
        }

        public void WriteLine(string vypisText)
        {
            Console.WriteLine(vypisText);
        }
        public void SmazaniConsole()
        {
            Console.Clear();
        }
    }

V hlavním formu si vytvořím instanci třídy DebugConsole

DebugConsole debugCon = new DebugConsole();

A v konstruktoru MainFormu (hlavním formu) spustím okno konzole a hned ho skryji:

public MainForm()
{
    InitializeComponent();

     debugCon.SpustConsole(true);
     debugCon.ZobrazConsole(false, "Konzole");
    }
}

V události klik na tlačítko na hlavním formu, kterým otevírám další form si přes konstruktor nového formu předám instanci třídy DebugConsole....

private void btn_Click(object sender, EventArgs e)
{
    Form NovyForm = new NovyForm(debugCon);
    NovyForm.ShowDialog();
}

V novém formu pak v konstruktoru převeznu ukazatel na instanci třídy DebugConsole vytvořenou v MainForm. A v události NovyForm_Load zobrazim skryté okno konzole a můžu do něj zapisovat. Když nový form ukončím a následně opět spustím přes tlačítko na hlavním formu (MainForm) vše funguje...

public partial class NovyForm: Form
{
    protected DebugConsole debugCon;

    public NovyForm(DebugConsole konzole)
    {
        InitializeComponent();

        debugCon = konzole;
    }

    private void NovyForm_Load(object sender, EventArgs e)
    {
        debugCon.ZobrazConsole(true, "DEBUG mód pro NovyForm");
        debugCon.WriteLine("Okno nového formuláře bylo úspěšně spuštěno.");
    }
}

Tak snad je to srozumitené a dobře :-)

Akceptované řešení
+5 Zkušeností
Řešení problému
 
Nahoru Odpovědět  +1 21. května 15:21
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.