C++/Cli odpowiednik deflaut i reakcja na zdarzenie

0

Witam, liznąłem trochę WinApi, ale chciłemsobie uproscic zycie za pomoca .NET

Napotkałem na samym początku 2 rzeczy, z którymi nie mogę sobie poradzić i znaleźć odpowiedzi:

  1. Jak znaleźć odpowiednik zdarzenia deflaut z winapi
  2. 'Narysowalem' Form1 i button. Dodalem 2 zdarzenia. Klikniecie buttona i klikniecie klawisza. Klikniecie klawisza mi dziala tylko wtedy, gdy button zmienie z Show na Hide.

Zalaczam kod i bardzo prosze o pomoc.

	private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
			 {
				 System::String^ a = _TEXT("sdfsdf");
				 this->button1->Hide();
				 MessageBox::Show( a  );
			 }

	public:  void Form1_OnKeyDown( Object^ sender, System::Windows::Forms::KeyEventArgs^ e )
 {
			 System::String^ a = _TEXT("sdfsdf");
				  this->button1->Show();
				 MessageBox::Show( a  );
 }
 
0
  1. co to jest zdarzenie deflaut z winapi?
  2. być może chodzi ci o Form::KeyPreview.
  3. możesz spokojnie używać L"sdfsdf" — typ System::String na pewno jest zawsze unikodowy.
0

jezeli nie przyszlo zadne zdarzenie, ktore ja obsluguje, to wtedy jest przypadek deflaut. W sumie glupio to nazwalem bo chodzi o konstrukcje switch'a. Czyli taki else dla wszystkich zdarzen.

0

Możesz to zrobić (przeładowując WndProc), ale po co? Programowanie w Windows Forms polega na zdarzeniach kontrolek, a nie komunikatach systemowych.

0

powiedz do czego ci to potrzebne, to się coś wymyśli.

0
Azarien napisał(a)

powiedz do czego ci to potrzebne, to się coś wymyśli.

Jeszcze do niczego, ale potrafie sobie taka sytuacje wyobrazic, a .net bawie sie od 2 dni :) np. komunkacja po socketach, gdzie sygnal jest nadawany caly czas, wcisniecie wielu klawiszy na raz (zeby za kazdym razem eni spradzac 100 ifow, a przy wiekszej ilosci klawiszow to calkeim mozliwe) itd.
w czystym WinApi wykonuje sie kod po deflaut, czy else - tutaj nic takeigo nie znalazlem.
Na pewno wielowatkowasc zalatwi sprawe, ale po co komplikwoac sobei zycie - na pewno ktos juz roziwazal ten problem.

O wlasnie przyszedl mi do glowy pomysl na problem - np. stoper. mam przycisk start, stop. czyli mam 2 zdarzenia i "deflaut" (domyslne - jak nie start, albo nie stop to inkrementuj zmienna)
Jak cos takiego roziwazac?

Pozdrawiam

0

Problem jest wyimaginowany. Po co inkrementować zmienną za każdym odebraniem komunikatu, których mogą być dziesiątki? Chcesz mieć takie samo zachowanie niezależnie od tego czy ktoś naciśnie przycisk, przesunie mysz, zminimalizuje okno, zmieni tapetę pulpitu? Przecież to jest totalnie bez sensu.

Potrzebujesz zareagować na jakąś akcję użytkownika to pod taką akcję podpinasz zdarzenie i tyle. Jak potrzebujesz gdzieś w kodzie wrzucić multum if'ów tzn., że po prostu popełniłeś błąd projektowy.

Co do przykładu ze stoperem to reagujesz na zdarzenia przycisków i zdarzenie timera - ot 3 różne metody.

0
crn napisał(a)

Jeszcze do niczego, ale potrafie sobie taka sytuacje wyobrazic, a .net bawie sie od 2 dni

Ja bawię się od 7 lat i takie coś nie było mi nigdy potrzebne, ani nie potrafię sobie wyobrazić takiej potrzeby. To jakiś WTF jest.

0

Jest zdarzenie Application.Idle. Z tym, że nie przekombinowywuj. Np. jeśli chodzi o sockety - dostaniesz ładne zdarzenie gdy będę gotowe dane do odbioru. Gdzieś tam pod spodem będzie chodzić sobie wątek odbierający dane, ale nie będzie musiał samemu tego implementować, wszystko jest gotowe.

1

Jeśli lubisz pisać wtf-owy kod, zawsze możesz przeciążyć WndProc (jak Rev napisał)

(Kod podaje w C#, nie ryzykuje tłumaczenia tego z głowy do C++\Cli bo nie pamiętam jak tam ref wyglądało):

        protected override void WndProc(ref Message m)
        {
            róbCośZaKażdymRazem();

            // wywołanie fx bazowej musi być, bo eventy nie będą działać.
            base.WndProc(ref m);
        }
0

Jeśli lubisz pisać wtf-owy kod, zawsze możesz przeciążyć WndProc (jak Rev napisał)

WndProc służy do tego, by móc zaimplementować własne zdarzenie na komunikat nie przewidziany w WinForms.
Ale robimy to tak jak są zrobione istniejące zdarzenia: przez dodanie eventa.

0

najpierw dziękuje za odzew, dalej napisze pytanei w punktach:

  1. Nadal potrafie sobie wyobrazic sporo przykladow np. apliakcja caly czas wysylajaca dane na storne/serwer/cokolwiek, stoper(w takiej implemtacji jak napsiaelm - bo jest dobym prykaldem), czy gra jakakolwiek.

  2. Moze moj blad jez z myslanie w c++ , ale zeby przeciazyc metode/funkcje musze podac inne argumety i wywolac ja z nimi. Jezeli dziedziczę, funkcja moze byc wirtulana i wtedy zastepuje ja swoja. stad pytanie: gdzie wywowlac moja wersje (czy w jakiejs klasie, czy tak porstu), i jak odwolac sie do oryginały ,kiedy w. mojej wiedzy, jest to nie mozliwe.

  3. W 'events' nie znalazlem zdarzen zwaiznych z odbieraniem danych przez socketym jak sie od nich odwolac? W czystym winapi jest obsluga takich komunikatow

  4. Znalazlem cos takeigo 'timer', ktory generuej zdarzenie 'ontick'. czy moze on zastapic 'deflaut', wykonujac kod co (np.) pare milisekund,

Dziekuje jeszce raz za pomoc i przepraszam zaprostote, ale powtarzam, ze 'dotykam' .NET 3 dzien, a problemy wymyslam, dla pokazania tego, o co mi chodzi.
Zaznaczam jeszcze, ze zaden ze mnei specjlaista net, czy winapi, tylo pytam w celu poszerzenia widzey.

Jeszcze raz dzieki za pomoc

1

Polecam sięgnąć po jakąś książkę o programowaniu w .NET i Windows Forms, bo podchodzisz do niego z zupełnie złej strony, a internetowe tutoriale z nauczania dobrych nawyków nie słyną.

0

mam ksiakzi, ale tam jest 'visual bascic' w c, a nie programownie - sa to raczej kursy kliknij tutaj itd. staram sie korzystac z MSDN i cos w tym napisac. Stad moje prosby na forum.
Pozdrawiam

edit:

btw: bede wdzieczny jak wkszesz te zle storny i od razu porawisz jak zmeinic myslenie na zdarzeniowe z while, bo ja takei mam caly czas chyba :)

0

wiesz, ta cała pętla while jest wewnątrz WinForms, bo WF to nakładka na WinAPI — i na upartego można się do niej dobrać.
Ale w każdej bibliotece chodzi o to, by korzystać z mechanizmów tej biblioteki: bo inaczej to możesz pisać przecież po prostu w WinAPI, bez żadnych wysokopoziomowych bibliotek…

0

To wiem i rozumiem, ale mi chodzi o realizację rzeczy, których nie widzę zrealizować za pomocą bibliotek - stad moje pytania. Pewnie to mój błąd bo nie nie wiem jak.
Pozdrawiam.

0
  1. stoper nie jest dobrym przykładem, do jego realizacji wystarczy Timer
  2. mylisz przeciążenie z przeładowaniem nazw funkcji
  3. taki event będzie miała klasa odpowiedzialna za sockety
  4. tak, ale trzeba pamiętać, że raczej co kilkanaście, a nie kilka milisekund(tak jak timer z winapi) i nie można polegać na jego dokładności

Wszystkie przykłady jakie podałeś można prosto zrobić w Windows Forms. .Net to nie jest zbiór bibliotek, które można ogarnąć w jeden wieczór, na to trzeba poświęcić raczej miesiące, a nie dni.

0

W .NET również implementuje się własną "główną pętle". Przykładem mogą być wspomniane gry. Szkielet wygląda tak:

for (;;) {
    WykonajObliczenia(); // fizyka gry, przemieszczanie obiektów itp.
    RysujScene(); // renderowanie sceny, swap buforów
    Application.DoEvents(); // obsługa wszystkiego czym .NET zajmuje się wewnętrznie
}

I to w zasadzie jedyne zastosowanie jakie potrafię przytoczyć, zastosowanie tego co autor wątku ma na myśli. Do wszystkiego innego można użyć event'ów.

I na litość boską nie przeładowywuj WndProc bez potrzeby! To jest wgryzanie się w wewnętrzne mechanizmy. .NET powstał po to by abstrahować od programowania niskopoziomowego (na poziomie WinApi). Wszystko co potrzebujesz zazwyczaj będzie dostępne w .NET na "wyższym" poziomie abstrakcji.

ad. 2) coś namieszałeś. W każdym razie w C# jest prawie identycznie jak w C++ jeśli chodzi o przeładowania i przeciążania.

0

Dzieki wszytkim za pomoc i mam kolejny zestaw pytan:

  1. Czyli taka petle glowna robie po
	Application::Run(gcnew Form1()); 

i tworze tam petle nieskonczona zamieszczajc w niej te 3 rzeczy, tak?
2. A jak dodac zdarzenie z klasy socketow? Jak napisze funkcje ktora obsluguje zdarzenie, to zeby zaczela dzialac msuze ja 'dodac' myszka do lisy events. Co zrobic jak przy socketach nie ma tam takiej opcji

3.Wiadomo, ze najlepiej uczy praktyka. Jaki projekt byscie polecili zorbic, zeby zaczac sie plynnie poruszac po .net? Jakas prosta gre?

Jeszcze raz dzieki i pozdrawiam

0

Ad. 3. Zrób edytor tekstu, wtedy może zrozumiesz o co chodzi ze zdarzeniami i wypadnie Ci z głowy ta Twoja pętla.

0

pętla jest właśnie wewnątrz Application::Run.
a grę to zrób lepiej w XNA, a nie Windows Forms.

0
adf88 napisał(a)

W .NET również implementuje się własną "główną pętle". Przykładem mogą być wspomniane gry. Szkielet wygląda tak:

for (;;) {
    WykonajObliczenia(); // fizyka gry, przemieszczanie obiektów itp.
    RysujScene(); // renderowanie sceny, swap buforów
    Application.DoEvents(); // obsługa wszystkiego czym .NET zajmuje się wewnętrznie
}

I to w zasadzie jedyne zastosowanie jakie potrafię przytoczyć, zastosowanie tego co autor wątku ma na myśli. Do wszystkiego innego można użyć event'ów.

I na litość boską nie przeładowywuj WndProc bez potrzeby! To jest wgryzanie się w wewnętrzne mechanizmy. .NET powstał po to by abstrahować od programowania niskopoziomowego (na poziomie WinApi). Wszystko co potrzebujesz zazwyczaj będzie dostępne w .NET na "wyższym" poziomie abstrakcji.

ad. 2) coś namieszałeś. W każdym razie w C# jest prawie identycznie jak w C++ jeśli chodzi o przeładowania i przeciążania.

W poscie wyzej, chodzilo mi o taka petle.

0

Taką pętlę wstawia się zamiast Application.Run(...).
Tu masz przykład:
http://www.drunkenhyena.com/cg[...]rticle.pl?chapter=2;article=10

Prawie identyczny efekt osiągniesz zostawiając Application.Run(...) i obsługując zdarzenie Idle:

Application.Idle +=new EventHandler(Application_Idle);
// ...
void Application_Idle(Object sender, EventArgs e) {
    WykonajObliczenia();
    RysujScene()
}

