Windows Mobile Support

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Tuesday, 28 February 2012

How NOT to use AS keyword

Posted on 11:01 by Unknown
Mai mult ca sigur ati folosit pana acuma "as". Prin intermediul sau se poate face cast unui obiect la un tip dat, iar in cazul in care cast-ul nu se poate face, valoarea returnata este null.
BaseItem item = val as BaseItem;    // returneaza null daca nu poate sa faca conversia
BaseItem item = (BaseItem) val; // arunca exceptie daca nu poate sa faca conversia
Despre "as" am mai discutat in acest post: http://vunvulearadu.blogspot.com/search/label/C%23%20AS%20Keyword%20Cast%20speed%20performance
Mai jos o sa va prezint un mod mai ciudat de a folosii keyword-ul "as". A fost folosit pentru a detecta daca un element este de un anumit. Iata cum a fost folosit:
BaseItem item;
...
if ( item as CarItem != null )
{
...
}
else if ( item as BookItem != null )
{
...
}
else if ( item as ClassItem != null )
{
...
}
Ce mi s-a parut interesant este cum a fost folosit "as". In locul sau se poate folosii fara probleme "is". Acesta o sa returneze true daca un obiect se poate converti la tipul dat. Codul de mai sus se poate rescrie in felul urmtor:
BaseItem item;
...
if ( item is CarItem )
{
...
}
else if ( item is BookItem )
{
...
}
else if ( item is ClassItem )
{
...
}
Codul arata ceva mai bine, dar inca ceva ce nu pare okay. Ca sa scapam de acest lant de IF-uri putem sa ne declaram in BaseItem o metoda virtuala sau abstracta la care sa facem override in clasele noastre( CarItem, BookItem,CLassItem). Prin acest mod am avea un singur apel la o metoda, care pentru fiecare din clasele noastre poate sa execute codul dorit:
abstract  class BaseItem
{
public abstract void DoAction();
}
public class CarItem : BaseItem
{
public override void DoAction()
{
...
}
}
... pentru fiecare din clasele noastre ...
Iar insiruirea de IF-uri pe care era mai sus devine:
item.DoAction();

Enjoy!
Read More
Posted in as, C# | No comments

Default value and TryParse

Posted on 07:19 by Unknown
Ce vi se pare ciudat in urmatorul cod?
int value;
if(!int.TryParse(text.ToString(), out value))
{
value = 0;
}
In mod default, toate tipurile de numere de tip value type au valoarea default 0. Din aceasta cauza nu mai este nevoie sa setam value 0. Ajunge sa avem doar urmatorul cod:
int value;
int.TryParse(text.ToString(), out value);
In cazul in care vrem sa obtinem valoarea default pentru orice tip de data putem sa ne folosim de "default". Acest keyword returneaza null pentru toate tipurile referinta si 0 (zero) pentru value type. In cazul structuriilor acesta o sa returneze structura noastra, iar fiecare element din structura o sa fie inializat cu default value pentru acesta.
var value1 = default(int);        // 0
var value2 = default(double); // 0
public struct Point
{
public int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
}
var value3 = default(Point); // X si Y o sa fie 0
var value 4 = default(MyCustomClass) // null

In cazul in care vrem ca codul nostru sa fie mai usor de inteles putem ca in momentul in care il declaram pe value sa il setam cu default(int) sau cu 0. Eu prefer a doua varianta deoarece este mult mai usor de citit.
Read More
Posted in default | No comments

Monday, 27 February 2012

Field like events and polymorphic invocation

Posted on 11:45 by Unknown
Ce vi se pare gresit in codul de mai jos:
public class Base
{
public virtual event EventHandler EventOne;
}
public class Derived : Base
{
public override event EventHandler EventOne;
public void DoAction()
{
...
EventOne(this, args);
}
}
In clasa de baza avem un eveniment la care se poate face override in orice clasa derivata. Desi la prima vedere totul pare sa fie in ordine daca ne uitam mai atent, putem sa observam o problema care poate sa apara din cauza la override.
EventOne o sa existe in doua locatii diferite, atat in clasa de baza cat si in clasa derivata. Din aceasta cauza o sa fie momente cand EventOne din clasa de baza nu o sa fie niciodata instantiat.
Din aceasta cauza, in cazul in care evenimentul este apelat din clasa de baza ne putem trezi cu un comportament ciudat, precum NullReferenceException sau sa se execute cod la aruncarea unui eveniment pe care noi nu ne-am astepta sa se execute.
Ce putem sa facem ca sa rezolvam aceasta problema?
Avem la indemana doua solutii. Prima varianta este sa eliminam virtual si override. O sa fie nevoie sa ne declaram o metode de tip "event-firing" in clasa de baza. Aceasta metoda o sa fie adaugata in clasa de baza si tot ce va face este sa arunce evenimentul nostru. In clasa derivata nu se va folosii direct evenimentul ci se va apela metoda pe care noi am declarato in clasa de baza. Iar aceata la randul ei o sa arunce evenimentul. Mai jos puteti sa gasiti implementarea propusa:
public class Base
{
public event EventHandler EventOne;
public void FireEventOne(object sender, EventArgs args)
{
if (EventOne != null)
{
EventOne(sender, args);
}
}
}
public class Derived
{
public void DoAction()
{
...
FireEventOne(this, args);
}
}

In varianta data mai sus, clasa derivata nu mai poate sa faca override la eveniment, aceasta putand doar sa se inscrie la acest eveniment. Field-ul EventOne nu o sa mai fie duplicat in clasa de baza. Prim aceasta metoda am eliminat orice comportament ciudat care ar fi putut sa apara.
Daca avem nevoie sa facem override, atunci va recomand sa mergeti pe varianta in care in clasa de baza evenimentul sa fie declarat ca si abstract( nu consider aceasta variata ca fiind cea mai sanatoasa).
public class Base
{
public abstract event EventHandler EventOne;
}
Va recomand sa va ganditi de doua ori daca chiar aveti nevoie de un eveniment abstract. S-ar putea ca design-ul pe care l-ati ales sa nu fie cel mai bun.
Read More
Posted in abstracta, event, virtual | No comments

Friday, 24 February 2012

The string representation of a bool

Posted on 04:43 by Unknown
Ce parere aveti de urmatorul cod:
var result = service.Call("True");
Totul pare destul de okay mai putin string-ul "True". O solutie ar putea sa fie sa il punem intr-o constanta, dar tot nu e destul de bine.
In cazul in care avem nevoie de reprezentarea sub forma unui string a unei valori boolean este nevoie sa folosim:
bool.TrueString
sau
bool.FalseString
Codul dat in exemplu mai sus ar arata in felul urmator:
var result = service.Call(bool.TrueString );
Enjoy!
Read More
Posted in C# | No comments

Wednesday, 22 February 2012

WCF and Silverlight - How to add custom information to a message header

Posted on 00:37 by Unknown
In acest post am discutat despre cum se pot pune informatii in header-ul unui mesaj care este trimis prin WCF. In cazul in care incercati sa folositi aceasta solutie pentru un client pe Silverlight, o sa observati ca desi serverul adauga proprietatiile in header-ul mesajului acestea nu ajung la client, chiar daca pe sarma sunt adaugate.
Din Silverlight nu avem acces la toate proprietatiile care sunt trimise in header. Avem acces doar la cateva proprietati. De exemplu una din propietati este StatusCode. Acesta are valoarea 200 daca apelul s-a terminat cu success.
Datele care le punem in header pentru un client Siverlight, trebuie sa fie puse ca un nou Header. Mai jos gasiti cum puteti adauga un nou header de pe server, iar clientul cum il poate accesa. Al doilea parametru pe care l-am setat cu empty string reprezinta namespace URI pentru header-ul nostru.
public class ServerTokenInspector : IDispatchMessageInspector
{
public void BeforeSendReply(ref Message reply, object correlationState)
{
reply.Headers.Add(MessageHeader.CreateHeader("ServerToken", string.Empty, Guid.NewGuid()));
}

public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
return null;
}
}

public class ServerTokenClientInspector : IClientMessageInspector
{
public void AfterReceiveReply(ref Message reply, object correlationState)
{
if (reply.Headers.FindHeader("ServerToken", string.Empty) >= 0)
{
Guid token = reply.Headers.GetHeader<Guid>("ServerToken", string.Empty);
}
}

public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
return null;
}
}

Enjoy!
Read More
Posted in C#, Silverlight, WCF | No comments

Monday, 20 February 2012

Windows Live - SkyDrive

Posted on 13:18 by Unknown
Windows LIVE series:
  • Introducere
  • Web Authentication
  • Live Connect
  • Basic Operations
  • SkyDrive
