4#include <afxdialogex.h>
8#include "ChineseChessView.h"
12#pragma comment(lib, "winmm")
16static char THIS_FILE[] = __FILE__;
24CChineseChessView::CChineseChessView()
26 m_pGoChessHandler =
nullptr;
28 m_QiPangColor = RGB(0, 0, 0);
29 m_TiShiBoxColor = RGB(0, 255, 0);
31 m_QiPangStartX = m_QiPangStartY = 0;
34 if (m_Chu.GetSafeHandle() == NULL)
35 m_Chu.LoadBitmap(IDB_CHU);
36 if (m_He.GetSafeHandle() == NULL)
37 m_He.LoadBitmap(IDB_HE);
38 if (m_Han.GetSafeHandle() == NULL)
39 m_Han.LoadBitmap(IDB_HAN);
40 if (m_Jie.GetSafeHandle() == NULL)
41 m_Jie.LoadBitmap(IDB_JIE);
42 if (m_Copyright.GetSafeHandle() == NULL)
43 m_Copyright.LoadBitmap(IDB_KL);
45#ifdef CHINESE_CHESS_USE_PNG
46 LoadImageFromResource(&m_QiPangPicture, _T(
"IDJ_QIPANG"), _T(
"JPG"));
47 LoadImageFromResource(&m_RedShuai, IDP_RSHUAI);
48 LoadImageFromResource(&m_RedShi, IDP_RSHI);
49 LoadImageFromResource(&m_RedXiang, IDP_RXIANG);
50 LoadImageFromResource(&m_RedMa, IDP_RMA);
51 LoadImageFromResource(&m_RedChe, IDP_RJU);
52 LoadImageFromResource(&m_RedPao, IDP_RPAO);
53 LoadImageFromResource(&m_RedBing, IDP_RBING);
55 LoadImageFromResource(&m_BlackShuai, IDP_BJIANG);
56 LoadImageFromResource(&m_BlackShi, IDP_BSHI);
57 LoadImageFromResource(&m_BlackXiang, IDP_BXIANG);
58 LoadImageFromResource(&m_BlackMa, IDP_BMA);
59 LoadImageFromResource(&m_BlackChe, IDP_BJU);
60 LoadImageFromResource(&m_BlackPao, IDP_BPAO);
61 LoadImageFromResource(&m_BlackBing, IDP_BBING);
63 if (m_QiPangPicture.GetSafeHandle() == NULL)
64 m_QiPangPicture.LoadBitmap(IDB_QIPANG);
66 if (m_RedShuai.GetSafeHandle() == NULL)
68 m_RedShuai.LoadBitmap(IDB_RSHUAI);
71 if (m_RedShi.GetSafeHandle() == NULL)
73 m_RedShi.LoadBitmap(IDB_RSHI);
76 if (m_RedXiang.GetSafeHandle() == NULL)
78 m_RedXiang.LoadBitmap(IDB_RXIANG);
81 if (m_RedMa.GetSafeHandle() == NULL)
83 m_RedMa.LoadBitmap(IDB_RMA);
86 if (m_RedChe.GetSafeHandle() == NULL)
88 m_RedChe.LoadBitmap(IDB_RCHE);
91 if (m_RedPao.GetSafeHandle() == NULL)
93 m_RedPao.LoadBitmap(IDB_RPAO);
96 if (m_RedBing.GetSafeHandle() == NULL)
98 m_RedBing.LoadBitmap(IDB_RBING);
102 if (m_BlackShuai.GetSafeHandle() == NULL)
104 m_BlackShuai.LoadBitmap(IDB_BSHUAI);
107 if (m_BlackShi.GetSafeHandle() == NULL)
109 m_BlackShi.LoadBitmap(IDB_BSHI);
112 if (m_BlackXiang.GetSafeHandle() == NULL)
114 m_BlackXiang.LoadBitmap(IDB_BXIANG);
117 if (m_BlackMa.GetSafeHandle() == NULL)
119 m_BlackMa.LoadBitmap(IDB_BMA);
122 if (m_BlackChe.GetSafeHandle() == NULL)
124 m_BlackChe.LoadBitmap(IDB_BCHE);
127 if (m_BlackPao.GetSafeHandle() == NULL)
129 m_BlackPao.LoadBitmap(IDB_BPAO);
132 if (m_BlackBing.GetSafeHandle() == NULL)
134 m_BlackBing.LoadBitmap(IDB_BBING);
140CChineseChessView::~CChineseChessView()
153 if (__super::OnCreate(lpCreateStruct) == -1)
160void CChineseChessView::OnLButtonUp(UINT nFlags, CPoint point)
163 ConvertCoordinate(&point.x, &point.y, &i, &j);
164 TRACE(_T(
"point: i = %d j = %d\n"), i, j);
165 TRACE(_T(
"CXQCtrl::OnLButtonUp的当前线程:%x\n"), ::GetCurrentThreadId());
171 CView::OnLButtonUp(nFlags, point);
175void CChineseChessView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
179 CView::OnKeyUp(nChar, nRepCnt, nFlags);
183void CChineseChessView::OnSize(UINT nType,
int cx,
int cy)
185 CView::OnSize(nType, cx, cy);
191void CChineseChessView::OnDraw(CDC* pDC)
194 GetClientRect(&rect);
195 pDC->SetStretchBltMode(HALFTONE);
196 DrawQiPang(pDC, rect);
199void CChineseChessView::AboutBox()
201 CDialogEx dlgAbout(IDD_ABOUTBOX_CHINESECHESSACTIVEX);
209int CChineseChessView::onPromptSound(PROMPT_SOUND sound)
215 pId = _T(
"IDW_CHECK");
224 pId = _T(
"IDW_DEAD");
227 pId = _T(
"IDW_SELECT");
241 case CGoRule::BEIJIANGJUN:
242 ::MessageBox(GetSafeHwnd(), _T(
"这步不能走,否则会输棋!"), _T(
"被将军"), MB_OK);
244 case CGoRule::JIANGDUIMIAN:
245 ::MessageBox(GetSafeHwnd(), _T(
"这步不能走,否则会输棋!"), _T(
"将对面"), MB_OK);
253 InvalidateRectage(i, j);
259 InvalidateRectage(i, j);
265 if (m_pGoChessHandler)
266 m_pGoChessHandler->
OnGoChess(i, j, chess);
272 m_pGoChessHandler = handler;
276int CChineseChessView::SaveChessGame(LPCTSTR pszFile)
279 return __super::SaveChessGame(T2CA(pszFile));
282int CChineseChessView::LoadChessGame(LPCTSTR pszFile)
286 nRet = __super::LoadChessGame(T2CA(pszFile));
287 if (nRet)
return nRet;
292int CChineseChessView::SetRedName(LPCTSTR pszName)
295 return __super::SetRedName(T2CA(pszName));
298int CChineseChessView::SetBlackName(LPCTSTR pszName)
301 return __super::SetBlackName(T2CA(pszName));
304int CChineseChessView::AddGameTag(LPCTSTR pszTag, LPCTSTR pszVal)
307 return __super::AddGameTag(T2CA(pszTag), T2CA(pszVal));
310CString CChineseChessView::GetGameTag(LPCTSTR pszTag)
313 return A2CT(__super::GetGameTag(T2CA(pszTag)).c_str());
320int CChineseChessView::SetQiPangColor(COLORREF col)
327COLORREF CChineseChessView::GetQiPangColor()
329 return m_QiPangColor;
332int CChineseChessView::SetTiShiBoxColor(COLORREF col)
334 m_TiShiBoxColor = col;
339COLORREF CChineseChessView::GetTiShiBoxColor()
341 return m_TiShiBoxColor;
356BOOL CChineseChessView::SetQiPang(
int width,
int height)
360 m_QiPangDistance = height / 11;
361 m_QiPangStartX = (width - m_QiPangDistance * 10) / 2 + m_QiPangDistance;
362 m_QiPangStartY = m_QiPangDistance;
366 m_QiPangDistance = width / 10;
367 m_QiPangStartX = m_QiPangDistance;
368 m_QiPangStartY = (height - m_QiPangDistance * 11) / 2 + m_QiPangDistance;
400void TransparentBlt2(HDC hdcDest,
413 HBITMAP hOldImageBMP, hImageBMP = CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest);
414 HBITMAP hOldMaskBMP, hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);
415 HDC hImageDC = CreateCompatibleDC(hdcDest);
416 HDC hMaskDC = CreateCompatibleDC(hdcDest);
417 hOldImageBMP = (HBITMAP)SelectObject(hImageDC, hImageBMP);
418 hOldMaskBMP = (HBITMAP)SelectObject(hMaskDC, hMaskBMP);
421 if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
422 BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
424 StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest,
425 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
428 SetBkColor(hImageDC, crTransparent);
431 BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY);
434 SetBkColor(hImageDC, RGB(0, 0, 0));
435 SetTextColor(hImageDC, RGB(255, 255, 255));
436 BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);
439 SetBkColor(hdcDest, RGB(0xff, 0xff, 0xff));
440 SetTextColor(hdcDest, RGB(0, 0, 0));
441 BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);
444 BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);
446 SelectObject(hImageDC, hOldImageBMP);
448 SelectObject(hMaskDC, hOldMaskBMP);
450 DeleteObject(hImageBMP);
451 DeleteObject(hMaskBMP);
454#ifdef CHINESE_CHESS_USE_PNG
455BOOL CChineseChessView::LoadImageFromResource(CImage *pImage, UINT ID, LPCTSTR pType)
457 return LoadImageFromResource(pImage, MAKEINTRESOURCE(ID), pType);
473BOOL CChineseChessView::LoadImageFromResource(CImage* pImage, LPCTSTR pID, LPCTSTR lpType)
475 if (pImage == NULL)
return false;
480 HINSTANCE hInstance = AfxFindResourceHandle(pID, lpType);
482 HINSTANCE hInstance = AfxGetInstanceHandle();
486 HRSRC hRsrc = ::FindResource(hInstance, pID, lpType);
487 if (hRsrc == NULL)
return false;
490 HGLOBAL hImgData = ::LoadResource(hInstance, hRsrc);
491 if (hImgData == NULL)
493 ::FreeResource(hImgData);
498 LPVOID lpVoid = ::LockResource(hImgData);
500 LPSTREAM pStream = NULL;
501 DWORD dwSize = ::SizeofResource(hInstance, hRsrc);
502 HGLOBAL hNew = ::GlobalAlloc(GHND, dwSize);
503 LPBYTE lpByte = (LPBYTE)::GlobalLock(hNew);
504 ::memcpy(lpByte, lpVoid, dwSize);
507 ::GlobalUnlock(hNew);
510 HRESULT ht = ::CreateStreamOnHGlobal(hNew, TRUE, &pStream);
518 pImage->Load(pStream);
523 ::FreeResource(hImgData);
541BOOL CChineseChessView::PromptSound(LPCTSTR ID)
547 HINSTANCE hInstance = AfxFindResourceHandle(ID, _T(
"WAVE"));
549 HINSTANCE hInstance = AfxGetInstanceHandle();
552 HRSRC hr = FindResource(hInstance, ID, _T(
"WAVE"));
553 if (NULL == hr)
return false;
555 HGLOBAL hg = LoadResource(hInstance, hr);
556 LPCTSTR lp = (LPCTSTR)LockResource(hg);
557 ::sndPlaySound(lp, SND_MEMORY | SND_ASYNC);
584BOOL CChineseChessView::ConvertCoordinate(
long *x,
long *y,
int *i,
int *j, ENUM_ConvertCoordinate eCC)
589 *i = (*x - m_QiPangStartX + m_QiPangDistance / 2) / m_QiPangDistance;
590 *j = (*y - m_QiPangStartY + m_QiPangDistance / 2) / m_QiPangDistance;
593 *x = m_QiPangStartX + *i * m_QiPangDistance;
594 *y = m_QiPangStartY + *j * m_QiPangDistance;
621void CChineseChessView::DrawQiPang(CDC *pdc, CRect rcBounds)
626#ifdef CHINESE_CHESS_USE_PNG
627 m_QiPangPicture.Draw(pdc->m_hDC, rcBounds);
630 m_QiPangPicture.GetBitmap(&bitmap);
633 psdc.CreateCompatibleDC(pdc);
634 psdc.SelectObject(&m_QiPangPicture);
636 pdc->StretchBlt(0, 0, rcBounds.Width(), rcBounds.Height(),
637 &psdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
643 for (i = 0; i < 9; i++)
645 if (i == 0 || i == 8)
648 Pen.CreatePen(PS_SOLID, 2, m_QiPangColor);
649 oldPen = (CPen*)pdc->SelectObject(&Pen);
651 pdc->MoveTo(m_QiPangStartX + i * m_QiPangDistance,
653 pdc->LineTo(m_QiPangStartX + i * m_QiPangDistance,
654 m_QiPangStartY + 9 * m_QiPangDistance);
656 pdc->SelectObject(&oldPen);
661 Pen.CreatePen(PS_SOLID, 1, m_QiPangColor);
662 oldPen = (CPen*)pdc->SelectObject(&Pen);
664 pdc->MoveTo(m_QiPangStartX + i * m_QiPangDistance,
666 pdc->LineTo(m_QiPangStartX + i * m_QiPangDistance,
667 m_QiPangStartY + 4 * m_QiPangDistance);
669 pdc->MoveTo(m_QiPangStartX + i * m_QiPangDistance,
670 m_QiPangStartY + 5 * m_QiPangDistance);
671 pdc->LineTo(m_QiPangStartX + i * m_QiPangDistance,
672 m_QiPangStartY + 9 * m_QiPangDistance);
674 pdc->SelectObject(&oldPen);
678 for (i = 0; i < 10; i++)
681 if (i == 0 || i == 9)
683 Pen.CreatePen(PS_SOLID, 2, m_QiPangColor);
684 oldPen = (CPen*)pdc->SelectObject(&Pen);
688 Pen.CreatePen(PS_SOLID, 1, m_QiPangColor);
689 oldPen = (CPen*)pdc->SelectObject(&Pen);
693 pdc->MoveTo(m_QiPangStartX,
694 m_QiPangStartY + i * m_QiPangDistance);
695 pdc->LineTo(m_QiPangStartX + 8 * m_QiPangDistance,
696 m_QiPangStartY + i * m_QiPangDistance);
698 pdc->SelectObject(&oldPen);
703 Pen.CreatePen(PS_SOLID, 1, m_QiPangColor);
704 oldPen = (CPen*)pdc->SelectObject(&Pen);
706 pdc->MoveTo(m_QiPangStartX + 3 * m_QiPangDistance,
708 pdc->LineTo(m_QiPangStartX + 5 * m_QiPangDistance,
709 m_QiPangStartY + 2 * m_QiPangDistance);
711 pdc->MoveTo(m_QiPangStartX + 5 * m_QiPangDistance,
713 pdc->LineTo(m_QiPangStartX + 3 * m_QiPangDistance,
714 m_QiPangStartY + 2 * m_QiPangDistance);
716 pdc->MoveTo(m_QiPangStartX + 3 * m_QiPangDistance,
717 m_QiPangStartY + 7 * m_QiPangDistance);
718 pdc->LineTo(m_QiPangStartX + 5 * m_QiPangDistance,
719 m_QiPangStartY + 9 * m_QiPangDistance);
721 pdc->MoveTo(m_QiPangStartX + 5 * m_QiPangDistance,
722 m_QiPangStartY + 7 * m_QiPangDistance);
723 pdc->LineTo(m_QiPangStartX + 3 * m_QiPangDistance,
724 m_QiPangStartY + 9 * m_QiPangDistance);
726 pdc->SelectObject(&oldPen);
729 DrawXinWei(pdc, 1, 2);
730 DrawXinWei(pdc, 7, 2);
731 DrawXinWei(pdc, 1, 7);
732 DrawXinWei(pdc, 7, 7);
733 DrawXinWei(pdc, 0, 3, Right_XinWei);
734 DrawXinWei(pdc, 2, 3);
735 DrawXinWei(pdc, 4, 3);
736 DrawXinWei(pdc, 6, 3);
737 DrawXinWei(pdc, 8, 3, Left_XinWei);
738 DrawXinWei(pdc, 0, 6, Right_XinWei);
739 DrawXinWei(pdc, 2, 6);
740 DrawXinWei(pdc, 4, 6);
741 DrawXinWei(pdc, 6, 6);
742 DrawXinWei(pdc, 8, 6, Left_XinWei);
745 DrawPicture(pdc, 7, 4, &m_Chu,
true);
746 DrawPicture(pdc, 6, 4, &m_He,
true);
747 DrawPicture(pdc, 1, 4, &m_Han,
true);
748 DrawPicture(pdc, 2, 4, &m_Jie,
true);
749 DrawPicture(pdc, 4, 4, &m_Copyright,
true);
752 for (i = 0; i < 9; i++)
753 for (j = 0; j < 10; j++)
759 if (IsValidPosition(m_PreviouPositionX, m_PreviouPositionY))
760 DrawTiShiBox(pdc, m_PreviouPositionX, m_PreviouPositionY);
761 if (IsValidPosition(m_CurrentPositionX, m_CurrentPositionY))
762 DrawTiShiBox(pdc, m_CurrentPositionX, m_CurrentPositionY);
783void CChineseChessView::DrawXinWei(CDC *pdc,
int i,
int j, ENUM_XINWEI xinwei)
788 d = m_QiPangDistance * 4 / 10;
789 ds = m_QiPangDistance * 2 / 10;
794 ConvertCoordinate(&x, &y, &i, &j, IJToXY);
797 Pen.CreatePen(PS_SOLID, 1, m_QiPangColor);
798 oldPen = (CPen*)pdc->SelectObject(&Pen);
800 if (xinwei != Left_XinWei)
823 if (xinwei != Right_XinWei)
845 pdc->SelectObject(&oldPen);
860BOOL CChineseChessView::DrawTiShiBox(CDC *pdc,
int i,
int j)
864 long m_X, m_Y, m_L = m_QiPangDistance / 2;
866 pen.CreatePen(PS_SOLID, 2, m_TiShiBoxColor);
867 oldpen = (CPen*)pdc->SelectObject(&pen);
869 ConvertCoordinate(&m_X, &m_Y, &i, &j, IJToXY);
870 pdc->MoveTo(m_X - m_L, m_Y - m_L);
871 pdc->LineTo(m_X - m_L, m_Y - m_L / 2);
873 pdc->MoveTo(m_X - m_L, m_Y - m_L);
874 pdc->LineTo(m_X - m_L / 2, m_Y - m_L);
876 pdc->MoveTo(m_X + m_L, m_Y + m_L);
877 pdc->LineTo(m_X + m_L, m_Y + m_L / 2);
879 pdc->MoveTo(m_X + m_L, m_Y + m_L);
880 pdc->LineTo(m_X + m_L / 2, m_Y + m_L);
882 pdc->MoveTo(m_X - m_L, m_Y + m_L);
883 pdc->LineTo(m_X - m_L, m_Y + m_L / 2);
885 pdc->MoveTo(m_X - m_L, m_Y + m_L);
886 pdc->LineTo(m_X - m_L / 2, m_Y + m_L);
888 pdc->MoveTo(m_X + m_L, m_Y - m_L);
889 pdc->LineTo(m_X + m_L, m_Y - m_L / 2);
891 pdc->MoveTo(m_X + m_L, m_Y - m_L);
892 pdc->LineTo(m_X + m_L / 2, m_Y - m_L);
895 pdc->SelectObject(oldpen);
912BOOL CChineseChessView::DrawQiZi(CDC *pdc,
int i,
int j, CPiece::ENUM_QiZi eQiZi)
915#ifdef CHINESE_CHESS_USE_PNG
916 CImage *pQiZi = NULL;
918 CBitmap *pQiZi = NULL;
921#pragma warning( disable : 4806 )
949 pQiZi = &m_BlackShuai;
955 pQiZi = &m_BlackXiang;
967 pQiZi = &m_BlackBing;
971#pragma warning( default : 4806 )
975 return DrawPicture(pdc, i, j, pQiZi);
981#ifdef CHINESE_CHESS_USE_PNG
982BOOL CChineseChessView::DrawPicture(CDC *pdc,
int i,
int j, CImage* pImage)
984 ASSERT(pdc != NULL && pImage != NULL);
988 ConvertCoordinate(&x, &y, &i, &j, IJToXY);
989 x -= m_QiPangDistance / 2;
990 y -= m_QiPangDistance / 2;
991 return pImage->Draw(pdc->m_hDC, x, y, m_QiPangDistance, m_QiPangDistance);
1010BOOL CChineseChessView::DrawPicture(CDC *pdc,
int i,
int j, CBitmap *pbmp, BOOL CHHJKL)
1012 ASSERT(pdc != NULL && pbmp != NULL);
1013 if (pbmp->GetSafeHandle() == NULL)
1018 ConvertCoordinate(&x, &y, &i, &j, IJToXY);
1021 x -= m_QiPangDistance / 2;
1025 x -= m_QiPangDistance / 2;
1026 y -= m_QiPangDistance / 2;
1031 pbmp->GetBitmap(&bitmap);
1034 psdc.CreateCompatibleDC(pdc);
1035 psdc.SelectObject(pbmp);
1037 TransparentBlt2(pdc->GetSafeHdc(), x, y, m_QiPangDistance, m_QiPangDistance,
1038 psdc.GetSafeHdc(), 0, 0, bitmap.bmWidth, bitmap.bmHeight, RGB(255, 255, 255));
1069void CChineseChessView::InvalidateRectage(
int i,
int j)
1072 if (i >= 0 && i <= 8 && j >= 0 && j <= 9)
1074 ConvertCoordinate(&x, &y, &i, &j, IJToXY);
1076 rect.top = y - m_QiPangDistance / 2 - 1;
1077 rect.left = x - m_QiPangDistance / 2 - 1;
1078 rect.bottom = y + m_QiPangDistance / 2 + 1;
1079 rect.right = x + m_QiPangDistance / 2 + 1;
1080 InvalidateRect(&rect);
virtual int OnGoChess(int i, int j, CPiece::ENUM_QiZi chess)=0
Executes the go chess action
virtual int onDrawPrompt(int i, int j)
画提示框
virtual int onGoChess(int i, int j, CPiece::ENUM_QiZi chess)
走棋事件
virtual int onCleanPrompt(int i, int j)
清除提示框
virtual int onPromptMessage(CGoRule::ENUM_ReturnValue val)
提示错误消息
CPiece::ENUM_QiZi m_ChessBoard[9][10]
棋盘描述
bool GoChess(int i, int j, bool bNext=false)
走棋