📄 laomapedtview.cpp
字号:
break;
}
default:
break;
}
CScrollView::OnLButtonDown(nFlags, point);
}
void CLaoMapEdtView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CPoint ptEnd = point;
Pos2Map(ptEnd);
CRect rc(m_ptStart, ptEnd);
rc.NormalizeRect();
rc.right += 1;
rc.bottom += 1;
rc = rc & CRect(0, 0, m_lBkWidth/_BLOCK_SIZE, m_lBkHeight/_BLOCK_SIZE);
if (m_bIsLBtDown)
{
m_bIsLBtDown = FALSE;
ReleaseCapture();
switch (m_euType)
{
case _CLOG:
{
SAFE_DELETE(m_pLastRect);
DrawSelRect(rc);
SAFE_DELETE(m_pLastRect);
for (long y=rc.top; y<rc.bottom; y++)
{
for (long x=rc.left; x<rc.right; x++)
{
long index = x + y*m_lBkWidth/_BLOCK_SIZE;
WORD mask = m_pArray[index] & 1;
if (mask == 1)
{
m_pArray[index] &= 0xfe;
}
else
{
m_pArray[index] |= 0x01;
}
}
}
Invalidate(FALSE);
break;
}
case _LAYER:
{
SAFE_DELETE(m_pLastRect);
DrawSelRect(rc);
SAFE_DELETE(m_pLastRect);
CMainFrame *pmainfrm = (CMainFrame*)AfxGetMainWnd();
BYTE btLayer = pmainfrm->GetLayer();
WORD mask = btLayer << 8;
for (long y=rc.top; y<rc.bottom; y++)
{
for (long x=rc.left; x<rc.right; x++)
{
long index = x + y*m_lBkWidth/_BLOCK_SIZE;
m_pArray[index] = mask | (m_pArray[index]&0x0f);
}
}
Invalidate(FALSE);
AnalLayerRect();
break;
}
default:
break;
}
}
CScrollView::OnLButtonUp(nFlags, point);
}
void CLaoMapEdtView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CPoint ptEnd = point;
Pos2Map(ptEnd);
CRect rc(m_ptStart, ptEnd);
rc.NormalizeRect();
rc.right += 1;
rc.bottom += 1;
rc = rc & CRect(0, 0, m_lBkWidth/_BLOCK_SIZE, m_lBkHeight/_BLOCK_SIZE);
if (m_bIsLBtDown)
{
switch (m_euType)
{
case _CLOG:
case _LAYER:
{
DrawSelRect(rc);
break;
}
default:
break;
}
}
CScrollView::OnMouseMove(nFlags, point);
}
void CLaoMapEdtView::Pos2Map(CPoint &pt)
{
pt.x += GetScrollPos(SB_HORZ);
pt.y += GetScrollPos(SB_VERT);
pt.x >>= 4;
pt.y >>= 4;
}
void CLaoMapEdtView::Pos2Map(CRect &rc)
{
rc.OffsetRect(-GetScrollPos(SB_HORZ), -GetScrollPos(SB_VERT));
rc.top >>= 4;
rc.left >>= 4;
rc.bottom >>= 4;
rc.right >>= 4;
}
void CLaoMapEdtView::DrawSelRect(CPoint &pt, long cx, long cy)
{
DrawSelRect(CRect(pt.x, pt.y, pt.x+cx, pt.y+cy));
}
void CLaoMapEdtView::DrawSelRect(CPoint &pt1, CPoint pt2)
{
DrawSelRect(CRect(pt1, pt2));
}
void CLaoMapEdtView::DrawSelRect(CRect &rc)
{
CDC *pDc = GetDC();
CRect rect = rc;
rect.top <<= 4;
rect.left <<= 4;
rect.bottom <<= 4;
rect.right <<= 4;
CRect CurRect = rect;
CurRect.OffsetRect(-GetScrollPos(SB_HORZ), -GetScrollPos(SB_VERT));
m_pLastRect->OffsetRect(-GetScrollPos(SB_HORZ), -GetScrollPos(SB_VERT));
pDc->DrawDragRect(&CurRect, CSize(1,1), m_pLastRect, CSize(1,1));
if (!m_pLastRect)
{
m_pLastRect = new CRect;
}
*m_pLastRect = rect;
ReleaseDC(pDc);
}
void CLaoMapEdtView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
CScrollView::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CLaoMapEdtView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);
}
BOOL CLaoMapEdtView::OpenBk()
{
CString filename;
CString ext;
if (m_csPicName.IsEmpty())
{
CFileDialog objFileDlg(TRUE, NULL, NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
"位图文件(*.bmp)|*.bmp|JPEG 文件(*.jpg)|*.jpg|", NULL);
if (objFileDlg.DoModal() == IDCANCEL)
return FALSE;
filename = objFileDlg.GetFileName();
}
else
{
filename = m_csPicName;
}
ext = filename.Right(3);
ext.MakeLower();
CBitmap *pbmp = NULL;
if (ext == "jpg")
{
BeginWaitCursor();
pbmp = JPG2CBitmap(filename);
EndWaitCursor();
}
else if (ext == "bmp")
{
BeginWaitCursor();
HBITMAP hbm = (HBITMAP)LoadImage(AfxGetInstanceHandle(), filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if (!hbm)
{
AfxMessageBox("无法读取bmp图片");
EndWaitCursor();
return FALSE;
}
pbmp = CBitmap::FromHandle(hbm);
if (!pbmp)
{
AfxMessageBox("无法读取bmp图片");
SAFE_DELETE(pbmp);
EndWaitCursor();
return FALSE;
}
EndWaitCursor();
}
else
{
AfxMessageBox("文件格式错误!");
return FALSE;
}
if (!pbmp)
{
AfxMessageBox("无法打开图片文件");
return FALSE;
}
long width,height;
BITMAP bmp;
pbmp->GetBitmap(&bmp);
width = bmp.bmWidth;
height = bmp.bmHeight;
if (width % 8 != 0) //调整宽度到8的整数倍
{
width = (width/_BLOCK_SIZE + 1) * _BLOCK_SIZE;
}
if (height % _BLOCK_SIZE != 0)
{
height = (height/_BLOCK_SIZE + 1) * _BLOCK_SIZE;
}
ReleaseDDraw();
if (!InitDDraw(m_hWnd, width, height))
{
AfxMessageBox("DirectDraw对象创建失败");
return FALSE;
}
if (m_pbmBackPic)
{
if (m_pbmBackPic->m_hObject)
{
m_pbmBackPic->DeleteObject();
}
SAFE_DELETE(m_pbmBackPic);
}
m_pbmBackPic = new CBitmap;
if (!m_pbmBackPic)
{
pbmp->DeleteObject();
SAFE_DELETE(pbmp);
AfxMessageBox("无法打开图片文件");
return FALSE;
}
CClientDC dc(this);
if (!m_pbmBackPic->CreateCompatibleBitmap(&dc, width, height))
{
pbmp->DeleteObject();
SAFE_DELETE(pbmp);
SAFE_DELETE(m_pbmBackPic);
AfxMessageBox("无法创建位图缓冲!");
return FALSE;
}
CDC SDc, DDc;
if (!SDc.CreateCompatibleDC(NULL))
{
pbmp->DeleteObject();
SAFE_DELETE(pbmp);
m_pbmBackPic->DeleteObject();
SAFE_DELETE(m_pbmBackPic);
AfxMessageBox("无法将图片复制到位图缓冲!");
return FALSE;
}
if (!DDc.CreateCompatibleDC(NULL))
{
SDc.DeleteDC();
pbmp->DeleteObject();
SAFE_DELETE(pbmp);
m_pbmBackPic->DeleteObject();
SAFE_DELETE(m_pbmBackPic);
AfxMessageBox("无法将图片复制到位图缓冲!");
return FALSE;
}
BITMAP bm;
pbmp->GetBitmap(&bm);
CBitmap *SOld = SDc.SelectObject(pbmp);
CBitmap *DOld = DDc.SelectObject(m_pbmBackPic);
DDc.BitBlt(0, 0, width, height, &SDc, 0, 0, SRCCOPY);
HDC hdc;
g_lpBackBuffer->GetDC(&hdc);
BitBlt(hdc, 0, 0, width, height, DDc.GetSafeHdc(), 0, 0, SRCCOPY);
g_lpBackBuffer->ReleaseDC(hdc);
SDc.SelectObject(SOld);
DDc.SelectObject(DOld);
SDc.DeleteDC();
DDc.DeleteDC();
pbmp->DeleteObject();
m_lBkWidth = width;
m_lBkHeight = height;
m_csPicName = filename;
return TRUE;
}
void CLaoMapEdtView::AnalLayerRect()
{
const long lLogicalX = m_lBkWidth / _BLOCK_SIZE;
const long lLogicalY = m_lBkHeight / _BLOCK_SIZE;
BYTE btPreLayer = 0;
WORD x,y;
ReleaseAllLayerRect();
TRACE("================================begin================================\n");
for (y=0; y<lLogicalY; y++)
{
WORD wStartPoint = 0;
BYTE btPrePt = m_pArray[y*lLogicalX] >> 8;
BYTE btLayer;
for (x=1; x<lLogicalX; x++)
{
btLayer = m_pArray[x+y*lLogicalX] >> 8;
if (btPrePt != btLayer)
{
TRACE("**************BEGIN1************\n");
UnitRect(btPrePt, y*_BLOCK_SIZE, wStartPoint*_BLOCK_SIZE, (x-1)*_BLOCK_SIZE);
TRACE("**************END1************\n");
wStartPoint = x;
}
btPrePt = btLayer;
}
TRACE("**************BEGIN2************\n");
UnitRect(btLayer, y*_BLOCK_SIZE, wStartPoint*_BLOCK_SIZE, (x-1)*_BLOCK_SIZE);
TRACE("**************END2************\n");
}
TRACE("================================end================================\n");
}
void CLaoMapEdtView::UnitRect(BYTE layer, WORD line, WORD s, WORD e)
{
//首先处理第一次出现的层的情况
//这种情况下只需要简单创建一个CRect添加到链表中就可以了
if (m_pLayerRect[layer] == NULL)
{
m_pLayerRect[layer] = new CRectList(s, line, e, line);
return;
}
//接着是非第一次出现的层
//这时先检查在已有的矩形中是否能合并上新的矩形(比较x坐标范围是否相等,以及y左边是否连续)
//如果可以就合并矩形
CRectList *pRect = m_pLayerRect[layer];
CRect rc(s, line, e, line);
while (pRect)
{
if (pRect->bottom+1 != line)
{
pRect = pRect->m_pNext;
continue;
}
//与上面矩形没有相交
if (pRect->left>e || pRect->right<s)
{
pRect = pRect->m_pNext;
continue;
}
//正好与上面矩形重合
if (pRect->left==s && pRect->right==e)
{
pRect->bottom++;
TRACE("正好与上面矩形重合\n");
return;
}
//有一端和矩形重合,另一端不重合
if (pRect->left == s) //左端重合
{
if (pRect->right < e) //右端在矩形外
{
pRect->bottom++;
s = pRect->right + 1;
TRACE("左端重合,右端在矩形外\n");
pRect = m_pLayerRect[layer];
continue;
}
else //右端在矩形内
{
CRectList *right = new CRectList(e+1, pRect->top, pRect->right, pRect->bottom);
pRect->SetRect(s, pRect->top, e, pRect->bottom+1);
right->m_pNext = pRect->m_pNext;
pRect->m_pNext = right;
TRACE("左端重合,右端在矩形内\n");
return;
}
}
else if (pRect->right == e) //右端重合
{
if (pRect->left > s) //左端在矩形外
{
pRect->bottom++;
e = pRect->left - 1;
TRACE("右端重合,左端在矩形外\n");
pRect = m_pLayerRect[layer];
continue;
}
else //左端在矩形内
{
CRectList *left = new CRectList(pRect->left, pRect->top, s-1, pRect->bottom);
pRect->SetRect(s, pRect->top, e, pRect->bottom+1);
left->m_pNext = pRect->m_pNext;
pRect->m_pNext = left;
TRACE("右端重合,左端在矩形内\n");
return;
}
}
//在上面矩形范围内
if (pRect->left<s && pRect->right>e)
{
CRectList *left = new CRectList(pRect->left, pRect->top, s-1, pRect->bottom);
CRectList *right = new CRectList(e+1, pRect->top, pRect->right, pRect->bottom);
pRect->SetRect(s, pRect->top, e, pRect->bottom+1);
left->m_pNext = right;
right->m_pNext = pRect->m_pNext;
pRect->m_pNext = left;
TRACE("在上面矩形范围内\n");
return;
}
//超过上面矩形范围
if (pRect->left>s && pRect->right<e)
{
pRect->bottom++;
UnitRect(layer, line, s, pRect->left-1);
UnitRect(layer, line, pRect->right+1, e);
TRACE("超过上面矩形范围\n");
return;
}
//在上面矩形偏左
if (pRect->left>s && pRect->left<e)
{
CRectList *right = new CRectList(e+1, pRect->top, pRect->right, pRect->bottom);
pRect->SetRect(pRect->left, pRect->top, e, pRect->bottom+1);
right->m_pNext = pRect->m_pNext;
pRect->m_pNext = right;
e = pRect->left - 1;
TRACE("在上面矩形偏左\n");
pRect = m_pLayerRect[layer];
continue;
}
//在上面矩形偏右
if (pRect->right>s && pRect->right<e)
{
CRectList *left = new CRectList(pRect->left, pRect->top, s-1, pRect->bottom);
pRect->SetRect(s, pRect->top, pRect->right, pRect->bottom+1);
s = pRect->right + 1;
left->m_pNext = pRect->m_pNext;
pRect->m_pNext = left;
TRACE("在上面矩形偏右\n");
pRect = m_pLayerRect[layer];
continue;
}
pRect = pRect->m_pNext;
}
//如果无法合并就创建一个新CRect添加到链表中
CRectList *pRc = new CRectList(s, line, e, line);
pRc->m_pNext = m_pLayerRect[layer];
m_pLayerRect[layer] = pRc;
TRACE("如果无法合并就创建一个新CRect添加到链表中\n");
}
void CLaoMapEdtView::ReleaseAllLayerRect()
{
for (BYTE i=0; i<0xff; i++)
{
while (m_pLayerRect[i])
{
CRectList *temp = m_pLayerRect[i];
m_pLayerRect[i] = m_pLayerRect[i]->m_pNext;
SAFE_DELETE(temp);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -