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

输入法编程

开发平台:

Delphi

  1.  {******************************************************}
  2.  {                                                      }
  3.  {    Copyright (c) 1990-1999 Microsoft Corporation     }
  4.  {                                                      }
  5.  {    Module Name:  Uisubs.c ->>  Uisubs.pas            }
  6.  {                                                      }
  7.  {    Translator:  Liu_mazi@126.com, 2005-11-14         }
  8.  {                                                      }
  9.  {******************************************************}
  10. unit Uisubs;
  11. {$I Define.Inc}
  12. interface
  13. uses Windows;
  14. procedure DrawDragBorder(_hWnd: hWnd; lCursorPos, lCursorOffset: DWord); // 绘制拖拽方框
  15. procedure DrawFrameBorder(_hDC: hDC; _hWnd: hWnd); // 绘制窗口边框
  16. function ContextMenuWndProc(hCMenuWnd: hWnd; uMsg: uInt; wParam: WParam; lParam: LParam): LResult; stdcall; // Context菜单窗口回调
  17. function SoftkeyMenuWndProc(hKeyMenuWnd: hWnd; uMsg: uInt; wParam: WParam; lParam: LParam): LResult; stdcall; // Softkey菜单窗口回调
  18. procedure ContextMenu(hStatusWnd: hWnd; x, y: Integer); // 弹出Context菜单
  19. procedure SoftkeyMenu(hStatusWnd: hWnd; x, y: Integer); // 弹出Softkey菜单
  20. function HtmlHelp(hWndCaller: HWnd; pszFile: PChar; uCommand: UInt; dwData: DWord): HWnd; stdcall;
  21. implementation
  22. uses Messages, ImmDev, ImeDefs, Data, Init, DDIS, Notify, Statusui;
  23. const
  24.   HH_DISPLAY_TOC     = $0001;
  25.   HH_DISPLAY_TOPIC   = $0000;
  26.   HH_CLOSE_ALL       = $0012;
  27.   HH_DISPLAY_INDEX   = $0002;
  28.   HH_HELP_CONTEXT    = $000F;
  29.   HH_DISPLAY_SEARCH  = $0003;
  30. function HtmlHelp; external 'HHCtrl.ocx' Name 'HtmlHelpA';
  31.   // 绘制拖拽方框
  32. procedure DrawDragBorder(_hWnd: hWnd; lCursorPos, lCursorOffset: DWord);
  33. var
  34.   _hDC: hDC;
  35.   cxBorder, cyBorder, x, y: Integer;
  36.   rcWnd: TRect;
  37. begin
  38.   // 边框宽度
  39.   cxBorder := GetSystemMetrics(SM_CXBORDER);
  40.   cyBorder := GetSystemMetrics(SM_CYBORDER);
  41.   // 当前位置
  42.   x := PSmallPoint(@lCursorPos).x;
  43.   y := PSmallPoint(@lCursorPos).y;
  44.   // 偏移计算
  45.   Dec(x, PSmallPoint(@lCursorOffset).x);
  46.   Dec(y, PSmallPoint(@lCursorOffset).y);
  47.   // 防止越界
  48.   if (x < sImeG.rcWorkArea.Left) then x := sImeG.rcWorkArea.Left;
  49.   if (y < sImeG.rcWorkArea.Top) then y := sImeG.rcWorkArea.Top;
  50.   // 窗口尺寸
  51.   GetWindowRect(_hWnd, rcWnd);
  52.   // 防止越界
  53.   if (x + (rcWnd.Right - rcWnd.Left) > sImeG.rcWorkArea.Right) then
  54.     x := sImeG.rcWorkArea.Right - (rcWnd.Right - rcWnd.Left);
  55.   if (y + (rcWnd.Bottom - rcWnd.Top) > sImeG.rcWorkArea.Bottom) then
  56.     y := sImeG.rcWorkArea.Bottom - (rcWnd.Bottom - rcWnd.Top);
  57.   // 绘制方框
  58.   _hDC := CreateDC('DISPLAY', nil, nil, nil);
  59.   SelectObject(_hDC, GetStockObject(GRAY_BRUSH));
  60.   PatBlt(_hDC, x, y, rcWnd.Right - rcWnd.Left - cxBorder, cyBorder, PATINVERT);
  61.   PatBlt(_hDC, x, y + cyBorder, cxBorder, rcWnd.Bottom - rcWnd.Top - cyBorder, PATINVERT);
  62.   PatBlt(_hDC, x + cxBorder, y + rcWnd.Bottom - rcWnd.Top, rcWnd.Right - rcWnd.Left - cxBorder, - cyBorder, PATINVERT);
  63.   PatBlt(_hDC, x + rcWnd.Right - rcWnd.Left, y, - cxBorder, rcWnd.Bottom - rcWnd.Top - cyBorder, PATINVERT); // **
  64.   DeleteDC(_hDC);
  65. end;
  66.   // 绘制窗口边框
  67. procedure DrawFrameBorder(_hDC: hDC; _hWnd: hWnd);
  68. var
  69.   rcWnd: TRect;
  70.   xWi, yHi: Integer;
  71. begin
  72.   GetWindowRect(_hWnd, rcWnd);
  73.   xWi := rcWnd.Right - rcWnd.Left; // 宽度
  74.   yHi := rcWnd.Bottom - rcWnd.Top; // 高度
  75.   // 第1层
  76.   PatBlt(_hDC, 0, 0, xWi, 1, WHITENESS);
  77.   PatBlt(_hDC, 0, 0, 1, yHi, WHITENESS);
  78.   PatBlt(_hDC, 0, yHi, xWi, -1, BLACKNESS);
  79.   PatBlt(_hDC, xWi, 0, -1, yHi, BLACKNESS);
  80.   // 第2层
  81.   Dec(xWi, 2);
  82.   Dec(yHi, 2);
  83.   SelectObject(_hDC, GetStockObject(LTGRAY_BRUSH));
  84.   PatBlt(_hDC, 1, 1, xWi, 1, PATCOPY);
  85.   PatBlt(_hDC, 1, 1, 1, yHi, PATCOPY);
  86.   PatBlt(_hDC, xWi + 1, 1, -1, yHi, PATCOPY);
  87.   SelectObject(_hDC, GetStockObject(GRAY_BRUSH));
  88.   PatBlt(_hDC, 1, yHi + 1, xWi, -1, PATCOPY);
  89.   // 第3层
  90.   Dec(xWi, 2);
  91.   Dec(yHi, 2);
  92.   PatBlt(_hDC, 2, 2, xWi, 1, PATCOPY);
  93.   PatBlt(_hDC, 2, 2, 1, yHi, PATCOPY);
  94.   PatBlt(_hDC, xWi + 2, 3, -1, yHi - 1, WHITENESS);
  95.   SelectObject(_hDC, GetStockObject(LTGRAY_BRUSH));
  96.   PatBlt(_hDC, 2, yHi + 2, xWi, -1, PATCOPY);
  97.   // 第4层
  98.   Dec(xWi, 2);
  99.   Dec(yHi, 2);
  100.   SelectObject(_hDC, GetStockObject(GRAY_BRUSH));
  101.   PatBlt(_hDC, 3, 3, xWi, 1, PATCOPY);
  102.   PatBlt(_hDC, 3, 3, 1, yHi, PATCOPY);
  103.   SelectObject(_hDC, GetStockObject(LTGRAY_BRUSH));
  104.   PatBlt(_hDC, xWi + 3, 4, -1, yHi - 1, PATCOPY);
  105.   PatBlt(_hDC, 3, yHi + 3, xWi, -1, WHITENESS);
  106. end;
  107.   // Context菜单窗口回调
  108. function ContextMenuWndProc(hCMenuWnd: hWnd; uMsg: uInt; wParam: WParam; lParam: LParam): LResult; stdcall;
  109. var
  110.   hUIWnd{, hCompWnd}: hWnd;
  111.   _hIMC: hIMC;
  112.   lpIMC: PInputContext;
  113.   lpImcP: PPrivContext;
  114.   ptSTFixPos: TPoint;
  115.   _hMenu: hMenu;
  116.   ui_Mode: Integer;
  117.   szOptGudHlpName: array[0..MAX_PATH] of Char;
  118.   szImeGudHlpName: array[0..MAX_PATH] of Char;
  119. begin
  120.   Result := 0;
  121.   case (uMsg) of
  122.     WM_DESTROY:
  123.     begin
  124.       hUIWnd := GetWindowLong(hCMenuWnd, CMENU_HUIWND);
  125.       if IsWindow(hUIWnd) then SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_PRIVATE, IMN_PRIVATE_CMENUDESTROYED);
  126.     end;
  127.     WM_USER_DESTROY:
  128.     begin
  129.       SendMessage(hCMenuWnd, WM_CLOSE, 0, 0); // **, Send此消息, 下面就没有必要调用DestroyWindow()了..
  130.       DestroyWindow(hCMenuWnd);
  131.     end;
  132.     WM_COMMAND:
  133.     begin
  134.       case LoWord(wParam) of
  135.         IDM_PROP:   // 设置...
  136.         begin
  137.           hUIWnd := GetWindowLong(hCMenuWnd, CMENU_HUIWND);
  138.           if (IsWindow(hUIWnd) = False) then Exit;
  139.           _hIMC := GetWindowLong(hUIWnd, IMMGWLP_IMC);
  140.           if (_hIMC = 0) then Exit;
  141.           lpIMC := ImmLockIMC(_hIMC);
  142.           if (lpIMC = nil) then Exit;
  143.           lpImcP := ImmLockIMCC(lpIMC.hPrivate);
  144.           if (lpImcP = nil) then Exit; // **
  145.           ImeConfigure(GetKeyboardLayout(0), lpIMC.hWnd, IME_CONFIG_GENERAL, nil);
  146.           lpImcP.iImeState := CST_INIT;
  147.           CompCancel(_hIMC, lpIMC);
  148.           // init fields of hIMC
  149.           lpIMC.fOpen := True;
  150.           if ((lpIMC.fdwInit and INIT_CONVERSION) = 0) then
  151.           begin
  152.             lpIMC.fdwConversion := IME_CMODE_NATIVE;
  153.             lpIMC.fdwInit := lpIMC.fdwInit or INIT_CONVERSION;
  154.           end;
  155.           lpImcP.fdwImeMsg := lpImcP.fdwImeMsg or MSG_IMN_DESTROYCAND;
  156.           GenerateMessage(_hIMC, lpIMC, lpImcP);
  157.           // set cand window data
  158.           if (sImeG.IC_Trace <> 0) then
  159.             ui_Mode := BOX_UI // **
  160.           else begin
  161.             ui_Mode := LIN_UI;
  162.             ptSTFixPos.x := 0;
  163.             ptSTFixPos.y := sImeG.rcWorkArea.Bottom - sImeG.yStatusHi;
  164.             ImmSetStatusWindowPos(_hIMC, @ptSTFixPos);
  165.           end;
  166.           InitCandUIData(GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER), ui_Mode);
  167.           ImmUnlockIMCC(lpIMC.hPrivate);
  168.           ImmUnlockIMC(_hIMC);
  169.         end;
  170.         IDM_OPTGUD: // 操作指南...
  171.         begin
  172.           szOptGudHlpName[0] := #0;
  173.           GetWindowsDirectory(szOptGudHlpName, MAX_PATH);
  174.           lStrCat(szOptGudHlpName, 'HELPWINIME.CHM');
  175.           HtmlHelp(hCMenuWnd, szOptGudHlpName, HH_DISPLAY_TOPIC, 0);
  176.         end;
  177.         IDM_IMEGUD: // 输入法入门...
  178.         begin
  179.           szImeGudHlpName[0] := #0;
  180.           GetWindowsDirectory(szImeGudHlpName, MAX_PATH);
  181.           lStrCat(szImeGudHlpName, 'HELPWINGB.CHM');
  182.           HtmlHelp(hCMenuWnd, szImeGudHlpName, HH_DISPLAY_TOPIC, 0);
  183.         end;
  184.         IDM_VER:    // 版本信息...
  185.         begin
  186.           hUIWnd := GetWindowLong(hCMenuWnd, CMENU_HUIWND);
  187.           if (IsWindow(hUIWnd) = False) then Exit;
  188.           _hIMC := GetWindowLong(hUIWnd, IMMGWLP_IMC);
  189.           if (_hIMC = 0) then Exit;
  190.           lpIMC := ImmLockIMC(_hIMC);
  191.           if (lpIMC = nil) then Exit;
  192.           DialogBox(HInstance, 'IMEVER', lpIMC.hWnd, @ImeVerDlgProc);
  193.           ImmUnlockIMC(_hIMC);
  194.         end;
  195.       end;
  196.     end;
  197.     WM_CLOSE:
  198.     begin
  199.       GetMenu(hCMenuWnd); // ??
  200.       _hMenu := GetWindowLong(hCMenuWnd, CMENU_MENU);
  201.       if (_hMenu <> 0) then
  202.       begin
  203.         SetWindowLong(hCMenuWnd, CMENU_MENU, 0);
  204.         DestroyMenu(_hMenu);
  205.       end;
  206.       Result := DefWindowProc(hCMenuWnd, uMsg, wParam, lParam); // **, DefWindowProc()将调用DestroyWindow()
  207.     end;
  208.     else
  209.       Result := DefWindowProc(hCMenuWnd, uMsg, wParam, lParam);
  210.   end;
  211. end;
  212.   // Softkey菜单窗口回调
  213. function SoftkeyMenuWndProc(hKeyMenuWnd: hWnd; uMsg: uInt; wParam: WParam; lParam: LParam): LResult; stdcall;
  214. var
  215.   hUIWnd: hWnd;
  216.   _hMenu: hMenu;
  217.   _hIMC: hIMC;
  218.   lpIMC: PInputContext;
  219.   lpImcP: PPrivContext;
  220.   fdwConversion: DWord;
  221.   J: uInt;
  222. begin
  223.   Result := 0;
  224.   case (uMsg) of
  225.     WM_DESTROY:
  226.     begin
  227.       hUIWnd := GetWindowLong(hKeyMenuWnd, SOFTKEYMENU_HUIWND);
  228.       if IsWindow(hUIWnd) then SendMessage(hUIWnd, WM_IME_NOTIFY, IMN_PRIVATE, IMN_PRIVATE_SOFTKEYMENUDESTROYED);
  229.     end;
  230.     WM_USER_DESTROY:
  231.     begin
  232.       SendMessage(hKeyMenuWnd, WM_CLOSE, 0, 0);
  233.       DestroyWindow(hKeyMenuWnd); // **
  234.     end;
  235.     WM_COMMAND:
  236.     begin
  237.       case LoWord(wParam) of
  238.         IDM_SKL1, IDM_SKL2, IDM_SKL3, IDM_SKL4, IDM_SKL5, IDM_SKL6, IDM_SKL7,
  239.         IDM_SKL8, IDM_SKL9, IDM_SKL10, IDM_SKL11, IDM_SKL12, IDM_SKL13: // 键盘类型
  240.         begin
  241.           hUIWnd := GetWindowLong(hKeyMenuWnd, SOFTKEYMENU_HUIWND);
  242.           if (IsWindow(hUIWnd) = False) then Exit;
  243.           _hIMC := GetWindowLong(hUIWnd, IMMGWLP_IMC);
  244.           if (_hIMC = 0) then Exit;
  245.           lpIMC := ImmLockIMC(_hIMC);
  246.           if (lpIMC = nil) then Exit;
  247.           lpImcP := ImmLockIMCC(lpIMC.hPrivate);
  248.           if (lpImcP = nil) then Exit; // **
  249.           sImeL.dwSKWant := LoWord(wParam) - IDM_SKL1;
  250.           sImeL.dwSKState[sImeL.dwSKWant] := 1;
  251.           // clear other SK State
  252.           for J := 0 to NumsSK - 1 do if (J <> sImeL.dwSKWant) then sImeL.dwSKState[J] := 0;
  253.           if (sImeL.dwSKState[sImeL.dwSKWant] <> 0) then
  254.           begin
  255.             if (LoWord(wParam) = IDM_SKL1) then lpImcP.iImeState := CST_INIT else lpImcP.iImeState := CST_SOFTKB;
  256.             fdwConversion := lpIMC.fdwConversion or IME_CMODE_SOFTKBD;
  257.           end else
  258.           begin
  259.             lpImcP.iImeState := CST_INIT;
  260.             fdwConversion := lpIMC.fdwConversion and (not IME_CMODE_SOFTKBD);
  261.           end;
  262.           ImmSetConversionStatus(_hIMC, fdwConversion and (not IME_CMODE_SOFTKBD), lpIMC.fdwSentence);
  263.           ImmSetConversionStatus(_hIMC, fdwConversion, lpIMC.fdwSentence);
  264.           ImmUnlockIMCC(lpIMC.hPrivate);
  265.           ImmUnlockIMC(_hIMC);
  266.         end;
  267.       end;
  268.     end;
  269.     WM_CLOSE:
  270.     begin
  271.       GetMenu(hKeyMenuWnd); // ??
  272.       _hMenu := GetWindowLong(hKeyMenuWnd, SOFTKEYMENU_MENU);
  273.       if (_hMenu <> 0) then
  274.       begin
  275.         SetWindowLong(hKeyMenuWnd, SOFTKEYMENU_MENU, 0);
  276.         DestroyMenu(_hMenu);
  277.       end;
  278.       Result := DefWindowProc(hKeyMenuWnd, uMsg, wParam, lParam); // **
  279.     end;
  280.     WM_SETCURSOR:
  281.     begin
  282.       if (HiWord(lParam) = WM_RBUTTONUP) then MessageBeep($FFFFFFFF);
  283.       Result := DefWindowProc(hKeyMenuWnd, uMsg, wParam, lParam);
  284.     end;
  285.     else
  286.       Result := DefWindowProc(hKeyMenuWnd, uMsg, wParam, lParam);
  287.   end;
  288. end;
  289.   // 弹出Context菜单
  290. procedure ContextMenu(hStatusWnd: hWnd; x, y: Integer);
  291. label
  292.   ContextMenuUnlockIMC;
  293. var
  294.   hUIWnd, hCMenuWnd: hWnd;
  295.   hUIPrivate: hGlobal;
  296.   lpUIPrivate: PUIPriv;
  297.   _hIMC: hIMC;
  298.   lpIMC: PInputContext;
  299.   _hMenu, hCMenu: hMenu;
  300.   rcStatusWnd: TRect;
  301. begin
  302.   hUIWnd := GetWindow(hStatusWnd, GW_OWNER);
  303.   if (IsWindow(hUIWnd) = False) then Exit;
  304.   GetWindowRect(hStatusWnd, rcStatusWnd);
  305.   _hIMC := GetWindowLong(hUIWnd, IMMGWLP_IMC);
  306.   if (_hIMC = 0) then Exit;
  307.   lpIMC := ImmLockIMC(_hIMC);
  308.   if (lpIMC = nil) then Exit;
  309.   hUIPrivate := GetWindowLong(hUIWnd, IMMGWLP_PRIVATE);
  310.   if (hUIPrivate = 0) then goto ContextMenuUnlockIMC;
  311.   lpUIPrivate := GlobalLock(hUIPrivate);
  312.   if (lpUIPrivate = nil) then goto ContextMenuUnlockIMC;
  313.   if (IsWindow(lpUIPrivate.hCMenuWnd) = False) then
  314.   begin
  315.     lpUIPrivate.hCMenuWnd := CreateWindowEx(CS_HREDRAW or CS_VREDRAW, szCMenuClassName,
  316.       'Context Menu', WS_POPUP or WS_DISABLED, 0, 0, 0, 0, lpIMC.hWnd, 0, HInstance, nil);
  317.   end;
  318.   hCMenuWnd := lpUIPrivate.hCMenuWnd;
  319.   GlobalUnlock(hUIPrivate);
  320.   if (IsWindow(hCMenuWnd) = False) then goto ContextMenuUnlockIMC;
  321.   _hMenu := LoadMenu(HInstance, 'PROPMENU');
  322.   hCMenu := GetSubMenu(_hMenu, 0);
  323.   SetWindowLong(hCMenuWnd, CMENU_HUIWND, hUIWnd);
  324.   SetWindowLong(hCMenuWnd, CMENU_MENU, _hMenu);
  325.   TrackPopupMenu(hCMenu, TPM_LEFTBUTTON, rcStatusWnd.Left, rcStatusWnd.Top, 0, hCMenuWnd, nil);
  326.   _hMenu := GetWindowLong(hCMenuWnd, CMENU_MENU);
  327.   if (_hMenu <> 0) then
  328.   begin
  329.     SetWindowLong(hCMenuWnd, CMENU_MENU, 0);
  330.     DestroyMenu(_hMenu);
  331.   end;
  332. ContextMenuUnlockIMC:
  333.   ImmUnlockIMC(_hIMC);
  334. end;
  335.   // 弹出Softkey菜单
  336. procedure SoftkeyMenu(hStatusWnd: hWnd; x, y: Integer);
  337. label
  338.   KeyMenuUnlockIMC;
  339. var
  340.   hUIWnd, hSoftkeyMenuWnd: hWnd;
  341.   hUIPrivate: hGlobal;
  342.   lpUIPrivate: PUIPriv;
  343.   _hIMC: hIMC;
  344.   lpIMC: PInputContext;
  345.   _hMenu, hKeyMenu: hMenu;
  346.   rcStatusWnd: TRect;
  347. begin
  348.   hUIWnd := GetWindow(hStatusWnd, GW_OWNER);
  349.   if (IsWindow(hUIWnd) = False) then Exit;
  350.   GetWindowRect(hStatusWnd, rcStatusWnd);
  351.   _hIMC := GetWindowLong(hUIWnd, IMMGWLP_IMC);
  352.   if (_hIMC = 0) then Exit;
  353.   lpIMC := ImmLockIMC(_hIMC);
  354.   if (lpIMC = nil) then Exit;
  355.   hUIPrivate := GetWindowLong(hUIWnd, IMMGWLP_PRIVATE);
  356.   if (hUIPrivate = 0) then goto KeyMenuUnlockIMC;
  357.   lpUIPrivate := GlobalLock(hUIPrivate);
  358.   if (lpUIPrivate = nil) then goto KeyMenuUnlockIMC;
  359.   if (IsWindow(lpUIPrivate.hSoftkeyMenuWnd) = False) then
  360.   begin
  361.     lpUIPrivate.hSoftkeyMenuWnd := CreateWindowEx(CS_HREDRAW or CS_VREDRAW, szSoftkeyMenuClassName,
  362.       'Softkey Menu', WS_POPUP or WS_DISABLED, 0, 0, 0, 0, lpIMC.hWnd, 0, HInstance, nil);
  363.   end;
  364.   hSoftkeyMenuWnd := lpUIPrivate.hSoftkeyMenuWnd;
  365.   GlobalUnlock(hUIPrivate);
  366.   if (IsWindow(hSoftkeyMenuWnd) = False) then goto KeyMenuUnlockIMC;
  367.   _hMenu := LoadMenu(HInstance, 'SKMENU');
  368.   hKeyMenu := GetSubMenu(_hMenu, 0);
  369.   SetWindowLong(hSoftkeyMenuWnd, SOFTKEYMENU_HUIWND, hUIWnd);
  370.   SetWindowLong(hSoftkeyMenuWnd, SOFTKEYMENU_MENU, _hMenu);
  371.   if (sImeL.dwSKState[sImeL.dwSKWant] <> 0) then CheckMenuItem(_hMenu, sImeL.dwSKWant + IDM_SKL1, MF_CHECKED);
  372.   TrackPopupMenu(hKeyMenu, TPM_LEFTBUTTON, rcStatusWnd.Left, rcStatusWnd.Top, 0, hSoftkeyMenuWnd, nil);
  373.   _hMenu := GetWindowLong(hSoftkeyMenuWnd, SOFTKEYMENU_MENU);
  374.   if (_hMenu <> 0) then
  375.   begin
  376.     SetWindowLong(hSoftkeyMenuWnd, SOFTKEYMENU_MENU, 0);
  377.     DestroyMenu(_hMenu);
  378.   end;
  379. KeyMenuUnlockIMC:
  380.   ImmUnlockIMC(_hIMC);
  381. end;
  382. end.