⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myime.cpp

📁 与游戏,网络,输入法相关
💻 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 + -