Lo scopo di questo breve post è dare un veloce sguardo alla prima cosa che notiamo nell’SDK, ovvero il Simulator, per capire come possiamo creare applicazioni per Surface senza avere a disposizione il dispositivo.

In questo momento non dispongo di una macchina adeguata, quindi ovviamente, non sono in grado di valutare correttamente le performance. Ricordo che il Simulator funziona con una risoluzione minima di 1280×960.

Per scrivere subito un pò di codice, ho scimmiottato quanto descritto in questo video, e ho lanciato il simultatore prima di andare con il debug. Se il simulatore non è in esecuzione al momento dell’avvio del debug, l’applicazione parte come WPF application, e quindi con funzionalità ridotte rispetto a quelle attese.  Al momento non ho ancora capito se e come agganciare il debug direttamente al simulatore, quindi per ora mi assicuro di averlo in esecuzione prima del debug.

Il risultato è visibile nella foto di seguito, con le poche righe di codice che vedrete nel video.

ScreenShot014

Rispetto all’esempio del video ho aggiunto solo un bottone per uscire dall’applicazione.
Purtroppo, nel printscreen non viene visualizzato il bordo della finestra del simulator, e neanche i mouse usati (3 contemporaneamente, di cui uno PS-2 e due USB), visualizzati con un cursore stilizzato a forma di “dito”. Infatti ogni mouse simula un “punto di contatto” che potremmo avere nell’esecuzione dell’applicazione.

Nell’immagine vengono comunque visualizzati due cerchietti che sono poi i punti di contatto usati durante l’esecuzione.
Surface consente fino a 52 punti di contatto contemporanei (non mi chiedete l’origine di questo limite, me lo chiedo anche io).

L’applicazione in sé non è niente di speciale, ma se pensate alle poche righe necessarie per implementarlo, si può facilmente capire che l’SDK anche allo stato attuale, fornisce un bel pò di classi pronte all’uso. In futuro probabilmente verranno aggiunte altre classi per facilitare ulteriormente lo sviluppo.

Un metodo rapido e veloce per esportare un semplice file Excel in un file CSV:

using _Excel = Microsoft.Office.Interop.Excel;

[DllImport("user32.dll")]

static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);

/// <summary>

///

/// </summary>

/// <param name=”sInFile”>Il file .xls in input</param>

/// <param name=”sOutFile”>Il file .csv in output</param>

/// <remarks>

/// Le seguenti considerazioni sono relative a questo specifico esempio.

/// Il file .xls deve essere in formato 97/2003, no 2007.

/// Il file .csv non è “comma-separated”, ma è “semicolon-separated”, cioè vengono separati i valori con “;”

/// I filename devono essere in “absolute path” e non in “relative path”.

/// </remarks>

/// <returns>Ritorna true se l’esportazione riesce con successo, false altrimenti.</returns>

private bool ExportXlsToCsv(string sInFile, string sOutFile)

{

bool Result = File.Exists(sInFile); // verifica che il file .xls esista

if (Result)

{

_Excel.ApplicationClass excel = null; // l’istanza di Excel

int excelProcessId = 0; //id del processo creato per l’istanza

try

{

if (File.Exists(sOutFile)) // se il file di destinazione esiste…

{

File.Delete(sOutFile); // … lo elimina preventivamente

}

excel = new _Excel.ApplicationClass(); // istanzia Excel

GetWindowThreadProcessId(excel.Hwnd, out excelProcessId); // ricava l’id assegnato per il processo generato

excel.Visible = false; // evita che l’istanza dell’applicativo sia visibile all’utente

_Excel.Workbook workBook = excel.Workbooks.Open(sInFile, 0, true, 5, “”, “”, true, _Excel.XlPlatform.xlWindows, “\t”, false, false, 0, true, 1, 0); // apre il file .xls

workBook.SaveAs(sOutFile, _Excel.XlFileFormat.xlCSVMSDOS, Type.Missing, Type.Missing, Type.Missing, Type.Missing, _Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); // salva il file in formato .csv

excel.DisplayAlerts = false; // evita che venga richiesta la conferma di salvataggio alla chiusura di Excel (dato che è già salvato in .csv)

excel.Quit(); // chiude l’istanza di Excel

Result = true;

}

catch

{

Result = false;

}

finally

{

excel = null; // una volta chiusa l’istanza, questa assegnazione è comunque necessaria

if (excelProcessId != 0)

{

// se per qualche motivo non viene chiusa l’istanza Excel, facciamo una kill

int iMaxTimeoutMs = 3000; // i ms di attesa per aspettare che l’istanza venga chiusa correttamente

int iCheck = 250; // i ms per ogni controllo

while ( (iMaxTimeoutMs>0) && (Process.GetProcessById(excelProcessId) != null) )

{

Thread.Sleep(iCheck);

iMaxTimeoutMs -= iCheck;

}

Process excelProcess = Process.GetProcessById(excelProcessId);

if (excelProcess != null) // se ancora a questo punto l’istanza è attiva…

{

// (non dovrebbe servire, ma non si sa mai)

excelProcess.Kill(); // …la si butta giù di forza !

}

}

}

}

return Result;

}

