#include<windows.h>
#include<stdio.h>
#include<time.h>
#include "Globle.h"
#include "resource.h"
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"msimg32.lib")
typedef struct BitMapPoint
{
long X;
long Y;
int Index;
int CurrentIndex;
}BMPoint;
BMPoint BMPList[COL*ROW];
void InitBMPList()
{
int nX =BeginX,nY=BeginY;
SmallBKWidth = BKWidth/COL ;
SmallBKHeight = BKHeight/ROW ;
for(int i =0 ; i<COL*ROW ; i++)
{
BMPList[i].X = nX ;
BMPList[i].Y = nY ;
BMPList[i].Index = i ;
if((i+1)%COL == 0)
{
nX = BeginX ;
nY += SmallBKHeight + 2;
}
else
{
nX += SmallBKWidth+2;
}
}
RandSetBMPList();
}
//随机设置每张图片出现的位置
void RandSetBMPList()
{
srand(time(NULL));
int num,i=0,j;
while(i<COL*ROW)
{
num = rand()%(COL*ROW);
for(j=0;j<i;j++)
if(BMPList[j].CurrentIndex == num)
break;
if(i == j)
{
BMPList[i].CurrentIndex = num ;
i++ ;
}
}
}
HDC CreateMemoryDC(HDC hClientDC,RECT rect)
{
//创建一个可兼容的绘图设备
HDC hMDC = ::CreateCompatibleDC(hClientDC);
HBITMAP hBitMap = ::CreateCompatibleBitmap(hClientDC,
rect.right-rect.left,
rect.bottom-rect.top);
::SelectObject(hMDC,hBitMap);
::FillRect(hMDC,&rect,NULL);
::DeleteObject(hBitMap);
return hMDC;
}
HDC LoadBitMapToDC(HINSTANCE hInst,char * fileName)
{
HBITMAP hBitMap=(HBITMAP)LoadImage(hInst,fileName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
HDC hBitMapDC = ::CreateCompatibleDC(NULL);
::SelectObject(hBitMapDC,hBitMap);
::DeleteObject(hBitMap);
return hBitMapDC;
}
HDC LoadBitMapToDC(HINSTANCE hInst,char * fileName,long& width,long& height)
{
HBITMAP hBitMap=(HBITMAP)LoadImage(hInst,fileName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE | LR_CREATEDIBSECTION);
//获取位图的宽度和高度
DIBSECTION dib;
::GetObject(hBitMap,sizeof(dib),&dib);
BITMAPINFOHEADER bm=dib.dsBmih;
width=bm.biWidth;
height=bm.biHeight;
HDC hBitMapDC = ::CreateCompatibleDC(NULL);
::SelectObject(hBitMapDC,hBitMap);
::DeleteObject(hBitMap);
return hBitMapDC;
}
void ShowSuccess(HWND hWnd,HDC hDc)
{
for(int i=0;i<=COL*ROW;i++)
{
if(i == COL*ROW)
{
BitBlt(hDc,
0,0,
SmallBKWidth,SmallBKHeight,
G_BitMapBKDC,
BMPList[0].X,
BMPList[0].Y,
SRCCOPY);
MessageBox(NULL,"Great!! Successful!","提示",MB_ICONWARNING);
KillTimer(hWnd,1);
break;
}
if(BMPList[i].Index == BMPList[i].CurrentIndex)
continue;
else
break;
}
}
void DrawBMPList(HDC hDc)
{
HDC hMDC = ::CreateMemoryDC(hDc,ClientRect);
int nX = BeginX,nY = BeginY;
//背景图片
::BitBlt(hMDC,0,0,
//SmallBKWidth*2+120,
BK11Width,
// SmallBKHeight*2,
BK11Height,
G_BitMapBK11DC,
0,0,
SRCCOPY);
//绘制边框
HPEN hPen = CreatePen(PS_SOLID,3,RGB(255,0,0));
SelectObject(hMDC,hPen);
Rectangle(hMDC,nX-7,nY-7,BKWidth+nX+7,BKHeight+nY+7);
DeleteObject(hPen);
//绘制拼图
for(int i=0;i<COL*ROW;i++)
{
::BitBlt(hMDC,
BMPList[i].X,
BMPList[i].Y,
SmallBKWidth,SmallBKHeight,
G_BitMapKoalaDC[BMPList[i].CurrentIndex],
0,0,
SRCCOPY);
}
//用于作参考的图片
BitBlt(hMDC,nX+BKWidth+100,nY,
//SmallBKWidth*2+120,
BKWidth,
// SmallBKHeight*2,
BKHeight,
G_BitMapBKDC,
0,0,
SRCCOPY);
//将内存中的图片绘制到窗体
::BitBlt(hDc,0,0,
ClientRect.right-ClientRect.left,
ClientRect.bottom-ClientRect.top,
hMDC,
0,0,
SRCCOPY);
::DeleteDC(hMDC);
}
//7、消息处理
long CALLBACK WndProc(HWND hWnd, int message, int wParam, int lParam)
{
switch (message)
{
case WM_KEYDOWN:
{
switch(wParam)
{
case VK_RIGHT :Music++;if(Music==6)Music=1;sprintf(s,"sound//Music%d.wav",Music);sndPlaySound(s,SND_ALIAS |SND_ASYNC);break;
case VK_LEFT :Music--;if(Music == 0)Music=5;sprintf(s,"sound//Music%d.wav",Music);sndPlaySound(s,SND_ALIAS |SND_ASYNC);break;
}
break;
}
case WM_LBUTTONDOWN:
{
HDC hMDC = ::CreateMemoryDC(hDc,ClientRect);
int nX = LOWORD(lParam);
int nY = HIWORD(lParam);
int i;
HDC hDc = GetDC(hWnd);
ShowSuccess(hWnd,hDc);//判断是否拼图结束
for(i=0;i<COL*ROW;i++)
{
if(nX>=BMPList[i].X
&&nX<=BMPList[i].X+SmallBKWidth
&&nY>=BMPList[i].Y
&&nY<=BMPList[i].Y+SmallBKHeight)
{
HPEN hPen = CreatePen(PS_SOLID,3,RGB(55,102,0));
SelectObject(hDc,hPen);
MoveToEx(hDc,BMPList[i].X,BMPList[i].Y,NULL);
LineTo(hDc,BMPList[i].X+SmallBKWidth,BMPList[i].Y);
MoveToEx(hDc,BMPList[i].X,BMPList[i].Y,NULL);
LineTo(hDc,BMPList[i].X,BMPList[i].Y+SmallBKHeight);
MoveToEx(hDc,BMPList[i].X,BMPList[i].Y+SmallBKHeight,NULL);
LineTo(hDc,BMPList[i].X+SmallBKWidth,BMPList[i].Y+SmallBKHeight);
MoveToEx(hDc,BMPList[i].X+SmallBKWidth,BMPList[i].Y,NULL);
LineTo(hDc,BMPList[i].X+SmallBKWidth,BMPList[i].Y+SmallBKHeight);
DeleteObject(hPen);
for(int j =0 ;j<COL*ROW ; j++)
{
if(BMPList[i].X + SmallBKWidth+2 == BMPList[j].X && BMPList[i].Y == BMPList[j].Y
&& G_BitMapKoalaDC[BMPList[i].CurrentIndex] && G_BitMapKoalaDC[BMPList[j].CurrentIndex] == NULL
|| BMPList[i].X == BMPList[j].X && BMPList[i].Y + SmallBKHeight+2== BMPList[j].Y
&& G_BitMapKoalaDC[BMPList[i].CurrentIndex] && G_BitMapKoalaDC[BMPList[j].CurrentIndex] == NULL
|| BMPList[i].X - SmallBKWidth-2 == BMPList[j].X && BMPList[i].Y == BMPList[j].Y
&& G_BitMapKoalaDC[BMPList[i].CurrentIndex] && G_BitMapKoalaDC[BMPList[j].CurrentIndex] == NULL
|| BMPList[i].X == BMPList[j].X && BMPList[i].Y - SmallBKHeight-2== BMPList[j].Y
&& G_BitMapKoalaDC[BMPList[i].CurrentIndex] && G_BitMapKoalaDC[BMPList[j].CurrentIndex] == NULL)
{
int n=BMPList[i].CurrentIndex;
BMPList[i].CurrentIndex = BMPList[j].CurrentIndex;
BMPList[j].CurrentIndex = n;
DrawBMPList(hDc);
ReleaseDC(hWnd,hDc);
}
}
}
}
}
/* case WM_RBUTTONDOWN:
{
int nX = LOWORD(lParam);
int nY = HIWORD(lParam);
int i =0;
HDC hDc = GetDC(hWnd);
ShowSuccess(hWnd,hDc);
for(i=0;i<COL*ROW;i++)
{
if(nX>=BMPList[i].X
&&nX<=BMPList[i].X+SmallBKWidth
&&nY>=BMPList[i].Y
&&nY<=BMPList[i].Y+SmallBKHeight)
{
HPEN hPen = CreatePen(PS_SOLID,2,RGB(55,102,0));
SelectObject(hDc,hPen);
MoveToEx(hDc,BMPList[i].X,BMPList[i].Y,NULL);
LineTo(hDc,BMPList[i].X+SmallBKWidth,BMPList[i].Y);
MoveToEx(hDc,BMPList[i].X,BMPList[i].Y,NULL);
LineTo(hDc,BMPList[i].X,BMPList[i].Y+SmallBKHeight);
MoveToEx(hDc,BMPList[i].X,BMPList[i].Y+SmallBKHeight,NULL);
LineTo(hDc,BMPList[i].X+SmallBKWidth,BMPList[i].Y+SmallBKHeight);
MoveToEx(hDc,BMPList[i].X+SmallBKWidth,BMPList[i].Y,NULL);
LineTo(hDc,BMPList[i].X+SmallBKWidth,BMPList[i].Y+SmallBKHeight);
DeleteObject(hPen);
if(PrevSelectIndex==-1)
{
PrevSelectIndex=i;
}
else
{
int n=BMPList[i].CurrentIndex;
BMPList[i].CurrentIndex = BMPList[PrevSelectIndex].CurrentIndex;
BMPList[PrevSelectIndex].CurrentIndex = n;
PrevSelectIndex = -1;
DrawBMPList(hDc);
ReleaseDC(hWnd,hDc);
}
break;
}
}
}*/
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hDc = BeginPaint(hWnd,&ps);
DrawBMPList(hDc);
EndPaint(hWnd,&ps);
break;
}
case WM_TIMER:
{
HDC hDc = GetDC(hWnd) ;
sprintf(s," 拼图剩余时间 :%02d:%02d",OverTime_m,OverTime_s);
SetWindowText(hWnd,s);
OverTime_s --;
if(OverTime_m>0 && OverTime_s < 0)
{
OverTime_m--;OverTime_s = 59 ;
}
if(OverTime_m == 0 && OverTime_s < 0)
{
OverTime_m = 0 ; OverTime_s = 0;
KillTimer(hWnd,1);
MessageBox(NULL,"对不起,您的时间已到!","提示",MB_ICONWARNING);
PostQuitMessage(0);
}
if(OverTime_m == 0 && OverTime_s == 30)
MessageBox(NULL,"您的所剩时间不多啦,还有30s","提示",MB_ICONWARNING);
ReleaseDC(hWnd,hDc);
break;
}
case WM_CREATE:
{
GetClientRect(hWnd,&ClientRect);
G_BitMapBKDC = LoadBitMapToDC(G_hInst,"map//1.bmp",BKWidth,BKHeight);
G_BitMapBK11DC = LoadBitMapToDC(G_hInst,"map//BK11.bmp",BK11Width,BK11Height);
// G_BitMapBKDC = LoadBitMapToDC(G_hInst,"map//1.bmp",BKWidth,BKHeight);
InitBMPList();
HDC hDc = GetDC(hWnd);
SetTimer(hWnd,1,1000,NULL);
RECT SmallRect = {0,0,SmallBKWidth,SmallBKHeight};
for(int i=0;i<COL*ROW;i++)
{
G_BitMapKoalaDC[i] = CreateMemoryDC(hDc,SmallRect);
::BitBlt(G_BitMapKoalaDC[i],
0,0,
SmallBKWidth,SmallBKHeight,
G_BitMapBKDC,
BMPList[i].X,
BMPList[i].Y,
SRCCOPY);
}
// RECT BK11rect = {0,0,BK11Width,BK11Height};//画背景
// G_BitMapBK11DC = CreateMemoryDC(hDc,BK11rect);
G_BitMapKoalaDC[0] = NULL;
ReleaseDC(hWnd,hDc);
break;
}
case WM_SIZE:
{
GetClientRect(hWnd,&ClientRect);
break;
}
case WM_DESTROY:
{
::DeleteObject(G_BitMapBKDC);
G_BitMapBKDC=NULL;
KillTimer(hWnd,1);
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int _stdcall WinMain(HINSTANCE hInstance,
HINSTANCE hPrelnstance,
LPSTR lpCmdLine,
int nShowCmd)
{
G_hInst = hInstance;
//1、设置窗体属性
WNDCLASSEX wcex;
// 结构体的大小
wcex.cbSize = sizeof(WNDCLASSEX);
// 窗体类的样式
wcex.style = CS_HREDRAW | CS_VREDRAW;
// *窗体回调函数
wcex.lpfnWndProc = (WNDPROC)WndProc;
// 窗体类额外字节数,通常为0
wcex.cbClsExtra = 0;
// 窗体实例额外字节数,通常为0
wcex.cbWndExtra = 0;
// *应用程序实例句柄
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON_KOALA));; // 窗体大图标
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); // 窗体鼠标光标样式
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 窗体背景色
wcex.lpszMenuName = NULL; // 窗体主菜单
// *窗体类名称
wcex.lpszClassName = "FW";
wcex.hIconSm = NULL; // 窗体小图标
//2、注册窗体
RegisterClassEx(&wcex);
//3、创建窗体
HWND hWnd = CreateWindow(
"FW", // *窗体类名称
"拼图", // 窗体标题名
WS_OVERLAPPEDWINDOW, // 窗体外观样式
CW_USEDEFAULT, // 窗体在屏幕上的水平位置
0, // 窗体在屏幕上的垂直位置
CW_USEDEFAULT, // 窗口的宽度
0, // 窗口的高度
NULL, // 父窗体句柄
NULL, // 窗口菜单句柄
hInstance, // *创建窗体的应用程序实例句柄
NULL); // 创建窗体时的额外信息,通常为NULL
if (NULL == hWnd)
{
return FALSE;
}
//4、显示窗体
ShowWindow(hWnd, nShowCmd);
//5、 更新窗体
UpdateWindow(hWnd);
//6、主消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) // 从消息队列中获取消息
{
TranslateMessage(&msg); // 转换消息
DispatchMessage(&msg); // 分发消息给回调函数
}
return msg.wParam;
}