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

📄 utf8edit.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
字号:
/*____________________________________________________________________________
		Copyright (C) 2002 PGP Corporation
        All rights reserved.

        $Id: UTF8Edit.c,v 1.14 2002/11/21 22:01:58 pbj Exp $
	
	This code subclasses an Edit control window so as to facilitate
	the use of UTF8 with the window.  This subclassing causes all 
	text sent to the window to be interpretted as UTF-8.  The text sent
	to the window is converted to UCS-2 and displayed as unicode text on
	systems that support Unicode.

	On NT/2K/XP we just subclass the edit control directly.  On 9x we
	actually create a new "RichEdit20W" window directly over the edit
	control subclass that new windows.  The original edit box is disabled
	and hidden.

    This approach better allows edit control to look/work as "normal" 
	edit controls.
	
____________________________________________________________________________*/

#include "windows.h"
#include "richedit.h"
#include "shlwapi.h"
#include "pgpUnicode.h"
#include "pgpUnicodeWin32.h"

#include "UTF8Edit.h"

// macro defitions
#define PACKVERSION(major,minor) MAKELONG(minor,major)

typedef struct
{
	HWND		hwndEdit;
	HWND		hwndRichEdit;
	BOOL		bUnicodeOS;
	WNDPROC		wpOrigProc;
	HFONT		hFont;
	UINT		uControlID;
} UTF8EditStruct;


//	______________________________________
//
//  edit box subclass procedure

static LRESULT APIENTRY 
sSubclassProc (
		HWND	hWnd, 
		UINT	uMsg, 
		WPARAM	wParam, 
		LPARAM	lParam) 
{
	UTF8EditStruct*	pues;

	pues = (UTF8EditStruct*)GetWindowLong (hWnd, GWL_USERDATA);

	if (uMsg == WM_HELP)
	{
		if (pues->hwndRichEdit)
		{
			// substitute in identifying info of edit control so as to allow
			// context-sensitive help to work for RichEdit control
			LPHELPINFO	lphi	= (LPHELPINFO)lParam;

			lphi->dwContextId = pues->uControlID;
			lphi->hItemHandle = pues->hwndEdit;
		}
	}

	if (pues->bUnicodeOS)
	{
		return CallWindowProcW (pues->wpOrigProc, 
				hWnd, uMsg, wParam, lParam);
	}
	else
	{
		return CallWindowProcA (pues->wpOrigProc, 
				hWnd, uMsg, wParam, lParam);
	}
} 


//	_______________________________________________
//
//  get the version number of ComCtl32.dll

static DWORD 
sGetComCtl32Version (VOID)
{
    HINSTANCE	hinstDll;
    DWORD		dwVersion = 0;

    hinstDll = LoadLibrary (TEXT("comctl32.dll"));
    if (hinstDll)
    {
        DLLGETVERSIONPROC pDllGetVersion;
        pDllGetVersion = 
				(DLLGETVERSIONPROC)GetProcAddress (hinstDll, "DllGetVersion");

        if (pDllGetVersion)
        {
            DLLVERSIONINFO	dvi;
            HRESULT			hr;

            ZeroMemory (&dvi, sizeof(dvi));
            dvi.cbSize = sizeof(dvi);

            hr = (*pDllGetVersion)(&dvi);

            if (SUCCEEDED(hr))
				dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
        }

        FreeLibrary(hinstDll);
    }
    return dwVersion;
}


//	______________________________________
//
//  initialize the subclassing

HWND
UTF8EditInit (
	   HWND		hwndEdit)
{
	OSVERSIONINFO	osvi={0};
	UTF8EditStruct*	pues=NULL;

	LOGFONT			lf;
	RECT			rc;
	DWORD			dwStyle;

	pues = malloc (sizeof(UTF8EditStruct));
	memset (pues, 0, sizeof(UTF8EditStruct));
	pues->hwndEdit = hwndEdit;
	pues->uControlID = GetDlgCtrlID (hwndEdit);

	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx (&osvi);
	pues->bUnicodeOS = (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT);

	SetWindowLong (hwndEdit, GWL_USERDATA, (LONG)pues);
	SetProp (hwndEdit, "UTF8Edit", (HANDLE)1);

	// if older than WinXP's version of Common Controls, 
	// then use the RichEdit control
	if (sGetComCtl32Version() < PACKVERSION(6,0))
	{
		// deal with edit window itself
		dwStyle = GetWindowLong (hwndEdit, GWL_STYLE);
		GetWindowRect (hwndEdit, &rc);
		ShowWindow (hwndEdit, SW_HIDE);
		EnableWindow (hwndEdit, FALSE);

		// create the RichEdit window
		MapWindowPoints (NULL, GetParent (hwndEdit), (LPPOINT)&rc, 2);
		dwStyle |= WS_BORDER;
		rc.top -= 1;
		rc.left -= 1;
		pues->hwndRichEdit = CreateWindowEx (0, "RichEdit20W", NULL,
				dwStyle, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, 
				GetParent (hwndEdit), NULL, NULL, 0);

		SetWindowPos (pues->hwndRichEdit, hwndEdit, 0, 0, 0, 0,
				SWP_NOMOVE | SWP_NOSIZE);

		if (dwStyle & ES_READONLY)
		{
			SendMessage (pues->hwndRichEdit, EM_SETBKGNDCOLOR, 
					0, GetSysColor (COLOR_BTNFACE));
		}

		//>>> the following line is RichEdit 3.0 specific
		SendMessage (pues->hwndRichEdit, 
				EM_SETEDITSTYLE, SES_USEAIMM, SES_USEAIMM);

		//>>> the following line is RichEdit 3.0 specific
		SendMessage (pues->hwndRichEdit, EM_SETEDITSTYLE, 
				SES_EMULATESYSEDIT, SES_EMULATESYSEDIT);

		SystemParametersInfo (
				SPI_GETICONTITLELOGFONT, sizeof(LOGFONT), &lf, 0);
		pues->hFont = CreateFontIndirect (&lf);
		SendMessage (pues->hwndRichEdit, WM_SETFONT, (WPARAM)pues->hFont, 0);

		SetWindowLong (pues->hwndRichEdit, GWL_USERDATA, (LONG)pues);

		SetProp (pues->hwndRichEdit, "UTF8Edit", (HANDLE)1);
	}
	else
	{
		// if using the standard edit control on WinXP, set the font
		// to DEFAULT_GUI_FONT, it seems to have better Unicode support
		GetObject (GetStockObject (DEFAULT_GUI_FONT), 
				sizeof(LOGFONT), &lf);
		pues->hFont = CreateFontIndirect (&lf);
		SendMessage (hwndEdit, WM_SETFONT, (WPARAM)pues->hFont, 0);
	}

	// if this is a unicode OS (NT onwards), subclass with SetWindowLongW
	if (pues->bUnicodeOS)
	{
		if (pues->hwndRichEdit)
		{
			pues->wpOrigProc = (WNDPROC) SetWindowLongW (pues->hwndRichEdit, 
					GWL_WNDPROC, (LONG)sSubclassProc);
		}
		else
		{
			pues->wpOrigProc = (WNDPROC) SetWindowLongW (hwndEdit, 
					GWL_WNDPROC, (LONG)sSubclassProc);
		}
	}
	// otherwise use SetWindowLong
	else
	{
		// if not Unicode we know we're using the RichEdit control
		pues->wpOrigProc = (WNDPROC) SetWindowLong (pues->hwndRichEdit, 
				GWL_WNDPROC, (LONG)sSubclassProc);
	}

	if (pues->hwndRichEdit)
		return pues->hwndRichEdit;
	else
		return hwndEdit;
}

VOID 
UTF8EditDestroy (HWND hwndEdit)
{
	UTF8EditStruct*	pues;

	pues = (UTF8EditStruct*)GetWindowLong (hwndEdit, GWL_USERDATA);

	if (pues)
	{
		if (pues->bUnicodeOS)
		{
			if (pues->hwndRichEdit)
			{
				SetWindowLongW (pues->hwndRichEdit, 
						GWL_WNDPROC, (LONG)pues->wpOrigProc);
			}
			else
			{
				SetWindowLongW (hwndEdit, 
						GWL_WNDPROC, (LONG)pues->wpOrigProc);
			}
		}
		else
		{
			// if not Unicode we know we're using the RichEdit control
			SetWindowLong (pues->hwndRichEdit, 
					GWL_WNDPROC, (LONG)pues->wpOrigProc);
		}

		if (pues->hFont)
			DeleteObject (pues->hFont);

		if (pues->hwndRichEdit)
		{
			RemoveProp (pues->hwndRichEdit, "UTF8Edit");
			DestroyWindow (pues->hwndRichEdit);
		}

		SetWindowLong (hwndEdit, GWL_USERDATA, (LONG)0);
		RemoveProp (hwndEdit, "UTF8Edit");

		free (pues);
	}
}


//	______________________________________
//
//  get/set text

INT
UTF8EditGetTextLength (HWND hwnd)
{
	UINT			uout	= 0;
	UINT			ulen;
	WCHAR*			wsz;
	UTF8EditStruct*	pues;
	HWND			hwndEdit;

	pues = (UTF8EditStruct*)GetWindowLong (hwnd, GWL_USERDATA);

	if (pues->bUnicodeOS)
	{
		if (pues->hwndRichEdit)
			hwndEdit = pues->hwndRichEdit;
		else
			hwndEdit = hwnd;

		ulen = CallWindowProcW (pues->wpOrigProc, 
				hwndEdit, WM_GETTEXTLENGTH, 0, 0) +1;

		wsz = malloc (ulen * sizeof(WCHAR));
		if (wsz)
		{
			ulen = CallWindowProcW (pues->wpOrigProc, 
					hwndEdit, WM_GETTEXT, (WPARAM)ulen, (LPARAM)wsz);

			if (ulen)
				pgpUCS2StringToUTF8 (wsz, ulen, NULL, 0, &uout);

			free (wsz);
		}
	}
	else
	{
		GETTEXTLENGTHEX		gtle;

		gtle.codepage = 1200; // Unicode
		gtle.flags = GTL_NUMCHARS | GTL_CLOSE;

		ulen = CallWindowProcA (pues->wpOrigProc, 
				pues->hwndRichEdit, EM_GETTEXTLENGTHEX, (WPARAM)&gtle, 0) +1;

		wsz = malloc (ulen * sizeof(WCHAR));
		if (wsz)
		{
			GETTEXTEX	gte;

			memset (&gte, 0, sizeof(GETTEXTEX));
			gte.cb = ulen * sizeof(WCHAR);
			gte.codepage = 1200; // Unicode

			ulen = CallWindowProcA (pues->wpOrigProc, 
					pues->hwndRichEdit, EM_GETTEXTEX, (WPARAM)&gte, (LPARAM)wsz);

			if (ulen)
			{
				pgpUCS2StringToUTF8 (wsz, ulen, 
						NULL, 0, &uout);
			}
			free (wsz);
		}
	}
	return uout;
}

INT
UTF8EditGetText (
		HWND	hwnd, 
		LPSTR	pszOut, 
		UINT	ubuflen)
{
	UINT			uout	= 0;
	UINT			ulen;
	WCHAR*			wsz;
	UTF8EditStruct*	pues;
	HWND			hwndEdit;

	pues = (UTF8EditStruct*)GetWindowLong (hwnd, GWL_USERDATA);

	if (pues->bUnicodeOS)
	{
		if (pues->hwndRichEdit)
			hwndEdit = pues->hwndRichEdit;
		else
			hwndEdit = hwnd;

		ulen = CallWindowProcW (pues->wpOrigProc, 
				hwndEdit, WM_GETTEXTLENGTH, 0, 0) +1;

		wsz = malloc (ulen * sizeof(WCHAR));
		if (wsz)
		{
			ulen = CallWindowProcW (pues->wpOrigProc, 
					hwndEdit, WM_GETTEXT, (WPARAM)ulen, (LPARAM)wsz);

			if (ulen==0)
			{
				if(ubuflen>=1)
				{
					pszOut[0]=0;
				}
			}
			else
			{
				pgpUCS2StringToUTF8 (wsz, ulen, 
						pszOut, ubuflen, &uout);
			}
			free (wsz);
		}
	}
	else
	{
		ulen = CallWindowProcA (pues->wpOrigProc, 
				pues->hwndRichEdit, WM_GETTEXTLENGTH, 0, 0) +1;

		wsz = malloc (ulen * sizeof(WCHAR));
		if (wsz)
		{
			GETTEXTEX	gte;

			memset (&gte, 0, sizeof(GETTEXTEX));
			gte.cb = ulen * sizeof(WCHAR);
			gte.codepage = 1200; // Unicode

			ulen = CallWindowProcA (pues->wpOrigProc, 
					pues->hwndRichEdit, EM_GETTEXTEX, (WPARAM)&gte, (LPARAM)wsz);

			if (ulen==0)
			{
				if(ubuflen>=1)
				{
					pszOut[0]=0;
				}
			}
			else
			{
				pgpUCS2StringToUTF8 (wsz, ulen, 
						pszOut, ubuflen, &uout);
			}
			free (wsz);
		}
	}

	return uout;
}

INT
UTF8EditSetText (
		HWND	hwnd, 
		LPSTR	psz)
{
	WCHAR*			wsz;
	UINT			ulen, uret;
	UTF8EditStruct*	pues;
	HWND			hwndEdit;

	pues = (UTF8EditStruct*)GetWindowLong (hwnd, GWL_USERDATA);

	pgpUTF8StringToUCS2 (psz, kPGPUnicodeNullTerminated, NULL, 0, &ulen);

	wsz = (WCHAR*)malloc ((ulen+1) * sizeof(WCHAR));
	if (wsz)
	{
		pgpUTF8StringToUCS2 (psz, kPGPUnicodeNullTerminated, wsz, ulen+1, NULL);

		if (pues->hwndRichEdit)
			hwndEdit = pues->hwndRichEdit;
		else
			hwndEdit = hwnd;

		if (pues->bUnicodeOS)
		{
			uret = CallWindowProcW (pues->wpOrigProc, 
					hwndEdit, WM_SETTEXT, 0, (LPARAM)wsz);
		}
		else
		{
			uret = CallWindowProcA (pues->wpOrigProc, 
					hwndEdit, WM_SETTEXT, 0, (LPARAM)wsz);
		}

		free (wsz);
	}

	return uret;
}

HWND
UTF8EditGetHandle (
		HWND	hwnd)
{
	UTF8EditStruct*	pues;

	if (GetProp (hwnd, "UTF8Edit") != NULL)
	{
		pues = (UTF8EditStruct*)GetWindowLong (hwnd, GWL_USERDATA);

		if (pues)
		{
			if (pues->hwndRichEdit)
				return pues->hwndRichEdit;
		}
	}

	return hwnd;
}


HWND
UTF8EditGetEditHandle (
		HWND	hwnd)
{
	UTF8EditStruct*	pues;

	if (GetProp (hwnd, "UTF8Edit") != NULL)
	{
		pues = (UTF8EditStruct*)GetWindowLong (hwnd, GWL_USERDATA);

		if (pues)
		{
			return pues->hwndEdit;
		}
	}

	return hwnd;
}


/*__Editor_settings____

	Local Variables:
	tab-width: 4
	End:
	vi: ts=4 sw=4
	vim: si
_____________________*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -