📄 myime.cpp
字号:
// 输入法管理演示代码
// 作者: Janhail Luo
// 最后整理: 2003-03-03
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "stdlib.h"
#include "stdio.h"
#pragma comment(lib, "imm32.lib")
#define MAX_LOADSTRING 100
// Global Variables:
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
HINSTANCE g_hInstance;
HWND g_hWnd;
HWND g_hWndComposition;
HWND g_hWndCandidate;
HWND g_hWndStatus;
HWND g_hText;
char g_szLanguageName[200];
char g_szBuf[1024];
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
DWORD HandleCandidate(HWND hWnd);
BOOL HandleConversion(HWND hWnd, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence);
BOOL HandleGetOpenStatus(HWND hWnd);
LONG HandleComposition(HWND hWnd);
int HandleChangeLanguage(char* lpszIMENameBuf, long lBufSize);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
g_hInstance = hInstance;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_MYIME, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_MYIME);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_MYIME);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCSTR)IDC_MYIME;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
g_hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
0, 0, 200, 400, NULL, NULL, hInstance, NULL);
g_hText = CreateWindow("EDIT", "Text", WS_POPUPWINDOW | ES_MULTILINE,
205, 0, 200, 50, g_hWnd, 0, g_hInstance, 0);
g_hWndComposition = CreateWindow("EDIT", "Composition", WS_POPUPWINDOW | ES_MULTILINE,
205, 50, 200, 50, g_hWnd, 0, g_hInstance, 0);
g_hWndCandidate = CreateWindow("LISTBOX", "Candidate", WS_POPUPWINDOW,
205, 100, 200, 250, g_hWnd, 0, g_hInstance, 0);
g_hWndStatus = CreateWindow("EDIT", "Status", WS_POPUPWINDOW | ES_MULTILINE,
205, 350, 200, 50, g_hWnd, 0, g_hInstance, 0);
ShowWindow(g_hText, nCmdShow);
UpdateWindow(g_hText);
ShowWindow(g_hWnd, nCmdShow);
UpdateWindow(g_hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
DWORD dwConversion, dwSentence;
HIMC hIMC;
int len;
switch (message)
{
case WM_CREATE:
HandleChangeLanguage(g_szLanguageName, 200);
hIMC = ImmCreateContext();
hIMC = ImmAssociateContext(hWnd,hIMC);
SetWindowLong(hWnd,0,(LONG)hIMC);
CreateWindow("Ime", "", WS_POPUP | WS_DISABLED, 0,0,0,0, hWnd, NULL, g_hInstance, NULL);
g_szBuf[0] = 0;
break;
case WM_DESTROY:
hIMC = (HIMC)GetWindowLong(hWnd,0);
hIMC = ImmAssociateContext(hWnd,hIMC);
ImmDestroyContext(hIMC);
PostQuitMessage(0);
break;
case WM_SETFOCUS:
HandleChangeLanguage(g_szLanguageName, 200);
break;
case WM_INPUTLANGCHANGE:
HandleChangeLanguage(g_szLanguageName, 200);
break;
case WM_CHAR:
len = strlen(g_szBuf);
if (len<1023)
{
if (wParam==8)
{
if (len>0) g_szBuf[len-1] = 0;
}else
{
g_szBuf[len] = (char)wParam;
g_szBuf[len+1] = 0;
}
::SetWindowText(g_hText, g_szBuf);
}
break;
case WM_IME_NOTIFY:
switch (wParam)
{
// IMN Open Candidate
case IMN_OPENCANDIDATE:
OutputDebugString("\nIMN Open Candidate");
::ShowWindow(g_hWndCandidate, SW_SHOW);
::UpdateWindow(g_hWndCandidate);
::SetFocus(g_hWnd);
HandleCandidate(hWnd);
break;
// IMN Close Candidate
case IMN_CLOSECANDIDATE:
OutputDebugString("\nIMN Close Candidate");
::ShowWindow(g_hWndCandidate, SW_HIDE);
break;
// IMN Change Candidate
case IMN_CHANGECANDIDATE:
HandleCandidate(hWnd);
break;
// IMN Set Candidate Pos
case IMN_SETCANDIDATEPOS:
OutputDebugString("\nIMN Set Candidate Pos");
HandleCandidate(hWnd);
break;
// IMN Set Conversion Mode
case IMN_SETCONVERSIONMODE:
OutputDebugString("\nIMN Set Conversion Mode");
HandleConversion(hWnd, &dwConversion, &dwSentence);
break;
// IMN Set Sentence Mode
case IMN_SETSENTENCEMODE:
OutputDebugString("\nIMN Set Sentence Mode");
HandleConversion(hWnd, &dwConversion, &dwSentence);
break;
// IMN Open Status Window
case IMN_OPENSTATUSWINDOW:
OutputDebugString("\nIMN Open Status Window");
HandleGetOpenStatus(hWnd);
HandleConversion(hWnd, &dwConversion, &dwSentence);
break;
// IMN Close Status Window
case IMN_CLOSESTATUSWINDOW:
OutputDebugString("\nIMN Close Status Window");
HandleGetOpenStatus(hWnd);
break;
// IMN Set Open Status
case IMN_SETOPENSTATUS:
OutputDebugString("\nIMN Set Open Status");
HandleGetOpenStatus(hWnd);
break;
// IMN Set Composition Window
case IMN_SETCOMPOSITIONWINDOW:
OutputDebugString("\nIMN Set Composition Window");
break;
}
break;
case WM_IME_STARTCOMPOSITION:
OutputDebugString("\nIME Composition Start");
::ShowWindow(g_hWndComposition, SW_SHOW);
::UpdateWindow(g_hWndComposition);
::SetFocus(g_hWnd);
HandleComposition(hWnd);
break;
case WM_IME_ENDCOMPOSITION:
OutputDebugString("\nIME Composition End");
::ShowWindow(g_hWndComposition, SW_HIDE);
break;
case WM_IME_COMPOSITION:
char buf[20];
buf[0] = '\n';
buf[1] = '-';
buf[3] = wParam&0x0FF;
buf[2] = (wParam&0x0FF00)>>8;
buf[4] = 0;
OutputDebugString(buf);
HandleComposition(hWnd);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(g_hInstance, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return DefWindowProc(hWnd, message, wParam, lParam);
return 0;
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
BOOL HandleGetOpenStatus(HWND hWnd)
{
HIMC hIMC;
hIMC = ::ImmGetContext(hWnd);
BOOL ret = ::ImmGetOpenStatus(hIMC);
::ImmReleaseContext(hWnd,hIMC);
#ifdef _DEBUG
char pOutputBuf[40];
sprintf(pOutputBuf, "\nIME Status is %s", ret?"Open":"Close");
::OutputDebugString(pOutputBuf);
#endif
return ret;
}
BOOL HandleConversion(HWND hWnd, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
{
HIMC hIMC;
hIMC = ::ImmGetContext(hWnd);
BOOL ret = ::ImmGetConversionStatus(hIMC, lpfdwConversion, lpfdwSentence);
::ImmReleaseContext(hWnd,hIMC);
char pOutputBuf[200];
sprintf(pOutputBuf, "%s\r\n模式:", g_szLanguageName);
if (*lpfdwConversion & 0x01) strcat(pOutputBuf, " 中文");
else strcat(pOutputBuf, " 英文");
if (*lpfdwConversion & 0x08) strcat(pOutputBuf, " 全角");
else strcat(pOutputBuf, " 半角");
if (*lpfdwConversion & 0x400) strcat(pOutputBuf, " 中文标点");
else strcat(pOutputBuf, " 英文标点");
if (*lpfdwConversion & 0x80) strcat(pOutputBuf, " 软键盘");
SetWindowText(g_hWndStatus, pOutputBuf);
#ifdef _DEBUG
sprintf(pOutputBuf, "\n Conversion = 0x%X, Sentence = 0x%X\n ", *lpfdwConversion, *lpfdwSentence);
::OutputDebugString(pOutputBuf);
::OutputDebugString(pOutputBuf);
#endif
return ret;
}
DWORD HandleCandidate(HWND hWnd)
{
HIMC hIMC;
unsigned long dwCount, dwSize, i, j;
char* pBuf;
LPCANDIDATELIST pList;
hIMC = ::ImmGetContext(hWnd);
dwSize = ::ImmGetCandidateListCount(hIMC, &dwCount);
pBuf = new char[dwSize];
pList = (LPCANDIDATELIST)pBuf;
#ifdef _DEBUG
char pOutputBuf[40];
sprintf(pOutputBuf, "\nCount= %d, size= %d", dwCount, dwSize);
::OutputDebugString(pOutputBuf);
#endif
while (::SendMessage(g_hWndCandidate, LB_GETCOUNT, 0, 0))
::SendMessage(g_hWndCandidate, LB_DELETESTRING, 0, 0);
for (i=0; i<dwCount; i++)
{
::ImmGetCandidateList(hIMC, i, pList,dwSize);
for (j=0; j<pList->dwPageSize; j++)
::SendMessage(g_hWndCandidate, LB_ADDSTRING, 0, (DWORD)pBuf+pList->dwOffset[pList->dwPageStart+j]);
::SendMessage(g_hWndCandidate, LB_SETCURSEL, pList->dwSelection, 0);
#ifdef _DEBUG
sprintf(pOutputBuf, "\nList[%d]:", pList->dwPageSize);
::OutputDebugString(pOutputBuf);
for (j=0; j<pList->dwPageSize; j++)
{
::OutputDebugString(" ");
::OutputDebugString(pBuf+pList->dwOffset[pList->dwPageStart+j]);
}
::OutputDebugString("\nSel: ");
::OutputDebugString(pBuf+pList->dwOffset[pList->dwSelection]);
#endif
}
delete[] pBuf;
::ImmReleaseContext(hWnd,hIMC);
return dwCount;
}
LONG HandleComposition(HWND hWnd)
{
HIMC hIMC = ::ImmGetContext(hWnd);
LONG lSize = ::ImmGetCompositionString(hIMC, GCS_COMPSTR, 0, 0);
if (lSize==0) return 0;
char* pString = new char[lSize+1];
::ImmGetCompositionString(hIMC, GCS_COMPSTR, pString, lSize);
pString[lSize] = '\0';
SetWindowText(g_hWndComposition, pString);
#ifdef _DEBUG
::OutputDebugString("\n");
::OutputDebugString(pString);
#endif
delete[] pString;
::ImmReleaseContext(hWnd, hIMC ) ;
return lSize ;
}
int HandleChangeLanguage(char* lpszIMENameBuf, long lBufSize)
{
HKL hKL = ::GetKeyboardLayout(0);
int iSize = ::ImmGetDescription(hKL, NULL, 0);
if (iSize>=lBufSize) return -1;
if (iSize==0)
{
::ShowWindow(g_hWndStatus, SW_HIDE);
#ifdef _DEBUG
::OutputDebugString("\n输入法关闭");
#endif
}else
{
::ShowWindow(g_hWndStatus, SW_SHOW);
::UpdateWindow(g_hWndStatus);
::SetFocus(g_hWnd);
::ImmGetDescription(hKL, lpszIMENameBuf, lBufSize);
#ifdef _DEBUG
::OutputDebugString("\n输入法:");
::OutputDebugString(lpszIMENameBuf);
#endif
}
return iSize;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -