Monthly archive for September, 2009

Pasek boczny czyli gadżetomania

2009-09-28 13:13

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):

File: Yubnub Gadget  Yubnub Gadget (43.1 KiB, 1,723 downloads)


Jeśli ktoś też chciałby pobawić się w tworzenie wtyczek do sidebara, to polecam odwiedzenie przede wszystkim tych linków:

  • Build Your Own Windows Vista Sidebar Gadgets – wyczerpujący artykuł omawiający wszystkie aspekty związane z tworzeniem gadżetów, łącznie z tymi bardziej skomplikowanymi, jak okienka ustawień i flyouty
  • Blog Tima Heuera skąd można ściągnąć szablon projektu dla Visual Studio, mogący służyć jako podstawa do tworzenia gadżetów (niestety jest tylko wersja dla VS2005)
Tags: ,
Author: Xion, posted under Programming » 3 comments

Przekierowanie z POST-em

2009-09-19 15:45

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:

  1. <form method="POST" action="http://someusefulwebsite.com/login">
  2.      <!-- parametry i ich wartości -->
  3.     <input type="hidden" id="user" value="qwerty"/>
  4.     <input type="hidden" id="pass" value="uiop"/>
  5. </form>

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:

  1. // HTTP/1.1
  2. Cache-Control: no-store, no-cache, must-revalidate
  1. // HTTP/1.0
  2. Cache-Control: post-check=0, pre-check=0
  3. Pragma: no-cache

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:

  1. <script language="javascript" type="text/javascript">
  2.     document.forms[0].submit();

Tak przygotowaną stronę możemy podlinkować pod nasz serwis. Jak widać trochę z tym zabawy, ale tak to jest, gdy chcemy zrobić coś niestandardowego :)

Tags: , , ,
Author: Xion, posted under Internet » 3 comments

Metody rozszerzające w C#

2009-09-11 12:28

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:

  1. public static class StringExtensions
  2. {
  3.     // zwraca liczbę znaków w ciągu
  4.     public static int WordCount(this String str)
  5.         { return str.Split(new char[] { ' ' }).Length; }
  6. }

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:

  1. string s = "Ala ma kota";
  2. int words = s.WordCount();

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:

  • Po pierwsze, możemy zdefiniować klasę pochodną po tej, której chcemy dodać metodę. Albo wręcz zdefiniować sobie po prostu zwykłą funkcję przyjmującą jeszcze zwyklejszy parametr i mieć coś w stylu 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 ;-]).
  • Po drugie, możemy zwyczajne pójść do deklaracji klasy i żądaną metodę dodać. Naturalnie, musi to być nasza własna klasa, której kodem dysponujemy i który możemy zmieniać.

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

Tags: ,
Author: Xion, posted under Programming » 6 comments

Kawałek kodu w makrze

2009-09-01 19:52

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 returnem musimy coś jeszcze zrobić – np.:

  1. bool SprobujCosObliczyc(const data& parametry, int* const wynik)
  2. {
  3.     if (parametryNieSaDobre) { *wynik = 0; return false; }
  4.     /* ... */
  5.     if (cosObliczylismyAleJestZle) { *wynik = 0; return false; }
  6.     /* ... */
  7.     if (tutajCosSiePopsulo) { *wynik = 0; return false; }
  8.     /* ... */
  9.     if (juzPrawieKoniecAleNiestetyLipa) { *wynik = 0; return false; }
  10.     /* ... */
  11.     return true;
  12. }

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:

  1. #define RETURN { *wynik = 0; return false; }

definiowane przed i #undefowane 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 ifie:

  1. if (wyjsc) RETURN; else { /* ... */ }

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ę:

  1. #define RETURN do { *wynik = 0; return false; } while (0)

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.

Tags: , ,
Author: Xion, posted under Programming » 12 comments
 


© 2023 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.