中国象棋控件 v2.0.13
载入中...
搜索中...
未找到
ChineseChessView.cpp
1// 实现文件
2//
3#include "framework.h"
4#include <afxdialogex.h>
5#include "Resource.h" // 主符号
6
7#include <atlconv.h>
8#include "ChineseChessView.h"
9
10//播放音频
11#include <mmsystem.h>
12#pragma comment(lib, "winmm")
13
14#ifdef _DEBUG
15#undef THIS_FILE
16static char THIS_FILE[] = __FILE__;
17#define new DEBUG_NEW
18#endif
19
20// CChineseChessView
21
22IMPLEMENT_DYNAMIC(CChineseChessView, CView)
23
24CChineseChessView::CChineseChessView()
25{
26 m_pGoChessHandler = nullptr;
27
28 m_QiPangColor = RGB(0, 0, 0);
29 m_TiShiBoxColor = RGB(0, 255, 0);
30
31 m_QiPangStartX = m_QiPangStartY = 0;
32 m_QiPangDistance = 0;
33
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); //KL
44
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);
54
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);
62#else
63 if (m_QiPangPicture.GetSafeHandle() == NULL)
64 m_QiPangPicture.LoadBitmap(IDB_QIPANG);
65
66 if (m_RedShuai.GetSafeHandle() == NULL)
67 {
68 m_RedShuai.LoadBitmap(IDB_RSHUAI);
69 }
70
71 if (m_RedShi.GetSafeHandle() == NULL)
72 {
73 m_RedShi.LoadBitmap(IDB_RSHI);
74 }
75
76 if (m_RedXiang.GetSafeHandle() == NULL)
77 {
78 m_RedXiang.LoadBitmap(IDB_RXIANG);
79 }
80
81 if (m_RedMa.GetSafeHandle() == NULL)
82 {
83 m_RedMa.LoadBitmap(IDB_RMA);
84 }
85
86 if (m_RedChe.GetSafeHandle() == NULL)
87 {
88 m_RedChe.LoadBitmap(IDB_RCHE);
89 }
90
91 if (m_RedPao.GetSafeHandle() == NULL)
92 {
93 m_RedPao.LoadBitmap(IDB_RPAO);
94 }
95
96 if (m_RedBing.GetSafeHandle() == NULL)
97 {
98 m_RedBing.LoadBitmap(IDB_RBING);
99 }
100
101
102 if (m_BlackShuai.GetSafeHandle() == NULL)
103 {
104 m_BlackShuai.LoadBitmap(IDB_BSHUAI);
105 }
106
107 if (m_BlackShi.GetSafeHandle() == NULL)
108 {
109 m_BlackShi.LoadBitmap(IDB_BSHI);
110 }
111
112 if (m_BlackXiang.GetSafeHandle() == NULL)
113 {
114 m_BlackXiang.LoadBitmap(IDB_BXIANG);
115 }
116
117 if (m_BlackMa.GetSafeHandle() == NULL)
118 {
119 m_BlackMa.LoadBitmap(IDB_BMA);
120 }
121
122 if (m_BlackChe.GetSafeHandle() == NULL)
123 {
124 m_BlackChe.LoadBitmap(IDB_BCHE);
125 }
126
127 if (m_BlackPao.GetSafeHandle() == NULL)
128 {
129 m_BlackPao.LoadBitmap(IDB_BPAO);
130 }
131
132 if (m_BlackBing.GetSafeHandle() == NULL)
133 {
134 m_BlackBing.LoadBitmap(IDB_BBING);
135 }
136#endif
137
138}
139
140CChineseChessView::~CChineseChessView()
141{}
142
143BEGIN_MESSAGE_MAP(CChineseChessView, CView)
144ON_WM_LBUTTONUP()
145ON_WM_KEYUP()
146ON_WM_SIZE()
147ON_WM_CREATE()
148END_MESSAGE_MAP()
149
150// CChineseChessView 消息处理程序
151int CChineseChessView::OnCreate(LPCREATESTRUCT lpCreateStruct)
152{
153 if (__super::OnCreate(lpCreateStruct) == -1)
154 return -1;
155
156
157 return 0;
158}
159
160void CChineseChessView::OnLButtonUp(UINT nFlags, CPoint point)
161{
162 int i = 0, j = 0;
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());
166 if (GoChess(i, j))
167 {
168
169 }
170
171 CView::OnLButtonUp(nFlags, point);
172}
173
174
175void CChineseChessView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
176{
177 // TODO: 在此添加消息处理程序代码和/或调用默认值
178
179 CView::OnKeyUp(nChar, nRepCnt, nFlags);
180}
181
182
183void CChineseChessView::OnSize(UINT nType, int cx, int cy)
184{
185 CView::OnSize(nType, cx, cy);
186
187 SetQiPang(cx, cy);
188 Invalidate();
189}
190
191void CChineseChessView::OnDraw(CDC* pDC)
192{
193 CRect rect;
194 GetClientRect(&rect);
195 pDC->SetStretchBltMode(HALFTONE);
196 DrawQiPang(pDC, rect); //画棋盘
197}
198
199void CChineseChessView::AboutBox()
200{
201 CDialogEx dlgAbout(IDD_ABOUTBOX_CHINESECHESSACTIVEX);
202 dlgAbout.DoModal();
203}
204
205//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
206//以下是完成 === 虚拟函数实现 === 的函数块
207//
208
209int CChineseChessView::onPromptSound(PROMPT_SOUND sound)
210{
211 LPCTSTR pId = NULL;
212 switch (sound)
213 {
214 case JiangJun:
215 pId = _T("IDW_CHECK");
216 break;
217 case Eat:
218 pId = _T("IDW_EAT");
219 break;
220 case Go:
221 pId = _T("IDW_GO");
222 break;
223 case NoGo:
224 pId = _T("IDW_DEAD");
225 break;
226 case Select:
227 pId = _T("IDW_SELECT");
228 break;
229 default:
230 break;
231 }
232
233 PromptSound(pId);
234 return 0;
235}
236
237int CChineseChessView::onPromptMessage(CGoRule::ENUM_ReturnValue val)
238{
239 switch (val)
240 {
241 case CGoRule::BEIJIANGJUN:
242 ::MessageBox(GetSafeHwnd(), _T("这步不能走,否则会输棋!"), _T("被将军"), MB_OK);
243 break;
244 case CGoRule::JIANGDUIMIAN:
245 ::MessageBox(GetSafeHwnd(), _T("这步不能走,否则会输棋!"), _T("将对面"), MB_OK);
246 break;
247 }
248 return 0;
249}
250
252{
253 InvalidateRectage(i, j);
254 return 0;
255}
256
258{
259 InvalidateRectage(i, j);
260 return 0;
261}
262
263int CChineseChessView::onGoChess(int i, int j, CPiece::ENUM_QiZi chess)
264{
265 if (m_pGoChessHandler)
266 m_pGoChessHandler->OnGoChess(i, j, chess);
267 return 0;
268}
269
270int CChineseChessView::SetChineseChessHandler(CChineseChessHandler* handler)
271{
272 m_pGoChessHandler = handler;
273 return 0;
274}
275
276int CChineseChessView::SaveChessGame(LPCTSTR pszFile)
277{
278 USES_CONVERSION;
279 return __super::SaveChessGame(T2CA(pszFile));
280}
281
282int CChineseChessView::LoadChessGame(LPCTSTR pszFile)
283{
284 USES_CONVERSION;
285 int nRet = 0;
286 nRet = __super::LoadChessGame(T2CA(pszFile));
287 if (nRet) return nRet;
288 Invalidate();
289 return nRet;
290}
291
292int CChineseChessView::SetRedName(LPCTSTR pszName)
293{
294 USES_CONVERSION;
295 return __super::SetRedName(T2CA(pszName));
296}
297
298int CChineseChessView::SetBlackName(LPCTSTR pszName)
299{
300 USES_CONVERSION;
301 return __super::SetBlackName(T2CA(pszName));
302}
303
304int CChineseChessView::AddGameTag(LPCTSTR pszTag, LPCTSTR pszVal)
305{
306 USES_CONVERSION;
307 return __super::AddGameTag(T2CA(pszTag), T2CA(pszVal));
308}
309
310CString CChineseChessView::GetGameTag(LPCTSTR pszTag)
311{
312 USES_CONVERSION;
313 return A2CT(__super::GetGameTag(T2CA(pszTag)).c_str());
314}
315
316//
317//以上是完成 === 虚拟函数实现 === 的函数块
318//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
319
320int CChineseChessView::SetQiPangColor(COLORREF col)
321{
322 m_QiPangColor = col;
323 Invalidate();
324 return 0;
325}
326
327COLORREF CChineseChessView::GetQiPangColor()
328{
329 return m_QiPangColor;
330}
331
332int CChineseChessView::SetTiShiBoxColor(COLORREF col)
333{
334 m_TiShiBoxColor = col;
335 Invalidate();
336 return 0;
337}
338
339COLORREF CChineseChessView::GetTiShiBoxColor()
340{
341 return m_TiShiBoxColor;
342}
343
344
356BOOL CChineseChessView::SetQiPang(int width, int height)
357{
358 if (width > height)
359 {
360 m_QiPangDistance = height / 11;
361 m_QiPangStartX = (width - m_QiPangDistance * 10) / 2 + m_QiPangDistance;
362 m_QiPangStartY = m_QiPangDistance;
363 }
364 else
365 {
366 m_QiPangDistance = width / 10;
367 m_QiPangStartX = m_QiPangDistance;
368 m_QiPangStartY = (height - m_QiPangDistance * 11) / 2 + m_QiPangDistance;
369 }
370 return TRUE;
371}
372
373//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
374//以下是完成 === 辅助 === 功能的函数块
375//
376
377
400void TransparentBlt2(HDC hdcDest, // 目标DC
401 int nXOriginDest, // 目标X偏移
402 int nYOriginDest, // 目标Y偏移
403 int nWidthDest, // 目标宽度
404 int nHeightDest, // 目标高度
405 HDC hdcSrc, // 源DC
406 int nXOriginSrc, // 源X起点
407 int nYOriginSrc, // 源Y起点
408 int nWidthSrc, // 源宽度
409 int nHeightSrc, // 源高度
410 UINT crTransparent // 透明色,COLORREF类型
411 )
412{
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);
419
420 // 将源DC中的位图拷贝到临时DC中
421 if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
422 BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
423 else
424 StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest,
425 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
426
427 // 设置透明色
428 SetBkColor(hImageDC, crTransparent);
429
430 // 生成透明区域为白色,其它区域为黑色的掩码位图
431 BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY);
432
433 // 生成透明区域为黑色,其它区域保持不变的位图
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);
437
438 // 透明部分保持屏幕不变,其它部分变成黑色
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);
442
443 // "或"运算,生成最终效果
444 BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);
445
446 SelectObject(hImageDC, hOldImageBMP);
447 DeleteDC(hImageDC);
448 SelectObject(hMaskDC, hOldMaskBMP);
449 DeleteDC(hMaskDC);
450 DeleteObject(hImageBMP);
451 DeleteObject(hMaskBMP);
452}
453
454#ifdef CHINESE_CHESS_USE_PNG
455BOOL CChineseChessView::LoadImageFromResource(CImage *pImage, UINT ID, LPCTSTR pType)
456{
457 return LoadImageFromResource(pImage, MAKEINTRESOURCE(ID), pType);
458}
459
473BOOL CChineseChessView::LoadImageFromResource(CImage* pImage, LPCTSTR pID, LPCTSTR lpType)
474{
475 if (pImage == NULL) return false;
476
477 pImage->Destroy();
478
479#ifdef _AFXEXT // MFC 扩展动态库
480 HINSTANCE hInstance = AfxFindResourceHandle(pID, lpType); //得到资源在哪个模块里,返回这个模块实例句柄
481#else
482 HINSTANCE hInstance = AfxGetInstanceHandle();
483#endif
484
485 // 查找资源
486 HRSRC hRsrc = ::FindResource(hInstance, pID, lpType);
487 if (hRsrc == NULL) return false;
488
489 // 加载资源
490 HGLOBAL hImgData = ::LoadResource(hInstance, hRsrc);
491 if (hImgData == NULL)
492 {
493 ::FreeResource(hImgData);
494 return false;
495 }
496
497 // 锁定内存中的指定资源
498 LPVOID lpVoid = ::LockResource(hImgData);
499
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);
505
506 // 解除内存中的指定资源
507 ::GlobalUnlock(hNew);
508
509 // 从指定内存创建流对象
510 HRESULT ht = ::CreateStreamOnHGlobal(hNew, TRUE, &pStream);
511 if (ht != S_OK)
512 {
513 GlobalFree(hNew);
514 }
515 else
516 {
517 // 加载图片
518 pImage->Load(pStream);
519
520 GlobalFree(hNew);
521 }
522 // 释放资源
523 ::FreeResource(hImgData);
524 return true;
525}
526#endif
527
528
541BOOL CChineseChessView::PromptSound(LPCTSTR ID)
542{
543 if (NULL != ID)
544 {
545 // @see https://docs.microsoft.com/en-us/cpp/build/extension-dlls?view=vs-2019
546#ifdef _AFXEXT // MFC 扩展动态库
547 HINSTANCE hInstance = AfxFindResourceHandle(ID, _T("WAVE")); //得到资源在哪个模块里,返回这个模块实例句柄
548#else
549 HINSTANCE hInstance = AfxGetInstanceHandle();
550#endif
551
552 HRSRC hr = FindResource(hInstance, ID, _T("WAVE"));
553 if (NULL == hr) return false;
554
555 HGLOBAL hg = LoadResource(hInstance, hr);
556 LPCTSTR lp = (LPCTSTR)LockResource(hg);
557 ::sndPlaySound(lp, SND_MEMORY | SND_ASYNC);
558 FreeResource(hg);
559 }
560 else
561 {
562 Beep(1000, 20);
563 }
564 return true;
565}
566
567
584BOOL CChineseChessView::ConvertCoordinate(long *x, long *y, int *i, int *j, ENUM_ConvertCoordinate eCC)
585{
586 switch (eCC)
587 {
588 case XYToIJ:
589 *i = (*x - m_QiPangStartX + m_QiPangDistance / 2) / m_QiPangDistance;
590 *j = (*y - m_QiPangStartY + m_QiPangDistance / 2) / m_QiPangDistance;
591 break;
592 case IJToXY:
593 *x = m_QiPangStartX + *i * m_QiPangDistance;
594 *y = m_QiPangStartY + *j * m_QiPangDistance;
595 break;
596 }
597 return true;
598}
599
600//
601//以上是完成 === 辅助 === 的函数块
602//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
603
604
605//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
606//以下是完成 === 中国象棋界面处理 === 的函数块
607//
608
609
621void CChineseChessView::DrawQiPang(CDC *pdc, CRect rcBounds)
622{
623 ASSERT(pdc != NULL);
624
625 //棋盘图片
626#ifdef CHINESE_CHESS_USE_PNG
627 m_QiPangPicture.Draw(pdc->m_hDC, rcBounds);
628#else
629 BITMAP bitmap;
630 m_QiPangPicture.GetBitmap(&bitmap);
631
632 CDC psdc;
633 psdc.CreateCompatibleDC(pdc);
634 psdc.SelectObject(&m_QiPangPicture);
635
636 pdc->StretchBlt(0, 0, rcBounds.Width(), rcBounds.Height(),
637 &psdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
638
639 psdc.DeleteDC();
640#endif
641
642 int i, j;
643 for (i = 0; i < 9; i++) //纵格
644 {
645 if (i == 0 || i == 8)
646 {
647 CPen Pen, *oldPen;
648 Pen.CreatePen(PS_SOLID, 2, m_QiPangColor);
649 oldPen = (CPen*)pdc->SelectObject(&Pen);
650
651 pdc->MoveTo(m_QiPangStartX + i * m_QiPangDistance,
652 m_QiPangStartY);
653 pdc->LineTo(m_QiPangStartX + i * m_QiPangDistance,
654 m_QiPangStartY + 9 * m_QiPangDistance);
655
656 pdc->SelectObject(&oldPen);
657 }
658 else
659 {
660 CPen Pen, *oldPen;
661 Pen.CreatePen(PS_SOLID, 1, m_QiPangColor);
662 oldPen = (CPen*)pdc->SelectObject(&Pen);
663
664 pdc->MoveTo(m_QiPangStartX + i * m_QiPangDistance,
665 m_QiPangStartY);
666 pdc->LineTo(m_QiPangStartX + i * m_QiPangDistance,
667 m_QiPangStartY + 4 * m_QiPangDistance);
668
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);
673
674 pdc->SelectObject(&oldPen);
675 }
676 }
677
678 for (i = 0; i < 10; i++) //横格
679 {
680 CPen Pen, *oldPen;
681 if (i == 0 || i == 9)
682 {
683 Pen.CreatePen(PS_SOLID, 2, m_QiPangColor);
684 oldPen = (CPen*)pdc->SelectObject(&Pen);
685 }
686 else
687 {
688 Pen.CreatePen(PS_SOLID, 1, m_QiPangColor);
689 oldPen = (CPen*)pdc->SelectObject(&Pen);
690 }
691
692
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);
697
698 pdc->SelectObject(&oldPen);
699 }
700
701 //九宫
702 CPen Pen, *oldPen;
703 Pen.CreatePen(PS_SOLID, 1, m_QiPangColor);
704 oldPen = (CPen*)pdc->SelectObject(&Pen);
705
706 pdc->MoveTo(m_QiPangStartX + 3 * m_QiPangDistance,
707 m_QiPangStartY);
708 pdc->LineTo(m_QiPangStartX + 5 * m_QiPangDistance,
709 m_QiPangStartY + 2 * m_QiPangDistance);
710
711 pdc->MoveTo(m_QiPangStartX + 5 * m_QiPangDistance,
712 m_QiPangStartY);
713 pdc->LineTo(m_QiPangStartX + 3 * m_QiPangDistance,
714 m_QiPangStartY + 2 * m_QiPangDistance);
715
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);
720
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);
725
726 pdc->SelectObject(&oldPen);
727
728 //星位
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);
743
744 //楚河汉界
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);
750
751 //画棋子
752 for (i = 0; i < 9; i++)
753 for (j = 0; j < 10; j++)
754 {
755 DrawQiZi(pdc, i, j, m_ChessBoard[i][j]);
756 }
757
758 //显示提示框
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);
763
764}
765
766
783void CChineseChessView::DrawXinWei(CDC *pdc, int i, int j, ENUM_XINWEI xinwei)
784{
785 int d, ds;
786 long x, y;
787
788 d = m_QiPangDistance * 4 / 10;
789 ds = m_QiPangDistance * 2 / 10;
790
791 /*x = m_QiPangStartX + i * m_QiPangDistance;
792 y = m_QiPangStartY + j * m_QiPangDistance;
793 */
794 ConvertCoordinate(&x, &y, &i, &j, IJToXY);
795
796 CPen Pen, *oldPen;
797 Pen.CreatePen(PS_SOLID, 1, m_QiPangColor);
798 oldPen = (CPen*)pdc->SelectObject(&Pen);
799
800 if (xinwei != Left_XinWei)
801 {
802 pdc->MoveTo(x + ds,
803 y + ds);
804 pdc->LineTo(x + d,
805 y + ds);
806
807 pdc->MoveTo(x + ds,
808 y - ds);
809 pdc->LineTo(x + d,
810 y - ds);
811
812 pdc->MoveTo(x + ds,
813 y + ds);
814 pdc->LineTo(x + ds,
815 y + d);
816
817 pdc->MoveTo(x + ds,
818 y - ds);
819 pdc->LineTo(x + ds,
820 y - d);
821 }
822
823 if (xinwei != Right_XinWei)
824 {
825 pdc->MoveTo(x - ds,
826 y - ds);
827 pdc->LineTo(x - ds,
828 y - d);
829
830 pdc->MoveTo(x - ds,
831 y + ds);
832 pdc->LineTo(x - ds,
833 y + d);
834
835 pdc->MoveTo(x - ds,
836 y + ds);
837 pdc->LineTo(x - d,
838 y + ds);
839
840 pdc->MoveTo(x - ds,
841 y - ds);
842 pdc->LineTo(x - d,
843 y - ds);
844 }
845 pdc->SelectObject(&oldPen);
846}
847
848
860BOOL CChineseChessView::DrawTiShiBox(CDC *pdc, int i, int j)
861{
862 // CClientDC dc(this);
863 ASSERT(pdc != NULL);
864 long m_X, m_Y, m_L = m_QiPangDistance / 2;
865 CPen pen, *oldpen;
866 pen.CreatePen(PS_SOLID, 2, m_TiShiBoxColor);
867 oldpen = (CPen*)pdc->SelectObject(&pen);
868
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);
872
873 pdc->MoveTo(m_X - m_L, m_Y - m_L);
874 pdc->LineTo(m_X - m_L / 2, m_Y - m_L);
875
876 pdc->MoveTo(m_X + m_L, m_Y + m_L);
877 pdc->LineTo(m_X + m_L, m_Y + m_L / 2);
878
879 pdc->MoveTo(m_X + m_L, m_Y + m_L);
880 pdc->LineTo(m_X + m_L / 2, m_Y + m_L);
881
882 pdc->MoveTo(m_X - m_L, m_Y + m_L);
883 pdc->LineTo(m_X - m_L, m_Y + m_L / 2);
884
885 pdc->MoveTo(m_X - m_L, m_Y + m_L);
886 pdc->LineTo(m_X - m_L / 2, m_Y + m_L);
887
888 pdc->MoveTo(m_X + m_L, m_Y - m_L);
889 pdc->LineTo(m_X + m_L, m_Y - m_L / 2);
890
891 pdc->MoveTo(m_X + m_L, m_Y - m_L);
892 pdc->LineTo(m_X + m_L / 2, m_Y - m_L);
893
894
895 pdc->SelectObject(oldpen);
896 return true;
897}
898
899
912BOOL CChineseChessView::DrawQiZi(CDC *pdc, int i, int j, CPiece::ENUM_QiZi eQiZi)
913{
914 ASSERT(pdc != NULL);
915#ifdef CHINESE_CHESS_USE_PNG
916 CImage *pQiZi = NULL;
917#else
918 CBitmap *pQiZi = NULL;
919#endif
920
921#pragma warning( disable : 4806 )
922
923 switch (eQiZi)
924 {
925 case CPiece::NoQiZi:
926 return false;
927 case CPiece::RShuai:
928 pQiZi = &m_RedShuai;
929 break;
930 case CPiece::RShi:
931 pQiZi = &m_RedShi;
932 break;
933 case CPiece::RXiang:
934 pQiZi = &m_RedXiang;
935 break;
936 case CPiece::RMa:
937 pQiZi = &m_RedMa;
938 break;
939 case CPiece::RChe:
940 pQiZi = &m_RedChe;
941 break;
942 case CPiece::RPao:
943 pQiZi = &m_RedPao;
944 break;
945 case CPiece::RBing:
946 pQiZi = &m_RedBing;
947 break;
948 case CPiece::BShuai:
949 pQiZi = &m_BlackShuai;
950 break;
951 case CPiece::BShi:
952 pQiZi = &m_BlackShi;
953 break;
954 case CPiece::BXiang:
955 pQiZi = &m_BlackXiang;
956 break;
957 case CPiece::BMa:
958 pQiZi = &m_BlackMa;
959 break;
960 case CPiece::BChe:
961 pQiZi = &m_BlackChe;
962 break;
963 case CPiece::BPao:
964 pQiZi = &m_BlackPao;
965 break;
966 case CPiece::BBing:
967 pQiZi = &m_BlackBing;
968 break;
969 }
970
971#pragma warning( default : 4806 )
972
973 if (NULL != pQiZi)
974 {
975 return DrawPicture(pdc, i, j, pQiZi);
976 }
977
978 return false;
979}
980
981#ifdef CHINESE_CHESS_USE_PNG
982BOOL CChineseChessView::DrawPicture(CDC *pdc, int i, int j, CImage* pImage)
983{
984 ASSERT(pdc != NULL && pImage != NULL);
985
986 long x, y;
987
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);
992}
993#endif
994
995
1010BOOL CChineseChessView::DrawPicture(CDC *pdc, int i, int j, CBitmap *pbmp, BOOL CHHJKL)
1011{
1012 ASSERT(pdc != NULL && pbmp != NULL);
1013 if (pbmp->GetSafeHandle() == NULL)
1014 return false;
1015
1016 long x, y;
1017
1018 ConvertCoordinate(&x, &y, &i, &j, IJToXY);
1019 if (CHHJKL)//画楚河汉界
1020 {
1021 x -= m_QiPangDistance / 2;
1022 }
1023 else
1024 {
1025 x -= m_QiPangDistance / 2;
1026 y -= m_QiPangDistance / 2;
1027 }
1028
1029 //棋盘图片
1030 BITMAP bitmap;
1031 pbmp->GetBitmap(&bitmap);
1032
1033 CDC psdc;
1034 psdc.CreateCompatibleDC(pdc);
1035 psdc.SelectObject(pbmp);
1036
1037 TransparentBlt2(pdc->GetSafeHdc(), x, y, m_QiPangDistance, m_QiPangDistance,
1038 psdc.GetSafeHdc(), 0, 0, bitmap.bmWidth, bitmap.bmHeight, RGB(255, 255, 255));
1039
1040
1041 /*------------------------------------------------------------------------
1042 //以下是由 ---康 林--- 删除于 2004-12-17 : 21:39:09
1043 //
1044
1045 //用于Windows 2000 以上版本
1046 TransparentBlt(pdc->GetSafeHdc(), m_X, m_Y, m_QiPangDistance, m_QiPangDistance,
1047 psdc.GetSafeHdc(), 0, 0, bitmap.bmWidth, bitmap.bmHeight, RGB(255, 255, 255));
1048
1049 //
1050 //以上是由 ---康 林--- 删除于 2004-12-17 : 21:39:09
1051 //------------------------------------------------------------------------*/
1052
1053 psdc.DeleteDC();
1054 return true;
1055}
1056
1057
1069void CChineseChessView::InvalidateRectage(int i, int j)
1070{
1071 long x, y;
1072 if (i >= 0 && i <= 8 && j >= 0 && j <= 9)
1073 {
1074 ConvertCoordinate(&x, &y, &i, &j, IJToXY);
1075 RECT rect;
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);
1081 }
1082}
1083
1084//
1085//以上是完成 === 中国象棋界面处理 === 的函数块
1086//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
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)
走棋