|
[ Hyperborejac @ 18.01.2006. 21:59 ] @
| Jednu stvar nikako da uradim u VB.NET-u. Naime, pretpostavimo da nesto crtam po formi (krugove, elipse i slicno). Nakon toga minimizujem formu i ponovo je aktiviram iz taskbara. Sve sto sam crtao nestane. Pitanje je : Kako da ostane, a da se ne iscrtava ponovo (ovo je jako vazan uslov).
Najvise bi mi odgovaralo resenje kada bi mogao da sacuvam izgled ekrana u bitmapu (pravougaonik, sliku) oblika me.location.x, me.location.y, me.width, me.height, i nakon vracanja prosto 'nalijepim' tu bitmapu preko forme (preko me.backgroundImage, npr.). Da li je ovo moguce uraditi i kako?
|
[ kovach @ 19.01.2006. 01:51 ] @
Moguce je uraditi... uz naravno malo volje... :)
Pre svega reci da li koristis naredbu Application.DoEvents() jer je ovo o cemu ti govoris veoma karakteristicno kao jedan od njenih sporednih efekata pogotovo ako se ne upotrebi na pravi nacin a neretko cak i kada je pravlino iskoriscena...
Druga stvar.... ti kada odradis to o cemu govoris i stavis sliku kao background image najverovatnije ce ti ona ostati iza svih ostalih objekata na formi tipa dugmad i slicne stvari... mozda toga na tvojoj formi nema pa ti nece biti problem... ne znam... pitam...
Ja sam isti problem resio na slican nacin ali nisam crtao direktno na formu nego u PictureBox pa sam onda tu snimljenu sliku u jpg formatu stavljao kao njegov image... dakle "picturebox1.image=image.fromfile(path)" (ili tako nesto... proslo je dosta vremena)... ovim dobijas to da ti iscrtane "slike" uvek budu na istom delu forme i tako znas kako da organisujes ostale objekte... dakle imas bukvalno polje za crtanje umesto da crtas na celoj formi... u principu ako su ti dimenzije bitne ti mozes da stavis da ti taj PictureBox prekriva bukvalno celu formu, no opet ti je tako bolje jer danas-sutra kada se setis da ti treba jos jedno dugme ladno "razvuces formu jos malo i nista ti se ne menja, odnosno polje za crtanje ti je nezavisno od ostatka forme... ali ako ti zelis tako ili ti program nalaze da to tako radis moze i to... mislim nije nikakav problem...
E sad sliku mozes da dobijes tako sto uhvatis screenshot cele forme a zatim bukvalno "iseces" to polje koje hoces da sacuvas kao sliku...
Ja sam radio tako da tu uhvacenu sliku cele forme fizicki sacuvam na disk jer mi je trebala i ona, a da li moze direktno bez cuvanja u jpg formatu zaista ne znam, ali ne sumnjam da moze uz minimalne izmene...
Ako te interesuje ista od ovoga odnosno ako sam dobro razumeo tvoju pitanje reci mi pa cu da prekopam malo ove programcice da ti to okacim ovde...
[ Shadowed @ 19.01.2006. 06:34 ] @
Daj to parce koda koje iscrtava po formi. Mislim da znam kako mozes jednostavo da uradis to kako treba, ali bi trebalo prvo videti kod koji si uradio.
[ Hyperborejac @ 19.01.2006. 12:24 ] @
Evo stize kod, doduse osakacen i jako kratak. Izdvojio sam srz problema u poseban program i njega (neocekivano) nazvao "Srz Problema". Master Mind nisam htio da postujem, jer ima 500kb, a i nije najpregledniji, pa je mozda ovako najbolje za ljude koji zele da pomognu.
Inace sam napisao MM koji radi korektno, ali koji ima tri tone kvadratica koji se vazda nanovo iscrtavaju pri resize-u forme, sto smatram skandalozno losim resenjem (kojeg se stidim). Hvala za trud i pozdrav.
[Ovu poruku je menjao Hyperborejac dana 19.01.2006. u 13:31 GMT+1]
[ Shadowed @ 19.01.2006. 12:39 ] @
Uh, nemam VS ovde. Koliko vidim iz Notepad-a, ovo je sav kod (osim generisanog).
Code: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
pctSlika.Image() = pctSlika.Image.FromFile(CurDir() & "\crvena.jpg")
End Sub
Private Sub bttnIzlaz_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bttnIzlaz.Click
Me.Close()
End Sub
Private Sub bttnSpusti_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bttnSpusti.Click
Dim bmp As Bitmap
Dim tacka As Point
bmp = New Bitmap(Me.Width, Me.Height)
Me.BackgroundImage = bmp
tacka.Y = pctSlika.Location.Y + 40
tacka.X = pctSlika.Location.X
If (tacka.Y > 480) Then
bttnSpusti.Enabled = False
Else
pctSlika.Location = tacka
End If
End Sub
A koliko vidim, ovde nema nikakvog crtanja vec samo pomeranje pctSlika po vertikali prilikom klika na taster bttnSpusti.
[ dusty @ 19.01.2006. 13:13 ] @
A sto ne iscrtas sve ponovo na OnPaint eventu ? Formu mozes da stavis u backbuffer.
[ Hyperborejac @ 19.01.2006. 14:53 ] @
Citat: A koliko vidim, ovde nema nikakvog crtanja vec samo pomeranje pctSlika po vertikali prilikom klika na taster bttnSpusti.
Kad ga budes startovao, bice ti jasno u cemu je problem. Dakle, kad se pctSlika pomjeri po vertikali, njena kopija gore ostaje, jer citavu formu cuvam kao bitmapu. Svakim klikom, bitmapu podesim kao pozadinu i spustim pctSliku... i tako stalno. To tako i treba da radi, problem je sto se nakon minimizovanja i ponovnog aktiviranja programa, sve te prosle kopije se izgube, dok konacna pctSlika, naravno, ostaje. Dakle, meni treba DA SVE OSTANU, sto i jeste slucaj dok se ne uradi minimizacija. Uzgred, ovo jeste citav kod i tacno, nema crtanja, jer sam htio da bude sto kraci (a ako se rijesi za ovaj slucaj, rijesio se i za sve ostale).
Citat: A sto ne iscrtas sve ponovo na OnPaint eventu? Formu mozes da stavis u backbuffer.
Stavljanje forme u backbuffer i jeste problem, kao sto se vidi iz koda. Po mojoj logici, minimize ne bi smio da ista mijenja prosto zato sto, u kodu, ja vec formu cuvam kao bitmapu. Uostalom kod je tu, i svako resenje koje ne uvodi definisanje novih kontrola prihvatam oberucke. Pozdrav i hvala.
[ dusty @ 20.01.2006. 08:31 ] @
Citat: Stavljanje forme u backbuffer i jeste problem, kao sto se vidi iz koda
Kog koda 
Ako ides na varijantu da koristis nekakav backbuffer, moraces da koristis Win32 API jer u .Net nemas pristupa device contextu prozora jer su unmanaged objekti.
Sa CreateCompatibleDC napravis kopiju DC-a tvog prozora i napravis kompatibilni bitmap (mislim da se bash zove CreateCompatibleBitmap) koji je u stvari bafer i selektujes ga u tu kopiju DC-a preko SelectObject funkcije.
BitBlt funkcijom prebacujes sadrzaj iz jednog DC-a u drugi, i na zatvaranju aplikacije moras da pozoves DeleteObject da bi oslobodio resurs bitmape i potom DeleteDC za oslobadanje DC-a, sto mozes iz Dispose() metode.
Ovo pricam napamet, davno je bilo kada sam ovako nesto radio, ali generalno to je to.
[ Hyperborejac @ 20.01.2006. 10:41 ] @
Ovog sto je dat iznad kao attachment (Srz Problema.rar). Uzgred, znam idejno kako ovo treba da se uradi, ali ne znam da napisem. Tebi hvala, ali malo sam sta shvatio iz tvog posta. Inace, ovo me zanima trenutno samo iz radoznalosti, jer sam napisao verziju koja sve ponovo iscrtava na formu (tj. ucitava .jpg slike u nic PictureBox-ova), ali, jednostavno receno, to je lose resenje i sigurno postoji bolji nacin. Pozdrav.
[ Shadowed @ 20.01.2006. 11:30 ] @
Mislim da radis po kompletno pogresnom principu. Zasto ne bi crtao koristeci Graphics objekat? Imas lepo metodu DrawBitmap kojom mozes iscrtati jedan bitmap preko drugog.
[ dusans @ 20.01.2006. 13:05 ] @
Hyperborejac:
Citat:
Kad ga budes startovao, bice ti jasno u cemu je problem. Dakle, kad se pctSlika pomjeri po vertikali, njena kopija gore ostaje, jer citavu formu cuvam kao bitmapu. Svakim klikom, bitmapu podesim kao pozadinu i spustim pctSliku... i tako stalno. To tako i treba da radi, problem je sto se nakon minimizovanja i ponovnog aktiviranja programa, sve te prosle kopije se izgube, dok konacna pctSlika, naravno, ostaje. Dakle, meni treba DA SVE OSTANU, sto i jeste slucaj dok se ne uradi minimizacija. Uzgred, ovo jeste citav kod i tacno, nema crtanja, jer sam htio da bude sto kraci (a ako se rijesi za ovaj slucaj, rijesio se i za sve ostale).
Code:
Private Sub bttnSpusti_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bttnSpusti.Click
Dim bmp As Bitmap
Dim tacka As Point
bmp = New Bitmap(Me.Width, Me.Height)
Me.BackgroundImage = bmp
tacka.Y = pctSlika.Location.Y + 40
tacka.X = pctSlika.Location.X
If (tacka.Y > 480) Then
bttnSpusti.Enabled = False
Else
pctSlika.Location = tacka
End If
End Sub
Ti ovde kreiraš bitmapu koja je po default-u transparentna i kad je staviš kao pozadinu forme ona sprečava crtanje pozadine forme (u stvari nikakvo iscrtavanje ove bitmape se ne dešava) tako da ti ostaje iscrtan picture box na prethodnoj poziciji - ovaj kod radi tačno ono što je i napisano, kad se forma minimizuje i ponovo prikaže onda je ona potpuno transparentna i prikazuje ono što je u pozadini. Ovaj tvoj pristup je vrlo čudan i u neku ruku pogrešan.
Evo ovde ti postujem kod koji radi ono što tebi treba samo obriši picture box sa forme i pokreni.
Code:
Private RedSquareLocation As Point
Private RedSquare As Bitmap
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim BackgroundBitmap As Bitmap
RedSquareLocation = New Point(16, -24)
RedSquare = Image.FromFile(CurDir() & "\crvena.jpg")
BackgroundBitmap = New Bitmap(Me.Width, Me.Height)
Me.BackgroundImage = BackgroundBitmap
Graphics.FromImage(Me.BackgroundImage).Clear(Me.BackColor)
MoveDown()
End Sub
Private Sub bttnIzlaz_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bttnIzlaz.Click
Me.Close()
End Sub
Private Sub bttnSpusti_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bttnSpusti.Click
MoveDown()
End Sub
Private Sub MoveDown()
Dim TempPoint As Point
TempPoint.Y = RedSquareLocation.Y + 40
TempPoint.X = RedSquareLocation.X
If (TempPoint.Y > 480) Then
bttnSpusti.Enabled = False
Else
Graphics.FromImage(Me.BackgroundImage).DrawImage(RedSquare, New Rectangle(TempPoint.X, TempPoint.Y, 32, 32))
RedSquareLocation = TempPoint
Me.Refresh()
End If
End Sub
[ Hyperborejac @ 20.01.2006. 16:20 ] @
Sta da kazem osim hvala, u potpunosti ste mi rijesili problem, i objasnili ga stvarno kako treba. Pozdrav svima koji su postovali i sve najbolje.
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|