七巧板 Chi7ren V0.1
来源:互联网 发布:淘宝会员名怎么取 编辑:程序博客网 时间:2024/04/29 04:09
Chi7ren
Version 0.1
Version 0.1
著名哲学家伯利克里:”一个有思想,但是不能表达的人,如同自己没有思想。“
前言:
前阵子看《COM技术内幕》,知道提供的最后一个程序是“七巧板”程序,当时看前几章的时候也很期待,那个Tangram程序会是怎么样的?看了介绍好像还有GDI版和OpenGL版,可以选择。甚是期待,但也是一直没去编译提供的源代码,只是按每一章的代码,去一章一章的去实现,想按“顺序”很自然的到最后一章,可以揭开它的“神秘面纱”。
有一天,我觉得我应该看看到底是个怎么样的“七巧板”了,以为很酷很帅的。就开始去编译源代码,结果遇到了点小麻烦,还好网上搜了下,还是把一个个错误给解决了。直到编译通过,生成EXE了。打开一看,啊,太失望了。不管是GDI,还是OpenGL都是那么“难看”。但是想想,《COM技术内幕》当然是讲COM为主啦,至于最后的Tnagram也只是对所有COM知识的一次汇总,但是具体代码没去研究,觉得还是很神奇。毕竟看了《COM技术内幕》还是有很大的收获,不过忘了做点笔记,想想看书还是得做点笔记好,以后可以翻阅,有据可查。
一直也想写个小游戏,可一直不知道该写什么,又想把看《Windows程序设计》的过程中能写点东西,加深对Windows SDK编程的理解,特别是消息机制的理解。还有就是家里可爱的小外甥,小外甥女,如果做的好的话,能给他们玩“舅舅做的游戏”,也是很酷的一件事。又觉得自己一直在看书,想问题,却很少动手写点东西,实践动手编程的能力实在有待提高。基于以上几点,“Chi7ren”(“七小孩”自己取的代号)就开始了...
有的时候,想是一回事,做又是一回事,写代码又是另一回事!
开发:
图形结构:
先把“七小孩”给画出来吧。我把坐标都定死了,我的设想应该是按客户区的大小是可以伸缩的,这也是一个验证的过程,不管怎么样先把图呈现出来先。画图是比较容易的,建立颜色画刷(CreateSolidBrush),选进设备描述表(SelectObject),画多边形(Polygon),一切都那么容易...
既然是“七巧板”,当然要七种颜色,我想到了彩虹的七颜色,所以在网上搜了他们的“资料”:
赤色 【RGB】255, 0, 0 【CMYK】 0, 100, 100, 0
橙色 【RGB】255, 165, 0 【CMYK】0, 35, 100, 0
黄色 【RGB】255, 255, 0 【CMYK】0, 0, 100, 0
绿色 【RGB】0, 255, 0 【CMYK】100, 0, 100, 0
青色 【RGB】0, 127, 255 【CMYK】100, 50, 0, 0
蓝色 【RGB】0, 0, 255 【CMYK】100, 100, 0, 0
紫色 【RGB】139, 0, 255 【CMYK】45, 100, 0, 0
(说明:这里的显示颜色和具体的RGB并不配对,只是为了好看!!)
"小孩"的结构:
struct TangPolygon
{
POINT polyPoint[4]; //多边形点,因为最多四边形,为简单就设为“四个点”
COLORREF rgb; //图形颜色
size_t polyType; //图形类型,即 3:三角形;4:四边形
float angle; //保存“世界坐标”角度,绘图时用
};
图形移动:
要实现图形的移动,首先得判断此时该移动哪个图形?通过鼠标左键单击,选择“激活”一个图形,然后鼠标拖动这个图形。然而问题是如何判断哪个图形被激活呢?难道还用判断鼠标坐标在哪个图形的“包围盒”内??这就麻烦了...后来想想,诶,我不是有每个图形的颜色吗?为什么不通过GetPixel得到当前鼠标位置的颜色,再和“七小孩”逐个比较不就知道哪个被激活了吗?这就大大简化了编码难度,也相当实用。
图形旋转:
这一点是我一开始就知道的可能难点所在!开始的时候,在想能有OpenGL里的坐标变换就好了,想当然的以为Win32 API应该没有这提供类似函数吧。然后试着通过改变顶点的坐标来实现图形的旋转,发现这实在有难度,大量的计算还不一定准确,难道没办法了吗??后来就去网上搜Win32 API有没有坐标变换的现成函数,啊哈、、还是被我找到了,说《Windows图形编程》里有提到这方面的内容,正好有电子书,也就去翻了下,还是找到了解决方法,以为之前学过OpengGL三维编程,理解这种坐标变换还是不难。关键还是这个函数ModifyWorldTransform,实现了左边转换。具体过程类似图1所示:
图1:坐标变换
赤色 【RGB】255, 0, 0 【CMYK】 0, 100, 100, 0
橙色 【RGB】255, 165, 0 【CMYK】0, 35, 100, 0
黄色 【RGB】255, 255, 0 【CMYK】0, 0, 100, 0
绿色 【RGB】0, 255, 0 【CMYK】100, 0, 100, 0
青色 【RGB】0, 127, 255 【CMYK】100, 50, 0, 0
蓝色 【RGB】0, 0, 255 【CMYK】100, 100, 0, 0
紫色 【RGB】139, 0, 255 【CMYK】45, 100, 0, 0
(说明:这里的显示颜色和具体的RGB并不配对,只是为了好看!!)
"小孩"的结构:
struct TangPolygon
{
POINT polyPoint[4]; //多边形点,因为最多四边形,为简单就设为“四个点”
COLORREF rgb; //图形颜色
size_t polyType; //图形类型,即 3:三角形;4:四边形
float angle; //保存“世界坐标”角度,绘图时用
};
图形移动:
要实现图形的移动,首先得判断此时该移动哪个图形?通过鼠标左键单击,选择“激活”一个图形,然后鼠标拖动这个图形。然而问题是如何判断哪个图形被激活呢?难道还用判断鼠标坐标在哪个图形的“包围盒”内??这就麻烦了...后来想想,诶,我不是有每个图形的颜色吗?为什么不通过GetPixel得到当前鼠标位置的颜色,再和“七小孩”逐个比较不就知道哪个被激活了吗?这就大大简化了编码难度,也相当实用。
图形旋转:
这一点是我一开始就知道的可能难点所在!开始的时候,在想能有OpenGL里的坐标变换就好了,想当然的以为Win32 API应该没有这提供类似函数吧。然后试着通过改变顶点的坐标来实现图形的旋转,发现这实在有难度,大量的计算还不一定准确,难道没办法了吗??后来就去网上搜Win32 API有没有坐标变换的现成函数,啊哈、、还是被我找到了,说《Windows图形编程》里有提到这方面的内容,正好有电子书,也就去翻了下,还是找到了解决方法,以为之前学过OpengGL三维编程,理解这种坐标变换还是不难。关键还是这个函数ModifyWorldTransform,实现了左边转换。具体过程类似图1所示:
图1:坐标变换
SHOW:
当你有个锤子的时候,什么东西看起来都像是钉子。
-摘自《世界因你不同》
致谢:
源代码:
-摘自《世界因你不同》
P.S.:
程序就像版本号一样(Version0.1),只是个简单的雏形,对于程序的改进可能会继续,我想后续版本的改进可能会出于以下几个方向:
程序就像版本号一样(Version0.1),只是个简单的雏形,对于程序的改进可能会继续,我想后续版本的改进可能会出于以下几个方向:
- 将Win32 API封装,这样有利于后续开发,也有利于对“面向对象思想”的加深理解;
- 将《Windows程序设计》中每章的内容都融入在程序中,这样有利于对Win32编程的进一步掌握和理解;
- 使用3D图形库如OpenGL进行开发,用户可选择;
- 结合招聘各种能力,锻炼各种能力;
- ...
希望:多指点,多提意见,感激不尽!
致谢:
- 感谢我的室友,Zhu,感谢他一直的鼓励,也感谢他提的一些宝贵意见。
- 还有最近看的几本书对我的影响《把时间当做朋友-运用心智获得解放》,特别是其中提到《奇特的一生》中的事件-时间日记;以及李开复自传《世界因你不同》,让我不停的寻找发自内心的声音,里面的很多方法如“新闻头条”,“墓志铭”,“从心选择”,也让我受益匪浅。
成功并没有绝对的意义,成功,就是做最好的自己,并把最好的你呈现出来。
源代码:
///////////////////////////////////////////////////////////////////////////
//Author: shenzi
//Date: 2009.12.15
//Version: 0.1
///////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include "resource.h"
//右键点击“七巧板”,旋转的角度,5度
const float acc = static_cast(5.0/180.0*3.1415926);
//“七巧板”图形的多边形结构
struct TangPolygon
{
POINT polyPoint[4]; //多边形点,因为最多四边形,为简单就设为“四个点”
COLORREF rgb; //图形颜色
size_t polyType; //图形类型,即 3:三角形;4:四边形
float angle; //保存“世界坐标”角度,绘图时用
};
//预设的“七巧板”
TangPolygon g_Tangram[7] = {
{{0, 0, 0, 320, 160, 160, 0, 0},RGB(255, 0, 0)/*赤色*/,3, 0},
{{0, 0, 160, 160, 320, 0, 0, 0},RGB(255, 165, 0)/*橙色*/,3, 0},
{{0, 320, 160, 320, 80, 240, 0, 0},RGB(255, 255, 0)/*黄色*/,3, 0},
{{160, 160, 240, 240, 240, 80, 0, 0},RGB(0, 255, 0)/*绿色*/,3, 0},
{{160, 320, 320, 320, 320, 160, 0, 0},RGB(0, 127, 255)/*青色*/,3, 0},
{{80, 240, 160, 320, 240, 240, 160, 160},RGB(0, 0, 255)/*蓝色*/,4, 0},
{{240, 80, 240, 240, 320, 160, 320, 0},RGB(139, 0, 255)/*紫色*/,4, 0}
};
//Author: shenzi
//Date: 2009.12.15
//Version: 0.1
///////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include "resource.h"
//右键点击“七巧板”,旋转的角度,5度
const float acc = static_cast(5.0/180.0*3.1415926);
//“七巧板”图形的多边形结构
struct TangPolygon
{
POINT polyPoint[4]; //多边形点,因为最多四边形,为简单就设为“四个点”
COLORREF rgb; //图形颜色
size_t polyType; //图形类型,即 3:三角形;4:四边形
float angle; //保存“世界坐标”角度,绘图时用
};
//预设的“七巧板”
TangPolygon g_Tangram[7] = {
{{0, 0, 0, 320, 160, 160, 0, 0},RGB(255, 0, 0)/*赤色*/,3, 0},
{{0, 0, 160, 160, 320, 0, 0, 0},RGB(255, 165, 0)/*橙色*/,3, 0},
{{0, 320, 160, 320, 80, 240, 0, 0},RGB(255, 255, 0)/*黄色*/,3, 0},
{{160, 160, 240, 240, 240, 80, 0, 0},RGB(0, 255, 0)/*绿色*/,3, 0},
{{160, 320, 320, 320, 320, 160, 0, 0},RGB(0, 127, 255)/*青色*/,3, 0},
{{80, 240, 160, 320, 240, 240, 160, 160},RGB(0, 0, 255)/*蓝色*/,4, 0},
{{240, 80, 240, 240, 320, 160, 320, 0},RGB(139, 0, 255)/*紫色*/,4, 0}
};
///////////////////////////////////////////////////////////////////////////
//Author: shenzi
//Date: 2009.12.15
//Version: 0.1
///////////////////////////////////////////////////////////////////////////
#include "Tangram.h"
//窗口过程函数
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//辅助函数,得到图形的中心坐标
POINT GetCenter(POINT *pPoint, size_t size);
//主函数
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PTSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Tangram");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
//画了个“七巧板”ICON
wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TANGRAM));
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = szAppName;
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
if (!::RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("Erroe:..."), TEXT("Error"), MB_ICONERROR);
return 0;
}
hwnd = ::CreateWindow(szAppName,
//取了个名字“七小孩”,版本就是0.1了,以后可能慢慢完善。
TEXT("Chi7ren! Version 0.1"),
WS_OVERLAPPEDWINDOW | WS_VSCROLL,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
::ShowWindow(hwnd, iCmdShow);
::UpdateWindow(hwnd);
while(::GetMessage(&msg, NULL, 0, 0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//客户区大小
static int cxClient, cyClient;
HDC hdc, hdcMem ;
HBITMAP hBmp;
HBRUSH hbrush;
static int priX, priY;
int moveLenthX, moveLenthY;
//指定当前可移动的“小孩”。
static int movePolygon;
PAINTSTRUCT ps;
COLORREF color;
POINT center;
unsigned int i;
//“世界坐标”旋转用到的两个XFORM结构
static XFORM Tansform = {1, 0, 0, 1, 0, 0};
static XFORM Tanslate = {1, 0, 0, 1, 0, 0};
switch (message)
{
//窗口大小改变时,得到新的客户区大小;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
//鼠标左键,确定当前可移动的图形
case WM_LBUTTONDOWN:
priX = LOWORD(lParam);
priY = HIWORD(lParam);
hdc = ::GetDC(hwnd);
color = ::GetPixel(hdc, priX, priY);
for (i = 0; i < 7; i++)
{
if (color == g_Tangram[i].rgb)
{
movePolygon = i;
break;
}
}
::ReleaseDC(hwnd, hdc);
return 0;
//鼠标右键,实现图形的旋转功能,"SHIFT"改变旋转方向;
case WM_RBUTTONDOWN:
priX = LOWORD(lParam);
priY = HIWORD(lParam);
hdc = ::GetDC(hwnd);
color = ::GetPixel(hdc, priX, priY);
for (i = 0; i < 7; i++)
{
if (color == g_Tangram[i].rgb)
{
movePolygon = i;
if (wParam & MK_SHIFT)
{
g_Tangram[i].angle += acc;
}
else
{
g_Tangram[i].angle -= acc;
}
break;
}
}
::ReleaseDC(hwnd, hdc);
::InvalidateRect(hwnd, NULL, FALSE);
return 0;
//鼠标移动并且左键按下,得到移动距离,并重绘
case WM_MOUSEMOVE:
if (wParam & MK_LBUTTON)
{
moveLenthX = LOWORD(lParam) - priX;
moveLenthY = HIWORD(lParam) - priY;
priX = LOWORD(lParam);
priY = HIWORD(lParam);
for (i = 0; i < g_Tangram[movePolygon].polyType; i++)
{
g_Tangram[movePolygon].polyPoint[i].x += moveLenthX;
g_Tangram[movePolygon].polyPoint[i].y += moveLenthY;
}
}
::InvalidateRect(hwnd, NULL, FALSE);
return 0;
//状态改变时,绘图
case WM_PAINT:
hdc = ::BeginPaint(hwnd, &ps);
//兼容DC,并选进相应的位图,解决“屏幕闪烁”问题;在兼容DC上画图,
//画完后再BitBlt到客户区,实现双缓存。
hdcMem = ::CreateCompatibleDC(hdc);
hBmp = ::CreateCompatibleBitmap(hdc, cxClient, cyClient);
::SelectObject(hdcMem, hBmp);
//为选进位图设定背景:白色
::PatBlt(hdcMem, 0, 0, cxClient, cyClient, WHITENESS);
//设定设备描述表高级图形模式,允许全局转换,即实现图形世界坐标转换;
::SetGraphicsMode(hdcMem, GM_ADVANCED);
//绘制“七巧板”
for (i = 0; i < 7; i++)
{
//得到当前处理图形的中心点
center = GetCenter(g_Tangram[i].polyPoint, g_Tangram[i].polyType);
//全局转换:
//1.重置当前全局转换
::ModifyWorldTransform(hdcMem, NULL, MWT_IDENTITY);
//2.先把世界坐标移到“中心”点
Tansform.eDx = static_cast(-center.x);
Tansform.eDy = static_cast(-center.y);
::ModifyWorldTransform(hdcMem, &Tansform, MWT_RIGHTMULTIPLY);
//3.再做旋转
Tanslate.eM11 = cos(g_Tangram[i].angle);
Tanslate.eM12 = -sin(g_Tangram[i].angle);
Tanslate.eM21 = sin(g_Tangram[i].angle);
Tanslate.eM22 = cos(g_Tangram[i].angle);
::ModifyWorldTransform(hdcMem, &Tanslate, MWT_RIGHTMULTIPLY);
//4.最后移回原处
Tansform.eDx = static_cast(center.x);
Tansform.eDy = static_cast(center.y);
::ModifyWorldTransform(hdcMem, &Tansform, MWT_RIGHTMULTIPLY);
//选定图形颜色,绘制该图形
hbrush = ::CreateSolidBrush(g_Tangram[i].rgb);
::SelectObject(hdcMem, hbrush);
::Polygon(hdcMem, g_Tangram[i].polyPoint, g_Tangram[i].polyType);
::DeleteObject(hbrush);
}
//****重置全局转换,不知道为什么需要加这条语句,不加这条语句最后个图形的
//旋转就会处问题。
::ModifyWorldTransform(hdcMem, NULL, MWT_IDENTITY);
//把结果“贴到”客户区
::BitBlt(hdc, 0, 0, cxClient, cyClient, hdcMem, 0, 0, SRCCOPY);
//删除创建的对象
::DeleteObject(hBmp);
::DeleteDC(hdcMem);
::EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(hwnd, message, wParam, lParam);
}
POINT GetCenter(POINT *pPoint, size_t size)
{
unsigned int i = 0;
POINT center = {0, 0};
for (i = 0; i < size; i++)
{
center.x += pPoint[i].x;
center.y += pPoint[i].y;
}
center.x /= size;
center.y /= size;
return center;
}
//Author: shenzi
//Date: 2009.12.15
//Version: 0.1
///////////////////////////////////////////////////////////////////////////
#include "Tangram.h"
//窗口过程函数
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
//辅助函数,得到图形的中心坐标
POINT GetCenter(POINT *pPoint, size_t size);
//主函数
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PTSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Tangram");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
//画了个“七巧板”ICON
wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TANGRAM));
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = szAppName;
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
if (!::RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("Erroe:..."), TEXT("Error"), MB_ICONERROR);
return 0;
}
hwnd = ::CreateWindow(szAppName,
//取了个名字“七小孩”,版本就是0.1了,以后可能慢慢完善。
TEXT("Chi7ren! Version 0.1"),
WS_OVERLAPPEDWINDOW | WS_VSCROLL,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
::ShowWindow(hwnd, iCmdShow);
::UpdateWindow(hwnd);
while(::GetMessage(&msg, NULL, 0, 0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
//客户区大小
static int cxClient, cyClient;
HDC hdc, hdcMem ;
HBITMAP hBmp;
HBRUSH hbrush;
static int priX, priY;
int moveLenthX, moveLenthY;
//指定当前可移动的“小孩”。
static int movePolygon;
PAINTSTRUCT ps;
COLORREF color;
POINT center;
unsigned int i;
//“世界坐标”旋转用到的两个XFORM结构
static XFORM Tansform = {1, 0, 0, 1, 0, 0};
static XFORM Tanslate = {1, 0, 0, 1, 0, 0};
switch (message)
{
//窗口大小改变时,得到新的客户区大小;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
return 0;
//鼠标左键,确定当前可移动的图形
case WM_LBUTTONDOWN:
priX = LOWORD(lParam);
priY = HIWORD(lParam);
hdc = ::GetDC(hwnd);
color = ::GetPixel(hdc, priX, priY);
for (i = 0; i < 7; i++)
{
if (color == g_Tangram[i].rgb)
{
movePolygon = i;
break;
}
}
::ReleaseDC(hwnd, hdc);
return 0;
//鼠标右键,实现图形的旋转功能,"SHIFT"改变旋转方向;
case WM_RBUTTONDOWN:
priX = LOWORD(lParam);
priY = HIWORD(lParam);
hdc = ::GetDC(hwnd);
color = ::GetPixel(hdc, priX, priY);
for (i = 0; i < 7; i++)
{
if (color == g_Tangram[i].rgb)
{
movePolygon = i;
if (wParam & MK_SHIFT)
{
g_Tangram[i].angle += acc;
}
else
{
g_Tangram[i].angle -= acc;
}
break;
}
}
::ReleaseDC(hwnd, hdc);
::InvalidateRect(hwnd, NULL, FALSE);
return 0;
//鼠标移动并且左键按下,得到移动距离,并重绘
case WM_MOUSEMOVE:
if (wParam & MK_LBUTTON)
{
moveLenthX = LOWORD(lParam) - priX;
moveLenthY = HIWORD(lParam) - priY;
priX = LOWORD(lParam);
priY = HIWORD(lParam);
for (i = 0; i < g_Tangram[movePolygon].polyType; i++)
{
g_Tangram[movePolygon].polyPoint[i].x += moveLenthX;
g_Tangram[movePolygon].polyPoint[i].y += moveLenthY;
}
}
::InvalidateRect(hwnd, NULL, FALSE);
return 0;
//状态改变时,绘图
case WM_PAINT:
hdc = ::BeginPaint(hwnd, &ps);
//兼容DC,并选进相应的位图,解决“屏幕闪烁”问题;在兼容DC上画图,
//画完后再BitBlt到客户区,实现双缓存。
hdcMem = ::CreateCompatibleDC(hdc);
hBmp = ::CreateCompatibleBitmap(hdc, cxClient, cyClient);
::SelectObject(hdcMem, hBmp);
//为选进位图设定背景:白色
::PatBlt(hdcMem, 0, 0, cxClient, cyClient, WHITENESS);
//设定设备描述表高级图形模式,允许全局转换,即实现图形世界坐标转换;
::SetGraphicsMode(hdcMem, GM_ADVANCED);
//绘制“七巧板”
for (i = 0; i < 7; i++)
{
//得到当前处理图形的中心点
center = GetCenter(g_Tangram[i].polyPoint, g_Tangram[i].polyType);
//全局转换:
//1.重置当前全局转换
::ModifyWorldTransform(hdcMem, NULL, MWT_IDENTITY);
//2.先把世界坐标移到“中心”点
Tansform.eDx = static_cast(-center.x);
Tansform.eDy = static_cast(-center.y);
::ModifyWorldTransform(hdcMem, &Tansform, MWT_RIGHTMULTIPLY);
//3.再做旋转
Tanslate.eM11 = cos(g_Tangram[i].angle);
Tanslate.eM12 = -sin(g_Tangram[i].angle);
Tanslate.eM21 = sin(g_Tangram[i].angle);
Tanslate.eM22 = cos(g_Tangram[i].angle);
::ModifyWorldTransform(hdcMem, &Tanslate, MWT_RIGHTMULTIPLY);
//4.最后移回原处
Tansform.eDx = static_cast(center.x);
Tansform.eDy = static_cast(center.y);
::ModifyWorldTransform(hdcMem, &Tansform, MWT_RIGHTMULTIPLY);
//选定图形颜色,绘制该图形
hbrush = ::CreateSolidBrush(g_Tangram[i].rgb);
::SelectObject(hdcMem, hbrush);
::Polygon(hdcMem, g_Tangram[i].polyPoint, g_Tangram[i].polyType);
::DeleteObject(hbrush);
}
//****重置全局转换,不知道为什么需要加这条语句,不加这条语句最后个图形的
//旋转就会处问题。
::ModifyWorldTransform(hdcMem, NULL, MWT_IDENTITY);
//把结果“贴到”客户区
::BitBlt(hdc, 0, 0, cxClient, cyClient, hdcMem, 0, 0, SRCCOPY);
//删除创建的对象
::DeleteObject(hBmp);
::DeleteDC(hdcMem);
::EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
return ::DefWindowProc(hwnd, message, wParam, lParam);
}
POINT GetCenter(POINT *pPoint, size_t size)
{
unsigned int i = 0;
POINT center = {0, 0};
for (i = 0; i < size; i++)
{
center.x += pPoint[i].x;
center.y += pPoint[i].y;
}
center.x /= size;
center.y /= size;
return center;
}
- 七巧板 Chi7ren V0.1
- [内存管理]管理图解v0.1 v0.2 v0.3
- 一点易七巧板玩玩乐 v2.1 官方
- 七巧板程序设计
- 七巧板图
- css3七巧板
- canvas七巧板
- Canvas---七巧板
- findlogin V0.1
- ESOE Specification v0.1
- mimisys pack v0.1
- 虚拟家庭 v0.1
- RayTracer v0.1
- Dump Buffer v0.1
- 文本框学习V0.1
- JIOPi v0.1 概述
- Tank Wat V0.1
- Forget3D V0.1
- Linux 下 Oracle 10g DATAGUARD 安装
- 【转】Qt 扩展插件
- 《Java就业培训教程》_张孝祥_书内源码_10
- Qt中扩展插件 命名空间的问题
- 此去经年
- 七巧板 Chi7ren V0.1
- 《Java就业培训教程》_张孝祥_书内源码_11
- php split 又学到一个正则
- 如何实现 VC中访问Access数据库的方法(不建立ODBC数据源)
- 《Scrum敏捷项目管理》读书总结
- asp.net 网站流量设置 获取IP 通过IP获取地址
- 如何将二维数组作为函数的参数传递
- ——php图像处理类
- 选购虚拟主机之主机代理[转]