Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.02.04;
Скачать: [xml.tar.bz2];

Вниз

Скин для формы   Найти похожие ветки 

 
Molotov   (2002-01-18 21:04) [0]

Хочу создать прогу с нестандартным окном (типа Windows media player 7.0, Sonique и тд). Причем, меня интересует окно неоднородной формы(т.е не четкая геометрическая фмгура). Знаю функцию SetWindowRgn, но как создать фигуру типа HRGN, какие для этого есть функции? Помогите! Заранее благодарен!


 
Hyper-X   (2002-01-18 21:31) [1]

Парень есть компонент Varian Skin Factory!!!!Если хоч его напеши мне на crak@ukr.net


 
Sergey_n   (2002-01-19 02:20) [2]

На Pascal пример не нашел, но нашел на C++, надеюсь разберешся:
Это очень простая функция, создающая регион из bitmap (.bmp) файла. Так же в примере представлен усовершенствованный вариант этой функции, позволяющий задавать маску изображения.

Компилятор: Visual C++ 4-6

Функция называется CreateRgn и имеет два параметра:
szFileName - имя файла, содержащего картинку.
pPoint - указатель на структуру POINT , которая содержит координаты цвета, который используется для конструирования региона, если параметр NULL, то будет использоваться цвет в координате (0, 0).

