📄 ch04.htm
字号:
TShiftState Shift, int X, int Y)
{
LMouseUp->Caption = "X " + IntToStr(X) + " Y " +
IntToStr(Y) + " " + GetShift(Shift);
}
void __fastcall TForm1::FormKeyUp(TObject *Sender, WORD &Key, TShiftState Shift)
{
LKeyUp->Caption = GetKey(Key) + " " + GetShift(Shift);
}
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
TShiftState
Shift)
{
LKeyDown->Caption = GetKey(Key) + " " + GetShift(Shift);
}
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X,
int Y)
{
LMouseMove->Caption = "X " + IntToStr(X) + " Y
" +
IntToStr(Y) + " " + GetShift(Shift);
}
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
LMouseDown->Caption = GetShift(Shift);
}
</FONT></PRE>
<P><A NAME="Heading18"></A><FONT COLOR="#000077"><B>Listing 4.5. The VKeys unit is
used by the EVENTS2 program.</B></FONT></P>
<PRE><FONT COLOR="#0066FF">///////////////////////////////////////
// Vkeys.cpp
// Project Name: Events2
//
Copyright (c) 1997 by Charles Calvert
//
#include <vcl.h>
#pragma hdrstop
#include "VKeys1.h"
AnsiString MessageArray[5] =
{"WM_CHAR", "WM_KEY", "WM_MOUSEMOVE", "WM_MOUSEDOWN",
"WM_MOUSEUP"};
AnsiString ButtonArray[3] =
{"mbLeft", "mbRight", "mbCenter"};
AnsiString ShiftArray[8] = {"ssShift", "ssAlt", "ssCtrl", "ssLeft",
"ssRight", "ssMiddle", "ssDouble", "ssUnknown"};
AnsiString GetShift(TShiftState State)
{
int B = 0, i;
AnsiString S;
for (i = 0; i <= 7; i++)
{
if (State.Contains(i))
S = S + "
" + ShiftArray[i];
}
return S;
}
AnsiString GetKey(WORD K)
{
AnsiString S;
switch (K)
{
case VK_LBUTTON: S = "VK_LButton"; break;
case VK_RBUTTON : S = "VK_RBUTTON"; break;
case VK_CANCEL
: S = "VK_CANCEL"; break;
case VK_MBUTTON : S = "VK_MBUTTON"; break;
case VK_BACK : S = "VK_BACK"; break;
case VK_TAB : S = "VK_TAB"; break;
case VK_CLEAR : S =
"VK_CLEAR"; break;
case VK_RETURN : S = "VK_RETURN"; break;
case VK_SHIFT : S = "VK_SHIFT"; break;
case VK_CONTROL : S = "VK_CONTROL"; break;
case VK_MENU : S =
"VK_MENU"; break;
case VK_PAUSE : S = "VK_PAUSE"; break;
case VK_CAPITAL : S = "VK_CAPITAL"; break;
case VK_ESCAPE : S = "VK_ESCAPE"; break;
case VK_SPACE : S =
"VK_SPACE"; break;
case VK_PRIOR : S = "VK_PRIOR"; break;
case VK_NEXT : S = "VK_NEXT"; break;
case VK_END : S = "VK_END"; break;
case VK_HOME : S = "VK_HOME";
break;
case VK_LEFT : S = "VK_LEFT"; break;
case VK_UP : S = "VK_UP"; break;
case VK_RIGHT : S = "VK_RIGHT"; break;
case VK_DOWN : S = "VK_DOWN"; break;
case
VK_SELECT : S = "VK_SELECT"; break;
case VK_PRINT : S = "VK_PRINT"; break;
case VK_EXECUTE : S = "VK_EXECUTE"; break;
case VK_SNAPSHOT : S = "VK_SNAPSHOT"; break;
case VK_INSERT
: S = "VK_INSERT"; break;
case VK_DELETE : S = "VK_DELETE"; break;
case VK_HELP : S = "VK_HELP"; break;
case VK_NUMPAD0 : S = "VK_NUMPAD0"; break;
case VK_NUMPAD1 : S =
"VK_NUMPAD1"; break;
case VK_NUMPAD2 : S = "VK_NUMPAD2"; break;
case VK_NUMPAD3 : S = "VK_NUMPAD3"; break;
case VK_NUMPAD4 : S = "VK_NUMPAD4"; break;
case VK_NUMPAD5 : S =
"VK_NUMPAD5"; break;
case VK_NUMPAD6 : S = "VK_NUMPAD6"; break;
case VK_NUMPAD7 : S = "VK_NUMPAD7"; break;
case VK_NUMPAD8 : S = "VK_NUMPAD8"; break;
case VK_NUMPAD9 : S =
"VK_NUMPAD9"; break;
case VK_MULTIPLY : S = "VK_MULTIPLY"; break;
case VK_ADD : S = "VK_ADD"; break;
case VK_SEPARATOR : S = "VK_SEPARATOR"; break;
case VK_SUBTRACT : S =
"VK_SUBTRACT"; break;
case VK_DECIMAL : S = "VK_DECIMAL"; break;
case VK_DIVIDE : S = "VK_DIVIDE"; break;
case VK_F1 : S = "VK_F1"; break;
case VK_F2 : S =
"VK_F2"; break;
case VK_F3 : S = "VK_F3"; break;
case VK_F4 : S = "VK_F4"; break;
case VK_F5 : S = "VK_F5"; break;
case VK_F6 : S = "VK_F6"; break;
case VK_F7 : S = "VK_F7"; break;
case VK_F8 : S = "VK_F8"; break;
case VK_F9 : S = "VK_F9"; break;
case VK_F10 : S = "VK_F10"; break;
case VK_F11 : S =
"VK_F11"; break;
case VK_F12 : S = "VK_F12"; break;
case VK_F13 : S = "VK_F13"; break;
case VK_F14 : S = "VK_F14"; break;
case VK_F15 : S = "VK_F15"; break;
case VK_F16 : S = "VK_F16"; break;
case VK_F17 : S = "VK_F17"; break;
case VK_F18 : S = "VK_F18"; break;
case VK_F19 : S = "VK_F19"; break;
case VK_F20 : S =
"VK_F20"; break;
case VK_F21 : S = "VK_F21"; break;
case VK_F22 : S = "VK_F22"; break;
case VK_F23 : S = "VK_F23"; break;
case VK_F24 : S = "VK_F24"; break;
case VK_NUMLOCK : S = "VK_NUMLOCK"; break;
case VK_SCROLL : S = "VK_SCROLL"; break;
default:
S = K;
}
return S;
}
</FONT></PRE>
<P>EVENTS2 shows how to extract the full content of a message sent to you by
BCB.
The main form for the program (shown in Figure 4.4) provides information on a wide
range of mouse and keyboard-generated events.<BR>
<BR>
<A NAME="Heading19"></A><A HREF="04ebu04.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/04/04ebu04.jpg">FIGURE 4.4.</A><FONT COLOR="#000077">
</FONT><I>The
EVENTS2 program tracks key Windows events as they occur.</I></P>
<P>To use the program, simply compile and run it. Click the mouse in random locations
and strike any of the keys on the keyboard. Just rattle away; you won't do any harm
unless you press
Ctrl+Alt+Del. Every time you move the mouse, click the mouse or
strike a key; the exact nature of the event that occurred is shown in the main form
of the program. For instance, if you move the mouse, its current location is shown
on the form. If you
press the F1 key while the Ctrl key is pressed, those keys' values
are displayed on the form.</P>
<P>If you don't have the <TT>MyMouseMove</TT> function defined, the <TT>FormMouseMove</TT>
event handler in the <TT>EVENTS2</TT> window tracks the
current location of the mouse
and the state of its buttons. It does this by responding to <TT>OnMouseMove</TT>
events:</P>
<PRE><FONT COLOR="#0066FF">void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X,
int Y)
{
LMouseMove->Caption = "X " + IntToStr(X) + " Y " +
IntToStr(Y) + " " + GetShift(Shift);
}
</FONT></PRE>
<P>The method for tracking the <TT>X</TT> and <TT>Y</TT> values is fairly intuitive.
<TT>X</TT> stands for the current column, and <TT>Y</TT> stands for the current row,
with columns and rows measured in pixels. Before these values can be shown to the
user, they need to be translated into strings by the <TT>IntToStr</TT> function.
Nothing could be simpler than the techniques used to record the current location
of the mouse.</P>
<P>The technique for recording the current shift state, however, is a bit more complex.
As you saw earlier, the elements of this set track all the
possible states of the
Shift, Alt, and Ctrl keys, as well as the mouse buttons.</P>
<P>The <TT>Set</TT> class makes it a simple matter to create a function that will
find all the currently selected elements of a variable of type
<TT>TShiftState</TT>:</P>
<PRE><FONT COLOR="#0066FF">AnsiString GetShift(TShiftState State)
{
int B = 0, i;
AnsiString S;
for (i = 0; i <= 7; i++)
{
if (State.Contains(i))
S = S + " " + ShiftArray[i];
}
return S;
}
</FONT></PRE>
<P>The preceding code takes advantage of the following constant array:</P>
<PRE><FONT COLOR="#0066FF">AnsiString ShiftArray[8] = {"ssShift", "ssAlt", "ssCtrl", "ssLeft",
"ssRight", "ssMiddle", "ssDouble", "ssUnknown"};
</FONT></PRE>
<P>More specifically, the code checks to see whether the first possible element of
the set is active, and if it is, <TT>"ssShift"</TT> is
added to the string
returned by the function. If the next element in the enumerated type underlying the
set is present, the string <TT>"ssAlt"</TT> is added to the string returned
by the function, and so on. As you move through the elements
in the underlying enumerated
type, you get a picture of the current state of the mouse and keyboard. For instance,
if the Shift and Ctrl keys are pressed, as well as the right mouse button, the string
returned by the function looks like this:</P>
<PRE><FONT COLOR="#0066FF">ssShift ssCtrl ssRight
</FONT></PRE>
<H3><A NAME="Heading20"></A><FONT COLOR="#000077">Trapping Virtual Keys</FONT></H3>
<P>When keys are pressed in a Windows program, two different messages can be sent
to your program. One
message is called <TT>WM_KEYDOWN</TT>, and it is sent whenever
any key on the keyboard is pressed. The second message is called <TT>WM_CHAR</TT>,
and it is sent when one of the alphanumeric keys is pressed. In other words, if you
press the A key, you
get both a <TT>WM</TT>_<TT>KEYDOW</TT> and a <TT>WM_CHAR</TT>
message. If you press the F1 key, only the <TT>WM_KEYDOWN</TT> message is sent.</P>
<P><TT>OnKeyPress</TT> event handlers correspond to <TT>WM_CHAR</TT> messages, and
<TT>OnKeyDown</TT>
events correspond to <TT>WM_KEYDOWN</TT> events. That's why <TT>OnKeyPress</TT>
handlers are passed a <TT>Key</TT> variable that is of type <TT>char</TT>, and <TT>OnKeyDown</TT>
handlers are passed a <TT>Key</TT> variable that is of type
<TT>WORD</TT>.</P>
<P>When you get a <TT>WM_KEYDOWN</TT> message, you need to have some way of translating
that message into a meaningful value. To help with this chore, Windows declares a
set of virtual key constants that all start with <TT>vk</TT>.
For example, if you
press the F1 key, the <TT>Key</TT> variable passed to an <TT>OnKeyDown</TT> event
is set to <TT>VK_F1</TT>, in which the letters <TT>vk</TT> stand for virtual key.
The virtual key codes are found in the <TT>WINDOWS</TT> unit and
also in the online
help under Virtual Key Codes.</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -