CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - LibZPlay - Wykres, słupki, Graph - pytanie.

LibZPlay - Wykres, słupki, Graph - pytanie.

problemy z tworzeniem aplikacji graficznych oraz audio i wideo

LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez Peter_M » sobota, 19 października 2019, 20:39

Witam, kontynuuję temat libki multimedialnej LibZPlay(dostępna jest tu: http://libzplay.sourceforge.net/) Libka ta potrafi wyświetlać graph FFT prostymi metodami, ogólnie piszę aplikację multimedialną o nazwie MP3Play, na własne potrzeby, aby podszkolić się z programowania w C++ Builderze, oraz pod szlifować sobie programowanie, ponieważ nie ukrywam że jest to dziedzina interesująca.
Jak już wspomniałem potrafi ona wygenerować graph aby w rytm muzyki leciały sobie słupki, oscylogram itd.
Do tego celu napisałem sobie aplikację pomocniczą, aby testować funkcje libki LibZPlay, by nie psuć aplikacji natywnej. Do rzeczy do tego celu wykorzystałem komponent TPaintBox, aby móc narysowac graph, z tym że nie było by nic z tym dziwnego, gdyby nie jeden szczegół, kiedy mam wyświetlony graph w komponencie, To forma jest jakby zamrożona, i wygląda w ten sposób jak na załączonym obrazku:

BaeQhCI.png


wystarczy przenieść w inne miejsce, Forma jak by się odświeża ale nie podświetlają się buttony, są jakby zamrożone, ale można uruchamiać testową muzykę, zatrzymywać itd.
O to kod odpowiedzialny za graph:
KOD cpp:     UKRYJ  
void __fastcall TForm1::PaintBox1Paint(TObject *Sender)
{
  TRect Rect;
  Rect.Top = 0;
  Rect.Bottom = 250; //wyznaczyłem pola gdzie ma być rysowany graph.
  Rect.Left = 0;
  Rect.Right = 250;
  Player->SetFFTGraphParam(gpGraphType, gtAreaLeftOnTop); // ustawiłem jak ma wyglądać graph
  Player->SetFFTGraphParam(gpHorizontalScale, gsLinear); // tu tak samo, korzystałem z pomocy dokumentacji.
  Player->DrawFFTGraphOnHDC(PaintBox1->Canvas->Handle, 0, 0, 250, 250); // wziąłem uchwyt canvas, ponieważ bez niego to już kompletna klapa. Funkcja pobiera jak widać 4 parametry Uchwyt, X, Y, Width, Height.
  Sleep(50);
  PaintBox1->Invalidate();
}


Jak mogę się pozbyć tego problemu? Podejrzewam, że problem jest w uchwycie, ponieważ nie mogę znaleźć skąd mogę pobrać HDC, lub HWND komponentu TPaintBox.
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Avatar użytkownika
Peter_M
Bladawiec
Bladawiec
 
Posty: 41
Dołączył(a): poniedziałek, 3 grudnia 2018, 23:36
Podziękował : 6
Otrzymał podziękowań: 0
System operacyjny: Windows 10
Kompilator: RAD Studio 10.3.2
SKYPE: pikus_666
Gadu Gadu: 68554272
    WindowsChrome

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez Cyfrowy Baron » niedziela, 20 października 2019, 10:10

Wstaw polecenie Application->ProcessMessages(), żeby odświeżyć kolejkę komunikatów. Sleep powoduje zamrożenie aplikacji, czyli nie jest to taki najlepszy pomysł.

KOD cpp:     UKRYJ  
  Sleep(50); // <-- lepiej to usunąć.
  PaintBox1->Invalidate();
 Application->ProcessMessages();
}


TPaintBox w odróżnieniu np. od Image nie posiada własnej powierzchni na której można rysować, korzysta z powierzchni na której się znajduje. To taki zbiór narzędzi a nie obiekt z powierzchnią, dlatego nie pobierzesz do niego uchwytu.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4731
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 445
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez polymorphism » niedziela, 20 października 2019, 10:25

Kontrolka TPaintBox nie ma uchwytu HWND, bo to nie jest okno. Ta klasa definiuje obszar okna-rodzica, w którym można rysować swoje rzeczy. Pobranie uchwytu z Canvas jest poprawne. Wywal to Sleep, bo metoda rysująca powinna być szybka, bez zbędnych zamulaczy (wywołania SetFFTGraphParam i Invalidate też bym wywalił). Zrób timer, który będzie wymuszał odmalowanie paintboxa.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2263
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 210
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez Cyfrowy Baron » niedziela, 20 października 2019, 10:53

Po zastanowieniu - odświeżenie kolejki komunikatów (Application-ProcessMessages()) nic nie da, bo musi wystąpić jakieś zdarzenie, które wymusi ponowne odrysowanie PaintBox.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4731
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 445
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows 7Firefox

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez Peter_M » niedziela, 20 października 2019, 20:25

polymorphism napisał(a):Wywal to Sleep, bo metoda rysująca powinna być szybka, bez zbędnych zamulaczy (wywołania SetFFTGraphParam i Invalidate też bym wywalił). Zrób timer, który będzie wymuszał odmalowanie paintboxa.

Sleep może i można wyrzucić, ale funkcji SetFFTGraph już nie, ponieważ one definiują, jak ma wyglądać wykres, próbowałem bez funkcji invalidate ale słupki nie skakały.
Nie będzie przeszkód jak by miało wyglądać w kodzie takie wywołanie, chodzi mi o przykład nie o gotowiec, będę wdzięczny.
Cyfrowy Baron napisał(a):Po zastanowieniu - odświeżenie kolejki komunikatów (Application-ProcessMessages()) nic nie da, bo musi wystąpić jakieś zdarzenie, które wymusi ponowne odrysowanie PaintBox.

Spróbuję najpierw usunąć funkcję Sleep(50);
Cyfrowy Baron napisał(a):Wstaw polecenie Application->ProcessMessages(), żeby odświeżyć kolejkę komunikatów. Sleep powoduje zamrożenie aplikacji, czyli nie jest to taki najlepszy pomysł.

KOD cpp:     UKRYJ  
  Sleep(50); // <-- lepiej to usunąć.
  PaintBox1->Invalidate();
 Application->ProcessMessages();
}


TPaintBox w odróżnieniu np. od Image nie posiada własnej powierzchni na której można rysować, korzysta z powierzchni na której się znajduje. To taki zbiór narzędzi a nie obiekt z powierzchnią, dlatego nie pobierzesz do niego uchwytu.

Faktycznie, dlatego pobrałem uchwyt do Canvas, Natomiast przy komponencie TImage nie mogłem wogóle wywołać zdarzenia onPaint, chyba że masz inny pomysł żeby rysować graph na komponencie TImage, używając właśnie biblioteki LibZPlay.
Avatar użytkownika
Peter_M
Bladawiec
Bladawiec
 
Posty: 41
Dołączył(a): poniedziałek, 3 grudnia 2018, 23:36
Podziękował : 6
Otrzymał podziękowań: 0
System operacyjny: Windows 10
Kompilator: RAD Studio 10.3.2
SKYPE: pikus_666
Gadu Gadu: 68554272
    WindowsChrome

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez polymorphism » niedziela, 20 października 2019, 20:38

ale funkcji SetFFTGraph już nie

Nie chodziło mi o to, by wywalić tę funkcję zupełnie z programu, tylko usunąć ją z funkcji rysującej, bo nie ma sensu co każde odmalowanie wykresu ustawiać parametry rysowania, które można ustawić raz, gdzieś na początku.

próbowałem bez funkcji invalidate ale słupki nie skakały.

Użyłeś timera, jak sugerowałem?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2263
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 210
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    UbuntuFirefox

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez Peter_M » niedziela, 20 października 2019, 20:50

polymorphism napisał(a):Nie chodziło mi o to, by wywalić tę funkcję zupełnie z programu, tylko usunąć ją z funkcji rysującej, bo nie ma sensu co każde odmalowanie wykresu ustawiać parametry rysowania, które można ustawić raz, gdzieś na początku.

To dam funkcje w konstruktor formy głównej.
polymorphism napisał(a):Użyłeś timera, jak sugerowałem?
Nie jeszcze nie.
Avatar użytkownika
Peter_M
Bladawiec
Bladawiec
 
Posty: 41
Dołączył(a): poniedziałek, 3 grudnia 2018, 23:36
Podziękował : 6
Otrzymał podziękowań: 0
System operacyjny: Windows 10
Kompilator: RAD Studio 10.3.2
SKYPE: pikus_666
Gadu Gadu: 68554272
    WindowsChrome

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez polymorphism » niedziela, 20 października 2019, 21:12

Skoro nie użyłeś timera, to dlaczego słupki miałyby skakać?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2263
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 210
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    UbuntuFirefox

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez Peter_M » niedziela, 20 października 2019, 22:40

Właśnie teraz użyłem Komponent Timer. Zadziałało, interwał zmniejszyłem do maximum czyli interwał = 10, płynnie chodzi.
Wpisałem w zdarzenie OnTimer metodę odpowiedzialną za rysowanie Graphu i w zdarzeniu onPaint dałem tylko funkcję Timer1->Enabled.
Docelowo chcę dodać do aplikacji CheckBoxy aby móc customizować Graph, ponieważ ma on dosyć sporo opcji i szkoda je likwidować.
KOD cpp:     UKRYJ  
void __fastcall TForm1::PaintBox1Paint(TObject *Sender)
{
  TRect Rect;
  Rect.Top = 0;
  Rect.Bottom = 250;
  Rect.Left = 0;
  Rect.Right = 250;
  Timer1->Enabled = true;

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

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
   Player->DrawFFTGraphOnHDC(PaintBox1->Canvas->Handle, 0, 0, 250, 250);
}

Tak to wygląda:
Bez tytułu.png
Nie masz wystarczających uprawnień, aby zobaczyć pliki załączone do tego postu.
Avatar użytkownika
Peter_M
Bladawiec
Bladawiec
 
Posty: 41
Dołączył(a): poniedziałek, 3 grudnia 2018, 23:36
Podziękował : 6
Otrzymał podziękowań: 0
System operacyjny: Windows 10
Kompilator: RAD Studio 10.3.2
SKYPE: pikus_666
Gadu Gadu: 68554272
    WindowsChrome

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez polymorphism » poniedziałek, 21 października 2019, 10:36

Jeśli metoda TForm1::PaintBox1Paint jest obsługą zdarzenia TPaintBox::OnPaint, to to jest pomieszanie z poplątaniem.

Tak bym zrobił:
KOD cpp:     UKRYJ  
void __fastcall TForm1::PaintBox1Paint(TObject* Sender)
{
    Player->DrawFFTGraphOnHDC(PaintBox1->Canvas->Handle, 0, 0, 250, 250);
}

void __fastcall TForm1::Timer1Timer(TObject* Sender)
{
    PaintBox1->Repaint(); // chociaż jakby zadziałało z Invalidate, to lepiej zamienić
}


(...) i w zdarzeniu onPaint dałem tylko funkcję Timer1->Enabled.

W zdarzeniach rysujących powinieneś tylko rysować, i nic więcej nie robić. Timer możesz aktywować w innych miejscach (chyba nawet z poziomu właściwości kontrolki w designerze).
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2263
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 210
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez Peter_M » poniedziałek, 21 października 2019, 16:03

Tak zdarzenie onPaint jest przypisane do paintbox1. Początkowo miałem tę metodę w zdarzeniu onPaint tyle że, powodowała ona jakby zamrożenie całej aplikacji pomocniczej(jest w pierwszym poście). Obecnie gdy jest w zdarzeniu timera wszystko działa, ale pewnie jest to zła metoda, tyle że nie mam pojęcia dlaczego kiedy mam to napisane w zdarzeniu onPaint komponentu Paintbox1 wszystko diabli bierze.
Tak timer mogę uruchomić nawet w konstruktorze formy lub w designerze.
polymorphism napisał(a):Jeśli metoda TForm1::PaintBox1Paint jest obsługą zdarzenia TPaintBox::OnPaint, to to jest pomieszanie z poplątaniem.

Tak bym zrobił:
KOD cpp:     UKRYJ  
void __fastcall TForm1::PaintBox1Paint(TObject* Sender)
{
    Player->DrawFFTGraphOnHDC(PaintBox1->Canvas->Handle, 0, 0, 250, 250);
}

void __fastcall TForm1::Timer1Timer(TObject* Sender)
{
    PaintBox1->Repaint(); // chociaż jakby zadziałało z Invalidate, to lepiej zamienić
}


(...) i w zdarzeniu onPaint dałem tylko funkcję Timer1->Enabled.

W zdarzeniach rysujących powinieneś tylko rysować, i nic więcej nie robić. Timer możesz aktywować w innych miejscach (chyba nawet z poziomu właściwości kontrolki w designerze).

Ehh, No tak, Ja to mam głowę, pisałem dość późno i takiej błahostki ... Teraz też działa super.
Avatar użytkownika
Peter_M
Bladawiec
Bladawiec
 
Posty: 41
Dołączył(a): poniedziałek, 3 grudnia 2018, 23:36
Podziękował : 6
Otrzymał podziękowań: 0
System operacyjny: Windows 10
Kompilator: RAD Studio 10.3.2
SKYPE: pikus_666
Gadu Gadu: 68554272
    LinuxChrome

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez Peter_M » poniedziałek, 21 października 2019, 22:18

Witam, chciałem dopytać jeszcze o jedną kwestię, Ponieważ mam jeden parametr dla mnie niezrozumiały.
Jest nim: gpBgBitmapHandle, przyjmuje wartość int. wg mojego rozumowania, parametr ten potrafi załadować własną bitmapę jako tło grapha, tylko pytanie teraz mam takie. W jaki sposób mogę dostosować Komponent OpenPicturedialog?
Próbowałem metodą StrToInt, ale niewiele z tego uzyskałem, oraz metodą OpenPictureDialog->Execute(); Dialog się uruchamia ale, żadna bitmapa się nie ładuje.
Avatar użytkownika
Peter_M
Bladawiec
Bladawiec
 
Posty: 41
Dołączył(a): poniedziałek, 3 grudnia 2018, 23:36
Podziękował : 6
Otrzymał podziękowań: 0
System operacyjny: Windows 10
Kompilator: RAD Studio 10.3.2
SKYPE: pikus_666
Gadu Gadu: 68554272
    WindowsChrome

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez Mironas » wtorek, 22 października 2019, 08:26

Nie używałem tego komponentu, ale przypuszczam, że musisz załadować obraz tła (bitmapę) do
Graphics::TBitmap* BMP;
a następnie do tego parametru podać BMP->Handle
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 467
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 22
Otrzymał podziękowań: 66
System operacyjny: Windows 10
Kompilator: C++Builder 10.2 Tokyo
TMS Components Pack
Gadu Gadu: 0
    WindowsChrome

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez Peter_M » wtorek, 22 października 2019, 10:51

Też tym wariantem się kierowałem. Ponieważ chciałem to połączyć z komponentem OpenPictureDialog.
Ale spróbuję jeszcze raz to okodować.
swoją drogą. Sama biblioteka jest bardzo prosta w użyciu i nie wymaga żadnych skomplikowanych algorytmów, a w prosty sposób pomaga zrobić naprawdę kawał solidnego odtwarzacza multimedialnego.
Avatar użytkownika
Peter_M
Bladawiec
Bladawiec
 
Posty: 41
Dołączył(a): poniedziałek, 3 grudnia 2018, 23:36
Podziękował : 6
Otrzymał podziękowań: 0
System operacyjny: Windows 10
Kompilator: RAD Studio 10.3.2
SKYPE: pikus_666
Gadu Gadu: 68554272
    LinuxChrome

Re: LibZPlay - Wykres, słupki, Graph - pytanie.

Nowy postprzez polymorphism » wtorek, 22 października 2019, 10:54

Próbowałem metodą StrToInt

A jakiż to string zmieniałeś na inta?

TOpenPictureDialog od TOpenDialog różni się tym, że masz podgląd grafiki w trakcie wyboru pliku.

Jakoś tak:
KOD cpp:     UKRYJ  
std::unique_ptr<TBitmap> bmp; // pole klasy
...

if (OpenPictureDialog1->Execute()) {
    bmp = std::make_unique<TBitmap>();
    bmp->LoadFromFile(OpenPictureDialog1->FileName);
    Player->SetFFTGraphParam(gpBgBitmapHandle, reinterpret_cast<int>(bmp->Handle));
}
 

Swoją drogą ta funkcja jest źle napisana, bo drugi parametr nie powinien być typu int, jeśli przekazywane mają być jakieś uchwyty. W Windowsie uchwyty są typu wskaźnikowego, a int może być (i często jest) 32-bitowy, nawet wtedy gdy kompilacja jest w 64-bitach. Tutaj powinien być typ intptr_t lub nawet windowsowy LONG_PTR (w sumie biblioteka definiuje typ System::IntPtr).
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2263
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 210
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Aplikacje multimedialne, graficzne

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 3 gości

cron