úterý 8. února 2011

Několik tapet pro odvážné

blog iconDnes jsem potřeboval po instalaci počítače najít nějakou zajímavou tapetu a tento odkaz se mi zalíbil, takže jsem se rozhodl se o něj podělit.

Takže několik hezkých tapet na Visual Studio 2010 naleznete na tého adrese http://vs2010wallpapers.com.

Užijte si je...

pátek 31. prosince 2010

Převod RGB Barvy z hexadecimální soustavy do desítkové soustavy

pastelkyJak napovídá nadpis dnešního článku, pokusíme se nalézt řešení problému, na který můžeme narazit v případě, kdy potřebujeme z RGB barvy v hexadecimálním zápisu (FF0000) vytvořit naplněnou strukturu Color ze jmenného prostoru System.Drawing reprezentujícího tuto barvu, tedy červenou (255, 0, 0). Celý problém je založen na absenci metody, která by umožnila tuto strukturu naplnit z barev v hexadecimálním formátu.

Vzhledem k tomu, že se tato funkcionalita občas hodí, byl to impuls k zamyšlení se nad vlastním řešením této problematiky.

Obecně řečeno jde o to převést hexadecimální číslo do desítkové soustavy, protože struktura Color má přímo statickou metodu FromArgb(int Red, int Green, int Blue), díky které je možné ji naplnit jednotlivými složkami.

Řešení není nikterak složité a je založené na převodu z hexadecimální soustavy do desítkové soustavy pomocí tohoto vzorce:

clip_image002

Tento vzorec popisuje obecný převod n číslic v hexadecimální soustavě. Pro převod barvy v RGB barvovém prostoru zapsané hexadecimálně, budeme potřebovat převádět vždy pouze dvouciferné hexadecimální číslo do desítkové soustavy, což lze z výše uvedeného vzorce vyvodit následovně:

clip_image002[5]

a po úpravě se tedy dostaneme k výslednému vzorci:

clip_image002[7]

Pokusme se tento vzorec dosadit a k tomuto účelu použijme červenou barvu reprezentovanou hexadecimálně jako FF0000. Rozeberme si tuto barvu po složkách. Červená složka R je FF zelená složka G je 00 a modrá složka B je také 00. Každá z těchto složek obsahuje dvouciferné hexadecimální číslo složené z číslic x0 a x1. Nyní již máme téměř veškeré informace pro náš převod. Jediné co ještě musíme znát, je jaké číslo reprezentují jednotlivá písmena AF. Přiřazení vidíme v následující tabulce:

A 10
B 11
C 12
D 13
E 14
F 15

Nyní už můžeme dosadit do vzorce hodnoty pro jednotlivé složky. Pro červenou:

clip_image002[10]

Pro zelenou:

clip_image002[12]

A pro modrou:

clip_image002[14]

Výsledkem našeho snažení je, že červená barva v RGB barvovém prostoru reprezentovaná čísli v desítkové soustavě vypadá takto: R=255, G=0, B=0. A s tímto výsledkem již můžeme vytvořit a naplnit strukturu Color:

System.Drawing.Color.FromArgb(255, 0, 0);
A tím bychom mohli být hotovy. Celé toto řešení je zabaleno do třídy Color, která obsahuje navíc informaci o průhlednosti a také strukturu Color plní i s touto informací.

image

Jak je vidět z diagramu naší třídy Color, obsahuje vlastnosti reprezentující jednotlivé složky barvového prostoru R, G, B a vlastnost pro průhlednost A. Dále jsou k dispozici konstruktory, které jsou přetížené a tyto vlastnosti naplňují voláním veřejné metody SetColor za použití popsaného převodu. Dále je pak k dispozici metoda GetColor, která vrací naplněnou strukturu System.Drawing.Color. z vlastností A, R, G, B třídy. Dále třída obsahuje statickou metodu GetColor pro rychlý převod barvy. Privátní metody GetHexDigit a GetIntFromHex jsou také statické, protože je potřebujeme využívat jek ve statické metodě GetColor tak i v nestatické metodě SetColor.