HRGN CreateRgn(LPTSTR szFileName, LPPOINT pPoint)
{
HBITMAP hBmp = (HBITMAP)LoadImage( NULL, szFileName,
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
if ( !hBmp ) return NULL;

BITMAP bi;
BYTE bpp;
DWORD e;
DWORD f, t;
INT i, j;
bool b = false;
HRGN Rgn, ResRgn = CreateRectRgn( 0, 0, 0, 0 );

GetObject( hBmp, sizeof( BITMAP ), &bi );

bpp = bi.bmBitsPixel >> 3;

BYTE *pBits = new BYTE[ bi.bmWidth * bi.bmHeight * bpp ];

int p = GetBitmapBits( hBmp, bi.bmWidth * bi.bmHeight * bpp,
pBits );

if ( pPoint == NULL || pPoint->x >= bi.bmWidth ||
pPoint->y >= bi.bmHeight )
e = *(DWORD*)pBits;
else
e = *(DWORD*)(pBits + (pPoint->y * bi.bmWidth + pPoint->x) * bpp );

e <<= 32 - bi.bmBitsPixel;

for ( i = 0; i < bi.bmHeight; i++ )
for ( j = 0; j < bi.bmWidth; j++ )
{
t = *(DWORD*)(pBits + (i * bi.bmWidth +
j) * bpp) << (32 - bi.bmBitsPixel);

if ( t == e )
{
if ( !b )
{
f = j;
b = true;
} else if ( j == (bi.bmWidth - 1) )
{
Rgn = CreateRectRgn( f, i, j, i + 1 );
CombineRgn( ResRgn, ResRgn, Rgn, RGN_OR );
b = false;
}
} else if ( b )
{
Rgn = CreateRectRgn( f, i, j, i + 1 );
CombineRgn( ResRgn, ResRgn, Rgn, RGN_OR );
b = false;
}
}

delete pBits;

return ResRgn;
}


 
Sergey_n   (2002-01-19 02:21) [3]

Update: Ниже представлена улучшенная версия функции, которая требует маску битмапа для TrueColor. В Win9x ширина маски битмапа должна быть DWORD.

HRGN CreateRgnFromFile(HBITMAP hBmp, COLORREF color)
{
// получаем размер маски
BITMAP bm = { 0 };
GetObject( hBmp, sizeof(BITMAP), &bm );

m_dwWidth = bm.bmWidth; // ширина bitmap
m_dwHeight = bm.bmHeight; // высота bitmap

// Распределяем буфер для маски
LPBYTE pBits = new BYTE[ bm.bmWidthBytes * bm.bmHeight ];
// заполняем буфер свойствами
BITMAPINFO bi = { 0 };
bi.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
bi.bmiHeader.biBitCount = bm.bmBitsPixel;
bi.bmiHeader.biHeight = bm.bmHeight;
bi.bmiHeader.biWidth = bm.bmWidth;
bi.bmiHeader.biPlanes = bm.bmPlanes;
// заполняем биты буфера
HDC hdc = ::GetDC( NULL );
GetDIBits( hdc, hBmp, 0, bm.bmHeight, pBits, &bi, DIB_RGB_COLORS );
::ReleaseDC( NULL, hdc );

if ( bi.bmiHeader.biBitCount < 16 ) return NULL;

// сдвигаем биты и байт на пиксель (для сравнения цветов)
BYTE sb = 32 - bi.bmiHeader.biBitCount;
BYTE bpp = bi.bmiHeader.biBitCount >> 3;

LPBYTE pClr = (LPBYTE)&color;
// переставляем красный и синий компоненты
BYTE tmp = pClr[0]; pClr[0] = pClr[2]; pClr[2] = tmp;
// convert color if curent DC is 16-bit (5:5:5)
if ( bpp == 2 ) color = ((DWORD)(pClr[0] & 0xf8) >> 3) |
((DWORD)(pClr[1] & 0xf8) << 2) |
((DWORD)(pClr[2] & 0xf8) << 7);
// выравниваем цвет для сравнения
color <<= sb;

const DWORD RDHDR = sizeof(RGNDATAHEADER);
const DWORD MAXBUF = 40; // размер одного блока в RECT-ах
// (т.e. MAXBUF*sizeof(RECT)
// в байтах)
LPBYTE pColor = pBits;
LPRECT pRects;
DWORD cBlocks = 0; // кол-во распределённых блоков

INT i, j; // текущая позиция в маске картинки
INT first = 0; // левая координата текущей линии,
// в которой была найдена маска
bool wasfirst = false; // устанавливается, если маска была
// найдена в текущей линии
bool ismask; // устанавливается, если текущий
// цвет является маской

// распределяем память для данных региона
RGNDATAHEADER* pRgnData = (RGNDATAHEADER*)new BYTE[ RDHDR +
++cBlocks * MAXBUF * sizeof(RECT) ];
memset( pRgnData, 0, RDHDR + cBlocks * MAXBUF * sizeof(RECT) );
// заполняем его по умолчанию
pRgnData->dwSize = RDHDR;
pRgnData->iType = RDH_RECTANGLES;
pRgnData->nCount = 0;

for ( i = 0; i < bm.bmHeight; i++ )
for ( j = 0; j < bm.bmWidth; j++ )
{
// получаем цвет
ismask = *(DWORD*)pColor << sb != color;
// сдвиг указателя на следующий цвет
pColor += bpp;
// помещаем часть сканируемой линии как регион RECT,
// если прозрачный цвет найден после цвета маски либо
// цвет маски найден в конце маски изображения
if ( wasfirst && (ismask ^ (j < bm.bmWidth - 1)) )
{
// получаем смещение в массиве RECT
pRects = (LPRECT)((LPBYTE)pRgnData + RDHDR);
// сохраняем текущий RECT
pRects[ pRgnData->nCount++ ] = CRect( first,
bm.bmHeight - i - 1, j, bm.bmHeight - i );
// если буфер полон, то перераспределяем его
if ( pRgnData->nCount >= cBlocks * MAXBUF )
{
LPBYTE pRgnDataNew = new BYTE[ RDHDR +
++cBlocks * MAXBUF * sizeof(RECT) ];
memcpy( pRgnDataNew, pRgnData, RDHDR +
(cBlocks - 1) * MAXBUF * sizeof(RECT));

delete pRgnData;
pRgnData = (RGNDATAHEADER*)pRgnDataNew;
}
wasfirst = false;
}
else if ( !wasfirst && ismask ) // устанавливаем
// wasfirst когда
// маска найдена
{
first = j;
wasfirst = true;
}
}

delete pBits;

// создаём регион
HRGN hRgn = ExtCreateRegion( NULL, RDHDR +
pRgnData->nCount * sizeof(RECT), (LPRGNDATA)pRgnData );

delete pRgnData;

return hRgn;
}


 
Ajax   (2002-01-19 14:17) [4]

То же самое, но на Delphi

function CreateRgnFromBitmap(rgnBitmap: TBitmap): HRGN;
var
transColor: TColor;
i, j: Integer;
width, height: Integer;
left, right: Integer;
rectRgn: HRGN;
begin
Result := 0;
width := rgnBitmap.Width;
height := rgnBitmap.Height;
transColor := rgnBitmap.Canvas.Pixels[width - 1, height - 1];
for i := 0 to height - 1 do
begin
left := -1;
for j := 0 to width - 1 do
begin
if left < 0 then
begin
if rgnBitmap.Canvas.Pixels[j, i] <> transColor then
left := j;
end
else
if rgnBitmap.Canvas.Pixels[j, i] = transColor then
begin
right := j;
rectRgn := CreateRectRgn(left, i, right, i + 1);
if Result = 0 then
Result := rectRgn
else
begin
CombineRgn(Result, Result, rectRgn, RGN_OR);
DeleteObject(rectRgn);
end;
left := -1;
end;
end;
if left >= 0 then
begin
rectRgn := CreateRectRgn(left, i, width, i + 1);
if Result = 0 then
Result := rectRgn
else
begin
CombineRgn(Result, Result, rectRgn, RGN_OR);
DeleteObject(rectRgn);
end;
end;
end;
end;


 
Molotov   (2002-01-19 14:40) [5]

Спасибо всем! То, что нужно!



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2002.02.04;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.007 c
1-8866
tovSuhov
2002-01-15 10:58
2002.02.04
TIniFile в Windows2000...


3-8795
dmitriyk
2002-01-04 04:20
2002.02.04
Как вывести информацию (HTML) в WebBrowser из БД Access


3-8796
roottim
2002-01-06 12:36
2002.02.04
DbGrid


14-8975
Вячеслав_
2001-10-10 05:13
2002.02.04
1C:Предприятие


4-9020
sanyaMM
2001-12-04 16:39
2002.02.04
Как перехватить Ctrl+Alt+Del?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский