Tips&Tricks I trucchi del mestiere

 

Creare delle immagini formato thumbnail

In un sito Web Φ sempre preferibile utilizzare delle immagini di formato ridotto che al semplice click del mouse possano mostrarsi nella loro interezza. Il tip mostra come realizzare delle immagini di formato ridotto note come thumbnail.

<%
Const MINPIXELS = 100

Set objImageSize = Server.CreateObject("ImgSize.Check")
objImageSize.FileName = Server.MapPath("IMG.jpg")
ImageHeight = objImageSize.Height
ImageWidth = objImageSize.Width
If ImageHeight > ImageWidth Then
    NewHeight = Cint(ImageHeight*MINPIXELS/ImageWidth)
    NewWidth = MINPIXELS
Else
    NewWidth = Cint(ImageWidth*MINPIXELS/ImageHeight)
    NewHeight = MINPIXELS
End If
Set objImageSize = Nothing

'*** Creazione dell'immagine thumbnail
Set Image = Server.CreateObject("AspImage.Image")
Image.LoadImage(Server.MapPath("IMG.jpg"))
Image.FileName = Server.MapPath("IMG_piccola.jpg")
Image.ImageFormat = 1
Image.JPEGQuality = 70
Image.Resize NewWidth,NewHeight
Image.SaveImage
Set Image = Nothing
%>



Creare un documento Word da ASP


Ecco come in modo semplice e veloce Φ possibile creare un documento Word da una comune pagina ASP. La pagina richiede di immettere dei semplici dati e da questi ne propone una visualizzazione in Word.

<form action="word_create.asp">
Name: <input type="text" name="Nome" size="50" maxlength="100">
Email: <input type="text" name="Email" size="50" maxlength="100">
Commenti:
<textarea cols="50" rows="10" name="commenti"></textarea> 
<input type="submit" value="Submit">
</form>

Di seguito come creare, di fatto, il documento Microsoft Word.

<% Response.ContentType = "application/msword" %>
<html>
<% strNome = Request.Querystring("Nome")
strEmail = Request.Querystring("Email")
strCommenti = Request.Querystring("Commenti")
%> 
<head>
</head>
<body>
<p align="right"><%=formatdatetime(now,2)%></p> 
Dear <%= strnome %>:
Il mio indirizzo email Φ: <%= stremail %>
Ecco qui i commenti: <%= strCommenti %>
</body>
</html> 


Una classe in C++ per manipolare le date

Una classe Data che pu≥ risultare comoda per chi fa programmi che utilizzano questo tipo di informazione.
Tip fornito dal Sig. Eugenio Dei Giudici

// FILE Data.h - Header File

#ifndef DATAH
#define DATAH

#include 
#include 

using namespace std;

class Data {

// Operatore d'uscita (output)
friend ostream& operator<<(ostream&, const Data&);
// Operatore d'ingresso (input)
friend istream& operator>>(istream&, Data&);
// Operatori di confronto
friend bool operator==(const Data&, const Data&);
friend bool operator!=(const Data&, const Data&);
friend bool operator<(const Data&, const Data&);
friend bool operator<=(const Data&, const Data&);
friend bool operator>(const Data&, const Data&);
friend bool operator>=(const Data&, const Data&);

public:
		Data(int,int,int);				// Costruttore
		Data(const Data&);			// Costruttore di copia
		Data();					// Costruttore di default

		Data& operator=(const Data&);	// Operatore d'assegnamento

		int getAnno() const { return anno; }	// Funzioni che restituiscono
		int getMese() const { return mese; }	// i valori delle variabili
		int getGiorno() const { return giorno; }	// di stato

		void modG(int);				// Funzioni atte
		void modM(int);				// a modificare
		void modA(int);				// le variabili di stato

private:
		int anno;					// Variabili
		int mese;					// di
		int giorno;					// stato

// Funzione di verifica dell'effettiva esattezza di una possibile Data
		bool controlla (int,int,int);	

}; // Data

#endif

// File Data.cpp - Implementazione

