IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: problém s Button a stiskem klávesy

V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
jenda
Člen
Avatar
jenda:4.8.2013 10:20

Mám jednoduchou aplikaci WFA, kde se obdélník v okně pohybuje podle toho, jakou klávesu stisknete (šipky). Je tam použitý i Timer, takže stačí klávesou udat směr a obdélník už dál jede sám. Funguje mi to do chvíle, kdy na formulář přidám Button. Pak to na stisk klávesy přestane reagovat. Co mám udělat jinak? Kde mám chybu? Díky

 
Odpovědět
4.8.2013 10:20
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na jenda
David Hartinger:4.8.2013 10:22

Při přidání buttonu dostane focus to tlačítko a ne formulář a ty reaguješ na klávesy na formuláři.

Nahoru Odpovědět
4.8.2013 10:22
New kid back on the block with a R.I.P
Avatar
jenda
Člen
Avatar
Odpovídá na David Hartinger
jenda:4.8.2013 11:44

Jasně, chápu. Myslel jsem, že ve vlastnosti formuláře stačí nastavit KeyPreview = true a pak by to mělo odchytávat stisknuté klávesy, i když nemá formulář focus ...

 
Nahoru Odpovědět
4.8.2013 11:44
Avatar
Theodor Johnson
Tvůrce
Avatar
Odpovídá na jenda
Theodor Johnson:4.8.2013 12:20

Klávesy odchytávej pomocí

protected override bool ProcessCmdKey
Nahoru Odpovědět
4.8.2013 12:20
Mo8ilε 15 Ѐλđ
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na jenda
David Hartinger:4.8.2013 12:30

To by skoro mělo :)

Nahoru Odpovědět
4.8.2013 12:30
New kid back on the block with a R.I.P
Avatar
jenda
Člen
Avatar
Odpovídá na David Hartinger
jenda:4.8.2013 13:24

Díky za rady, pořád se v tom plácám ...

  1. Jakým způsobem bych vrátil focus na formulář?
  2. Můžeš mi prosím podrobněji popsat to odchytávání pomocí protected override bool ProcessCmdKey?

Díky za trpělivost :-)

 
Nahoru Odpovědět
4.8.2013 13:24
Avatar
Jan Vargovský
Tvůrce
Avatar
Jan Vargovský:4.8.2013 13:47
  1. No formulář má vlastnost Focus, tak tu buď nastav na true nebo je tam metoda Focus() toto mi ve většině případů nefunguje, tak používám Activate().
 
Nahoru Odpovědět
4.8.2013 13:47
Avatar
jenda
Člen
Avatar
Odpovídá na Jan Vargovský
jenda:4.8.2013 18:12

Asi jsem natvrdlý, ale přepínat focus mezi button mi jde, ale přepnout ho na form1 to nebere - to vůbec tu metodu nenabízí... :-)

 
Nahoru Odpovědět
4.8.2013 18:12
Avatar
Jan Vargovský
Tvůrce
Avatar
Odpovídá na jenda
Jan Vargovský:4.8.2013 18:15

Vždyť jsem říkal, že je to vadné. Zkus Activate metodu :)

 
Nahoru Odpovědět
4.8.2013 18:15
Avatar
jenda
Člen
Avatar
Odpovídá na Jan Vargovský
jenda:4.8.2013 19:24

Tak chyba bude někde jinde, ani to mi nepomohlo. Asi mám něco blbě - jsem začátečník.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace pristaniGraficke
{
    public partial class Form1 : Form
    {
        double casKonstant = 1000; // milisekundové cykly
        private int x = 50;
        private int y = 0;
        int modulX = 100;
        int modulY = 100;
        double g = 1.62; //hodnota gravitačního zrychlení

        double vyskaH; //h
        double rychlostV; //v
        double palivoM; //Mp
        int tahMotoruT; //Z
        double zrychleniA; //a
        double doprava;
        double doleva;


        int hmotnostModulu = 9000; //M
        double maxBrzdiciTah = 36000; //R
        double vytokovaRachlost = 3000; //Vv

        double rekord = 60;
        double pokus;
        int planeta;


        double k; //pomocna konstanta
        double l; //pomsocna konstanta


        public Form1()
        {
            InitializeComponent();
            resetHodnot();




        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.FillRectangle(Brushes.Blue, x, y, modulX, modulY);
            e.Graphics.DrawImage(new Bitmap("raketa.png"), x, y, modulX, modulY);

        }

        private void timer1_Tick(object sender, EventArgs e)
        {


            label2.Text = tahMotoruT.ToString();
            label4.Text = (vyskaH-modulY-33).ToString(); // výpis výšky na obrazovku
            label6.Text = (rychlostV*10).ToString();
            label7.Text = palivoM.ToString();

            if (vyskaH > modulY + 33)
            {
                zrychleniA = g - k * tahMotoruT / casKonstant;
                vyskaH = (vyskaH - rychlostV - (zrychleniA / 2));
                rychlostV = rychlostV + zrychleniA;
                palivoM = palivoM - l * tahMotoruT * 10;
                y = Height - Convert.ToInt16(vyskaH);

                x = Convert.ToInt16(x - doleva + doprava);
                if (x < 0)
                {
                    x = 0;
                    doleva = 0;
                }
                if (x > Width - modulX)
                {
                    x = Width - modulX;
                    doprava = 0;
                }
            }
            else
            {
                if (rychlostV*10 < rekord)
                {
                    rekord = rychlostV*10;
                    label9.Text = "Udělal jsi nový rekord: " + rekord.ToString();
                }
                label8.Text = "přistál jsi rychlostí: " + (rychlostV*10).ToString();

            }
            if (palivoM < 0)
            {
                palivoM = 0;
                k = 0;
            }

            if (doleva > 0)
                doleva = doleva - 0.05;

            if (doprava > 0)
                doprava = doprava - 0.05;


            if (tahMotoruT > 0)
            {
                tahMotoruT = tahMotoruT - 1;
            }
            Invalidate();

        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Up)
             if(tahMotoruT<100)
                 tahMotoruT = tahMotoruT + 30;


            if (e.KeyCode == Keys.Down)
                if (tahMotoruT > 4)
                    tahMotoruT = tahMotoruT - 30;

            if (e.KeyCode == Keys.Left)
                if (x > 10)
                    doleva = doleva + 2;

            if (e.KeyCode == Keys.Right)
                if (x < (Width-5))
                    doprava = doprava + 2;

        }

        private void resetHodnot()
        {
            Form1.ActiveForm.Activate();
            vyskaH = Height; // počáteční výška se nastaví dle velikosti okna snížená o proužek
            rychlostV = 0; //v
            palivoM = vyskaH/5; //Mp
            tahMotoruT = 0; //Z
            zrychleniA = 0; //a
            g = 1.62;
            x = Convert.ToInt16(Width/2)-modulX/2;
            y = 0;
            doleva = 0;
            doprava = 0;


            g = g / casKonstant;
            k = maxBrzdiciTah / 100 / hmotnostModulu;
            l = maxBrzdiciTah / 100 / (vytokovaRachlost * casKonstant);
            label8.Text = "";
            label9.Text = "";
        }

        private void Reset_Click(object sender, EventArgs e)
        {
            resetHodnot();
        }
    }
}
 
Nahoru Odpovědět
4.8.2013 19:24
Avatar
Jan Vargovský
Tvůrce
Avatar
Jan Vargovský:4.8.2013 19:29
Form1.ActiveForm.Activate();

Tohle ti jde? Nahraď to tímto:

this.Activate()

EDIT: Divím se, že to vůbec zkompiluješ. Mělo by ti to vyhodit vyjímku, že odkazuješ na objekt, který nemá instanci.

Editováno 4.8.2013 19:31
 
Nahoru Odpovědět
4.8.2013 19:29
Avatar
jenda
Člen
Avatar
jenda:4.8.2013 19:31

Bez efektu, stále nefunguje :-)

 
Nahoru Odpovědět
4.8.2013 19:31
Avatar
Jan Vargovský
Tvůrce
Avatar
Odpovídá na jenda
Jan Vargovský:4.8.2013 19:32

A co teda chceš? Na co chceš přenést focus? Na ten Form, aby jsi mohl zachytávat ty klávesy, protože když má focus to tlačítko, tak to nejde?

 
Nahoru Odpovědět
4.8.2013 19:32
Avatar
jenda
Člen
Avatar
Odpovídá na Jan Vargovský
jenda:4.8.2013 19:34

ano, na form potřebuji zachytávat klávesy.

 
Nahoru Odpovědět
4.8.2013 19:34
Avatar
Theodor Johnson
Tvůrce
Avatar
Odpovídá na jenda
Theodor Johnson:4.8.2013 19:36

Všiml jsem si toho až teď

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Enter)
            {
                MessageBox.Show("Stisknut byl Enter");
            }

            return base.ProcessCmdKey(ref msg, keyData);
        }

form nemusí mít focus, klávesy jdou příídávat nebo odebírat kontrolou keyData

Nahoru Odpovědět
4.8.2013 19:36
Mo8ilε 15 Ѐλđ
Avatar
jenda
Člen
Avatar
Odpovídá na Theodor Johnson
jenda:4.8.2013 19:47

Super, díky, tohle zafungovalo. :-)

 
Nahoru Odpovědět
4.8.2013 19:47
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 16 zpráv z 16.