Pojďme se podívat jak to funguje. Pro ukázku funkčnosti využijeme statické metody GetColor, která vrací naplněnou strukturu System.Drawing.Color.

public static System.Drawing.Color GetColor(int Alpha = 255, string Color = "FFFFFF")
{
if (!Regex.IsMatch(Color, @"[A-Fa-f0-9]{6}"))
throw new ArgumentException("Hexadecimální zadání barvy není ve správném tvaru. Například 'FFFFFF'.", "Color");
if (Alpha < 0 || Alpha > 255)
throw new ArgumentException("Hodnota průhlednosti je mimo dovolený rozsah 0-255", "Alpha");

return System.Drawing.Color.FromArgb(Alpha,
GetIntFromHex(Color.Substring(0, 2)),
GetIntFromHex(Color.Substring(2, 2)),
GetIntFromHex(Color.Substring(4, 2))
);
}
Na začátku metody nalezneme nezbytné ošetření vstupů, k čemuž se u hexadecimálního zadání barvy hodí regulární výraz a pak ještě zkontrolujeme rozsah parametru průhlednosti. Oba parametry mají nastavenou výchozí hodnotu. Vlastní převod jednotlivých složek se provádí v metodě GetIntFromHex.
private static int GetIntFromHex(string Hex)
{
int L = GetHexDigit(sHex.Substring(0, 1));
int R = GetHexDigit(sHex.Substring(1, 1));
return (L * 16) + R;
}
Zde se v první řadě provede převod písmeného vyjádření hexadecimálního čísla na číselné pokud je to třeba v metodě GetHexDigit. A poté již nic nebrání aplikování výše popsaného vzorce, při čemž tedy x0 je proměnná L a x1 je proměnná R. Zbývá doplnit již zmíněnou metodu GetHexDigit.
private static int GetHexDigit(string Hex)
{
Hex = Hex.ToLower();
Hex = Hex.Replace("a", "10");
Hex = Hex.Replace("b", "11");
Hex = Hex.Replace("c", "12");
Hex = Hex.Replace("d", "13");
Hex = Hex.Replace("e", "14");
Hex = Hex.Replace("f", "15");

return int.Parse(Hex);
}
Tato metoda se tedy stará o převod písmen na čísla po té, co si případné velké písmena upravíme na malé.

Nyní jsme hotovy a převod bude funkční. Pro úplnost je zde ke stažení kompletní třída Color jako knihovna, a také její zdrojový kód.

sobota 11. prosince 2010

Jak na to : Obrázek z Resources

poradacPři programování WinFormových aplikací se může stát, že narazíte na potřebu mít uložené obrázky v Resources a teprve z něho přiřazovat obrázky do zobrazovacího prvku dynamicky.Naštěstí popisovaný scénář není problém, takže se pojďme podívat jak na to.

Prvním krokem je vytvoření Resource souboru. Provedeme to standartním způsobem. Nad objektem, do kterého chceme soubor Resources umístit, použijeme klávesovou zkratku Ctrl+Shift+A a nebo pravé tlačítko myši jak je ukázáno na obrázku.

res1

Dále v následném dialogu vybereme Resources File a pojmenujeme v našem případě na MyResource1.

res2

Nyní přepneme typ zdroje na Images, přičemž se změní i prostředí otevřeného Resources souboru.

res3

Teď už můžeme obrázky přidávat pomocí volby Add Resource v panelu. k dispozici máme obrázky typu PNG, BMP, GIF, JPEG, TIFF. Takže například pro drobnou animaci v aplikaci můžeme využít animovaný gif.

res4

Další možností jak do Resource dostat obrázek je prosté přetažení obrázku do otevřeného Resources souboru. V tuto chvíli máme v Resources souboru vložené naše obrázky, což v projektu vytvoří složku Resource a do ní naše obrázky vloží.

res6

Pokud do více Resources souborů budete ukládat obrázek se stejným názvem, bude se nahrazovat již vložený obrázek z jiného Resouces souboru.

Nyní už zbývá připravené obrázky použít. K tomu můžeme využít kontrol PictureBox, který umístíme na formulář. V kódu, třeba v události nahrání formuláře Load, přiřadíme do vlastnosti Image obrázek z našeho Resources souboru.

pictureBox1.Image = MyResource1.res1;
Object MyResource1 vzniká automaticky a jeho název je totožný s názvem našeho Resources souboru. Respektive, tento objekt náš Resources soubor reprezentuje. Dobré je, že díky tomu po napsání selektoru “.” se nabízejí námi vložené obrázky reprezentované vlastnostmi se stejným názvem jako vložené obrázky.

res5

A to je celé tajemství přiřazování obrázků z Resouces souborů. Jednoduchý příklad demonstrující zobrazení obrázku po stisknutí tlačítka ze dvou různých Resources souborů naleznete zde.

sobota 4. prosince 2010

Vytváření vlastních událostí

Motor-skoda-blogDneska se podíváme na vytváření vlastních událostí za použití standartních i vlastních delegátů.

Co je vlastně událost? Událost je základní komunikační nástroj mezi objekty, reprezentovaná metodou. Vyvolána je objektem v okamžiku, kdy je chtěné předat vnějšímu okolí informaci o tom, že se v objektu něco mění, nedaří, začíná apod. Záleží tedy na daném programátorovi zda o danou informaci má či nemá zájem, jestli si událost objedná tím, že vytvoří tělo metody události a přiřadí ho k této události. Tak bude moci v těle metody na danou událost reagovat.

Aby mohl programátor kvalifikovaně reagovat mnohdy nestačí pouze informace, že ta či ona událost proběhla, ale je nutné získat i nějaké doplňující informace. K tomu nám slouží vlastní delegát události, který může obsahovat třídu argumentů speciálně vytvořenou pro danou událost. Pomocí této třídy, jež je odvozena od třídy EventArgs, můžeme předávat informace (např. chybový kód či chybovou zprávu) v okamžiku, kdy se bude jednat o událost vyvolanou při nějakém chybovém stavu. Nyní se podíváme na oba případy podrobněji.

Celou problematiku si ukážeme na třídě, která reprezentuje automobil. Jako každý automobil bude mít naše třída palivovou nádrž a tzv. “Hladové oko” – kontrolku signalizující docházející palivo. V našem případě se kontrolka rozsvítí v okamžiku, kdy bude v nádrži méně než 5 litrů paliva.

Podívejme se nyní na třídu Auto:

image

Třída obsahuje dvě konstanty: VelikostNadrze nastavenou na 60 litrů a VelikostRezervy s hodnotou 5 litrů. Dále proměnou pro objekt časovače t, vlastnost ObsahNadrze, ve které budeme uchovávat informaci o aktuálním obsahu nádrže v litrech a logickou vlastnost SvitiRezerva indikující zda svítí “hladové oko”. Konstruktor obsahuje nastavení časovače na 1 vteřinu a objednání události Elapsed, tedy uplynutí intervalu časovače. Při vyvolání této události se zavolá metoda t_Elapsed, ve které se provedou tyto úkony:

  • Zmenší se obsah nádrže o jeden litr, což simuluje jízdu.
  • Pokud je nádrž prázdná, vyvolá událost “došlo palivo” a zavolá se metoda “zastav motor”, která simuluju zastavení motoru při nedostatku paliva.
  • Pokud není nádrž prázdná, vyvolá událost obsahující informaci o aktuálním stavu paliva v nádrži.
  • Pokud je obsah nádrže menší než velikost rezervy a kontrolka ještě nesvítí, rozsvítí “hladové oko” a vyvolá událost informující o tom, že dochází palivo.

Přehledně se na to můžeme podívat v následujícím vývojovém diagramu reprezentujícím metodu t_Elapsed volanou událostí časovače Elapsed.

Elapsed

Dále třída Auto obsahuje metodu pro spuštění motoru SpustMotor, což na naší simulaci představuje spuštění časovače a samozřejmě metodu pro zastavení motoru ZastavMotor. Nezbytná je metoda NatankujPalivo, která naplní nádrž až po okraj.

Samostatnou kapitolou jsou události třídy Auto. Jak jsme si již říkali na začátku článku, třída obsahuje dva druhy událostí. Všechny události, kromě události StavPaliva, využívají  standartního delegáta. Událost StavPaliva má vlastního delegáta StavPalivaEventHandler, který obsahuje již zmiňovanou třídu argumentů AutoEventArgs. Třída AutoEventArgs obsahuje jedinou vlastnost ObsahNadrze, která uvádí množství paliva v nádrži v litrech.

Události se dají rozdělit na dvě části. První je vytvoření a vyvolání události na straně objektu, který událostmi disponuje, v našem případě třídy Auto. Druhou částí je obsluha události na straně vnějšího okolí objektu, v našem případě to bude testovací program, lépe řečeno konzole.

Události uvnitř objektu

Vytvoření události se standartním delegátem je poměrně jednoduché a stačí uvést následující deklaraci události obsahující klíčové slovo event a delegáta, ke kterému se vztahuje.

public event EventHandler DochaziPalivo;
Přičemž EventHandler je již deklarovaný delegát v ASP.NETu a vypadá takto:
public delegate void EventHandler(object sender, EventArgs e)
Po vytvoření deklarace už můžeme naši událost vyvolávat:
if (this.DosloPalivo != null)
this.DosloPalivo(this, new EventArgs());
Před skutečným vyvoláním události je nutné zjistit, zda si ji někdo objednal, respektive vytvořil tělo této události. To zjistíme dotazem, jestli se vyvolávaná událost nerovná null. Je-li událost objednaná, zavoláme ji jako jakoukoliv jinou metodu.

Pokud bychom chtěli vytvořit událost, která bude předávat i další informace, musíme si vytvořit vlastního delegáta a jako jeden z parametrů použít třídu argumentů odvozenou od třídy EventArgs. Postupně se na to podívejme. Naše třída argumentů může vypadat například takto:

public class AutoEventArgs : EventArgs
{
public int ObsahNadrze
{
get;
set;
}
public AutoEventArgs(int ObsahNadrze)
{
this.ObsahNadrze = ObsahNadrze;
}
}
Jak je vidět, v tomto případě třída AutoEventArgs obsahuje pouze vlastnost ObsahNadrze, ve které se předává aktuální množství paliva v nádrži, a samozřejmě konstruktor, který má jako parametr celé číslo, jež je přiřazeno do popisované vlastnosti. Pokud by bylo třeba, tato třída může obsahovat i další informace, případně metody.

Máme-li naši třídu argumentů připravenou, nic nám nebrání abychom si vytvořili onoho vlastního delegáta:

public delegate void StavPalivaEventHandler(object sender, AutoEventArgs e);
Je vidět, že se náš delegát příliš od standartního neliší. Zaměněna je pouze již zmiňovaná třída argumentů. Nyní můžeme přistoupit k poslednímu kroku a tím je vytvoření naší události:
public event StavPalivaEventHandler StavPaliva;
Událost je vytvořena a my s ní můžeme začít pracovat. Vyvolání takovéto události je analogické jako u předchozí ukázky, pouze při vytváření instance třídy argumentů je jako parametr předána informace o množství paliva v nádrži.
if (this.StavPaliva != null)
this.StavPaliva(this, new AutoEventArgs(55));
Jako v předchozí ukázce volání události, i zde je nutné testovat, zda si někdo událost objednal. Pokud bychom to neotestovali a událost nebyla objednána, skončili bychom v chybě “Object reference not set to an instance of an object”.

Nyní se podívejme na třídu Auto jako na celek:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;

public class Auto
{
public event EventHandler DochaziPalivo;
public event EventHandler DosloPalivo;
public event EventHandler SpustenyMotor;
public event EventHandler ZastavenyMotor;
public delegate void StavPalivaEventHandler(object sender, AutoEventArgs e);
public event StavPalivaEventHandler StavPaliva;

private const int VelikostRezervyPaliva = 5;
private const int VelikostPalivoveNadrze = 30;
private Timer t;

public int ObsahNadrze
{
get;
private set;
}
public bool SvitiRezerva
{
get;
private set;
}
public Auto()
{
t = new Timer(1000);
t.Elapsed += new ElapsedEventHandler(t_Elapsed);
}
public void NatankujPalivo()
{
this.ObsahNadrze = VelikostPalivoveNadrze;
this.SvitiRezerva = false;
}
public void SpustMotor()
{
t.Start();
if (this.SpustenyMotor != null)
this.SpustenyMotor(this, new EventArgs());
}
public void ZastavMotor()
{
t.Stop();
if (this.ZastavenyMotor != null)
this.ZastavenyMotor(this, new EventArgs());
}
private void t_Elapsed(object sender, ElapsedEventArgs e)
{
if (--ObsahNadrze == 0)
{
if (this.DosloPalivo != null)
this.DosloPalivo(this, new EventArgs());
this.ZastavMotor();
}
if (this.StavPaliva != null)
this.StavPaliva(this, new AutoEventArgs(this.ObsahNadrze));
if (ObsahNadrze <= VelikostRezervyPaliva && !this.SvitiRezerva)
{
this.SvitiRezerva = true;
if (this.DochaziPalivo != null)
this.DochaziPalivo(this, new EventArgs());
}
}

public class AutoEventArgs : EventArgs
{
public int ObsahNadrze
{
get;
set;
}
public AutoEventArgs(int ObsahNadrze)
{
this.ObsahNadrze = ObsahNadrze;
}
}
}
Tím jsme si popsali třídu Auto a ještě se podívejme, jak s touto třídou pracuje testovací aplikace.

Události vně objektu

Máme-li třídu Auto, můžeme si s touto třídou hrát a vše řádně otestovat. Za tímto účelem si vytvoříme konzolovou aplikaci, která bude simulovat chování řidiče. Scénář bude vypadat takto:

  • Vytvoříme instanci třídy Auto.
  • Natankujeme palivo.
  • Spustíme motor.

O spuštění motoru nás bude informovat událost, sami budeme sledovat informace o množství paliva v nádrži a zároveň budeme informováni o tom, že v nádrži je méně paliva než je rezerva – díky tomu se rozsvítí kontrolka “hladové oko”. O nulovém stavu paliva budeme opět informováni událostí. Nakonec dojde k ukončení běhu motoru, o čemž budeme opět informováni.

Dosti abstrakce, pojďme se na to podívat. Pro to, abychom mohli být informování událostí, musíme si pro každou z popisovaných událostí nastavit odběr, tedy si jí objednat. To se prování za pomoci operátoru +=. Pokud bychom chtěli událost z nějakého důvodu odregistrovat, můžeme tak učinit za pomoci operátoru –=.

Objekt.Udalost += new NazevDelegata(NazevMetody);

private void NazevMetody(object sender, EventArgs e)
{
//tělo obslužné události
}
Nyní se pojďme podívat na reálnou testovací aplikaci, jejíž chování jsme si popsali.
class Program
{
private static Auto shAuto;
static void Main(string[] args)
{
//nová instance automobilu
shAuto = new Auto();
//objednání událostí
shAuto.DochaziPalivo += new EventHandler(shAuto_DochaziPalivo);
shAuto.DosloPalivo += new EventHandler(shAuto_DosloPalivo);
shAuto.SpustenyMotor += new EventHandler(shAuto_SpustenyMotor);
shAuto.ZastavenyMotor += new EventHandler(shAuto_ZastavenyMotor);
shAuto.StavPaliva += new Auto.StavPalivaEventHandler(shAuto_StavPaliva);
//natankujeme nádrž
shAuto.NatankujPalivo();
//spustíme motor a budeme čekat než nám dojde palivo
shAuto.SpustMotor();
//zamezeni ukončení konzole
Console.Read();
}

//zpracování jednotlivých událostí
private static void shAuto_StavPaliva(object sender, Auto.AutoEventArgs e)
{
Console.WriteLine("V nádrži je {0} litrů paliva", e.ObsahNadrze);
}
private static void shAuto_DosloPalivo(object sender, EventArgs e)
{
Console.WriteLine("Došlo palivo!");
}
private static void shAuto_ZastavenyMotor(object sender, EventArgs e)
{
Console.WriteLine("Motor je zastaven...");
}
private static void shAuto_SpustenyMotor(object sender, EventArgs e)
{
Console.WriteLine("Motor je spuštěn...");
}
private static void shAuto_DochaziPalivo(object sender, EventArgs e)
{
Console.WriteLine("Dochazí palivo, natankuj!");
Console.WriteLine("Hladové oko: {0}", shAuto.SvitiRezerva ? "Svítí" : "Nesvítí");
}
}
Po spuštění se na konzoli vypíší informace z třídy Auto dle popisovaného scénáře. Pro ukončení aplikace je třeba stisknout například klávesu enter. 

