venerdì 29 ottobre 2010

Sillabe (Array di sillabe italiane)

Come sempre ... devo inventarmi qualcosa per risolvere un problema...

Scherzavo .. eh eh eh ! questa volta il problema non esiste ma sono più che sicuro che questo post possa essere uno dei miei post più importanti.

Già sono più che sicuro che molti di noi si siano più volte imbattuti in questa domanda.. MA QUALCUNO AVRA' MAI PENSATO A CREARE UN ARRAY DELLE SILLABE ITALIANE ??

Credo (anche se non lo spero) di essere il primo ... ed ecco il quanto

public const string[] Sillabe { "à","a","ab","ac","àc","ad","af","ag","ai","al","am","an","ap","ar","àr","as","at",
"au","az","az","ba","bà","bac","bal","bam","ban","bar","bàr","bat","be","bè","bel",
"bèl","béz","bi","bil","bo","bò","boc","bor","bra","bràn","bri","brò","brùt","ca",
"cà","cal","càl","cam","can","car","cat","ce","cel","cèl","cem","cèn","cet","ces",
"cer","cét","che","ché","chi","chì","chia","chià","chiac","chie","chiò","chio","cì",
"ci","cia","ciè","ciè","cièn","cìl","cil","cin","cio","cio","ciòl","clé","co","cò",
"coc","col","còl","com","con","cón","cop","cor","còr","crà","cra","crè","crè","cre",
"crì","cri","cro","crò","cru","cu","cù","cul","da","dà","dar","dàt","de","dèl","den",
"di","dì","dig","dio","diu","do","dò","dol","dól","don","dót","du","dù","dur","e",
"ei","eu","fa","fà","fab","fal","fan","fè","fèt","fi","fie","fiu","fo","for","fra",
"fra","frà","frap","fré","frin","frìt","frón","fron","fu","ga","gà","gal","gat",
"gaz","ge","get","ghe","gi","giàl","gio","giù","giu","giùn","gli","glie","glie",
"glie","gliò","gliò","go","gò","gon","gor","gra","grìl","gròp","gù","gua","guan",
"gue","guèl","guì","gui","i","ì","ia","ia","ià","ià","iai","ie","iei","in","ìn",
"io","io","iu","iuo","ka","kov","la","là","làn","las","làsc","làt","laz","le","lè",
"lèn","let","lét","lét","lèt","léz","léz","lì","lì","lia","liar","liè","lìn","lin",
"lis","lo","lò","lon","lon","lón","lòp","lòp","lór","lot","lòt","lot","lu","lù","lù",
"luò","ma","mà","mac","mal","man","màr","mar","mat","me","mé","mè","mè","mèl","mén",
"men","met","mi","mì","mic","mit","mo","mò","mol","mon","mor","mór","mul","mùl","na",
"nà","nal","nar","né","nè","ne","nel","nèl","ner","nér","nèr","net","ni","nì","nìs",
"niz","no","nò","noc","nòc","non","nòt","nu","nù","nua","nuo","nuò","o","ò","oc","oi",
"on","os","ot","ou","pa","pà","pàl","pal","pan","pàn","pàp","par","par","pàt","pe",
"pé","pèl","pen","per","pèr","per","pèt","péz","pi","pì","pie","pìl","pin","piu",
"pla","plàn","ple","pli","pli","plu","pluì","pò","po","pó","pò","pòl","pór","pòr",
"prà","pra","pre","pren","prez","pric","pro","pu","pùl","pùm","quag","quas","quàt",
"quin","ra","rà","rac","ral","ran","ràn","rat","rat","ré","re","rec","rèl","rem",
"ren","rèn","rét","rì","ri","rial","riàn","ric","rio","riz","ro","rò","róm","ron",
"rù","ru","rul","rùl","sa","sà","sac","sàc","sàg","sal","sàl","san","sàn","sba",
"sbal","sbi","sca","scà","scar","scel","sci","sci","sco","scon","scor","scrac","scré",
"scu","scu","sdi","se","sè","se","sen","sen","ses","set","sfar","si","sì","sià",
"sic","sìc","sièr","sìl","sim","slà","slab","slàr","slès","slit","smàl","smu",
"so","sò","só","sol","sòl","són","sor","sòr","sot","spèt","spi","spre","sra",
"sta","stà","stan","stè","ste","stéc","sti","stì","stic","stìn","sto","sto","stò",
"stra","strà","stràc","stres","strì","stri","stril","striz","strò","stroz","stu",
"stuò","su","sù","suà","sur","svio","ta","tà","tal","tàn","tap","tàr","tàr","te",
"tè","tè","tel","tèl","ten","tèn","tèn","ter","ti","tì","tià","tiè","tiè","tis","tìs",
"to","tó","tò","ton","tór","tor","tra","trét","tri","tro","trol","tron","trù","tu",
"tù","tù","tùc","u","ua","uai","uc","ue","uei","ui","un","uo","uoi","va","ve","vel",
"ven","vèn","ver","vi","vì","vil","vo","vò","vol","vòr","vór","yò","zà","za","zam",
"zé","ze","zec","zèl","zèl","zi","zì","zial","zio","zió","zio","zò","zòp","zop","zu"
};

Probabilmente qualche doppione c'e' è possibile che non siano tutte, ma sono più che convinto
che sia un ottimo (se non essenziale) punto di partenza...

A che cosa può servire ??
A) Generatore di parole casuali
B) Generatore di frasi casuali
C) Generatore di Password (volendo si .. )

E molto altro credo .. la fantasia rimane a voi...

martedì 12 ottobre 2010

From XML to C# Class...

Si già e poi ?? Verrebbe da dire, ma questa funzionalità esiste dal VS 2005 solo che non tutti lo sanno.

Esattamente in che cosa consiste ? Esiste un tools "XSD" che consente varie opzioni, quella in analisi consente
a) la generazione di un file xsd, partendo da un xml
b) la generazione di un file .cs (classe o classi) che rappresentano l'xsd.

Onestamente ho fatto solo una prova e sono più o meno convinto del risultato ottenuto, anche se sono partito da un XML.

Fate questa prova:
-createvi un file xml che possegga l'intestazione un nodo (root) e una serie di figli..
-qualcosa di simile a
[animali]
[animale]
[tipo] qudrupede [/tipo]
[verso] bau [/verso]
[famglia] canidi [/famglia]
[nome] Doggy [/nome]
[/animale]
[animale]
[tipo] qudrupede [/tipo]
[verso] miao [/verso]
[famglia] felinidi [/famglia]
[nome] kitty [/nome]
[/animale]
[/animali]
-salvatevi il file come [nome].xml
-da prompt di visual studio lanciate il comando XSD [nome].xml
-il risultato è un xsd che descrive il vostro xml
-sempre da prompt lanciate il comando XSD [nome].xsd /Classes
-E il risultato è il file [nome].cs che contiene le classi rappresentanti il vostro XML

Provare per credere....

giovedì 7 ottobre 2010

IsNumeric ( regular Expression )...

Avevo già affrontato questo simpatico problema... come comprendere se un valore in una stringa, è o non è un numero.

Al tempo mi ero risolto il problema (non molto elegantemente) con un try catch dove nel try avevo bene pensato di forzare il valore letto in un int in caso di Exception... non stavo trattando un numero.

Bene l'idea era valida, e funzionante ma non del tutto efficace..

Ad oggi ecco due nuove Idee... testate e garantite basate sulle regular expression.

public bool isNumeric (string value)
{
Regex verifier = new Regex( @"^(\+|-)?\d+(.|,)*\d+$");

return verifier.IsMatch(value);
}

public bool isNumeric (string value)
{
Regex verifier = new Regex(@"[0-9](.|,)*[0-9]$");

return verifier.IsMatch(value);
}

Nel primo caso si considera anche la possibilità di avere un + o un - come intestazione del numero, il secondo no.

Entrambi funzionano, ma è necessario includere la System.Text.RegularExpressions...

martedì 5 ottobre 2010

Assmbly Build Version...

Mi è capitato di voler sapere la data di build di un assembly (non la data di creazione o la data in cui è stato copiato.. per quello basta leggerle da file sistem...) e non è stato semplice comprendere dove e come reperire l'informazione.

Tuttavia, il linker (in fase di build) si occupa anche di questo... E' necessario fare una premessa, questo codice in parte trovato on line, in parte modificato da me, ha lo scopo nudo e crudo di recuperare una porzione di byte che rappresentano proprio o quasi la data di buil di un assembly.

E' doveroso ricordare che quest'informazione proviene in parte o in toto dall'assembly Version che se compilato con logica (1.0.*) funziona... (nel mio caso funziona anche con (1.0.0.0).

private string GetAssemblyBuildDate()
{
//
// percorso dell'assembly
//
string filePath = System.Reflection.Assembly.GetCallingAssembly().Location;
//
// posizione di Offset dell'header..
//
const int c_PeHeaderOffset = 60;
//
// posizione in cui il linker deposita la data durante la sua fase.
//
const int c_LinkerTimestampOffset = 8;
//
// buffer
//
byte[] b = new byte[2048];
//
// stream di byte.
//
System.IO.Stream sAssembly = null;

try
{
//
// operazione ad assembly aperto...
//
sAssembly = new System.IO.FileStream(
filePath,
System.IO.FileMode.Open,
System.IO.FileAccess.Read
);
//
// legge dal byte 0 al 2048'esimo
//
sAssembly.Read(b, 0, 2048);
}
finally
{
//
// se non è riuscito nel tentativo di aprire il buffer..
//
if (sAssembly != null)
{
sAssembly.Close();
}
}

//
// legge dal buffer i primi 60 char/byte
//
int i = System.BitConverter.ToInt32(b, c_PeHeaderOffset);
//
// crea il limite (superiore byte che rappresentano la data di build in secondi...) partendo da ciò che letto
//
int secondsSince1970 = System.BitConverter.ToInt32(b, i + c_LinkerTimestampOffset);

//
// si crea la data di comodo a cui sommare il limite
//
DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0);

//
// li aggiunge alla data di comodo
//
dt = dt.AddSeconds(secondsSince1970);
//
// "aggiunge" il gmt
//
dt = dt.AddHours(TimeZone.CurrentTimeZone.GetUtcOffset(dt).Hours);

return dt.ToShortDateString() + " " + dt.ToLongTimeString();
}

Come sempre se recuperate questo codice, potrebbe essere necessario verificare l'indentazione dei commenti ...

giovedì 9 settembre 2010

C# COM Visible

Risolviamo questo problema una volta per tutte.

C'e' tanta letteratura nel web sull'argomento, ma è davvero complesso ottenere una soluzione veritiera. C'e' chi afferma che serva solo un flag nell'assembly info, c'e' chi afferma che è necessario
lo strong Name, c'e' chi afferma che servono danze e balli propriziatori o congiunzioni astrali...

C'e' chi come me prova e ottiene la solzuione senza dover ricorrere a strani oracoli.

-Step by step C#Com Visible
1) create una nuova soluzione di tipo Class Library
2) create una classe
3) aggiungete il namespace System.Runtime.Interop
4) aggiungete alla classe i vostri Metodi / Proprietà
5) aggiungete ai metodi che devono essere COM visible gli Attributi
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
6) aggiungete (se non lo fate per abitudine i commenti ///summary)
7) create un INTERFACE che mappa tutti i Metodi e tutte le proprietà COM visible della classe
8) aggiungete alla classe l'interfaccia.

-Codice d'esempio
(ho rimosso il maggiore e il minore nei summary)

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace ComVisibleTest
{

public interface iComTest
{
string HelloWord();
int GetInt();
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class ComTest:iComTest
{
/// summary
/// Non fa nulla ma lo fa bene
/// /summary
/// returns/returns
[ComVisible(true)]
public string HelloWord()
{
return "ciao mondo";
}

/// summary
/// Restituisce il mio numero preferito.
/// /summary
/// returns/returns
[ComVisible(true)]
public int GetInt()
{
return 7;
}
}
}

-Come e cosa fare negli Attributi dell'Assembly
Nelle proprietà del progetto è necessario esplicitare che si tratta di un ComVisible.
Quindi dalle proprietà del progetto/assembly information settare:
MAKE ASSEMBLY COM VISIBLE = true.

Nelle proprietà del progetto sotto build può essere necessario indicare di ri registrare
ad ogni build l'assembly
Quindi dalle proprietà di build settare:
REGISTER FOR COM INTEROP = true.

-Volte davvero fare un salto di qualità ??
Nelle azioni di build in POST BUILD
Regasm [nome della libreria].dll /tlb:[nome della libreria.]tlb
es
Regasm ComVisibleTest.dll /tlb:ComVisibleTest.tlb


-Qualche info in più...
a) L'interfaccia, serve anzi è necessaria, perchè rappresenta l'entryPoint, o header della nostra dll. Come questa venga tratta, o come questa venga resa a livello di TLB, giuro non lo so. Ma senza l'interfaccia VB6 ( mio caso di test per questo prototipo ) vede la classe ma non i metodi, aggiungendo l'interfaccia VEDO TUTTO.

b) in VB.Net tutto questo non serve, anzi basta solo indicare che la nostra libreria è comvisible.

c) E' possibile che in caso la soluzione sia composta da più libreria, si devono realizzare tante
interfaccie per quante classi dovranno essere rese come COMvisible.


-Note Tecniche sull'ambiente:
Visual Studio 2008 tipo di build "Release X86"
Visual basic 6 sp 6
Windows 7 64 bit

martedì 24 agosto 2010

FlowLayoutPanel C#

Avete mai provato a usare questo splendido controllo ?? Io mi sto divertendo proprio ora ad usare uno strumento javesco in c#...
Non so effettivamente chi abbia fatto il primo passo con questo tortuoso strumento .. tuttavia lo trovo discretamente pratico, nel caso si debba ricorrere ad array di controlli... e gestirne il riposizionamento dopo la rimozione di uno o più elementi.

Nel mio caso sto cercando di realizzare un Tab control un po più ricercato e customizzabile di quello proposto nel VS 2008 che devo dire fa pure il suo porco mestiere... ma lascia poco spazio alla fantasia.

Ora imbattendomi in questo controllo speravo di trovare fra le properties qualcosa di utile.. stile grip / grid size.. ma nulla.

Scopro e mi pare carino condividere che "non esiste nulla di cio'" tuttavia lo spazio fra un controllo e l'altro all'interno del FlowLayoutPanel è demandato alla proprietà margin dei controlli che sta usando... o impilando.

Bene quindi ricordate che se usate :
Button myButton = new Button();
myButton.Text = "My Button";
flpMain.control.Add(myButton);
di aggiungere
myButton.Margin= new Padding(0, 0, 0, 0);

Attenzione MARGIN è una struct e non è del tutto accessibile..

lunedì 16 agosto 2010

ConfigurationManager Add Key & Value...

Sempre a me...?? ma perchè quando voglio fare qualcosa io .. becco sempre qualche sfiga strana..

System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

config.AppSettings.Settings.Remove(settingName);

config.AppSettings.Settings.Add(settingName, settingValue);

config.Save(ConfigurationSaveMode.Modified);

ConfigurationManager.RefreshSection("appSettings");

Questo effettivamente più che un add.. è un Edit, ma non è questo il vero problema... anzi...
In questo breve brano di codice sono emerse ben 2 cose...

A) in debug mode... non funzionerà e potrete tentarci quanto vorrete... ma non andrà... questo
perche ????
- Semplice in debug non accedete al vero app config... ma all' [Applicativo].vshost.exe.config...

Sembra facile ma non è difficile.. c'e' un motivo più che semplice, non modificare nulla, nel caso
l'exe originale ( ma perchè ??? ) fosse nella stessa cartella... ( qualcuno in m.s. si droga ).

B) a runtime va...

C) Lo sapevate che ...
In proprietà del vostro applicativo c'e' una voce chiamata... AssemblyName...
scrivete li dentro il nome del vostro "exe"...ehm...
poi Andate su assembly information (sempre da proprietà ) e modificate la voce
product.. in modo che sia diverso del vostro nome "exe"...
ED ECCO CHE APPARE UN ALTRO [nome prodotto].vshost.exe.config... !!
Vuoto naturalmente...

Ora... Ora... e ancora ora ... mi pare lecito avere tante possibilità .. ma dai un cotrollino sui nomi,
lo si poteva anche mettere no ???