.h
#if !defined(AFX_KEYBOARD_H__8E1FF9C9_0EFD_4403_A860_8E62E6676A68__INCLUDED_)
#define AFX_KEYBOARD_H__8E1FF9C9_0EFD_4403_A860_8E62E6676A68__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Keyboard.h : header file
//
#include "Keyboard.h"
#include "AfxTempl.h"
/////////////////////////////////////////////////////////////////////////////
// CKeyboard dialog
struct KEYDEF
{
char cNormal;
char cShifted;
int cWidth;
};
class CKeyboard : public CDialog
{
// Construction
public:
CKeyboard(CWnd* pParent = NULL); // standard constructor
HWND m_hDlg;
int pKeyWidth;
int pKeyHeight;
CTypedPtrList<CPtrList, KEYDEF*> cKeys;
void AddKey(
char pNormal,
char pShifted,
int pWidth);
void CalcWidthHeight();
void DrawKey(CDC * dc, CRect & rc, KEYDEF * key, BOOL cHilight=FALSE);
void SendKey(KEYDEF * key);
void ReleaseFocus();
int DescribeKeyState();
void DrawKeyboard();
int cCurrentKeyState;
HWND gFocus;
BOOL ISShow;
POINT Point ;
CDC KEY_pDC;
HDC KEY_hdc;
HWND KEY_hwnd;
CString res_string;
CString img_string;
CString res_imgstring;
CRect keyRect;
BOOL MaybeMove;
CPoint OldPoint;
RECT allkey;
CRect MoveKey;
~CKeyboard();
// Dialog Data
//{{AFX_DATA(CKeyboard)
enum { IDD = IDD_ONSCREENKEYBOARD_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CKeyboard)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CKeyboard)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_KEYBOARD_H__8E1FF9C9_0EFD_4403_A860_8E62E6676A68__INCLUDED_)
.cpp
#include "stdafx.h"
#include "tsylq.h"
#include "Keyboard.h"
#include "Paper\Paper.h"
#include ".\common\Common.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define TIMER_ID 101
extern HWND hWndold;
extern CPaper* g_pPaper;
/////////////////////////////////////////////////////////////////////////////
// CKeyboard dialog
void CKeyboard::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CKeyboard)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CKeyboard, CDialog)
//{{AFX_MSG_MAP(CKeyboard)
ON_WM_PAINT()
ON_WM_LBUTTONDBLCLK()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_SIZE()
ON_WM_MOUSEWHEEL()
ON_WM_SHOWWINDOW()
ON_WM_TIMER()
ON_WM_SETCURSOR()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CKeyboard message handlers
#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
#define KEYBORADW 527
#define KEYBORADH 236
//////////////////////////////////////////////////////////////////////////////
BOOL CKeyboard::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
m_hDlg=GetSafeHwnd();
//control row
//KEY_hwnd = GetSafeHwnd();
pKeyWidth = 0;
pKeyHeight = 0;
ISShow = false;
MaybeMove = false;
KEY_hdc = ::GetDC(m_hDlg);
KEY_pDC.Attach(KEY_hdc);
SetWindowPos(NULL,g_pPaper->iWidth-KEYBORADW-8,g_pPaper->iHeigh-KEYBORADH-8, KEYBORADW+8, KEYBORADH+8,SWP_NOZORDER);
allkey.left = g_pPaper->iWidth-KEYBORADW-8;
allkey.top = g_pPaper->iHeigh-KEYBORADH-8;
allkey.right = KEYBORADW+8;
allkey.bottom = KEYBORADH+8;
//control row
//first row
AddKey(0x00,0x00,0); //signal row change
AddKey('~','`',35);
AddKey('1','!',36);
AddKey('2','@',36);
AddKey('3','#',36);
AddKey('4','$',36);
AddKey('5','%',36);
AddKey('6','^',36);
AddKey('7','&',36);
AddKey('8','*',36);
AddKey('9','(',36);
AddKey('0',')',36);
AddKey('-','_',36);
AddKey('=','+',36);
AddKey(0x00,BSPACE,56); //backspace
//second row
AddKey(0x00,0x00,1); //signal row change
AddKey(0x00,TAB,56); //tab
AddKey('q','Q',36);
AddKey('w','W',36);
AddKey('e','E',36);
AddKey('r','R',36);
AddKey('t','T',36);
AddKey('y','Y',36);
AddKey('u','U',36);
AddKey('i','I',36);
AddKey('o','O',36);
AddKey('p','P',36);
AddKey('[','{',36);
AddKey(']','}',36);
AddKey('\\','|',36);
//third row
AddKey(0x00,0x00,2); //signal row change
AddKey(0x00,CAPSLOCK,66); //caps lock
AddKey('a','A',36);
AddKey('s','S',36);
AddKey('d','D',36);
AddKey('f','F',36);
AddKey('g','G',36);
AddKey('h','H',36);
AddKey('j','J',36);
AddKey('k','K',36);
AddKey('l','L',36);
AddKey(';',':',36);
AddKey('\'','\"',36);
AddKey(0x00,ENTER,62); //enter
//fourth row
AddKey(0x00,0x00,3); //signal row change
AddKey(0x00,SHIFT,92); //shift
AddKey('z','Z',36);
AddKey('x','X',36);
AddKey('c','C',36);
AddKey('v','V',36);
AddKey('b','B',36);
AddKey('n','N',36);
AddKey('m','M',36);
AddKey(',','<',36);
AddKey('.','>',36);
AddKey('/','?',36);
AddKey(0x00,UP,72);
//fifth row
AddKey(0x00,0x00,4); //signal row change
AddKey(0x00,INS,63); //ctrl
AddKey(0x00,UP,17);
AddKey(0x00,DEL,63); //window
AddKey(' ',' ',275);
AddKey(0x00,UP,45);
AddKey(0x00,ESC,62);
CalcWidthHeight();
SetTimer(TIMER_ID,250,NULL);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CKeyboard::CalcWidthHeight()
{
KEYDEF * key;
POSITION pos = cKeys.GetHeadPosition();
long totalWidth = 0;
long longest = 0;
long rows = 0;
if((0 != pKeyWidth)&&(0 != pKeyHeight))
{
return;
}
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 CKeyboard::AddKey(
char pNormal,
char pShifted,
int pWidth)
{
KEYDEF * key = new KEYDEF;
key->cNormal = pNormal;
key->cShifted = pShifted;
key->cWidth = pWidth;
cKeys.AddTail(key);;
}
void CKeyboard::SendKey(KEYDEF * keydef)
{
if(keydef->cNormal == 0x00)
{
int vk;
BOOL uptoo = TRUE;
if(keydef->cShifted > 0x6F) //is a function key
{
vk = keydef->cShifted;
}
else
{
switch(keydef->cShifted)
{
case ESC:
//vk = VK_ESCAPE;
//break;
ISShow = false;
ShowWindow(SW_HIDE);
return;
case TAB: // 0x02
vk = VkKeyScan(0x09) & 0xFF;
break;
case CAPSLOCK: // 0x03
vk = VK_CAPITAL;
break;
case SHIFT: // 0x04
vk = VK_SHIFT;
if(GetKeyState(vk) & 0xF000) return;
uptoo = FALSE;
break;
case CTRL: // 0x05
vk = VK_CONTROL;
if(GetKeyState(vk) & 0xF000) return;
uptoo = FALSE;
break;
case BSPACE: // 0x06
vk = VK_BACK;
break;
case ENTER: // 0x07
vk = VkKeyScan(0x0D) & 0xFF;
break;
case ALT: // 0x08
vk = VK_MENU;
break;
case WINDOW: // 0x9
vk = VK_LWIN;
break;
case LEFT: // 0x0A
vk = VK_LEFT;
break;
case RIGHT: // 0x0B
vk = VK_RIGHT;
break;
case UP: // 0x0C
//vk = VK_UP;
//break;
return;
case DOWN: // 0x0D
vk = VK_DOWN;
break;
case PUP: //0x0F
vk = VK_PRIOR;
break;
case PDN: //0x10
vk = VK_NEXT;
break;
case HOME: //0x11
vk = VK_HOME;
break;
case END: //0x12
vk = VK_END;
break;
case INS: //0x13
vk = VK_INSERT;
break;
case DEL: //0x14
vk = VK_DELETE;
break;
case WWW:
KEYDEF key;
key.cNormal = key.cShifted = 'H';
SendKey(&key);
key.cNormal = key.cShifted = 'T';
SendKey(&key);
SendKey(&key);
key.cNormal = key.cShifted = 'P';
SendKey(&key);
key.cNormal = key.cShifted = ':';
SendKey(&key);
key.cNormal = key.cShifted = '/';
SendKey(&key);
SendKey(&key);
key.cNormal = key.cShifted = 'W';
SendKey(&key);
SendKey(&key);
SendKey(&key);
vk = VkKeyScan('.') & 0xFF;
break;
default:
ASSERT(FALSE);
break;
}
}
keybd_event(vk,0,0,0);
if(uptoo)
{
keybd_event(vk,0,KEYEVENTF_KEYUP,0);
}
}
else
{
char pChar = keydef->cNormal;
SHORT ks = VkKeyScan(pChar);
BYTE key = ks & 0xFF;
keybd_event(key,0,0,0);
keybd_event(key,0,KEYEVENTF_KEYUP,0);
//turn off the control and shift if they were down
unsigned char vk = VK_SHIFT;
if(GetKeyState(vk) & 0xF000)
{
keybd_event(vk,0,KEYEVENTF_KEYUP,0);
}
vk = VK_CONTROL;
if(GetKeyState(vk) & 0xF000) //allow toggle
{
keybd_event(vk,0,KEYEVENTF_KEYUP,0);
}
}
}
void CKeyboard::DrawKeyboard()
{
res_imgstring.LoadString(IDS_keypic);
img_string = g_pPaper->strMainPath+res_imgstring;
SetRect(keyRect,0,0,KEYBORADW,KEYBORADH);
SetRect(MoveKey,450,142,523,187);
CCommon::DrawJPG(&KEY_pDC,this->keyRect,img_string);
MoveWindow(allkey.left,allkey.top, allkey.right, allkey.bottom ,1);
}
int CKeyboard::DescribeKeyState()
{
int state = 0;
short ks;
ks = GetKeyState(VK_CAPITAL);
if(ks & 0x000F) state += 0x01;
ks = GetKeyState(VK_SHIFT);
if(ks & 0xF000) state += 0x02;
ks = GetKeyState(VK_CONTROL);
if(ks & 0xF000) state += 0x04;
return state;
}
void CKeyboard::OnPaint()
{
// CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CDialog::OnPaint() for painting messages
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
}
else
{
CDialog::OnPaint();
DrawKeyboard();
}
}
void CKeyboard::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
OnLButtonDown(nFlags, point);
//CDialog::OnLButtonDblClk(nFlags, point);
}
void CKeyboard::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(MaybeMove)
MaybeMove=false;
point.x = (point.x - allkey.left);
point.y = (point.y - allkey.top);
OldPoint = point;
MaybeMove = true;
//CDialog::OnLButtonDown(nFlags, point);
}
void CKeyboard::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(MaybeMove)
MaybeMove = false;
point.x = (point.x - allkey.left);
point.y = (point.y - allkey.top);
if((point.x!=OldPoint.x)&&(point.y!=OldPoint.y))
{//移动
int offset_x = point.x -OldPoint.x;
int offset_y = point.y -OldPoint.y;
MoveWindow(allkey.left+offset_x,allkey.top+offset_y, allkey.right, allkey.bottom,1);
allkey.left = allkey.left+offset_x;
allkey.top = allkey.top+offset_y;
}else
{
//CRect client;
//GetClientRect(client);
int x = 0;
int y = -pKeyHeight;
KEYDEF * key;
POSITION pos = cKeys.GetHeadPosition();
while(pos)
{
key = cKeys.GetNext(pos);
if((key->cNormal == 0x00) && (key->cShifted == 0x00))
{
x = 5;
y += pKeyHeight;
}
else
{
//int width = ((abs(key->cWidth) * pKeyWidth) / 10);
int width = abs(key->cWidth);
CRect rc(x,y,x + width, y + pKeyHeight);
if(key->cWidth < 0)
{
rc.right = allkey.left;
}
x += width;
if(rc.PtInRect(point))
{
SendKey(key);
}
}
}
}
//CDialog::OnLButtonUp(nFlags, point);
}
void CKeyboard::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if(IsWindow(m_hWnd))
{
if(cKeys.GetCount())
{
CalcWidthHeight();
Invalidate();
}
}
}
BOOL CKeyboard::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
// TODO: Add your message handler code here and/or call default
return TRUE;
// return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}
void CKeyboard::OnShowWindow(BOOL bShow, UINT nStatus)
{
CDialog::OnShowWindow(bShow, nStatus);
// TODO: Add your message handler code here
}
void CKeyboard::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if(nIDEvent == TIMER_ID)
{
int state = DescribeKeyState();
if(state != cCurrentKeyState)
{
DrawKeyboard();
}
}
//CDialog::OnTimer(nIDEvent);
}
BOOL CKeyboard::OnCommand(WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
return CDialog::OnCommand(wParam, lParam);
}
BOOL CKeyboard::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
LRESULT CKeyboard::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
switch(message)
{
case WM_SETCURSOR:
if(HIWORD(lParam) == WM_LBUTTONDOWN)
{
GetCursorPos( &Point);
this->OnLButtonDown(0, Point);
return true;
}
if(HIWORD(lParam) == WM_LBUTTONUP)
{
GetCursorPos( &Point);
this->OnLButtonUp(0, Point);
return true;
}
if(HIWORD(lParam) == WM_MOUSEMOVE)
{
GetCursorPos( &Point);
this->OnMouseMove(0, Point);
return true;
}
case WM_DESTROY:
cKeys.RemoveAll();
break;
default :
break;
}
return CDialog::DefWindowProc(message, wParam, lParam);
}
void CKeyboard::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(MaybeMove)
{
if((point.x > (allkey.left+allkey.right-10)) || (point.y > (allkey.top+allkey.bottom-10)))
{
this->OnLButtonUp(nFlags, point);
}else
{
if((point.x < (allkey.left+10)) || (point.y < (allkey.top+10)))
{
this->OnLButtonUp(nFlags, point);
}
}
}
//CDialog::OnMouseMove(nFlags, point);
}