Po przesiadce na monitor typu widescreen (w moim przypadku 22-calowy) zaczyna się doceniać sens istnienia takiego wynalazku jak pasek boczny Windows. Na takim ekranie zmniejszenie obszaru przeznaczonego na okna nie tylko przeszkadza, ale wręcz pomaga w uniknięciu zeza rozbieżnego ;) A że przy okazji taki pasek może wyświetlać chociaż częściowo przydatne informacje – tym lepiej…
Zawsze jednak można chcieć więcej. Dlatego też przez te kilka ostatnich dni, kiedy to przygotowywałem do użytku dołączony do wspomnianego wcześniej monitora komputer (o czym pewnie wspomnę jeszcze później ;]), zainteresowałem się też tworzeniem swoich własnych gadżetów do umieszczenia na sidebarze. Zaprezentuję więc, co na ten temat odkryłem.
Jak wiadomo, pasek boczny Windows to właśnie skupisko takich gadżetów, które coś przydatnego pokazują i czasem są też interaktywne. Domyślnie mamy tu zegar, kalendarz, miernik zużycia procesora i pamięci, itp. Nie są więc one jakoś specjalnie zachwycające; lepiej byłoby mieć tutaj coś bardziej spersonalizowanego. A skoro umiemy kodować, to może dałoby się samemu taką wtyczkę napisać?… Okazuje się, że to całkiem proste – chociaż w nieco innym sensie niż mogłoby się z początku wydawać.
Prostota polega na tym, że tworzenie takich wtyczek nie wymaga programowania w klasycznym sensie. Są one bowiem głównie… zbiorami dokumentów HTML, czyli małymi stronami WWW. To, co widać na pasku bocznym jest zwyczajnie renderowane przez silnik przeglądarki IE7. (Pod tym względem pomysł przypomina trochę ActiveDesktop z Windows 95).
Naturalnie jest tutaj trochę dodatkowej roboty, polegającej m.in. na przygotowaniu manifestu, czyli dokumentu XML z opisem plików składających się na nasz gadżet – łącznie ze wskazaniem, który z plików HTML stanowi jego zasadniczą zawartość. Ponadto możliwe jest też utworzenie oddzielnego dokumentu (też HTML) z ustawieniami na gadżetu – sidebar udostępnia przy tym proste API, które pozwala na ich wczytywanie i zapisywanie. Podobnie jest z tzw. flyoutem, czyli częścią pluginu “wystającą” poza pasek boczny; tutaj też możliwe jest jej pokazywanie i ukrywanie.
Te bardziej zaawansowane funkcje wymagają już używania skryptów (np. JavaScript), ale nawet z niewielką ich znajomością można osiągnąć ciekawe efekty. Oto jeden z nich, jaki przy okazji poznawania tematu popełniłem – bardzo prosty gadżet, który umieszcza na pasku okienko na wpisywanie poleceń YubNuba (przydatnej usługi sieciowej, o której kiedyś pisałem):
Yubnub Gadget (43.1 KiB, 1,723 downloads)
Oprócz ciasteczek (cookies) dwoma podstawowymi sposobami przekazywania parametrów na wejście serwera HTTP są metody znane jako GET i POST. Ta pierwsza wykorzystuje do tego sam adres URL, umieszczając dodatkowe dane po znaku zapytania, np.: /forum/showthread.php?id=12345&filter=none. W przypadku tej drugiej parametry są przekazywane poprzez treść samego żądania HTTP; z punktu widzenia użytkownika są więc one niewidoczne.
Metoda GET zwykle służy do wymiany danych między stronami połączonymi za pomocą zwykłych linków. POST z kolei wykorzystuje się do wysyłania informacji wprowadzanych przez użytkownika w różnego rodzaju formularzach. Przekierowanie następuje wówczas po jego wysłaniu, co zwykle czyni się odpowiednim przyciskiem (submit).
Bywa jednak tak, że chcemy dokonać takiego przekierowania – z ustalonymi parametrami – po zwykłym kliknięciu na link, z pominięciem wypełniania formularza przez użytkownika. Dobrym przykładem jest sytuacja, gdy nasza strona korzysta w jakiś sposób z innego serwisu, do którego przejście wymaga logowania. Jeśli chcielibyśmy, by odbywało się ono automatycznie – po kliknięciu jakiegoś linku – to musimy wysłać odpowiednie żądanie HTTP z parametrami przesłanymi metodą POST. Do tego nie wystarczy niestety sam znacznik <a>
.
Rozwiązaniem jest wtedy użycie dodatkowej strony przekierowującej, na której umieścimy już odpowiednio “wypełniony” formularz:
Oczywiście nazwy i wartości parametrów (zapewne generowane dynamicznie po stronie serwera) zależą ściśle od tego, dokąd chcemy nasz wyrób formularzopodobny wysłać. Wszystkie je deklarujemy jednak jako <input type="hidden" />
, bo w założeniu użytkownik nie powinien ich (łatwo) zobaczyć. Ponadto, jeśli – tak jak wyżej – mówimy o loginie/haśle czy innych danych, które powinno się chronić przed niepowołanym dostępem, to powinniśmy jeszcze wysyłać razem z naszą stroną nagłówki HTTP zabraniające cache‘owania:
W końcu, skoro mamy już gotowy “formularz”, to trzeba jeszcze zadbać o to, by wysłał się on sam natychmiast po załadowaniu strony przekierowującej. Do tego już trzeba wykorzystać skrypt uruchamiany w przeglądarce:
Tak przygotowaną stronę możemy podlinkować pod nasz serwis. Jak widać trochę z tym zabawy, ale tak to jest, gdy chcemy zrobić coś niestandardowego :)
Wspomnę dzisiaj o dość dziwnej funkcji, która została dodana w wersji 3.0 języka C#. Polega ona na możliwości dodania nowych metod do istniejących klas bez zmiany ich definicji. Odbywa się to poprzez zdefiniowanie tych dodatkowych metod jako statycznych (w innych klasach) i użyciu specjalnej składni dla jej pierwszego parametru. Oto przykład:
Jeśli ktoś co nieco wie o tym, jak od środka działają metody obiektów w C++, to pewnie przypomina sobie, że to co wewnątrz metody jest wskaźnikiem this
w rzeczywistości przekazywane jest metodzie jako jej pierwszy parametr. Pewnie ten fakt posłużył twórcom C# jako inspiracja przy ustalaniu składni metod rozszerzających.
Jak to działa? Otóż bardzo prosto. Dzięki powyższej definicji standardowa klasa System.String
została teraz wzbogacona o nową metodę WordCount
, której możemy użyć tak samo, jak każdej innej metody tej klasy:
Powód, dla którego fakt istnienia podobnego feature‘a nazwałem dość dziwnym, powinien się w tej chwili stać nieco jaśniejszy. Po krótkim zastanowieniu można bowiem stwierdzić, że niemal identyczny efekt można osiągnąć dwoma innymi sposobami:
StringUtils.WordCount(s)
. Jak widać, co najmniej jeden z tych sposobów można zastosować do każdej klasy – także takiej, której definicją nie dysponujemy (co w gruncie rzeczy jest banalne; na takich “sztuczkach” polega przecież całe programowanie obiektowe ;-]).Cechą wspólną obu tych “obejść” jest to, iż to my chcemy mieć tę nową metodę i to my ją definiujemy – zapewne dlatego, że to my chcemy jej potem używać. A skoro tak, to mamy wolność w ustaleniu sposobu jej wywoływania, ergo: nie ma znaczenia, jak ją zdefiniujemy. Któryś z tych dwóch/trzech sposobów będzie więc wystarczający.
Czyżby więc wychodziło na to, że C# w końcu dorobił się feature‘a, który rzeczywiście niczemu nie służy i jest kompletnie bez sensu? :) Prawie… Jak to z większością nowości w C# 3.0, przyczyna wprowadzenia metod rozszerzających streszcza się w – za przeproszeniem – czterech literach: LINQ.
LINQ opiera się bowiem na rozszerzeniu interfejsów pojemników (np. IEnumerable
) o dodatkowe metody służące wykonywaniu na nich quasi-SQL-owych zapytań – jak np. Select
czy Where
. One właśnie zostały zaimplementowane jako metody rozszerzające. A że ponadto trafiły one do przestrzeni nazw System.Linq
, to stają się dostępne dopiero po zadeklarowaniu użycia tej właśnie przestrzeni.
Reasumując: twórcy .NET-a dodali dwie nowości (metody rozszerzające oraz LINQ) po to, żeby ta pierwsza pozwalała na nieużywanie tej drugiej. Genialne, czyż nie? ;D
Jeśli staramy się pisać kod zgodnie z dobrymi praktykami programowania w C/C++, to niezbyt często korzystamy z dyrektywy #define
. W większości przypadków ogranicza się to zresztą do zdefiniowania jakiegoś symbolu służącego do kompilacji warunkowej (np. WIN32_LEAN_AND_MEAN
). Od czasu do czasu bywa jednak tak, że chcemy użyć #define
w jego – teoretycznie – głównym zastosowaniu, czyli do zastępowania jednego kawałka kodu innym.
Uzasadnione przypadki takiego postępowania (do których nie należą np. makra udające funkcje, czyli sławetne #define min
/max
) to tylko takie sytuacje, w których bez #define
rzeczywiście musielibyśmy wiele razy pisać (prawie) to samo. Moim ulubionym przykładem czegoś takiego jest wychodzenie z funkcji w wielu miejscach, gdzie przed każdym return
em musimy coś jeszcze zrobić – np.:
Zwyczajne ustawienie *wynik = 0;
na początku funkcji będzie nieakceptowalne, jeśli chcemy, by w przypadku rzucenia wyjątku w którymś z /*... */
podana do funkcji zmienna pozostała bez zmian.
Prostym rozwiązaniem wydaje się więc makro:
definiowane przed i #undef
owane tuż po funkcji. Pomysł byłby dobry, gdyby nie to, że w tej postaci makro to powodowałoby błędy składniowe. Kiedy? Chociażby w takim if
ie:
Tutaj bowiem kompilator nie znalazłby instrukcji if
pasującej do else
, co jest naturalnie błędem. Powodem tego jest średnik po wystąpieniu makra, generujący pustą instrukcję i sygnalizujący (przedwczesny) koniec klauzuli if
.
Jak ominąć ten problem? Odpowiedź jest może zaskakująca: instrukcje trzeba zamknąć w… pętlę:
Jak nietrudno zauważyć, taka pętla wykona się dokładnie raz (i co więcej, kompilator o tym doskonale wie, zatem może ją zoptymalizować – tj. wyrzucić wszystko poza zawartością). Działanie jest więc takie same. Różnica polega na tym, że teraz takie makro może być używane w dowolnym miejscu bez żadnych niespodziewanych efektów.