⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 move pic.cpp

📁 真是一款用VC++编写的小游戏
💻 CPP
📖 第 1 页 / 共 2 页
字号:

				cxScr = GetSystemMetrics (SM_CXSCREEN) ;
				cyScr = GetSystemMetrics (SM_CYSCREEN) ;

				// 计算最合适的显示尺寸
				fcxDiv = 5 * (float) (bitmap.bmWidth) /	(float) (cxScr) / 2 ;
				fcyDiv = 5 * (float) (bitmap.bmHeight) / (float) (cyScr) / 3 ;

				// 获得相对于最合适的显示区域,图像比较宽的一边
				if ( (fDiv = (fcxDiv > fcyDiv) ? fcxDiv : fcyDiv) <= 1)
					fDiv = 1 ;

				// 计算出最合适的大小,并保持图像长宽比例
				cxClient = (int) (bitmap.bmWidth / fDiv) ;
				cyClient = (int) (bitmap.bmHeight / fDiv) ;

				// 重新计算窗口尺寸和坐标
				rcWin.left   -= (cxClient - (rcClient.right - rcClient.left)) / 2 ;
				rcWin.right  += (cxClient - (rcClient.right - rcClient.left)) / 2 ;
				rcWin.top    -= (cyClient - (rcClient.bottom - rcClient.top)) / 2 ;
				rcWin.bottom += (cyClient - (rcClient.bottom - rcClient.top)) / 2 ;

				// 经过多次打开图像后,窗口位置就不再是屏幕中央了。不知道哪里出了问题

				MoveWindow (hwnd, rcWin.left, rcWin.top, rcWin.right - rcWin.left,
							rcWin.bottom - rcWin.top, TRUE);

				/*==================================================
								让Static显示图像
				==================================================*/
				// Static控件应该调整了位置和大小。下面显示图像
				hdc = GetDC (hwnd) ;

				// 把图像载入内存设备表
				hdcMem = CreateCompatibleDC (hdc) ;
				SelectObject (hdcMem, hBitmap) ;
				
				for (i = 0; i < 4; i++)
					for (j = 0; j < 4; j++)
					{
						// 这里以后应该改进,因为我希望空白地方能够出现在随机位置
						if (i * 4 + j == 15)
						{	idStcBlank = 15;
							break ;
						}

						hdcStc = CreateCompatibleDC (hdc) ;
						// 创建新的图像句柄
						hBmpStc = CreateCompatibleBitmap (hdc,
														  cxClient / 4,
														  cyClient / 4);
						SelectObject (hdcStc, hBmpStc) ;

						// 分割图像并拷贝到hdcStc内存设备表
						StretchBlt (hdcStc,	0, 0, 
									cxClient / 4,
									cyClient / 4,
									hdcMem,
									bitmap.bmWidth * j / 4,
									bitmap.bmHeight * i / 4,
									bitmap.bmWidth / 4,
									bitmap.bmHeight / 4,
									SRCCOPY) ;
						
						// 设置对应的Static控件的图像
						SendDlgItemMessage (hwnd,
											4 * i + j, 
											STM_SETIMAGE,
											(WPARAM) IMAGE_BITMAP,
											(LPARAM) hBmpStc) ;

						DeleteObject (hBmpStc) ;	// 删除句柄,这一句可以不要,什么影响?
						DeleteDC (hdcStc) ;
					}

				DeleteDC (hdcMem) ;
				ReleaseDC (hwnd, hdc) ;

				// 使Static控件可以接受mouse点击消息
				bWinFlag = false ;
				// 使reset菜单有效
				EnableMenuItem (hMenu, IDM_GAME_RESET, MF_ENABLED) ;
			}
			
			return 0 ;

		case ID_GAME_EXIT:	// 退出游戏
			SendMessage (hwnd, WM_CLOSE, 0, 0);
			return 0;

		case ID_HELP_ABOUT:
			DialogBox (hInst, TEXT ("AboutDlg"), hwnd, AboutDlgProc) ;
			return 0;

		default:
			if (bWinFlag == false)
			{
				/*==================================================
							Windows通知Static被鼠标点击
				原本应该这样,像菜单项处理一样,使用case id来判断,
				但是我们就要重复16次,为了方便和美观,我就这样处理。
				因为除了菜单消息就是点击Static控件消息了。
				==================================================*/
				// 获得被点击的Static控件的id
				idStcClk = (int) LOWORD (wParam) ;
	
				// 得到BlankStatic和被点击的Static控件的位置信息
				iStcClkPos = iStcPos[idStcClk / 4][idStcClk % 4] ;
				iStcBlankPos = iStcPos[idStcBlank / 4][idStcBlank % 4] ;
			
				// 判断是否应该对点击做出反应
				if (iStcClkPos == iStcBlankPos)		// player click the blank static
					return 0 ;

				if (iStcClkPos != iStcBlankPos - 4 &&	// not up static of blank static
					iStcClkPos != iStcBlankPos + 4 &&	// not below static of blank static
					iStcClkPos != iStcBlankPos - 1 &&	// not left static of blank static
					iStcClkPos != iStcBlankPos + 1)		// not right static of blank static
					return 0 ;

				// 移动Static控件
				MoveWindow (hwndPic_Button[idStcClk / 4][idStcClk % 4],
							(iStcBlankPos % 4) * cxClient / 4,
							(iStcBlankPos / 4) * cyClient / 4,
							cxClient / 4, cyClient / 4, TRUE) ;
	
				MoveWindow (hwndPic_Button[idStcBlank / 4][idStcBlank % 4],
							(iStcClkPos % 4) * cxClient / 4,
							(iStcClkPos / 4) * cyClient / 4,
							cxClient / 4, cyClient / 4, TRUE) ;

				// 更新Static控件的位置信息
				iStcPos[idStcClk / 4][idStcClk % 4] = iStcBlankPos ;
				iStcPos[idStcBlank / 4][idStcBlank / 4] = iStcClkPos ;

				// 判断是否胜利
				int iWinFlag = 0 ;
				for (i = 0; i < 4; i++)
					for (j = 0; j < 4; j++)
						if (iStcPos[i][j] == 4 * i + j)
							iWinFlag ++ ;

				if (iWinFlag == 16)	// win the game
				{
					// 显示祝贺信息
					MessageBox (hwnd, szWinGame, szAppName,
								MB_OK | MB_ICONINFORMATION) ;
					bWinFlag = true ;
				}
			}

			return 0 ;
		}
		break;		

	case WM_DESTROY:
		if (hBitmap)
			DeleteObject (hBitmap) ;

		PostQuitMessage (0) ;
		return 0 ;
	}
	
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}


/*==========================================================
				从位图文件创建位图对象
==========================================================*/
HBITMAP CreateBitmapObjectFromDibFile (HDC hdc, PTSTR szFileName)
{
	BITMAPFILEHEADER * pbmfh ;
	BOOL               bSuccess ;
	DWORD              dwFileSize, dwHighSize, dwBytesRead ;
	HANDLE             hFile ;
	HBITMAP            hBitmap ;
	
	// 打开文件: 只读,写禁止
	hFile = CreateFile (szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, 
						OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL) ;
	
	if (hFile == INVALID_HANDLE_VALUE)
		return NULL ;
	
	// 读入整个文件
	dwFileSize = GetFileSize (hFile, &dwHighSize) ;
	
	if (dwHighSize)
	{
		CloseHandle (hFile) ;
		return NULL ;
	}
	
	pbmfh = (BITMAPFILEHEADER *) malloc (dwFileSize) ;
	
	if (!pbmfh)
	{
		CloseHandle (hFile) ;
		return NULL ;
	}
	
	bSuccess = ReadFile (hFile, pbmfh, dwFileSize, &dwBytesRead, NULL) ;
	CloseHandle (hFile) ;
	
	// 验证文件
	if (!bSuccess || (dwBytesRead != dwFileSize)
					|| (pbmfh->bfType != * (WORD *) "BM") 
					|| (pbmfh->bfSize != dwFileSize))
	{
		free (pbmfh) ;
		return NULL ;
	}
	
	// 创建DDB
	hBitmap = CreateDIBitmap	(hdc, 
								(BITMAPINFOHEADER *) (pbmfh + 1),
								CBM_INIT,
								(BYTE *) pbmfh + pbmfh->bfOffBits,
								(BITMAPINFO *) (pbmfh + 1),
								DIB_RGB_COLORS) ;
	free (pbmfh) ;
	
	return hBitmap ;
}


/*==========================================================
				初始化OPENFILENAME结构
==========================================================*/
void InitOfnStruct (OPENFILENAME& ofn, HWND hWin)
{
	// initialize OPENFILENAME struct
	ofn.lStructSize       = sizeof (OPENFILENAME) ;
	ofn.hwndOwner         = hWin ;
	ofn.hInstance         = NULL ;
	ofn.lpstrFilter       = szFilter ;
	ofn.lpstrCustomFilter = NULL ;
	ofn.nMaxCustFilter    = 0 ;
	ofn.nFilterIndex      = 0 ;
	ofn.lpstrFile         = szFileName ;
	ofn.nMaxFile          = MAX_PATH ;
	ofn.lpstrFileTitle    = szTitleName ;
	ofn.nMaxFileTitle     = MAX_PATH ;
	ofn.lpstrInitialDir   = NULL ;
	ofn.lpstrTitle        = NULL ;
	ofn.Flags             = 0 ;
	ofn.nFileOffset       = 0 ;
	ofn.nFileExtension    = 0 ;
	ofn.lpstrDefExt       = TEXT ("bmp") ;
	ofn.lCustData         = 0 ;
	ofn.lpfnHook          = NULL ;
	ofn.lpTemplateName    = NULL ;
}


/*==========================================================
					对话框窗口函数
==========================================================*/
BOOL CALLBACK AboutDlgProc (HWND hDlg, UINT message, 
                            WPARAM wParam, LPARAM lParam)
{
     switch (message)
     {
     case WM_INITDIALOG :
          return TRUE ;
          
     case WM_COMMAND :
          switch (LOWORD (wParam))
          {
          case IDOK :
               EndDialog (hDlg, 0) ;
               return TRUE ;
          }
          break ;
     }
     return FALSE ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -