📄 freepy.c
字号:
/*
* Copyright (C) 1999.4 Li ZhenChun
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License; or
* (at your option) any later version.
*
* This program is distributed in the hope that is will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, M A 02139, USA.
*
* Author: Li ZhenChun email: zhchli@163.net or zhchli@126.com
*
*/
#include "freepy.h"
#define CS_FREEPY (CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS)
/**********************************************************************/
/* DLLEntry */
/**********************************************************************/
BOOL WINAPI DllMain (
HINSTANCE hInstDLL,
DWORD dwFunction,
LPVOID lpNot)
{
switch(dwFunction)
{
case DLL_PROCESS_ATTACH:
/* for debug ********************************/
#ifdef _MY_DEBUG
if(nDebugLevel){
if( (DebugLogFile=_tfopen( DEBUGLOGFILE, "w"))==NULL)
MessageBox(NULL,"can not open Debuglogfile","debug",MB_OK);
DebugLog(1,(DebugLogFile,"Entry in\n"));
}
#endif
/********************************************/
InitDictionary();
hInst = hInstDLL;
IMERegisterClass( hInst );
break;
case DLL_PROCESS_DETACH:
UnregisterClass(UICLASSNAME,hInst);
UnregisterClass(COMPCLASSNAME,hInst);
UnregisterClass(CANDCLASSNAME,hInst);
UnregisterClass(STATUSCLASSNAME,hInst);
DestroyDictionary();
/* for debug ********************************/
#ifdef _MY_DEBUG
if(nDebugLevel){
DebugLog(1,(DebugLogFile,"Entry out\n"));
if(DebugLogFile!=NULL)
fclose(DebugLogFile);
}
#endif
/********************************************/
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
BOOL IMERegisterClass( HANDLE hInstance )
{
WNDCLASSEX wc;
//
// register class of UI window.
//
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_FREEPY | CS_IME;
wc.lpfnWndProc = UIWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 2 * sizeof(LONG);
wc.hInstance = hInstance;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hIcon = NULL;
wc.lpszMenuName = (LPTSTR)NULL;
wc.lpszClassName = UICLASSNAME;
wc.hbrBackground = NULL;
wc.hIconSm = NULL;
if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
return FALSE;
//
// register class of composition window.
//
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_FREEPY | CS_IME;
wc.lpfnWndProc = CompWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = UICHILDEXTRASIZE;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hIcon = NULL;
wc.lpszMenuName = (LPSTR)NULL;
wc.lpszClassName = COMPCLASSNAME;
wc.hbrBackground = NULL;
wc.hIconSm = NULL;
if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
return FALSE;
//
// register class of candadate window.
//
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_FREEPY | CS_IME;
wc.lpfnWndProc = CandWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = UICHILDEXTRASIZE;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hIcon = NULL;
wc.lpszMenuName = (LPSTR)NULL;
wc.lpszClassName = CANDCLASSNAME;
wc.hbrBackground = NULL;
wc.hIconSm = NULL;
if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
return FALSE;
//
// register class of status window.
//
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_FREEPY | CS_IME;
wc.lpfnWndProc = StatusWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = UICHILDEXTRASIZE;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hIcon = NULL;
wc.lpszMenuName = (LPSTR)NULL;
wc.lpszClassName = STATUSCLASSNAME;
wc.hbrBackground = NULL;
wc.hIconSm = NULL;
if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
return FALSE;
return TRUE;
}
/**********************************************************************/
/* */
/* UIWndProc() */
/* */
/* IME UI window procedure */
/* */
/**********************************************************************/
LRESULT WINAPI UIWndProc(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
HIMC hUICurIMC;
LPINPUTCONTEXT lpIMC;
LPUIEXTRA lpUIExtra;
HGLOBAL hUIExtra;
LONG lRet = 0L;
DebugLog(1,(DebugLogFile,"UIWnd\n"));
hUICurIMC = (HIMC)GetWindowLong(hWnd,IMMGWL_IMC);
//
// Even if there is no current UI. these messages should not be pass to
// DefWindowProc().
//
if (!hUICurIMC)
{
switch (message)
{
case WM_IME_STARTCOMPOSITION:
case WM_IME_ENDCOMPOSITION:
case WM_IME_COMPOSITION:
case WM_IME_NOTIFY:
case WM_IME_CONTROL:
case WM_IME_COMPOSITIONFULL:
case WM_IME_SELECT:
case WM_IME_CHAR:
return 0L;
default:
break;
}
}
switch (message)
{
case WM_CREATE:
DebugLog(1,(DebugLogFile,"UIWnd:WM_CREATE\n"));
//
// Allocate UI's extra memory block.
//
hUIExtra = GlobalAlloc(GHND,sizeof(UIEXTRA));
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
lpUIExtra->uiComp.pt.x = -1;
lpUIExtra->uiComp.pt.y = -1;
CreateCompWindow(hWnd,lpUIExtra);
CreateCandWindow(hWnd,lpUIExtra);
GlobalUnlock(hUIExtra);
SetWindowLong(hWnd,IMMGWL_PRIVATE,(DWORD)hUIExtra);
break;
case WM_IME_SETCONTEXT:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_SETCONTEXT\n"));
if (wParam)
{
hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
if (hUICurIMC)
{
//
// input context was chenged.
// if there are the child windows, the diplay have to be
// updated.
//
lpIMC = ImmLockIMC(hUICurIMC);
if (lpIMC)
{
MoveCandWindow(hWnd,lpUIExtra,lpIMC);
MoveCompWindow(hWnd,lpUIExtra,lpIMC);
}
else
{
HideCandWindow(lpUIExtra);
HideCompWindow(lpUIExtra);
}
ImmUnlockIMC(hUICurIMC);
}
else // it is NULL input context.
{
HideCandWindow(lpUIExtra);
HideCompWindow(lpUIExtra);
}
GlobalUnlock(hUIExtra);
}
break;
case WM_IME_STARTCOMPOSITION:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_STARTCOMPOSITION\n"));
//
// Start composition! Ready to display the composition string.
//
break;
case WM_IME_COMPOSITION:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_COMPOSITION\n"));
//
// Update to display the composition string.
//
lpIMC = ImmLockIMC(hUICurIMC);
hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
MoveCompWindow(hWnd,lpUIExtra,lpIMC);
MoveCandWindow(hWnd,lpUIExtra,lpIMC);
GlobalUnlock(hUIExtra);
ImmUnlockIMC(hUICurIMC);
break;
case WM_IME_ENDCOMPOSITION:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_ENDCOMPOSITION\n"));
//
// Finish to display the composition string.
//
hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
HideCompWindow(lpUIExtra);
HideCandWindow(lpUIExtra);
GlobalUnlock(hUIExtra);
break;
case WM_IME_COMPOSITIONFULL:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_COMPOSITIONFULL\n"));
break;
case WM_IME_SELECT:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_SELECT\n"));
break;
case WM_IME_CONTROL:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_CONTROL\n"));
lRet = ControlHandle(hUICurIMC, hWnd,message,wParam,lParam);
break;
case WM_IME_NOTIFY:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY\n"));
lRet = NotifyHandle(hUICurIMC, hWnd,message,wParam,lParam);
break;
case WM_DESTROY:
DebugLog(1,(DebugLogFile,"UIWnd:WM_DESTROY\n"));
hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
if (IsWindow(lpUIExtra->uiStatus.hWnd))
DestroyWindow(lpUIExtra->uiStatus.hWnd);
if (IsWindow(lpUIExtra->uiCand.hWnd))
DestroyWindow(lpUIExtra->uiCand.hWnd);
if (IsWindow(lpUIExtra->uiComp.hWnd))
DestroyWindow(lpUIExtra->uiComp.hWnd);
GlobalUnlock(hUIExtra);
GlobalFree(hUIExtra);
break;
case WM_UI_COMPMOVE:
hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
lpUIExtra->uiComp.pt.x = (long)LOWORD(lParam);
lpUIExtra->uiComp.pt.y = (long)HIWORD(lParam);
GlobalUnlock(hUIExtra);
break;
default:
return DefWindowProc(hWnd,message,wParam,lParam);
}
return lRet;
}
/**********************************************************************/
/* */
/* NotifyHandle() */
/* */
/* Handle WM_IME_NOTIFY messages. */
/* */
/**********************************************************************/
LONG NotifyHandle(HIMC hUICurIMC, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LONG lRet = 0L;
LPINPUTCONTEXT lpIMC;
HGLOBAL hUIExtra;
LPUIEXTRA lpUIExtra;
if (!(lpIMC = ImmLockIMC(hUICurIMC)))
return 0L;
hUIExtra = (HGLOBAL)GetWindowLong(hWnd,IMMGWL_PRIVATE);
lpUIExtra = (LPUIEXTRA)GlobalLock(hUIExtra);
switch (wParam)
{
case IMN_CLOSESTATUSWINDOW:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_CLOSESTATUSWINDOW\n"));
if (IsWindow(lpUIExtra->uiStatus.hWnd)) {
ShowWindow(lpUIExtra->uiStatus.hWnd,SW_HIDE);
}
break;
case IMN_OPENSTATUSWINDOW:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_OPENSTATUSWINDOW\n"));
CreateStatusWindow( hWnd, lpUIExtra);
break;
case IMN_OPENCANDIDATE:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_OPENCANDIDATE\n"));
break;
case IMN_CHANGECANDIDATE:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_CHANGECANDIDATE\n"));
break;
case IMN_CLOSECANDIDATE:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_CLOSECANDIDATE\n"));
break;
case IMN_SETCONVERSIONMODE:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCONVERSIONMODE\n"));
UpdateStatusWindow(lpUIExtra);
break;
case IMN_SETSENTENCEMODE:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETSENTENCEMODE\n"));
break;
case IMN_SETOPENSTATUS:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETOPENSTATUS\n"));
UpdateStatusWindow(lpUIExtra);
break;
case IMN_SETCANDIDATEPOS:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCANDIDATEPOS\n"));
break;
case IMN_SETCOMPOSITIONFONT:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCOMPOSITIONFONT\n"));
break;
case IMN_SETCOMPOSITIONWINDOW:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETCOMPOSITIONWINDOW\n"));
if(wConversionSet & CONVERSION_SET_FOLLOW) {
POINT ptSrc;
SIZE szOffset;
HDC hDC;
ptSrc = lpIMC->cfCompForm.ptCurrentPos;
ClientToScreen(lpIMC->hWnd, &ptSrc);
hDC = GetDC(lpIMC->hWnd);
GetTextExtentPoint(hDC,"A",1,&szOffset);
ReleaseDC(lpIMC->hWnd,hDC);
lpUIExtra->uiComp.pt.x = ptSrc.x + szOffset.cx;
lpUIExtra->uiComp.pt.y = ptSrc.y + szOffset.cy;
}
if (IsWindow(lpUIExtra->uiComp.hWnd))
InvalidateRect(lpUIExtra->uiComp.hWnd,NULL,FALSE);
break;
case IMN_GUIDELINE:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_GUIDELINE\n"));
break;
case IMN_SETSTATUSWINDOWPOS:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_SETSTATUSWINDOWPOS\n"));
break;
case IMN_PRIVATE:
DebugLog(1,(DebugLogFile,"UIWnd:WM_IME_NOTIFY:IMN_PRIVATE\n"));
break;
default:
break;
}
GlobalUnlock(hUIExtra);
ImmUnlockIMC(hUICurIMC);
return lRet;
}
/**********************************************************************/
/* */
/* ControlHandle() */
/* */
/* Handle WM_IME_CONTROL messages. */
/* */
/**********************************************************************/
LONG ControlHandle(HIMC hUICurIMC, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return 0L;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -