Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.01.25;
Скачать: CL | DM;

Вниз

Форма окна по картинке   Найти похожие ветки 

 
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 вся ветка

Текущий архив: 2009.01.25;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.018 c
2-1228979229
opoloxai
2008-12-11 10:07
2009.01.25
Колёсико мыши


2-1228999918
well2
2008-12-11 15:51
2009.01.25
Как выбрать директорию с помощью OpenDialog?


3-1213785828
zorik
2008-06-18 14:43
2009.01.25
Оптимизация запроса


15-1227966287
Городской Шаман
2008-11-29 16:44
2009.01.25
Что я теряю, переводя проект с Delphi на С++(VS)


2-1228807718
noob_one
2008-12-09 10:28
2009.01.25
Разный размер исполнимого файла.