ForumFree

Stampe, ....

« Older   Newer »
  Share  
TecnoBobbit
icon9  view post Posted on 12/4/2007, 12:48




...buondìgiorno.....

inizio questa nuova discussione per far fronte ad un problema/dubbio che ho da anni:

Esiste il modo di stampare il contenuto di vari editbox SENZA dover passare per forza attraverso un DB?

nel senso.....devo stampare una decina di editbox SOPRA un'immagine...FuzzyReport mi permette di fare questo, basta che nel report metta come sfondo l'immagine e poi piazzi il rettangolo per il testo....ma il problema è che il testo per riempire il rettangolo di Fuzzy è preso da un campo DB.....io vorrei qualcosa che prenda direttamente dal form..........utopia?...richiesta assurda?....non riesco a trovare niente di simile.....
:alienff:
 
Top
DigitX32
view post Posted on 12/4/2007, 17:08




Uhm, non so se ho interpretato correttamente la tua richiesta, comunque elenco un pò di nozioni che possono avvicinarsi alla questione:

Una cosa che utilizzo di solito è l'esportazione del contenuto di una form o di un controllo posto su di essa (o una regione) in immagine: per far questo uso la procedura seguente che prende in input un TControl e restituisce una TBitmap

CODICE
procedure ExportControl(
               Control: TControl;
               var bmp: tbitmap
               );
var
 //handle al Device Context dello schermo
 ScreenDC: HDC;
 //rettangolo definito dal controllo Control
 //facendo riferimento a tutto lo schermo
 ControlRect: TRect;

 ControlRectTop, ControlRectLeft: Cardinal;

begin
 //alcune nozioni di base:
 //1) control.clientorigin: è un TPoint che rappresenta le coordinate del punto
 //in alto a sinistra del controllo Control facendo riferimento a tutto lo schermo

 ControlRectTop := Control.ClientOrigin.Y;
 ControlRectLeft := Control.ClientOrigin.X;

 ControlRect := Bounds(
                   ControlRectLeft,
                   ControlRectTop,
                   Control.ClientWidth,
                   control.ClientHeight
                   );

 //imposto le dimensioni della bitmap di destinazione
 bmp.Width := ControlRect.Right - ControlRect.Left;
 bmp.Height := ControlRect.Bottom - ControlRect.Top;

 //ottengo l'handle al Device Context dello schermo
 ScreenDC := GetDC(0);

 //eseguo la copia dei bit della regione di schermo
 //occupata dal mio controllo Control nella bitmap bmp di destinazione
 //Sorgente = area di schermo
 //Destinazione = bitmap
 try
   bitblt(
     bmp.Canvas.Handle, //handle al Device Context della bitmap di destinazione
     0, //left di destinazione
     0, //top di destinazione
     bmp.Width, //ampiezza di destinazione
     bmp.Height, //altezza di destinazione
     ScreenDC,  //handle al Device Context sorgente (ossia lo schermo)
     ControlRect.Left, //left sorgente
     ControlRect.Top, //top sorgente
     SRCCOPY  //copio semplicemente i bit dell'area sorgente nell'area destinazione
     );
 finally
   ReleaseDC(0, ScreenDC);
 end;

end;


Un esempio di utilizzo potrebbe essere il seguente

CODICE
//salvo il contenuto di un controllo di classe TGroupBox in una immagine bitmap su disco
procedure TForm1.Button1Click(Sender: TObject);
var
 bmp:tbitmap;
begin
   bmp:=tbitmap.Create;
   ExportControl(GroupBox1, bmp);

   Bmp.SaveToFile ( 'C:\Test.bmp');

   bmp.free;

end;


Se a questo punto vuoi stampare la bitmap invece di salvarla su disco puoi ricorrere alla seguente procedura

CODICE
procedure DrawImage(Canvas: TCanvas; DestRect: TRect; ABitmap: TBitmap);
var
 Header, Bits: Pointer;
 HeaderSize: DWORD;
 BitsSize: DWORD;
begin
 GetDIBSizes(ABitmap.Handle, HeaderSize, BitsSize);
 Header := AllocMem(HeaderSize);
 Bits := AllocMem(BitsSize);
 try
   GetDIB(ABitmap.Handle, ABitmap.Palette, Header^, Bits^);
   StretchDIBits(Canvas.Handle, DestRect.Left, DestRect.Top,
     DestRect.Right, DestRect.Bottom,
     0, 0, ABitmap.Width, ABitmap.Height, Bits, TBitmapInfo(Header^),
     DIB_RGB_COLORS, SRCCOPY);
 finally
   FreeMem(Header, HeaderSize);
   FreeMem(Bits, BitsSize);
 end;
end;


La DrawImage consente di disegnare una bitmap su qualsiasi canvas: se si vuole stampare basta disegnare sul canvas della stampante,
ossia Printer.Canvas;

Ci si può quindi creare una procedura di stampa bitmap tramite la DrawImage appena definita:

CODICE
uses
 ... Printers ... //occorre includere la unit Printers

...

procedure PrintBMP(bmp:TBitmap; ZoomPercent: Integer);
//con ZoomPercent=100, la bmp sarà stampata sull'intera pagina
var
 relHeight, relWidth: integer;
begin
 Screen.Cursor := crHourglass;
 Printer.BeginDoc;
 with bmp do
 begin
   if ((Width / Height) > (Printer.PageWidth / Printer.PageHeight)) then
   begin
     // adatto la bitmap all'ampiezza della pagina di stampa
     relWidth := Printer.PageWidth;
     relHeight := MulDiv(Height, Printer.PageWidth, Width);
   end
   else
   begin
     // adatto la bitmap all'altezza della pagina di stampa
     relWidth  := MulDiv(Width, Printer.PageHeight, Height);
     relHeight := Printer.PageHeight;
   end;
   relWidth := Round(relWidth * ZoomPercent / 100);
   relHeight := Round(relHeight * ZoomPercent / 100);
   DrawImage(Printer.Canvas, Rect(0, 0, relWidth, relHeight), bmp);
 end;
 Printer.EndDoc;
 Screen.cursor := crDefault;
end;


La procedura PrintBMP prende in input una bitmap ed una percentuale di zoom della medesima per la stampa

Behh, in ogni caso, anche se non centravano niente con la tua richiesta, ho messo un pò di carne al fuoco

Edited by DigitX32 - 12/4/2007, 18:34
 
Top
TecnoBobbit
view post Posted on 12/4/2007, 18:24




uhmm......si...ho capito cosa s'intende fare con queste procedure.....diciamo che POTREI anche farlo così...ma mi sa di massacro :P

...per dare una spiegazione migliore del mio problema mi aiuterò con un esempio...

poniamo che io debba stampare una scheda per D&D...come mostra quest'immagine.. image


i campi evidenziati sono dinamici (il nome, i pf, le statistiche ecc ecc)...

La mia applicazione ha diversi editbox, ognuno corrispondente ad uno dei campi dinamici della scheda...
il mio problema è:

Come stampo i contenuti degli EditBox ESATTAMENTE al loro corrispondente posto sulla scheda?..

L'unica maniera che ho trovato è:
- Scannerizzare la scheda
- Installare FuzzyReport
- Creare un nuovo report con sfondo l'immagine scannerizzata
- Piazzare i rettangoli nei posti giusti.

L'unica pecca di Fuzzy è che i rettangoli DEVONO corrispondere PER FORZA ad un campo DB....quindi....devo obbligatoriamente usare un db nella mia applicazione...anche se non ne ho bisogno....


spero di essere stato + chiaro di prima image
 
Top
DigitX32
view post Posted on 12/4/2007, 22:24




Io mi sono installato il pacchetto FuzzyReport all'indirizzo

http://www2.samatel.com/icld/upload/dl/Com...e/Fuzzy_Report/

In passato avevo lavorato con FreeReport (sempre la stessa minestra condita in modo leggermente diverso) e mi ricordo d'aver usato l'evento OnGetValue per settare i valori non corrispondenti a campi di una tabella in un db

Dopo aver dato un'occhiata al manuale pdf downloadabile sempre all'url sopra, ho fatto le seguenti operazioni:

1) mi creo un nuovo progetto in Delphi e butto sulla form il componente TfrReport
2) pulsante destro sul componente --> Disegna Report, ed ecco che mi compare il modulo per disegnare il report: metto 3 rettangoli (ne posso mettere anche 20, non cambia niente), lì sopra direttamente senza crearmi bande varie
3) A questo punto salvo ed esco
4) pulsante destro sul componente --> Editor di Variabili: creo una nuova categoria (con il pulsante in basso Nuova Categoria) e la chiamo ElencoVars (l'avrei potuta chiamare anche Paperini). A questo punto vado ad aggiungere 3 variabili alla categoria in questione: ne aggiungo 3 perchè sono 3 i rettangoli che ho messo nel report e andrò ad assegnare ogni variabile come valore di un rettangolo; chiamo le variabili con i nomi Var_1, Var_2, VCiao.
5) Riapro il modulo di design del report corrispondente: su ogni rettangolo faccio le seguenti operazioni:
pulsante destro --> modifica, mi si apre l'editor di testo, click sul pulsante Variabile, mi si apre l'editor delle Variabili, Categoria "ElencoVars" e seleziono una delle variabili sotto (Var_1, Var_2, VCiao). Se ad esempio ho associato Var_2 al primo rettangolo, ciò significa che il contenuto di tale rettangolo sarà il valore che andrò ad assegnare alla variabile Var_2
6) Assegno i valori alle variabili: semplicissimo, implemento l'evento OnGetValue del componente TfrReport nella seguante maniera

CODICE
procedure TForm1.frReport1GetValue(const ParName: String;
 var ParValue: Variant);
begin

 if ParName = 'Var_1' then
   ParValue := 'Giorgio'; //questo valore verrà visualizzato nel rettangolo a cui ho assegnato il testo [Var_1]
 if ParName = 'Var_2' then
   ParValue := 'Rossini';//questo valore verrà visualizzato nel rettangolo a cui ho assegnato il testo [Var_2]

 if ParName = 'VCiao' then
   ParValue := 'programmatore';//questo valore verrà visualizzato nel rettangolo a cui ho assegnato il testo [VCiao]

end;



In pratica metti tanti rettangoli quante sono le informazioni che vuoi visualizzare poi ti crei tante variabili quanti sono i rettangoli in questione: ad ogni rettangolo assegni una delle variabili in questione; poi tramite l'evengo OnGetValue di TfrReport di definisci i valori delle variabili


 
Top
TecnoBobbit
view post Posted on 13/4/2007, 09:36




sapevo di cheidere nel posto giusto :D

...funziona tutto alla perfezione!!...

Ancora una volta, GRAZIE MILLE.....ho risolto un problema che avevo da un bel po d tempo

PS: ...sinceramente non ho MAI nemmeno visto il menu VARIABILI.. :wacko:

 
Top
DigitX32
view post Posted on 13/4/2007, 12:51




Anche per me a suo tempo (all'incirca il 2002) con FreeReport era stato un pò ostico ed infatti mi ricordo che, alla domanda di inserire un semplice campo che facesse una semplice distinzione di tipologie e che non veniva prelevato dal db, avevo risposto immediatamente con un secco "si si , certo non ci vuol niente" e poi ci son stato su una giornatina intera.
 
Top
5 replies since 12/4/2007, 12:48   136 views
  Share