Nella mia infinita, consapevole ignoranza, ho scoperto l’esistenza dei Multicast Delegate.
In pratica si traduce nella possibilità di sommare o sottrarre l’esecuzione di diversi metodi che siano conformi ad uno stesso delegate.
Questo comporta un’esecuzione in serie, secondo la somma (o la sottrazione) effettuata.
Mi spiego meglio con un esempio (liberamente tratto da questo esempio msdn):

namespace ConsoleApplication1
{

delegate int delegate1(string s);

class Class1
{

public static int Hello(string s)
{

Console.Write(“hello {0} “,s);

return
s.Length;

}

public
static int World(string s)
{

Console
.Write(” world {0} “, s);

return
s.Length;

}
public static int CarriageReturn(string s)
{
Console.WriteLine(” {0} “, s);
return s.Length;

}

public Class1()
{
delegate1 d1, d2, d3, d4;
d1 = Hello;

d2 = World;

d3 = CarriageReturn;

d4 = d1 + d2 + d3;
d4(“!”);
Console.ReadLine();
}
}
}

Questo comporta il seguente output :

hello ! world ! !

Quindi abbiamo eseguito i metodi nella sequenza identificata dalla somma. Come dicevo, si possono eseguire anche operazioni di sottrazione, corrispondenti alla fine ad una eliminazione dalla sequenza di esecuzione.
Quindi avremmo potuto scrivere (al posto della riga in rosso)

d4(“!”);

d4 -= d2;

d4(“!”);

e ottenere :

hello ! world ! !

hello ! !

Questo “sommatoria” si può eseguire come dicevo, solo se i metodi usati come addendi sono conformi ad uno stesso delegate. Lo stesso discorso non vale per un eventuale valore di
ritorno del metodo, che non corrisponde ad una “sommatoria dei valori di ritorno” dei metodi addendi.

In pratica se avessi scritto :

int i1 = d4(“!”);

Console.WriteLine(“Return : {0}”, i1);

d4 -= d2;

int i2 = d4(“!”);

Console.WriteLine(“Return : {0}”, i2);

avrei ottenuto come output :

hello ! world ! !

Return : 1

hello ! !

Return : 1

quindi è chiaro che il risultato è relativo solo all’ultimo metodo eseguito.

Questo si evidenzia ancora maggiormente se lanciamo un ILDASM sull’assembly, dove notiamo che i punti in cui eseguiamo il delegate d4, viene composto dalle chiamate in sequenza dei metodi che in quel momento lo compongono.

Il risultato di una sommatoria anche del valore di ritorno, si potrebbe comunque ottenere, se proprio necessario in uno scenario del genere, ricorrendo semplicemente (ad esempio) a delle variabili statiche con visibilità globale per la classe.

Alcune volte è necessario inserire in una listbox delle righe (negli items) che vanno oltre la larghezza della listbox stessa.

Il controllo in sè non ha le proprietà, ma neanche le responsabilità, per decidere come e quando tagliare le righe inserite.

Ovviamente questo è un esempio e va preso così com’è. Modificatelo poi per il vostro caso specifico.

- innanzitutto la proprietà DrawMode della listbox va posta a OwnerDrawFixed;
- quindi si deve definire un gestore per l’evento DrawItem della stessa listbox, come di seguito indicato :

