[Borland C++ Builder] Umieszczenie obrazka w TStatusBar

0

Hej,

Rozbudowuję pewną aplikację w Borland C++ Builder 5. Problem polega na tym, że nie potrafię umieścić obrazka GIF w TStatusBar. Mam TStatusBar, a w nim kilka TStatusPanel, których właściwości style ustawione są na psOwnerDraw. Wiem, że muszę teraz skorzystać ze zdarzenia DrawPanel.

void __fastcall T_MainWindow::StatusBar1DrawPanel(TStatusBar *StatusBar,
TStatusPanel *Panel, const TRect &Rect)
{
TImage *i = new TImage(this);
i->Parent = StatusBar;
i->Picture->LoadFromFile("C://obrazek.gif");
}

Oczywiście powyższy kod jest zły, ale jest to już któraś z kolei modyfikacja i zauważyłem, że znacząco zwiększa się bezmyślność kodowania :/ Obrazek się wyświetla, ale strasznie miga i po użyciu CPU widzę, że program zbyt intensywnie pracuje. Czy ktoś z szanownych forumowiczów mogłby kopnąć mnie we właściwym kierunku?

0

że program zbyt intensywnie pracuje

 TImage *i = new TImage(this);

I zżera pamięć bez opamiętania , po każdym wywołaniu StatusBar1DrawPanel
przydzielasz pamięć dla nowego TImage .... to podstawowy błąd
bo jej nie zwalniasz .
Drugi błąd to i->Picture->LoadFromFile("C://obrazek.gif");
też jest wywoływane bez potrzeby za każdym StatusBar1DrawPanel .

StatusBar1DrawPanel jest wywoływana w momencie gdy wymagane jest "odmalowanie"
panel więc może być dosyć często .
Jak to zrobić poprawnie , na razie nie pamiętam ale znajdę ,,,,

0

Dzięki za odpowiedź.

Tak, wiem, że mam tam wyciek. Ale tak jak pisałem, to kod powstały w akcie desperacji. Googlałem intensywnie, ale nie znalazłem jak wstawić obrazek - ikonki z TListImage owszem, były. Skoro ta metoda wywołuje się za każdym razem, gdy zachodzi potrzeba odmalowania paneli (czyli np. przy resize, move), to czy nie da się do tego w ogóle jakoś inaczej podejść?

Jeszcze jedna rzecz mnie zastanawia - skoro ta metoda wykonuje się tylko przy odrysowywaniu, to dlaczego ten obrazek miga ciągle? Nawet kiedy nie dotykam myszy? Z helpa:

The OnDrawPanel event occurs when a status panel needs to be redisplayed—for example, when the user resizes the status bar. The Rect parameter gives the (new) dimensions of the status panel. OnDrawPanel occurs only if the status panel’s Style property is set to psOwnerDraw.

Więc trochę tego migania nie rozumiem...

0

to czy nie da się do tego w ogóle jakoś inaczej podejść?

Da się , trzeba utworzyć jeden TImage (np. w konstruktorze T_MainWindow::)
wskaźnik do niego umieścić w klasie T_MainWindow:: .
Załadować obrazek 1 raz (np.też w konstruktorze T_MainWindow::)
i go wyświetlić . Jeśli znalazłeś przykład z TImageList to będzie pewnie analogicznie ,
więc gdzie problem ?
Użyj TImageList co za różnica ?

0

Kombinowałem w ten sposób. Tylko w jaki sposób go wyświetlić tak, żeby znalazł się w panelu statusbara? Już zrobiłem reverta, więc dokładnego kodu nie wkleję, ale w metodzie OnPanelDraw próbowałem ustawić parenta tego TImage na TStatusPanel, ale wówczas nie wyświetlało się nic.

TImageList nie mogę użyć, bo po pierwsze nie obsługuje niczego poza bmp i ico, a ja potrzebuję mieć przezroczystość. Po drugie obrazek nie jest taki mały jak ikona i tworząc TImageList z poziomu GUI proponuje mi dzielenie tego obrazka na kilkanaście mniejszych. Pisać tego z palca jeszcze nie próbowałem, ale nie sądzę, że zadziała.

0

Rysowanie na pierwszym TStatusPanel :

void __fastcall TForm1::StatusBar1DrawPanel(TStatusBar *StatusBar,
      TStatusPanel *Panel, const TRect &Rect)
{
  if(Panel->Index == 0 )
  {
    if(StatusBar1->ClientHeight >= Image1->Picture->Bitmap->Height)
    {
       StatusBar1->Canvas->Draw(Rect.Left,Rect.Top,Image1->Picture->Bitmap);
    }
  }
}

Mam starą wersje Buildera więc , do TImage mam załadowany orazek w formacie .bmp
jesli załaduję .ico nie jest wyświetlany .
TImage mam normalnie umieszczony na formularzu z Visible == false .
Obrazek jest załadowany do TImage przez Inspektora Obiektów ,,,
wszystko się ładnie wyświetla .

Nie wiem jak gif ,ale mogą być problemy , popróbuj najpierw z .bmp bo na razie oglądają
jakiś debilny film na kompie gdzie mam BCB6 ,,,

Oczywiście TStatusPanel ->Style == psOwnerDraw

Ps. ewent:

StatusBar1->Canvas->StretchDraw(Rect,Image1->Picture->Bitmap);

