📄 onscreenkeyboarddlg.cpp
字号:
}
}
//是普通键
else
{
//画键
if((key->cShifted >= 'A') && (key->cShifted <= 'Z'))
{
CSize tsize;
tsize = dc->GetTextExtent(key->cShifted);
dc->TextOut(
((rc.left + rc.right)/2) - (tsize.cx/2),
((rc.top + rc.bottom)/2) - (tsize.cy/2),
key->cShifted);
}
else
{
CSize tsize;
tsize = dc->GetTextExtent('M');
dc->TextOut(rc.left, rc.top, key->cShifted);
dc->TextOut(
rc.right - tsize.cx,
rc.bottom - tsize.cy,
key->cNormal);
}
}
}
void COnscreenKeyboardDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
//画键盘
DrawKeyboard();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR COnscreenKeyboardDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//处理一个按键消息
void COnscreenKeyboardDlg::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 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;
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
//如果"control"和"shift"键是被按下的,则让其弹起
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 COnscreenKeyboardDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
//释放本程序的焦点状态,即使刚才处于活动的程序重新激活
ReleaseFocus();
//找到是哪个键被单击到了
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 = 0;
y += pKeyHeight;
}
else
{
int width = ((abs(key->cWidth) * pKeyWidth) / 10);
CRect rc(x,y,x + width, y + pKeyHeight);
if(key->cWidth < 0)
{
rc.right = client.right;
}
x += width;
if(rc.PtInRect(point))
{
//发送按键消息
SendKey(key);
}
}
}
}
//双击和单击一样处理
void COnscreenKeyboardDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
OnLButtonDown(nFlags, point);
}
//处理系统消息循环
BOOL COnscreenKeyboardDlg::PreTranslateMessage(MSG* pMsg)
{
HWND wnd = ::GetForegroundWindow();
if(IsWindow(wnd))
{
//如果当前激活窗口不是本程序的窗口
if(wnd != this->m_hWnd)
{
//激活窗口发生了改变
if(gFocus != wnd)
{
if(IsWindow(gFocus))
{
//释放本进程和gFocus线程的联系
AttachThreadInput(
GetWindowThreadProcessId(m_hWnd,NULL),
GetWindowThreadProcessId(gFocus,NULL),
FALSE);
}
gFocus = wnd;
//使本进程和激活窗口的进程联系起来,接收本进程的按键消息
AttachThreadInput(
GetWindowThreadProcessId(m_hWnd,NULL),
GetWindowThreadProcessId(gFocus,NULL),
TRUE);
}
}
}
return CDialog::PreTranslateMessage(pMsg);
}
//双击右键,按单击左键处理
void COnscreenKeyboardDlg::OnRButtonDblClk(UINT nFlags, CPoint point)
{
OnLButtonDown(nFlags, point);
}
//单击右键,按单击左键处理
void COnscreenKeyboardDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
OnLButtonDown(nFlags, point);
}
void COnscreenKeyboardDlg::OnRButtonUp(UINT nFlags, CPoint point)
{
ReleaseFocus();
}
BOOL COnscreenKeyboardDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
ReleaseFocus();
return TRUE;
}
void COnscreenKeyboardDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
ReleaseFocus();
}
//释放本程序的窗口激活状态
void COnscreenKeyboardDlg::ReleaseFocus()
{
if(IsWindow(gFocus))
{
HWND wnd = ::GetForegroundWindow();
if(IsWindow(wnd))
{
if(wnd == gFocus)
{
return;
}
}
//设置保存的焦点窗口处于激活状态
::SetForegroundWindow(gFocus);
::SetFocus(gFocus);
}
}
//主窗口调整大小,重新画键盘
void COnscreenKeyboardDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
if(IsWindow(m_hWnd))
{
if(cKeys.GetCount())
{
CalcWidthHeight();
Invalidate();
}
}
}
void COnscreenKeyboardDlg::OnOK()
{
CDialog::OnOK();
}
void COnscreenKeyboardDlg::OnCancel()
{
CDialog::OnCancel();
}
void COnscreenKeyboardDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
CDialog::OnShowWindow(bShow, nStatus);
}
//获得当时键"capital","shift","control"的状态
int COnscreenKeyboardDlg::DescribeKeyState()
{
int state = 0;
short ks;
//capital
ks = GetKeyState(VK_CAPITAL);
if(ks & 0x000F) state += 0x01;
//shift
ks = GetKeyState(VK_SHIFT);
if(ks & 0xF000) state += 0x02;
//control
ks = GetKeyState(VK_CONTROL);
if(ks & 0xF000) state += 0x04;
return state;
}
//画键盘
void COnscreenKeyboardDlg::DrawKeyboard()
{
//获得设备场景并设置模式
CClientDC dc(this);
CRect client;
GetClientRect(client);
CRgn clipRgn;
clipRgn.CreateRectRgnIndirect(&client);
dc.SelectClipRgn(&clipRgn);
dc.SelectObject(GetStockObject(DEFAULT_GUI_FONT));
dc.SetBkMode(TRANSPARENT);
int x = 0;
int y = -pKeyHeight;
KEYDEF * key;
POSITION pos = cKeys.GetHeadPosition();
cCurrentKeyState = DescribeKeyState();
int state = cCurrentKeyState;
while(pos)
{
//获得每一个键
key = cKeys.GetNext(pos);
if((key->cNormal == 0x00) && (key->cShifted == 0x00))
{
x = 0;
y += pKeyHeight;
}
else
{
int width = ((abs(key->cWidth) * pKeyWidth) / 10);
CRect rc(x,y,x + width, y + pKeyHeight);
x += width;
if(key->cWidth < 0)
{
rc.right = client.right;
}
//检查系统键释放处于高亮度显示
BOOL hilight = FALSE;
if(key->cNormal == 0x00)
{
switch(key->cShifted)
{
case CAPSLOCK:
if(state & 0x01)
{
hilight = TRUE;
}
break;
case SHIFT:
if(state & 0x02)
{
hilight = TRUE;
}
break;
case CTRL:
if(state & 0x04)
{
hilight = TRUE;
}
break;
default:
break;
}
}
//画键
DrawKey(&dc, rc, key, hilight);
}
}
}
//处理定时器,随时获得键盘键的状态
void COnscreenKeyboardDlg::OnTimer(UINT nIDEvent)
{
if(nIDEvent == TIMER_ID)
{
int state = DescribeKeyState();
//如果状态发生改变,则重新画键盘
if(state != cCurrentKeyState)
{
DrawKeyboard();
}
}
}
//退出时,清空内存
void COnscreenKeyboardDlg::OnDestroy()
{
//清除所有键
POSITION pos = cKeys.GetHeadPosition();
while(pos)
{
delete cKeys.GetNext(pos);
}
int state = DescribeKeyState();
if(state & 0x01) keybd_event(VK_CAPITAL,0,KEYEVENTF_KEYUP,0);
if(state & 0x02) keybd_event(VK_SHIFT,0,KEYEVENTF_KEYUP,0);
if(state & 0x04) keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
//关闭定时器
KillTimer(TIMER_ID);
CDialog::OnDestroy();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -