visualboyadvance-m/src/win32/BitmapControl.cpp

275 lines
5.7 KiB
C++

#include "BitmapControl.h"
#include "stdafx.h"
#include "vba.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
bool BitmapControl::isRegistered = false;
/////////////////////////////////////////////////////////////////////////////
// BitmapControl
IMPLEMENT_DYNCREATE(BitmapControl, CScrollView)
BitmapControl::BitmapControl()
{
w = 0;
h = 0;
data = NULL;
bmpInfo = NULL;
stretch = false;
registerClass();
CSize sizeTotal;
sizeTotal.cx = sizeTotal.cy = 0;
SetScrollSizes(MM_TEXT, sizeTotal);
}
BitmapControl::~BitmapControl()
{
}
BEGIN_MESSAGE_MAP(BitmapControl, CScrollView)
//{{AFX_MSG_MAP(BitmapControl)
ON_WM_ERASEBKGND()
ON_WM_SIZE()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// BitmapControl drawing
void BitmapControl::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
// TODO: calculate the total size of this view
sizeTotal.cx = sizeTotal.cy = 100;
SetScrollSizes(MM_TEXT, sizeTotal);
}
void BitmapControl::OnDraw(CDC* dc)
{
RECT r;
GetClientRect(&r);
int w1 = r.right - r.left;
int h1 = r.bottom - r.top;
CDC memDC;
memDC.CreateCompatibleDC(dc);
if (!stretch) {
if (w > w1)
w1 = w;
if (h > h1)
h1 = h;
}
CBitmap bitmap, *pOldBitmap;
bitmap.CreateCompatibleBitmap(dc, w1, h1);
pOldBitmap = memDC.SelectObject(&bitmap);
if (stretch) {
bmpInfo->bmiHeader.biWidth = w;
bmpInfo->bmiHeader.biHeight = -h;
StretchDIBits(memDC.GetSafeHdc(),
0,
0,
w1,
h1,
0,
0,
w,
h,
data,
bmpInfo,
DIB_RGB_COLORS,
SRCCOPY);
} else {
FillOutsideRect(&memDC, CBrush::FromHandle(GetSysColorBrush(COLOR_BTNFACE)));
bmpInfo->bmiHeader.biWidth = w;
bmpInfo->bmiHeader.biHeight = -h;
SetDIBitsToDevice(memDC.GetSafeHdc(),
0,
0,
w,
h,
0,
0,
0,
h,
data,
bmpInfo,
DIB_RGB_COLORS);
}
dc->BitBlt(0, 0, w1, h1,
&memDC, 0, 0, SRCCOPY);
if (boxreigon.right != 0 && boxreigon.bottom != 0) {
CBrush br = CBrush(RGB(255, 0, 0));
dc->FrameRect(&boxreigon, &br);
}
memDC.SelectObject(pOldBitmap);
bitmap.DeleteObject();
memDC.DeleteDC();
}
/////////////////////////////////////////////////////////////////////////////
// BitmapControl diagnostics
#ifdef _DEBUG
void BitmapControl::AssertValid() const
{
CScrollView::AssertValid();
}
void BitmapControl::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// BitmapControl message handlers
BOOL BitmapControl::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void BitmapControl::OnSize(UINT nType, int cx, int cy)
{
if (!stretch)
CScrollView::OnSize(nType, cx, cy);
}
void BitmapControl::OnLButtonDown(UINT nFlags, CPoint pt)
{
GetParent()->SendMessage(WM_BITMAPCLICK,
GetDlgCtrlID(),
0);
if (!data)
return;
int x = pt.x;
int y = pt.y;
WPARAM point;
if (stretch) {
RECT rect;
GetClientRect(&rect);
int height = rect.bottom - rect.top;
int width = rect.right - rect.left;
int xx = (x * w) / width;
int yy = (y * h) / height;
point = xx | (yy << 16);
int xxx = xx / 8;
int yyy = yy / 8;
for (int i = 0; i < 8; i++) {
memcpy(&colors[i * 3 * 8], &data[xxx * 8 * 3 + w * yyy * 8 * 3 + i * w * 3], 8 * 3);
}
} else {
POINT p;
p.x = GetScrollPos(SB_HORZ);
p.y = GetScrollPos(SB_VERT);
p.x += x;
p.y += y;
if (p.x >= w || p.y >= h)
return;
point = p.x | (p.y << 16);
int xxx = p.x / 8;
int yyy = p.y / 8;
for (int i = 0; i < 8; i++) {
memcpy(&colors[i * 3 * 8], &data[xxx * 8 * 3 + w * yyy * 8 * 3 + i * w * 3], 8 * 3);
}
}
GetParent()->SendMessage(WM_MAPINFO,
point,
(LPARAM)colors);
}
void BitmapControl::setBmpInfo(BITMAPINFO* info)
{
bmpInfo = info;
}
void BitmapControl::setData(uint8_t* d)
{
data = d;
}
void BitmapControl::setSize(int w1, int h1)
{
if (w != w1 || h != h1) {
w = w1;
h = h1;
SIZE s;
s.cx = w;
s.cy = h;
SetScrollSizes(MM_TEXT, s);
}
}
void BitmapControl::setSelectedRectangle(int x, int y, int width, int height)
{
boxreigon.left = x;
boxreigon.right = x + width;
boxreigon.top = y;
boxreigon.bottom = y + height;
}
void BitmapControl::refresh()
{
Invalidate();
}
void BitmapControl::registerClass()
{
if (!isRegistered) {
WNDCLASS wc;
ZeroMemory(&wc, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
wc.lpfnWndProc = (WNDPROC)::DefWindowProc;
wc.hInstance = AfxGetInstanceHandle();
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "VbaBitmapControl";
AfxRegisterClass(&wc);
isRegistered = true;
}
}
void BitmapControl::setStretch(bool b)
{
if (b != stretch) {
stretch = b;
Invalidate();
}
}
bool BitmapControl::getStretch()
{
return stretch;
}
void BitmapControl::PostNcDestroy()
{
}