Tetris Windows API代码记录:windows
1. 下面是Windows API代码框架,感受用API写东西比别的框架清爽不少。数组
#include <windows.h> LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); //窗口过程函数 /* 程序的入口点WinMain函数 第一个参数:应用程序的当前实例句柄。 第二个参数:应用程序的前一个实例句柄,别管它,对于Win32位而言,它通常是NULL. 第三个参数:指向任何传给程序的命令行参数。PSTR表明"指向字符串的指针"。 第四个参数:它告诉应用程序如何初始化窗口,如最大化,最小化等状态。 WinMain()所起的做用:初始化,展现,销毁应用程序等。 */ int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow) { static TCHAR szAppName[] = TEXT("Hello Win"); HWND hwnd;//定义窗口句柄 MSG msg;//建立消息 WNDCLASS wc;//定义窗口类,下面是窗口类的结构定义 /* typedef struct _WNDCLASSA { UINT style ; //窗口类风格 WNDPROC lpfnWndProc ; //指向窗口过程函数的指针 int cbClsExtra ; //窗口类附加数据 int cbWndExtra ; //窗口附加数据 HINSTANCE hInstance ; //拥有窗口类的实例句柄 HICON hIcon ; //最小窗口图标 HCURSOR hCursor ; //窗口内使用的光标 HBRUSH hbrBackground ; //用来着色窗口背景的刷子 LPCSTR lpszMenuName ; //指向菜单资源名的指针 LPCSTR lpszClassName ; // 指向窗口类名的指针 } */ wc.style = CS_HREDRAW | CS_VREDRAW; //窗口类风格 wc.lpfnWndProc = WndProc; //指向窗口过程函数的指针 wc.cbWndExtra = 0; //窗口类附加数据 wc.cbClsExtra = 0; //窗口附加数据 wc.hInstance = hinstance; //拥有窗口类的实例句柄 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); //最小窗口图标 wc.hCursor = LoadCursor(NULL, IDC_HAND);//窗口内使用的光标 wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); //用来着色窗口背景的刷子 wc.lpszMenuName = NULL;//指向菜单资源名的指针 wc.lpszClassName = szAppName;// 指向窗口类名的指针 //注册窗口类 if (!RegisterClass(&wc)) { MessageBox(NULL, TEXT("This program requires Windows NT"),szAppName,MB_ICONERROR); return 0; } //建立窗口,下面是函数原型 /* HWND CreateWindow( LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam ); 参数1:登记的窗口类名,这个类名刚才我们在注册窗口时已经定义过了。 参数2:用来代表窗口的标题。 参数3: 用来代表窗口的风格,若有无最大化,最小化按纽啊什么的。 参数4,5: 用来代表程序运行后窗口在屏幕中的坐标值。 参数6,7: 用来代表窗口初始化时(即程序初运行时)窗口的大小,即长度与宽度。 参数8: 在建立窗口时能够指定其父窗口,这里没有父窗口则参数值为。 参数9: 用以指明窗口的菜单,菜单之后会讲,这里暂时为。 最后一个参数是附加数据,通常都是NULL。 CreateWindow()的返回值是已经建立的窗口的句柄,应用程序使用这个句柄来引用该窗口。若是返回值为,就应该终止该程序, 由于可能某个地方出错了。若是一个程序建立了多个窗口,则每一个窗口都有各自不一样的句柄. */ hwnd = CreateWindow(szAppName,TEXT("Welcome to Windows API!"), WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL, NULL, hinstance,NULL); /*显示窗口 其第一个参数是窗口句柄,告诉ShowWindow()显示哪个窗口,而第二个参数则告诉它如何显示这个窗口: 最小化(SW_MINIMIZE),普通(SW_SHOWNORMAL),仍是最大化(SW_SHOWMAXIMIZED)。WinMain在建立完窗口后就调用ShowWindow函数, 并把nCmdShow参数传送给这个窗口。 */ ShowWindow(hwnd, nCmdShow); //更新窗口 UpdateWindow(hwnd); //消息循环 /* GetMessage(&msg,NULL,0,0),第一个参数是要接收消息的MSG结构的地址,第二个参数表示窗口句柄, NULL则表示要获取该应用程序建立的全部窗口的消息;第三,四参数指定消息范围。后面三个参数被设置为默认值, 这就是说你打算接收发送到属于这个应用程序的任何一个窗口的全部消息。在接收到除WM_QUIT以外的任何一个消息后, GetMessage()都返回TRUE。若是GetMessage收到一个WM_QUIT消息,则返回FALSE,如收到其余消息,则返回TRUE。所以, 在接收到WM_QUIT以前,带有GetMessage()的消息循环能够一直循环下去。只有当收到的消息是WM_QUIT时,GetMessage才 返回FALSE,结束消息循环,从而终止应用程序。均为NULL时就表示获取全部消息。 */ while (GetMessage(&msg,NULL, 0, 0)) { TranslateMessage(&msg);//翻译消息 DispatchMessage(&msg);//撤去消息 } return msg.wParam; } //窗口过程函数 LRESULT CALLBACK WndProc(HWND hwnd, //Handle to the window UINT message, // Specifies the message WPARAM wParam,//Specifies additional message information LPARAM lParam)// Specifies additional message information { HDC hdc;//Handle the device context PAINTSTRUCT ps; RECT rect; //消息处理 switch (message) { case WM_PAINT://重绘消息 hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rect); DrawText(hdc, TEXT("Hello, Windows API!"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); EndPaint(hwnd, &ps); return 0; case WM_DESTROY://窗口销毁消息 PostQuitMessage(0); return 0; default://其余消息由这个默认处理函数来处理 return DefWindowProc(hwnd, message, wParam,lParam); } }
2. 类中的数组不能直接={}赋值;则采用以下技巧:框架
class A{ private : int m_arr[10]; public: A() { int temp_arr[10] = {1,2,3,4,5,6,7,8,9,10}; memcpy(m_arr,temp_arr,sizeof(temp_arr)); } .................... }
3. 类中的const int不能开数组。可是static const int 能够。好比函数
private: //data static const int _mapheight = 23; static const int _mapwidth = 13; static const int _nblocktype = 7; int _tmap[_mapheight][_mapwidth]; //covered = 1; uncovered = 0;
4. 在case语句下若是有声明变量要加{}ui
5. 使用windows API绘图时很容易产生闪屏现象,须要使用双缓冲机制。特别注意释放内存。代码参照: RECT中的bottom>top;spa
HDC hMemDC; HBITMAP hbmp; hMemDC = CreateCompatibleDC(hdc); hbmp = CreateCompatibleBitmap(hdc, rect.right-rect.left, rect.bottom - rect.top ); SelectObject(hMemDC, hbmp); HBRUSH hb = CreateSolidBrush(RGB(0, 0, 0)); FillRect(hMemDC, &rect, CreateSolidBrush(GetBkColor(hdc))); //printf parameters RECT outputrect; outputrect.left = 10; outputrect.right = 300; outputrect.top = 10; outputrect.bottom = 30; char debug[20];sprintf(debug,"state: %d", myTetris._state); DrawText(hMemDC, debug, -1, &outputrect, DT_SINGLELINE | DT_LEFT | DT_VCENTER); outputrect.top += 20; outputrect.bottom += 20; sprintf(debug,"blockstate: %d", myTetris._blockstate); DrawText(hMemDC, debug, -1, &outputrect, DT_SINGLELINE | DT_LEFT | DT_VCENTER); outputrect.top += 20; outputrect.bottom += 20; sprintf(debug,"block_y: %d", myTetris._block_y); DrawText(hMemDC, debug, -1, &outputrect, DT_SINGLELINE | DT_LEFT | DT_VCENTER); outputrect.top += 20; outputrect.bottom += 20; sprintf(debug,"block_x: %d", myTetris._block_x); DrawText(hMemDC, debug, -1, &outputrect, DT_SINGLELINE | DT_LEFT | DT_VCENTER); int map[23][13]; myTetris.getMap(map); MoveToEx(hMemDC, rect.right/2 - 6.5*20 , rect.bottom - 0 ,NULL); LineTo(hMemDC, rect.right/2 - 6.5*20 , rect.bottom - 23*20); MoveToEx(hMemDC, rect.right/2 - 6.5*20 , rect.bottom - 0 ,NULL); LineTo(hMemDC, rect.right/2 + 6.5*20 , rect.bottom - 0); MoveToEx(hMemDC, rect.right/2 + 6.5*20 , rect.bottom - 0 ,NULL); LineTo(hMemDC, rect.right/2 + 6.5*20 , rect.bottom - 23*20); MoveToEx(hMemDC, rect.right/2 - 6.5*20 , rect.bottom - 23*20 ,NULL); LineTo(hMemDC, rect.right/2 + 6.5*20 , rect.bottom - 23*20); for(int i = 0 ; i < 23; i++) { for(int j = 0 ; j < 13; j++) { if(map[i][j]) { RECT* prect = new RECT(); prect->bottom = rect.bottom - i*20; prect->left = j*20 + rect.right/2 - 6.5*20; prect->top = prect->bottom - 18; prect->right = prect->left + 18; FillRect(hMemDC, prect, hb); } } } BitBlt(hdc,0,0,rect.right-rect.left,rect.bottom - rect.top,hMemDC,0,0,SRCCOPY); DeleteObject(hbmp); DeleteObject(hMemDC); DeleteObject(hb); ReleaseDC(hwnd,hdc); EndPaint(hwnd, &ps);
注意响应WM_ERASEBKGND消息命令行