📄 onscreenkeyboarddlg.cpp
字号:
// COnscreenKeyboardDlg.cpp : implementation file
//
#include "stdafx.h"
#include "OnscreenKeyboard.h"
#include "OnscreenKeyboardDlg.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define TIMER_ID 101 //定时器ID
//定义特殊系统键的键值
#define TAB 0x02
#define CAPSLOCK 0x03
#define SHIFT 0x04
#define CTRL 0x05
#define BSPACE 0x06
#define ENTER 0x07
#define ALT 0x08
#define WINDOW 0x9
#define LEFT 0x0A
#define RIGHT 0x0B
#define UP 0x0C
#define DOWN 0x0D
#define ESC 0x0E
#define PUP 0x0F
#define PDN 0x10
#define HOME 0x11
#define END 0x12
#define INS 0x13
#define DEL 0x14
#define WWW 0x15
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COnscreenKeyboardDlg dialog
COnscreenKeyboardDlg::COnscreenKeyboardDlg(CWnd* pParent /*=NULL*/)
: CDialog(COnscreenKeyboardDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(COnscreenKeyboardDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void COnscreenKeyboardDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(COnscreenKeyboardDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(COnscreenKeyboardDlg, CDialog)
//{{AFX_MSG_MAP(COnscreenKeyboardDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONDBLCLK()
ON_WM_RBUTTONDBLCLK()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_WM_MOUSEWHEEL()
ON_WM_LBUTTONUP()
ON_WM_SIZE()
ON_WM_SHOWWINDOW()
ON_WM_TIMER()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COnscreenKeyboardDlg message handlers
BOOL COnscreenKeyboardDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
//将所有键加到链表中保存起来
AddKey(0x00,0x00,0); //signal row change
AddKey(0x00,ESC,10);
for(int fnkey = 0x70; fnkey < 0x7C; fnkey++)
{
AddKey(0x00,fnkey & 0xFF,10);
}
AddKey(0x00,INS,14);
AddKey(0x00,DEL,-10);
//第一行的键
//改变键盘行的标志
AddKey(0x00,0x00,1); //signal row change
AddKey('`','~',10);
AddKey('1','!',10);
AddKey('2','@',10);
AddKey('3','#',10);
AddKey('4','$',10);
AddKey('5','%',10);
AddKey('6','^',10);
AddKey('7','&',10);
AddKey('8','*',10);
AddKey('9','(',10);
AddKey('0',')',10);
AddKey('-','_',10);
AddKey('=','+',10);
AddKey(0x00,BSPACE,14); //backspace
AddKey(0x00,PUP,-12);
//第二行的键
//改变键盘行的标志
AddKey(0x00,0x00,2); //signal row change
AddKey(0x00,TAB,14); //tab
AddKey('q','Q',10);
AddKey('w','W',10);
AddKey('e','E',10);
AddKey('r','R',10);
AddKey('t','T',10);
AddKey('y','Y',10);
AddKey('u','U',10);
AddKey('i','I',10);
AddKey('o','O',10);
AddKey('p','P',10);
AddKey('[','{',10);
AddKey(']','}',10);
AddKey('\\','|',10);
AddKey(0x00,PDN,-12);
//第三行的键
//改变键盘行的标志
AddKey(0x00,0x00,3); //signal row change
AddKey(0x00,CAPSLOCK,18); //caps lock
AddKey('a','A',10);
AddKey('s','S',10);
AddKey('d','D',10);
AddKey('f','F',10);
AddKey('g','G',10);
AddKey('h','H',10);
AddKey('j','J',10);
AddKey('k','K',10);
AddKey('l','L',10);
AddKey(';',':',10);
AddKey('\'','\"',10);
AddKey(0x00,ENTER,16); //enter
AddKey(0x00,HOME,-10);
//第四行的键
//改变键盘行的标志
AddKey(0x00,0x00,4); //signal row change
AddKey(0x00,SHIFT,22); //shift
AddKey('z','Z',10);
AddKey('x','X',10);
AddKey('c','C',10);
AddKey('v','V',10);
AddKey('b','B',10);
AddKey('n','N',10);
AddKey('m','M',10);
AddKey(',','<',10);
AddKey('.','>',10);
AddKey('/','?',10);
AddKey(0x00,SHIFT,22); //shift
AddKey(0x00,END,-10);
//第五行的键
//改变键盘行的标志
AddKey(0x00,0x00,5);
AddKey(0x00,CTRL,12); //ctrl
AddKey(0x00,WINDOW,12); //window
AddKey(0x00,ALT,12); //alt
AddKey(' ',' ',60);
AddKey(0x00,LEFT,12); //left
AddKey(0x00,UP,12); //up
AddKey(0x00,DOWN,12); //down
AddKey(0x00,RIGHT,12); //right
AddKey(0x00,WWW,-10); //http://WWW
//获得键宽和键高
CalcWidthHeight();
//打开定时器
SetTimer(TIMER_ID,250,NULL);
return TRUE; // return TRUE unless you set the focus to a control
}
//计算键的宽度和高度
void COnscreenKeyboardDlg::CalcWidthHeight()
{
pKeyWidth = 0;
pKeyHeight = 0;
KEYDEF * key;
POSITION pos = cKeys.GetHeadPosition();
long totalWidth = 0;
long longest = 0;
long rows = 0;
while(pos)
{
key = cKeys.GetNext(pos);
//是换行的标志键
if((key->cNormal == 0x00) && (key->cShifted == 0x00))
{
//增加行数
rows++;
if(totalWidth > longest)
{
//获得总长最长的行
longest = totalWidth;
}
totalWidth = 0;
}
//正确的键
else
{
//计算每行键的总长度
totalWidth += abs(key->cWidth);
}
}
CRect rect;
GetClientRect(rect);
pKeyHeight = rect.Height() / rows;
pKeyWidth = (int)(((double)rect.Width()) / ((((double)(longest)) / 10)));
}
//增加一个键,保存起来
void COnscreenKeyboardDlg::AddKey(
char pNormal,
char pShifted,
int pWidth)
{
KEYDEF * key = new KEYDEF;
key->cNormal = pNormal;
key->cShifted = pShifted;
key->cWidth = pWidth;
cKeys.AddTail(key);
}
void COnscreenKeyboardDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
//画一个键
void COnscreenKeyboardDlg::DrawKey(CDC * dc, CRect & rc, KEYDEF * key, BOOL cHilight)
{
//不是高亮度显示,设置颜色
if(!cHilight)
{
rc.DeflateRect(1,1);
dc->FillSolidRect(rc,GetSysColor(COLOR_3DFACE));
dc->Draw3dRect(rc,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DDKSHADOW));
rc.DeflateRect(1,1);
dc->Draw3dRect(rc,GetSysColor(COLOR_3DLIGHT),GetSysColor(COLOR_3DSHADOW));
}
//是高亮度显示,设置不同的颜色
else
{
rc.DeflateRect(1,1);
dc->FillSolidRect(rc,GetSysColor(COLOR_3DLIGHT));
dc->Draw3dRect(rc,GetSysColor(COLOR_3DLIGHT),GetSysColor(COLOR_3DSHADOW));
rc.DeflateRect(1,1);
dc->Draw3dRect(rc,GetSysColor(COLOR_3DSHADOW),GetSysColor(COLOR_3DDKSHADOW));
}
rc.DeflateRect(3,1);
//不是普通键
if(key->cNormal == 0x00)
{
//获得键名字符串
CString label = " ";
BOOL special = FALSE;
if(key->cShifted > 0x6F) //is a function
{
int fkeynum = key->cShifted - 0x6F;
label.Format("F%d",fkeynum);
}
else
{
switch(key->cShifted)
{
case TAB: // 0x02
label = "Tab->";
break;
case CAPSLOCK: // 0x03
label = "Caps";
break;
case SHIFT: // 0x04
label = "Shift";
break;
case CTRL: // 0x05
label = "Ctrl";
break;
case BSPACE: // 0x06
label = "<-Bspc";
break;
case ENTER: // 0x07
label = "Enter";
break;
case ALT: // 0x08
label = "Alt";
break;
case WINDOW: // 0x9
label = "Wnd";
break;
case ESC:
label = "Esc";
break;
case LEFT: // 0x0A
special = TRUE;
{
int cx = (rc.left + rc.right)/2;
int cy = (rc.top + rc.bottom)/2;
int siz = rc.Width()/3;
dc->MoveTo(cx+siz, cy);
dc->LineTo(cx-siz, cy);
dc->LineTo(cx-siz + (siz*4)/5, cy - siz/2);
dc->MoveTo(cx-siz, cy);
dc->LineTo(cx-siz + (siz*4)/5, cy + siz/2);
}
break;
case RIGHT: // 0x0B
special = TRUE;
{
int cx = (rc.left + rc.right)/2;
int cy = (rc.top + rc.bottom)/2;
int siz = rc.Width()/3;
dc->MoveTo(cx-siz, cy);
dc->LineTo(cx+siz, cy);
dc->LineTo(cx+siz - (siz*4)/5, cy - siz/2);
dc->MoveTo(cx+siz, cy);
dc->LineTo(cx+siz - (siz*4)/5, cy + siz/2);
}
break;
case UP: // 0x0C
special = TRUE;
{
int cx = (rc.left + rc.right)/2;
int cy = (rc.top + rc.bottom)/2;
int siz = rc.Width()/3;
dc->MoveTo(cx, cy+siz);
dc->LineTo(cx, cy-siz);
dc->LineTo(cx - siz/2, cy-siz + (siz*4)/5);
dc->LineTo(cx, cy-siz);
dc->LineTo(cx + siz/2, cy-siz + (siz*4)/5);
}
break;
case DOWN: // 0x0D
special = TRUE;
{
int cx = (rc.left + rc.right)/2;
int cy = (rc.top + rc.bottom)/2;
int siz = rc.Width()/3;
dc->MoveTo(cx, cy-siz);
dc->LineTo(cx, cy+siz);
dc->LineTo(cx - siz/2, cy+siz - (siz*4)/5);
dc->LineTo(cx, cy+siz);
dc->LineTo(cx + siz/2, cy+siz - (siz*4)/5);
}
break;
case PUP: //0x0F
label = "PgUp";
break;
case PDN: //0x10
label = "PgDn";
break;
case HOME: //0x11
label = "Home";
break;
case END: //0x12
label = "End";
break;
case INS: //0x13
label = "Ins";
break;
case DEL: //0x14
label = "Del";
break;
case WWW:
label = "WWW";
break;
default:
ASSERT(FALSE);
label = "#ERR#";
break;
}
}
//不是特殊键
if(!special)
{
CSize tsize;
tsize = dc->GetTextExtent(label);
dc->TextOut(
((rc.left + rc.right)/2) - (tsize.cx/2),
((rc.top + rc.bottom)/2) - (tsize.cy/2),
label);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -