Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Нестандартные окна и кнопки  (Прочитано 5275 раз)
0 Пользователей и 1 Гость смотрят эту тему.
larry
Участник

ua
Offline Offline

« : 16-09-2009 11:41 » 

Добрый день! Написал класс для загрузки изображения и обрезки окна по этому изображению... Но возникли две проблемы:
1. При наложении рисунка на обрезанное окно рисунок смещается на 1 пиксель вправо и вниз...
2. При создании окна по рисунку с нечетными размерами(например: 30х30, 50х50 и т.д.) происходит искажение

А вот, собственно, и реализация класса:

Код:
// TYPES //////////////////////////////////////////////////////
typedef struct BITMAP_FILE_TYPE
{
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
PALETTEENTRY     palette[256];
UCHAR            *buffer;
}BITMAP_FILE, *BITMAP_FILE_PTR;
typedef struct BITMAP_IMAGE_TYPE
{
COORD    pos;        // координаты изображения
int      width;      // размер изображения по горизонтали
int      height;     // размер изображения по вертикали
int      sizeImage;  // размер изображения в байтах
COLORREF color_key;  // прозрачный цвет
int      byte_pixel; // байт на пиксел
int      **buffer;   // изображение
}BITMAP_IMAGE, *BITMAP_IMAGE_PTR;
///////////////////////////////////////////
//классы
class CControlUser
{
private:
BITMAP_IMAGE_PTR image;
public:
CControlUser();
~CControlUser();

int  LoadBitmapImage(char*, COLORREF, int=0, int=0);
HRGN CreateWindowOnBitmap(HRGN);
void FlipBitmap(BITMAP_FILE_PTR);
void DrawBitmap(HDC);
};


Загрузка изображения

Код:
int CControlUser::LoadBitmapImage(char *filename, COLORREF color_key, int x, int y)
{
FILE *file;
BITMAP_FILE_PTR bitmap = new BITMAP_FILE;

if((file = fopen(filename, "rb")) == NULL)
return 0;

fread(&bitmap->bfh, sizeof(BITMAPFILEHEADER), 1, file);

if(bitmap->bfh.bfType != BITMAP_ID)
{
fclose(file);
return -1;
}

fread(&bitmap->bih, sizeof(BITMAPINFOHEADER), 1, file);

fseek(file, -(int)(bitmap->bih.biSizeImage), SEEK_END);

if(bitmap->bih.biBitCount == 24)
{
if(!(bitmap->buffer = new UCHAR[bitmap->bih.biSizeImage]))
{
fclose(file);
return -2;
}

fread(bitmap->buffer, bitmap->bih.biSizeImage, 1, file);
}
else
{
fclose(file);
return -3;
}

FlipBitmap(bitmap);

fclose(file);

image->height = bitmap->bih.biHeight;
image->width  = bitmap->bih.biWidth;
image->sizeImage = bitmap->bih.biSizeImage;
image->pos.X = x;
image->pos.Y = y;
image->color_key = color_key;
image->byte_pixel = bitmap->bih.biBitCount/8;

image->buffer = new int*[bitmap->bih.biHeight];

for(int pos = 0; pos < bitmap->bih.biHeight; pos++)
image->buffer[pos] = new int[bitmap->bih.biWidth];

int red, green, blue;

for(int pos_y = 0; pos_y < bitmap->bih.biHeight; pos_y++)
{
for(int pos_x = 0; pos_x < bitmap->bih.biWidth; pos_x++)
{
int index = pos_y*(bitmap->bih.biWidth*image->byte_pixel)+pos_x*image->byte_pixel;

red   = bitmap->buffer[index];
green = bitmap->buffer[index+1];
blue  = bitmap->buffer[index+2];

image->buffer[pos_y][pos_x] = RGB_24(red,green,blue);
}
}

return 1;
}

Создание региона по изображению

Код:
HRGN CControlUser::CreateWindowOnBitmap(HRGN rgn)
{
HRGN temp_rgn;
int  left_pos;    // начало строки с непрозрачными пикселами
int  red;
int  green;
int  blue;

rgn = CreateRectRgn(0,0,0,0);

for (int pos_y = 0; pos_y < image->height; pos_y++)
{
left_pos = -1;
for (int pos_x = 0; pos_x < image->width; pos_x++)
{
if (image->buffer[pos_y][pos_x] != image->color_key)
{
if (left_pos < 0)
{
left_pos = pos_x;
}
else
if (pos_x == (image->width - 1))
{
temp_rgn = CreateRectRgn(left_pos, pos_y, pos_x, pos_y+1);
CombineRgn( rgn, rgn, temp_rgn, RGN_OR);
left_pos = -1;
}
}
else
if (left_pos >= 0)
{
temp_rgn = CreateRectRgn(left_pos, pos_y, pos_x, pos_y+1);
CombineRgn( rgn, rgn, temp_rgn, RGN_OR);
left_pos = -1;
}
}
}


return rgn;
}

Зеркальное отображение изображения

Код:
void CControlUser::FlipBitmap(BITMAP_FILE_PTR bitmap)
{
int red, green, blue;

int s_bitmap = bitmap->bih.biSizeImage;
int width    = (bitmap->bih.biWidth*3);
int height   = bitmap->bih.biHeight;

for(int index = 0; index < height/2; index++)
{
int left_pos_begin = index*width;
int left_pos_end   = (index+1)*width+2;

for(int pos = 0; pos < width; pos += 3)
{
red   = bitmap->buffer[(left_pos_begin+pos)+2];
green = bitmap->buffer[(left_pos_begin+pos)+1];
blue  = bitmap->buffer[(left_pos_begin+pos)];

bitmap->buffer[(left_pos_begin+pos)] = bitmap->buffer[((s_bitmap-left_pos_end)+pos)+2];
bitmap->buffer[(left_pos_begin+pos)+1] = bitmap->buffer[((s_bitmap-left_pos_end)+pos)+1];
bitmap->buffer[(left_pos_begin+pos)+2]   = bitmap->buffer[((s_bitmap-left_pos_end)+pos)];

bitmap->buffer[((s_bitmap-left_pos_end)+pos)]   = red;
bitmap->buffer[((s_bitmap-left_pos_end)+pos)+1] = green;
bitmap->buffer[((s_bitmap-left_pos_end)+pos)+2] = blue;
}
}
}

Вывод на экран изображения

Код:
void CControlUser::DrawBitmap(HDC hdc)
{
HDC     hdcMem     = CreateCompatibleDC(hdc);
HBITMAP hBitmapMem = CreateCompatibleBitmap(hdc, image->width, image->height);

SelectObject(hdcMem, hBitmapMem);

for(int pos_y = 0; pos_y < image->height; pos_y++)
{
for(int pos_x = 0; pos_x < image->width; pos_x++)
{
if((image->buffer[pos_y][pos_x]) != image->color_key)
SetPixel(hdcMem,(image->pos.X+pos_x),(image->pos.Y+pos_y),(COLORREF)image->buffer[pos_y][pos_x]);
}
}

BitBlt(hdc,0, 0, image->width, image->height, hdcMem, 0, 0, SRCCOPY);
}
« Последнее редактирование: 16-09-2009 16:21 от Sel » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #1 : 16-09-2009 12:30 » 

Да, кода многовато... Сорри. МОгу только общий совет дать. Как раз в таких ситуациях. Вот смотри у тебя столько параметров фигурирует. а в коде НИ ОДНОГО TRACE нету. Да как же без этого вобще, что-то делать.
Сделай вывод координат, размеров на разных этапах начиная с загрузки, проанализируй и скорей всего сразу увидишь сам, где это происходит. Ну а дальше или сразу всё станет ясно или добро пожаловать. Собственно что я хочу сказать.
В итоге ты должень увидеть изменение координат и в каком месте это происходит. Разбираться будет гораздо легче.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
larry
Участник

ua
Offline Offline

« Ответ #2 : 16-09-2009 12:37 » 

Спасибо...
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines