home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winui / input / ime / imeapps / comp.c next >
Encoding:
C/C++ Source or Header  |  1997-09-11  |  14.0 KB  |  516 lines

  1. /**********************************************************************/
  2. /*                                                                    */
  3. /*      COMP.C                                                        */
  4. /*                                                                    */
  5. /*      Copyright (c) 1995-1997  Microsoft Corporation                */
  6. /*                                                                    */
  7. /**********************************************************************/
  8.  
  9. #include "windows.h"
  10. #include "imm.h"
  11. #include "resource.h"
  12. #include "imeapps.h"
  13.  
  14. #define DEBUG 1
  15.  
  16. LRESULT HandleStartComposition(HWND hWnd,WPARAM wParam,LPARAM lParam)
  17. {
  18.     COMPOSITIONFORM cpf;
  19.     HIMC hIMC;
  20.  
  21. #ifdef DEBUG
  22.     OutputDebugString("WM_STARTCOMPOSITIONSTRING!!!\r\n");
  23. #endif
  24.  
  25.     if (fdwProperty & IME_PROP_SPECIAL_UI)
  26.     {
  27.         // Normally, we need to set the composition window
  28.         // position to caret position for a special UI IME
  29.     }
  30.     else if (fdwProperty & IME_PROP_AT_CARET)
  31.     {
  32.         // If an application show composition string by itself, we do not
  33.         // need to set the position of composition window for an at caret
  34.         // IME.
  35.  
  36.         return 1;
  37.     }
  38.     else
  39.     {
  40.         // Normally, we need to set the composition window
  41.         // position to caret position for a near caret IME
  42.     }
  43.  
  44.     hIMC = ImmGetContext(hWnd);
  45.  
  46.     if (!hIMC)
  47.     {
  48.         return 1;
  49.     }
  50.  
  51.     cpf.dwStyle = CFS_POINT;
  52.     cpf.ptCurrentPos.x = ptImeUIPos.x;
  53.     cpf.ptCurrentPos.y = ptImeUIPos.y;
  54.  
  55.     ImmSetCompositionWindow(hIMC,&cpf);
  56.  
  57.     ImmReleaseContext(hWnd,hIMC);
  58.  
  59.     return 1;
  60. }
  61.  
  62. LRESULT HandleEndComposition(HWND hWnd,WPARAM wParam,LPARAM lParam)
  63. {
  64. #ifdef DEBUG
  65.     OutputDebugString("WM_ENDCOMPOSITIONSTRING!!!\r\n");
  66. #endif
  67.     dwCompStrLen      = 0;
  68.     dwCompAttrLen     = 0;
  69.     dwCompClsLen      = 0;
  70.     dwCompReadStrLen  = 0;
  71.     dwCompReadAttrLen = 0;
  72.     dwCompReadClsLen  = 0;
  73.     dwResultStrLen      = 0;
  74.     dwResultClsLen      = 0;
  75.     dwResultReadStrLen  = 0;
  76.     dwResultReadClsLen  = 0;
  77.     InvalidateRect(hWnd,NULL,TRUE);
  78.  
  79.     return 1;
  80. }
  81.  
  82. void MakePaintString(HWND hWnd, LPMYSTR lpStr,DWORD dwStrLen,LPDWORD lpCls,DWORD dwClsLen,LPMYSTR lpPaintStr)
  83. {
  84.     LPMYSTR lpPaintStart = lpPaintStr;
  85.  
  86.     lpPaintStr += Mylstrlen(lpPaintStr);
  87.  
  88.     if (dwStrLen)
  89.     {
  90.         if (dwClsLen)
  91.         {
  92.             lpCls[127] = 0;
  93.  
  94.             while (*(lpCls+1) && *lpCls < dwStrLen)
  95.             {
  96.                 DWORD dwTextLen = *(lpCls+1) - *lpCls;
  97.                 LPMYSTR lpT = lpStr + *lpCls;
  98.  
  99.                 memcpy(lpPaintStr,lpT,dwTextLen * sizeof(MYCHAR));
  100.                 lpPaintStr += dwTextLen;
  101.                 *lpPaintStr = MYTEXT(',');
  102.                 lpPaintStr++;
  103.                 lpCls++;
  104.             }
  105.             *lpPaintStr = MYTEXT('\0');
  106.         }
  107.         else
  108.         {
  109.             Mylstrcpy(lpPaintStr,lpStr);
  110.             Mylstrcat(lpPaintStr,MYTEXT(","));
  111.         }
  112.     }
  113.  
  114. }
  115.  
  116. LRESULT HandleComposition(HWND hWnd,WPARAM wParam,LPARAM lParam)
  117. {
  118.     HIMC hIMC;
  119.     BOOL fRedraw = FALSE;
  120.  
  121.     hIMC = ImmGetContext(hWnd);
  122.  
  123.     if (lParam & GCS_COMPSTR)
  124.     {
  125.         dwCompStrLen = MyImmGetCompositionString(hIMC,GCS_COMPSTR,szCompStr,sizeof(szCompStr));
  126.         dwCompStrLen /= sizeof(MYCHAR);
  127.         szCompStr[dwCompStrLen] = MYTEXT('\0');
  128.         fRedraw = TRUE;
  129.     }
  130.     else
  131.     {
  132.         dwCompStrLen = 0;
  133.         szCompStr[0] = MYTEXT('\0');
  134.     }
  135.  
  136.     if (lParam & GCS_COMPATTR)
  137.     {
  138.         dwCompAttrLen = MyImmGetCompositionString(hIMC,GCS_COMPATTR,bCompAttr,sizeof(bCompAttr));
  139.         fRedraw = TRUE;
  140.     }
  141.     else
  142.     {
  143.         dwCompAttrLen = 0;
  144.         bCompAttr[0] = 0;
  145.     }
  146.  
  147.     if (lParam & GCS_COMPCLAUSE)
  148.     {
  149.         dwCompClsLen = MyImmGetCompositionString(hIMC,GCS_COMPCLAUSE,dwCompCls,sizeof(dwCompCls));
  150.         fRedraw = TRUE;
  151.     }
  152.     else
  153.     {
  154.         dwCompClsLen = 0;
  155.         dwCompCls[0] = 0;
  156.         dwCompCls[1] = 0;
  157.     }
  158.  
  159.  
  160.     if (lParam & GCS_COMPREADSTR)
  161.     {
  162.         dwCompReadStrLen = MyImmGetCompositionString(hIMC,GCS_COMPREADSTR,szCompReadStr,sizeof(szCompReadStr));
  163.         dwCompReadStrLen /= sizeof(MYCHAR);
  164.         szCompReadStr[dwCompReadStrLen] = MYTEXT('\0');
  165.         fRedraw = TRUE;
  166.     }
  167.     else
  168.     {
  169.         dwCompReadStrLen = 0;
  170.         szCompReadStr[0] = MYTEXT('\0');
  171.     }
  172.  
  173.     if (lParam & GCS_COMPREADATTR)
  174.     {
  175.         dwCompReadAttrLen = MyImmGetCompositionString(hIMC,GCS_COMPREADATTR,bCompReadAttr,sizeof(bCompReadAttr));
  176.         fRedraw = TRUE;
  177.     }
  178.     else
  179.     {
  180.         dwCompReadAttrLen = 0;
  181.         bCompReadAttr[0] = 0;
  182.     }
  183.  
  184.     if (lParam & GCS_COMPREADCLAUSE)
  185.     {
  186.         dwCompReadClsLen = MyImmGetCompositionString(hIMC,GCS_COMPREADCLAUSE,dwCompReadCls,sizeof(dwCompReadCls));
  187.         fRedraw = TRUE;
  188.     }
  189.     else
  190.     {
  191.         dwCompReadClsLen = 0;
  192.         dwCompReadCls[0] = 0;
  193.         dwCompReadCls[1] = 0;
  194.     }
  195.  
  196.  
  197.     if (lParam & GCS_RESULTSTR)
  198.     {
  199.         RECT rc;
  200.         HDC hIC;
  201.         SIZE sz0,sz1;
  202.         HFONT hOldFont;
  203.  
  204.         if (lParam & GCS_RESULTCLAUSE)
  205.         {
  206.             dwResultClsLen = MyImmGetCompositionString(hIMC,GCS_RESULTCLAUSE,dwResultCls,sizeof(dwResultCls));
  207.         }
  208.         else
  209.         {
  210.             dwResultClsLen = 0;
  211.             dwResultCls[0] = 0;
  212.             dwResultCls[1] = 0;
  213.         }
  214.  
  215.         dwResultStrLen = MyImmGetCompositionString(hIMC,GCS_RESULTSTR,szResultStr,sizeof(szResultStr));
  216.         dwResultStrLen /= sizeof(MYCHAR);
  217.         szResultStr[dwResultStrLen] = MYTEXT('\0');
  218.  
  219.  
  220.         // szPaintResult may overflow..
  221.         GetClientRect(hWnd,&rc);
  222.         hIC = CreateIC("DISPLAY", NULL, NULL, NULL);
  223.         hOldFont = SelectObject(hIC,hFont);
  224. #ifdef USEWAPI
  225.         GetTextExtentPointW(hIC,szPaintResult,Mylstrlen(szPaintResult),&sz0);
  226.         GetTextExtentPointW(hIC,szResultStr,Mylstrlen(szResultStr),&sz1);
  227. #else
  228.         GetTextExtentPoint(hIC,szPaintResult,Mylstrlen(szPaintResult),&sz0);
  229.         GetTextExtentPoint(hIC,szResultStr,Mylstrlen(szResultStr),&sz1);
  230. #endif
  231.         if (sz0.cx + sz1.cx >= rc.right)
  232.         {
  233.             szPaintResult[0] = MYTEXT('\0');
  234.             szPaintResultRead[0] = MYTEXT('\0');
  235.         }
  236.         SelectObject(hIC,hOldFont);
  237.         DeleteDC(hIC);
  238.  
  239.         MakePaintString(hWnd,szResultStr,dwResultStrLen,dwResultCls,dwResultClsLen,szPaintResult);
  240.  
  241.         fRedraw = TRUE;
  242.     }
  243.     else
  244.     {
  245.         dwResultStrLen = 0;
  246.         szResultStr[0] = MYTEXT('\0');
  247.         dwResultClsLen = 0;
  248.         dwResultCls[0] = 0;
  249.         dwResultCls[1] = 0;
  250.     }
  251.  
  252.  
  253.  
  254.     if (lParam & GCS_RESULTREADSTR)
  255.     {
  256.         if (lParam & GCS_RESULTREADCLAUSE)
  257.         {
  258.             dwResultReadClsLen = MyImmGetCompositionString(hIMC,GCS_RESULTREADCLAUSE,dwResultReadCls,sizeof(dwResultReadCls));
  259.             fRedraw = TRUE;
  260.         }
  261.         else
  262.         {
  263.             dwResultReadClsLen = 0;
  264.             dwResultReadCls[0] = 0;
  265.             dwResultReadCls[1] = 0;
  266.         }
  267.         dwResultReadStrLen = MyImmGetCompositionString(hIMC,GCS_RESULTREADSTR,szResultReadStr,sizeof(szResultReadStr));
  268.         dwResultReadStrLen /= sizeof(MYCHAR);
  269.         szResultReadStr[dwResultReadStrLen] = MYTEXT('\0');
  270.         MakePaintString(hWnd,szResultReadStr,dwResultReadStrLen,dwResultReadCls,dwResultReadClsLen,szPaintResultRead);
  271.         fRedraw = TRUE;
  272.     }
  273.     else
  274.     {
  275.         dwResultReadStrLen = 0;
  276.         szResultReadStr[0] = MYTEXT('\0');
  277.         dwResultReadClsLen = 0;
  278.         dwResultReadCls[0] = 0;
  279.         dwResultReadCls[1] = 0;
  280.     }
  281.  
  282.  
  283.  
  284.     if (fRedraw)
  285.     {
  286.         InvalidateRect(hWnd,NULL,TRUE);
  287.         UpdateWindow(hWnd);
  288.     }
  289.     return 1;
  290. }
  291.  
  292.  
  293. LRESULT HandleChar(HWND hWnd,WPARAM wParam,LPARAM lParam)
  294. {
  295.     RECT rc;
  296.     HDC hIC;
  297.     SIZE sz0,sz1;
  298.     HFONT hOldFont;
  299.     LPMYSTR lp;
  300.     // is the previous received char is a DBCS lead byte char ?
  301.     static BOOL fIsPrevLeadByte = FALSE;
  302.  
  303.     GetClientRect(hWnd,&rc);
  304.     hIC = CreateIC("DISPLAY", NULL, NULL, NULL);
  305.     hOldFont = SelectObject(hIC,hFont);
  306. #ifdef USEWAPI
  307.     GetTextExtentPointW(hIC,szPaintResult,Mylstrlen(szPaintResult),&sz0);
  308.     GetTextExtentPointW(hIC,szResultStr,Mylstrlen(szResultStr),&sz1);
  309. #else
  310.     GetTextExtentPoint(hIC,szPaintResult,Mylstrlen(szPaintResult),&sz0);
  311.     GetTextExtentPoint(hIC,szResultStr,Mylstrlen(szResultStr),&sz1);
  312. #endif
  313.     if (sz0.cx + sz1.cx >= rc.right)
  314.     {
  315.         szPaintResult[0] = MYTEXT('\0');
  316.         szPaintResultRead[0] = MYTEXT('\0');
  317.     }
  318.     SelectObject(hIC,hOldFont);
  319.     DeleteDC(hIC);
  320.  
  321.     lp = szPaintResult + Mylstrlen(szPaintResult);
  322.  
  323. #ifndef USEWAPI
  324.     if (fIsPrevLeadByte) {
  325.         // remove , and append second byte for showing DBCS char
  326.         if (*(lp - 1) == ',') {
  327.             lp--;
  328.         }
  329.     }
  330. #endif
  331.  
  332.     // append second byte
  333.     *lp++ = (MYCHAR)(BYTE)wParam;
  334.     *lp++ = MYTEXT(',');
  335.     *lp++ = MYTEXT('\0');
  336.  
  337.     lp = szPaintResultRead + Mylstrlen(szPaintResultRead);
  338.  
  339. #ifndef USEWAPI
  340.     if (fIsPrevLeadByte) {
  341.         // remove , and append second byte for showing DBCS char
  342.         if (*(lp - 1) == ',') {
  343.             lp--;
  344.         }
  345.  
  346.         fIsPrevLeadByte = FALSE;
  347.     } else {
  348.         fIsPrevLeadByte = IsDBCSLeadByte((BYTE)wParam);
  349.     }
  350. #endif
  351.  
  352.     *lp++ = (BYTE)wParam;
  353.     *lp++ = MYTEXT(',');
  354.     *lp++ = MYTEXT('\0');
  355.  
  356.     InvalidateRect(hWnd,NULL,TRUE);
  357.     UpdateWindow(hWnd);
  358.  
  359.     return 1;
  360. }
  361.  
  362.  
  363. LRESULT HandleNotify(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
  364. {
  365.     HIMC hIMC;
  366.     BOOL fOpen;
  367.     DWORD dwConvMode,dwSentMode;
  368.  
  369.  
  370.     switch (wParam)
  371.     {
  372.         case IMN_OPENSTATUSWINDOW:
  373.         case IMN_CLOSESTATUSWINDOW:
  374.             break;
  375.  
  376.         case IMN_SETOPENSTATUS:
  377.             SetStatusItems(hWnd);
  378.  
  379.             hIMC = ImmGetContext(hWnd);
  380.             fOpen = ImmGetOpenStatus(hIMC);
  381.             UpdateShowOpenStatusButton(fOpen);
  382.  
  383.             ImmReleaseContext(hWnd,hIMC);
  384.             break;
  385.  
  386.         case IMN_SETCONVERSIONMODE:
  387.             hIMC = ImmGetContext(hWnd);
  388.             fOpen = ImmGetOpenStatus(hIMC);
  389.             ImmGetConversionStatus(hIMC,&dwConvMode,&dwSentMode);
  390.             if (fOpen)
  391.             {
  392.                 SetConvModeParts(dwConvMode);
  393.                 UpdateModeButton(dwConvMode);
  394.             }
  395.             else
  396.                 ClearConvModeParts();
  397.             ImmReleaseContext(hWnd,hIMC);
  398.             break;
  399.  
  400.         case IMN_OPENCANDIDATE:
  401.             if (!fShowCand || (lParam != 0x01))
  402.             {
  403.                 if (fdwProperty & IME_PROP_SPECIAL_UI)
  404.                 {
  405.                     // Normally, we only need to set the composition window
  406.                     // position for a special UI IME
  407.                 }
  408.                 else if (fdwProperty & IME_PROP_AT_CARET)
  409.                 {
  410.                     CANDIDATEFORM cdf;
  411.                     HIMC          hIMC;
  412.  
  413.                     hIMC = ImmGetContext(hWnd);
  414.  
  415.                     cdf.dwIndex = 0;
  416.                     cdf.dwStyle = CFS_CANDIDATEPOS;
  417.                     cdf.ptCurrentPos.x = ptImeUIPos.x;
  418.                     cdf.ptCurrentPos.y = ptImeUIPos.y;
  419.                     ImmSetCandidateWindow(hIMC,&cdf);
  420.  
  421.                     ImmReleaseContext(hWnd,hIMC);
  422.                 }
  423.                 else
  424.                 {
  425.                     // Normally, we only need to set the composition window
  426.                     // position for a near caret IME
  427.                 }
  428.  
  429.                 return (DefWindowProc(hWnd, message, wParam, lParam));
  430.             }
  431.  
  432.         case IMN_CHANGECANDIDATE:
  433.  
  434. #ifdef _DEBUG
  435. {
  436. char szDev[80];
  437. DWORD dwSize;
  438. LPCANDIDATELIST lpC;
  439.  
  440. hIMC = ImmGetContext(hWnd);
  441. if (dwSize = ImmGetCandidateList(hIMC,0x0,NULL,0))
  442. {
  443.     lpC = (LPCANDIDATELIST)GlobalAlloc(GPTR,dwSize);
  444.    
  445.     ImmGetCandidateList(hIMC,0x0,lpC,dwSize);
  446.  
  447.     OutputDebugString("DumpCandList!!!\r\n");
  448.     wsprintf((LPSTR)szDev,"dwCount %d\r\n",lpC->dwCount);
  449.     OutputDebugString((LPSTR)szDev);
  450.     wsprintf((LPSTR)szDev,"dwSelection %d\r\n",lpC->dwSelection);
  451.     OutputDebugString((LPSTR)szDev);
  452.     wsprintf((LPSTR)szDev,"dwPageStart %d\r\n",lpC->dwPageStart);
  453.     OutputDebugString((LPSTR)szDev);
  454.     wsprintf((LPSTR)szDev,"dwPageSize %d\r\n",lpC->dwPageSize);
  455.     OutputDebugString((LPSTR)szDev);
  456.     GlobalFree((HANDLE)lpC);
  457. }
  458. }
  459. #endif
  460.             if (fShowCand && (lParam == 0x01))
  461.             {
  462.                 DWORD dwSize;
  463.  
  464.                 if (!lpCandList)
  465.                     lpCandList = (LPCANDIDATELIST)GlobalAlloc(GPTR,sizeof(CANDIDATELIST));
  466.  
  467.                 hIMC = ImmGetContext(hWnd);
  468.                 if (dwSize = ImmGetCandidateList(hIMC,0x0,NULL,0))
  469.                 {
  470.                     GlobalFree((HANDLE)lpCandList);
  471.                     lpCandList = (LPCANDIDATELIST)GlobalAlloc(GPTR,dwSize);
  472.                    
  473.                     ImmGetCandidateList(hIMC,0x0,lpCandList,dwSize);
  474.  
  475.                 }
  476.                 else
  477.                 {
  478.                     memset(lpCandList, 0, sizeof(CANDIDATELIST));
  479.                 }
  480.  
  481.                 InvalidateRect(hWndCandList,NULL,TRUE);
  482.                 UpdateWindow(hWndCandList);
  483.                     
  484.  
  485.                 ImmReleaseContext(hWnd,hIMC);
  486.             }
  487.             else
  488.             {
  489.                 return (DefWindowProc(hWnd, message, wParam, lParam));
  490.             }
  491.             break;
  492.  
  493.         case IMN_CLOSECANDIDATE:
  494.             if (fShowCand && (lParam == 0x01))
  495.             {
  496.                 if (!lpCandList)
  497.                     lpCandList = (LPCANDIDATELIST)GlobalAlloc(GPTR,sizeof(CANDIDATELIST));
  498.  
  499.                 memset(lpCandList, 0, sizeof(CANDIDATELIST));
  500.                 InvalidateRect(hWndCandList,NULL,TRUE);
  501.                 UpdateWindow(hWndCandList);
  502.             }
  503.             else
  504.             {
  505.                 return (DefWindowProc(hWnd, message, wParam, lParam));
  506.             }
  507.             break;
  508.  
  509.  
  510.        default:
  511.             return (DefWindowProc(hWnd, message, wParam, lParam));
  512.     }
  513.  
  514.     return 0;
  515. }
  516.