private void ListBoxcheckuser_DrawItem(object sender, DrawItemEventArgs e)
{
ListBox myListbox = (ListBox)sender;
// disegna il background e definisco il brush
e.DrawBackground();
Brush myBrush = Brushes.Black;
// la stringa da mostrare nella riga
string sTextToDisplay =
myListbox.Items[e.Index].ToString();
// stabilisco la larghezza massima di ogni riga, in caratteri
int iLength = 50;
// se la lunghezza della stringa supera quella visibile, la taglio e
// faccio l'insert delle righe a seguire
if (sTextToDisplay.Length > iLength)
{
// ottengo il primo blocco (per la riga corrente)
string sFirstBlock = sTextToDisplay.Substring(0, iLength - 1);
// e quindi il secondo blocco (il rimanente della riga)
string sSecondBlock = sTextToDisplay.Remove(0, iLength - 1);
// assegno il primo blocco alla riga corrente (che ora
è stata modificata)
myListbox.Items[e.Index] = sFirstBlock; //
questa riga è fondamentale;
// inserisco la nuova riga all'indice successivo
// questo farà scattare nuovamente questo evento, per
la riga in questione
myListbox.Items.Insert(e.Index + 1, sSecondBlock);
// riporto il valore da stampare (disegnare)
sTextToDisplay = sFirstBlock;
}
// disegno il testo per la riga corrente (o quello che ne rimane)
e.Graphics.DrawString(sTextToDisplay, e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
// assegno il focus al rectangle se necessario
e.DrawFocusRectangle();
}

questo ti consente di determinare una lunghezza massima in caratteri del testo che viene inserito nella textbox;
l’unico svantaggio è che non è dinamico in base al font; a questo si può rimediare ragionando in termini di pixel, vedendo di volta in volta la larghezza della stringa da scrivere rispetto alla larghezza della listbox, tramite il metodo :

// ottengo il primo blocco (per la riga corrente)
int iPixel = TextRenderer.MeasureText(myString, myFont).Width;

ma è un’alternativa ancor più faticosa della prima, e poco gestibile (per il fatto che il DrawItem viene rilanciato ad ogni visualizzazione/refresh del controllo/della pagina)…

Pensavo che queste seghe mentali soluzioni geniali fossero solo un ricordo dell’epoca di Delphi

Ritorno dopo un paio di mesi di inattività a causa di moltissimi impegni dovuti ad una marea di cazzate attività di puro management.

Quindi sono ritornato sul pezzo, stavolta (ahimè) su Java (mi scusino i javisti).

Devo dire che questo corso che sto seguendo lo trovo niente male. Fatene buon pro.

Se cercate le specifiche del C# 3.0 e non riuscite a scaricarle da MSDN, vi comunico che il link segnalato un pò in giro per i vari siti (anche della stessa MS) è sbagliato.

Quello corretto è questo.

Per quanto riguarda la mia assenza dal blog, ultimamente ho fatto dei gran botti sono stato molto molto molto impegnato per lavoro, spero di recuperare a breve.

riferimenti : link

Una vecchia nota di qualche anno fa, ritrovata su Outloook, mi dà lo spunto per questo post. Non so se serve ancora ma lo riporto qui, copio e incollo così com’è.

DEBUGGING DELPHI 5 DLL ON WINDOWS XP

Se ci sono problemi con i breakpoint sulle dll in progetti Delphi 5 e Windows XP:
1 – eseguire il programma exe principale
2 – fermare lo stesso su un breakpoint dopo che abbia caricato le dll in memoria
3 – Ctrl+Alt+M apre la finestra dei moduli caricati in memoria
4 – vedere quali indirizzi sono riportati come base address per le dll
5 – chiudere il debug
6 – nelle options dei progetti dll, impostare nella pagina linker il base address a quello letto nella finestra dei moduli
7 – fare il “rebuild all” del progetto
8 – fine

1. Introduzione

La programmazione software rappresenta una delle attività più complesse dello scenario informatico.

Da sempre la realizzazione di software affidabile e funzionale è stato uno degli obiettivi maggiormente inseguiti delle più grandi aziende del panorama ICT internazionale, e per ben riuscire in questo scopo sono state elaborate moltissime teorie, scritti migliaia di testi, ed è risultato necessario persino creare una nuova branca dell’ingegneria, appunto l’ingegneria del software.

Da questo lavoro, tutte le problematiche dello sviluppo sono state apparentemente affrontate, portando alla definizione di diverse metodologie di sviluppo software. Tuttavia, ad oggi, non si può dire che esista una metodologia più completa o affidabile delle altre, tanto che molte di esse sono state dimenticate col passare del tempo.

Negli ultimi anni una nuova metodologia sembra essersi largamente diffusa, evolvendo al punto tale da potersi definire matura. Stiamo parlando della metodologia che va sotto il nome di Extreme Programming, e nota anche come XP.

Elaborata da Kent Beck, Ward Cunningham e da Ron Jeffries verso la fine degli anni 90, sta diffondendosi tramite la rete, maturando sempre più ampi consensi, grazie alla sua natura estremamente dinamica.

Questa metodologia rientra nelle cosiddette metodologie agili, dove con questo termine si classificano quelle metodologie di sviluppo che hanno alla loro base una elevata reattività ai cambiamenti di requisiti, e un continuo scambio di informazioni tra il cliente e il committente, per ottenere un risultato meglio aderente alle sue reali necessità.

2. Principi e regole fondamentali

Un insieme di regole ben preciso delinea le caratteristiche della metodologia in questione.
Proviamo ad accorparle per riassumerle come segue :

  • la progettazione avviene con il supporto del cliente (o di un suo referente) che contribuisce in maniera continuativa allo sviluppo, verificando e testando, che il prodotto rispecchi le necessità espresse; se il cliente è disponibile, si possono stabilire degli incontri periodici, magari settimanali, per stabilire lo stato di avanzamento dei lavori;
  • progettare entità modulari e minime; in questo modo si potranno effettuare refactoring continui dei moduli senza coinvolgere le altre parti che la usano, integrando continuamente i cambiamenti che intervengono e se necessario riscrivendo anche parti fondamentali del modulo;
  • test continui sul codice, su ogni unità o modulo realizzato, in modo da intervenire prima possibile per sistemare i bachi trovati;
  • il gruppo di lavoro deve convivere in uno spazio comune (open workspace) per poter meglio interagire; ognuno può contribuire alla stesura di codice, su qualunque parte del progetto (proprietà collettiva del codice); la programmazione va fatta rigorosamente a coppie, con intervalli stabiliti di tempo in cui alternarsi alla tastiera, se possibile formando coppie con livelli di skill differenti o non equivalenti; lavorare non più di 40 ore settimanali (e non meno possibilmente); tutti devono seguire delle linee comuni e degli standard di scrittura del codice, per consentire l’interazione di persone diverse sulla stessa porzione di codice;
  • ogni mattina va fatta una riunione per stabilire cosa si è fatto rispetto al giorno prima, verificare difficoltà incontrate e decidere cosa si farà durante la giornata; queste riunioni sono caratterizzate dal fatto che coinvolgono tutto il gruppo, durano poco (5-10 minuti al massimo) e si svolgono in piedi (non ci devono essere sedie), per evitare di rilassarsi (ciò consente di andare dritti al punto);
  • la documentazione tecnica deve essere ridotta e concreta; per il resto delle informazioni si fa riferimento al codice che ovviamente deve essere ben dettagliato e commentato;

Ci sono tante altre sfaccettature di queste “regole” che per il momento non è necessario dettagliare.

3. Ambiti applicativi

La metodologia trova il suo miglior terreno di applicazione in gruppi piccoli, composti al massimo da una decina di persone, di cui alcuni con uno skill notevole, in cui esista una figura carismatica del project manager che porti avanti i fili di questa trama; inoltre il gruppo deve elaborare se non tutta l’intera soluzione da realizzare, quantomeno un blocco “chiuso” che non abbia necessità di parti esterne realizzate da altri gruppi o aziende.

4. Vantaggi e svantaggi della metodologia

La parola d’ordine è produttività. E con questa metodologia, la produttività è certamente elevata. Tuttavia non è garantito il risultato, molto è legato alla figura del project leader e alla sua personalità.

La metodologia resta comunque una valida alternativa su progetti dinamici, in cui si evidenzi da subito che i requisiti sono o non ben definiti o suscettibili di numerose variazioni in corso d’opera.
E’ applicabile avendo a disposizione risorse dinamiche e motivate.

Per la parte relativa alla programmazione a coppie, è stato stimato un sostanziale aumento dei tempi di sviluppo, circa il 40%, quando sul progetto vi siano risorse con skill bassi. Questo se da un lato può comportare uno svantaggio non indifferente, dall’altro lato può risultare utile in progetti futuri, in cui la risorsa poco esperta, lavorando a coppie con una esperta, riesca velocemente a colmare buona parte del gap, acquisendo esperienza sul campo, e studiando/assimilando le tecniche della persona più esperta, in una sorta di full-immersion-training-on-the-job (passatemi il termine).

Inoltre questo divario di tempo sullo sviluppo viene in parte riassorbito dall’aumentata produttività del team, rispetto all’utilizzo delle classiche metodologie non-agili (metodologie pesanti e metodologie iterative).

5. Strumenti per la gestione

Come detto più volte, l’Extreme Programming è una metodologia. Questo vuol dire che non si lega ad un prodotto o un insieme di prodotti specifici. Esistono tuttavia in commercio soluzioni che consentono la gestione completa del ciclo di sviluppo software con XP.

Mi limito a segnalare XPlanner, una suite open source.
Non l’ho mai provata, lo farò spero a breve.

N.B. : questo post è in-progress, verrà aggiornato ancora.
revision-0 : 2007-10-09 14.25