【转】自制软键盘代码~

.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);
}

posted @ 2011-01-17 16:23  gushiyi  阅读(803)  评论(0编辑  收藏  举报