#include "Data.h"
#include 

Data::Data(int g,int m,int a) {
	if(!controlla(g,m,a)) throw new exception();
	giorno=g;
	mese=m;
	anno=a;
} // costruttore

Data::Data(const Data& d) {
	giorno=d.giorno;
	mese=d.mese;
	anno=d.anno;
} // costruttore di copia

Data::Data() {
	int g;
	int m;
	int a;
	time_t t=time(NULL);
	char* s=ctime(&t);	/* stringa contenente la data corrente sottoforma di:
				giorno_della_settimana mese giorno ora anno*/
	char* p;			/* puntatore a carattere necessario a puntare
					il primo carattere utile dei token */
	p=strtok(s," ");	// prendo il primo token che non mi serve
	p=strtok(NULL," ");	/* prendo il token successivo sostituendo NULL al carattere 
				   \0 del token precedente, modificando cos∞ la stringa di					   partenza */
	if(strcmp(p,"Jan")==0) m=1;
	if(strcmp(p,"Feb")==0) m=2;
	if(strcmp(p,"Mar")==0) m=3;
	if(strcmp(p,"Apr")==0) m=4;
	if(strcmp(p,"May")==0) m=5;
	if(strcmp(p,"Jun")==0) m=6;
	if(strcmp(p,"Jul")==0) m=7;
	if(strcmp(p,"Aug")==0) m=8;
	if(strcmp(p,"Sep")==0) m=9;
	if(strcmp(p,"Oct")==0) m=10;	
	if(strcmp(p,"Nov")==0) m=11;
	if(strcmp(p,"Dec")==0) m=12;
	p=strtok(NULL," ");	// prendo il token col giorno
	g=atoi(p);		// converto il giorno da string in int
	p=strtok(NULL," ");  // prendo il token con l'ora e lo scarto subito
	p=strtok(NULL," ");	// prendo il token con l'anno
	a=atoi(p);		// converto l'anno da string in int
	if(!controlla(g,m,a)) throw new exception();
	giorno=g;
	mese=m;
	anno=a;	
} // costruttore di default (ritorna la data corrente dell'orologio di sistema)

Data& Data::operator=(const Data& d) {
	giorno=d.giorno;
	mese=d.mese;
	anno=d.anno;
	return *this;
} // operator=

void Data::modG(int g) {
	if (!controlla(g, mese, anno)) throw new exception();
	giorno=g;
} // modG

void Data::modM(int m) {
	if (!controlla(giorno, m, anno)) throw new exception();
	mese=m;
} // modM

void Data::modA(int a) {
	if (!controlla(giorno, mese, a)) throw new exception();
	anno=a;
} // modA

bool Data::controlla (int g,int m,int a) {
	if (g<1 || g>31) return false;
	if (m<1 || m>12) return false;
	if (a<=-1000000000 || a>=1000000000) return false;	// limiti totalmente arbitrari (cifra tonda!)
	if (g==31 && (m==4 || m==6 || m==9 || m==11) ) return false;
	if (m==2) 
		if (g>29 || g==29 && a%4!=0 ) return false;
	return true;
} // controlla

// Overloading degli operatori

// Operatore d'uscita (output)
ostream& operator<<(ostream& os, const Data& d) {
	os<<d.giorno<<"/"<<d.mese<<"/"<<d.anno;
	return os;
} // operator><

// Operatore d'ingresso (input)
istream& operator>>(istream& is, Data& d) {
	int g,m,a;
	char* c=new char[50];
	cout<<"Inserisci il giorno: "; 
	is.getline(c,50);
	g=atoi(c);
	cout<<"Inserisci il mese: ";
	is.getline(c,50);
	m=atoi(c);
	cout<<"Inserisci l'anno: ";
	is.getline(c,50);
	a=atoi(c);
	delete [] c;
	if(!d.controlla(g,m,a)) throw new exception();
	d.modG(g);
	d.modM(m);
	d.modA(a);
	return is;
} // operator>>

