1。 Text----------------------------------------------------------------
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint (hwnd, &ps);
//Make the bottom part of window a pattern so you can see what
//the transparency flag does
HBRUSH PatternBrush = CreateHatchBrush(HS_BDIAGONAL, RGB(0,0,255));
HBRUSH OldBrush = (HBRUSH)SelectObject(ps.hdc, PatternBrush);
Rectangle(ps.hdc,0, cyClient/2, cxClient, cyClient);
//replace the old brush
SelectObject(ps.hdc, OldBrush);
//first a demonstration of TextOut
char* text = "1. I ain't got time to bleed.";
TextOut(ps.hdc, 5, 5, text, strlen(text));
//now DrawText. First we create a text box
//文本框
RECT TextBox;
TextBox.top = 30;
TextBox.left = 100;
TextBox.bottom = 200;
TextBox.right = cxClient-100;
//assign some text
text = "2. You take the blue pill and the story ends.You wake in your bed and believe whatever you want to believe.You take the red pill and you stay in Wonderland and I show you how deep the rabbit-hole goes.";
//now print the text
DrawText(ps.hdc, text, strlen(text), &TextBox, DT_WORDBREAK);
//3. 开始颜色变化
//now to change the colors. First set text to red
SetTextColor(ps.hdc, RGB(255, 0, 0));
//background to black
SetBkColor(ps.hdc, RGB(0, 0, 0));
TextBox.top = 200;
TextBox.left = 5;
TextBox.bottom = 300;
TextBox.right = cxClient-200;
text = "3. The greatest trick the devil ever pulled was convincing the world he didn't exist.";
DrawText(ps.hdc, text, strlen(text), &TextBox, DT_WORDBREAK);
//now set background to transparent
SetBkMode(ps.hdc, TRANSPARENT);
TextBox.top = 300;
TextBox.left = 100;
TextBox.bottom = cyClient;
TextBox.right = cxClient-50;
text = "4. ...I�m 42 years old. In less than a year I�ll be dead";
DrawText(ps.hdc, text, strlen(text), &TextBox, DT_WORDBREAK);
EndPaint (hwnd, &ps);
}
2。 使用PeekMessage not GetMessage--------------------------------------------
// Enter the message loop
bool bDone = false;
MSG msg;
while(!bDone)
{
while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if( msg.message == WM_QUIT )
{
// Stop loop if it's a quit message
bDone = true;
}
else
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
//this will call WM_PAINT which will render our scene
InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);
//*** your game loop goes here ***//
}//end while
3。 bouncing ball----------------------------------------------------------------
LRESULT CALLBACK WindowProc (HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
static HPEN BluePen = CreatePen(PS_SOLID, 1, RGB(0,0,255));
static HPEN OldPen = NULL;
static HBRUSH RedBrush = CreateSolidBrush(RGB(255,0,0));
static HBRUSH OldBrush = NULL;
static int cxClient, cyClient;
//小球
static SBall* balls = new SBall[NUM_BALLS];
switch (msg)
{
//A WM_CREATE msg is sent when your application window is first
//created
case WM_CREATE:
{
RECT rect;
GetClientRect(hwnd, &rect);
cxClient = rect.right;
cyClient = rect.bottom;
srand((unsigned)time(NULL));
//Initial the balls
for(int i=0; i<NUM_BALLS; i++){
balls[i].posX = RandInt(0, cxClient);
balls[i].posY = RandInt(0, cyClient);
balls[i].velX = RandInt(0, MAX_VELOCITY);
balls[i].velY = RandInt(0, MAX_VELOCITY);
}
//绘制出小球?用Ellipse
//让小球移动呢?用改变坐标的方法
//小球的移动速度如何处理?刷新显示(就能看到)
}
break;
case WM_SIZE:
{
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
}
break;
case WM_KEYUP:
{
switch(wParam)
{
case VK_ESCAPE:
{
PostQuitMessage(0);
}
break;
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint (hwnd, &ps);
//**this is where we do any drawing to the screen**
OldPen = (HPEN) SelectObject(ps.hdc, BluePen);
OldBrush = (HBRUSH) SelectObject(ps.hdc, RedBrush);
for(int i=0; i<NUM_BALLS; ++i){
if((balls[i].posX>=cxClient)||(balls[i].posY<0))
balls[i].velX = -balls[i].velX;
if((balls[i].posY>=cyClient)||(balls[i].posY<0))
balls[i].velY = -balls[i].velY;
//Update their position
balls[i].posX += balls[i].velX;
balls[i].posY += balls[i].velY;
//Render to display
Ellipse(ps.hdc,
balls[i].posX - RADIUS,5
balls[i].posY - RADIUS,
balls[i].posX + RADIUS,
balls[i].posY + RADIUS);
}
SelectObject(ps.hdc, OldPen);
//and brush
SelectObject(ps.hdc, OldBrush);
EndPaint (hwnd, &ps);
//加了这句就能看到缓慢的刷新过程(移动过程)
Sleep(10);
}
break;
case WM_DESTROY:
{
// kill the application, this sends a WM_QUIT message
DeleteObject(BluePen);
DeleteObject(OldPen);
//and the brushes
DeleteObject(RedBrush);
DeleteObject(OldBrush);
//and the balls
delete[] balls;
PostQuitMessage (0);
}
break;
}//end switch
//this is where all the messages not specifically handled by our
//winproc are sent to be processed
return DefWindowProc (hwnd, msg, wParam, lParam);
}
4。 bouncing ball (cache)------------------------------------------------------
实现双缓冲: 如果要在内存中创建一块区域来表示前置(显示区域),首先需要的,是创建一个与显示DC相兼容的内存设备描述表。 分3步。
HDC hdcBackBuffer = CreateCompatibleDC(NULL);
用NULL作为参数时,Windows默认创建一个与当前屏幕兼容的DC,而这正是编程者所希望实现的。但当内存设备描述表被创建出来时,它是单色的,并且宽度和高度各为一个像素,这并不实用。 因此, 在开始使用它绘图之前,需要创建一张大小和格式与前置缓冲区完全一致的位图,并利用SelectObject函数将其选入内存DC.
HDC hdc = GetDC(hWnd);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, cxClient, cyClient);
HBITMAP hOldBitMap = (HBITMAP) SelectObject( hdcBackBuffer, hBitmap);
已经存在的1*1像素的单色位图的一个备份被保留,因此可以在绘图完毕时将它返回来,清理后备缓冲。
LRESULT CALLBACK WindowProc (HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
static HPEN BluePen = CreatePen(PS_SOLID, 1, RGB(0,0,255));
static HPEN OldPen = NULL;
static HBRUSH RedBrush = CreateSolidBrush(RGB(255,0,0));
static HBRUSH OldBrush = NULL;
static int cxClient, cyClient;
//小球
static SBall* balls = new SBall[NUM_BALLS];
//创建Back Buffer
static HDC hdcBackBuffer;
static HBITMAP hBitmap;
static HBITMAP hOldBitmap;
switch (msg)
{
//A WM_CREATE msg is sent when your application window is first
//created
case WM_CREATE:
{
RECT rect;
GetClientRect(hwnd, &rect);
cxClient = rect.right;
cyClient = rect.bottom;
srand((unsigned)time(NULL));
//Initial the balls
for(int i=0; i<NUM_BALLS; i++){
balls[i].posX = RandInt(0, cxClient);
balls[i].posY = RandInt(0, cyClient);
balls[i].velX = RandInt(0, MAX_VELOCITY);
balls[i].velY = RandInt(0, MAX_VELOCITY);
}
//绘制出小球?用Ellipse
//让小球移动呢?用改变坐标的方法
//小球的移动速度如何处理?刷新显示(就能看到)
//创建后备缓冲区
hdcBackBuffer = CreateCompatibleDC(NULL);
HDC hdc = GetDC(hwnd);
//cxClient 和 cyClient 变化了怎么办
hBitmap = CreateCompatibleBitmap(hdc, cxClient, cyClient);
hOldBitmap = (HBITMAP) SelectObject(hdcBackBuffer, hBitmap);
//释放DC
ReleaseDC(hwnd, hdc);
}
break;
case WM_SIZE:
{
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
//双缓冲
//因为
SelectObject(hdcBackBuffer, hOldBitmap);
DeleteObject(hBitmap);
HDC hdc = GetDC(hwnd);
hBitmap = CreateCompatibleBitmap(hdc, cxClient, cyClient);
ReleaseDC(hwnd, hdc);
SelectObject(hdcBackBuffer, hBitmap);
}
break;
case WM_KEYUP:
{
switch(wParam)
{
case VK_ESCAPE:
{
PostQuitMessage(0);
}
break;
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint (hwnd, &ps);
//1.使用缓冲区,使用BitBlt填充背景
BitBlt(hdcBackBuffer,
0,
0,
cxClient,
cyClient,
NULL,
NULL,
NULL,
WHITENESS);
//**this is where we do any drawing to the screen**
OldPen = (HPEN) SelectObject(hdcBackBuffer, BluePen);
OldBrush = (HBRUSH) SelectObject(hdcBackBuffer, RedBrush);
for(int i=0; i<NUM_BALLS; ++i){
if((balls[i].posX>=cxClient)||(balls[i].posY<0))
balls[i].velX = -balls[i].velX;
if((balls[i].posY>=cyClient)||(balls[i].posY<0))
balls[i].velY = -balls[i].velY;
//Update their position
balls[i].posX += balls[i].velX;
balls[i].posY += balls[i].velY;
//Render to display
Ellipse(hdcBackBuffer,
balls[i].posX - RADIUS,
balls[i].posY - RADIUS,
balls[i].posX + RADIUS,
balls[i].posY + RADIUS);
}
SelectObject(hdcBackBuffer, OldPen);
//and brush
SelectObject(hdcBackBuffer, OldBrush);
BitBlt(ps.hdc,
0,
0,
cxClient,
cyClient,
hdcBackBuffer,
0,
0,
SRCCOPY);
EndPaint (hwnd, &ps);
//加了这句就能看到缓慢的刷新过程(移动过程)
Sleep(10);
}
break;
case WM_DESTROY:
{
// kill the application, this sends a WM_QUIT message
DeleteObject(BluePen);
DeleteObject(OldPen);
//and the brushes
DeleteObject(RedBrush);
DeleteObject(OldBrush);
//and the balls
delete[] balls;
SelectObject(hdcBackBuffer, hOldBitmap);
DeleteDC(hdcBackBuffer);
DeleteObject(hBitmap);
PostQuitMessage (0);
}
break;
}//end switch
//this is where all the messages not specifically handled by our
//winproc are sent to be processed
return DefWindowProc (hwnd, msg, wParam, lParam);
}
//利用到了WNDCLASSEX结构的填充,API还是会把窗口填充为白色背景,造成一定的闪烁
//winclass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);