-
Доброго времени суток! Может кто знает как форму окна по картинке, типа как в заставке к CorelDraw, но так что бы при загрузке фотографии не было белых краев, а край формы был гладким.
-
Пользуй регионы.
function GBS(B: HBITMAP):SIZE; var buf : BITMAP; begin FillChar(buf, SizeOf(BITMAP), 0); GetObject(B, SizeOf(BITMAP), @buf); result.cx:=buf.bmWidth; result.cy:=buf.bmHeight; end;
function GetBmpRgn(var BMP:HBITMAP):HRGN; var RG : HRGN; TC:COLORREF; i, j, L, R, H, W : integer;
begin Result:=0; DC:=CreateCompatibleDC(0); SelectObject(DC, BMP); sz:=GBS(BMP);
W:=sz.cx; H:=sz.cy;
TC:=GetPixel(DC, 0, 0);
for i:=0 to H-1 do begin L:=-1; for j:=0 to W-1 do begin if L<0 then begin if GetPixel(DC, j, i)<>TC then L:=j; end else if GetPixel(DC, j, i)=TC then begin R:=j; RG:=CreateRectRgn(L, i, R, i+1); if Result=0 then Result:=RG else begin CombineRgn(Result, Result, RG, RGN_OR); DeleteObject(RG); end; L:=-i; end; end;
if L>=0 then begin RG:=CreateRectRgn(L, i, W, i+1); if Result=0 then Result:=RG else begin CombineRgn(Result, Result, RG, RGN_OR); DeleteObject(RG); end; end; end;
ReleaseDC(BMP, DC); DeleteDC(DC); end;
После вызова этой функции проставляешь окну регион с помощью SetWindowRgn и радуешься жизни :) Когда будешь дестроить окно, не забудь DeleteObject'ом удалить регион.
-
-
Этот вариант побыстрее будет: function CreateRgnFromBitmap(Bitmap: TBitmap): HRGN;
const
dCount = 500;
var
PLine: Pointer; PPixel: PLongint; DataMem: PRgnData; H: THandle; MaxRects: DWORD; X,StartX,FinishX,Y: integer; TransColor: TColor; TransR,TransG,TransB: Byte; TempBitmap: TBitmap; function IsTrans(Pixel: Longint): boolean;
var
R,G,B: Byte;
begin
R:=GetBValue(Pixel);
G:=GetGValue(Pixel);
B:=GetRValue(Pixel);
Result:=(TransR = R) and (TransG = G) and (TransB = B);
end;
procedure AddRect;
var
Rect: PRect;
begin
Rect:=@DataMem^.Buffer[DataMem^.rdh.nCount*SizeOf(TRect)];
SetRect(Rect^,StartX,Y,FinishX,Y+1);
Inc(DataMem^.rdh.nCount);
end;
begin
MaxRects:=dCount; TransColor:=GetPixel(Bitmap.Canvas.Handle,0,0);
TransR:=GetRValue(TransColor);
TransG:=GetGValue(TransColor);
TransB:=GetBValue(TransColor);
TempBitmap:=TBitmap.Create;
TempBitmap.Assign(Bitmap);
TempBitmap.PixelFormat:=pf24bit; H:=GlobalAlloc(GMEM_MOVEABLE,SizeOf(TRgnDataHeader)+
SizeOf(TRect)*MaxRects);
DataMem:=GlobalLock(H);
ZeroMemory(@DataMem^.rdh,SizeOf(TRgnDataHeader));
DataMem^.rdh.dwSize:=SizeOf(TRgnDataHeader); DataMem^.rdh.iType:=RDH_RECTANGLES; for Y:=0 to TempBitmap.Height-1 do begin PLine:=TempBitmap.ScanLine[Y]; PPixel:=PLongint(PLine); X:=0; StartX:=0; FinishX:=0; while X<TempBitmap.Width do begin Inc(X); if not IsTrans(PPixel^) then FinishX:=X
else begin
if DataMem^.rdh.nCount>=MaxRects then
begin
Inc(MaxRects,dCount);
GlobalUnlock(H);
H:=GlobalReAlloc(H,SizeOf(TRgnDataHeader)+SizeOf(TRect)*MaxRects,
GMEM_MOVEABLE);
DataMem:=GlobalLock(H);
end;
if FinishX>StartX then AddRect;
StartX:=X;
FinishX:=X;
end;
Inc(PByte(PPixel),3); end;
if FinishX>StartX then AddRect;
end;
TempBitmap.Free;
try
Result:=ExtCreateRegion(nil,SizeOf(TRgnDataHeader)+
SizeOf(TRect)*DataMem^.rdh.nCount,DataMem^);
finally
GlobalFree(H); end;
end;
. . .
end. Только советую от Global-функций избавится, заменить на аналоги, были проблемы с ними.
-
> Когда будешь дестроить окно, не забудь DeleteObject'ом удалить > регион.
Не нужно. Справочку по SetWindowRgn читаем.
-
Спасибо всем! Вроде разобрался.
-
особенно гладкими края будут с регионами:)
-
> [6] antonn © (15.09.07 22:03)
Layered - это конечно хорошо, но не панацея, полно ограничений.
-
> Инс © (15.09.07 22:46) [7]
ограничений нет, была бы фантазия:) к тому же автору нужно сделать заставку "наподобие корела"
-
> [8] antonn © (16.09.07 09:13)
Есть, Win2000 - минимум, и если использовать UpdateLayeredWindow и на форме лежат другие контролы, то их придется отрисовывать самому.
-
а у автора WinXP в запросе :Р контролы это конечно минус, зато можно свои рисовать:)
-
> а у автора WinXP в запросе :Р
А у пользователя какая система автор не указал? :)
|