Newsgroup: it.comp.lang.c++
Titolo: Sfondo sfumato

Come si fa ?
Stile installazione....

Stile installazione....
Su Windows98 e WinNT 5, l'API GradientFill fa esattamente quel che
desideri.  Non mi pare che esistano funzioni analoghe per versioni
piu` vecchie di Win32, ne` per Windows/CE; in questo caso ci si
dovra` arrabattare "interpolando a mano", ad esempio con una serie
di FillRect per "strisce" da sinistra a destra, con CreateSolidBrush
di COLORREF's che progressivamente passano da un colore verso
l'altro (o analogamente in MFC con delle FillSolidRect).
Alex


Ciao Maurizio, puoi semplicemente creare un'immagine di sfondo
di tuo piacere con un qualsiasi software di grafica.
In seguito salvalo come Bitmap, Metafile o Enhanced-Metafile.
Ora puoi inserire il tuo file immagine come una resource della
tua applicazione e, al momento opportuno, visualizzarlo tramite
le funzioni BitBlt/StretchBlt, PlayMetaFile o PlayEnhMetaFile.
Se la dimensione dell'area su cui vuoi visualizzare il tuo sfondo
é variabile, o comunque non prevedibile, ti consiglio di usare
i Metafile/EnhMetafile visto che sono scalabili.
Inoltre i Metafile/EnhMetafile sono "playabili" direttamente dal file
sorgente creato dal software di grafica.
Saluti, Neil

Io l'ho fatto con il C++Builder ed una applicazione MDI.
Aggiungi al file header della main form le seguenti righe:
private:  // User declarations
  Pointer OriginalClientProc;
  Pointer ClientObjectInstance;
  virtual void __fastcall CreateWnd();
  virtual void __fastcall DestroyWnd();
  virtual void __fastcall ClientProc(TMessage &Msg);
  virtual void __fastcall DrawClientWindow (HDC &Hdc) ;
  void __fastcall WMEraseBkgnd(TWMEraseBkgnd &Msg);
public:  // User declarations
  __fastcall TMDIParent(TComponent* Owner);
BEGIN_MESSAGE_MAP
  MESSAGE_HANDLER(WM_ERASEBKGND,TWMEraseBkgnd,WMEraseBkgnd)
END_MESSAGE_MAP(TForm)
E, quindi, al codice:
void __fastcall TMDIParent::CreateWnd(void)
{
  // crea una main window per il programma
  TForm::CreateWnd();
  // subclassing della finestra MDI client in modo tale da sostituire il
gestore
  // standard dei messaggi con il nostro
  ClientObjectInstance = MakeObjectInstance (ClientProc) ;
  OriginalClientProc = (Pointer) SetWindowLong (ClientHandle, GWL_WNDPROC,
                                                (long)ClientObjectInstance);
}
void __fastcall TMDIParent::ClientProc (TMessage &Msg)
{
  switch (Msg.Msg)
  {
    case WM_ERASEBKGND:
      // intercetta il messaggio di repainting dello sfondo
      DrawClientWindow ((HDC) Msg.WParam) ;
      Msg.Result = true;
      return;
    case WM_HSCROLL:
    case WM_VSCROLL:
      // intercetta il messaggio di scrolling dell'area
      Msg.Result = CallWindowProc ((FARPROC)OriginalClientProc,ClientHandle,
                                    Msg.Msg, Msg.WParam, Msg.LParam);
      InvalidateRect (ClientHandle, 0, true) ;
      break ;
    default:
      // passa tutti gli altri messaggi alla procedura originale
      Msg.Result = CallWindowProc ((FARPROC)OriginalClientProc,ClientHandle,
                                    Msg.Msg, Msg.WParam, Msg.LParam);
  }
}
void __fastcall TMDIParent::DrawClientWindow (HDC &Hdc)
{
  // disegna un gradiente blue sullo sfondo
  const int    NumGradients = 64;   // number of shading levels
  const TColor StartColor = clBlue; // colore iniziale
  TRect rect ;
  ::GetClientRect (ClientHandle, (RECT *) &rect) ;
  // siccome disegnare un gradiente e' un'operazione lenta, usiamo
  // la tecnica del memory-buffer
  Graphics::TBitmap *MemBitmap = new Graphics::TBitmap;
  MemBitmap->Width = rect.Right - rect.Left;
  MemBitmap->Height= rect.Bottom- rect.Top;
  MemBitmap->Canvas->Brush->Style = bsSolid;
  MemBitmap->Canvas->Brush->Color = clBlack;
  MemBitmap->Canvas->FillRect(Rect(0,0, MemBitmap->Width,
MemBitmap->Height));
  // calcola l'altezza di ogni sezione del gradiente
  int GradientHeight = MemBitmap->Height / NumGradients;
  // calcola l'intensita di ogni colore RGB
  int InitialRed   = GetRValue(StartColor);
  int InitialGreen = GetGValue(StartColor);
  int InitialBlue  = GetBValue(StartColor);
  int RedIncrement  = (InitialRed + 1)  / NumGradients;
  int GreenIncrement= (InitialGreen + 1)/ NumGradients;
  int BlueIncrement = (InitialBlue + 1) / NumGradients;
  TColor FillColor;
  // disegna le sezioni del gradiente
  for (int j=0;j< NumGradients;j++)
  {
    rect.Bottom = rect.Top + GradientHeight;
    FillColor = (TColor) RGB( InitialRed   -(RedIncrement * j),
                              InitialGreen -(GreenIncrement* j),
                              InitialBlue  -(BlueIncrement * j));
    MemBitmap->Canvas->Brush->Color = FillColor;
    MemBitmap->Canvas->FillRect(rect);
    rect.Top += GradientHeight;
  }
  // copia i pixels sullo schermo
  ::BitBlt(Hdc,0,0,MemBitmap->Width, MemBitmap->Height,
           MemBitmap->Canvas->Handle,0,0,SRCCOPY);
  delete MemBitmap;
}
void __fastcall TMDIParent::DestroyWnd ()
{
  SetWindowLong (ClientHandle, GWL_WNDPROC, (long) OriginalClientProc) ;
  FreeObjectInstance (ClientObjectInstance) ;
  TForm::DestroyWnd();
}
void __fastcall TMDIParent::WMEraseBkgnd(TWMEraseBkgnd &Msg)
{
  Msg.Result = false;  // dice a windows di non occuparsi del repaint dello
sfondo: lo facciamo noi ;-P
}
--
Byez.
Stefano Tempesta
s.tem...@usa.net
http://tempesta.freeweb.org
--------------------------------
(-: To "shut down" your system, type "WIN" :-)
(-: Windows VirusScan 1.0 - "Windows found: Remove it? (Y/N)" :-)