Добрый день! Написал класс для загрузки изображения и обрезки окна по этому изображению... Но возникли две проблемы:
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);
}