Astazi o sa vorbim despre cum putem accesa SkyDrive.
Pentru a putea avea acces la datele pe care un user le are pe SkyDrive este nevoie ca la logare sa setam scopul "wl.skydrive". Avand setat acest scope o sa putem accesa orice informatie pe care userul o are pe SkyDrive.
WL.init({ client_id: {idClient}, redirect_uri: {ourRedirectUrl} });
WL.login(
{ "scope": "wl.skydrive" },
function (response) {
if (response.status == "connected") {
alert("Utilizator conectat");
}
else {
alert("Autentificare esuata");
}
});
Dupa ce utilizatorul s-a logat tot ce ne-a mai ramas este sa apelam API-ul care il avem la dispozitie. Fiecare element care ne vine dupa o interogare o sa contina date precum tipul ementului( daca e folder sau fisier - ce tip de fisier), nume fisier, id, dimensiune etc. Aceste informatii sunt foarte asemanatoare cu cele pe care le avem cand suntem intr-un director de pe disk-ul local. Din JS pentru a aduce toate elementele din root trebuie sa facem urmatorul apel:
 WL.api({ path: ""/me/skydrive/files", method: "GET" }, onGetRootItemsComplete);
function onGetRootItemsComplete(response) {
if (response.error) {
alert("A aparut o eroare");
return;
}
var items = response.data;
var foundFolder = 0;
for (var i = 0; i < items.length; i++)
{
// item[i].type - tipul fisierului. Valore este "fo-lder" daca elementul este un folder
// daca ar fi un fisier aceast camp ar avea valoarea "file"
// item[i].name - numele la element
// item[i].id - id unic a elementului din SkyDrive
}
}

O sa avem nevoie de id, daca vrem de exemplu sa facem download la continutul unui fisier.
Pentru a putea vedea toate folderele, albumele de poze si fisierele din root a unui user pe de Skydrive e nevoie sa facem un request cu path-ul setat spre: me/skydrive/files
Pentru a accesa fisierele unui folder este nevoie sa apelam urmatorul path: {folderId}/files . Exact la fel se face daca vrem sa aducem pozele dintr-un albul: {album_id}/files.
Dar cum putem sa adaugam un nou folder pe SkyDrive. Pentru acest lucru avem nevoie de numele la folder, o scurta descriere si locatia unde dorim sa il adaugam. Mai jos puteti gasi un exemplu in C#:
Dictionary<string, object> newFolderData = new Dictionary<string, object>();
folderData.Add("NewFolderName", "New folder description");
LiveConnectClient liveConnectClient = new LiveConnectClient(session);
liveConnectClient.PostCompleted +=
new EventHandler<LiveOperationCompletedEventArgs>(CreateFolderPostCompleted);
client.PostAsync("me/skydrive/files/BaseFolder", newFolderData);
...
void CreateFolderPostCompleted(object sender, LiveOperationCompletedEventArgs e)
{
// Daca e.Error este diferit de NULL, atunci actiunea nu s-a terminat cu succes.
}
Daca in al doilea exemplu am vazut cum putem itera printr-un folder, acuma va propun sa download un fisier de pe SkyDrive. Odata ce avem id-ul la fisierul pe care vrem sa il copiem local, e nevoie sa apelam direct metoda download din JS sau DownloadAsync din C#. Pentru exemplul de mai jos am ales tot varianta C#:
client.DownloadCompleted +=
new EventHandler<LiveDownloadCompletedEventArgs>(OnFileDownloadCompleted);
client.DownloadAsync("file.{id_fisier}/content");
...
void OnFileDownloadCompleted(object sender, LiveDownloadCompletedEventArgs e)
{
// e.Result o sa contina fisierul nostru.
// Nu uitati sa faceti close la Result, deoarece este un stream: e.Result.Close();
}
Dupa cum am putut vedea prin intermediul API-ului este foarte simplu sa lucram cu SkyDrive. Nu uitati ca SkyDrive nu permite prin intermediul API-ului upload-ul la orice fel de fisiere. Asigurativa inainte sa faceti upload ca fisierul vostru este suportat. Din interfata web puteti uploada orice fel de fisiere.
Fisierele care se pot copia pe SkyDrive prin intermediul API sunt:
  • PDF, txt + fisiere Office precum Word, Excell, etc
  • poze in orice format supotat de Windows
  • audio doar in format wav
  • video in format wmv sau H.264
Orice tip de fisier poate sa fie adaugat din brower de exemplu. Trebuie tinut cont ca, chiar daca din API manipulam datele unui user( schimba vizibilitatea unui fisier), nu putem sa restrictionam accesul la fisere a.i. userul sa nu le poata accesa.
Read More
Posted in Live Connect, SkyDrive | No comments

Sunday, 19 February 2012

WCF - How to add custom information to a message header

Posted on 09:52 by Unknown
De obicei intr-o aplicatie client-server folosim WCF pentru a putea comunica intre client si server. WCF este un framework destul de complex si desi este usor de integrat intr-o aplicatie, cand dorim sa facem ceva mai complex putem sa ne trezim pierduti intre tot felul de documentatii si carti despre WCF.
In acest post o sa prezint cum putem adauga in header-ul mesajului care se trimite la client un continut custom( date suplimentare).
O sa pornim de la urmatarea cerinta: fiecare mesaj care vine de la server trebuie sa vina insotit de un token unic a serverului.
O solutie la aceasta problema ar putea fi ca fiecare mesaj( contract) pe care il primim de la server sa fie incapsulat intr-o clasa de tip Response care contina tokenul nostru. Aceasta solutie este destul de buna, dar ce ne facem daca avem nevoie sa adaugam alte date pe langa token? O sa fie nevoie sa facem update imediat la clienti, servicile pe care le expunem prin WCF trebuie versionate si alte probleme de acest gen. Plus ca raspunsul pe care il primim de la server ar trebui sa contina doar datele pentru operatiea( actiunea) care vrem sa se execute. Altfel o sa fim nevoiti de fiecare data sa verificam daca raspunsul contine token-ul sau sa facem un wrapper peste apel. Toate aceste lucruri duc la o crestere a complexitati plus apare si un smel.
Toate aceste date, care contin statusul la server, tokenul de identificare si orice alte date pot sa fie adaugate in headerul mesajului. Trebuie avut doar grija ce fel de date punem. Informatile care se adauga in header trebuie sa fie informatii comune tuturor mesajelor si nu specifice unei singure operatii.
Acest comportament se obtine destul de simplu daca implementam interfata IDispatchMessageInspector. Prin intermediul acestei interfete putem sa modificam continutul unui mesaj inainte sa fie trimis la client. Avem doua metode pe care trebuie sa le implementam:
  • AfterReceiveRequest - metoda care este apelata automat dupa ce o cerere a ajuns pe client, dar inante ca ea sa fie executata
  • BeforeSendReply - metoda care este apelata chiar inainte ca raspunsul sa fie trimis la client
In cazul in care pe una din actiuni nu vrem sa facem nimic, putem returna null, sau lasam metoda goala. Primul parametru este de tip Message si ne permite sa accesam si/sau modificam mesajul primit sau trimis de la client in orice fel. Prin intermediul la Message avem access atat la header cat si la proprietatea message.Properties. Aceasta colectie de propietati de format (cheie,valoare) ajunge in header-ul mesajului. Valorea poate sa fie orice obiect serializabil, iar cheia este de tip string. Clientul ca sa poata accesa aceste propietati trebuie explicit sa acceseze aceasta colectie( este nevoie ca si clientul sa implementeze un comportament asemanator). Comunicarea intre cei doi o sa functioneze chiar daca clientul nu stie( verifica) aceste propietati. Doar ca nu le v-a putea accesa.
internal class TokenDispatchMessageInspector : IDispatchMessageInspector
{
public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
{
request.Properties["ServerToken"] = "SomeValue";

return null;
}

public void BeforeSendReply(ref Message reply, object correlationState)
{

}
}
Odata ce am facut acest lucru este nevoie sa ne definim un OperationBehavior sub forma unui atribut, pe care o sa il putem folosi la contractele sau operatiile pentru care avem nevoie de acest comportament. Prin intermediul interfetei IOperationBehavior, putem sa facem si alte actiuni precum validarea unei operatii. Noi avem nevoie doar sa ne inregistram inspectorul de mesaje definit mai sus( de fapt sa il adaugam in lista de message inspectors).
    public class TokenHeadersOperationBehaviorAttribute : Attribute, IOperationBehavior
{
public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
{
}

public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
{
}

public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
TokenDispatchMessageInspector inspector = new TokenDispatchMessageInspector();
dispatchOperation.Parent.MessageInspectors.Add(inspector);
}

public void Validate(OperationDescription operationDescription)
{
}
}

Pentru operatiile la care avem nevoie de acest comportament, ajunge sa le decoram cu atributul nostru.
    "[ServiceContract]"
internal class MyService:IMyService
{
"[OperationContract]"
[TokenHeadersOperationBehaviorAttribute]
public Response OperationOne()
{
...
}
}
Urmatorul pas este sa ne declaram behaviorul nostru. Acest lucru se face din fisierul de configurare( dar se poate face si din cod):
<system.ServiceModel>
<extensions>
<behaviorExtensions>
<add
name="endpointTokenMessageInspector"
type="Example.TokenDispatchMessageInspector, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
/>
</behaviorExtensions>
</extensions>
...
<behaviors>
<endpointBehaviors>
<behavior name="tokenBehaviorMessageInspector">
<endpointMessageInspector />
</behavior>
</endpointBehaviors>
</behaviors>
...
<service name="Test" ...>
<endpoint
address="/Test"
binding="wsHttpBinding"
behaviorConfiguration="tokenBehaviorMessageInspector"
contract="Test.IMyService"
/>
</service>
</system.ServiceModel>

In acest moment avem configurat serverul. In cazul in care dupa ce faceti configurarile in fisierul de configurare, vedeti ca servicul nu pornteste, va recomand sa adaugati pe rand fiecare linie de configurare. In cazul in care configurarea la serviciu o faceti din cod, va puteti definii propiul endpointBehavior implementand interfata IEndpointBehavior.
Am terminat cu serverul, aproape acelasi lucru trebuie sa il facem pe server, tot ce difera este ca in loc sa implementam interfata IDispatchMessageInspector o sa fie nevoie sa ne folosim de interfata IClientMessageInspector. Aceasta contine doua metode asemanatoare:
  • BeforeSendReply - metoda apelata inainte ca un mesaj sa fie trimis la server
  • AfterReceiveReply - metoda apelata dupa ce se primeste un raspuns de la server
Pe client avantajul folosirii acestei interfete este ca o putem folosii si intr-o aplicatie Silverlight. Pe client, in assembly-urile care formeaza core-ul de la Silverlight oricat am cauta nu o gasim niciodata IDispatchMessageInspector.
    internal class TokenDispatchMessageInspector : IClientMessageInspector
{
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
return null;
}

public void AfterReceiveReply(ref Message reply, object correlationState)
{
string serverToken = reply.Properties["ServerToken"] as string;
}
}
Pentru inregistrarea acestui comportament pe client trebuie sa face aceiasi pasi ca si pe server( definirea unui endpoint custom in care sa specificam behaviorul nostru).
Enjoy!
Read More
Posted in C#, Silverlight, WCF | No comments

Saturday, 18 February 2012

Post Event - CodeCamp la Cluj-Napoca, 18 feb. 2012

Posted on 23:58 by Unknown
Ieri in Cluj-Napoca a avut loc un eveniment Codecamp, unde au participat peste 50 de persoane. S-a discutat despre:
  • Access Control Service
  • Windows Phone 7
  • Kinect
  • Line of Bussines Application on Silverlight

Cat de curand o sa punem toate prezentariile pe codecamp.ro. Eu am tinut o prezentare despre Kinect, unde am vorbit despre partea hardware a acestuia cat si despre SDK oficial lansat de Microsoft. Mai jos puteti sa gasiti prezentarea mea.Kinect SDK preview

View more PowerPoint from Radu Vunvulea
Cateva poze de la acest eveniment puteti sa gasiti pe contul meu de Facebook:
http://www.facebook.com/radu.vunvulea
Inregistrarea vocala o puteti gasi aici: http://www.livescribe.com/cgi-bin/WebObjects/LDApp.woa/wa/MLSOverviewPage?sid=V2bpHq7xsdtk ( multumim Razvan Burz)

Va asteptam pe toti si la alte evenimente IT din Cluj-Napoca.
Read More
Posted in Cluj, codecamp, Kinect SDK, prezentare | No comments

Friday, 17 February 2012

Debug Silverlight application - breakpoint not hit

Posted on 06:25 by Unknown
In cazul in care lucrati cu o aplicatie Silverlight si vreti sa faceti debug s-ar putea sa va treziti nici un brake point nu este atins. Cele mai comune cauze la aceasta probleme sunt:
  • proiectul web care contine XAP nu este setat sa permita debug si la Silverlight. Acest lucru se poate activa in felul urmator: click dreapta pe proiectul web care contine xap-ul. Sub tabul Web in zona de Debuggers, verificati sa fie selectat si Silverlight
  • puteti incerca tot din Properties de pe proiectul web din tab-ul Silverlight Applications sa stergeti link-ul spre proiectul Silverlight si sa il adaugati din nou( in cazul in care nu aveti proiectul adaugat ca si link, checkboxul de la punctul precedent nu o sa fie vizibil
  • verificati ca in browser rulati un url care contine http// si nu file//. Debugul spre linkuri spre local file system este dezactivat
  • nu sunteti atasati la procesul care trebuie( aceasta este o problema a Visual Studio care nu se ataseaza la procesul care trebuie). Pentru a va atasa la proces, cand sunteti in debug este nevoie sa selectati Debug->Attach to Process. Acolo trebuie sa selectati procesul care ruleaza aplicatia voastra( iexplorer.exe, firefox.exe etc)

Daca nici o solutie nu a functionat, atunci puteti incerca sa instalati din nou tool-urile pentru Silverlight, in unele cazuri chiar merge.

In cazul in care vreti sa folosti Firefox, este necesar sa faceti urmatori pasi:

  • Load FireFox
  • Type "about:config" into FF's address bar
  • Accept the warning (if applicable)
  • Search for the entry "dom.ipc.plugins.enabled"
  • Change its value from "true" to "false" (double-click)
  • Restart the browser

Enjoy

Read More
Posted in breakpoint, Silverlight | No comments

Tuesday, 14 February 2012

DateTime.ToString() formats

Posted on 14:03 by Unknown
Zilele astea m-am trezit cu niste probleme la o aplicatie la care am lucrat impreuna cu niste colegi. Formatul la ora nu era consistent in toata aplicatia. In unele locatii aparea sub forma 04:50, iar in alte locatii aparea sub forma 16:50.
Problema principala a fost ca s-a folosit formatarea fara a se cunoaste exact ce se afiseaza cand se foloseste HH sau hh.
Mai jos as vrea sa ne uitam la metoda ToString a unui DateTime. Aceasta primeste ca si parametru un string prin intermediul caruia se poate specifica modul de formatare a datei.
  • yyyy - o sa afiseze anul in formatul 2012
  • MMMM - luna in litere( iulie, august, ...)
  • MM - luna in cifre( 07, 08)
  • dddd - ziua din saptamana in litere( luni, marti)
  • ddd - ziua in litere dar prescurta
  • dd - ziua curenta din luna( 20, 31, ...)
  • H - ora in format 24, iar daca ora e mai mica ca 10 se va afisa o singura cifra, fara 0( 1, 2, 14)
  • HH - ora in format 24, iar daca ora e mai mica ca 10 se va afisa un 0 la inceput( 01, 02, 14)
  • h - ora in format AM/PM, iar daca ora e mai mica ca 10 se va afisa o singura cifra, fara 0( 1, 2, 2)
  • hh- ora in format AM/PM, iar daca ora e mai mica ca 10 se va afisa un 0 la inceput( 01, 02, 02)
  • tt - daca este AM sau PM( AM, PM)
  • mm - minute
  • ss - secunde
Read More
Posted in datetime, format | No comments

Monday, 13 February 2012

Kinect SDK preview

Posted on 12:23 by Unknown
Kinect este un dispozitiv periferic care permite utilizatorilor sa controleze un calculator sau o consola doar prin intermediul gesturiilor. Acesta a fost lansat impreuna cu XBOX 360 in 2010. In 1 februarie 2012 a fost lansata o versiunea finala a SDK-ului pentru PC. Acesta ne permite sa scriem aplicatie pentru PC care sa foloseasca senzorii de pe Kinect. Ce trebuie sublineat aici este ca acest SDK se poate folosi doar pentru aplicatii non-comerciale in cazul in care aveti un Kinect pentru XBOX si nu pentru PC.
Din punct de vedere hardware, acest device contine:
  • camera video de 640x480 folosita pentru capturarea imaginii
  • camera cu infrarosu folosita pentru a calcula la ce distanta se afla obiectele
  • un microfon pentru capturarea sunetului
Camera cu infrarosu este cea care diferentiaza acest device de orice alt device de pe piata. Aceasa ne permite sa putem stii cu precizie la ce distanta se afla fiecare obiect. SDK-ul care este disponibil in acest moment nu ne permite doar sa capturam imagii si sa calculam distante fata de camera. In mod automat acesta identifica fiecare utilizator care este in fata deviceului separat si ne ofera date despre pozitia acestuia.
Dar haideti sa o luam cu inceputul. Pentru a putea sa folosim Kinect pe PC avem nevoie de Visual Studio 2010 si de SDK-ul de Kinect care poate sa fie downloadat de aici.
Odata instalat, putem sa adaugam referinta Microsoft.Kinect la proiectul nostru. In acest moment merita sa mentionam doua lucruri importante:
  • pentru a conecta Kinectul la PC avem nevoie de un adaptor( o mufa normala de USB nu furnizeaza destula energie)
  • daca vrem sa avem mai multe deviceuri conectate, acestea trebuie sa fie conectate pe controale USB diferite
Pentru a putea accesa datele de pe Kinect, este nevoie sa obtinem o instanta a acestuia. Pe un sistem pot sa existe mai multe deviceuri conectare. Odata ce obtinem o instanta a deviceului este nevoie sa initializam senzori pe care urmeaza sa ii folosim. Nu este obligatoriu sa inializam doar un singur senzor de pe device. Putem sa iniailizam oricati senzori avem nevoie.
KinectSensor kinect = KinectSensor.KinectSensors[0];
kinect.Start();
kinect.SkeletonStream.Enable();
kinect.ColorStream.Enable();
Este foarte importat la in momentul in care aplicatia se inchide si am terminat sa folosim Kinectul sa apelam Stop(). In caz contrat sunt sanse ca la urmatoarea pornire a aplicatiei sa nu mai putem conecta la Kinect.
Dupa initializare, trebuie sa pornim explicit fiecare senzor pe care vrem sa il folosim. In exemplul urmator o sa pornim streamul video si o sa ne inregistram la evenimentul care este aruncat cand un nou frame este disponibil.
kinect.ColorStream.Enable(ColorImageFormat.RgbResolution1280x960Fps12);
kinect.ColorFrameReady += new EventHandler&lt;ColorImageFrameReadyEventArgs&gt;(kinect_ColorFrameReady);
...
void kinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{
ColorImageFrame frame = e.OpenColorImageFrame();
}
Pentru fiecare stream la care ne inregistram o sa fim notificati cand un nou frame este disponibil. Ce trebuie mentionat aici este cand lucram cu frameurile pentru depth. Rezultatul o sa vina tot ca si o insiruire de biti, exact la fel ca si pentru streamul video, doar ca
primii 13 biti ne dau distanta in milimetrii a punctului respectiv. Mai jos putem vedea cum sa extragem dintr-un frame distanta in milimetrii la care se afla obiectul dintr-o locatia data:
void kinect_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
{
DepthImageFrame frame = e.OpenDepthImageFrame();

short[] pixelInfos=new short[frame.PixelDataLength];
frame.CopyPixelDataTo(pixelInf os);

int distanceInMillimeters = pixelInfos[pixelPosition] &gt;&gt; DepthImageFrame.PlayerIndexBitmaskWidth;
}
Un alt lucru pe care Kinectul il face automat este sa identifice unic fiecare persoana care este in fata senzorului. In acest mod putem sa izolam si sa identificam fiecare jucator. Acesta informatie se poate extrage si din frameul de mai sus in felul urmator:
int playeNumber = depthFrame[pixelPosition] & DepthImageFrame.PlayerIndexBitmask;
Cea ce diferentea Kinectul de toate deviceurile care sunt pe piata in acest moment nu este ca identifica fiecare jucator separat sau calitatea imaginii video ci datele care ne sunt returnate despre fiecare jucator. Kinectul poate sa identifice mai multe puncte a fi ecarui jucator( “articulatii”). Pentru fiecare din aceste puncte ne sunt returnate pozitiile in spatiu (x,y,z). Fara sa scrim nici un algoritm, putem automat sa identificam pozitia unei persoane, daca aceasta are mana intinsa, daca sta aplecata sau daca a ridicat un picior. Mai jos gasiti punctele de pe un jucator la care se face tracking.
Asa cum primeam de la senzorul video cate un nou frame, exact la fel primim cate un frame de tip SkeletonFrame care contine toate punctele. In acest moment trebuie sublineat ca fiecare frame o sa contina toate punctele, chiar daca la o parte din acestea nu se poate face tracking. Daca pentru un punct s-a putut face tracking atunci propietatea TrackingState o sa fie egala cu SkeletonTrackingState.Tracked.
Fiecare punct a unui jucator se identifica unic printr-un enum de tip JointType. De exemplu capul are valorea JointType.Head, iar coloana vertebrala JointType.Spline.
Mai jos gasiti un exemplu de cod care ne permite sa iteram prin punctele la care se face tracking si sa afisam pozitia acestora:
void kinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
SkeletonFrame frame = e.OpenSkeletonFrame();
Skeleton[] skeletons=new Skeleton[frame.SkeletonArrayLength];

frame.CopySkeletonDataTo(skeletons);
foreach (Skeleton skeleton in skeletons)
{
foreach (Joint joint in skeleton.Joints)
{
if (joint.TrackingState != JointTrackingState.Tracked)
{
continue;
}

Console.Write(joint.JointType);
Console.Write(joint.Position.X);
Console.Write(joint.Position.Y);
Console.WriteLine(joint.Position.Z);
}
}
Impreuna cu acest SDK, Kinectul devine un device foarte usor de folosit. De la o capturare de imagine, pana la calcularea distantei la care se afla un obiect sau pozitia mainii fata de corp a unei personae, totul se poate foarte usor, apeland API cu care vine insotit acest device.
Daca pentru XBOX 360 exista o multime de jocuri care folosesc acest device, pentru PC nu exita aproape nici o aplicatie. Cauza principal este suportul pentru PC care doar acupa a aparut dar si modul de licentiere a acestui device(SDK-ul este disponibil doar pentru uz non-comercial - daca deviceul este pentru XBOX 360). Potentialul acestui device este extreme de mare, din aceasta cauza merita studiat. El este doar la inceput si mai mult ca sigur o mai auzim de el.
Cu aceasta ocazie va invit pe data de 18 februarie la o prezentare detaliata a acetui device. Mai multe informatii puteti sa gasiti aici:
http://codecamp-cluj-2012.eventbrite.co.uk/
http://vunvulearadu.blogspot.com/2012/02/intalnire-codecamp-la-cluj-napoca-18.html
Read More
Posted in Kinect SDK | No comments

Friday, 10 February 2012

MVC - What a view should never contain( part 2)

Posted on 06:47 by Unknown
Part 1
Ieri am promis ca revin cu un post despre ce nu ar trebuii sa contina un view.
Pornim de la o clasa PersonModel care are urmatoarea definitie:
public class PersonModel
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
Pentru acest model avem urmatorul view:
@model PersonModel

@{
Layout = null;
}

<!DOCTYPE html>

<html>
<head>
<title>Person</title>
</head>
<body>
<fieldset>
<legend>PersonModel</legend>

<div class="display-label">Name</div>
<div class="display-field">
@Html.DisplayFor(model => model.Name)
</div>

<div class="display-label">Age</div>
<div class="display-field">
@Html.DisplayFor(model => model.Age)
</div>

<div class="display-label">Address</div>
<div class="display-field">
@Html.DisplayFor(model => model.Address)
</div>
</fieldset>
</body>
</html>
Mai tarziu apare o noua cerinta in aplicatie, ca sa se afiseze si coodonatele GPS a locatiei date. Pentru acest lucru se foloseste o adresa web care stie sa rezolve orice adresa. O implementare simpla este urmatoarea:
@model CIC.PersonModel
@{
Layout = null;

string coordLat;
string coordLong;

var request = WebRequest.Create(someAddress + "?location=" + Model.Address);
var webResponse = request.GetResponse();
using (var contentStream = new StreamReader(webResponse.GetResponseStream()))
{
var content = contentStream.ReadToEnd();
webResponse.Close();
string[] coords = content.Split(' ');
coordLong = coords[0];
coordLat = coords[1];
}
}
<!DOCTYPE html>
<html>
<head>
<title>Person</title>
</head>
<body>
<fieldset>
<legend>PersonModel</legend>
<div class="display-label">
Name</div>
<div class="display-field">
@Html.DisplayFor(model => model.Name)
</div>
<div class="display-label">
Age</div>
<div class="display-field">
@Html.DisplayFor(model => model.Age)
</div>
<div class="display-label">
Address</div>
<div class="display-field">
@Html.DisplayFor(model => model.Address)
</div>
<div class="display-label">
GPS Location</div>
<div class="display-field">
@coordLong
@coordLat
</div>
</fieldset>
</body>
</html>
Pagina functioneaza fara nici o problema doar ca in viewul face mult prea multe lucruri. Din el se face un request spre o alta componenta( serviciu), prin intermediul caruia se obtin coordonatele GPS a unei adrese, care se afiseza in view.
Modelul nu contine toate datele necesare pentru a afisa tot ce este necesar. Din aceasta cauza se ajunge sa se faca un apel spre o componenta externa. Nu are importanta daca aceasta componenta este un serviciu extern sau o clasa din assemblyul nostru. Toate datele necesare trebuie sa fie continute de catre model. Orice data trebuie sa ajunga in view prin intermediul modelului.
O solutie este sa adaugam doua propietati in PersonModel care sa reprezinte coordonatele GPS( sau putem sa ne cream o clasa care sa stocheze longitudinea si latitudinea - dar tot ca si o propietate din PersonModel o sa fie).
public class PersonModel
{
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
public string Longitude { get; set; }
public string Latitude { get; set; }
}
Inițializarea coordonatelor urmeaza sa fie mutata in controler. Problema de la care am pornit a fost rezolvata, insa ... apare un smell la orizont. Nu foarte puternic, dar extrem de periculos. Apelul spre serviciu se face direct din controler, cea ce nu e normal. Da, este adevarat ca controlerul ar trebuii sa pregateasca modelul, dar obtinerea coordonatelor ar trebuii sa se faca in alt loc. De exemlu putem sa scoatem acest apel intr-o alta clasa.
Read More
Posted in MVC, view | No comments

Thursday, 9 February 2012

MVC - What a view should never contain( part 1)

Posted on 07:16 by Unknown
Part 2
Suntem intr-o aplicatie MVC. Un model poate sa fie folosit de 1 sau mai multe viewuri.
Intrebarea de unde a pornit totul este Ce ar trebuii sa contina un view?
Daca ne luam dupa carte: Un View trebuie sa contina codul prin intermediul caruia se genereaza interfara grafica asteptata. Viewul se ocupa cu partea de render la date pentru a afisa modelul corespunzator.
In acest caz ce este un Model? Raspunsul scurt si sec pe care il primesc mereu este: o clasa care contine datele ce trebuie afisate in view.
Citisem anul trecut ca un model poate sa fie reprezentat de un web service, de un repository sau de catre un alt bussines layer. Aceasta afirmatie este falsa. Da sursa datelor poate sa fie un web-service, un repository sau un bussines layer, dar datele care o sa fie afisate tot ca o colectie de la 1 la n de de obiecte pe care le primim. Indifierent ca este o colectie de stringuri, o clasa, sau un singur string. Aceste date pot sa fie modelate ca si o clasa.
Daca ne intoarcem la prima afirmatie( modelul este o clasa) - putem sa schimbam raspunsul si sa spunem ca modelul este reprezentat de o colectie de date. In lumea ASP.NET MVC aceasta va fi mereu o clasa( da, chiar si un string este de fapt o clasa in .NET).
Si acuma pot sa pun intrebarea de unde a pornit totul.
Ce ar trebuii sa contina un View?
Doar codul prin intermediul caruia se face render la UI.
Dar daca trebuie sa formatam un element din model, aceast cod unde trebuie sa apara? In controler cand pregateste modelul sau in view. Ati spune ca depinde? Daca formatam un datetime atunci acest lucru s-ar putea face in view sau chiar in template. Daca formatam un obiect mai complex ar trebuii sa fie in controler. In al doilea caz avem o problema cu modelul. Modelul nu este in formatul de care avem nevoie, iar daca incercam sa refolosim un alt model, atunci mai bine ne facem un nou model cu datele de care avem nevoie.
Nu este nimic gresit sa avem cate un model pentru fiecare view. Este gresit sa avem un singur model la 20 de view-uri, iar modelul sa contina date care sa nu fie folosite de toate viewurile sau viewurile sa fie obligat sa faca procesare datelor pentru a putea afisa datele in formatul dorit.
Dar daca avem nevoie sa afisam date din model apeland un web-service. Niciodata sa nu puneti acest apel in view. In unele cazuri poate apelul sa fie facut din Java Script, dar niciodata din view. Genul acesta de logica nu are ce cauta in view.
Totul a pornit in momentul in care am vazut intr-un view un apel spre un web-service facut din C#.
Part 2
Read More
Posted in MVC, MVC 3, view | No comments

Wednesday, 8 February 2012

Interop - release COM objects( Excel.EXE hanging)

Posted on 02:12 by Unknown
Pentru mine "interopul" a fost mereu o provocare. Nu neaparat modul prin care se pot face apelurile ci modul in care se face dispose la acestea si eliberarea resurselor.
O sa ma duc pe un exemplu concret - interopul cu Excel. Cand lucram cu acesta viata noastra poate sa devina un iad daca nu eliberam resursele corespunzator. Daca avem un serviciu windows care proceseaza fisiere Excel, foarte usor ne putem trezii ca avem 100 de procese EXCEL.EXE ramase agatate in sistem cu care nu stim ce sa facem. Dar asta nu e tot, fisierele raman agate pe disk pana cand cineva omoara procesul.
Sa incepem cu inceputul. Pentru a putea accesa un fisier Excel folosind Microsoft Office, avem un cod asemanator cu acesta:
Application application = new Application()
{
Visible = false,
UserControl = true,
};
Workbook workbook = Application.Workbooks.Open(fileName, 0, false, 5, "", "", true, XlPlatform.xlWindows, "\t",true,false, 0, true, 1, 0);
Worksheet worksheet = (Worksheet)Workbook.Worksheets.Item[1];
Range range = Worksheet.UsedRange;
.....
string value = (range.Cells[rowNumber, columnNumber] as Range).Text;
Pentru fiecare obiect din Office trebuie sa facem explicit dispose folosind
"System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)".
Trebuie avuta mare grija, deoarece in exemplul dat mai sus ultima linie de cod contine un obiect la care o sa pierdem referinta si la care nu o sa mai putem face dispose:
range.Cells[rowNumber, columnNumber] as Range
Un apel corect, care o sa ne permita sa facem si dispose ar fi:
Range cell = range.Cells[rowNumber, columnNumber] as Range;
string value = cell.Text;
In acest fel o sa putem face release si la obiectul care are o referinta la celula pe care o procesam.
Inainte sa facem release la Workbook si Application este nevoie sa le inchidem si sa facem quit pe ele:
workbook.Close(false, Type.Missing, Type.Missing);
Application.Application.Quit();
Application.Quit();
O implementare a metodei care face release pentru exemplul nostru ar putea sa fie urmatoarea:
System.Runtime.InteropServices.Marshal.ReleaseComObject(cell);
workbook.Close(false, Type.Missing, Type.Missing);
Application.Application.Quit();
Application.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(application);
GC.Collect();
GC.WaitForPendingFinalizers();
Dupa cum se poate observa toate actiunile care se fac sunt destul de complexe si trebuie avut grija ca sa se face release la fie obiect in parte. Daca nu eliberam aceste resurse o sa ne trezim cu procese de tip EXCEL.exe ramane in memorie la care trebuie sa facem manual dispose( kill). Ca sa ne usuram putin viata putem sa ne definim o clasa generica care sa faca release automat la obictele din COM.
public class AutoReleaseComObject<TComObject> : IDisposable
where TComObject : class
{
private TComObject _comObject;
private bool _disposed = false;

public AutoReleaseComObject(TComObject comObject)
{
_comObject = comObject;
}

public TComObject ComObject
{
get { return _comObject; }
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
lock (this)
{
if (_disposed)
{
return;
}

int refcnt = 0;
do
{
refcnt = System.Runtime.InteropServices.Marshal.ReleaseComObject(_comObject);
} while (refcnt > 0);

_comObject = default(TComObject);
_disposed = true;
}
}
}
Cam asa ar arata implementarea pentru un obiect COM. Daca aveam nevoie sa facem si alte actiuni, asa cum facem pentru Application, putem sa face ovverite la metoda Dispose si sa facem intr-un alt mod eliberarea de resurse.
Totul o sa fie bine pana cand un alt dezvoltator o sa vina si o sa ne modifice codul cand fara sa isi dea seama nu o sa faca release la resurse. De exemplu in urmatoarea line de cod:
((Range)range.get_Value(rangeValueDataType)).QueryTable.Creator
se pierde referinta la doua obiecte la care nu o sa se mai poata face dispose. Prima greseala este obiectul returnat de 'get_Value', la care trebuie sa se faca dispose. Al doilea obiect este QueryTable unde apare aceiasi problema. Corect ar trebui sa avem:
Range itemRange = (Range)Range.get_Value(rangeValueDataType);
QueryTable queryTable = itemRange.QueryTable;
XlCreator creator = queryTable.Creator;
Daca folosim solutie prezentata putin mai sus am obtine urmatorul cod:
using (AutoReleaseComObject<Range> range=GetRange())
{
using (AutoReleaseComObject<Range> itemRange = range.ComObject.get_Value(rangeValueDataType))
{
using (AutoReleaseComObject<QueryTable> queryTable = itemRange.ComObject.QueryTable)
{
XlCreator creator = queryTable.Creator;
}
}
}
Si totusi sunt diferite cazuri cand un obiect COM ne scapa si ne trezim cu un proces agatat. Exista si diferite probleme cu inteoropul de Office din cauza carora nu se poate face release la date corespunzator si ne trezim ca nu putem sa scapam de proces.
O solutie destul de hard-core, care trebuie folosita cu mare grija este sa omoram direct procesul. In exemplul de mai jos o sa obtin Hwnd( adrsa din memorie) din procesul EXCEL.exe pe baza caruia putem obtine id-ul procesului EXCEL.EXE pe care dorim sa il omoram.
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
...
int currentHWn =application.Hwnd
uint processID;
GetWindowThreadProcessId((IntPtr)hWnd, out processID);
if (processID != 0)
{
Process.GetProcessById((int)processID).Kill();
}
O alternativa la interop pentru Office este Open XML: http://msdn.microsoft.com/en-us/library/bb448854%28office.14%29.aspx
Succes!
Read More
Posted in excel, interop | No comments

Tuesday, 7 February 2012

Intâlnire CodeCamp la Cluj-Napoca - 18 feb. 2012

Posted on 01:39 by Unknown
http://codecamp-cluj-2012.eventbrite.co.uk/

Si iată ca am pregătit încă un eveniment pentru dezvoltatorii din Cluj-Napoca. Va așteptam pe toți in 18 februatie, de la ora 9:50 pe Calea Dorobanţilor, Nr. 18-20, etaj 7( sediul Yonder).

Participarea la eveniment este gratuita. Mulțumim în special sponsoriilor pentru sustinere.

Agenda
9:50-10:00
Sosirea participanților

10:00-11:00
O introducere in Access Control Service
Mihai Nadăș
Un nou mod de a implementa scenarii hibride de autentificare folosind Windows Azure, Facebook, Twitter sau Active Directory.
11:00-12:00
Introducere in Windows Phone 7
Paul Țirban
O introducere in lumea WP7. Incepand de la API si tooluri pentru dezvoltare, pana la markerplace.
12:00-12:30
Pauza de masa
Delicious Lunch (courtesy of our sponsors)
12:30-13:30
Discover the power of Kinect
Radu Vunvulea
Discover the power of Kinect as the hardware device equipped with a very simple and powerful SDK. Face recognition or object tracking can be made with the based API without headaches
13:30-14:30
LoB (Line of Business) apps on Silverlight - custom controls composition
Dragos Andronic
6 months into porting a desktop app on the web (with the help of the SL platform) is time to look back and see what went well and what could have went better.
Discussing today: custom controls composition
- using the fluid layout (examples)
- using Prism based region navigation (examples)
- Prism based region navigation & hard-linking
- delegating UI design
- performance, performance, performance - some of the issues we've encountered


Pentru mai multe informații
  • Mihai Nadăș
    • 0742117996
    • mihai@nadas.ro
  • Radu Vunvulea
    • 0766562375
    • vunvulear@yahoo.com
Read More
Posted in Cluj, codecamp, prezentare | No comments

Monday, 6 February 2012

How to change Windows wallpaper from .NET

Posted on 07:11 by Unknown
Din core-ul de .NET, nu avem nici o posibilitate sa schimbam imaginea de fundal a sistemului de operare sau sa schimbam modul in care se afiseaza - in mod direct. Ca sa putem face acest lucru, putem sa schimbam valorile din registri care stocheaza modul in care se afiseaza imaginea de fundal. Iar imaginea de fundal se schimba apeland direct API sistemului de operare.
Sub directorul userului curent, in path-ul "ControlPanel\Desktop" o sa gasim cheile necesare pentru a seta modul in care se afiseaza imagina de fundal.
Cheia WallpaperStyle impreuna cu TileWallpaper ne permite sa setam felul in care se centreaza imaginea. Urmatarele combinatii de valori se pot face:
  • (WallpaperStyle = 2, TileWallpaper = 0) - se face stretch la imagine ca sa acopere tot spatil ecranului
  • (WallpaperStyle = 0, TileWallpaper = 1) - se face tile pe imagine pana cand ecranul este umplut
  • (WallpaperStyle = 0, TileWallpaper = 0) - imaginea se afiseaza centrat
Aceste valori se pot seta in felul urmator
public enum Style
{
Tiled,
Centered,
Stretched
}
...
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop", true);
switch (style)
{
case Style.Stretched:
key.SetValue(@"WallpaperStyle", 2.ToString());
key.SetValue(@"TileWallpaper", 0.ToString());
break;
case Style.Centered:
key.SetValue(@"WallpaperStyle", 1.ToString());
key.SetValue(@"TileWallpaper", 0.ToString());
break;
case Style.Tiled:
key.SetValue(@"WallpaperStyle", 1.ToString());
key.SetValue(@"TileWallpaper", 1.ToString());
break;
}
Am vazut cum putem seta ca imaginea de fundal sa se afiseze in diferite moduri. Urmatorul pas este sa vedem cum putem sa setam din cod imaginea de fundal. Pentru acest lucru trebuie sa facem apel la API de windows si sa ne definim urmatoarea metoda:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
Prin intermediul acestei metode putem seta sau obtine valoarea parametriilor din sistemul de operare. Actiunea care permite setarea imaginii din fundal are valoare 20.
SystemParametersInfo(
20, // Actiunea pentru setarea imaginii de fundal.
0,
imageFilePath, // Locatia spre imaginea noastra
0x01 | 0x02);

Enjoy!
Read More
Posted in wallpaper | No comments

Friday, 3 February 2012

How to display simple math formulas using .NET

Posted on 07:17 by Unknown
Cum sa formatam un text astfel incat sa avem ceva de genul:
By default, acest lucru se poate folosind Unicode. Trebuie sa avem doar rabdare sa formatam textul. De exemplu pentru a scris (x+1)^2 este nevoie de urmatorul artificiu:
String.Format("(x+1){0,-3}",'\u00B2');
Pentru a scrix (x+1)^3 este nevoie sa scriem urmatoarea linie de cod:
String.Format("(x+1){0,-3}",'\u00B3');
Teoretic, cu destula imaginatie putem sa afisam orice formula matematica, dar pentru acest lucru exista nenumarate tool-uri care ne pot ajuta. La formule complexe pot sa apara probleme de afisare in functie platforma, versiune etc.
Pentru lucruri simple merita merita sa folosim formatarea, deoarece textul afisat de catre noi o sa arate mult mai bine.
Lista tuturor caracterelor Unicode o puteti gasii aici: http://www.tamasoft.co.jp/en/general-info/unicode.html
Read More
Posted in string | No comments

Short brief - Request-Response, Asynchron and Fire and Forget patterns

Posted on 05:36 by Unknown
Un apel spre un serviciu poate sa fie facut in diferite moduri. Cele mai uzuale moduri sunt cele care respecta paternul Request-Response si Asynchron. Pe langa aceste doua paternuri mai exista inca unul, dar care este mai rar folosit Fire and Forget.
Request-Response pattern- se refera la faptul ca pentru fiecare request facut se asteapta raspunsul.
Response response = service.CallService(request)
Asynchron pattern - este un patern bazat pe evenimente. Odata ce un apel a fost facut, aplicatia nu asteapta raspunsul de la server. Cel care face apelul trebuie sa se inregistreze la un eveniment care o sa fie declansat cand raspunsul soseste.
service.ResponseEvent += new EventHandler(ResponseReceived);
service.CallServiceAsync(request);
Fire and Forget pattern - este destul de asemanator cu paternul Asynchron, doar ca odata comanda trimisa nu ne mai intereseaza ce se intampla cu aceasta.
service.CalService(request);    // Metoda nu returneaza nimica
Exista diferite scenarii cand Fire and Forget este recomandat sa fie folosit. Conditia principala care trebuie sa fie implinita ca sa putem folostii acest patern este ca sa ne putem asigura ca request-ul ajunge la server - avem un protocol ce ne garanteaza ca mesajele au ajuns la destinatie( de exemplu daca folosim cozi de mesaje care ne asigura ca mesajele nu se pierd - de exemplul MQ).
In cazul in care avem servicii cu un volum mare de request-uri, atunci poate pentru unele tipuri de request-uri putem sa folosim acest patern. De exemplu pentru cele in care rezultatul este format din mesaje precum Okay.
Cele mai mari dezavantaje apar in momentul in care ceva nu functioneaza bine. Debug-ul este destul de complicat si de obicei necesita interventia umana pentru a putea gasi problema. Problemele care pot sa apara sunt la nivelului protocolului care ar trebui sa ne garanteze ca mesajele ajung la destinatie.
Un alt mod de a apela un serviciu este de a face unu sau mai multe request-uri de tipul Fire and Forget, iar apoi la un moment dat sa se verifice daca a venit un raspuns( intr-un cache, in baza de date etc) - in cazul in care raspunsul se pune intr-o locatie unde atat clientul cat si serverul le pot accesa
Nu trebuie confundat un apel de forma:
service.CallService(request,()=>{ ... });
ca si cum ar fi un apel de tip Fire and Forget. Orice metoda sau lambda expresion specificata ca si al doilea parametru care este apelata in momentul in care raspunsul soseste de la server reprezinta un apel de tip asincron.
Read More
Posted in asyncron, fire and forget, request response | No comments

Thursday, 2 February 2012

Windows Live - Basic operations

Posted on 07:44 by Unknown
Windows LIVE series:
  • Introducere
  • Web Authentication
  • Live Connect
  • Basic Operations
  • SkyDrive
Astazi o sa incepem sa vorbim despre serviciile de tip CORE care exista pe Windows Live Connect. Nu imi este foarte clar daca sa ofer exemplele in C# sau in JavaScript. Cred ca ar fi mai interesant sa prezint exemplele in JavaScript si din cand in cand o sa prezint si exemple in C#. In .NET avem o librărie, este destul de simplu, iar modul în care totul funcționează este destul de ascuns.
Înainte sa începem trebuie știut ceva foarte importat. Cand un utilizator nou accesează aplicația noastră pentru prima data, iar noi dorim sa accesam anumite servicii ca și cum am fi utilizatorul respectiv, acesta o sa trebuiască sa ne de-a dreptul ca putem sa accesam aceasta informație. In general apare un pop-up, asemănător cu cel de logare, unde userul își da acordul ca aplicația noastră sa acceseze o colecție de servicii în numele sau. In funcție de modul în care facem request-ul acest drept poate sa aibe o durata limitata sau sa fie pe veci. By default dreptul de acces la resursele unui utilizator sunt temporare.
In funcție de platforma, avem la dispoziție diferite librari prin care putem sa accesam mai ușor resursele. Pentru JavaScript avem la dispozitive o librărie cu numele WL.js, iar pentru .NET avem la dispoziție librăria Microsoft.Live. Toate apelurile se pot face și manual prin intermediul apelurilor de tip REST, dar acest lucru consuma timp și este generator de bug-uri.
Oriunde dorim sa folosim librăria WL, este nevoie ca aceasta sa fie inițializata cu id de client pe care l-am primit și url de redirect, care o sa fie apelat de către Live Connect in momentul în care un utilizator se autentifica.
In primul exemplu o sa presupunem ca dorim sa accesam datele de baza a utilizatorului împreuna cu datele de profil. Primul pas este ca utilizatorul sa se logheze:
WL.init({ client_id: {idClient}, redirect_uri: {ourRedirectUrl} });
WL.login(
{ "scope": "wl.basic" },
function (response) {
if (response.status == "connected") {
alert("Utilizator conectat");
}
else {
alert("Autentificare esuata");
}
});
Acuma ca utilizatorul este autentificat, putem sa accesam datele de baza a acestuia. Pentru acest lucru trebuie sa apelam path-ul "me" prin GET. Un obiect în format JSON o sa ne fie returnat si o sa contina toate de profil a acestuia.
WL.api(
"/me", "GET",
function (response) {
if (response.error) {
alert("A aparut o eroare.");
return;
}
// response - o sa conțină toate datele de profil
}
);

In cazul in care sunteti curiosi, iata mai jos un exemplu de răspuns:
{"id":"XXXd9f52e4XXX02X"
"name":"Vunvulea Radu"
"first_name":"Vunvulea"
"last_name":"Radu"
"link":"http://profile.live.com/cid-bb7d9f52e4fdb024/"
"birth_day":null
"birth_month":null
"birth_year":null
"gender":null
"emails":
{
"preferred":"XXX@hotmail.com"
"account":"XXX@hotmail.com"
"personal":null
"business":null
}
"addresses":
{
"personal":
{
"street":null
"street_2":null
"city":null
"state":null
"postal_code":null
"region":null
}
"business":
{
"street":null
"street_2":null
"city":null
"state":null
"postal_code":null
"region":null
}
}
"phones":
{
"personal":null
"business":null
"mobile":null
}
"locale":"ro_RO"
"updated_time":"2012-02-02T06:21:16+0000"
}
Din cate putem sa observam răspunsul este in format JSON, care se poate procesa foarte usor. Odata ce un user este logat cu SCOPE-ul "wl.basic", putem sa accesam orice informatii de baza, precum date de profil, lista de contacte. Ce imi placela acest API este faptul ca, chiar daca ai acces la contacte sau la evenimente din calendar, dreptul de adaugare pe fiecare din ele se obtine printr-un SCOPE separat, a.i. utilizatorul este protejat si stie exact ce poate sa faca o aplicatie cu contul sau.
Sa presupunem ca vrem sa facem retrive la toate evenimentele utilizatorului. In acest caz o sa avem nevoie sa ne logam folosind SCOP-ul "wl.calendars" si sa apelam path-ul "/me/events".
De menționat doua lucruri:
  • cand ne definim scope-ul putem sa avem o lista de genul "scope: "wl.basic wl.calendars"
  • resursele pe care le accesam trebuie sa fie văzute ca și o structura de foldere, organizate ierarhic
In exemplul de mai jos încărcam toate evenimentele utilizatorului:
 WL.api({
path: "/me/events",
method: "GET"
}, onResponseReceive);
function onResponseReceive(response)
{
// response contine lista de evenimente
}
In cazul in care dorim sa adaugam un eveniment este nevoie sa facem request la un nou scope "wl.events_create".
 WL.api({
path: "/me/events",
method: "POST",
body: {
name: "Iesire la bere",
description: "Iesire la bere cu Ghita",
start_time: "1/1/2012 20:00",
end_time: "1/1/2012 22:00",
location: "Cluj-Napoca",
is_all_day_event: false,
availability: "busy",
visibility: "public"
}
}, onResponseReceive);
Cand ne vine raspunsul, trebuie sa verificam doar ca proprietatea error nu conține nici o eroare.
Data următoare o sa povestim despre SkyDrive si Messenger.
Read More
Posted in Live Connect | No comments

Wednesday, 1 February 2012

CRUD operation on Windows Task from .NET

Posted on 07:46 by Unknown
Zilele trecute am gasit o librarie simpla si foarte usor de folosit pentru a crea task-uri sub Windows. Aceasta poarta numele de Task Scheduler Managed Wrappe si o puteti gasi la urmatoarea adresa: http://taskscheduler.codeplex.com/
Primul lucru care mi-a atras atentia a fost cat de usor se poate integra intr-o aplicatia deja existenta.
Clasa de baza, in jurul careia se invarte totul este TaskService, prin intermediul caruia putem sa inregistram task-uri noi sau sa le manipulam pe cele deja existente. Fiecare task se identifica unic printr-un nume. Pe baza acestui nume putem sa obtinem un task deja existent.
La fiecare task putem sa inregistram una sau mai multe actiuni care sa se execute. Actiunile pot sa fie de orice fel, incepand de la trimiterea unui email sau rularea unui executabil pana la afisarea unui mesaj la utilizator.
Acelasi lucru se intampla si cu trigerurile, toate cele existente pe Windows exista si in aceasta librarie:
  • EventTrigger
  • DailyTrigger
  • WeeklyTrigger
  • MonthlyTrigger
  • IdleTrigger
  • TimeTrigger
  • RegistrationTrigger
  • BootTrigger
  • LogonTrigger
  • SessionStateChangeTrigger
Pentru a adauga, sterge sau controla un task este nevoie sa ne cream o instanta de tip TaskService. Prin intermediul ei putem sa manipulam orice task de pe calculatorul curent sau de pe orice alt calculator.
Mai jos gasiti un exemplu de cod in care am creat un nou task. Modul de logare ii setez pe baza de token si va rula cu drepturile userului curent. Iar apoi setez task-ul sa ruleze odata la 12 ore si la fiecare logare in sistem a utilizatorului. La fiecare executie a acestui task, un fisier executabil urmareaza sa fie apelat.
using (TaskService taskService = new TaskService())
{
TaskDefinition taskDefinition = taskService.NewTask();
taskDefinition.RegistrationInfo.Description = "Description";
taskDefinition.Principal.LogonType = TaskLogonType.InteractiveToken;

var interval = new TimeTrigger();
interval.Repetition.Interval = TimeSpan.FromHours(12);
taskDefinition.Triggers.Add(interval);
taskDefinition.Triggers.Add(new LogonTrigger());

taskDefinition.Actions.Add(new ExecAction("doWork.exe", null, null));

taskService.RootFolder.RegisterTaskDefinition("TaskService playground task", taskDefinition);
}
Orice setare a unui Task am gasit-o mapata in aceasta librarie ajutatoare si decat sa folosesc interop pentru a lucra cu task-urile din Windows, prefer sa folosesc aceasta librarie. Pana acuma nu am avut nici o problema cu ea.

Enjoy!
Enjoy it!
Read More
Posted in Windows Task | No comments
Newer Posts Older Posts Home
Subscribe to: Comments (Atom)

Popular Posts

  • Service Bus Topic - Automatic forward messages from a subscription to a topic
    Windows Azure Service Bus Topic is a service that enables us to distribute the same messages to different consumers without having to know e...
  • CDN is not the only solution to improve the page speed - Reverse Caching Proxy
    I heard more and more often think like this: “If your website is to slow, you should use a CDN.” Great, CDN is THE solution for any kind of ...
  • Content Types - Level 6: Rich Media
    Level 6: Rich Media NOTE: This is part 7 of 7 and the conclusion of this continuing series; please see earlier posts for more background inf...
  • Publishing our CellCast Widget for iPad
    The rush has been on this week as our development team worked to design a new version of our CellCast Widget specifically for Apple's up...
  • Patterns in Windows Azure Service Bus - Message Splitter Pattern
    In one of my post about Service Bus Topics from Windows Azure I told you that I will write about a post that describe how we can design an a...
  • E-Learning Vendors Attempt to Morph Mobile
    The sign should read: " Don't touch! Wet Paint !" I had a good chuckle today after receiving my latest emailed copy of the eLe...
  • SQL - UNION and UNION ALL
    I think that all of us used until now UNION in a SQLstatement. Using this operator we can combine the result of 2 queries. For example we wa...
  • Cum sa salvezi un stream direct intr-un fisier
    Cred ca este a 2-a oara când întâlnesc aceasta cerința in decurs de câteva săptămâni. Se da un stream și o locație unde trebuie salvat, se c...
  • Task.Yield(...), Task.Delay(...)
    I think that a lot of person already heard about these new methods. In this post I want to clarify some things about these new methods that ...
  • Content Types - Level 4: Reference
    Level 4: Reference Materials & Static Content NOTE: This is part 5 of 7 in a continuing series; please see earlier posts for more backgr...

Categories

  • .NET
  • .NET nice to have
  • #if DEBUG
  • 15 iunie 2011
  • 15 octombrie 2011
  • 2011
  • abstracta
  • action
  • adaugare
  • ajax
  • Amsterdam
  • Android
  • aplicatii
  • App Fabric
  • Apple iSlate
  • array
  • as
  • ASP.NET
  • AsReadOnly
  • Assembly comun
  • async
  • Asynchronous programming
  • asyncron
  • Autofac
  • AutoMapper
  • az
  • Azure
  • Azure AppFabric Cache
  • Azure backup solution
  • Azure Storage Explorer
  • azure. cloud
  • backup
  • BCP utility
  • bing maps v7
  • BitArray
  • BlackBerry
  • blob
  • BlobContainerPublicAccessType
  • breakpoint
  • bucuresti
  • C#
  • cache
  • CallerMemberName
  • CellCast
  • Certificate
  • CES
  • change
  • ChannelFactory
  • clasa
  • classinitialize
  • clean code
  • click event
  • close
  • Cloud
  • Cluj
  • cluj-napoca
  • Code contracts
  • code retrat
  • codecamp
  • CollectionAssert
  • Compact Edition
  • compara
  • Comparer T .Default
  • CompareTo
  • comparison
  • comunitate
  • concurs
  • Conditional attribute
  • configurare
  • connection string
  • container
  • content type
  • control
  • Convert
  • convertAll
  • convertor
  • cross platform
  • CRUD
  • css
  • custom properties
  • custom request
  • DACPAC
  • Daniel Andres
  • data sync service
  • database
  • date time
  • datetime
  • debug
  • default
  • delegate
  • dependency injection
  • deploy
  • DeploymentItem
  • design patterns
  • Dev de Amsterdam
  • development stoage
  • dictionary
  • diferente
  • digging
  • director
  • Directory.Exist
  • disable
  • dispatcher
  • dispose
  • dropdown
  • dynamic
  • EF
  • email
  • encoding
  • entity framework
  • enum
  • enumerable
  • Environment.NewLine
  • error
  • error 404
  • error handling
  • eveniment
  • event
  • ews
  • excel
  • exception
  • exchange
  • exita
  • explicit
  • export
  • extension
  • field
  • File.Exist
  • finalize
  • fire and forget
  • Fluent interface pattern
  • format
  • func
  • GC.SuppressFinalize
  • generic
  • getdirectoryname
  • globalization
  • gmail
  • hackathon
  • Hadoop
  • handle
  • HTML
  • html 5
  • Html.ActionLink
  • http://www.blogger.com/img/blank.gif
  • HttpModule
  • IComparable
  • IE
  • ienumerable
  • IIS
  • image
  • implicit
  • import
  • int
  • internationalization
  • Internet Explorer
  • interop
  • Ioc
  • IP Filter
  • iPhone
  • iQuest
  • IStructuralEquatable
  • ITCamp
  • itspark
  • java script
  • javascript
  • July 2012
  • KeyedByTypeCollection
  • KeyNotFoundException
  • Kinect SDK
  • lambda expression
  • LightSwitch Microsoft Silverlight
  • linq
  • list
  • lista
  • lista servicii
  • liste
  • Live Connect
  • Live ID
  • load
  • localization
  • lock
  • m-learning
  • MAC
  • Mango
  • map
  • mapare
  • mapare propietati
  • messagequeue
  • meta properties
  • method
  • MethodImpl
  • Metro App
  • Microsoft
  • Microsoft Sync Framework
  • mlearning
  • mlearning devices
  • Mobile Apps
  • mobile in the cloud
  • mobile learning
  • mobile services
  • Mobile Web
  • mongoDb
  • monitorizare
  • msmq
  • multitasking
  • MVC
  • MVC 3
  • MVVM
  • namespace
  • nextpartitionkey
  • nextrowkey
  • Ninject
  • nivel acces
  • no result
  • normalize
  • nosql
  • null expcetion
  • null object pattern
  • NullReferenceException
  • OAuth API
  • office
  • offline
  • Open ID
  • openhackeu2011
  • operations
  • operator
  • optimization
  • option
  • outputcache
  • OutputCacheProvider
  • override
  • paginare
  • pagination
  • path
  • persistare
  • Portable Library tool
  • Post event – CodeCamp Cluj-Napoca
  • predicate
  • predictions
  • prezentare
  • process
  • proiect
  • property
  • propietati
  • query
  • ReadOnlyCollection
  • ReadOnlyDictionary
  • referinta
  • reflection
  • remote
  • reply command
  • request
  • request response
  • resouce
  • REST
  • REST Client
  • RESTSharp
  • ronua
  • rss
  • rulare
  • salvare in fisier
  • sc
  • schimbare timp
  • select
  • select nodes
  • send
  • serializare
  • serialization
  • Server.Transfer. Resposen.Redirect
  • service bus
  • ServiceBase
  • servicecontroller
  • sesiune
  • session
  • Session_End
  • Session_Start
  • setup
  • Sibiu
  • signalR
  • Silverlight
  • sincronizare
  • Single Responsibility Principle
  • SkyDrive
  • skype
  • smartphones
  • smtp
  • Snapguide
  • sniffer
  • socket
  • solid
  • spec#
  • sql
  • Sql Azure
  • SQL CE
  • sql server 2008 RC
  • SRP
  • startuptype
  • stateful
  • stateless
  • static
  • stergere
  • store
  • store procedure
  • stream
  • string
  • string.join
  • struct
  • StructuralEqualityComparer
  • submit
  • switch
  • Symbian
  • Synchronized
  • system
  • tabele
  • table
  • techEd 2012
  • tempdata
  • test
  • testcleanup
  • testinitialize
  • testmethod
  • thread
  • timer
  • ToLower
  • tool
  • tostring
  • Total Cost Calculator
  • trace ASP.NET
  • transcoding
  • tuplu
  • tutorial
  • TWmLearning
  • type
  • unit test
  • unittest
  • UrlParameter.Optional
  • Validate
  • validation
  • verificare
  • video
  • view
  • ViewBag
  • virtual
  • visual studio
  • VM role
  • Vunvulea Radu
  • wallpaper
  • WCF
  • WebBrower
  • WebRequest
  • where clause
  • Windows
  • windows 8
  • Windows Azure
  • Windows Azure Service Management CmdLets
  • windows live messenger
  • Windows Mobile
  • Windows Phone
  • windows service
  • windows store application
  • Windows Task
  • WinRT
  • word
  • workaround
  • XBox
  • xml
  • xmlns
  • XNA
  • xpath
  • YMesseger
  • Yonder
  • Zip

Blog Archive

  • ►  2013 (139)
    • ►  November (17)
    • ►  October (12)
    • ►  September (10)
    • ►  August (7)
    • ►  July (8)
    • ►  June (15)
    • ►  May (12)
    • ►  April (17)
    • ►  March (16)
    • ►  February (9)
    • ►  January (16)
  • ▼  2012 (251)
    • ►  December (9)
    • ►  November (19)
    • ►  October (26)
    • ►  September (13)
    • ►  August (35)
    • ►  July (28)
    • ►  June (27)
    • ►  May (24)
    • ►  April (18)
    • ►  March (17)
    • ▼  February (20)
      • How NOT to use AS keyword
      • Default value and TryParse
      • Field like events and polymorphic invocation
      • The string representation of a bool
      • WCF and Silverlight - How to add custom informat...
      • Windows Live - SkyDrive
      • WCF - How to add custom information to a message h...
      • Post Event - CodeCamp la Cluj-Napoca, 18 feb. 2012
      • Debug Silverlight application - breakpoint not hit
      • DateTime.ToString() formats
      • Kinect SDK preview
      • MVC - What a view should never contain( part 2)
      • MVC - What a view should never contain( part 1)
      • Interop - release COM objects( Excel.EXE hanging)
      • Intâlnire CodeCamp la Cluj-Napoca - 18 feb. 2012
      • How to change Windows wallpaper from .NET
      • How to display simple math formulas using .NET
      • Short brief - Request-Response, Asynchron and Fire...
      • Windows Live - Basic operations
      • CRUD operation on Windows Task from .NET
    • ►  January (15)
  • ►  2011 (127)
    • ►  December (11)
    • ►  November (20)
    • ►  October (8)
    • ►  September (8)
    • ►  August (8)
    • ►  July (10)
    • ►  June (5)
    • ►  May (8)
    • ►  April (9)
    • ►  March (14)
    • ►  February (20)
    • ►  January (6)
  • ►  2010 (26)
    • ►  December (1)
    • ►  November (1)
    • ►  October (1)
    • ►  June (2)
    • ►  May (1)
    • ►  April (4)
    • ►  March (1)
    • ►  February (1)
    • ►  January (14)
Powered by Blogger.

About Me

Unknown
View my complete profile