报告鼠标和键盘事件的一个程序(转)

在本章中,我将介绍窗口过程和基本的正文输出,并对一些较高级的题材,如键盘和鼠标,作一个简洁的介绍。消息系统完美的风格使得你可以相对完全地、及时地对这两个硬件设备进行控制。
  现在,你可以开始输入并运行程序清单 5.1 上的程序。

程序清单 5.1 KeyMouse 程序,用于追踪键盘和鼠标的输入
///////////////////////////////////////
// Program Name:KeyMouse.cpp
// Programer: skyline
// Description: Show how to trap keyboard and mouse input
///////////////////////////////////////

#define STRICT
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <windowsx.h>
#include <string.h>
#include <stdio.h>

#pragma warning (disable:4068)
#pragma warning (disable:4100)

//-----------------------------
// Interface
//-----------------------------

// Some variabls

static int Xval=10;
static int Yval=30;
static char szAppName[]="KeyMouse";
static HWND MainWindow;

// Some procs

LRESULT CALLBACK WndProc(HWND hwnd,UINT Message,
WPARAM wParam,LPARAM lParam);
BOOL Register(HINSTANCE hInst);
HWND Create(HINSTANCE hInst,int nCmdShow);

#define skyline_DefProc DefWindowProc

void skyline_OnDestroy(HWND hwnd);
void skyline_OnChar(HWND hwnd,UINT ch,int cRepeat);
void skyline_OnKey(HWND hwnd,UINT vk,BOOL fDown,
int cRepeat,UINT flags);
void skyline_OnLButtonDown(HWND hwnd,BOOL fDoubleCick,
int x,int y,UINT KeyFlags);
void skyline_OnLButtonUp(HWND hwnd,int x,int y,UINT KeyFlags);
void skyline_OnMouseMove(HWND hwnd,int x,int y,UINT KeyFlags);
void skyline_OnPaint(HWND hwnd);
void skyline_OnSysKey(HWND hwnd,UINT vk,BOOL fDown,
int cRepeat,UINT flags);

//-----------------------
// Initalization
//-----------------------

///////////////////////////
// Program entry point.
///////////////////////////

