?? move pic.cpp
字號:
/*==========================================================
Move Pic.cpp -- A move-picture game with SDK
Soft Zealot (R) Robin Hood, 2001
SoftZealot@china.com Soft_Zealot@china.com
====================================================
我正在學習SDK編程,嘗試編寫了一個小游戲,因為我討厭
一些無聊的編程問題,我喜歡有意思的編程工作 :)
這個游戲完全是用SDK編寫的,沒有涉及MFC,其中打開圖片
的函數是Charles Petzold的《Windows程序設計》一書中的
源代碼,我只不過加上了注釋,看懂了意思而已。其他的代
碼是我自己編寫的,你可以任意使用其中的代碼。
歡迎大家和我討論編程的問題,你可以在www.csdn.net的專
家門診的vc部分找到我,我的id是Soft_Zealot或者
SoftZealot, :),不好意思,水平不夠只好多注冊幾個。
如果你發現了bug或者找到了任何能夠改進程序性能或者任何
能夠使code更精煉的方法,請你通知我,我會很高興能夠更
加完善這個游戲。
====================================================
有待完成:
1.勝利時通知游戲者游戲時間
3.可不可以找到尋找最佳解的算法
4.如何加入預覽功能,可不可以采用類似Splash方法
====================================================
bugs :
1.顯示圖片后每個Static控件排列不整齊
2.由于對圖像處理和windows底層工作原理還不是很清楚,所
以有可能會有內存泄漏
==========================================================*/
#include <windows.h>
#include <commdlg.h>
#include <time.h>
#include "Move Pic.h"
#include "resource.h"
/*==========================================================
應用程序入口函數
==========================================================*/
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szMenuName[] = TEXT ("MainMenu") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
// save the application's HINSTANCE
hInst = hInstance ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ; // WndProc !!! here
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (hInstance, "AppIcon") ; // how to load self-cus icon
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (LTGRAY_BRUSH) ;
wndclass.lpszMenuName = szMenuName ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
// Caculate the window's size and position, I don't like huge_window :-)
int cxWindow, cyWindow;
cxWindow = GetSystemMetrics (SM_CXSCREEN) / 3;
cyWindow = GetSystemMetrics (SM_CYSCREEN) / 3;
hwnd = CreateWindow (szAppName, // window class name
TEXT ("奇幻拼圖 Soft Zealot"), // window caption
WS_OVERLAPPEDWINDOW, // window style
cxWindow, // initial x position
cyWindow, // initial y position
cxWindow, // initial x size
cyWindow, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
// message WM_QUIT cause function GetMessage return 0
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 HMENU hMenu ;
static HWND hwndPic_Button[4][4] ;
static int iStcPos[4][4], iStcPosSave[4][4] ;
static HBITMAP hBitmap, hBmpStc ;
static int cxClient, cyClient ;
static int i, j ;
static int idStcClk, idStcBlank ;
static OPENFILENAME ofn ;
static bool bWinFlag ;
BITMAP bitmap ;
HDC hdc, hdcMem, hdcStc ;
PAINTSTRUCT ps ;
RECT rcClient, rcWin ;
int iStcClkPos, iStcBlankPos ;
int cxScr, cyScr ;
float fcxDiv, fcyDiv, fDiv ;
switch (message)
{
case WM_CREATE:
InitOfnStruct (ofn, hwnd) ;
// create statics who hold pic
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
{
hwndPic_Button[i][j] =
CreateWindow (TEXT ("Static"), NULL,
WS_CHILD | WS_VISIBLE | SS_NOTIFY | SS_BITMAP | SS_SUNKEN,
0, 0, 0, 0,
hwnd, (HMENU) (4 * i + j), hInst, NULL) ;
iStcPos[i][j] = 4 * i + j ;
}
// 使static控件不能接收mouse點擊消息
bWinFlag = true ;
// 開始使reset菜單無效
hMenu = GetMenu (hwnd) ;
EnableMenuItem (hMenu, IDM_GAME_RESET, MF_GRAYED) ;
return 0 ;
case WM_SIZE:
// get client area size
cxClient = LOWORD (lParam);
cyClient = HIWORD (lParam);
// move the statics to the new center
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
{
MoveWindow (hwndPic_Button[i][j],
(iStcPos[i][j] % 4) * cxClient / 4,
(iStcPos[i][j] / 4) * cyClient / 4,
cxClient / 4, cyClient / 4, TRUE);
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
EndPaint (hwnd, &ps) ;
return 0 ;
// 處理菜單命令
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDM_GAME_RESET:
/*==================================================
游戲復位:因為Static已經加載圖像,窗口也得到調整,所
以我們需要打開圖像時,每個Static的位置,在這里恢復
Static的位置就行了。如果以后加入計時功能,就需要復位
開始時間。
==================================================*/
// 恢復初始Static位置信息
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
{
iStcPos[i][j] = iStcPosSave[i][j] ;
// 移動Static控件回到初始位置
MoveWindow (hwndPic_Button[i][j],
(iStcPos[i][j] % 4) * cxClient / 4,
(iStcPos[i][j] / 4) * cyClient / 4,
cxClient / 4, cyClient / 4, TRUE);
}
bWinFlag = false ;
return 0 ;
case IDM_PIC_OPEN:
// 顯示打開文件對話框
if (!GetOpenFileName (&ofn))
return 0 ;
// 如果已經有一個DIB,刪除它
if (hBitmap)
{
DeleteObject (hBitmap) ;
hBitmap = NULL ;
}
// 從DIB創建DDB
SetCursor (LoadCursor (NULL, IDC_WAIT)) ; // 使用漏斗指針
ShowCursor (TRUE) ;
hdc = GetDC (hwnd) ;
hBitmap = CreateBitmapObjectFromDibFile (hdc, szFileName) ;
ReleaseDC (hwnd, hdc) ;
ShowCursor (FALSE) ;
SetCursor (LoadCursor (NULL, IDC_ARROW)) ; // 恢復箭頭指針
// 使客戶區無效以便稍后重繪
InvalidateRect (hwnd, NULL, TRUE) ;
if (hBitmap == NULL)
{
// 如果不能載入DIB文件,顯示錯誤消息
MessageBox (hwnd, TEXT ("Cannot load DIB file"),
szAppName, MB_OK | MB_ICONEXCLAMATION) ;
}
else
{
/*==================================================
在調整窗口大小之前隨機安排Static控件的位置,以便調整
窗口的時候也隨機產生了Static的布局。注意分割后的圖像
仍然是按照順序(id)分配給Static的,隨機的只是位置。
==================================================*/
srand ( (unsigned int) time (NULL)); // for random seed
int iRanA, iRanB ;
for (i = 0; i < 32; i++)
{
// 得到 0 -- 16 之間的兩個隨機數
iRanA = rand( ) % 16 ;
do
{
iRanB = rand( ) % 16 ;
}
while (iRanA == iRanB);
// 隨機調整 Note: index = id XXX[index] = pos
iStcBlankPos = iStcPos[iRanA / 4][iRanA % 4] ;
iStcPos[iRanA / 4][iRanA % 4] = iStcPos[iRanB / 4][iRanB % 4] ;
iStcPos[iRanB / 4][iRanB % 4] = iStcBlankPos ;
}
// 保存開始狀態
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
{
iStcPosSave[i][j] = iStcPos[i][j] ;
MoveWindow (hwndPic_Button[i][j],
(iStcPos[i][j] % 4) * cxClient / 4,
(iStcPos[i][j] / 4) * cyClient / 4,
cxClient / 4, cyClient / 4, TRUE);
}
/*==================================================
調整窗口大小以適應圖像
==================================================*/
GetWindowRect (hwnd, &rcWin);
GetClientRect (hwnd, &rcClient);
GetObject (hBitmap, sizeof (BITMAP), &bitmap) ;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -