📄 move pic.cpp
字号:
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 + -