W zasadzie nie wiem które z rozwiązań jest bardziej eleganckie, to raczej zależy od ogólnego zamysłu jak ma wyglądać aplikacja.

Jeszcze jedno co do socketów. Nie używałem bezpośrednio .NET'owych socketów (System.Net.Socket). Okazuje się, że nie zgłaszają żadnym event'em gotowości odebranych danych. Obsługiwać można je asynchronicznie przy pomocy callback'ów. Socket łączy się z klientem czy odbiera dane i jak operacja będzie ukończona to woła zadany callback, wywołanie odbywa się w odrębnym wątku. Stamtąd można banalnie wywołać jakieś zdarzenie przez "Invoke". Więcej info: http://www.google.com/search?q=asynchronous+System.Net.Socket

0

Dzieki wielkie za pomoc.

0

BTW: jest sposob dotarcia do zdarzenia, ktorego nie obslufuje .net (pisze ozdarzeniu abstrakcyjnym, a nie czyms konkretnym:) Mowicie o przeciaznaniu petli komunkatow ale jak? ja z c++ rozumiem polimorfizm i wiem jak dziala - nie moge sie odwolac do funkcji bazowej, ytylko wyszystko robie sam. Piszecei do odwolanie sie do obiektu base, ale czym on ejst? moglby kto to mi objansic?

Serdecznie Pozdrawiam

1

To zanim zabierzesz się za bardziej skomplikowane rzeczy w .Net, proponuję nauczyć się najpierw samego C#

0
somekind napisał(a)

http://msdn.microsoft.com/en-us/library/hfw7t1ce%28v=vs.100%29.aspx

Pomoglo. Widac jest wiecej ronic miedzy C++ a C#. W C++ do wywolania funkcji bazowej trzeb by sie trochę 'nakombinować' :)

BTW: Jak moge zrobuc offtop w temacie: potrzebuje pozyskac sporo inforamcji ze storny html, jednak jest ona generowane przez jave itd. Po poczytaniu trochę o net widzę, ze istnieje kontrolka web browser. Czy ona udostępnia mi w jakiejs "czytelnej" formie dane ze strony.
tzn. W momencie, w którym storna jest wyświetla, wszystko musi gdzieś istnieć. Chciałbym do tych danych dotrzeć, bo to sporo ułatwiłoby mi prace. Mógłby ktoś podpowiedzieć ? Jak nie gotowa odpowiedz, to czego szukać? bo ja pana google nawet nie wiem o co zapytać. Wersją alternatywna jest zapytanie get, najprawdopodobniej użycie jakiegoś implementatora (o ile dobrze to nazwałem) jawy do wygenerowania kodu i wtedy pobranie istotnych informacji. Chciałbym uprościć sobie życie :)
Pozdrawiam

0

W C++ do wywolania funkcji bazowej trzeb by sie trochę 'nakombinować' :)

Tzn. napisać Bazowa::Metoda zamiast base.Metoda?

0
Rev napisał(a)

Tzn. napisać Bazowa::Metoda zamiast base.Metoda?

Sam widzisz, w C# musisz użyć jednej kropki, a w C++ aż czterech. Na pewno trzeba się dużo nakombinować, żeby ustawić je w odpowiedniej kolejności.

crn napisał(a)

potrzebuje pozyskac sporo inforamcji ze storny html, jednak jest ona generowane przez jave itd.

Czyli chcesz wyciągnąć dane ze strony HTML pochodzącej z jakiegoś serwisu wykonanego w technologii JSP, z apletu Javy pracującego na stronie, czy też pomyliła Ci się Java z JavaScriptem?

Po poczytaniu trochę o net widzę, ze istnieje kontrolka web browser. Czy ona udostępnia mi w jakiejs "czytelnej" formie dane ze strony.

Tak, wyświetla w oparciu o silnik IE.

Nie wiem co to jest implementator jawy, ale do wyciągnięcia danych ze strony HTML można użyć klasy WebClient, pobrać zawartość strony metodą DownloadString i później ją analizować.

1 użytkowników online, w tym zalogowanych: 0, gości: 1