Pagina 1 di 5 1 2 3 ... ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 41
  1. #1

    [Borland C++ Builder] Interfaccia non rettangolare....

    'giorno...

    sapete mica come si possa creare un progetto che invece della solita interfaccia rettangolare di base, possa avere forme particolari? Ad esempio che segue i contorni di un'immagine predisegnata o modellarlo sul momento? VVoVe:

    Come esempio reale mi viene in mente il classico Windows Media Player di Winzozz XP nella modalità "Interfaccia".



    Grazie mille




  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,387
    L'effetto a cui ti riferisci viene spesso utilizzato anche nelle SplashForm, allo scopo di modellare la finestra introduttiva dell'applicazione rendendola trasparente, in alcuni casi "bucata", in corrispondenza di un'immagine caricata al suo interno.

    Ho scritto una procedura simile in Delphi; a grandi linee, si tratta di usare le funzioni API CreateRectRgn e CombineRgn.

    La funzione CreateRectRgn permette di creare una regione rettangolare; la "regione" definisce un'area di disegno entro la quale ogni operazione di disegno, appunto, viene concessa, mentre all'esterno diviene ininfluente.

    La regione può essere associata ad un form affinchè esso venga tracciato seguendo tale regione, quindi la complessità del lavoro si ha nel definire una regione che abbia la forma del bitmap selezionato, ma escludendo le parti che possiedono un colore predeterminato come trasparente.

    Si può iniziare creando una regione rettangolare che abbia le dimensioni del bitmap con la funzione CreateRectRgn; in seguito, si scandisce ogni singolo pixel del bitmap e, quando si individua il colore trasparente, si crea una regione rettangolare separata che abbia le dimensioni e la posizione del pixel; attraverso la funzione CombineRgn si combinano le due regioni sottraendo la regione del pixel da quella del bitmap.

    Ripetendo l'operazione per tutti i pixel del bitmap, si otterrà una regione rettangolare privata di tutte le microregioni interne appartenenti a ciascun pixel che viene decretato come trasparente.

    Attraverso la funzione API SetWindowRgn si può associare la regione risultante alla form, affinchè le operazioni grafiche necessarie al suo tracciamento non escano dall'area definita dalla regione stessa. Inserendo poi un controllo TImage con coordinate (0, 0) nella form con il bitmap stesso, si avrà l'effetto di una form modellata attorno all'immagine che lascia intravedere lo sfondo.

    In Delphi 6 e C++Builder 6 sono presenti anche le proprietà Transparent e TransparentColor per le form, ma utilizzando API funzionanti solo su sistemi Windows 2000 e XP, mentre la soluzione presentata prima lavora su qualsiasi sistema.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  3. #3
    Interessante il primo modo....quindi non fai altro che creare tante regioni trasparenti ove l'immagine è bianca (ad esempio..), poi elimini dalla regione creata con CreateRectRgn(Top,Left,Height,Width); (che sovrappone esattamente la bitmap inserita in TImage) tutte le regioni trasparenti ed infine il form viene settato con quest'ultima regione risultante...

    Come logica mi piace, ma ci sono dei problemi in fase di programmazione....
    1)come si fa a testare pixel a pixel in un TImage? :master:
    2)Questa funzione va richiamata all'evento OnCreate, OnPaint o On Activate?? Io sarei propenso all'OnCreate....ma non ne sono certo...

    Per il resto....grazie!

    Ci provo immediatamente

  4. #4
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,387
    Il concetto di "trasparenza" non è incluso nel concetto di "regione".

    La regione è semplicemente un'area geometrica nella quale sono valide le operazioni di disegno, mentre all'esterno esse non vengono eseguite.

    Si possono creare regioni rettangolari, ellittiche e così via; quella rettangolare è la base di partenza, nel nostro caso.

    Per ciascun pixel da considerare trasparente nel bitmap si deve creare una piccola regione rettangolare delle dimensioni del pixel; tale regione dovrà essere combinata con la regione rettangolare più grande affinchè da quest'ultima venga rimossa la prima. In poche parole, la regione risultante è la regione rettangolare originale privata della regione corrispondente al pixel trasparente. Ripetendo questa operazione per tutti e soli i pixel da considerate trasparenti, la regione finale avrà la forma desiderata della figura.

    Per ottenere le caratteristiche dell'immagine e il colore dei singoli pixel, devi accedere al bitmap contenuto nel controllo TImage attraverso la proprietà Picture.Bitmap; la proprietà Bitmap di tipo TBitmap dispone di una proprietà ScanLine che ti permette di reperire le informazioni sul colore; esiste anche la proprietà Pixels del Canvas, ma è più lenta. Le informazioni su ScanLine le trovi nella Guida in linea.

    Per quanto riguarda l'esecuzione del metodo, io ridefinirei il metodo Loaded della form e inserirei in quel punto la chiamata al metodo che implementa la definizione della regione, poichè tutte le proprietà della form e dei controlli in essa contenuti sono già state caricate.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  5. #5
    Perfetto....diventi sempre più chiaro (ti spieghi sempre meglio) ma complichi sempre di più le cose........... :
    Non ho la più pallida idea di come modificare un metodo (non sapevo nemmeno che si potesse fare fino a qualche minuto fa...) potresti essere così gentile da spendere 2 paroline sull'argomento?

    Grazie mille...



  6. #6
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,387
    La trattazione può essere molto complessa. In Delphi, si ottiene aggiungendo la parola chiave override alla dichiarazione del metodo.

    Ridefinire metodi virtuali è una prerogativa della programmazione orientata agli oggetti e serve ad implementare il concetto di polimorfismo.

    Come ben sai, non conosco così bene C++Builder poichè lavoro in Delphi, quindi non uso C++ bensì il linguaggio Object Pascal (anzi, Delphi), pertanto non mi è possibile fornirti aiuto sulla stesura del codice, se non in quei frangenti in cui si tratta di analizzare la VCL, che è identica sia in C++Builder che in Delphi.

    L'unico ulteriore suggerimento che posso darti è quello di fare una ricerca approfondita su Google riguardo questo argomento, oppure attendere aiuto da qualcun altro che utilizzi C++Builder.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  7. #7
    Sto cercando su google e non solo....con scarsi risultati...continuerò finché non sarò distrutto

    Comunque se non erro il C++Builder ha la possibilità di importare file Delphi(ne sono certo perché il mio proff. era solito scrivere in Delphi le sue applicazioni per poi farcele "modificare"/"utilizzare" sul C++...

    Se stendi qualche riga di codice in Pascal provo a farla girare sul C Builder....mal che vada cercherò di tradurla a mano Che pazzo che sono......



    Davvero molte grazie comunque....ti farò sapere se ne vengo a capo...


  8. #8
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,387
    Originariamente inviato da Ephestus
    Comunque se non erro il C++Builder ha la possibilità di importare file Delphi(ne sono certo perché il mio proff. era solito scrivere in Delphi le sue applicazioni per poi farcele "modificare"/"utilizzare" sul C++...
    Per quanto ne so, sono i file compilati (dcu e bpl) ad essere compatibili, ma non il codice sorgente vero e proprio, che deve essere compilato all'interno di ciascun ambiente.

    Originariamente inviato da Ephestus
    Se stendi qualche riga di codice in Pascal provo a farla girare sul C Builder....mal che vada cercherò di tradurla a mano Che pazzo che sono......
    Ti posto il codice del metodo che si occupa di creare la regione, ma non posso prendermi il tempo di formattarlo in HTML nè di commentarlo in modo approfondito:
    codice:
    function TSplashForm.CreateRegion(Bmp: TBitmap): THandle;
    type
      PRGBArray = ^TRGBArray;
      TRGBArray = array[0..32767] of TRGBTriple;
    var
      x, y, s: Integer;
      Excl: THandle;
      Row: PRGBArray;
      TrColor: TRGBTriple;
    begin
      Bmp.PixelFormat := pf24bit;
      Result := CreateRectRgn(0, 0, Bmp.Width, Bmp.Height);
      with TrColor do
      begin
        rgbtRed := 0;
        rgbtGreen := 255;
        rgbtBlue := 0;
      end;
      for y := 0 to Bmp.Height - 1 do
      begin
        Row := Bmp.ScanLine[y];
        s := -1;
        for x := 0 to Bmp.Width - 1 do
        begin
          if (Row[x].rgbtRed = TrColor.rgbtRed)
           and (Row[x].rgbtGreen = TrColor.rgbtGreen)
           and (Row[x].rgbtBlue = TrColor.rgbtBlue) then
          begin
            if s = -1 then
              s := x;
          end
          else begin
            if s > -1 then
            begin
              Excl := CreateRectRgn(s, y, x + 1, y + 1);
              try
                CombineRgn(Result, Result, Excl, RGN_DIFF);
                s := -1;
              finally
                DeleteObject(Excl);
              end;
            end;
          end;
        end;
        if s > -1 then
        begin
          Excl := CreateRectRgn(s, y, Bmp.Width, y + 1);
          try
            CombineRgn(Result, Result, Excl, RGN_DIFF);
          finally
            DeleteObject(Excl);
          end;
        end;
      end;
    end;
    La funzione accetta come parametro di ingresso il bitmap da utilizzare come modello e restituisce l'handle della regione corrispondente da impostare sul form.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  9. #9
    grazie davvero....adesso con calma me lo studio...ti farò sapere!



  10. #10
    FATTO!!!!!!! ......in parte!

    Queste sono le mie scoperte (mischiando le informazioni trovate in 8 siti diversi....)
    1) Non è necessario modificare il metodo Loaded... basta che all'evento OnCreate venga richiamata la funzione, nella quale è presente SetWindowRgn(Handle,Regione,true); Il true alla fine indica che il programma deve immediatamente ridisegnare la Form.
    2) Al contrario del Delphi il CreateRectRgn non può essere assegnato ad una variabile THandle (non esiste o non me la riconosce), ma bensi ad una variabile HRGN.

    Appena avrò finito tutta la funzione la scriverò qua sotto così i posteri non dovranno dannarsi...



    Moltissime grazie a te Alka....prima o poi erigerò un monumento in tuo onore....


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.