Registrace událostí v prostření Visual Studia

Pokud pracujeme ve Visual Studiu, můžeme pro registraci událostí využívat vlastnost tohoto prostředí, která se nám snaží celý proces zjednodušit. Po zapsání operátoru += za název události objektu nám Visual Studio zobrazí volbu v podobě nabídky IntelliSence, ve které je možnost automatického vytvoření asociace s delegátem události při stisknutí klávesy TAB.

tab1

Při druhém stisknutí klávesy TAB vytvoří přímo kostru metody, která bude událost obsluhovat.

tab2

Tato kostra potom vypadá takto:

private static void shAuto_DochaziPalivo(object sender, EventArgs e)
{
//prostor pro zpracování události
}

Nyní bychom již měli být schopni vytvářet vlastní události objektů se standartním i vlastním delegátem události. Pro úplnost ještě přikládám zdrojový kód příkladu zde.

Tím je to pro dnešek vše.

středa 24. listopadu 2010

Když už nevím kudy kam, je čas na Fix it

FixitKdyž už nevím kudy kam, tak je načase vyzkoušet portál podpory Fix it. Je ho možné nalézt na této adrese v českém jazyce. Tato služba napomáhá řešit nejčastější problémy na stanicích i na serverech.

Celé to funguje tak, že po prvotní volbě okruhu problémů a následném upřesnění problému, portál nabídne balíčky msi ke stažení pro vlastní diagnostiku problému na postiženém PC. Po spuštění toho staženého balíčku, je provedena diagnostika a je možné zvolit automatickou opravu, je-li možná, případně je nabídnuto možné řešení problému. Pokud se diagnostickému balíčku nepodaří nalézt deklarovaný problém, případně nezná-li řešení, nabízí kontakt pro další řešení problému mocí běžné podpory.

fixitobr

Osobě mě překvapil rozsah okruhů problému a jsem tím mile překvapen.

A nakonec ještě adresa http://support.microsoft.com/fixit/cs.

čtvrtek 11. listopadu 2010

Free SEO Toolkit

framework-controls-smDnes jsem náhodou objevil zajímavou utilitu pro optimalizaci webu. Jedná se o modul který je instalován na web serveru IIS 7 a umožňuje analyzovat web. Instalace se prování standardně pomocí Web platform installeru.

Po provedení analýzy je k dispozici mnoho pohledů na web a je možné výsledky filtrovat dle potřeby vývojáře. Více informací je na webu Microsoftu, kde je ke shlédnutí i demonstrační video.

středa 10. listopadu 2010

ValidateRequest v ASP.NET 4

kruhV ASP.NET se stala změna ve validaci requestu stránky. Způsob který bylo možné používat do verze ASP.NET 3.5 již nestačí. Respektive není možné validovat request tak jak jsme byli zvyklí. K tomu aby vše fungovalo jako zastara je nutné přidat je do web.config souboru toto nastavení:

<system.web>
<httpruntime requestvalidationmode="2.0" />
</system.web>

Tímto nastavení povolíme režim validace jako ve verzi ASP.NET 2.0 a problém vyřešen.

Celý problém vznikl tím, že od verze ASP.NET 4.0 jsou validovány všechny všechny požadavky a tak k vyhození vyjímky dochází již při volání http handleru.

Pokud by jsme chtěli využívat nové možnosti validace, které nám umožňuje ASP.NET 4.0, můžeme tak učinit napsáním vlastních validačních providerů.

Více informací naleznete ASP.NET 4 Whitepaperu.