Jeśli obrazek ma być automatycznie rozciągnięty do rozmiaru panel .

Jeśli nie wyświetli .gif , trzeba konwertować .gif na .bmp ,,,

Co do umieszczenia TImage z animownym gif lub w ogóle z gif to trzeba to rozwiązać inaczej
ale nad tym mogę popracować jutro bo wiadomo ,, filmy :/
może się i da ,,

0

Serdeczne dzięki :) Spróbuję to zastosować u mnie i dam znać, co z tego wyszło :)

0

Masz rację, w ten sposób dla bmp działa, dla gifa nie. Nie łapię dlaczego... I tak już jestem Ci wdzięczny, ale jeśli znalazłbyś jutro chwilkę czasu i udałoby Ci się wpaść na to, jak zrobić gifa, to byłbym jeszcze bardziej wdzięczny :D Teraz mam jakiś punkt zaczepienia, to sam też pokombinuję.

Pozdrawiam!

0

Odkryłem właśnie, że bmp też się nadaje :) Ustawiając transparency na true uzyskuję efekt, na jakim mi zależało. Jeszcze raz wielkie dzięki.

0

Chym trochę pokręciłem z tymi .gif - chodzi o co innego .
Jest Komponent do obsługi .gif .
Uzywałem go w BCB4 dawno temu
Nie aktualne - wpis z licencji

Author: Theodor Kleynhans
Web   : http://www.sulako.com/
E-Mail: [email protected]
Tel   : +27-(0)21-92-7221
Fax   : +27-(0)21-930-8251

GIFImage , ale nie można go umieścić na StatusBar . (przynajmniej bezpośrednio )
W dodatku nie mam dla wer. wyżej BCB4 , ale coś można pokombinować ,,,
Ewent poszukaj jakiegoś komponentu do obsługi .GIF .

Tak właściwie to pod jaką wer. BCB ma być ten program ?
U Ciebie da się załadować do TImage obraz .gif ?

0

Ma być pod BCB5. Da się załadować gifa do TImage. Przy tej czynności dodało mi się do projektu wiele dodatkowych klas, z tego co pamiętam była to implementacja Andersa Melandera. Ale kiedy próbowałem ładować gifa bezpośrednio z kodu, a nie z GUI, to się rzucał, że format pliku jest niepoprawny. Jutro jeszcze przy tym podłubię i dam znać, co z tego wyszło :)

0

Da się załadować gifa do TImage
Zupełnie nie ma takiej potrzeby ....

była to implementacja Andersa Melandera
No i dobra [green] w C++ Builder 5 Vademecum prof jest o nim mowa .
Mi na podstawie tego komponentu (Andersa Melandera) :

TGIFImage for Delphi 5: gifimaged5.zip (76 KB).

http://www.tolderlund.eu/delphi/
Działa [nad przezroczystością nie myslałem jeszcze] i ładuję gifa z pliku :

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//**************
#include <gifimage.hpp>  // !!!!!!!!!!!!!!!!! To prawidłowo powinno zostać
//*****************      przeniesione do Unit1.h
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

TGIFImage* gif_image; // A to umieszczone w klasie Formy
Graphics::TBitmap* bmp_image; // i to
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
   gif_image = new TGIFImage  ;
   bmp_image = new Graphics::TBitmap ;
   
  gif_image->LoadFromFile("MyBitmap.GIF") ; // Załadowanie gif z pliku
  bmp_image->Assign(gif_image); // Komponent "oddaje" gif jako .bmp
  delete gif_image ; // Zrobił co trzeba , więc do widzenia

}
//---------------------------------------------------------------------------

void __fastcall TForm1::StatusBar1DrawPanel(TStatusBar *StatusBar,
      TStatusPanel *Panel, const TRect &Rect)
{
  if(Panel->Index == 0 )
  {
    if(StatusBar1->ClientHeight >= bmp_image->Height)
    {
       //StatusBar1->Canvas->Draw(Rect.Left,Rect.Top,bmp_image);
       StatusBar1->Canvas->StretchDraw(Rect,bmp_image);
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
   delete bmp_image ;
}
//---------------------------------------------------------------------------

Po przekompilowaniu gifimage.pas , wrzucam gifimage.hpp do folderu include/VCL
Do projektu dołączam gifimage.obj i hula gula ,,,
Co do przezroczystości i innych bajerów :
http://melander.dk/delphi/gifimage

Ps. Hi "Po przekompilowaniu" ,,, dobre sobie :-D

chciałem zinstalować to jako komponent pod BCB4 kompilacja poszła ale już instalacja komponentu
w pakiecie nie , nie wnikam bo mnie to nie obchodzi więc dodałem pliki TGIFImage na "piechotę" skoro zostały utworzone potrzebne składniki .
Więc wyszło bez wizualnych klikań , tylko z poziomu kodu .
Plik "MyBitmap.GIF" został utworzony na podstawie mapy bitowej 16 kolor i umieszczony
w katalogu kompilowanej aplikacji .

0

Z przezroczystością można sobie poradzić w ten sposób, że przy konwersji gif'a na bitmapę składać go razem tłem. Jeśli tylko tło się nie zmienia zbyt często, gdyż każda zmiana pociąga za sobą konieczność odmalowania wszystkiego na nowo.

1 użytkowników online, w tym zalogowanych: 0, gości: 1