CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Screenshot z okna

Screenshot z okna

problemy z tworzeniem aplikacji graficznych oraz audio i wideo

Screenshot z okna

Nowy postprzez Arnold_S » środa, 20 lipca 2016, 00:09

Witam!
Mam proste pytanie odnośnie sposobu, który został opisany w temacie "Zrzuty z ekranu" na Waszej stronie. Kod wyglądał następująco:

KOD cpp:     UKRYJ  
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 TCanvas *pCanvas = new TCanvas();
 Graphics::TBitmap *Bmp = new Graphics::TBitmap;

 HWND okno = FindWindow(NULL, "Form1");
 pCanvas->Handle = GetWindowDC(okno);
 TRect oR;
 GetWindowRect(okno, &oR);
 Bmp->Width = oR.Width();
 Bmp->Height = oR.Height();
 Bmp->Canvas->CopyRect(Rect(0, 0, Bmp->Width, Bmp->Height), pCanvas, Rect(0, 0, Bmp->Width, Bmp->Height));

 Bmp->SaveToFile("c:\\ekran.bmp");
 ReleaseDC(0, pCanvas->Handle);

 delete pCanvas, Bmp;
}
 


Czy funkcja GetWindowRect jest obowiązkowa w tym przypadku? Czy zamiast pobierać rozmiaru okna tą funkcją, mogę wypełnić ręcznie obiekt o nazwie "oR"?
na przykład:
KOD cpp:     UKRYJ  
TRect oR;
oR.Left = 0;
oR.Top = 500;
oR.Right = 100;
oR.Bottom = 400;
Czy to oznacza, że byłby to wycinek okna 100x100 pikseli, umieszczony od lewego, górnego rogu okna?
Czy jeśli wypełnię ręcznie obiekt oR to muszę również ręcznie obliczyć oR.Width i oR.Height?
Pytam dlatego, że próbowałem wypełniać tą strukturę ręcznie bo nie chcę aby mój program robił zrzut całego okna, tylko wycinek, który ja zdefiniuję...i nie bardzo mi to wychodzi.
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Mironas » środa, 20 lipca 2016, 09:10

Top powinien być mniejszy niż Bottom.
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
    Windows XPChrome

Re: Screenshot z okna

Nowy postprzez polymorphism » środa, 20 lipca 2016, 10:09

KOD cpp:     UKRYJ  
delete pCanvas, Bmp;

Ta konstrukcja jest nieprawidłowa, bo usuwa jedynie pCanvas. Nieusunięcie Bmp powoduje wyciek pamięci.
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: Screenshot z okna

Nowy postprzez Cyfrowy Baron » środa, 20 lipca 2016, 14:50

To prawda, popełniłem tam błąd. Powinno być:

KOD cpp:     UKRYJ  
delete pCanvas;
delete Bmp;
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: Screenshot z okna

Nowy postprzez Arnold_S » środa, 20 lipca 2016, 23:29

Mironas napisał(a):Top powinien być mniejszy niż Bottom.


Dlaczego mniejszy? Czy Top jest współrzędną lewego-górnego rogu prostokąta? To w takim razie ten prostokąt znajduje się pod osią X czy nad osią X?
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Mironas » czwartek, 21 lipca 2016, 09:28

Na ekranie punkt 0,0 znajduje się w lewym górnym rogu. Możesz porównać ekran do IV ćwiartki układu współrzędnych.

Top - to odległość od górnej krawędzi ekranu do górnej krawędzi prostokąta.

Za ten post autor Mironas otrzymał podziękowanie od:
Arnold_S
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
    Windows XPChrome

Re: Screenshot z okna

Nowy postprzez Arnold_S » wtorek, 26 lipca 2016, 23:38

Jeszcze raz...Mam taki fragment kodu:
Użyłem funkcji GetDC ponieważ nie chcę na screenie mieć górnej "belki" okna, tylko od razu jego zawartość.

KOD cpp:     UKRYJ  
 TCanvas *pCanvas = new TCanvas();
 Graphics::TBitmap *Bmp = new Graphics::TBitmap;
 pCanvas->Handle = GetDC(hWnd);
 TRect prostokat;                                  
 prostokat.Left = 16;                              
 prostokat.Top = 80;                                
 prostokat.Right = 168;                            
 prostokat.Bottom = 90;                            

 Bmp->Width = prostokat.Width();
 Bmp->Height = prostokat.Height();
 Bmp->Canvas->CopyRect(Rect(0, 0, Bmp->Width, Bmp->Height), pCanvas, Rect(0, 0, Bmp->Width, Bmp->Height));

 Bmp->SaveToFile("c:\\screen1.bmp");
 ReleaseDC(0, pCanvas->Handle);
 delete pCanvas;
 delete Bmp;


Problem polega na tym, że jakkolwiek zwiększam (o tę samą wartość) Top i jednocześnie Bottom aby przesuwać tym prostokątem w dół lub w górę otrzymuję screenshot tego samego miejsca na ekranie...jak to możliwe?
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Mironas » środa, 27 lipca 2016, 10:12

Bo w CopyRect jako obszar źródłowy podajesz inne parametry niż ten prostokat.
Zrób tak:
KOD cpp:     UKRYJ  
Bmp->Canvas->CopyRect(Rect(0, 0, Bmp->Width, Bmp->Height), pCanvas, prostokat);

PS
Do wstawiania kodu na forum używaj znaczników CPP.
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
    Windows XPChrome

Re: Screenshot z okna

Nowy postprzez Cyfrowy Baron » środa, 27 lipca 2016, 10:16

KOD cpp:     UKRYJ  
CopyRect(const System::Types::TRect &Dest, TCanvas* Canvas, const System::Types::TRect &Source);


Dest - przeznaczenie - czyli wymiary i położenie obszaru na które kopiujesz obraz
Source - źródło - czyli wymiary i położenie obszaru z którego kopiujesz
Canvbas - płótno na które kopiujesz

Korzystaj z pomocy dołączonej do środowiska. Szybki dostęp - zaznacz funkcję w edytorze i wciśnij na klawiaturze klawisz F1.
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: Screenshot z okna

Nowy postprzez Arnold_S » środa, 27 lipca 2016, 19:54

Wielkie dzięki już to rozkminiam. Mam nadzieję, że mnie nie znienawidzicie za taką ilość pytań. Dla mnie przepisanie właściwego rozwiązania nie załatwia sprawy. Więc drążę temat do puki czegoś nie zrozumiem.

/edit
Wydaje mi się. że wiem na czym polegał mój błąd.
Gdy argumenty wyglądały tak:
KOD cpp:     UKRYJ  
CopyRect(Rect(0, 0, Bmp->Width, Bmp->Height), pCanvas, Rect(0, 0, Bmp->Width, Bmp->Height));
 

to obiekt typu TCanvas został jakby "skonfigurowany" poprzez właściwości obiektu typu TRect (który zwraca funkcja Rect)...ale tam nie było współrzędnych tylko długość boków prostokąta, obliczonych na podstawie współrzędnych obiektu "prostokąt". Dlatego za każdym razem screenshot pokazywał wycinek o właściwych wymiarach ale pobrany z niewłaściwych współrzędnych. ehhhh

Temat następny to fakt, że nie bardzo wiem z czego, do czego kopiujemy i w którym obiekcie znajduje się faktycznie ten obraz. Bardzo bym prosił abyście sprostowali mój pogląd na tą sprawę.
Z opisów w pliku pomocy wynika, że pierwszy argument funkcji CopyRect to nic innego jak obiekt, który zawiera rozmiar kwadratu lub prostokąta. Według ustawień, które posiada zostanie przygotowane miejsce (jego wymiar) w którym znajdzie się obraz.
Drugi argument to wskaźnik pokazujący na obiekt TCanvas i to tutaj - do niego ma zostać "wklejony" fragment obrazu.
Trzeci argument to też obiekt TRect ale zawierający współrzędne, wg. których zostanie "wycięty" fragment obrazu źródła.
Zastanawiam się po co obiekt TCanvas musi zawierać kontekst do przechwytywanego okna, skoro w tym obiekcie umieszczamy fragment obrazu? Czy obj. Tcanvas po prostu zawiera rozmiar przechwytywanego okna i po to jest potrzebny funkcji Copyrect?
Inną rzeczą jest fakt, że "*Bmp" to pointer wskazujący na obiekt klasy TBitmap. "Z niego" wywołujemy funkcję CopyRect. Czy to oznacza, że to ten obiekt po wywołaniu tej funkcji będzie przechowywał wycięty kawałek obrazu okna? ...to w takim razie co z obiektem Tcanvas, na który wskazuje pointer pCanvas?
W którym miejscu i kiedy znajduje się kopiowany fragment obrazu przechwyconego okna? Jakoś nie mogę sobie tego wyobrazić, może dlatego, że jestem początkujący. Proszę możliwie ramowe sprostowanie.
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Mironas » czwartek, 28 lipca 2016, 09:21

