回顾GDI绘制文本(一)
以下是游戏编程大师技巧里的代码// get the dc and hold it
HDC hdc = GetDC(hwnd);
// enter main event loop, but this time we use PeekMessage()
// instead of GetMessage() to retrieve messages
while(TRUE)
{
// test if there is a message in queue, if so get it
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
// test if this is a quit
if (msg.message == WM_QUIT)
break;
// translate any accelerator keys
TranslateMessage(&msg);
// send the message to the window proc
DispatchMessage(&msg);
} // end if
// main game processing goes here
// set the foreground color to random
SetTextColor(hdc, RGB(rand()%256,rand()%256,rand()%256));
// set the background color to black
SetBkColor(hdc, RGB(0,0,0));
// finally set the transparency mode to transparent
SetBkMode(hdc, TRANSPARENT);
// draw some text at a random location
TextOut(hdc,rand()%400,rand()%400, "GDI Text Demo!", strlen("GDI Text Demo!"));
Sleep(10);
} // end while
// release the dc
ReleaseDC(hwnd,hdc);
以上代码作用是在一个大小400*400的窗口中随机绘制文本"GDI Text Demo!"
文本前景色为随机产生,使用RGB()控制.
文本背景色为黑色.
透明模式为TRANSPARENT
每次绘制采用Sleep(10)作延时
---------------------------------------------------------------------------------------------------------------------------------
我是菜鸟不是高手,在这里不讨论GDI+的内容,在这里发的只是个人的理解,希望对你学习GDI有所帮助^_^
[ 本帖最后由 qxtianlong 于 2005-12-22 10:57 AM 编辑 ] 回顾GDI绘制文本(二)
case WM_SIZE:
{
// extract size info
int width= LOWORD(lparam);
int height = HIWORD(lparam);
// get a graphics context
hdc = GetDC(hwnd);
// set the foreground color to green
SetTextColor(hdc, RGB(0,255,0));
// set the background color to black
SetBkColor(hdc, RGB(0,0,0));
// set the transparency mode to OPAQUE
SetBkMode(hdc, OPAQUE);
// draw the size of the window
sprintf(buffer,"WM_SIZE Called -New Size = (%d,%d)", width, height);
TextOut(hdc, 0,0, buffer, strlen(buffer));
// release the dc back
ReleaseDC(hwnd, hdc);
} break;
哇哈哈,这次新东西少了,主要是可以通过LOWORD(lparam)和HIWORD(lparam)跟踪客户区的尺寸
透明模式:OPAQUE
但是似乎XP系统里,WM_PAINT消息晚于WM_SIZE消息,这样在WM_SIZE消息中的显示信息都会被擦除啊 回顾GDI绘制文本(三)
case WM_CLOSE:
{
// kill message, so no further WM_DESTROY is sent
return(0);
} break;
------------------------------------------------------------------------------------------------------------------------------------
WM_CLOSE消息发送于WM_DESTRY和WM_QUIT之前,所以我们什么都不做就不会传递窗口被关闭的消息了!酷吧~~
------------------------------------------------------------------------------------------------------------------------------------
case WM_CLOSE:
{
// display message box
int result =MessageBox(hwnd, "Are you sure you want to close this application?",
"WM_CLOSE Message Processor",
MB_YESNO | MB_ICONQUESTION);
// does the user want to close?
if (result == IDYES)
{
// call default handler
return (DefWindowProc(hwnd, msg, wparam, lparam));
} // end if
else // throw message away
return(0);
} break;
------------------------------------------------------------------------------------------------------------------------------------
此为根据检测MessageBox的返回值来进行一些处理,当result=IDYES时就默认处理,当然你可以做别的处理啦! 回顾GDI绘制文本(四)
case WM_MOVE:
{
// extract the position
int xpos = LOWORD(lparam);
int ypos = HIWORD(lparam);
// get a graphics context
hdc = GetDC(hwnd);
// set the foreground color to green
SetTextColor(hdc, RGB(0,255,0));
// set the background color to black
SetBkColor(hdc, RGB(0,0,0));
// set the transparency mode to OPAQUE
SetBkMode(hdc, OPAQUE);
// draw the size of the window
sprintf(buffer,"WM_MOVE Called -New Positition = (%d,%d)", xpos, ypos);
TextOut(hdc, 0,0, buffer, strlen(buffer));
// release the dc back
ReleaseDC(hwnd, hdc);
} break;
这个和以前一样,只不过LOWORD(lparam)和HIWORD(lparam)捕获的是窗口移动时的坐标了而不再是WM_SIZE消息时的窗口大小 回顾GDI绘制文本(五)
case WM_CHAR:
{
// get the character
char ascii_code = wparam;
unsigned int key_state = lparam;
// get a graphics context
hdc = GetDC(hwnd);
// set the foreground color to green
SetTextColor(hdc, RGB(0,255,0));
// set the background color to black
SetBkColor(hdc, RGB(0,0,0));
// set the transparency mode to OPAQUE
SetBkMode(hdc, OPAQUE);
// print the ascii code and key state
sprintf(buffer,"WM_CHAR: Character = %c ",ascii_code);
TextOut(hdc, 0,0, buffer, strlen(buffer));
sprintf(buffer,"Key State = 0X%X",key_state);
TextOut(hdc, 0,16, buffer, strlen(buffer));
// release the dc back
ReleaseDC(hwnd, hdc);
} break;
---------------------------------------------------------------
上面是一个检测按键消息的测试,使用WM_CHAR方式,wparam包含ascII码,lparam包含状态量
按键又一消息方式为
WM_KEYDOWN和WM_KEYUP
他们所不同的是一个跟踪按下的状态、一个跟踪松开时的状态
他们与WM_CHAR所不同的是wparam包含的不是ascII码而是虚拟键码,lparam包含的也是状态量
例如可以通过;
int virtual_code = (int)wparam;
switch(virtual_code)
{
case VK_RIGHT:
{
//do someting
}break;
……………………
default:break;
}
这样的方式来检测按键所发生的事情.
------------------------------------------------------
还有一种就是用Win32的函数GetAsyncKeyState等这一类的函数检测键盘状态
游戏大师中定义的宏
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
改函数的好处在于没有和事件循环耦合,可以随意的测试按键
例如:
// enter main event loop, but this time we use PeekMessage()
// instead of GetMessage() to retrieve messages
while(TRUE)
{
// test if there is a message in queue, if so get it
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
// test if this is a quit
if (msg.message == WM_QUIT)
break;
// translate any accelerator keys
TranslateMessage(&msg);
// send the message to the window proc
DispatchMessage(&msg);
} // end if
// main game processing goes here
// get a graphics context
hdc = GetDC(hwnd);
// set the foreground color to green
SetTextColor(hdc, RGB(0,255,0));
// set the background color to black
SetBkColor(hdc, RGB(0,0,0));
// set the transparency mode to OPAQUE
SetBkMode(hdc, OPAQUE);
// print out the state of each arrow key
sprintf(buffer,"Up Arrow: = %d ",KEYDOWN(VK_UP));
TextOut(hdc, 0,0, buffer, strlen(buffer));
sprintf(buffer,"Down Arrow: = %d ",KEYDOWN(VK_DOWN));
TextOut(hdc, 0,16, buffer, strlen(buffer));
sprintf(buffer,"Right Arrow: = %d ",KEYDOWN(VK_RIGHT));
TextOut(hdc, 0,32, buffer, strlen(buffer));
sprintf(buffer,"Left Arrow: = %d ",KEYDOWN(VK_LEFT));
TextOut(hdc, 0,48, buffer, strlen(buffer));
// release the dc back
ReleaseDC(hwnd, hdc);
} // end while
以上是在主循环中利用定义的宏不停的测试按键消息 回顾GDI绘制文本(六)
case WM_MOUSEMOVE:
{
// get the position of the mouse
int mouse_x = (int)LOWORD(lparam);
int mouse_y = (int)HIWORD(lparam);
// get the button state
int buttons = (int)wparam;
// get a graphics context
hdc = GetDC(hwnd);
// set the foreground color to green
SetTextColor(hdc, RGB(0,255,0));
// set the background color to black
SetBkColor(hdc, RGB(0,0,0));
// set the transparency mode to OPAQUE
SetBkMode(hdc, OPAQUE);
// print the ascii code and key state
sprintf(buffer,"Mouse (X,Y) = (%d,%d) ",mouse_x,mouse_y);
TextOut(hdc, 0,0, buffer, strlen(buffer));
sprintf(buffer,"Right Button = %d",((buttons & MK_RBUTTON) ? 1 : 0));
TextOut(hdc, 0,16, buffer, strlen(buffer));
sprintf(buffer,"Left Button = %d",((buttons & MK_LBUTTON) ? 1 : 0));
TextOut(hdc, 0,32, buffer, strlen(buffer));
// release the dc back
ReleaseDC(hwnd, hdc);
} break;
WM_MOUSEMOVE消息,lparam包含鼠标位置量,wparam包含WM_MOUSEMOVE按键状态量
以上只有在鼠标移动中才会产生消息,如果不移动将不会有消息,不管你有没有按下鼠标键
因为它是WM_MOUSEMOVE! 回顾GDI绘制文本(七)
// enter main event loop, but this time we use PeekMessage()
// instead of GetMessage() to retrieve messages
while(TRUE)
{
// test if there is a message in queue, if so get it
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
// test if this is a quit
if (msg.message == WM_QUIT)
break;
// translate any accelerator keys
TranslateMessage(&msg);
// send the message to the window proc
DispatchMessage(&msg);
} // end if
// main game processing goes here
if (KEYDOWN(VK_ESCAPE))
SendMessage(hwnd, WM_CLOSE, 0,0);
} // end while
自行发送消息有两种方式:一种是SendMessage(), 一种是PostMessage(),他们的区别在于
SendMessage是向窗口传递一个要求立即处理的消息,接受窗口处理完该消息后,该函数紧接着Winproc()返回.
PostMessage是将消息发送窗口的消息序列中去,如果你不在意延迟可以使用他!
对于窗口的关闭可以使用WM_CLOSE、WM_DESTROY,他们都可以起到关闭的作用。
我们可以利用以前定义的宏来实现:
例如上面的那样:
if(KEYDOWN(VK_ESCAPE))
SendMessage(hwnd,WM_CLOSE,0,0);
页:
[1]