// Operatori di confronto
bool operator==(const Data& d1, const Data& d2) {
	return (d1.giorno==d2.giorno && d1.mese==d2.mese && d1.anno==d2.anno);
} // operator==

bool operator!=(const Data& d1, const Data& d2) {
	return (d1.giorno!=d2.giorno || d1.mese!=d2.mese || d1.anno!=d2.anno);
} // operator!=

bool operator<(const Data& d1, const Data& d2) {
	return (d1.anno<d2.anno || d1.anno==d2.anno && d1.mese<d2.mese || 
			d1.anno==d2.anno && d1.mese==d2.mese && d1.giorno<d2.giorno);
} // operator<

bool operator<=(const Data& d1, const Data& d2) {
	return (d1.anno<d2.anno || d1.anno==d2.anno && d1.mese<d2.mese || 
			d1.anno==d2.anno && d1.mese==d2.mese && d1.giorno<d2.giorno ||
			d1.giorno==d2.giorno && d1.mese==d2.mese && d1.anno==d2.anno);
} // operator<=

bool operator>(const Data& d1, const Data& d2) {
	return (d1.anno>d2.anno || d1.anno==d2.anno && d1.mese>d2.mese || 
			d1.anno==d2.anno && d1.mese==d2.mese && d1.giorno>d2.giorno);
} // operator>

bool operator>=(const Data& d1, const Data& d2) {
	return (d1.anno>d2.anno || d1.anno==d2.anno && d1.mese>d2.mese || 
			d1.anno==d2.anno && d1.mese==d2.mese && d1.giorno>d2.giorno ||
			d1.giorno==d2.giorno && d1.mese==d2.mese && d1.anno==d2.anno);
} // operator>=

Nascondere il menu contestuale dei filmati Macromedia Flash di una Windows Forms

Il tip in linguaggio C# spiega come inserire un filmato Macromedia Flash in una applicazione windows .NET e nasconderne completamente il menu contestuale.
Tip fornito dal Sig. Sergio Turolla
Come prima operazione, utilizzando l'applicazione "aximp" fornita a corredo con l'SDK del Framework .NETm si importa l'activeX di Flash utilizzando la seguente sintassi:

aximp "c:\WINDOWS\system32\Macromed\Flash\Flash.ocx" /source

(NB: Si presuppone che il player Flash 6 sia correttametne installato nella sua path di default ("c:\WINDOWS\system32\Macromed\Flash\Flash.ocx", se non Φ cosi lo si puo scaricare dal sito della macromedia "www.macromedia.com")
Saranno generati tre file di cui solo due necessari ai nostri scopi: "ShockwaveFlashObjects.dll" e soprattutto "AxShockwaveFlashObjects.cs" (il sorgente del wrapper .NET per l'activeX di flash)
Successivamente editando il file "AxShockwaveFlashObjects.cs" generato automaticamente dall'utility "aximp" si deve aggiungere il seguente codice alla classe AxShockwaveFlash:

public class AxShockwaveFlash : System.Windows.Forms.AxHost {

// Costante dell'evento da intercettare
		private readonly int rightMouseClickMessage = 516;

		// Disabilita il menu contestuale
		protected override void WndProc(ref System.Windows.Forms.Message m)
		{			
			// Intercetta ed esegue tutti i messaggi tranne 
// quello del tasto destro del mouse che causa la 
// visualizzazione del menu contestuale
			if (m.Msg != rightMouseClickMessage)
				base.WndProc(ref m);		
		}
...
...

Questo codice fa si che vengano intercettati e gestiti, dal componente Flash, tutti i messaggi ad eccezione di quello generato dalla pressione del tasto destro del mouse. In questo modo il player Flash, non ricevendo mai il messaggio di Windows, che lo informa della pressione del tasto destro del mouse, inibisce la visualizzazione del menu contestuale associato all'evento. E' ora possibile utilizzare la classe all'interno dei nostri applicativi Windows Forms, ad esempio in questo modo:

using System;
using System.Drawing;
using System.Windows.Forms;
using AxShockwaveFlashObjects;

namespace FlashTest
{
	public class FlashForm  : System.Windows.Forms.Form
	{

		private AxShockwaveFlash flashControl;

		public FlashForm ()
		{
			this.Text = "FlashTest";
			this.Size = new Size(500,400);
			this.Load += new EventHandler(this.myWindow_Load);

			// crea il controllo flash e lo aggiung al form
			this.flashControl = new AxShockwaveFlash();
			this.flashControl.Location = new Point(10,10);
			this.flashControl.Size = new Size(300,300);
			this.Controls.Add(this.flashControl);

		}

		public void myWindow_Load(object sender,EventArgs e)
		{
			// Carica il filmato flash
			// Per un corretto funzionamento caricare il filmato
			// sempre sull'evento Load del form o successivamente
	// e mai nel costruttore			
this.flashControl.Movie = 
System.IO.Path.Combine(Application.StartupPath,"Login.swf");
		}

		public static void Main()
		{
			Application.Run(new FlashForm());
		}
	}
}

In ultimo, per compilare l'applicativo, bisogna ricordarsi di aggiungere un riferimento al file "ShockwaveFlashObjects.dll" generato da "aximp", ad esempio eseguire:

csc /target:winexe FlashForm.cs AxShockwaveFlashObjects.cs /r:ShockwaveFlashObjects.dll

Applicazioni protette!

In allegato un'applicazione a riga di comando (scritta in Delphi 6) che mostra l'utilizzo dell'API CreateProcessWithLogonW. Permette di lanciare un'applicazione in un contesto di sicurezza specificato (tramite UserName, Dominio e Password). I parametri da passare alla funzione API Win32 CreateProcessWithLogonW (esportata da advapi32.dll, e presente soltanto da Windows 2000 in poi) sono:

lpUserName, lpDominio ed lpPassword : Puntatori a Wide String rispettivamente contenenti il nome utente, il dominio e la password d'accesso

dwLogonFlags : DWORD che specifica le opzioni per il logon (impostato a LOGON_WITH_PROFILE che impone il caricamento del profilo utente)

lpApplicationName ed lpCommandLine: Puntatori a Wide String rispettivamente per il percorso e nome dell'eseguibile e per la riga di comando

dwCreationFlags: DWORD che specifica i flag di creazione del processo; vengono impostati CREATE_DEFAULT_ERROR_MODE, CREATE_NEW_CONSOLE e CREATE_NEW_PROCESS_GROUP che normalmente sono settati per default

lpEnvironment: Puntatore ad un blocco di variabili di ambiente. Settato a NIL consente di utilizzare l'ambiente del processo chiamante

lpCurrentDirectory: Puntatore a Wide String contente la directory in cui verrα eseguita l'applicazione

lpStartupInfo: Puntatore ad una struttura STARTUPINFO che specifica i parametri di visualizzazione della finestra.

lpProcessInfo: Puntatore ad una struttura PROCESSINFO che riceverα gli handle e gli ID di processo e thread.

Nell'esempio viene anche fatto uso dell'API Win32 FormatMessage che restituisce il testo dal codice di un eventuale errore riportato dalla GetLastError nella lingua specificata (dalla GetUserDefaultLangID). Viene inoltre dimostrata anche l'importazione implicita in Delphi di funzioni dalle librerie dinamiche.
Tip fornito dal Sig. Raffaele Cirillo

Program CreateProcess;
{$APPTYPE CONSOLE}
Uses
        SysUtils, Windows;
Const
        LOGON_WITH_PROFILE        = 1;
        LOGON_NETCREDENTIALS_ONLY = 2;
Var
        lpUsername              : LPCWSTR;
        lpDomain                : LPCWSTR;
        lpPassword              : LPCWSTR;
        dwLogonFlags            : LongWord;
        lpApplicationName       : LPCWSTR;
        lpCommandLine           : LPWSTR;
        dwCreationFlags         : LongWord;
        lpEnvironment           : Pointer;
        lpCurrentDirectory      : LPCWSTR;
        StartupInfo             : TSTARTUPINFO;
        lpStartupInfo           : PSTARTUPINFO;
        ProcessInfo             : TProcessInformation;
        lpProcessInfo           : PProcessInformation;
        lpMsgBuf                : Array[0..100] Of Char;

Function CreateProcessWithLogonW
                        (
                        lpUsername         : LPCWSTR;
                        lpDomain           : LPCWSTR;
                        lpPassword         : LPCWSTR;
                        dwLogonFlags       : LongWord;
                        lpApplicationName  : LPCWSTR;
                        lpCommandLine      : LPWSTR;
                        dwCreationFlags    : LongWord;
                        lpEnvironment      : Pointer;
                        lpCurrentDirectory : LPCWSTR;
                        lpStartupInfo      : PSTARTUPINFO;
                        lpProcessInfo      : PProcessInformation
                        )
                        : Boolean; StdCall;
                        External 'advapi32.dll' NAME 'CreateProcessWithLogonW';
Begin
        If ParamCount <> 4 Then
                WriteLn ('Uso: ' + #13#10 +
                         'CreateProcess NOMEAPPLICAZIONE USERNAME' +
                         'DOMINIO PASSWORD')
        Else
        Begin
                lpApplicationName   := PWideChar(WideString(ParamStr(1)));
                lpUserName          := PWideChar(WideString(ParamStr(2)));
                lpDomain            := PWideChar(WideString(ParamStr(3)));
                lpPassword          := PWideChar(WideString(ParamStr(4)));
                lpCommandLine       := NIL;
                lpCurrentDirectory  := PWideChar(WideString(
                                         ExtractFilePath(ParamStr(1))));
                dwLogonFlags        := LOGON_WITH_PROFILE;
                dwCreationFlags     := CREATE_DEFAULT_ERROR_MODE Or
                                       CREATE_NEW_CONSOLE Or
                                       CREATE_NEW_PROCESS_GROUP;
                lpEnvironment       := NIL;
                With StartupInfo Do
                Begin
                        cb          := SizeOf(StartupInfo);
                        lpReserved  := NIL;
                        lpDesktop   := NIL;
                        lpTitle     := NIL;
                        dwFlags     := STARTF_USEPOSITION      Or
                                       STARTF_USEFILLATTRIBUTE Or
                                       STARTF_USECOUNTCHARS    Or
                                       STARTF_USESHOWWINDOW    Or
                                       STARTF_USESIZE;
                        wShowWindow := SW_SHOWDEFAULT;
                        cbReserved2 := 0;
                        lpReserved2 := NIL;
                End;
                lpStartupInfo       := @StartupInfo;
                lpProcessInfo       := @ProcessInfo;
                If CreateProcessWithLogonW(
                                        lpUserName,
                                        lpDomain,
                                        lpPassword,
                                        dwLogonFlags,
                                        lpApplicationName,
                                        lpCommandline,
                                        dwCreationFlags,
                                        lpEnvironment,
                                        lpCurrentDirectory,
                                        lpStartupInfo,
                                        lpProcessInfo)
                Then
                        WriteLn('Handle processo: ', ProcessInfo.hProcess,
                                #13#10,
                                'Handle thread: ',   ProcessInfo.hThread,
                                #13#10,
                                'PID: ',             ProcessInfo.dwProcessId,
                                #13#10,
                                'Thread ID: ',       ProcessInfo.dwThreadId)
                Else
                Begin
                        FormatMessage(
                                FORMAT_MESSAGE_FROM_SYSTEM,
                                NIL,
                                GetLastError,
                                GetUserDefaultLangID,
                                @lpMsgBuf,
                                100,
                                NIL);
                        MessageBox(0,
                                @lpMsgBuf,
                                'CreateProcessWithLogonW',
                                MB_ICONERROR);
                End;
        End;
End.

Numeri binari con Visual Basic


Una serie di funzioni che permettono di "lavorare" con i numeri binari; nella fattispecie sono implementate le seguenti procedure e/o funzioni:
- DecTOBin e BinTODec permettono di convertire valori di byte nel loro corrispettivo binario e vice versa.
- GetLowHightValueBits restituisce I valori dei bits alti e bassi all'interno di un byte.
- SplitLongValues, SplitIntegerValues, MergeLongValues e MergeIntegerValues scompogno e ricompongono numeri Integer e Long nei (oppure a partire da i) loro sotto byte.
- ShiftByte permette di compiere operazioni tipo Mid$ sui valori dei Bits di un singolo byte restituendo poi il valore risultante.
Tip fornito dal Sig. S.Tubini

Option Explicit

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Public Enum ShiftType
    RightShift = 1
    LeftShift = 2
End Enum

Public Sub GetLowHightValueBits(bValue As Byte, lValue As Byte, hValue As Byte)
Dim BitArr(7) As Byte, LBArr(7) As Byte, HBArr(7) As Byte

    DecTOBin bValue, BitArr()

    LBArr(0) = BitArr(7)
    LBArr(1) = BitArr(6)
    LBArr(2) = BitArr(5)
    LBArr(3) = BitArr(4)

    HBArr(0) = BitArr(3)
    HBArr(1) = BitArr(2)
    HBArr(2) = BitArr(1)
    HBArr(3) = BitArr(0)
    
    lValue = BinTODec(LBArr())
    hValue = BinTODec(HBArr())

End Sub

Public Sub DecTOBin(bValue As Byte, BitArr() As Byte)
Dim I As Long

    For I = 1 To bValue Step 1
      If BitArr(7) = 1 Then
        
        BitArr(7) = 0
        If BitArr(6) = 1 Then
        
            BitArr(6) = 0
            If BitArr(5) = 1 Then
            
                BitArr(5) = 0
                If BitArr(4) = 1 Then
                
                    BitArr(4) = 0
                    If BitArr(3) = 1 Then
                    
                        BitArr(3) = 0
                        If BitArr(2) = 1 Then
                        
                            BitArr(2) = 0
                            If BitArr(1) = 1 Then
                            
                                BitArr(1) = 0
                                BitArr(0) = 1
                            
                            Else
                                BitArr(1) = 1
                            End If
                        
                        Else
                            BitArr(2) = 1
                        End If
                    
                    Else
                        BitArr(3) = 1
                    End If
                
                Else
                    BitArr(4) = 1
                End If
                
            Else
                BitArr(5) = 1
            End If
        
        Else
            BitArr(6) = 1
        End If
      
      Else
        BitArr(7) = 1
      End If
    
    Next

End Sub

Public Function BinTODec(BitIn() As Byte) As Byte
Dim I As Long, BitArr(7) As Byte

    For I = 1 To 255 Step 1
      If BitArr(7) = 1 Then
        
        BitArr(7) = 0
        If BitArr(6) = 1 Then
        
            BitArr(6) = 0
            If BitArr(5) = 1 Then
            
                BitArr(5) = 0
                If BitArr(4) = 1 Then
                
                    BitArr(4) = 0
                    If BitArr(3) = 1 Then
                    
                        BitArr(3) = 0
                        If BitArr(2) = 1 Then
                        
                            BitArr(2) = 0
                            If BitArr(1) = 1 Then
                            
                                BitArr(1) = 0
                                BitArr(0) = 1
                            
                            Else
                                BitArr(1) = 1
                            End If
                        
                        Else
                            BitArr(2) = 1
                        End If
                    
                    Else
                        BitArr(3) = 1
                    End If
                
                Else
                    BitArr(4) = 1
                End If
                
            Else
                BitArr(5) = 1
            End If
        
        Else
            BitArr(6) = 1
        End If
      
      Else
        BitArr(7) = 1
      End If
    
      If BitIn(0) = BitArr(0) And BitIn(1) = BitArr(1) And BitIn(2) = BitArr(2) And BitIn(3) = 
BitArr(3) And BitIn(4) = BitArr(4) And BitIn(5) = BitArr(5) And BitIn(6) = 
BitArr(6) And BitIn(7) = BitArr(7) Then
            BinTODec = I
            Exit For
      End If
     Next

End Function

Public Sub SplitLongValues(lValue As Long, ByteArr() As Byte)
    CopyMemory ByteArr(0), lValue, 4
End Sub

Public Sub SplitIntegerValues(iValue As Integer, ByteArr() As Byte)
    CopyMemory ByteArr(0), lValue, 2
End Sub

Public Function MergeLongValues(ByteArr() As Byte) As Long
    CopyMemory MergeLongValues, ByteArr(), 4
End Function

Public Function MergeIntegerValues(ByteArr() As Byte) As Integer
    CopyMemory MergeIntegerValues, ByteArr(), 2
End Function

Public Function ShiftByte(bValue As Byte, nBitStart As Byte, nSize As Byte, ShiftMode As 
ShiftType) As Byte

On Local Error Resume Next
Dim bArr(7) As Byte
Dim NewbArr(7) As Byte

Dim I As Long,, nStep As Long, nSkip As Long
If (nBitStart + nSize * nStep) < 8 Or (nBitStart + nSize * nStep) > -1 And nBitStart < 8 Then

    If ShiftMode = LeftShift Then
        nStep = -1
    ElseIf ShiftMode = RightShift Then
        nStep = 1
    End If

    DecTOBin bValue, bArr()
    nSkip = 7
    For  I = (7 - nBitStart) To (7 - (nBitStart + nSize - 1)) Step nStep
        NewbArr(nSkip) = bArr(I)
        nSkip = nSkip - 1
    Next
End If

If Err <> 0 Then Err = 0: Exit Function
ShiftByte = BinTODec(NewbArr())
End Function


Grafici a torta? Sempliceà


Un piccolo ma funzionale tip che consente di creare grafici a torta senza utilizzare nessun ActiveX di supporto.
Tip fornito dal Sig. Luciano Busetti
Il codice del progetto Φ presente nella sezione codice del Cd-Rom allegato o sul Web: cdrom.ioprogrammo.net

Alla ricerca del file perduto


Un tip che consente di cercare un qualunque file contenuto in qualunque hard-disk installato nel personal computer. L'intera operazione di ricerca Φ affidata a delle API di sistema in grado di interagire direttamente con il FileSystem di Windows. Per la ricerca Φ anche possibile inserire il carattere jolly "*"Es.: "*.txt"; in output fornisce:
1. Il numero di File trovati
2. Il numero di Cartelle nelle quali ha cercato
3. La grandezza complessiva in Byte dei file trovati
4. Come parametro di ritorno una stringa contenente i percorsi dei file che sono stati trovati separati dal carattere "|"
Tip fornito dal Sig. Alessandro Castaldo

'Creare un Form con:
'un TextBox nominato Text1 per la Cartella di ricerca
'un TextBox nominato Text2 per il nome del file da cercare
'un CommandButton nominato Command1 per avviare la ricerca


Option Explicit

Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA"
(ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA"
(ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function GetFileAttributes Lib "kernel32" Alias
"GetFileAttributesA" (ByVal lpFileName As String) As Long
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long)
As Long


Const MAX_PATH = 260
Const MAXDWORD = &HFFFF

Const INVALID_HANDLE_VALUE = -1
Const FILE_ATTRIBUTE_ARCHIVE = &H20

Const FILE_ATTRIBUTE_DIRECTORY = &H10

Const FILE_ATTRIBUTE_HIDDEN = &H2

Const FILE_ATTRIBUTE_NORMAL = &H80

Const FILE_ATTRIBUTE_READONLY = &H1

Const FILE_ATTRIBUTE_SYSTEM = &H4

Const FILE_ATTRIBUTE_TEMPORARY = &H100



Private Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type


Private Type WIN32_FIND_DATA
    dwFileAttributes As Long
    ftCreationTime As FILETIME
    ftLastAccessTime As FILETIME
    ftLastWriteTime As FILETIME
    nFileSizeHigh As Long
    nFileSizeLow As Long
    dwReserved0 As Long
    dwReserved1 As Long
    cFileName As String * MAX_PATH
    cAlternate As String * 14
End Type



Private Function StripNulls(OriginalStr As String) As String
    If (InStr(OriginalStr, Chr(0)) > 0) Then
        OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
    End If
    StripNulls = OriginalStr
End Function


Private Function FindFilesAPI(ByVal Path As String, ByVal SearchStr As
String, ByRef FileCount As Long, ByRef DirCount As Long, ByRef FoundFiles As
String)


    Dim FileName As String
    Dim DirName As String
    Dim dirNames() As String
    Dim nDir As Long
    Dim i As Long
    Dim hSearch As Long
    Dim WFD As WIN32_FIND_DATA
    Dim Cont As Long


    DoEvents


    If Right(Path, 1) <> "\" Then Path = Path & "\"
    nDir = 0
    ReDim dirNames(nDir)
    Cont = True
    hSearch = FindFirstFile(Path & "*", WFD)
    If hSearch <> INVALID_HANDLE_VALUE Then
        Do While Cont
        DirName = StripNulls(WFD.cFileName)
        If (DirName <> ".") And (DirName <> "..") Then
            If GetFileAttributes(Path & DirName) And
FILE_ATTRIBUTE_DIRECTORY Then
                dirNames(nDir) = DirName
                DirCount = DirCount + 1
                nDir = nDir + 1
                ReDim Preserve dirNames(nDir)
            End If
        End If
        Cont = FindNextFile(hSearch, WFD)
        Loop
        Cont = FindClose(hSearch)
    End If
    hSearch = FindFirstFile(Path & SearchStr, WFD)
    Cont = True
    If hSearch <> INVALID_HANDLE_VALUE Then
        While Cont
            FileName = StripNulls(WFD.cFileName)
            If (FileName <> ".") And (FileName <> "..") Then
                FindFilesAPI = FindFilesAPI + (WFD.nFileSizeHigh * MAXDWORD)
+ WFD.nFileSizeLow
                FileCount = FileCount + 1
                If FoundFiles <> "" Then FoundFiles = FoundFiles & "|"
                FoundFiles = FoundFiles & Path & FileName
            End If
            Cont = FindNextFile(hSearch, WFD)
        Wend
        Cont = FindClose(hSearch)
    End If
    If nDir > 0 Then
        For i = 0 To nDir - 1
            FindFilesAPI = FindFilesAPI + FindFilesAPI(Path & dirNames(i) &
"\", SearchStr, FileCount, DirCount, FoundFiles)
        Next i
    End If


End Function


Public Function FindFile(ByVal SearchPath As String, ByVal SearchStr As
String, ByRef FileCount As Long, ByRef DirCount As Long, ByRef FileSize As
Long) As String
    FileSize = FindFilesAPI(SearchPath, SearchStr, FileCount, DirCount,
FindFile)
End Function

Sub Command1_Click()
    Dim FileSize As Long
    Dim FileCount As Long
    Dim DirCount As Long
    Dim OutMessage As String
    Dim FoundFiles As String


    Screen.MousePointer = vbHourglass
    Command1.Enabled = False
    FoundFiles = FindFile(Text1.Text, Text2.Text, FileCount, DirCount,
FileSize)
    Command1.Enabled = True
    Screen.MousePointer = vbDefault
    FoundFiles = Replace(FoundFiles, "|", vbCrLf)
    OutMessage = OutMessage & FoundFiles & vbCrLf
    OutMessage = OutMessage & vbCrLf
    OutMessage = OutMessage & FileCount & " file trovati in " & DirCount + 1
& " cartelle"
    OutMessage = OutMessage & vbCrLf
    OutMessage = OutMessage & "La dimensione dei file trovati in " &	
Text1.Text & " Φ " & Format(FileSize, "#,###,###,##0") & " Byte"
    MsgBox OutMessage, , "Risultato ricerca"
End Sub