softkeyboard.cpp
来自「自己用Markov模型做的一个整句物笔输入法的原型」· C++ 代码 · 共 597 行
CPP
597 行
// softkeyboard.cpp : implementation file
//
#include "stdafx.h"
#include "resource.h"
#include "Afxtempl.h"
#include "HikerWBFunc.h"
#include "softkeyboard.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define BACKSPACE 8
#define TAB 9
#define CAPS 20
#define ENTER 13
#define SHIFT 16
#define ESC 27
#define SPACE 32
#define INS 45
#define DEL 46
#define BUTTONSIZE 29
#define KEYNAMECOLOR 0x00AF0000
#define KEYTEXTCOLOR 0x000000AF
static unsigned char gSpcKeyArr[9] = {BACKSPACE, TAB, CAPS, ENTER, SHIFT, ESC, SPACE, INS, DEL};
static unsigned char gVKArr[47] = {192, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 189, 187, 81, 87, 69, 82, 84, 89, 85, 73, 79, 80, 219, 221, 220, 65, 83, 68, 70, 71, 72, 74, 75, 76, 186, 222, 90, 88, 67, 86, 66, 78, 77, 188, 190, 191};
static unsigned char gKeyArr[SOFTKEYBOARD_NUM*2][SOFTKEYBOARD_LEN] = {
/*PC keyboard*/
{
SOFTKEY_PCC
},
{
SOFTKEY_PCL
},
/*Greece letter*/
{
SOFTKEY_GLC
},
{
SOFTKEY_GLL
},
/*Russia letter*/
{
SOFTKEY_RLC
},
{
SOFTKEY_RLL
},
/*chinese spell letter*/
{
SOFTKEY_NON
},
{
SOFTKEY_CSL
},
/*phonetic notation*/
{
SOFTKEY_NON
},
{
SOFTKEY_CPN
},
/*Japanese hiragana */
{
SOFTKEY_JHC
},
{
SOFTKEY_JHL
},
/*Japanese katakana*/
{
SOFTKEY_JKC
},
{
SOFTKEY_JKL
},
/*punctuation*/
{
SOFTKEY_NON
},
{
SOFTKEY_PCT
},
/*serial number*/
{
SOFTKEY_SNC
},
{
SOFTKEY_SNL
},
/*mathematics notation*/
{
SOFTKEY_NON
},
{
SOFTKEY_MAT
},
/*special notation*/
{
SOFTKEY_NON
},
{
SOFTKEY_SPC
},
/*全角字符*/
{
SOFTKEY_SBC
},
{
SOFTKEY_SBL
},
};
/////////////////////////////////////////////////////////////////////////////
// CSoftKeyboard dialog
CSoftKeyboard::CSoftKeyboard(CWnd* pParent /*=NULL*/)
{
//{{AFX_DATA_INIT(CSoftKeyboard)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
BEGIN_MESSAGE_MAP(CSoftKeyboard, CWnd)
//{{AFX_MSG_MAP(CSoftKeyboard)
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_PAINT()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDOWN()
//}}AFX_MSG_MAP
ON_COMMAND_RANGE(ID_MENU_SKB_CLOSE, ID_MENU_SKB_CLOSE, OnMenuSkb)
ON_COMMAND_RANGE(ID_MENU_SKB_CSL,ID_MENU_SKB_CSL, OnMenuSkb)
ON_COMMAND_RANGE(ID_MENU_SKB_GL, ID_MENU_SKB_GL, OnMenuSkb)
ON_COMMAND_RANGE(ID_MENU_SKB_JH, ID_MENU_SKB_JH, OnMenuSkb)
ON_COMMAND_RANGE(ID_MENU_SKB_JK, ID_MENU_SKB_JK, OnMenuSkb)
ON_COMMAND_RANGE(ID_MENU_SKB_MN, ID_MENU_SKB_MN, OnMenuSkb)
ON_COMMAND_RANGE(ID_MENU_SKB_PC, ID_MENU_SKB_PC, OnMenuSkb)
ON_COMMAND_RANGE(ID_MENU_SKB_PN, ID_MENU_SKB_PN, OnMenuSkb)
ON_COMMAND_RANGE(ID_MENU_SKB_PT, ID_MENU_SKB_PT, OnMenuSkb)
ON_COMMAND_RANGE(ID_MENU_SKB_RL, ID_MENU_SKB_RL, OnMenuSkb)
ON_COMMAND_RANGE(ID_MENU_SKB_SN, ID_MENU_SKB_SN, OnMenuSkb)
ON_COMMAND_RANGE(ID_MENU_SKB_SP, ID_MENU_SKB_SP, OnMenuSkb)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSoftKeyboard message handlers
int CSoftKeyboard::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
//ordinary key (0 ~ 46)
CRect rt;
int i;
rt.SetRect(0, 0, BUTTONSIZE, BUTTONSIZE); //backquote key
m_cRectList.AddTail(rt);
for (i = 0; i < 12; i++)
{
rt.OffsetRect(BUTTONSIZE, 0);
m_cRectList.AddTail(rt); //1 key
}
rt.SetRect(BUTTONSIZE+10, BUTTONSIZE, BUTTONSIZE*2+10, BUTTONSIZE*2); //q key
m_cRectList.AddTail(rt);
for (i = 0; i < 12; i++)
{
rt.OffsetRect(BUTTONSIZE, 0);
m_cRectList.AddTail(rt); //1 key
}
rt.SetRect(BUTTONSIZE+20, BUTTONSIZE*2, BUTTONSIZE*2+20, BUTTONSIZE*3); //q key
m_cRectList.AddTail(rt);
for (i = 0; i < 10; i++)
{
rt.OffsetRect(BUTTONSIZE, 0);
m_cRectList.AddTail(rt); //1 key
}
rt.SetRect(BUTTONSIZE+30, BUTTONSIZE*3, BUTTONSIZE*2+30, BUTTONSIZE*4); //q key
m_cRectList.AddTail(rt);
for (i = 0; i < 9; i++)
{
rt.OffsetRect(BUTTONSIZE, 0);
m_cRectList.AddTail(rt); //1 key
}
//special key (47~55)
rt.SetRect(13*BUTTONSIZE, 0, 14*BUTTONSIZE+10, BUTTONSIZE); //backspace key
m_cRectList.AddTail(rt);
rt.SetRect(0, BUTTONSIZE, BUTTONSIZE+10, BUTTONSIZE*2); //tab key
m_cRectList.AddTail(rt);
rt.SetRect(0, BUTTONSIZE*2, BUTTONSIZE+20, BUTTONSIZE*3); //caps lock key
m_cRectList.AddTail(rt);
rt.SetRect(BUTTONSIZE+20+11*BUTTONSIZE, BUTTONSIZE*2, 14*BUTTONSIZE+10, BUTTONSIZE*3); //enter key
m_cRectList.AddTail(rt);
rt.SetRect(0, BUTTONSIZE*3, BUTTONSIZE+30, BUTTONSIZE*4); //shift key
m_cRectList.AddTail(rt);
rt.SetRect(0, BUTTONSIZE*4, BUTTONSIZE, BUTTONSIZE*5); //Esc key
m_cRectList.AddTail(rt);
rt.SetRect(BUTTONSIZE, BUTTONSIZE*4, BUTTONSIZE*12+10, BUTTONSIZE*5); //space key
m_cRectList.AddTail(rt);
rt.SetRect(BUTTONSIZE*12+10, BUTTONSIZE*4, BUTTONSIZE*13+10, BUTTONSIZE*5); //Ins key
m_cRectList.AddTail(rt);
rt.SetRect(BUTTONSIZE*13+10, BUTTONSIZE*4, BUTTONSIZE*14+10, BUTTONSIZE*5); //Del key
m_cRectList.AddTail(rt);
LOGPEN lpen;
lpen.lopnWidth = CPoint(1,1);
lpen.lopnColor = KEYNAMECOLOR;
lpen.lopnStyle = PS_SOLID;
m_pen1.CreatePenIndirect(&lpen);
lpen.lopnWidth = CPoint(2,2);
m_pen2.CreatePenIndirect(&lpen);
m_bShiftDown = FALSE;
m_iDonwKey = -1;
return 0;
}
void CSoftKeyboard::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
int iKey = HitTest(point);
if (-1 == iKey)
return;
m_iDonwKey = iKey;
POSITION pos = m_cRectList.FindIndex(iKey);
CRect rt = m_cRectList.GetAt(pos);
InvalidateRect(rt);
if (20 == iKey)
return; //if capslock key down, don't post message
if (51 == iKey)
{
m_bShiftDown = !m_bShiftDown;
return; //if shift key down, don't post the key-down message immediately
}
HANDLE hFile = OpenFileMapping(FILE_MAP_READ, FALSE, "Hook");
if (hFile)
{
HWND *pHWnd = (HWND*)MapViewOfFile(hFile, FILE_MAP_READ, 0, 0, 0);
if (iKey < 47) //alphabetic or number key
{
// if (m_bShiftDown)
// {
// ::PostMessage(*pHWnd, WM_HOOKKEY, gKeyArr[m_iKeyboardId*2][iKey*2], -1);
// if (m_iKeyboardId > 0) //double bytes keyboard
// ::PostMessage(*pHWnd, WM_HOOKKEY, gKeyArr[m_iKeyboardId*2][iKey*2+1], -1);
// }
// else
// {
// ::PostMessage(*pHWnd, WM_HOOKKEY, gKeyArr[m_iKeyboardId*2+1][iKey*2], -1);
// if (m_iKeyboardId > 0) //double bytes keyborad
// ::PostMessage(*pHWnd, WM_HOOKKEY, gKeyArr[m_iKeyboardId*2+1][iKey*2+1], -1);
// }
::PostMessage(*pHWnd, WM_HOOKKEY, gVKArr[iKey], ((m_bShiftDown)?-100:0)-m_iKeyboardId);
}
else
{
::PostMessage(*pHWnd, WM_HOOKKEY, gSpcKeyArr[iKey-47], ((m_bShiftDown)?-100:0)-m_iKeyboardId);
}
UnmapViewOfFile(pHWnd); //取消映射
CloseHandle(hFile); //关闭内存映射文件
}
if (m_bShiftDown)
m_bShiftDown = FALSE;
CWnd::OnLButtonDown(nFlags, point);
}
void CSoftKeyboard::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect rt;
GetClientRect(&rt);
dc.FillSolidRect(rt, GetSysColor(COLOR_BTNFACE));
CFont* font = dc.GetCurrentFont();
LOGFONT lfont;
font->GetLogFont(&lfont);
lfont.lfWeight = FW_NORMAL;
lfont.lfHeight = -14;
lstrcpy(lfont.lfFaceName, "Times New Roman");
CFont ftnew;
ftnew.CreateFontIndirect(&lfont);
dc.SelectObject(&ftnew);
DrawKeys(&dc);
// Do not call CWnd::OnPaint() for painting messages
}
void CSoftKeyboard::DrawKeys(CDC *pdc)
{
CRect rt;
POSITION pos = m_cRectList.GetHeadPosition();
for(int i = 0; pos != 0; i++)
{
rt = m_cRectList.GetNext(pos);
DrawButton(pdc, &rt, i);
}
}
void CSoftKeyboard::DrawButton(CDC *pdc, CRect *rt, int id)
{
char c, c1, c2;
POINT pt;
int i;
if (id != m_iDonwKey)
pdc->Draw3dRect(rt, GetSysColor(COLOR_BTNHIGHLIGHT), GetSysColor(COLOR_3DSHADOW));
else
pdc->Draw3dRect(rt, GetSysColor(COLOR_3DSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT));
pdc->SetBkColor(GetSysColor(COLOR_BTNFACE));
if (id < 47)
{
//display key name
pdc->SetTextColor(KEYNAMECOLOR);
rt->DeflateRect(1, 1, 8, 8);
if (id >= 13)
c = gKeyArr[0][id*2];
else
c = gKeyArr[1][id*2];
pdc->DrawText(CString(c), rt, DT_LEFT|DT_TOP);
pdc->SetTextColor(KEYTEXTCOLOR);
rt->OffsetRect(11, 0);
c1 = gKeyArr[m_iKeyboardId*2][id*2];
c2 = gKeyArr[m_iKeyboardId*2][id*2+1];
if (0 != c1)
pdc->DrawText(CString(c1)+CString(c2), rt, DT_LEFT|DT_TOP);
rt->OffsetRect(-6, 12);
c1 = gKeyArr[m_iKeyboardId*2+1][id*2];
c2 = gKeyArr[m_iKeyboardId*2+1][id*2+1];
if (0 != c1)
pdc->DrawText(CString(c1)+CString(c2), rt, DT_LEFT|DT_TOP);
}
else
{
pdc->SetTextColor(KEYNAMECOLOR);
rt->DeflateRect(2, 1, 1, 1);
switch(id) {
case 47: //BACKSPACE key
//pdc->DrawText(CString("Backspace"), rt, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
pdc->SelectObject(&m_pen2);
pdc->MoveTo(rt->left+17, rt->CenterPoint().y);
pdc->LineTo(rt->right-9,rt->CenterPoint().y);
pdc->SelectObject(&m_pen1);
pt = CPoint(rt->left+9, rt->CenterPoint().y-1);
for (i = 0; i < 4; i++)
{
pdc->MoveTo(pt);
pdc->LineTo(pt.x + 8 - 2*i, pt.y);
pt.x += 2;
pt.y --;
}
pt = CPoint(rt->left+9, rt->CenterPoint().y);
for (i = 0; i < 4; i++)
{
pdc->MoveTo(pt);
pdc->LineTo(pt.x + 8 - 2*i, pt.y);
pt.x +=2;
pt.y ++;
}
break;
case 48:
pdc->DrawText(CString("Tab"), rt, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
break;
case 49:
pdc->DrawText(CString("Caps"), rt, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
break;
case 50:
pdc->DrawText(CString("Enter"), rt, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
break;
case 51:
pdc->DrawText(CString("Shift"), rt, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
break;
case 52:
pdc->DrawText(CString("Esc"), rt, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
break;
case 54:
pdc->DrawText(CString("Ins"), rt, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
break;
case 55:
pdc->DrawText(CString("Del"), rt, DT_LEFT|DT_VCENTER|DT_SINGLELINE);
break;
default:
break;
}
}
}
int CSoftKeyboard::HitTest(POINT pt)
{
CRect rt;
POSITION pos = m_cRectList.GetHeadPosition();
for (int i = 0; pos != 0; i++)
{
rt = m_cRectList.GetNext(pos);
if (rt.PtInRect(pt))
return i;
}
return -1;
}
//05.11.10
void CSoftKeyboard::LockInputWnd()
{
HWND wnd = ::GetForegroundWindow();
if(IsWindow(wnd))
{
if(wnd != this->m_hWnd)
{
if(m_hInputWnd != wnd)
{
if(IsWindow(m_hInputWnd))
{
AttachThreadInput(
GetWindowThreadProcessId(m_hWnd,NULL),
GetWindowThreadProcessId(m_hInputWnd, NULL),
FALSE);
}
m_hInputWnd = wnd;
AttachThreadInput(
GetWindowThreadProcessId(m_hWnd,NULL),
GetWindowThreadProcessId(m_hInputWnd,NULL),
TRUE);
}
}
}
}
void CSoftKeyboard::ReleaseFocus()
{
if(IsWindow(m_hInputWnd))
{
HWND wnd = ::GetForegroundWindow();
if(IsWindow(wnd))
{
if(wnd == m_hInputWnd)
{
return;
}
}
::SetForegroundWindow(m_hInputWnd);
::SetFocus(m_hInputWnd);
}
}
BOOL CSoftKeyboard::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
HCURSOR hcur = LoadCursor(NULL, IDC_ARROW);
SetCursor(hcur);
LockInputWnd();
ReleaseFocus();
return CWnd::PreTranslateMessage(pMsg);
}
void CSoftKeyboard::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (m_iDonwKey < 0)
return;
POSITION pos = m_cRectList.FindIndex(m_iDonwKey);
CRect rt = m_cRectList.GetAt(pos);
m_iDonwKey = -1;
InvalidateRect(rt);
CWnd::OnLButtonUp(nFlags, point);
}
void CSoftKeyboard::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CMenu menuskb;
CPoint pt = point;
ClientToScreen(&pt);
menuskb.CreatePopupMenu();
menuskb.AppendMenu(MF_STRING, ID_MENU_SKB_PC, "PC 键盘");
menuskb.AppendMenu(MF_SEPARATOR);
menuskb.AppendMenu(MF_STRING, ID_MENU_SKB_GL, "希腊字母");
menuskb.AppendMenu(MF_SEPARATOR);
menuskb.AppendMenu(MF_STRING, ID_MENU_SKB_RL, "俄文字母");
menuskb.AppendMenu(MF_SEPARATOR);
menuskb.AppendMenu(MF_STRING, ID_MENU_SKB_CSL, "拼 音");
menuskb.AppendMenu(MF_SEPARATOR);
menuskb.AppendMenu(MF_STRING, ID_MENU_SKB_PN, "注 音");
menuskb.AppendMenu(MF_SEPARATOR);
menuskb.AppendMenu(MF_STRING, ID_MENU_SKB_JH, "日文平假名");
menuskb.AppendMenu(MF_SEPARATOR);
menuskb.AppendMenu(MF_STRING, ID_MENU_SKB_JK, "日文片假名");
menuskb.AppendMenu(MF_SEPARATOR);
menuskb.AppendMenu(MF_STRING, ID_MENU_SKB_PT, "标点符号");
menuskb.AppendMenu(MF_SEPARATOR);
menuskb.AppendMenu(MF_STRING, ID_MENU_SKB_SN, "数字序号");
menuskb.AppendMenu(MF_SEPARATOR);
menuskb.AppendMenu(MF_STRING, ID_MENU_SKB_MN, "数学符号");
menuskb.AppendMenu(MF_SEPARATOR);
menuskb.AppendMenu(MF_STRING, ID_MENU_SKB_SP, "特殊符号");
menuskb.AppendMenu(MF_SEPARATOR);
menuskb.AppendMenu(MF_STRING, ID_MENU_SKB_CLOSE, "关闭软键盘");
menuskb.TrackPopupMenu(TPM_RIGHTALIGN, pt.x, pt.y, this);
CWnd::OnRButtonDown(nFlags, point);
}
void CSoftKeyboard::OnMenuSkb(int nID)
{
// TODO: Add your command handler code here
//LockInputWnd();
switch(nID) {
case ID_MENU_SKB_PC:
ShowSoftKeyboard(TRUE, 0);
break;
case ID_MENU_SKB_GL:
ShowSoftKeyboard(TRUE, 1);
break;
case ID_MENU_SKB_RL:
ShowSoftKeyboard(TRUE, 2);
break;
case ID_MENU_SKB_CSL:
ShowSoftKeyboard(TRUE, 3);
break;
case ID_MENU_SKB_PN:
ShowSoftKeyboard(TRUE, 4);
break;
case ID_MENU_SKB_JH:
ShowSoftKeyboard(TRUE, 5);
break;
case ID_MENU_SKB_JK:
ShowSoftKeyboard(TRUE, 6);
break;
case ID_MENU_SKB_PT:
ShowSoftKeyboard(TRUE, 7);
break;
case ID_MENU_SKB_SN:
ShowSoftKeyboard(TRUE, 8);
break;
case ID_MENU_SKB_MN:
ShowSoftKeyboard(TRUE, 9);
break;
case ID_MENU_SKB_SP:
ShowSoftKeyboard(TRUE, 10);
break;
case ID_MENU_SKB_CLOSE:
ShowSoftKeyboard(FALSE);
break;
default:
break;
}
//ReleaseFocus();
return;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?