#pragma argsused

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInstance,
LPSTR lpszCmdParam,int nCmdShow)
{
MSG Msg;

if (! hPrevInstance)
if (! Register(hInst))
return FALSE;

MainWindow = Create(hInst,nCmdShow);
if(! MainWindow)
return FALSE;

while(GetMessage(&Msg,NULL,0,0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}

////////////////////////////////////
// Register the window
////////////////////////////////////

BOOL Register(HINSTANCE hInst)
{
WNDCLASS WndClass;

WndClass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInst;
WndClass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = szAppName;

return RegisterClass(&WndClass);
}

////////////////////////////////////
// Create the Window
////////////////////////////////////

HWND Create(HINSTANCE hInstance,int nCmdShow)
{
HWND hwnd = CreateWindowEx (0,szAppName,szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL);
if(hwnd == NULL)
return hwnd;

ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);

return hwnd;
}

//----------------------------
// WndProc and Implementation
//----------------------------

//////////////////////////////////
// The WindowProcedured
//////////////////////////////////

LRESULT CALLBACK WndProc(HWND hwnd,UINT Message,
WPARAM wParam,LPARAM lParam)
{
switch(Message)
{
HANDLE_MSG(hwnd,WM_DESTROY,skyline_OnDestroy);
HANDLE_MSG(hwnd,WM_CHAR,skyline_OnChar);
HANDLE_MSG(hwnd,WM_KEYDOWN,skyline_OnKey);
HANDLE_MSG(hwnd,WM_KEYUP,skyline_OnKey);
HANDLE_MSG(hwnd,WM_MOUSEMOVE,skyline_OnMouseMove);
HANDLE_MSG(hwnd,WM_LBUTTONDBLCLK,skyline_OnLButtonDown);
HANDLE_MSG(hwnd,WM_LBUTTONDOWN,skyline_OnLButtonDown);
HANDLE_MSG(hwnd,WM_LBUTTONUP,skyline_OnLButtonUp);
HANDLE_MSG(hwnd,WM_PAINT,skyline_OnPaint);
HANDLE_MSG(hwnd,WM_SYSKEYUP,skyline_OnSysKey);
HANDLE_MSG(hwnd,WM_SYSKEYDOWN,skyline_OnSysKey);

default:
return skyline_DefProc(hwnd,Message,wParam,lParam);
}
}

///////////////////////////////////////
// Handle WM_DESTROY
///////////////////////////////////////

#pragma argsused
void skyline_OnDestroy(HWND hwnd)
{
PostQuitMessage(0);
}

///////////////////////////////////////
// Handle regular keyboard hits
// Use if you want to trap the letter keys or number keys.
///////////////////////////////////////

#pragma argsused
void skyline_OnChar(HWND hwnd,UINT ch,int cRepeat)
{
char S[100];

HDC DC = GetDC(hwnd);

sprintf(S,"WM_CHAR ==> Char = %c cRepeat = %d ",
ch,cRepeat);
TextOut(DC,Xval,Yval+20,S,strlen(S));

ReleaseDC(hwnd,DC);
}

///////////////////////////////////////
// Handle a key press
// Don't try to process letter keys or number keys here.
// Instead, ues WM_CHAR messages.
///////////////////////////////////////

#pragma argsused
void skyline_OnKey(HWND hwnd,UINT vk,BOOL fDown,
int cRepeat,UINT flags)
{
char S[100];

HDC DC = GetDC(hwnd);

if(fDown)
sprintf(S,"WM_KEYDOWN ==> VK = %d fDown = %d cRepeat = %d "
"Flags = %d ",vk,fDown,cRepeat,flags);
else
sprintf(S,"WM_KEYUP ==> VK = %d fDown = %d cRepeat = %d "
"Flags = %d ",vk,fDown,cRepeat,flags);

SetBkColor(DC,GetSysColor(COLOR_WINDOW));
TextOut(DC,Xval,Yval+40,S,strlen(S));

ReleaseDC(hwnd,DC);
}

///////////////////////////////////////
// This function is called when the left mouse button is
// click or when the user double-clicks the mouse
///////////////////////////////////////

#pragma argsused
void skyline_OnLButtonDown(HWND hwnd,BOOL fDoubleClick,
int x,int y,UINT KeyFlags)
{
char S[100];

HDC DC = GetDC(hwnd);

if(fDoubleClick)
sprintf(S,"WM_LBUTTONDBLCLK ==> DblClk = %d X = %d Y = %d "
"Flags = %d ",fDoubleClick,x,y,KeyFlags);
else
sprintf(S,"WM_LBUTTONDOWN ==> Down = %d X = %d Y = %d "
"Flags = %d ",fDoubleClick,x,y,KeyFlags);

SetBkColor(DC,GetSysColor(COLOR_WINDOW));
TextOut(DC,Xval,Yval+100,S,strlen(S));

ReleaseDC(hwnd,DC);
}

///////////////////////////////////////
// This function is called when the mouse button is released
///////////////////////////////////////

#pragma argsused
void skyline_OnLButtonUp(HWND hwnd,int x,int y,UINT KeyFlags)
{
char S[100];

HDC DC = GetDC(hwnd);

sprintf(S,"WM_LBUTTONUP ==> X = %d Y = %d "
"Flag = %d ",x,y,KeyFlags);

SetBkColor(DC,GetSysColor(COLOR_WINDOW));
TextOut(DC,Xval,Yval+120,S,strlen(S));

ReleaseDC(hwnd,DC);
}

///////////////////////////////////////
// This function is called whenever the mouse moves
///////////////////////////////////////

#pragma argsused
void skyline_OnMouseMove(HWND hwnd,int x,int y,UINT KeyFlags)
{
char S[100];

HDC DC = GetDC(hwnd);

sprintf(S,"WM_MOUSEMOVE ==> X = %d Y = %d "
"KeyFlags = %d ",x,y,KeyFlags);

if((KeyFlags & MK_CONTROL) == MK_CONTROL)
SetTextColor(DC,RGB(0,0,255));
if((KeyFlags & MK_LBUTTON) == MK_LBUTTON)
SetTextColor(DC,RGB(0,128,0));
if((KeyFlags & MK_RBUTTON) == MK_RBUTTON)
SetTextColor(DC,RGB(152,84,95));
if((KeyFlags & MK_SHIFT) == MK_SHIFT)
SetTextColor(DC,RGB(196,0,196));

SetBkColor(DC,GetSysColor(COLOR_WINDOW));
TextOut(DC,Xval,Yval+80,S,strlen(S));

ReleaseDC(hwnd,DC);
}

///////////////////////////////////////
// Handle WM_PAINT messages
///////////////////////////////////////

void skyline_OnPaint(HWND hwnd)
{
PAINTSTRUCT PaintStruct;
RECT Rect;

static char * Message[] =
{
"WM_CHAR",
"WM_KEY",
"WM_SYSKEY",
"WM_MOUSEMOVE",
"WM_MOUSEDOWN",
"WM_MOUSEUP"
};

HDC PaintDC = BeginPaint(hwnd,&PaintStruct);

SetBkColor(PaintDC,GetSysColor(COLOR_WINDOW));
HFONT OldFont = SelectFont(PaintDC,
GetStockObject(OEM_FIXED_FONT));

GetClientRect(hwnd,&Rect);
Rect.top = 5;
DrawText(PaintDC,"Mouse and Keyboard Demonstration",-1,
&Rect,DT_CENTER);
Rect.top = 20;
Rect.bottom = 40;
DrawText(PaintDC,"Try experimenting with mouse and keyboard.",-1,
&Rect,DT_CENTER);

SelectFont(PaintDC,OldFont);

for(int i=0;i<6;i++)
TextOut(PaintDC,Xval,Yval+(20*(i+1)),
Message[i],strlen(Message[i]));

EndPaint(hwnd,&PaintStruct);
}

///////////////////////////////////////
// This function is called whenever the ALT key is pressed.
///////////////////////////////////////

#pragma argsused
void skyline_OnSysKey(HWND hwnd,UINT vk,BOOL fDown,
int cRepeat,UINT flags)
{
char S[100];

HDC DC = GetDC(hwnd);
SetBkColor(DC,GetSysColor(COLOR_WINDOW));

if(fDown)
{
sprintf(S,"WM_SYSKEYDOWN ==> VK = %d fDown = %d "
"cRepeat = %d ",vk,fDown,cRepeat,flags);
TextOut(DC,Xval,Yval+60,S,strlen(S));
FORWARD_WM_SYSKEYUP(hwnd,vk,cRepeat,flags,skyline_DefProc);
}
else
{
sprintf(S,"WM_SYSKEYUP ==> VK = %d fDown = %d "
"cRepeat = %d ",vk,fDown,cRepeat,flags);
TextOut(DC,Xval,Yval+60,S,strlen(S));
FORWARD_WM_SYSKEYUP(hwnd,vk,cRepeat,flags,skyline_DefProc);
}

ReleaseDC(hwnd,DC);
}
KeyMouse 程序提供两种主要的服务:
  ·如何检测一个键被按下,并且显示按下键的键值以及一些相关的信息。
  ·如何检测鼠标的移动或鼠标是否被按下,并在屏幕上显示出鼠标的当前位置及状态。
  你可以花几分钟运行一下这个程序。当你移动鼠标或者按下键盘时,注意屏幕窗口上的反应。还要记住,每当你按下 Alt 键时,位于标题栏左上方的系统菜单就会被激活。此时若按一般的键都不会使屏幕恢复原样,除非再次按下 Alt 键或者采取其他动作改变焦点(focus)。有关检测 Alt 键按下动作的讨论在论述 WM_SYSKEY 消息一节中进行。

  附注:
  在 Windows 程序设计中,焦点的概念是很重要的。只有被聚焦的窗口才会响应键盘和鼠标的输入,而没有被聚焦的窗口是不响应的。你经常可以知道哪一个特定程序处于焦点,只要检查一下它的标题栏是否为高亮度显示就可以了。

  同样十分重要的是要理解一个时刻只有一个窗口处于聚焦状态。例如,如果你打开 File 菜单,那么这个新打开的菜单处于焦点位置,而程序的主窗口就处于非活动状态。同样,在 My Computer 窗口中,当从 View 菜单中弹出 Options 对话框时,这个对话框是焦点,而 My Computer 窗口的其它部分是不活动的。
posted @ 2011-11-09 18:47  ☆A希亿  阅读(618)  评论(0编辑  收藏  举报