Форум: "Media";
Текущий архив: 2009.01.25;
Скачать: [xml.tar.bz2];
ВнизФорма окна по картинке Найти похожие ветки
← →
master_asasin (2007-09-13 14:26) [0]Доброго времени суток! Может кто знает как форму окна по
картинке, типа как в заставке к CorelDraw, но так что бы
при загрузке фотографии не было белых краев, а край формы был гладким.
← →
Dib@zol © (2007-09-13 14:41) [1]Пользуй регионы.
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"ом удалить регион.
← →
antonn © (2007-09-13 16:46) [2]окно с альфаканалом
http://desksoft.ru/index.php?forum=13&th=47
← →
Инс © (2007-09-14 23:13) [3]Этот вариант побыстрее будет:
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; // Значения R, G и B прозрачного цвета
TempBitmap: TBitmap; // Временный Bitmap
// Функция возвращает true, если цвет Pixel совпадает с прозрачным
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;
// Процедура добавляет прямоугольник (StartX, Y, FinishX, Y+1) к региону
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; // Начальное значение MaxRects
// Определяем прозрачный цвет
TransColor:=GetPixel(Bitmap.Canvas.Handle,0,0);
TransR:=GetRValue(TransColor);
TransG:=GetGValue(TransColor);
TransB:=GetBValue(TransColor);
// Формируем временный Bitmap, с которым будем работать
TempBitmap:=TBitmap.Create;
TempBitmap.Assign(Bitmap);
TempBitmap.PixelFormat:=pf24bit; // 24 бита на пиксель
// Выделяем память на данные для региона и получаем указатель на нее
H:=GlobalAlloc(GMEM_MOVEABLE,SizeOf(TRgnDataHeader)+
SizeOf(TRect)*MaxRects);
DataMem:=GlobalLock(H);
// Заполняем заголовок
// Обнуляем все поля в заголовке
ZeroMemory(@DataMem^.rdh,SizeOf(TRgnDataHeader));
DataMem^.rdh.dwSize:=SizeOf(TRgnDataHeader); // Заполняем поле dwSize
DataMem^.rdh.iType:=RDH_RECTANGLES; // Заполняем поле iType
// Начинаем цикл обхода рисунка по точкам. Будем двигаться слева-направо,
// сверху-вниз. В переменных X и Y будем хранить текущее значение
// координат.
// В переменной StartX - начало нового прямоугольника, FinishX -
// соответственно конец прямоугольника.
for Y:=0 to TempBitmap.Height-1 do begin // Цикл по строкам
PLine:=TempBitmap.ScanLine[Y];// Получаем указатель на строку
PPixel:=PLongint(PLine); // Получаем указатель на первую точку в строке
X:=0; StartX:=0; FinishX:=0; // Обнуляем X, StartX, FinishX
while X<TempBitmap.Width do begin // Цикл по столбцам
Inc(X); // Увеличиваем текущее значение координаты X
// Если цвет точки отличен от прозрачного,
// то надо включить ее в новый прямоугольник
if not IsTrans(PPixel^) then FinishX:=X
else begin
// Цвет точки равен прозрачному. Значит нужно завершить формирование
// прямоугольника, если он не пустой, то добавить его к региону и начать
// формирование нового прямоугольника. Если количество прямоугольников
// в регионе достигло MaxRects, то увеличиваем MaxRects на dCount, и
// выделяем память под данные о регионе заново
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, FinishX для формирования нового
// прямоугольника
StartX:=X;
FinishX:=X;
end;
Inc(PByte(PPixel),3); // Получаем указатель не следующую точку рисунка
end;
// Возможен следующий случай: если цвет последней точки в строке не равен
// прозрачному, то FinishX будет больше, чем StartX, однако прямоугольник
// не будет добавлен к региону, так так добавление нового прямоугольника
// происходит только если встретился прозрачный пиксель. Это нужно учесть.
if FinishX>StartX then AddRect;
end;
// Временный Bitmap больше не нужен
TempBitmap.Free;
try
// Формируем регион по данным из DataMem^
Result:=ExtCreateRegion(nil,SizeOf(TRgnDataHeader)+
SizeOf(TRect)*DataMem^.rdh.nCount,DataMem^);
finally
GlobalFree(H); // Освобождаем выделенную память
end;
end;
. . .
end.
Только советую от Global-функций избавится, заменить на аналоги, были проблемы с ними.
← →
Инс © (2007-09-14 23:15) [4]
> Когда будешь дестроить окно, не забудь DeleteObject"ом удалить
> регион.
Не нужно. Справочку по SetWindowRgn читаем.
← →
master_asasin (2007-09-15 12:50) [5]Спасибо всем! Вроде разобрался.
← →
antonn © (2007-09-15 22:03) [6]особенно гладкими края будут с регионами:)
← →
Инс © (2007-09-15 22:46) [7]
> [6] antonn © (15.09.07 22:03)
Layered - это конечно хорошо, но не панацея, полно ограничений.
← →
antonn © (2007-09-16 09:13) [8]
> Инс © (15.09.07 22:46) [7]
ограничений нет, была бы фантазия:)
к тому же автору нужно сделать заставку "наподобие корела"
← →
Инс © (2007-09-16 11:40) [9]
> [8] antonn © (16.09.07 09:13)
Есть, Win2000 - минимум, и если использовать UpdateLayeredWindow и на форме лежат другие контролы, то их придется отрисовывать самому.
← →
antonn © (2007-09-16 14:50) [10]а у автора WinXP в запросе :Р
контролы это конечно минус, зато можно свои рисовать:)
← →
Инс © (2007-09-16 18:01) [11]
> а у автора WinXP в запросе :Р
А у пользователя какая система автор не указал? :)
Страницы: 1 вся ветка
Форум: "Media";
Текущий архив: 2009.01.25;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.007 c