275 lines
5.7 KiB
C++
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()
|
|
{
|
|
}
|