[ Genesis @ 18.01.2005. 00:07 ] @
Hi ! Zanima me da li je moguće promjeniti standardni oblik delphi formi? Kako je moguće učitati neku sliku koja bi mogla da bude umjesto standardne forme ? Cao! |
[ Genesis @ 18.01.2005. 00:07 ] @
[ bancika @ 18.01.2005. 01:23 ] @
napravi u nekom programu slicicu kako hoces da ti izgleda forma i postavi boju pozadine koja hoces da ti bude transparentna. Obrati paznju da se ta boja ne javlja nigde drugde na formi jer ce delphi sve pixele te boje napraviti providnim. Najbolje je koristiti onu pedersku roze clFuschia jer nju sigurno neces da koristis (nadam se) u ostatku slike ili forme.
Sad tu sliku postavi u tImage i njega stavi preko cele forme, postavi svojstvo forme Style na fsNone (moze i ne mora), Transparent (valjda je tako) na True a TransparentColor na clFuschia. Pritisni F9 i probaj... postoji i drugi nacin, ako ne zelis da se vidi ostatak slike koji nije transparentan...ak treba tu sam. pozdrav [ _v!rus_ @ 18.01.2005. 05:14 ] @
Ne mogu da verujem, toliko radim u delphiu i nisam znao da D6 native podrzava transparentne forme, mislio sam da treba da koristim neke hardcore API pozive za tako nesto...Extra...
Btw., radi li na non-NT platformama (95 :), 98, ME)? [ dogriz @ 18.01.2005. 06:47 ] @
Ne radi na Win9x-ovima
[ bancika @ 18.01.2005. 11:35 ] @
probaj sledece:
ubaci proceduru Code: function TForm1.BitmapToRegion(bmp: TBitmap; TransparentColor: TColor=clBlack; RedTol: Byte=1; GreenTol: Byte=1; BlueTol: Byte=1): HRGN; const AllocUnit = 100; type PRectArray = ^TRectArray; TRectArray = Array[0..(MaxInt div SizeOf(TRect))-1] of TRect; var pr: PRectArray; // used to access the rects array of RgnData by index h: HRGN; // Handles to regions RgnData: PRgnData; // Pointer to structure RGNDATA used to create regions lr, lg, lb, hr, hg, hb: Byte; // values for lowest and hightest trans. colors x,y, x0: Integer; // coordinates of current rect of visible pixels b: PByteArray; // used to easy the task of testing the byte pixels (R,G,B) ScanLinePtr: Pointer; // Pointer to current ScanLine being scanned ScanLineInc: Integer; // Offset to next bitmap scanline (can be negative) maxRects: Cardinal; // Number of rects to realloc memory by chunks of AllocUnit function min(a,b:integer):integer; begin if a<b then Result:=a else Result:=b; end; begin Result := 0; { Keep on hand lowest and highest values for the "transparent" pixels } lr := GetRValue(TransparentColor); lg := GetGValue(TransparentColor); lb := GetBValue(TransparentColor); hr := Min($ff, lr + RedTol); hg := Min($ff, lg + GreenTol); hb := Min($ff, lb + BlueTol); { ensures that the pixel format is 32-bits per pixel } bmp.PixelFormat := pf32bit; { alloc initial region data } maxRects := AllocUnit; GetMem(RgnData,SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * maxRects)); try with RgnData^.rdh do begin dwSize := SizeOf(RGNDATAHEADER); iType := RDH_RECTANGLES; nCount := 0; nRgnSize := 0; SetRect(rcBound, MAXLONG, MAXLONG, 0, 0); end; { scan each bitmap row - the orientation doesn't matter (Bottom-up or not) } ScanLinePtr := bmp.ScanLine[0]; ScanLineInc := Integer(bmp.ScanLine[1]) - Integer(ScanLinePtr); for y := 0 to bmp.Height - 1 do begin x := 0; while x < bmp.Width do begin x0 := x; while x < bmp.Width do begin b := @PByteArray(ScanLinePtr)[x*SizeOf(TRGBQuad)]; // BGR-RGB: Windows 32bpp BMPs are made of BGRa quads (not RGBa) if (b[2] >= lr) and (b[2] <= hr) and (b[1] >= lg) and (b[1] <= hg) and (b[0] >= lb) and (b[0] <= hb) then Break; // pixel is transparent Inc(x); end; { test to see if we have a non-transparent area in the image } if x > x0 then begin { increase RgnData by AllocUnit rects if we exceeds maxRects } if RgnData^.rdh.nCount >= maxRects then begin Inc(maxRects,AllocUnit); ReallocMem(RgnData,SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * MaxRects)); end; { Add the rect (x0, y)-(x, y+1) as a new visible area in the region } pr := @RgnData^.Buffer; // Buffer is an array of rects with RgnData^.rdh do begin SetRect(pr[nCount], x0, y, x, y+1); { adjust the bound rectangle of the region if we are "out-of-bounds" } if x0 < rcBound.Left then rcBound.Left := x0; if y < rcBound.Top then rcBound.Top := y; if x > rcBound.Right then rcBound.Right := x; if y+1 > rcBound.Bottom then rcBound.Bottom := y+1; Inc(nCount); end; end; // if x > x0 { Need to create the region by muliple calls to ExtCreateRegion, 'cause } { it will fail on Windows 98 if the number of rectangles is too large } if RgnData^.rdh.nCount = 2000 then begin h := ExtCreateRegion(nil, SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * maxRects), RgnData^); if Result > 0 then begin // Expand the current region CombineRgn(Result, Result, h, RGN_OR); DeleteObject(h); end else // First region, assign it to Result Result := h; RgnData^.rdh.nCount := 0; SetRect(RgnData^.rdh.rcBound, MAXLONG, MAXLONG, 0, 0); end; Inc(x); end; // scan every sample byte of the image Inc(Integer(ScanLinePtr), ScanLineInc); end; { need to call ExCreateRegion one more time because we could have left } { a RgnData with less than 2000 rects, so it wasn't yet created/combined } h := ExtCreateRegion(nil, SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * MaxRects), RgnData^); if Result > 0 then begin CombineRgn(Result, Result, h, RGN_OR); DeleteObject(h); end else Result := h; finally FreeMem(RgnData,SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * MaxRects)); end; end; i u OnCreate forme stavi: Code: var Rgn:Hrgn; begin rgn:=BitmapToRegion(Image1.Picture.Bitmap, clFuschia); SetWindowRgn(handle,Rgn,false); to daje slican efekat, samo mislim da je brze od onog delphi-jevog jer se sa ovim ne desava da forma "zablinka" kada se pokaze, nego je odmah cool. cak *mozda* i radi pod 9x...onaj drugi metod sigurno ne. [ _v!rus_ @ 19.01.2005. 01:11 ] @
Znao sam da ima neki zez sa API-jem :)
Trebalo bi da radi posto se svi 32-bit windowsi oslanjaju na regione za definiciju izgleda prozora. Moram da probam da li radi mozda @real-time (ako bi vise puta pozvao SetWindowRgn u nekom timeru, da li bi mogao da menjam oblik forme u toku rada aplikacije, interesantno za desktop applete kao npr. bancikin merac kilometraze misa). [ bancika @ 19.01.2005. 02:00 ] @
moze real-time. nemoj da ocekujes previse ali par fps-ova je sasvim izvodljivo. ne mozes da pravis sexy dancere, ali za neke satove ili slicno je odlicno :)
pozdrav [ Nemanja Avramović @ 19.01.2005. 11:16 ] @
na drugom disku delphija 6 enterprise se dobija dxfforumlibrary i tu ima jedna komponenta koja moze da "isece" form po slici i u win9x
[ bancika @ 19.01.2005. 12:39 ] @
verovatno moze i ovo zadnje sto sam dao...to sam koristio u proslom veku, tad nije bilo winXP-a :)
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|