Advertisement
Guest User

Untitled

a guest
Nov 18th, 2017
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 24.71 KB | None | 0 0
  1. //
  2. // Copyright (c) Microsoft Corporation.  All rights reserved.
  3. //
  4. //
  5. // Use of this sample source code is subject to the terms of the Microsoft
  6. // license agreement under which you licensed this sample source code. If
  7. // you did not accept the terms of the license agreement, you are not
  8. // authorized to use this sample source code. For the terms of the license,
  9. // please see the license agreement between you and Microsoft or, if applicable,
  10. // see the LICENSE.RTF on your install media or the root of your tools installation.
  11. // THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
  12. //
  13. //
  14. //
  15. /*++
  16.  
  17.  
  18. Module Name:
  19.  
  20.     im.cpp
  21.  
  22. Abstract:
  23.  
  24.     Sample LSIP Input Method.
  25.  
  26.  
  27. Revision History:
  28.  
  29. --*/
  30.  
  31.  
  32. #define INITGUID
  33. #include <windows.h>
  34. #include <coguid.h>
  35. #undef INITGUID
  36. #include <commctrl.h>
  37. #include <sipapi.h>
  38. #include <Keybd.h>
  39. #include "resource.h"
  40. #include "dllmain.h"
  41. #include "im.h"
  42.  
  43.  
  44. #ifdef DEBUG
  45.  
  46. DBGPARAM dpCurSettings = {
  47.     TEXT("DynamicIM"), {
  48.     TEXT("Init"),TEXT("Keys"),TEXT(""),TEXT(""),
  49.     TEXT(""),TEXT(""),TEXT(""),TEXT(""),
  50.     TEXT(""),TEXT(""),TEXT("Interface"),TEXT("Misc"),
  51.     TEXT("Alloc"),    TEXT("Function"), TEXT("Warning"),  TEXT("Error") },
  52.     0x00000000
  53. };
  54. #else
  55. DWORD   v_dwDebugFlag = 0x0;     // Allow some retail debug zones.
  56. #endif // DEBUG
  57.  
  58.  
  59. //
  60. // The KEYENTRY structure describes a single key on the keyboard.
  61. //
  62. typedef struct {
  63.     UINT    bVk;        // If VK then just a byte, -1 for sentinel
  64.     UINT    wcUnshift;  // => Valeur qu'écrit la touche
  65.     UINT    wcShift;    // wcShift => Valeur qu'écrit la touche en étant combiné avec shift
  66.     UINT    nCtrl;      // nCtrl => Valeur qu'écrit la touche en étant combiné avec ctrl
  67.     DWORD   fdwFlags;   // fdwFlags =>
  68.     // NO_CTL si pas de fonction ctrl
  69.     // F_VK si c'est une touche spéciale avec fonction VK
  70.     // F_STK si c'est une touche spéciale nécessitant un second appui pour être relaché comme shift ...
  71.     // F_REDRAW pour forcer à redessiner
  72.     // Et d'autre surement possible voir im.h
  73.     int     nLeft; // nLeft => Offset de la touche à partir de la gauche de l'image
  74. } KEYENTRY;
  75.  
  76. #define NUM_ROWS    5
  77. KEYENTRY g_keys[NUM_ROWS][16+1] = {
  78.     // First Row
  79.     {
  80.         { VK_BACKQUOTE, '~',    '`',     NO_CTL, 0,                0 },
  81.         { '1',          '!',    '1',     NO_CTL, 0,               40 },
  82.         { '2',          '@',    '2',     0,      0,               80 },
  83.         { '3',          '#',    '3',     NO_CTL, 0,              120 },
  84.         { '4',          '$',    '4',     NO_CTL, 0,              160 },
  85.         { '5',          '%',    '5',     NO_CTL, 0,              200 },
  86.         { '6',          '^',    '6',     30,     0,              240 },
  87.         { '7',          '&',    '7',     NO_CTL, 0,              280 },
  88.         { '8',          '*',    '8',     NO_CTL, 0,              320 },
  89.         { '9',          '(',    '9',     NO_CTL, 0,              360 },
  90.         { '0',          ')',    '0',     NO_CTL, 0,              400 },
  91.         { VK_HYPHEN,    '_',    '-',     31,     0,              440 },
  92.         { VK_EQUAL,     '+',    '=',     NO_CTL, 0,              480 },
  93.         { VK_BACK,      '\x8',  '\x8',   127,    0,              520 },
  94.         { SENTINEL,     0,      0,       NO_CTL, 0,              560 }
  95.     },
  96.  
  97.     // 2 row
  98.     {
  99.         { VK_TAB,       '\t',   '\t',    '\t',   0,              0   },
  100.         { 'A',          'a',    'A',     1,      0,              40  },
  101.         { 'Z',          'z',    'Z',     26,     0,              80  },
  102.         { 'E',          'e',    'E',     5,      0,              120 },
  103.         { 'R',          'r',    'R',     18,     0,              160 },
  104.         { 'T',          't',    'T',     20,     0,              200 },
  105.         { 'Y',          'y',    'Y',     25,     0,              240 },
  106.         { 'U',          'u',    'U',     21,     0,              280 },
  107.         { 'I',          'i',    'I',     9,      0,              320 },
  108.         { 'O',          'o',    'O',     15,     0,              360 },
  109.         { 'P',          'p',    'P',     16,     0,              400 },
  110.         { VK_LBRACKET,  '[',    '{',     27,     0,              440 },
  111.         { VK_RBRACKET,  ']',    '}',     29,     0,              480 },
  112.         { VK_BACKSLASH, '\\',   '|',     28,     0,              520 },
  113.         { SENTINEL,     0,      0,       NO_CTL, 0,              560 }
  114.     },
  115.  
  116.     // 3 row
  117.     {
  118.         { VK_CAPITAL,   0,      0,      NO_CTL, F_VK | F_STK | F_REDRAW,      0 },
  119.         { 'Q',          'q',    'Q',    17,     0,                           40 },
  120.         { 'S',          's',    'S',    19,     0,                           80 },
  121.         { 'D',          'd',    'D',    4,      0,                          120 },
  122.         { 'F',          'f',    'F',    6,      0,                          160 },
  123.         { 'G',          'g',    'G',    7,      0,                          200 },
  124.         { 'H',          'h',    'H',    8,      0,                          240 },
  125.         { 'J',          'j',    'J',    10,     0,                          280 },
  126.         { 'K',          'k',    'K',    11,     0,                          320 },
  127.         { 'L',          'l',    'L',    12,     0,                          360 },
  128.         { 'M',          'm',    'M',    13,     0,                          400 },
  129.         { VK_APOSTROPHE,'\'',   '\"',   NO_CTL, 0,                          440 },
  130.         { VK_RETURN,    '\xD',  '\xD',  10,     0,                          480 },
  131.         { SENTINEL,     0,      0,      NO_CTL, 0,                          560 }
  132.  
  133.     },
  134.  
  135.     // 4 row
  136.     {
  137.         { VK_SHIFT,     0,      0,       NO_CTL, F_VK | F_STK | F_REDRAW,     0 },
  138.         { VK_SEMICOLON, '<',    '>',     NO_CTL, 0,                          40 },
  139.         { 'W',          'w',    'W',     23,     0,                          80 },
  140.         { 'X',          'x',    'X',     24,     0,                         120 },
  141.         { 'C',          'c',    'C',     3,      0,                         160 },
  142.         { 'V',          'v',    'V',     22,     0,                         200 },
  143.         { 'B',          'b',    'B',     2,      0,                         240 },
  144.         { 'N',          'n',    'N',     14,     0,                         280 },
  145.         { VK_COMMA,     ',',    '?',     NO_CTL, 0,                         320 },
  146.         { VK_PERIOD,    '.',    ';',     NO_CTL, 0,                         360 },
  147.         { VK_SLASH,     '/',    ':',     NO_CTL, 0,                         400 },
  148.         { VK_UP,        0,      0,       NO_CTL, 0,                         440 },
  149.         { VK_ESCAPE,    0,      0,       NO_CTL, F_VK,                      480 },
  150.         { VK_PRIOR,     0,      0,       NO_CTL, 0,                         520 },
  151.         { SENTINEL,     0,      0,       NO_CTL, 0,                         560 }
  152.     },
  153.  
  154.     // 5 row
  155.     {
  156.         { VK_CONTROL,   0,      0,       NO_CTL, F_VK | F_STK,     0 },
  157.         { VK_LWIN,      0,      0,       0,      F_VK,            40 },
  158.         { VK_LMENU,     0,      0,       0,      F_VK | F_STK,    80 },
  159.         { VK_SPACE,     ' ',    ' ',     32,     0,              120 },
  160.         { VK_INSERT,    0,      0,       NO_CTL, 0,              320 },
  161.         { VK_DELETE,    0,      0,       NO_CTL, 0,              360 },
  162.         { VK_LEFT,      0,      0,       NO_CTL, 0,              400 },
  163.         { VK_DOWN,      0,      0,       NO_CTL, 0,              440 },
  164.         { VK_RIGHT,     0,      0,       NO_CTL, 0,              480 },
  165.         { VK_NEXT,      0,      0,       NO_CTL, 0,              520 },
  166.         { SENTINEL,     0,      0,       NO_CTL, 0,              560 }
  167.     },
  168. };
  169.  
  170. static int g_RowCoord[7] = { 0, 40, 80, 120, 160, 200, 0xFFFF };
  171. //static int g_RowCoord[8] = { 0, 29, 62, 95, 128, 161, 194, 0xFFFF };
  172.  
  173. //
  174. // Globals.
  175. //
  176. static TCHAR const g_pwszClassName[] = TEXT("A523DFC7-1A7E-4af6-991A-510E75847828 - MicrosoftIMWndClass");
  177. static HWND g_hwndMain;
  178. static HDC  g_hdcKeybd;
  179. static HBITMAP g_hbmKeybd, g_hbmOld;
  180. static IIMCallback *g_pIMCallback;
  181. static int g_nDown;
  182. static BOOL g_fControlDown;
  183. static BOOL g_fCapsLockDown;
  184. static BOOL g_fShiftDown;
  185. static BOOL g_fAltDown;
  186.  
  187.  
  188.  
  189. //
  190. // Draw the key in the up/down position based on fPress
  191. //
  192. void IM_DrawKey(KEYENTRY *pKey, RECT *prc, BOOL fPress)
  193. {
  194.     HDC hdc;
  195.     RECT rc;
  196.     int Offset = 0;
  197.  
  198.     hdc = GetDC(g_hwndMain);
  199.  
  200.     rc = *prc;
  201.  
  202.     InflateRect(&rc, -1, -1);
  203.  
  204.     if (g_fShiftDown ^ g_fCapsLockDown) {
  205.         Offset = 200; ///////////////////////////////////////////////////////////////
  206.     }
  207.  
  208.     BitBlt(hdc, rc.left, rc.top, rc.right - rc.left + 1, rc.bottom - rc.top + 1,
  209.            g_hdcKeybd,  rc.left, rc.top + Offset, fPress ? NOTSRCCOPY : SRCCOPY);
  210.  
  211.     ReleaseDC(g_hwndMain, hdc);
  212. }
  213.  
  214. //
  215. // Paint an area of the keyboard.
  216. //
  217. static
  218. void WINAPI
  219. IM_DrawArea( HDC hdc, RECT *prcUpdate )
  220. {
  221.     int Offset = 0;
  222.  
  223.     RETAILMSG (ZONE_FUNCTION, (TEXT("+IM_DrawArea(0x%08X, 0x%08X(%d,%d,%d,%d))\r\n"), hdc, prcUpdate,
  224.                               prcUpdate->left, prcUpdate->top, prcUpdate->right, prcUpdate->bottom));
  225.  
  226.     // Draw the keys.
  227.     if (g_fShiftDown ^ g_fCapsLockDown) {
  228.         Offset = 200; //////////////////////////////////////////////////////////////////
  229.     }
  230.  
  231.     BitBlt(hdc, prcUpdate->left, prcUpdate->top, prcUpdate->right - prcUpdate->left,
  232.            prcUpdate->bottom - prcUpdate->top, g_hdcKeybd,  prcUpdate->left,
  233.            prcUpdate->top + Offset, SRCCOPY );
  234.  
  235.     // Now draw any keys that are down
  236.     if (g_nDown) {
  237.         int nRow, nCol;
  238.         KEYENTRY *pKey;
  239.         RECT    rc;
  240.         for (nRow = 0; nRow < NUM_ROWS; nRow++) {
  241.             for (nCol = 0; SENTINEL != g_keys[nRow][nCol].bVk; nCol++) {
  242.                 pKey = &(g_keys[nRow][nCol]);
  243.                 if (pKey->fdwFlags & F_DOWN) {
  244.                     rc.left   = pKey->nLeft;
  245.                     rc.right  = (pKey + 1)->nLeft;
  246.                     rc.top    = g_RowCoord[nRow];
  247.                     rc.bottom = g_RowCoord[nRow + 1];
  248.                     IM_DrawKey(pKey, &rc, TRUE);
  249.                 }
  250.             }
  251.         }
  252.     }
  253.  
  254.     return;
  255. }
  256.  
  257. //
  258. // Refresh the entire keyboard bitmap.
  259. //
  260. static
  261. void WINAPI
  262. IM_SwitchBitmap( void )
  263. {
  264.     HDC hdc;
  265.     RECT rc;
  266.  
  267.     GetClientRect( g_hwndMain, &rc );
  268.     hdc = GetDC( g_hwndMain );
  269.     IM_DrawArea( hdc, &rc );
  270.     ReleaseDC( g_hwndMain, hdc );
  271.  
  272.     return;
  273. }
  274.  
  275.  
  276.  
  277. //
  278. // Determine the left edge of nKey + 1
  279. //
  280. #define KeyLeftCoord(nRow,nKey) (g_keys[nRow][nKey+1].nLeft)
  281.  
  282. //
  283. // Determine what key contains the point specified in rcKey.left,rcKey.top.
  284. // Fill in the full coordinates for the key and return the keyentry.
  285. //
  286. // Assumptions: we will not get a down event outside of our window, and every
  287. // point in the window maps to a key.
  288. //
  289. __inline static
  290. KEYENTRY* WINAPI
  291. IM_GetKeyFromCoord( RECT *prcKey )
  292. {
  293.     int nRow = 0, nKey = 0, nLeft;
  294.     POINT pt;
  295.  
  296.     pt.x = prcKey->left;
  297.     pt.y = prcKey->top;
  298.  
  299.     //
  300.     // Row
  301.     //
  302.  
  303.     while( prcKey->top > g_RowCoord[nRow + 1] ) {
  304.         nRow++;
  305.     }
  306.     if (nRow > 5) {
  307.        nRow = 5;
  308.  //   if (nRow > 4) {
  309.  //       nRow = 4;
  310.     }
  311.  
  312.     //
  313.     // Key
  314.     //
  315.  
  316.     while (prcKey->left > (nLeft = KeyLeftCoord(nRow, nKey))) {
  317.         nKey++;
  318.     }
  319.  
  320.     RETAILMSG (ZONE_KEYS, (TEXT("%d,%d -> %d,%d\r\n"), prcKey->top, prcKey->left, nRow, nKey));
  321.  
  322.     //
  323.     // Set up rect and return the key.
  324.     //
  325.     prcKey->left   = g_keys[nRow][nKey].nLeft;
  326.     prcKey->right  = nLeft;
  327.     prcKey->top    = g_RowCoord[nRow];
  328.     prcKey->bottom = g_RowCoord[nRow + 1];
  329.  
  330.     return g_keys[nRow] + nKey;
  331. }
  332.  
  333. static
  334. BOOL WINAPI
  335. IM_PressKey( BOOL fPress, KEYENTRY *pKey, RECT *prcKey )
  336. {
  337.     DWORD dwVkFlags;
  338.     KEY_STATE_FLAGS nShiftState;
  339.     HRESULT hRes;
  340.     UINT *pnChar = NULL;
  341.  
  342.     if( fPress )
  343.         {
  344.         pKey->fdwFlags |= F_DOWN;
  345.         dwVkFlags = KEYEVENTF_SILENT;
  346.         nShiftState = KeyStateDownFlag;
  347.         }
  348.     else
  349.         {
  350.         pKey->fdwFlags &= ~F_DOWN;
  351.         dwVkFlags = KEYEVENTF_KEYUP | KEYEVENTF_SILENT;
  352.         nShiftState = KeyShiftNoCharacterFlag;
  353.         }
  354.  
  355.  
  356.     //
  357.     // Adjust down count (an optimization for redraw and searching).
  358.     //
  359.  
  360.     g_nDown += fPress ? 1 : -1;
  361.     ASSERT(g_nDown >= 0);
  362.  
  363.     if ( pKey->fdwFlags & F_VK )
  364.         {
  365.         hRes = g_pIMCallback->SendVirtualKey( pKey->bVk, dwVkFlags );
  366.         }
  367.     else
  368.         {
  369. #define ISNOCHARACTERKEY(pKey) (pKey->wcUnshift == 0 && pKey->wcShift == 0)
  370.  
  371.         if (ISNOCHARACTERKEY(pKey))
  372.             {
  373.             nShiftState |= KeyShiftNoCharacterFlag;
  374.             }
  375.         if(g_fAltDown)
  376.             {
  377.             nShiftState |= KeyShiftAnyAltFlag | KeyShiftLeftAltFlag;
  378.             }
  379.         if (g_fControlDown)
  380.             {
  381.             nShiftState |= KeyShiftAnyCtrlFlag;
  382.             if (NO_CTL == pKey->nCtrl)
  383.                 {
  384.                 nShiftState |= KeyShiftNoCharacterFlag;
  385.                 }
  386.             pnChar = &pKey->nCtrl;
  387.             }
  388.         else if (g_fShiftDown ^ g_fCapsLockDown)
  389.             {
  390.             nShiftState |= KeyShiftAnyShiftFlag;
  391.             pnChar = &pKey->wcShift;
  392.             }
  393.         else
  394.             {
  395.             pnChar = &pKey->wcUnshift;
  396.             }
  397.  
  398.         if (pnChar)
  399.             {
  400.             hRes = g_pIMCallback->SendCharEvents(pKey->bVk, nShiftState, 1, &nShiftState, pnChar);
  401.             }
  402.         }
  403.  
  404.     switch (pKey->bVk)
  405.         {
  406.     case VK_CONTROL :
  407.         g_fControlDown = fPress;
  408.         break;
  409.     case VK_SHIFT :
  410.         g_fShiftDown = fPress;
  411.         break;
  412.     case VK_LMENU :
  413.         g_fAltDown = fPress;
  414.         break;
  415.     case VK_CAPITAL :
  416.         g_fCapsLockDown = fPress;
  417.         break;
  418.         }
  419.  
  420.     if (pKey->fdwFlags & F_REDRAW)
  421.         {
  422.         IM_SwitchBitmap();
  423.         }
  424.     IM_DrawKey (pKey, prcKey, fPress);
  425.  
  426.     if (!fPress && g_nDown)
  427.         {
  428.         int nRow, nCol;
  429.         KEYENTRY *pKeyTemp;
  430.         RECT    rc;
  431.         for (nRow = 0; g_nDown && (nRow < NUM_ROWS); nRow++)
  432.             {
  433.             for (nCol = 0; g_nDown && (SENTINEL != g_keys[nRow][nCol].bVk); nCol++)
  434.                 {
  435.                 pKeyTemp = &(g_keys[nRow][nCol]);
  436.                 if ((pKeyTemp->fdwFlags & F_DOWN) && (VK_CAPITAL != pKeyTemp->bVk))
  437.                     {
  438.                     //  We need a small delay to allow characters sent earlier
  439.                     //  to be processed before we change the global keyboard state.
  440.                     //  If not, keybd_event may change the global keyboard state before
  441.                     //  an application has received and processed the characters sent earlier.
  442.                     Sleep(100);
  443.                     rc.left   = pKeyTemp->nLeft;
  444.                     rc.right  = (pKeyTemp + 1)->nLeft;
  445.                     rc.top    = g_RowCoord[nRow];
  446.                     rc.bottom = g_RowCoord[nRow + 1];
  447.                     IM_PressKey(FALSE, pKeyTemp, &rc);
  448.                     }
  449.                 }
  450.             }
  451.         }
  452.  
  453.     return SUCCEEDED(hRes);
  454. }
  455.  
  456. //
  457. // Handle mouse events.
  458. //
  459.  
  460. __inline static
  461. LRESULT WINAPI
  462. IM_OnMouseEvent( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
  463. {
  464.     static int nKeyDownX, nKeyDownY;
  465.     static RECT rcKey;
  466.     static KEYENTRY *pKey = NULL;
  467.     int nKeyUpX, nKeyUpY;
  468.     static BOOL fDblClk = FALSE;
  469.  
  470. //    RETAILMSG (ZONE_FUNCTION, (TEXT("+IM_OnMouseEvent(0x%08X, 0x%08X, 0x%08X, 0x%08X)\r\n"), hwnd, msg, wParam, lParam));
  471.  
  472.     switch (msg) {
  473.     case WM_LBUTTONDOWN :
  474.         RETAILMSG (ZONE_MOUSE, (TEXT("Got WM_LBUTTONDOWN\r\n")));
  475.         fDblClk = FALSE;
  476.         rcKey.left = nKeyDownX = (int)((short)LOWORD(lParam));  //keep the sign
  477.         rcKey.top = nKeyDownY = (int)((short)HIWORD(lParam));
  478.  
  479.         if (pKey = IM_GetKeyFromCoord(&rcKey)) {
  480.             RETAILMSG (ZONE_KEYS, (TEXT("Found pKey=0x%08X\r\n"), pKey));
  481.             pKey->fdwFlags |= F_CAPTURED;
  482.             IM_DrawKey(pKey, &rcKey, TRUE);
  483.             SetCapture(hwnd);
  484.         } else {
  485.             RETAILMSG (ZONE_KEYS, (TEXT("ERROR: Get coord (%d,%d)but can't find key\r\n"),
  486.                            nKeyDownX, nKeyDownY));
  487.         }
  488.         break;
  489.     case WM_LBUTTONUP :
  490.         RETAILMSG (ZONE_MOUSE, (TEXT("Got WM_LBUTTONUP\r\n")));
  491.         if (fDblClk) {
  492.             break;
  493.         }
  494.         nKeyUpX = (int)((short)LOWORD(lParam));  // keep the sign
  495.         nKeyUpY = (int)((short)HIWORD(lParam));
  496.  
  497.         if (pKey) {
  498.             pKey->fdwFlags &= ~F_CAPTURED;
  499.  
  500.             if ((pKey->fdwFlags & F_STK) && (pKey->fdwFlags & F_DOWN)) {
  501.                 if (VK_CAPITAL == pKey->bVk) {
  502.                     g_pIMCallback->SendVirtualKey(pKey->bVk, KEYEVENTF_SILENT);
  503.                 }
  504.                 IM_PressKey (FALSE, pKey, &rcKey);
  505.             } else {
  506.                 IM_PressKey (TRUE, pKey, &rcKey);
  507.                 if (VK_CAPITAL == pKey->bVk) {
  508.                     g_pIMCallback->SendVirtualKey(pKey->bVk,
  509.                         KEYEVENTF_SILENT | KEYEVENTF_KEYUP );
  510.                     //Now, get the CAPS lock mode bitmap up
  511.                     IM_SwitchBitmap();
  512.                 }
  513.             }
  514.  
  515.  
  516.             if( !(pKey->fdwFlags & F_STK) ) {
  517.                 //Not a sticky key, so unpress this guy please
  518.                 IM_PressKey( FALSE, pKey, &rcKey );
  519.                 pKey = NULL;
  520.             }
  521.         }
  522.         ReleaseCapture();
  523.         break;
  524.  
  525.     case WM_LBUTTONDBLCLK:
  526.         RETAILMSG (ZONE_MOUSE, (TEXT("Got WM_LBUTTONDBCLK\r\n")));
  527.         rcKey.left = LOWORD(lParam);
  528.         rcKey.top = HIWORD(lParam);
  529.         pKey = IM_GetKeyFromCoord( &rcKey );
  530.         SetCapture(hwnd);
  531.         if (pKey->fdwFlags & F_STK) {
  532.             //For sticky keys, we need to remember that we got a double click
  533.             //and BLOW OFF the ensuing WM_LBUTTONUP.  This will allow them to
  534.             //stay down.  For normal keys, processing the ensuing button up
  535.             //allows us to get a key for the double click.
  536.             fDblClk = TRUE;
  537.         } else {
  538.             IM_DrawKey(pKey, &rcKey, TRUE);
  539.         }
  540.  
  541. #if 0
  542.         // LARGEKB doesn't really support shift lock state.  This would be used if you wanted to have a different
  543.         // handling of keys like the numeric keys.  On most keyboards CAPS lock does not affect the numeric values
  544.         // This simplistic keyboard shiftlock and capslock are the same.
  545.         switch (pKey->bVk) {
  546.         case VK_SHIFT:
  547.             if (pKey->fdwFlags & F_DOWN) {
  548.                 //Shift key is down, unpress it
  549.                 g_pIMCallback->SendVirtualKey(VK_SHIFT, KEYEVENTF_KEYUP | KEYEVENTF_SILENT);
  550.                 g_nDown--;
  551.             }
  552.             pKey->fdwFlags |= F_DOWN;
  553.             g_fShiftDown = TRUE;
  554.  
  555.             g_nDown++;  //When in CAPS LOCK mode, we'll consider the key "down" for painting purposes.
  556.             g_pIMCallback->SendVirtualKey(VK_CAPITAL, KEYEVENTF_SILENT);
  557.             g_pIMCallback->SendVirtualKey(VK_CAPITAL, KEYEVENTF_KEYUP | KEYEVENTF_SILENT);
  558.             //Now, get the CAPS lock mode bitmap up
  559.             IM_SwitchBitmap();
  560.             break;
  561.         }
  562. #endif
  563.         break;
  564.     }
  565.     return 0;
  566. }
  567.  
  568.  
  569. //
  570. // Main window procedure.
  571. //
  572. LRESULT WINAPI
  573. ImWndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
  574. {
  575. //    RETAILMSG (ZONE_FUNCTION, (TEXT("+ImWndProc(0x%08X, 0x%08X, 0x%08X, 0x%08X)\r\n"), hwnd, msg, wParam, lParam));
  576.  
  577.     PAINTSTRUCT ps;
  578.  
  579.     switch( msg )
  580.     {
  581.  
  582.     case WM_PAINT:
  583.         BeginPaint( hwnd, &ps );
  584.         IM_DrawArea( ps.hdc, &ps.rcPaint );
  585.         EndPaint( hwnd, &ps );
  586.         return 0;
  587.  
  588.     case WM_LBUTTONDOWN:
  589.     case WM_LBUTTONUP:
  590.     case WM_MOUSEMOVE:
  591.     case WM_LBUTTONDBLCLK:
  592.         return IM_OnMouseEvent( hwnd, msg, wParam, lParam );
  593.  
  594.     } // switch( message )
  595.  
  596.     return DefWindowProc( hwnd, msg, wParam, lParam );
  597. }
  598.  
  599.  
  600. //
  601. // At startup, set our keystate for all of our keys to up.
  602. // We rely on the SIP manager to lift all sticky/modifier keys, and to turn
  603. // caps lock off, before selecting a new IM.
  604. //
  605.  
  606.  
  607. //
  608. // IInputMethod implementation.
  609. //
  610.  
  611.  
  612. //
  613. // Ctor, Dtor.
  614. //
  615.  
  616. CInputMethod::CInputMethod( IUnknown *pUnkOuter, HINSTANCE hInstance )
  617. {
  618.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::CInputMethod(0x%08X, 0x%08X)\r\n"), pUnkOuter, hInstance));
  619.  
  620.  
  621.     m_cRef = 0;
  622.     g_dwObjectCount++;
  623.  
  624.     if( !pUnkOuter ) {
  625.         m_pUnkOuter = this;
  626.     } else {
  627.         m_pUnkOuter = pUnkOuter;
  628.     }
  629.  
  630.     return;
  631. }
  632.  
  633. CInputMethod::~CInputMethod()
  634. {
  635.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::~CInputMethod()\r\n")));
  636.     g_dwObjectCount--;
  637.     return;
  638. }
  639.  
  640.  
  641. //
  642. // IInputMethod methods.
  643. //
  644.  
  645. STDMETHODIMP CInputMethod::Select( HWND hwndSip )
  646. {
  647.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::Select(0x%08X)\r\n"), hwndSip));
  648.     WNDCLASS wc;
  649. //    UINT uKB;
  650.  
  651.     RETAILMSG (ZONE_KEYS, (TEXT("CInputMethod::Select\r\n")));
  652.  
  653.     ZeroMemory( &wc, sizeof(wc) );
  654.     wc.style = CS_DBLCLKS;
  655.     wc.lpfnWndProc = ImWndProc;
  656.     wc.hInstance = g_hInstDll;
  657.     wc.hbrBackground = NULL;
  658.     wc.lpszClassName = g_pwszClassName;
  659.  
  660.     if( !RegisterClass( &wc ) ) {
  661.         return E_FAIL;
  662.     }
  663.  
  664.     g_hdcKeybd = CreateCompatibleDC( NULL );
  665.  
  666.     g_hbmKeybd = LoadBitmap (g_hInstDll, MAKEINTRESOURCE(IDB_KEYBD));
  667.     g_hbmOld = (HBITMAP)SelectObject (g_hdcKeybd, g_hbmKeybd);
  668.  
  669.     g_hwndMain = CreateWindow(
  670.                         g_pwszClassName,
  671.                         TEXT(""),
  672.                         WS_CHILD,
  673.                         0,
  674.                         0,
  675.                         10,
  676.                         10,
  677.                         hwndSip,
  678.                         (HMENU)NULL,
  679.                         g_hInstDll,
  680.                         NULL );
  681.  
  682.     InvalidateRect(g_hwndMain, NULL, TRUE);
  683.     UpdateWindow(g_hwndMain);
  684.     ShowWindow( g_hwndMain, SW_SHOWNOACTIVATE );
  685.     return NOERROR;
  686. }
  687.  
  688.  
  689. STDMETHODIMP CInputMethod::Deselect( void )
  690. {
  691.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::Deselect()\r\n")));
  692.     SelectObject( g_hdcKeybd, g_hbmOld );
  693.     DeleteObject( g_hbmKeybd );
  694.     DeleteDC( g_hdcKeybd );
  695.     DestroyWindow( g_hwndMain );
  696.     UnregisterClass( g_pwszClassName, g_hInstDll );
  697.     return NOERROR;
  698. }
  699.  
  700.  
  701. STDMETHODIMP CInputMethod::Showing( void )
  702. {
  703.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::Showing()\r\n")));
  704.     IM_SwitchBitmap ();
  705.     return NOERROR;
  706. }
  707.  
  708.  
  709. STDMETHODIMP CInputMethod::Hiding( void )
  710. {
  711.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::Hiding()\r\n")));
  712.     return NOERROR;
  713. }
  714.  
  715.  
  716. STDMETHODIMP CInputMethod::GetInfo( IMINFO *pimi )
  717. {
  718.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::GetInfo()\r\n")));
  719.     pimi->fdwFlags = SIPF_DOCKED;
  720.     pimi->hImageNarrow = (HANDLE)NULL;
  721.     pimi->hImageWide = (HANDLE)NULL;
  722.     pimi->iNarrow = pimi->iWide = 0;
  723.     pimi->rcSipRect.right  = pimi->rcSipRect.left + 560; ////////////////////////////////////////////
  724.     pimi->rcSipRect.bottom = pimi->rcSipRect.top  + 200; /////////////////////////////////////////////
  725.  
  726.     if (g_pIMCallback)
  727.     {
  728.         g_pIMCallback->SetImInfo(pimi);
  729.     }
  730.  
  731.     InvalidateRect(g_hwndMain, NULL, TRUE);
  732.     UpdateWindow(g_hwndMain);
  733.     return NOERROR;
  734. }
  735.  
  736.  
  737. STDMETHODIMP CInputMethod::ReceiveSipInfo( SIPINFO *psi )
  738. {
  739.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::ReceiveSipInfo()\r\n")));
  740.  
  741.     RETAILMSG (ZONE_KEYS, (TEXT("MIM: ReceiveSipInfo!!!  ltrb: %d %d %d %d\r\n"), psi->rcSipRect.left,
  742.                    psi->rcSipRect.top,
  743.                    psi->rcSipRect.right,
  744.                    psi->rcSipRect.bottom));
  745.     MoveWindow(
  746.         g_hwndMain,
  747.         0,
  748.         0,
  749.         psi->rcSipRect.right - psi->rcSipRect.left,
  750.         psi->rcSipRect.bottom - psi->rcSipRect.top,
  751.         FALSE );
  752.  
  753.     return NOERROR;
  754. }
  755.  
  756.  
  757. STDMETHODIMP CInputMethod::RegisterCallback( IIMCallback *pIMCallback )
  758. {
  759.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::RegisterCallback(0x%08X)\r\n"), pIMCallback));
  760.     g_pIMCallback = pIMCallback;
  761.     return NOERROR;
  762. }
  763.  
  764.  
  765. STDMETHODIMP CInputMethod::GetImData( DWORD dwSize, void *pvImData )
  766. {
  767.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::GetImData(%d, 0x%08X)\r\n"), dwSize, pvImData));
  768.     return E_NOTIMPL;
  769. }
  770.  
  771.  
  772. STDMETHODIMP CInputMethod::SetImData( DWORD dwSize, void *pvImData )
  773. {
  774.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::SetImData(%d, 0x%08X)\r\n"), dwSize, pvImData));
  775.  
  776.     return NOERROR;
  777. }
  778.  
  779.  
  780. STDMETHODIMP CInputMethod::UserOptionsDlg( HWND hwndParent )
  781. {
  782.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::UserOptionsDlg(0x%08X)\r\n"), hwndParent));
  783.     return E_NOTIMPL;
  784. }
  785.  
  786.  
  787. //
  788. // IUnknown methods.
  789. //
  790.  
  791. STDMETHODIMP CInputMethod::QueryInterface( REFIID riid, LPVOID FAR* ppobj )
  792. {
  793.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::QueryInterface(0x%08X, 0x%08X)\r\n"), riid, ppobj));
  794.  
  795.     if( IID_IUnknown == riid || IID_IInputMethod == riid ) {
  796.         *ppobj = this;
  797.         AddRef();
  798.         return NOERROR;
  799.     }
  800.     RETAILMSG (ZONE_ERROR, (TEXT("CInputMethod::QueryInterface : Error Ret\r\n")));
  801.     return E_NOINTERFACE;
  802. }
  803.  
  804. STDMETHODIMP_(ULONG) CInputMethod::AddRef( void )
  805. {
  806.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::AddRef()\r\n")));
  807.     return ++m_cRef;
  808. }
  809.  
  810. STDMETHODIMP_(ULONG) CInputMethod::Release( void )
  811. {
  812.     RETAILMSG (ZONE_FUNCTION, (TEXT("+CInputMethod::Release()\r\n")));
  813.  
  814.     if( --m_cRef ) {
  815.         return m_cRef;
  816.     }
  817.     delete this;
  818.     return 0;
  819. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement