Keys.cpp
上传用户:hmc_gdtv
上传日期:2013-08-04
资源大小:798k
文件大小:19k
源码类别:

Windows Mobile

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 2001,2002,2003 Mike Matsnev.  All Rights Reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice immediately at the beginning of the file, without modification,
  10.  *    this list of conditions, and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. Absolutely no warranty of function or purpose is made by the author
  15.  *    Mike Matsnev.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  * 
  28.  * $Id: Keys.cpp,v 1.8.2.13 2006/05/07 18:08:15 mike Exp $
  29.  * 
  30.  */
  31. #include <afxext.h>
  32. #include "Keys.h"
  33. #include "resource.h"
  34. #include "config.h"
  35. #define BUTTON_W_CH   7
  36. #define BUTTON_SPACE  5
  37. #define MARGIN       3
  38. #define LABEL_BASE    1000
  39. #define LABEL_MAX     1999
  40. #define BUTTON_BASE   2000
  41. #define BUTTON_MAX    2999
  42. #define ACTION_BASE   3000
  43. #define ACTION_MAX    3999
  44. #define KEY_BASE      4000
  45. #define KEY_MAX       4999
  46. #define MINHK       0xc0
  47. #define MAXHK       0xcf
  48. // keys
  49. static struct {
  50.   const TCHAR   *name;
  51.   UINT cmd;
  52.   UINT vk1,vk2,vk3;
  53. } g_actions[]={
  54.   { _T("Line forward"),     ID_LINE_DOWN     },
  55.   { _T("Line backward"),    ID_LINE_UP     },
  56.   { _T("Page forward"),     ID_PAGE_DOWN,   VK_DOWN,  VK_NEXT,   VK_SPACE  },
  57.   { _T("Page backward"),    ID_PAGE_UP,     VK_UP,    VK_PRIOR     },
  58.   { _T("Start of file"),    ID_START_OF_FILE, VK_HOME     },
  59.   { _T("End of file"),     ID_END_OF_FILE, VK_END     },
  60.   { _T("Toggle fullscreen"),ID_FULLSCREEN,  VK_RETURN     },
  61.   { _T("Find"),     ID_FIND     },
  62.   { _T("Find next"),     ID_FINDNEXT,    VK_F3     },
  63.   { _T("Contents"),     ID_BOOKMARKS     },
  64.   { _T("Back"),     ID_BACK,     VK_LEFT     },
  65.   { _T("Forward"),     ID_FORWARD,     VK_RIGHT     },
  66.   { _T("Exit"),     ID_APP_EXIT     },
  67.   { _T("Rotate"),     ID_ROTATE     },
  68.   { _T("Next bookmark/section"), ID_NEXTBM     },
  69.   { _T("Previous bookmark/section"), ID_PREVBM     },
  70.   { _T("Next section"),     ID_NEXTCH     },
  71.   { _T("Previous section"), ID_PREVCH     },
  72.   { _T("Start autoscroll"), ID_AS_START     },
  73.   { _T("Stop autoscroll"),  ID_AS_STOP     },
  74.   { _T("Toggle autoscroll"),ID_AS_TOGGLE     },
  75.   { _T("Faster autoscroll"),ID_AS_FASTER     },
  76.   { _T("Slower autoscroll"),ID_AS_SLOWER     },
  77.   { _T("Faster AS (fine)"), ID_AS_FASTER_FINE     },
  78.   { _T("Slower AS (fine)"), ID_AS_SLOWER_FINE     },
  79.   { _T("Open file"),     ID_FILE_OPEN     },
  80.   { _T("Next color profile"), ID_NEXT_PROFILE     },
  81. };
  82. #define NUMACTIONS    (sizeof(g_actions)/sizeof(g_actions[0]))
  83. static struct {
  84.   UINT       vk;
  85.   const TCHAR *name;
  86. } g_keys[]={
  87.   { VK_LEFT, _T("Left")  },
  88.   { VK_UP, _T("Up")    },
  89.   { VK_RIGHT, _T("Right") },
  90.   { VK_DOWN, _T("Down")  },
  91.   { VK_RETURN, _T("Enter") },
  92.   { VK_SPACE, _T("Space") },
  93.   { VK_PRIOR, _T("PgUp")  },
  94.   { VK_NEXT, _T("PgDown")},
  95.   { VK_HOME, _T("Home")  },
  96.   { VK_END, _T("End")   },
  97.   { VK_INSERT, _T("Insert")  },
  98.   { VK_DELETE, _T("Delete")  },
  99.   { VK_F1, _T("F1")      },
  100.   { VK_F2, _T("F2")      },
  101.   { VK_F3, _T("F3")      },
  102.   { VK_F4, _T("F4")      },
  103.   { VK_F5, _T("F5")      },
  104.   { VK_F6, _T("F6")      },
  105.   { VK_F7, _T("F7")      },
  106.   { VK_F8, _T("F8")      },
  107.   { VK_F9, _T("F9")      },
  108.   { VK_F10, _T("F10")     },
  109.   { VK_F11, _T("F11")     },
  110.   { VK_F12, _T("F12")     },
  111.   { 0x86, _T("Action")  },
  112. };
  113. #define NUMKEYS (sizeof(g_keys)/sizeof(g_keys[0]))
  114. #define MAXVK 256
  115. BOOL     (*g_UnregisterFunc1)(UINT one,UINT two);
  116. static bool IsMod(UINT vk) {
  117.   return  vk == VK_LWIN || vk == VK_RWIN ||
  118.   vk == VK_SHIFT || vk == VK_CONTROL ||
  119.   vk == VK_MENU || vk == VK_LSHIFT ||
  120.   vk == VK_RSHIFT || vk == VK_LCONTROL ||
  121.   vk == VK_RCONTROL || vk == VK_LMENU ||
  122.   vk == VK_RMENU;
  123. }
  124. static void GrabKey(HWND hWnd,UINT vk) {
  125.   if (g_UnregisterFunc1)
  126.     g_UnregisterFunc1(MOD_WIN,vk);
  127.   RegisterHotKey(hWnd,vk,MOD_WIN,vk);
  128. }
  129. static void ReleaseKey(HWND hWnd,UINT vk) {
  130.   UnregisterHotKey(hWnd,vk);
  131. }
  132. static const TCHAR  *GetKeyName(UINT vk) {
  133.   if (vk == 0)
  134.     return _T("");
  135.   for (int i=0;i<NUMKEYS;++i)
  136.     if (g_keys[i].vk==vk)
  137.       return g_keys[i].name;
  138.   static TCHAR   buf[32];
  139.   if (vk>=MINHK && vk<MAXHK)
  140.     _stprintf(buf,_T("App %d"),vk-MINHK);
  141.   else
  142.     _stprintf(buf,_T("Key %02x"),vk);
  143.   return buf;
  144. }
  145. static CString GetKeyNames(int i) {
  146.   CString rv;
  147.   if (g_actions[i].vk1 != 0)
  148.     rv = GetKeyName(g_actions[i].vk1);
  149.   if (g_actions[i].vk2 != 0) {
  150.     if (!rv.IsEmpty()) rv += ',';
  151.     rv += GetKeyName(g_actions[i].vk2);
  152.   }
  153.   if (g_actions[i].vk3 != 0) {
  154.     if (!rv.IsEmpty()) rv += ',';
  155.     rv += GetKeyName(g_actions[i].vk3);
  156.   }
  157.   return rv;
  158. }
  159. static int  GetActionId(UINT cmd) {
  160.   for (int i=0;i<NUMACTIONS;++i)
  161.     if (g_actions[i].cmd==cmd)
  162.       return i;
  163.   return NUMACTIONS-1;
  164. }
  165. static int  LookupKey(UINT vk) {
  166.   for (int i = 0; i < NUMACTIONS; ++i) {
  167.     if (g_actions[i].vk1 == vk)
  168.       return g_actions[i].cmd;
  169.     if (g_actions[i].vk2 == vk)
  170.       return g_actions[i].cmd;
  171.     if (g_actions[i].vk3 == vk)
  172.       return g_actions[i].cmd;
  173.   }
  174.   return 0;
  175. }
  176. static bool HaveKeys(int i) {
  177.   return g_actions[i].vk1 || g_actions[i].vk2 || g_actions[i].vk3;
  178. }
  179. static bool HaveSlots(int i) {
  180.   return !g_actions[i].vk1 || !g_actions[i].vk2 || !g_actions[i].vk3;
  181. }
  182. static void AddKey(int i,UINT vk) {
  183.   if (!g_actions[i].vk1) {
  184.     g_actions[i].vk1 = vk;
  185.     return;
  186.   }
  187.   if (!g_actions[i].vk2) {
  188.     g_actions[i].vk2 = vk;
  189.     return;
  190.   }
  191.   if (!g_actions[i].vk3) {
  192.     g_actions[i].vk3 = vk;
  193.     return;
  194.   }
  195. }
  196. static HWND g_keyowner;
  197. void Keys::InitKeys() {
  198.   for (int i = 0; i < NUMACTIONS; ++i) {
  199.     CString   kn;
  200.     kn.Format(_T("%u"),g_actions[i].cmd);
  201.     CString   val(AfxGetApp()->GetProfileString(_T("Keys2"),kn));
  202.     if (!val.IsEmpty())
  203.       if (_stscanf(val,_T("%u,%u,%u"),&g_actions[i].vk1,&g_actions[i].vk2,&g_actions[i].vk3) != 3)
  204. g_actions[i].vk1 = g_actions[i].vk2 = g_actions[i].vk3 = 0;
  205.   }
  206. #ifdef _WIN32_WCE
  207.   if (!g_UnregisterFunc1) {
  208.     HMODULE hLib=GetModuleHandle(_T("coredll.dll"));
  209.     if (hLib)
  210.       g_UnregisterFunc1=(BOOL (*)(UINT,UINT))GetProcAddress(hLib,_T("UnregisterFunc1"));
  211.   }
  212. #endif
  213. }
  214. static void SaveKeys() {
  215.   for (int i = 0; i < NUMACTIONS; ++i) {
  216.     CString   kn;
  217.     kn.Format(_T("%u"),g_actions[i].cmd);
  218.     CString   val;
  219.     val.Format(_T("%u,%u,%u"),g_actions[i].vk1,g_actions[i].vk2,g_actions[i].vk3);
  220.     AfxGetApp()->WriteProfileString(_T("Keys2"),kn,val);
  221.   }
  222. }
  223. static void GrabAct(HWND hWnd,int i) {
  224.   if (g_actions[i].vk1)
  225.     GrabKey(hWnd,g_actions[i].vk1);
  226.   if (g_actions[i].vk2)
  227.     GrabKey(hWnd,g_actions[i].vk2);
  228.   if (g_actions[i].vk3)
  229.     GrabKey(hWnd,g_actions[i].vk3);
  230. }
  231. static void ReleaseAct(HWND hWnd,int i) {
  232.   if (g_actions[i].vk1)
  233.     ReleaseKey(hWnd,g_actions[i].vk1);
  234.   if (g_actions[i].vk2)
  235.     ReleaseKey(hWnd,g_actions[i].vk2);
  236.   if (g_actions[i].vk3)
  237.     ReleaseKey(hWnd,g_actions[i].vk3);
  238. }
  239. static void GrabAllKeys(HWND hWnd) {
  240.   for (int i = 0; i < NUMACTIONS; ++i)
  241.     GrabAct(hWnd,i);
  242. }
  243. static void ReleaseAllKeys(HWND hWnd) {
  244.   for (int i = 0; i < NUMACTIONS; ++i)
  245.     ReleaseAct(hWnd,i);
  246. }
  247. void Keys::SetWindow(HWND hWnd) {
  248.   if (g_keyowner)
  249.     ReleaseAllKeys(g_keyowner);
  250.   g_keyowner=hWnd;
  251.   if (g_keyowner)
  252.     GrabAllKeys(g_keyowner);
  253.   else {
  254. #ifdef SPI_APPBUTTONCHANGE
  255.     // WinCE doesn't have SendMessageTimeout, so we have to post it
  256.     ::PostMessage(HWND_BROADCAST,WM_WININICHANGE,SPI_APPBUTTONCHANGE,0);
  257. #endif
  258.   }
  259. }
  260. bool  Keys::TranslateKey(UINT vk,UINT& cmd,int angle) {
  261.   UINT cc = LookupKey(vk);
  262.   if (!cc)
  263.     return false;
  264.   cmd = cc;
  265.   if (angle) {
  266.     int   idx;
  267.     switch (vk) {
  268.     case VK_LEFT:
  269.       idx=0;
  270.       break;
  271.     case VK_UP:
  272.       idx=1;
  273.       break;
  274.     case VK_RIGHT:
  275.       idx=2;
  276.       break;
  277.     case VK_DOWN:
  278.       idx=3;
  279.       break;
  280.     default:
  281.       return true;
  282.     }
  283.     int delta;
  284.     switch (angle) {
  285.     case 900:
  286.       delta=1;
  287.       break;
  288.     case 1800:
  289.       delta=2;
  290.       break;
  291.     case 2700:
  292.       delta=3;
  293.       break;
  294.     default:
  295.       delta=0;
  296.     }
  297.     idx=(idx+delta)%4;
  298.     switch (idx) {
  299.     case 0:
  300.       vk=VK_LEFT;
  301.       break;
  302.     case 1:
  303.       vk=VK_UP;
  304.       break;
  305.     case 2:
  306.       vk=VK_RIGHT;
  307.       break;
  308.     case 3:
  309.       vk=VK_DOWN;
  310.       break;
  311.     }
  312.     cc = LookupKey(vk);
  313.     if (!cc)
  314.       return false;
  315.     cmd=cc;
  316.     return true;
  317.   }
  318.   return true;
  319. }
  320. class CKeysDlg : public CDialog
  321. {
  322.   // Construction
  323. public:
  324.   CKeysDlg(CWnd* pParent = NULL);   // standard constructor
  325.   
  326.   // Dialog Data
  327.   //{{AFX_DATA(CKeysDlg)
  328.   enum { IDD = IDD_KEYS };
  329.   //}}AFX_DATA
  330.   
  331.   
  332.   // Overrides
  333.   // ClassWizard generated virtual function overrides
  334.   //{{AFX_VIRTUAL(CKeysDlg)
  335. protected:
  336.   virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
  337.   //}}AFX_VIRTUAL
  338.   
  339.   // Implementation
  340. protected:
  341.   void   SetButtons(int i) {
  342.     ::EnableWindow(::GetDlgItem(m_hWnd,IDCLEAR),HaveKeys(i));
  343.     ::EnableWindow(::GetDlgItem(m_hWnd,IDASSIGN),HaveSlots(i));
  344.   }
  345.   void   SetText(int i) {
  346.     LVITEM    ii;
  347.     ii.mask = LVIF_TEXT;
  348.     ii.stateMask = 0;
  349.     ii.iItem = i;
  350.     ii.iSubItem = 1;
  351.     CString ks = GetKeyNames(i);
  352.     ii.pszText = (TCHAR *)(const TCHAR *)ks;
  353.     ::SendMessage(::GetDlgItem(m_hWnd,IDC_COMMANDS),LVM_SETITEMTEXT,i,(LPARAM)&ii);
  354.   }
  355.   // Generated message map functions
  356.   //{{AFX_MSG(CKeysDlg)
  357.   virtual BOOL OnInitDialog();
  358.   afx_msg void OnActivate(NMHDR* pNMHDR, LRESULT* pResult);
  359.   //}}AFX_MSG
  360.   DECLARE_MESSAGE_MAP()
  361. };
  362. CKeysDlg::CKeysDlg(CWnd* pParent /*=NULL*/)
  363. : CDialog(CKeysDlg::IDD, pParent)
  364. {
  365.   //{{AFX_DATA_INIT(CKeysDlg)
  366.   //}}AFX_DATA_INIT
  367. }
  368. BEGIN_MESSAGE_MAP(CKeysDlg, CDialog)
  369. //{{AFX_MSG_MAP(CKeysDlg)
  370. ON_NOTIFY(LVN_ITEMCHANGED, IDC_COMMANDS, OnActivate)
  371. //}}AFX_MSG_MAP
  372. END_MESSAGE_MAP()
  373. BOOL CKeysDlg::OnInitDialog() 
  374. {
  375.   CDialog::OnInitDialog();
  376. #if POCKETPC
  377.   ((CCeCommandBar *)m_pWndEmptyCB)->LoadToolBar(cIDR_DIALOG);
  378. #endif
  379. #if POCKETPC
  380.   // resize the list box
  381.   RECT     rcC,rcB1,rcB2,rcL;
  382.   GetClientRect(&rcC);
  383.   ::GetWindowRect(::GetDlgItem(m_hWnd,IDC_LABEL),&rcL); ScreenToClient(&rcL);
  384.   ::GetWindowRect(::GetDlgItem(m_hWnd,IDASSIGN),&rcB1); ScreenToClient(&rcB1);
  385.   ::GetWindowRect(::GetDlgItem(m_hWnd,IDCLEAR),&rcB2); ScreenToClient(&rcB2);
  386.   int     delta = rcC.bottom - rcB1.bottom - 4;
  387.   if (delta > 0) {
  388.     rcL.top += delta; rcL.bottom += delta;
  389.     rcB1.top += delta; rcB1.bottom += delta;
  390.     rcB2.top += delta; rcB2.bottom += delta;
  391.     GetDlgItem(IDC_LABEL)->MoveWindow(&rcL);
  392.     GetDlgItem(IDASSIGN)->MoveWindow(&rcB1);
  393.     GetDlgItem(IDCLEAR)->MoveWindow(&rcB2);
  394.     GetDlgItem(IDC_COMMANDS)->GetWindowRect(&rcL);
  395.     ScreenToClient(&rcL);
  396.     rcL.bottom += delta;
  397.     rcL.left = rcC.left - 1;
  398.     rcL.right = rcC.right + 1;
  399.     GetDlgItem(IDC_COMMANDS)->MoveWindow(&rcL);
  400.   }
  401. #endif
  402.   ::EnableWindow(::GetDlgItem(m_hWnd,IDASSIGN),FALSE);
  403.   ::EnableWindow(::GetDlgItem(m_hWnd,IDCLEAR),FALSE);
  404.   CWnd   *lv = GetDlgItem(IDC_COMMANDS);
  405. #ifdef LVS_EX_FULLROWSELECT
  406.   lv->SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE,LVS_EX_FULLROWSELECT,LVS_EX_FULLROWSELECT);
  407. #endif
  408.   RECT   rcLV;
  409.   lv->GetClientRect(&rcLV);
  410.   int   vw = rcLV.right - rcLV.left - GetSystemMetrics(SM_CXVSCROLL);
  411.   LVCOLUMN   col;
  412.   memset(&col, 0, sizeof(col));
  413.   col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  414.   col.fmt = LVCFMT_LEFT;
  415.   col.cx = vw / 2;
  416.   GetDlgItem(IDC_COMMANDS)->SendMessage(LVM_INSERTCOLUMN,0,(LPARAM)&col);
  417.   col.cx = vw - col.cx;
  418.   GetDlgItem(IDC_COMMANDS)->SendMessage(LVM_INSERTCOLUMN,1,(LPARAM)&col);
  419.   CString   ks;
  420.   for (int i = 0; i < NUMACTIONS; ++i) {
  421.     LVITEM    ii;
  422.     memset(&ii, 0, sizeof(ii));
  423.     ii.mask = LVIF_TEXT;
  424.     ii.stateMask = 0;
  425.     ii.pszText = (TCHAR *)g_actions[i].name;
  426.     ii.iItem = i;
  427.     ii.iSubItem = 0;
  428.     lv->SendMessage(LVM_INSERTITEM,0,(LPARAM)&ii);
  429.     ks = GetKeyNames(i);
  430.     ii.iSubItem = 1;
  431.     ii.pszText = (TCHAR *)(const TCHAR *)ks;
  432.     lv->SendMessage(LVM_SETITEMTEXT,i,(LPARAM)&ii);
  433.   }
  434.   return TRUE;
  435. }
  436. class CKeyGrabDlg : public CDialog
  437. {
  438.   // Construction
  439. public:
  440.   CKeyGrabDlg(CWnd* pParent = NULL);   // standard constructor
  441.   UINT       m_vk[16];
  442.   void Record(UINT vk) {
  443.     SetTimer(1,50,NULL);
  444.     for (int i = 0; i < sizeof(m_vk)/sizeof(m_vk[0]); ++i)
  445.       if (m_vk[i] == 0) {
  446. m_vk[i] = vk;
  447. return;
  448.       }
  449.   }
  450.   UINT Get() {
  451.     UINT    vk = 0;
  452.     for (int i = 0; i < sizeof(m_vk)/sizeof(m_vk[0]); ++i)
  453.       if (LOWORD(m_vk[i]) && (vk == 0 || LOWORD(m_vk[i]) < vk))
  454. vk = LOWORD(m_vk[i]);
  455.     return vk;
  456.   }
  457. #if 0
  458.   CString List() {
  459.     CString s;
  460.     for (int i = 0; i < sizeof(m_vk)/sizeof(m_vk[0]); ++i) {
  461.       if (m_vk[i] == 0)
  462. break;
  463.       CString t; t.Format(_T("0x%x"),m_vk[i]);
  464.       if (!s.IsEmpty())
  465. s+=' ';
  466.       s+=t;
  467.     }
  468.     return s;
  469.   }
  470. #endif
  471.   enum { IDD = IDD_KEYGRAB };
  472.   
  473. protected:
  474.   static LRESULT CALLBACK GrabKeyProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
  475.   
  476.   // Generated message map functions
  477.   //{{AFX_MSG(CKeyGrabDlg)
  478.   virtual BOOL OnInitDialog();
  479.   afx_msg void OnDestroy();
  480.   afx_msg void OnTimer(UINT nIDEvent);
  481.   //}}AFX_MSG
  482.   afx_msg LRESULT OnHotkey(WPARAM,LPARAM);
  483.   afx_msg LRESULT OnApp(WPARAM,LPARAM);
  484.   DECLARE_MESSAGE_MAP()
  485. };
  486. /////////////////////////////////////////////////////////////////////////////
  487. // CKeyGrabDlg dialog
  488. CKeyGrabDlg::CKeyGrabDlg(CWnd* pParent /*=NULL*/)
  489. : CDialog(CKeyGrabDlg::IDD, pParent)
  490. {
  491.   memset(m_vk,0,sizeof(m_vk));
  492. }
  493. BEGIN_MESSAGE_MAP(CKeyGrabDlg, CDialog)
  494. //{{AFX_MSG_MAP(CKeyGrabDlg)
  495. ON_WM_DESTROY()
  496. ON_WM_TIMER()
  497. //}}AFX_MSG_MAP
  498. ON_MESSAGE(WM_HOTKEY, OnHotkey)
  499. ON_MESSAGE(WM_APP, OnApp)
  500. #if POCKETPC
  501. ON_WM_SETTINGCHANGE()
  502. #endif
  503. END_MESSAGE_MAP()
  504. /////////////////////////////////////////////////////////////////////////////
  505. // CKeyGrabDlg message handlers
  506. void CKeyGrabDlg::OnTimer(UINT nIDEvent) 
  507. {
  508.   for (int i = 0; i < sizeof(m_vk)/sizeof(m_vk[0]); ++i)
  509.     if (LOWORD(m_vk[i]) && (GetAsyncKeyState(LOWORD(m_vk[i])) & 0x8000)) {
  510.       SetTimer(1,50,NULL);
  511.       return;
  512.     }
  513.   EndDialog(IDOK);
  514. }
  515. BOOL CKeyGrabDlg::OnInitDialog() {
  516.   CDialog::OnInitDialog();
  517. #if POCKETPC
  518.   ((CCeCommandBar *)m_pWndEmptyCB)->LoadToolBar(cIDR_DIALOG);
  519. #endif
  520.   RECT rcC;
  521.   GetClientRect(&rcC);
  522.   HWND hWnd = ::CreateWindow(_T("Static"),_T("Press any key..."),WS_VISIBLE|WS_CHILD|SS_CENTER,
  523.     rcC.left,rcC.top + (rcC.bottom-rcC.top)/2 - HIWORD(GetDialogBaseUnits()),
  524.     rcC.right-rcC.left,HIWORD(GetDialogBaseUnits()*2),m_hWnd,
  525.     (HMENU)47793,AfxGetInstanceHandle(),NULL);
  526.   // release all keys
  527.   if (g_keyowner)
  528.     ReleaseAllKeys(g_keyowner);
  529.   // and grab all
  530.   for (int i=MINHK;i<=MAXHK;++i)
  531.     GrabKey(m_hWnd,i);
  532.   SetWindowLong(m_hWnd,GWL_USERDATA,GetWindowLong(m_hWnd,GWL_WNDPROC));
  533.   SetWindowLong(m_hWnd,GWL_WNDPROC,(LONG)GrabKeyProc);
  534.   SetWindowLong(hWnd,GWL_USERDATA,GetWindowLong(hWnd,GWL_WNDPROC));
  535.   SetWindowLong(hWnd,GWL_WNDPROC,(LONG)GrabKeyProc);
  536.   SetFocus();
  537.   return TRUE;
  538. }
  539. void CKeyGrabDlg::OnDestroy() {
  540.   // release keys
  541.   for (int i=MINHK;i<=MAXHK;++i)
  542.     ReleaseKey(m_hWnd,i);
  543.   // and regrab
  544.   if (g_keyowner)
  545.     GrabAllKeys(g_keyowner);
  546.   CDialog::OnDestroy();
  547. }
  548. LRESULT CKeyGrabDlg::OnHotkey(WPARAM wp,LPARAM lp) {
  549.   Record(MAKELONG(HIWORD(lp),LOWORD(lp)));
  550.   return 0;
  551. }
  552. LRESULT CKeyGrabDlg::OnApp(WPARAM wp,LPARAM lp) {
  553.   if (wp == 0x86)
  554.     Record(13);
  555.   return 0;
  556. }
  557. LRESULT CALLBACK CKeyGrabDlg::GrabKeyProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) {
  558.   WNDPROC wp = (WNDPROC)GetWindowLong(hWnd,GWL_USERDATA);
  559.   HWND   mWnd = hWnd;
  560.   if (::GetDlgCtrlID(hWnd) == 47793)
  561.     mWnd = ::GetParent(hWnd);
  562.   if (mWnd == NULL)
  563.     return CallWindowProc(wp,hWnd,uMsg,wParam,lParam);
  564.   if (uMsg == WM_KEYDOWN) {
  565.     if (!IsMod(wParam) && !(lParam & 0x40000000))
  566.       ::PostMessage(mWnd,WM_APP,wParam,0);
  567.   }
  568.   if (uMsg == WM_KEYUP) {
  569.     if (!IsMod(wParam))
  570.       ::PostMessage(mWnd,WM_HOTKEY,wParam,MAKELONG(0,wParam));
  571.     return 0;
  572.   }
  573.   if (uMsg == WM_DESTROY)
  574.     SetWindowLong(hWnd,GWL_WNDPROC,GetWindowLong(hWnd,GWL_USERDATA));
  575.   return CallWindowProc(wp,hWnd,uMsg,wParam,lParam);
  576. }
  577. void Keys::SetupKeys(CWnd *parent) {
  578.   CKeysDlg    dlg;
  579.   if (dlg.DoModal()==IDOK)
  580.     SaveKeys();
  581.   else {
  582.     HWND  owner=g_keyowner;
  583.     Keys::SetWindow(0);
  584.     Keys::InitKeys();
  585.     Keys::SetWindow(owner);
  586.   }
  587. }
  588. BOOL CKeysDlg::OnCommand(WPARAM wParam, LPARAM lParam) 
  589. {
  590.   int sel = ::SendMessage(::GetDlgItem(m_hWnd,IDC_COMMANDS),LVM_GETSELECTIONMARK,0,0);
  591.   switch (LOWORD(wParam)) {
  592.     case IDASSIGN:
  593.       if (sel >= 0 && sel < NUMACTIONS && HaveSlots(sel)) {
  594. CKeyGrabDlg dlg(this);
  595. dlg.DoModal();
  596. if (dlg.Get()) {
  597.   UINT  vk = dlg.Get();
  598.   for (int j = 0; j < NUMACTIONS; ++j) {
  599.     if (g_actions[j].vk1 == vk) {
  600.       g_actions[j].vk1 = 0;
  601.       SetText(j);
  602.     }
  603.     if (g_actions[j].vk2 == vk) {
  604.       g_actions[j].vk2 = 0;
  605.       SetText(j);
  606.     }
  607.     if (g_actions[j].vk3 == vk) {
  608.       g_actions[j].vk3 = 0;
  609.       SetText(j);
  610.     }
  611.   }
  612.   if (g_keyowner)
  613.     ReleaseAct(g_keyowner,sel);
  614.   AddKey(sel,vk);
  615.   if (g_keyowner)
  616.     GrabAct(g_keyowner,sel);
  617.   SetButtons(sel);
  618.   SetText(sel);
  619. }
  620.       }
  621.       return TRUE;
  622.     case IDCLEAR:
  623.       if (sel >= 0 && sel < NUMACTIONS) {
  624. if (g_keyowner)
  625.   ReleaseAct(g_keyowner,sel);
  626. g_actions[sel].vk1 = g_actions[sel].vk2 = g_actions[sel].vk3 = 0;
  627. SetButtons(sel);
  628. SetText(sel);
  629.       }
  630.       return TRUE;
  631.   }
  632.   return CDialog::OnCommand(wParam, lParam);
  633. }
  634. void CKeysDlg::OnActivate(NMHDR* pNMHDR, LRESULT* pResult) 
  635. {
  636.   NMLISTVIEW  *nv = (NMLISTVIEW *)pNMHDR;
  637.   if (nv->iItem >= 0 && (nv->uChanged & LVIF_STATE) && 
  638.       (nv->uNewState & LVIS_SELECTED))
  639.   {
  640.     SetButtons(nv->iItem);
  641.   }
  642. #if 0
  643.   int sel = ::SendMessage(::GetDlgItem(m_hWnd,IDC_COMMANDS),LVM_GETSELECTIONMARK,0,0);
  644.   if (sel >= 0 && sel < NUMACTIONS)
  645.     SetButtons(sel);
  646. #endif
  647.   *pResult = 0;
  648. }