Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

345 lines
7.2 KiB

  1. //
  2. // candkey.cpp
  3. //
  4. #include "private.h"
  5. #include "globals.h"
  6. #include "mscandui.h"
  7. #include "candkey.h"
  8. #include "candui.h"
  9. void DllAddRef(void);
  10. void DllRelease(void);
  11. /*============================================================================*/
  12. /* */
  13. /* C C A N D U I K E Y T A B L E */
  14. /* */
  15. /*============================================================================*/
  16. /* C C A N D U I K E Y T A B L E */
  17. /*------------------------------------------------------------------------------
  18. ------------------------------------------------------------------------------*/
  19. CCandUIKeyTable::CCandUIKeyTable( void )
  20. {
  21. m_cRef = 1;
  22. m_nKeyData = 0;
  23. m_pKeyData = NULL;
  24. DllAddRef();
  25. }
  26. /* ~ C C A N D U I K E Y T A B L E */
  27. /*------------------------------------------------------------------------------
  28. ------------------------------------------------------------------------------*/
  29. CCandUIKeyTable::~CCandUIKeyTable( void )
  30. {
  31. if (m_pKeyData != NULL) {
  32. delete m_pKeyData;
  33. }
  34. DllRelease();
  35. }
  36. /* Q U E R Y I N T E R F A C E */
  37. /*------------------------------------------------------------------------------
  38. Query interface
  39. (IUnknown method)
  40. ------------------------------------------------------------------------------*/
  41. STDAPI CCandUIKeyTable::QueryInterface( REFIID riid, void **ppvObj )
  42. {
  43. if (ppvObj == NULL) {
  44. return E_POINTER;
  45. }
  46. *ppvObj = NULL;
  47. if (IsEqualIID( riid, IID_IUnknown ) || IsEqualIID( riid, IID_ITfCandUIKeyTable )) {
  48. *ppvObj = SAFECAST( this, ITfCandUIKeyTable* );
  49. }
  50. if (*ppvObj == NULL) {
  51. return E_NOINTERFACE;
  52. }
  53. AddRef();
  54. return S_OK;
  55. }
  56. /* A D D R E F */
  57. /*------------------------------------------------------------------------------
  58. Increment reference count
  59. (IUnknown method)
  60. ------------------------------------------------------------------------------*/
  61. STDAPI_(ULONG) CCandUIKeyTable::AddRef( void )
  62. {
  63. m_cRef++;
  64. return m_cRef;
  65. }
  66. /* R E L E A S E */
  67. /*------------------------------------------------------------------------------
  68. Decrement reference count and release object
  69. (IUnknown method)
  70. ------------------------------------------------------------------------------*/
  71. STDAPI_(ULONG) CCandUIKeyTable::Release( void )
  72. {
  73. m_cRef--;
  74. if (0 < m_cRef) {
  75. return m_cRef;
  76. }
  77. delete this;
  78. return 0;
  79. }
  80. /* G E T K E Y D A T A N U M */
  81. /*------------------------------------------------------------------------------
  82. Get count of key data
  83. (ITfCandUIKeyTable method)
  84. ------------------------------------------------------------------------------*/
  85. HRESULT CCandUIKeyTable::GetKeyDataNum( int *piNum )
  86. {
  87. if (piNum == NULL) {
  88. return E_INVALIDARG;
  89. }
  90. *piNum = m_nKeyData;
  91. return S_OK;
  92. }
  93. /* G E T K E Y D A T A */
  94. /*------------------------------------------------------------------------------
  95. Get key data
  96. (ITfCandUIKeyTable method)
  97. ------------------------------------------------------------------------------*/
  98. HRESULT CCandUIKeyTable::GetKeyData( int iData, CANDUIKEYDATA *pData )
  99. {
  100. *pData = m_pKeyData[iData];
  101. return S_OK;
  102. }
  103. /* S E T K E Y T A B L E */
  104. /*------------------------------------------------------------------------------
  105. ------------------------------------------------------------------------------*/
  106. HRESULT CCandUIKeyTable::SetKeyTable( const CANDUIKEYDATA *pKeyData, int nKeyData )
  107. {
  108. Assert( 0 <= nKeyData );
  109. if (m_pKeyData != NULL) {
  110. delete m_pKeyData;
  111. }
  112. // copy data to buffer
  113. m_nKeyData = nKeyData;
  114. m_pKeyData = new CANDUIKEYDATA[ nKeyData ];
  115. if (m_pKeyData)
  116. memcpy( m_pKeyData, pKeyData, sizeof(CANDUIKEYDATA)*nKeyData );
  117. return S_OK;
  118. }
  119. /* S E T K E Y T A B L E */
  120. /*------------------------------------------------------------------------------
  121. ------------------------------------------------------------------------------*/
  122. HRESULT CCandUIKeyTable::SetKeyTable( ITfCandUIKeyTable *pCandUIKeyTable )
  123. {
  124. HRESULT hr;
  125. int i;
  126. int nKeyData;
  127. CANDUIKEYDATA *pKeyData;
  128. Assert( pCandUIKeyTable != NULL );
  129. if (m_pKeyData != NULL) {
  130. delete m_pKeyData;
  131. m_pKeyData = NULL;
  132. m_nKeyData = 0;
  133. }
  134. // get number
  135. hr = pCandUIKeyTable->GetKeyDataNum( &nKeyData );
  136. if (hr != S_OK) {
  137. return hr;
  138. }
  139. if (nKeyData <= 0) {
  140. return E_FAIL;
  141. }
  142. // create buffer
  143. pKeyData = new CANDUIKEYDATA[ nKeyData ];
  144. if (pKeyData == NULL) {
  145. return E_OUTOFMEMORY;
  146. }
  147. for (i = 0; i < nKeyData; i++) {
  148. hr = pCandUIKeyTable->GetKeyData( i, &pKeyData[i] );
  149. if (hr != S_OK) {
  150. delete pKeyData;
  151. return E_FAIL;
  152. }
  153. }
  154. //
  155. m_pKeyData = pKeyData;
  156. m_nKeyData = nKeyData;
  157. return S_OK;
  158. }
  159. /* C O M M A N D F R O M K E Y */
  160. /*------------------------------------------------------------------------------
  161. Get command from key
  162. ------------------------------------------------------------------------------*/
  163. void CCandUIKeyTable::CommandFromKey( UINT uVKey, WCHAR wch, BYTE *pbKeyState, CANDUIUIDIRECTION uidir, CANDUICOMMAND *pcmd, UINT *pParam )
  164. {
  165. BOOL fShift;
  166. BOOL fCtrl;
  167. int i;
  168. int iRotRelative;
  169. Assert( pcmd != NULL );
  170. Assert( pParam != NULL );
  171. *pcmd = CANDUICMD_NONE;
  172. *pParam = 0;
  173. // get keystate
  174. fShift = (pbKeyState[ VK_SHIFT ] & 0x80) != 0;
  175. fCtrl = (pbKeyState[ VK_CONTROL ] & 0x80) != 0;
  176. // calc rotation for relative direction key
  177. switch (uidir) {
  178. default:
  179. case CANDUIDIR_TOPTOBOTTOM: {
  180. iRotRelative = 0;
  181. break;
  182. }
  183. case CANDUIDIR_RIGHTTOLEFT: {
  184. iRotRelative = 1;
  185. break;
  186. }
  187. case CANDUIDIR_BOTTOMTOTOP: {
  188. iRotRelative = 2;
  189. break;
  190. }
  191. case CANDUIDIR_LEFTTORIGHT: {
  192. iRotRelative = 3;
  193. break;
  194. }
  195. }
  196. // find the key from keymap table
  197. for (i = 0; i < m_nKeyData; i++) {
  198. BOOL fMatch = FALSE;
  199. if (m_pKeyData[i].dwFlag == CANDUIKEY_CHAR) {
  200. // check character code
  201. fMatch = ((WCHAR)m_pKeyData[i].uiKey == wch);
  202. }
  203. else {
  204. UINT uVKeyFixed;
  205. // map directional key when it's relative
  206. uVKeyFixed = m_pKeyData[i].uiKey;
  207. if (m_pKeyData[i].dwFlag & CANDUIKEY_RELATIVEDIR) {
  208. int iKey;
  209. const UINT rguVKey[4] = {
  210. VK_DOWN,
  211. VK_LEFT,
  212. VK_UP,
  213. VK_RIGHT
  214. };
  215. // find key
  216. for (iKey = 0; iKey < 4; iKey++) {
  217. if (uVKeyFixed == rguVKey[iKey]) {
  218. uVKeyFixed = rguVKey[ (iKey + iRotRelative) % 4 ];
  219. break;
  220. }
  221. }
  222. }
  223. // check keycode
  224. fMatch = (uVKeyFixed == uVKey);
  225. // check shift state
  226. if (m_pKeyData[i].dwFlag & CANDUIKEY_SHIFT) {
  227. fMatch &= fShift;
  228. }
  229. else if (m_pKeyData[i].dwFlag & CANDUIKEY_NOSHIFT) {
  230. fMatch &= (!fShift);
  231. }
  232. // check ctrl state
  233. if (m_pKeyData[i].dwFlag & CANDUIKEY_CTRL) {
  234. fMatch &= fCtrl;
  235. }
  236. else if (m_pKeyData[i].dwFlag & CANDUIKEY_NOCTRL) {
  237. fMatch &= (!fCtrl);
  238. }
  239. }
  240. // match?
  241. if (fMatch) {
  242. *pcmd = m_pKeyData[i].cmd;
  243. *pParam = m_pKeyData[i].uiParam;
  244. break;
  245. }
  246. }
  247. }