Cyfrowy Baron napisał(a):Canvbas - płótno na które kopiujesz

Nie "na które" tylko "z którego". W funkcji CopyRect parametr Canvas wskazuje płótno źródłowe a nie docelowe.

Arnold_S napisał(a):Drugi argument to wskaźnik pokazujący na obiekt TCanvas i to tutaj - do niego ma zostać "wklejony" fragment obrazu.

Jak wyżej. Nie "do niego" tylko "z niego".
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
    Windows XPChrome

Re: Screenshot z okna

Nowy postprzez Arnold_S » piątek, 29 lipca 2016, 23:21

Czy tak bardzo ogólnikowo to:
Obiekt na który pokazuje pCanvas, zawiera kontekst do okna. Czy wówczas w tym obiekcie znajduje się obraz z okna?
Czyli CopyRect kopiuje z tego "płótna" do obiektu TBitmap...tak?
Jeśli tak, to czy przed zapisaniem obrazu do pliku, mogę go w jakiś sposób edytować w TBitmap używając wskaźnika Bmp?
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Cyfrowy Baron » sobota, 30 lipca 2016, 00:33

TCanvas nie jest obiektem, nie posiada żadnej powierzchni. Canvas będący argumentem funkcji CopyRect jest wskaźnikiem na płótno TCanvas z którego kopiujesz. Nie zawiera jeszcze żadnego kontekstu do okna. Najpierw musisz wskazać z ktrego płótna kopiujesz i robisz to tutaj

KOD cpp:     UKRYJ  
 pCanvas->Handle = GetDC(hWnd);


Po przypisaniu do Canvas uchwytu do okna przechwytujesz okno, a funkcja CopyRect kopiuje go na płótno Canvas innego obiektu.

Obiekt typu TBitmap możesz oczywiście edytować. Przejrzyj te przykłady: http://programowanie.cal.pl/cyfbar/grafika.html
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: Screenshot z okna

Nowy postprzez Arnold_S » piątek, 2 września 2016, 23:03

Napotkałem kolejny problem. Niekoniecznie jest to problem związany bezpośrednio z grafiką ale...

Skonstruowałem funkcję i definicję umieściłem w pliku unit1.h. Na samym dole pliku.
W pliku unit1.cpp umieściłem deklarację tej funkcji.
Wszystko było dobrze dopóki nie musiałem przebudować tej funkcji.
Od momentu gdy zaczęła ona przyjmować wskaźnik do obiektu znajdującego się globalnie w pliku cpp. Program zaczął mi strzelać komunikatami AccessViolation, a gdy definicję przeniosłem do pliku cpp na sam koniec i deklarację do pliku unit1.h

KOD cpp:     UKRYJ  
private:        // User declarations
public:         // User declarations
        __fastcall TForm1(TComponent* Owner);
     // tutaj  <-------------------------------
};


....to pojawiają się komunikaty typu: [Linker Error] Unresolved external 'TForm1::compareBars(void *, tagRGBQUAD *, short)' referenced from C:\PROGRAM TESTOWY\UNIT1.OBJ

Proszę podpowiedzcie mi jak to w końcu powinno być.
1. Czy definicje funkcji mogą być w pliku unit1.cpp, a deklaracje muszą być w unit1.h? - jeśli tak to gdzie dokładnie?
2. Czy na odwrót?
3. Czy w 1 przypadku, w pliku unit1.h zaraz pod includami muszę wpisać zmienne globalne z pliku unit1.cpp z dodatkiem extern?

Jaką konwencję należy przyjąć żeby to działało jak trzeba?
Ostatnio edytowano piątek, 2 września 2016, 23:10 przez Cyfrowy Baron, łącznie edytowano 2 razy
Powód: Nie można umieszczać tagów bbcode wewnątrz innych tagów bbcode.
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: Screenshot z okna

Nowy postprzez Cyfrowy Baron » piątek, 2 września 2016, 23:11

Opisałeś to tak, że nie wiem o co chodzi.
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

Następna strona

Powrót do Aplikacje multimedialne, graficzne

Kto przegląda forum

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

cron