Statusui.pas
上传用户:wen198501
上传日期:2013-04-01
资源大小:335k
文件大小:20k
源码类别:

输入法编程

开发平台:

Delphi

  1.  {******************************************************}
  2.  {                                                      }
  3.  {    Copyright (c) 1990-1999 Microsoft Corporation     }
  4.  {                                                      }
  5.  {    Module Name:  Statusui.c ->>  Statusui.pas        }
  6.  {                                                      }
  7.  {    Translator:  Liu_mazi@126.com, 2005-11-16         }
  8.  {                                                      }
  9.  {******************************************************}
  10. unit Statusui;
  11. {$I Define.Inc}
  12. interface
  13. uses Windows;
  14. function GetStatusWnd(hUIWnd: hWnd): hWnd; // 返回Status窗口句柄
  15. function StatusWndProc(hStatusWnd: hWnd; uMsg: uInt; wParam: WParam; lParam: LParam): LResult; stdcall; // Status窗口回调
  16. function ImeVerDlgProc(hDlg: hWnd; uMessage: uInt; wParam: WParam; lParam: LParam): Bool; stdcall; // 版本对话框回调
  17. procedure OpenStatus(hUIWnd: hWnd);  // "打开"Status窗口
  18. procedure ShowStatus(hUIWnd: hWnd; nShowStatusCmd: Integer); // 显示隐藏Status窗口
  19. implementation
  20. uses Messages, ImmDev, ImeDefs, Data, DDIS, Uisubs, Ui, LogText;
  21.   // 返回Status窗口句柄
  22. function GetStatusWnd(hUIWnd: hWnd): hWnd;
  23. var
  24.   hUIPrivate: hGlobal;
  25.   lpUIPrivate: PUIPriv;
  26. begin
  27.   Result := 0;
  28.   hUIPrivate := GetWindowLong(hUIWnd, IMMGWLP_PRIVATE);
  29.   if (hUIPrivate = 0) then Exit;     // can not darw status window
  30.   lpUIPrivate := GlobalLock(hUIPrivate);
  31.   if (lpUIPrivate = nil) then Exit;  // can not draw status window
  32.   Result := lpUIPrivate.hStatusWnd;
  33.   GlobalUnlock(hUIPrivate);
  34. end;
  35.   // 调整Status窗口位置
  36. procedure AdjustStatusBoundary(lppt: PSmallPoint; hUIWnd: hWnd);
  37. var
  38.   Comp_CandWndLen: Integer;
  39. begin
  40.   // boundary check ..
  41.   if (lppt.x < sImeG.rcWorkArea.Left) then
  42.     lppt.x := sImeG.rcWorkArea.Left
  43.   else
  44.     if (lppt.x + sImeG.xStatusWi > sImeG.rcWorkArea.Right) then
  45.       lppt.x := sImeG.rcWorkArea.Right - sImeG.xStatusWi;
  46.   if (lppt.y < sImeG.rcWorkArea.Top) then
  47.     lppt.y := sImeG.rcWorkArea.Top
  48.   else
  49.     if (lppt.y + sImeG.yStatusHi > sImeG.rcWorkArea.Bottom) then
  50.       lppt.y := sImeG.rcWorkArea.Bottom - sImeG.yStatusHi;
  51.   // 固定模式
  52.   if (sImeG.IC_Trace = 0) then
  53.   begin
  54.     Comp_CandWndLen := 0;
  55.     if (uStartComp <> 0) then Inc(Comp_CandWndLen, sImeL.xCompWi + UI_MARGIN);
  56.     if (uOpenCand <> 0) then Inc(Comp_CandWndLen, sImeG.xCandWi + UI_MARGIN);
  57.     if (lppt.x + sImeG.xStatusWi + Comp_CandWndLen > sImeG.rcWorkArea.Right) then
  58.       lppt.x := sImeG.rcWorkArea.Right - sImeG.xStatusWi - Comp_CandWndLen;
  59.   end;
  60. end;
  61.   // 设置Status窗口位置
  62. function SetStatusWindowPos(hStatusWnd: hWnd): LResult;
  63. var
  64.   hUIWnd: hWnd;
  65.   _hIMC: hIMC;
  66.   lpIMC: PInputContext;
  67.   ptPos: TSmallPoint;
  68. begin
  69.   Result := 1;
  70.   hUIWnd := GetWindow(hStatusWnd, GW_OWNER);
  71.   _hIMC := GetWindowLong(hUIWnd, IMMGWLP_IMC);
  72.   if (_hIMC = 0) then Exit;
  73.   lpIMC := ImmLockIMC(_hIMC);
  74.   if (lpIMC = nil) then Exit;
  75.   ptPos.x := lpIMC.ptStatusWndPos.x;
  76.   ptPos.y := lpIMC.ptStatusWndPos.y;
  77.   AdjustStatusBoundary(@ptPos, hUIWnd);
  78.   SetWindowPos(hStatusWnd, 0, ptPos.x, ptPos.y, 0, 0, SWP_NOACTIVATE or SWP_NOCOPYBITS or SWP_NOSIZE or SWP_NOZORDER);
  79.   ImmUnlockIMC(_hIMC);
  80.   Result := 0;
  81. end;
  82.   // 显示隐藏Status窗口
  83. procedure ShowStatus(hUIWnd: hWnd; nShowStatusCmd: Integer);
  84. var
  85.   hUIPrivate: hGlobal;
  86.   lpUIPrivate: PUIPriv;
  87. begin
  88.   hUIPrivate := GetWindowLong(hUIWnd, IMMGWLP_PRIVATE);
  89.   if (hUIPrivate = 0) then Exit;  // can not darw status window
  90.   lpUIPrivate := GlobalLock(hUIPrivate);
  91.   if (lpUIPrivate = nil) then Exit; // can not draw status window
  92.   if IsWindow(lpUIPrivate.hStatusWnd) and (lpUIPrivate.nShowStatusCmd <> nShowStatusCmd) then
  93.   begin
  94.     SystemParametersInfo(SPI_GETWORKAREA, 0, @sImeG.rcWorkArea, 0);
  95.     SetStatusWindowPos(lpUIPrivate.hStatusWnd);
  96.     ShowWindow(lpUIPrivate.hStatusWnd, nShowStatusCmd);
  97.     lpUIPrivate.nShowStatusCmd := nShowStatusCmd;
  98.   end;
  99.   GlobalUnlock(hUIPrivate);
  100. end;
  101.   // "打开"Status窗口
  102. procedure OpenStatus(hUIWnd: hWnd);
  103. var
  104.   hUIPrivate: hGlobal;
  105.   lpUIPrivate: PUIPriv;
  106.   _hIMC: hIMC;
  107.   lpIMC: PInputContext;
  108.   ptPos: TPoint;
  109. //  nShowStatusCmd: Integer;
  110. begin
  111.   hUIPrivate := GetWindowLong(hUIWnd, IMMGWLP_PRIVATE);
  112.   if (hUIPrivate = 0) then Exit;       // can not darw status window
  113.   lpUIPrivate := GlobalLock(hUIPrivate);
  114.   if (lpUIPrivate = nil) then Exit;    // can not draw status window
  115.   _hIMC := GetWindowLong(hUIWnd, IMMGWLP_IMC);
  116.   if (_hIMC = 0) then
  117.   begin
  118.     ptPos.x := sImeG.rcWorkArea.Left;
  119.     ptPos.y := sImeG.rcWorkArea.Bottom - sImeG.yStatusHi;
  120.     // nShowStatusCmd := SW_HIDE;
  121.   end else
  122.   begin
  123.     lpIMC := ImmLockIMC(_hIMC);
  124.     if (lpIMC <> nil) then
  125.     begin
  126.       if (lpIMC.ptStatusWndPos.x < sImeG.rcWorkArea.Left) then
  127.         lpIMC.ptStatusWndPos.x := sImeG.rcWorkArea.Left
  128.       else
  129.         if (lpIMC.ptStatusWndPos.x + sImeG.xStatusWi > sImeG.rcWorkArea.Right) then
  130.           lpIMC.ptStatusWndPos.x := sImeG.rcWorkArea.Right - sImeG.xStatusWi;
  131.       if (lpIMC.ptStatusWndPos.y < sImeG.rcWorkArea.Top) then
  132.         lpIMC.ptStatusWndPos.y := sImeG.rcWorkArea.Top
  133.       else
  134.         if (lpIMC.ptStatusWndPos.y + sImeG.yStatusHi > sImeG.rcWorkArea.Right) then
  135.           lpIMC.ptStatusWndPos.y := sImeG.rcWorkArea.Bottom - sImeG.yStatusHi;
  136.       if (sImeG.IC_Trace <> 0) then
  137.       begin
  138.         ptPos.x := lpIMC.ptStatusWndPos.x;
  139.         ptPos.y := lpIMC.ptStatusWndPos.y;
  140.       end else
  141.       begin
  142.         ptPos.x := sImeG.rcWorkArea.Left;
  143.         ptPos.y := sImeG.rcWorkArea.Bottom - sImeG.yStatusHi;
  144.       end;
  145.       ImmUnlockIMC(_hIMC);
  146.       // nShowStatusCmd := SW_SHOWNOACTIVATE;
  147.     end else
  148.     begin
  149.       ptPos.x := sImeG.rcWorkArea.Left;
  150.       ptPos.y := sImeG.rcWorkArea.Bottom - sImeG.yStatusHi;
  151.       // nShowStatusCmd := SW_HIDE;
  152.     end;
  153.   end;
  154.   if IsWindow(lpUIPrivate.hStatusWnd) then
  155.   begin
  156.     SetWindowPos(lpUIPrivate.hStatusWnd, 0, ptPos.x, ptPos.y, 0, 0, SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOZORDER);
  157.   end else
  158.   begin
  159.     lpUIPrivate.hStatusWnd := CreateWindowEx(WS_EX_WINDOWEDGE or WS_EX_DLGMODALFRAME, szStatusClassName, nil,
  160.       WS_POPUP or WS_DISABLED, ptPos.x, ptPos.y, sImeG.xStatusWi, sImeG.yStatusHi, hUIWnd, 0, HInstance, nil);
  161.     SetWindowLong(lpUIPrivate.hStatusWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
  162.     SetWindowLong(lpUIPrivate.hStatusWnd, UI_MOVE_XY, 0);
  163.   end;
  164.   lpUIPrivate.fdwSetContext := lpUIPrivate.fdwSetContext or ISC_OPEN_STATUS_WINDOW;
  165.   if (_hIMC <> 0) then ShowStatus(hUIWnd, SW_SHOWNOACTIVATE);
  166.   GlobalUnlock(hUIPrivate);
  167. end;
  168.   // WM_DESTROY消息处理
  169. procedure DestroyStatusWindow(hStatusWnd: hWnd);
  170. var
  171.   hUIWnd: hWnd;
  172.   hUIPrivate: hGlobal;
  173.   lpUIPrivate: PUIPriv;
  174. begin
  175.   if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) <> WINDOW_NOT_DRAG) then // undo the drag border
  176.   begin
  177.     DrawDragBorder(hStatusWnd, GetWindowLong(hStatusWnd, UI_MOVE_XY), GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  178.   end;
  179.   hUIWnd := GetWindow(hStatusWnd, GW_OWNER);
  180.   if (IsWindow(hUIWnd) = False) then Exit;
  181.   hUIPrivate := GetWindowLong(hUIWnd, IMMGWLP_PRIVATE);
  182.   if (hUIPrivate = 0) then Exit;         // can not darw status window
  183.   lpUIPrivate := GlobalLock(hUIPrivate);
  184.   if (lpUIPrivate = nil) then Exit;      // can not draw status window
  185.   lpUIPrivate.nShowStatusCmd := SW_HIDE;
  186.   lpUIPrivate.hStatusWnd := 0;
  187.   GlobalUnlock(hUIPrivate);
  188. end;
  189.   // WM_LBUTTONDOWN处理
  190. procedure SetStatus(hStatusWnd: hWnd; lpptCursor: PPoint);
  191. var
  192.   hUIWnd: hWnd;
  193.   _hIMC: hIMC;
  194.   lpIMC: PInputContext;
  195.   lpbKeyState: TKeyboardState;
  196.   dwConvMode, fdwConversion: DWord;
  197.   lpImcP: PPrivContext;
  198. begin
  199.   hUIWnd := GetWindow(hStatusWnd, GW_OWNER);
  200.   if (IsWindow(hUIWnd) = False) then Exit;
  201.   _hIMC := GetWindowLong(hUIWnd, IMMGWLP_IMC);
  202.   if (_hIMC = 0) then Exit;
  203.   lpIMC := ImmLockIMC(_hIMC);
  204.   if (lpIMC = nil) then Exit;
  205.   if (lpIMC.fOpen = False) then
  206.   begin
  207.     ImmSetOpenStatus(_hIMC, True);
  208.   end else
  209.     if PtInRect(sImeG.rcImeIcon, lpptCursor^) then // Ime图标..
  210.     begin
  211.       if (lpIMC.fdwConversion and (IME_CMODE_CHARCODE or IME_CMODE_EUDC) <> 0) then
  212.       begin  // change to native mode
  213.         fdwConversion := (lpIMC.fdwConversion or IME_CMODE_NATIVE) and not(IME_CMODE_CHARCODE or IME_CMODE_EUDC);
  214.       end else
  215.         if ((lpIMC.fdwConversion and IME_CMODE_NATIVE) <> 0) then
  216.         begin  // change to alphanumeric mode
  217.           fdwConversion := lpIMC.fdwConversion and not(IME_CMODE_CHARCODE or IME_CMODE_NATIVE or IME_CMODE_EUDC);
  218.         end else
  219.         begin
  220.           GetKeyboardState(lpbKeyState);
  221.           if ((lpbKeyState[VK_CAPITAL] and 1) <> 0) then
  222.           begin
  223.             keybd_event(VK_CAPITAL, $3A, KEYEVENTF_EXTENDEDKEY or 0, 0);  // Simulate a key press
  224.             keybd_event(VK_CAPITAL, $3A, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0);  // Simulate a key release
  225.           end;
  226.           fdwConversion := (lpIMC.fdwConversion or IME_CMODE_NATIVE) and not(IME_CMODE_CHARCODE or IME_CMODE_EUDC);
  227.           uCaps := 0;
  228.         end;
  229.       ImmSetConversionStatus(_hIMC, fdwConversion, lpIMC.fdwSentence);
  230.     end else
  231.       if PtInRect(sImeG.rcImeName, lpptCursor^) then  // 切换方式..
  232.       begin
  233.       end else
  234.         if PtInRect(sImeG.rcShapeText, lpptCursor^) then // 全角半角..
  235.         begin
  236.           if ((lpIMC.fdwConversion and IME_CMODE_CHARCODE) <> 0) or
  237.              ((lpIMC.fdwConversion and IME_CMODE_EUDC) <> 0) then
  238.           begin
  239.             MessageBeep($FFFFFFFF);
  240.           end else
  241.           begin
  242.             dwConvMode := lpIMC.fdwConversion xor IME_CMODE_FULLSHAPE;
  243.             ImmSetConversionStatus(_hIMC, dwConvMode, lpIMC.fdwSentence);
  244.           end;
  245.         end else
  246.           if PtInRect(sImeG.rcSymbol, lpptCursor^) then // 标点符号..
  247.           begin
  248.             if (lpIMC.fdwConversion and IME_CMODE_CHARCODE) <> 0 then MessageBeep($FFFFFFFF)
  249.             else begin
  250.               fdwConversion := lpIMC.fdwConversion xor IME_CMODE_SYMBOL;
  251.               ImmSetConversionStatus(_hIMC, fdwConversion, lpIMC.fdwSentence);
  252.             end;
  253.           end else
  254.             if PtInRect(sImeG.rcSKText, lpptCursor^) then // 软键盘..
  255.             begin
  256.               lpImcP := ImmLockIMCC(lpIMC.hPrivate);
  257.               if (lpImcP <> nil) then
  258.               begin
  259.                 if (sImeL.hSKMenu = 0) then sImeL.hSKMenu := LoadMenu(HInstance, 'SKMENU');
  260.                 sImeL.dwSKState[sImeL.dwSKWant] := sImeL.dwSKState[sImeL.dwSKWant] xor 1;
  261.                 fdwConversion := lpIMC.fdwConversion xor IME_CMODE_SOFTKBD;
  262.                 ImmSetConversionStatus(_hIMC, fdwConversion, lpIMC.fdwSentence);
  263.                 ImmUnlockIMCC(lpIMC.hPrivate);
  264.               end else
  265.                 MessageBeep($FFFFFFFF);
  266.             end else
  267.               MessageBeep($FFFFFFFF);
  268.   ImmUnlockIMC(_hIMC);
  269. end;
  270.   // WM_SETCURSOR处理
  271. procedure StatusSetCursor(hStatusWnd: hWnd; lParam: LParam);
  272. const {$J+}
  273.   fSoftkey: Bool = False;
  274.   fCmenu: Bool = False; {$J-}
  275. var
  276.   ptCursor, ptSavCursor: TPoint;
  277.   rcWnd: TRect;
  278. begin
  279.   if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) <> WINDOW_NOT_DRAG) then // 拖拽中..
  280.   begin
  281.     SetCursor(LoadCursor(0, IDC_SIZEALL));
  282.     Exit;
  283.   end;
  284.   GetCursorPos(ptCursor);
  285.   ptSavCursor := ptCursor;
  286.   ScreenToClient(hStatusWnd, ptCursor);
  287.   if PtInRect(sImeG.rcStatusText, ptCursor) then
  288.   begin
  289.     SetCursor(LoadCursor(HInstance, szHandCursor));
  290.     if (HiWord(lParam) = WM_LBUTTONDOWN) then // 左键按下
  291.     begin
  292.       SetStatus(hStatusWnd, @ptCursor);
  293.     end else
  294.       if (HiWord(lParam) = WM_RBUTTONUP) then // 右键按下
  295.       begin
  296.         if PtInRect(sImeG.rcSKText, ptCursor) then // 软键盘
  297.         begin
  298.           // configuration already bring up
  299.           if (fSoftkey) then Exit;
  300.           fSoftkey := True;
  301.           SoftkeyMenu(hStatusWnd, ptSavCursor.x, ptSavCursor.y);
  302.           fSoftkey := False;
  303.         end else
  304.         begin
  305.           // configuration already bring up
  306.           if (fCmenu) then Exit;
  307.           fCmenu := True;
  308.           ContextMenu(hStatusWnd, ptSavCursor.x, ptSavCursor.y);
  309.           fCmenu := False;
  310.         end;
  311.       end;
  312.   end else
  313.   begin
  314.     SetCursor(LoadCursor(0, IDC_SIZEALL));
  315.     if (HiWord(lParam) = WM_LBUTTONDOWN) then // start drag
  316.     begin
  317.       SystemParametersInfo(SPI_GETWORKAREA, 0, @sImeG.rcWorkArea, 0);
  318.       SetCapture(hStatusWnd);
  319.       SetWindowLong(hStatusWnd, UI_MOVE_XY, MakeLong(ptSavCursor.x, ptSavCursor.y));
  320.       GetWindowRect(hStatusWnd, rcWnd);
  321.       SetWindowLong(hStatusWnd, UI_MOVE_OFFSET, MakeLong(ptSavCursor.x - rcWnd.Left, ptSavCursor.y - rcWnd.Top));
  322.       DrawDragBorder(hStatusWnd, MakeLong(ptSavCursor.x, ptSavCursor.y),
  323.       GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  324.     end;
  325.   end;
  326. end;
  327.   // 绘制Status窗口
  328. procedure PaintStatusWindow(_hDC: hDC; hStatusWnd: hWnd);
  329. var
  330.   hUIWnd: hWnd;
  331.   _hIMC: hIMC;
  332.   lpIMC: PInputContext;
  333.   lpImcP: PPrivContext;
  334.   hOldFont: hGdiObj;
  335.   hImeIconBmp, hShapeBmp, hSymbolBmp, hSKBmp, hOldBmp: hBitMap;
  336.   hMemDC: hDC;
  337.   lfFont: TLogFont;
  338. begin
  339.   hUIWnd := GetWindow(hStatusWnd, GW_OWNER);
  340.   if (IsWindow(hUIWnd) = False) then Exit;
  341.   _hIMC := GetWindowLong(hUIWnd, IMMGWLP_IMC);
  342.   if (_hIMC = 0) then
  343.   begin
  344.     MessageBeep($FFFFFFFF);
  345.     Exit;
  346.   end;
  347.   lpIMC := ImmLockIMC(_hIMC);
  348.   if (lpIMC = nil) then
  349.   begin
  350.     MessageBeep($FFFFFFFF);
  351.     Exit;
  352.   end;
  353.   // get lpImcP
  354.   lpImcP := ImmLockIMCC(lpIMC.hPrivate);
  355.   if (lpImcP = nil) then
  356.   begin
  357.     MessageBeep($FFFFFFFF);
  358.     Exit;
  359.   end;
  360.   // set font
  361.   if (sImeG.fDiffSysCharSet) then
  362.   begin
  363.     hOldFont := GetCurrentObject(_hDC, OBJ_FONT);
  364.     ZeroMemory(@lfFont, SizeOf(lfFont));
  365.     lfFont.lfHeight := - MulDiv(12, GetDeviceCaps(_hDC, LOGPIXELSY), 72);
  366.     lfFont.lfCharSet := NATIVE_CHARSET;
  367.     lStrCpy(lfFont.lfFaceName, '宋体');
  368.     SelectObject(_hDC, CreateFontIndirect(lfFont));
  369.   end else
  370.     hOldFont := 0;
  371.   // draw Ime Name ..
  372.   if (lpIMC.fOpen) then SetTextColor(_hDC, RGB($00, $00, $00)) else SetTextColor(_hDC, RGB($80, $80, $80));
  373.   SetBkColor(_hDC, RGB($C0, $C0, $C0));
  374.   DrawText(_hDC, szImeName, lStrLen(szImeName), sImeG.rcImeName, DT_CENTER or DT_VCENTER or DT_SINGLELINE);
  375.   DrawConvexRect(_hDC, sImeG.rcImeName.Left, sImeG.rcImeName.Top, sImeG.rcImeName.Right - 1, sImeG.rcImeName.Bottom - 1);
  376.   DrawConvexRectP(_hDC, sImeG.rcImeName.Left, sImeG.rcImeName.Top, sImeG.rcImeName.Right, sImeG.rcImeName.Bottom);
  377.   // load all bitmap & draw ..
  378.   hSymbolBmp := 0;
  379.   hShapeBmp := 0;
  380.   hSKBmp := 0;
  381.   if (lpIMC.fOpen = False) then
  382.   begin
  383.     hSymbolBmp := LoadBitmap(HInstance, szNone);
  384.     hShapeBmp := LoadBitmap(HInstance, szNone);
  385.     hSKBmp := LoadBitmap(HInstance, szNone);
  386.     hImeIconBmp := LoadBitmap(HInstance, szChinese);
  387.   end else
  388.     if (lpIMC.fdwConversion and IME_CMODE_NATIVE) <> 0 then
  389.       hImeIconBmp := LoadBitmap(HInstance, szChinese)
  390.     else
  391.       hImeIconBmp := LoadBitmap(HInstance, szEnglish);
  392.   if (hShapeBmp = 0) then
  393.   begin
  394.     if (lpIMC.fdwConversion and IME_CMODE_FULLSHAPE) <> 0 then
  395.       hShapeBmp := LoadBitmap(HInstance, szFullShape)
  396.     else
  397.       hShapeBmp := LoadBitmap(HInstance, szHalfShape);
  398.   end;
  399.   if (hSymbolBmp = 0) then
  400.   begin
  401.     if (lpIMC.fdwConversion and IME_CMODE_SYMBOL) <> 0 then
  402.       hSymbolBmp := LoadBitmap(HInstance, szSymbol)
  403.     else
  404.       hSymbolBmp := LoadBitmap(HInstance, szNoSymbol);
  405.   end;
  406.   if (hSKBmp = 0) then
  407.   begin
  408.     if (lpIMC.fdwConversion and IME_CMODE_SOFTKBD) <> 0 then
  409.       hSKBmp := LoadBitmap(HInstance, szSoftKBD)
  410.     else
  411.       hSKBmp := LoadBitmap(HInstance, szNoSoftKBD);
  412.   end;
  413.   ImmUnlockIMC(_hIMC);
  414.   ImmUnlockIMCC(lpIMC.hPrivate);
  415.   hMemDC := CreateCompatibleDC(_hDC);
  416.   hOldBmp := SelectObject(hMemDC, hImeIconBmp);
  417.   BitBlt(_hDC, sImeG.rcImeIcon.Left, sImeG.rcImeIcon.Top,
  418.     sImeG.rcImeIcon.Right - sImeG.rcImeIcon.Left, STATUS_DIM_Y, hMemDC, 0, 0, SRCCOPY);
  419.   SelectObject(hMemDC, hShapeBmp);
  420.   BitBlt(_hDC, sImeG.rcShapeText.Left, sImeG.rcShapeText.Top,
  421.     sImeG.rcShapeText.Right - sImeG.rcShapeText.Left, STATUS_DIM_Y, hMemDC, 0, 0, SRCCOPY);
  422.   SelectObject(hMemDC, hSymbolBmp);
  423.   BitBlt(_hDC, sImeG.rcSymbol.Left, sImeG.rcSymbol.Top,
  424.     sImeG.rcSymbol.Right - sImeG.rcSymbol.Left, STATUS_DIM_Y, hMemDC, 0, 0, SRCCOPY);
  425.   SelectObject(hMemDC, hSKBmp);
  426.   BitBlt(_hDC, sImeG.rcSKText.Left, sImeG.rcSKText.Top,
  427.      sImeG.xStatusWi - sImeG.rcSKText.Left, STATUS_DIM_Y, hMemDC, 0, 0, SRCCOPY);
  428.   SelectObject(hMemDC, hOldBmp);
  429.   DeleteDC(hMemDC);
  430.   DeleteObject(hImeIconBmp);
  431.   DeleteObject(hSymbolBmp);
  432.   DeleteObject(hShapeBmp);
  433.   DeleteObject(hSKBmp);
  434.   if (sImeG.fDiffSysCharSet) then DeleteObject(SelectObject(_hDC, hOldFont));
  435. end;
  436.   // Status窗口回调
  437. function StatusWndProc(hStatusWnd: hWnd; uMsg: uInt; wParam: WParam; lParam: LParam): LResult; stdcall;
  438. var
  439.   ptCursor: TPoint;
  440.   lTmpCursor, lTmpOffset: DWord;
  441.   _hDC: hDC;
  442.   ps: TPaintStruct;
  443. begin
  444.   Result := 0;
  445.   case (uMsg) of
  446.     WM_DESTROY:
  447.       DestroyStatusWindow(hStatusWnd);
  448.     WM_SETCURSOR:
  449.       StatusSetCursor(hStatusWnd, lParam);
  450.     WM_MOUSEMOVE:
  451.       if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) <> WINDOW_NOT_DRAG) then // 拖拽中..
  452.       begin
  453.         DrawDragBorder(hStatusWnd, GetWindowLong(hStatusWnd, UI_MOVE_XY), GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  454.         GetCursorPos(ptCursor);
  455.         SetWindowLong(hStatusWnd, UI_MOVE_XY, MakeLong(ptCursor.x, ptCursor.y));
  456.         DrawDragBorder(hStatusWnd, MakeLong(ptCursor.x, ptCursor.y), GetWindowLong(hStatusWnd, UI_MOVE_OFFSET));
  457.       end else
  458.         Result := DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  459.     WM_LBUTTONUP:
  460.       if (GetWindowLong(hStatusWnd, UI_MOVE_OFFSET) <> WINDOW_NOT_DRAG) then // 拖拽中..
  461.       begin
  462.         lTmpCursor := GetWindowLong(hStatusWnd, UI_MOVE_XY);
  463.         lTmpOffset := GetWindowLong(hStatusWnd, UI_MOVE_OFFSET);
  464.         DrawDragBorder(hStatusWnd, lTmpCursor, lTmpOffset);
  465.         // calculate the org by the offset
  466.         Dec(PSmallPoint(@lTmpCursor).x, PSmallPoint(@lTmpOffset).x);
  467.         Dec(PSmallPoint(@lTmpCursor).y, PSmallPoint(@lTmpOffset).y);
  468.         SetWindowLong(hStatusWnd, UI_MOVE_OFFSET, WINDOW_NOT_DRAG);
  469.         ReleaseCapture();
  470.         AdjustStatusBoundary(PSmallPoint(@lTmpCursor), GetWindow(hStatusWnd, GW_OWNER));
  471.         SendMessage(GetWindow(hStatusWnd, GW_OWNER), WM_IME_CONTROL, IMC_SETSTATUSWINDOWPOS, lTmpCursor);
  472.       end else
  473.         Result := DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  474.     WM_IME_NOTIFY:
  475.     begin
  476.       SystemParametersInfo(SPI_GETWORKAREA, 0, @sImeG.rcWorkArea, 0); // get work area for changing
  477.       if (wParam = IMN_SETSTATUSWINDOWPOS) then SetStatusWindowPos(hStatusWnd);
  478.     end;
  479.     WM_PAINT:
  480.     begin
  481.       _hDC := BeginPaint(hStatusWnd, ps);
  482.       PaintStatusWindow(_hDC, hStatusWnd);
  483.       EndPaint(hStatusWnd, ps);
  484.     end;
  485.     WM_MOUSEACTIVATE:
  486.       Result := MA_NOACTIVATE;
  487.     else
  488.       Result := DefWindowProc(hStatusWnd, uMsg, wParam, lParam);
  489.   end;
  490. end;
  491.   // 版本对话框回调
  492. function ImeVerDlgProc(hDlg: hWnd; uMessage: uInt; wParam: WParam; lParam: LParam): Bool; stdcall;
  493. var
  494.   Rc: TRect;
  495.   DlgWidth, DlgHeight: Integer;
  496. begin
  497.   case (uMessage) of
  498.     WM_INITDIALOG:
  499.     begin
  500.       hCrtDlg := hDlg;
  501.       GetWindowRect(hDlg, Rc);
  502.       DlgWidth := Rc.Right - Rc.Left;
  503.       DlgHeight := Rc.Bottom - Rc.Top;
  504.       // reset position ..
  505.       SetWindowPos(hDlg, HWND_TOP, (sImeG.rcWorkArea.Right - DlgWidth) div 2,
  506.         (sImeG.rcWorkArea.Bottom - DlgHeight) div 2, 0, 0, SWP_NOSIZE);
  507.       Result := True;
  508.     end;
  509.     WM_COMMAND:
  510.     begin
  511.       case (wParam) of
  512.         IDOK, IDCANCEL: EndDialog(hDlg, 0);
  513.       end;
  514.       Result := True;
  515.     end;
  516.     WM_CLOSE:
  517.     begin
  518.       EndDialog(hDlg, 0); // 没必要吧, ??
  519.       Result := False;
  520.     end;
  521.     WM_PAINT: // 画了有用吗, ??
  522.     begin
  523.       GetClientRect(hDlg, Rc);
  524.       DrawConvexRect(GetDC(hDlg), Rc.Left + 10, Rc.Top + 10, Rc.Right - 10 - 1, Rc.Bottom - 43 - 1);
  525.       DrawConvexRectP(GetDC(hDlg), Rc.Left + 10, Rc.Top + 10, Rc.Right - 10, Rc.Bottom - 43);
  526.       Result := False;
  527.     end;
  528.     else Result := False;
  529.   end;
  530. end;
  531. end.