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

📄 reitp.c

📁 文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 *	reitp.c
 *	
 *	Purpose:
 *		Test program for RichEdit.  Excercises main RichEdit
 *		functionality while providing a good replacement for notepad.
 *	
 *	Owner:
 */

#include "preinc.h"

#include <windows.h>
#include <windowsx.h>

#include <commdlg.h>
#include <cderr.h>
#include <ctype.h>
#include <stdio.h>
#include <tchar.h>

// for the benefit of the outside world,
// richedit.h uses cpMax instead of cpMost
// I highly prefer cpMost
#ifdef cpMax
#error "cpMax hack won't work"
#endif	// cpMax
#define cpMax cpMost
#include <richedit.h>
#undef cpMax

#include "olestd.h"
#include "reguid.h"
#include "dbugit.h"
#include <richole.h>

#include "reitp.h"
#include "reitp.rh"
#include "frmtbar.h"
#include <oledlg.h>


ASSERTDATA


#define SUNKENRICHEDIT

// define to use LiFormatRange() directly instead of via blitting
//#define NOBLIT

// used to make life simpler while testing, should not normally be defined
//#define NO_SAVE_PROMPT

#define CFM_EFFECTS (CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | \
						CFM_STRIKEOUT)

struct _itpcall;

typedef struct _pp
{
	BOOL fDone;
	HWND hwndDlg;
	REDOC *predoc;
	LONG cchText;
	LONG dxPage;
	LONG dyPage;
	RECT rc;
	FORMATRANGE fr;
#ifndef NOBLIT
	HBITMAP hbmp;
	HBITMAP hbmpOld;
	INT dxBmp;
	INT dyBmp;
#endif	// !NOBLIT
	INT ipage;
	INT cpage;
	INT cpageMost;
	LONG *rgcpPages;
} PRINTPREVIEW;

// number of pages to allocate at once in PRINTPREVIEW.rgcpPages
#define cpageChunk 4

#define szFmtPrintPreview TEXT("Print Preview - Page %d")

typedef struct _assensz
{
	WORD wNotification;
	LPCSTR szDescription;
} ASSENSZ;

// added to the client rect to get the RichEdit size
#ifdef SUNKENRICHEDIT
#define dxRESize -GetSystemMetrics(SM_CXBORDER)
#define dyRESize -GetSystemMetrics(SM_CYBORDER)
#else	// SUNKENRICHEDIT
#define dxRESize 0
#define dyRESize 0
#endif	// SUNKENRICHEDIT, else

// Control ID for the format bar
#define	FBR_FormatBar	217

#define HinstFromHwnd(_hwnd) ((HINSTANCE) GetWindowLong(_hwnd, GWL_HINSTANCE))

#define uiMFDisabled MF_DISABLED | MF_GRAYED
#define uiMFEnabled MF_ENABLED

// Maximum text to be corrected under PenWin
#define cchMaxCorrectText		4096

#define szClosedName szAppName

static TCHAR szAppName[] = TEXT("REITP");
static const TCHAR szClassRE[] = TEXT(RICHEDIT_CLASS);

static const TCHAR szFmtTitle[] = TEXT("REITP - %s");
static const TCHAR szUntitled[] = TEXT("[Untitled]");
static const TCHAR szRTFSig[] = TEXT("{\\rtf");
#define cchRTFSig 5
static TCHAR szRegKey[] = TEXT("software\\microsoft\\reitp");
static TCHAR szRegValue[] = TEXT("placement");
static const POINT ptMinTrackSize = {300, 90};
// Make sure that these strings match the order of SF_*
static TCHAR szFilterLoad[] = TEXT("Text and Rich Text\0*.TXT;*.RTF\0Text Files (*.TXT)\0*.TXT\0Rich Text Format (*.RTF)\0*.RTF\0All Files\0*.*\0\0");
static TCHAR szFilterSave[] = TEXT("Text Files (*.TXT)\0*.TXT\0Rich Text Format (*.RTF)\0*.RTF\0RTF w/o Objects (*.RTF)\0*.RTF\0Textized\0*.TXT\0\0");

static HMODULE hmod = 0;		// Flag for FreeLibrary()
HWND hwndMain = 0;
static HMENU hmenuLoaded = 0;
HMENU hmenuFull = 0;
static PRINTDLG pdDef = {0};
static BOOL fPrint = fFalse;
static BOOL fWysiwygDefault = fFalse;
static BOOL fWrapDefault = fTrue;
static UINT msgFindReplace = 0;
static HWND hwndFR = 0;					// find/replace dialog
HINSTANCE hinst = 0;

static LONG cchTextMost = 0;
static CLIPFORMAT cfTxtObj = 0;
static BOOL fErrSpace = fFalse;




static CHARFORMAT cfDefault =
{
	sizeof(CHARFORMAT),
	CFM_EFFECTS | CFM_PROTECTED | CFM_SIZE | CFM_OFFSET | CFM_COLOR | CFM_CHARSET | CFM_FACE,
	CFE_AUTOCOLOR,		// effects
	200,				// height, 200 twips == 10 points
	0,					// offset
	0,					// color (not used since CFE_AUTOCOLOR is specified)
	ANSI_CHARSET,
	FF_ROMAN,			// pitch and family
	"Arial"				// face name
};

static ASSENSZ rgassenszErrors[] =
{
	{EN_ERRSPACE, "Out of memory. Exit some other applications and try again."},
	{EN_MAXTEXT, "The maximum text length has been reached."},
	{0, NULL}
};

/*
 *	ITPOLEINPLACEFRAME
 *	
 *	Purpose:
 *		Frame window support for in place editing
 */
typedef struct _itpoleinplaceframe
{
	IOleInPlaceFrameVtbl * lpVtbl;		// Virtual table
	ULONG cRef;						// Reference count
	REDOC * predoc;					// Document
	LPOLEINPLACEACTIVEOBJECT pipaobj;		// Current active object
}
ITPOLEINPLACEFRAME;

#define PipframeFromPunk(_p) ((ITPOLEINPLACEFRAME *) (_p))

// Functions for ITP in place frame
ITPOLEINPLACEFRAME * ITPOLEINPLACEFRAME_New(REDOC * predoc);
STDMETHODIMP ITPOLEINPLACEFRAME_QueryInterface(LPUNKNOWN punk, REFIID riid,
											   LPUNKNOWN * ppvObj);
STDMETHODIMP_(ULONG) ITPOLEINPLACEFRAME_AddRef(LPUNKNOWN punk);
STDMETHODIMP_(ULONG) ITPOLEINPLACEFRAME_Release(LPUNKNOWN punk);
STDMETHODIMP ITPOLEINPLACEFRAME_GetWindow(ITPOLEINPLACEFRAME * pipframe,
										  HWND * phwnd);
STDMETHODIMP ITPOLEINPLACEFRAME_ContextSensitiveHelp(ITPOLEINPLACEFRAME *pipframe,
													 BOOL fEnterMode);
STDMETHODIMP ITPOLEINPLACEFRAME_GetBorder(ITPOLEINPLACEFRAME * pipframe,
										  LPRECT prcBorder);
STDMETHODIMP ITPOLEINPLACEFRAME_RequestBorderSpace(ITPOLEINPLACEFRAME * pipframe,
												   LPCBORDERWIDTHS pbw);
STDMETHODIMP ITPOLEINPLACEFRAME_SetBorderSpace(ITPOLEINPLACEFRAME * pipframe,
											   LPCBORDERWIDTHS pbw);
STDMETHODIMP ITPOLEINPLACEFRAME_SetActiveObject(ITPOLEINPLACEFRAME * pipframe,
											    LPOLEINPLACEACTIVEOBJECT pipaobj,
											    LPCSTR szObjName); 
STDMETHODIMP ITPOLEINPLACEFRAME_InsertMenus(ITPOLEINPLACEFRAME * pipframe,
										    HMENU hmenuShared, 
										    LPOLEMENUGROUPWIDTHS pmgw);
STDMETHODIMP ITPOLEINPLACEFRAME_SetMenu(ITPOLEINPLACEFRAME * pipframe, 
									    HMENU hmenuShared, HOLEMENU holemenu, 
									    HWND hwndActiveObject);
STDMETHODIMP ITPOLEINPLACEFRAME_RemoveMenus(ITPOLEINPLACEFRAME * pipframe, 
										    HMENU hmenuShared);
STDMETHODIMP ITPOLEINPLACEFRAME_SetStatusText(ITPOLEINPLACEFRAME * pipframe, 
											  LPCSTR szStatusText);    
STDMETHODIMP ITPOLEINPLACEFRAME_EnableModeless(ITPOLEINPLACEFRAME * pipframe, 
											   BOOL fEnable);
STDMETHODIMP ITPOLEINPLACEFRAME_TranslateAccelerator(ITPOLEINPLACEFRAME *pipframe,
													 LPMSG pmsg, WORD wID);

// Virtual table for ole in place frame interface
IOleInPlaceFrameVtbl ITPOLEINPLACEFRAME_Vtbl =
{
	(LPVOID) ITPOLEINPLACEFRAME_QueryInterface,
	(LPVOID) ITPOLEINPLACEFRAME_AddRef,
	(LPVOID) ITPOLEINPLACEFRAME_Release,
	(LPVOID) ITPOLEINPLACEFRAME_GetWindow,
	(LPVOID) ITPOLEINPLACEFRAME_ContextSensitiveHelp,
	(LPVOID) ITPOLEINPLACEFRAME_GetBorder,
	(LPVOID) ITPOLEINPLACEFRAME_RequestBorderSpace,
	(LPVOID) ITPOLEINPLACEFRAME_SetBorderSpace,
	(LPVOID) ITPOLEINPLACEFRAME_SetActiveObject,
	(LPVOID) ITPOLEINPLACEFRAME_InsertMenus,
	(LPVOID) ITPOLEINPLACEFRAME_SetMenu,
	(LPVOID) ITPOLEINPLACEFRAME_RemoveMenus,
	(LPVOID) ITPOLEINPLACEFRAME_SetStatusText,
	(LPVOID) ITPOLEINPLACEFRAME_EnableModeless,
	(LPVOID) ITPOLEINPLACEFRAME_TranslateAccelerator
};


/*
 *	ITPCALL
 *	
 *	Purpose:
 *		Callbacks from the Rich Edit OLE support
 */

typedef struct _itpcall
{
	IRichEditOleCallbackVtbl * lpVtbl;	// Virtual table
	ULONG cRef;						    // Reference count
	REDOC * predoc;						// Document
	ITPOLEINPLACEFRAME * pipframe;		// In place frame object
}
ITPCALL;


#define PitpcallFromPunk(_p) ((ITPCALL *) (_p))

// Functions for ITP callbacks
ITPCALL * ITPCALL_New(REDOC * predoc);
STDMETHODIMP ITPCALL_QueryInterface(LPUNKNOWN punk, REFIID riid,
								    LPUNKNOWN * ppvObj);
STDMETHODIMP_(ULONG) ITPCALL_AddRef(LPUNKNOWN punk);
STDMETHODIMP_(ULONG) ITPCALL_Release(LPUNKNOWN punk);
STDMETHODIMP ITPCALL_GetNewStorage(ITPCALL * pitpcall, LPSTORAGE FAR * ppstg);
STDMETHODIMP ITPCALL_GetInPlaceContext(ITPCALL * pitpcall, 
									   LPOLEINPLACEFRAME FAR * ppipframe,
									   LPOLEINPLACEUIWINDOW FAR* ppipuiDoc,
									   LPOLEINPLACEFRAMEINFO pipfinfo);
STDMETHODIMP ITPCALL_ShowContainerUI(ITPCALL * pitpcall, BOOL fShow);
STDMETHODIMP ITPCALL_QueryInsertObject(ITPCALL * pitpcall, LPCLSID pclsid,
				LPSTORAGE pstg, LONG cp);
STDMETHODIMP ITPCALL_DeleteObject(ITPCALL * pitpcall, LPOLEOBJECT poleobj);
STDMETHODIMP ITPCALL_QueryAcceptData(ITPCALL * pitpcall, LPDATAOBJECT pdataobj,
				CLIPFORMAT *pcfFormat, DWORD reco, BOOL fReally,
				HGLOBAL hMetaPict);
STDMETHODIMP ITPCALL_ContextSensitiveHelp(ITPCALL * pitpcall, BOOL fEnterMode);
STDMETHODIMP ITPCALL_GetClipboardData(ITPCALL *pitpcall, CHARRANGE *pchrg,
				DWORD reco, LPDATAOBJECT *ppdataobj);
STDMETHODIMP ITPCALL_GetDragDropEffect(ITPCALL *pitpcall, BOOL fDrag,
				DWORD grfKeyState, LPDWORD pdwEffect);
STDMETHODIMP ITPCALL_GetContextMenu(ITPCALL *pitpcall, WORD seltype,
				LPOLEOBJECT poleobj, CHARRANGE * pchrg, HMENU * phmenu);

// Virtual table for ITP callbacks
IRichEditOleCallbackVtbl ITPCALL_Vtbl =
{
	(LPVOID) ITPCALL_QueryInterface,
	(LPVOID) ITPCALL_AddRef,
	(LPVOID) ITPCALL_Release,
	(LPVOID) ITPCALL_GetNewStorage,
	(LPVOID) ITPCALL_GetInPlaceContext,
	(LPVOID) ITPCALL_ShowContainerUI,
	(LPVOID) ITPCALL_QueryInsertObject,
	(LPVOID) ITPCALL_DeleteObject,
	(LPVOID) ITPCALL_QueryAcceptData,
	(LPVOID) ITPCALL_ContextSensitiveHelp,
	(LPVOID) ITPCALL_GetClipboardData,
	(LPVOID) ITPCALL_GetDragDropEffect,
	(LPVOID) ITPCALL_GetContextMenu
};


LOCAL VOID ParseArguments(LPSTR *pszDoc, LPCSTR szCmdLine);
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
LOCAL LRESULT HandleCreate(REDOC *predoc, LPCSTR szCmdLine);
LOCAL VOID ResizeRedoc(REDOC *predoc, RECT rc);
LOCAL VOID SetupMenu(REDOC *predoc, int iMenu, HMENU hmenu);
LOCAL LRESULT HandleCommand(REDOC *predoc, HWND hwnd, WPARAM wparam,
								LPARAM lparam);
LOCAL BOOL ToggleCheck(REDOC *predoc, UINT uiMenuid);
LOCAL BOOL QueryCheck(REDOC *predoc, UINT uiMenuid);
LOCAL LRESULT NewREDoc(REDOC *predoc, BOOL fPrompt, BOOL fUpdateUI);
LOCAL LONG CheckSave(REDOC *predoc);
LOCAL INT CheckRevert(REDOC *predoc);
LOCAL LRESULT CloseREDoc(REDOC *predoc, BOOL fPrompt, BOOL fUpdateUI);
DWORD CALLBACK MyRead(DWORD dwCookie, LPBYTE pbBuffer, LONG cb, LONG *pcb);
LOCAL LRESULT OpenREDoc(REDOC *predoc, BOOL fInsert);
LOCAL LRESULT RevertREDoc(REDOC *predoc);
LOCAL DWORD ReadREDoc(REDOC *predoc, LPCSTR szFile, LPCSTR szTitle,
						DWORD dwFormat, BOOL fInsert);
DWORD CALLBACK MyWrite(DWORD dwCookie, LPBYTE pbBuffer, LONG cb, LONG *pcb);
LOCAL LRESULT SaveREDoc(REDOC *predoc);
LOCAL LRESULT SaveREDocAs(REDOC *predoc, BOOL fSelect);
LOCAL LRESULT InsertObject(REDOC *predoc);
LOCAL VOID SelectCharFormat(REDOC *predoc);
LOCAL VOID SaveWindowPos(HWND hwnd);
LOCAL BOOL FRestoreWindowPos(WINDOWPLACEMENT *pwndpl);
LOCAL VOID SetAlignment(REDOC *predoc, WORD wAlignment);
LOCAL VOID IndentFirst(REDOC *predoc, BOOL fIndent);
LOCAL VOID ProtectSelection(REDOC *predoc);
LOCAL VOID SetWordWrap(REDOC *predoc, BOOL fWysiwyg, BOOL fWrap);
LOCAL VOID SetupWordWrapMenu(REDOC *predoc);
LOCAL VOID SetOffset(REDOC *predoc, BOOL fSuperscript);
LRESULT CALLBACK PPDlgProc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam);
LOCAL BOOL FPPInit(PRINTPREVIEW *ppp);
LOCAL VOID PPInitDialogSize(PRINTPREVIEW *ppp);
LOCAL VOID PPChangePage(PRINTPREVIEW *ppp, BOOL fPrev);
LOCAL VOID PPPaint(PRINTPREVIEW *ppp);
VOID DoVerb(REDOC * predoc, INT ioleverb);
LOCAL VOID FindReplace(REDOC *predoc, BOOL fReplace);
LOCAL VOID ProcessFindReplace(REDOC *predoc, FINDREPLACE *pfr);
LOCAL BOOL FEnablePaste(VOID);
LOCAL VOID UpdateFormatBar(REDOC *predoc);
LOCAL VOID ShowMargins(REDOC *predoc);


int PASCAL
WinMain(HINSTANCE hinstCurr, HINSTANCE hinstPrev, LPSTR szCmdLine, int nCmdShow)
{
	SCODE sc;
	MSG msg;
	WNDCLASS wndclass;
	WINDOWPLACEMENT wndpl;
	TCHAR *szDoc = NULL;
	REDOC *predoc = NULL;
	HACCEL hAccels;
#ifndef NO_OLE
	LPOLEINPLACEACTIVEOBJECT pipaobj;
#endif	// NO_OLE

    LoadLibrary("RichEd32.Dll"); // Load the RichEdit DLL to activate the
				 // RichEdit classes

    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = sizeof(REDOC *);
    wndclass.hInstance     = hinstCurr;
    wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH) (COLOR_BACKGROUND + 1);
    wndclass.hIcon	       = LoadIcon(hinstCurr, TEXT("IconApp"));
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = szAppName;

	RegisterClass(&wndclass);
	hinst = hinstCurr;

#ifdef TEST_OLE_INITIALIZE
	OleInitialize(NULL);
	OleUninitialize();
	OleInitialize(NULL);
	OleUninitialize();
#endif	// TEST_OLE_INITIALIZE

	OleInitialize(NULL);
	sc = GetScode(OleInitialize(NULL));
	if (FAILED(sc))
	{
		TraceError("OleInitialize failed", sc);
		goto done;				// If OLE can't be initialized abort.
	}
	// OleStdInitialize();

	// Initialize the format bar class
	if(!FInitFormatBarClass(hinst))
	{						
		MessageBoxA(NULL, "Unable to register format bar", NULL,
					MB_ICONSTOP | MB_OK);
		goto done;
	}

	hmenuLoaded = LoadMenu(hinstCurr, TEXT("LoadedMenu"));
	hmenuFull = LoadMenu(hinstCurr, TEXT("FullMenu"));

	msgFindReplace = RegisterWindowMessage(TEXT("commdlg_FindReplace"));

	cfTxtObj = RegisterClipboardFormat(TEXT(CF_RETEXTOBJ));

	ParseArguments(&szDoc, szCmdLine);

	if(fPrint && !szDoc)
		goto done;

	hwndMain = CreateWindow(szAppName, szAppName,
            WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 
            0, 0, 750, 500, NULL, NULL, hinstCurr, szDoc);
	if(!hwndMain)
	{
		MessageBoxA(NULL, "Unable to create main window", NULL, MB_ICONSTOP | MB_OK);
		goto done;
	}
	SideAssert(predoc = (REDOC *) GetWindowLong(hwndMain, 0));

	if(!fPrint)
	{
		if(FRestoreWindowPos(&wndpl))
			SetWindowPlacement(hwndMain, &wndpl);
		ShowWindow(hwndMain, nCmdShow);
	}

	hAccels = LoadAccelerators(hinstCurr, "WARPKEYS");
	Assert(hAccels);
	while(GetMessage(&msg, NULL, 0, 0))
	{
# ifndef NO_OLE
		// Translate accelerators for possible in place objects
		if(predoc->pitpcall && (pipaobj = predoc->pitpcall->pipframe->pipaobj))
			pipaobj->lpVtbl->TranslateAccelerator(pipaobj, &msg);
# endif	// NO_OLE

		if(predoc->hwndRE && TranslateAccelerator(hwndMain, hAccels, &msg))
			continue;

		if(!hwndFR || !IsDialogMessage(hwndFR, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}



done:
	if(szDoc)
		GlobalFreePtr(szDoc);
	if(hwndMain)
		DestroyWindow(hwndMain);
	if(hmenuLoaded)
		DestroyMenu(hmenuLoaded);
	if(hmenuFull)
		DestroyMenu(hmenuFull);

	// OleStdUninitialize();

	return msg.wParam;
}


LOCAL VOID ParseArguments(LPSTR *pszDoc, LPCSTR szCmdLine)
{
	const TCHAR *pch;

	*pszDoc = NULL;
	pch = szCmdLine - 1;
	while(pch)
	{
		pch++;
		if(*pch == TEXT('/') || *pch == '-')
		{
			pch++;
			switch(*pch)
			{
			case TEXT('p'):
			case TEXT('P'):
				fPrint = fTrue;
				break;

			case TEXT('w'):
			case TEXT('W'):
				pch++;
				if(*pch == 'p' || *pch == 'P')
				{
					pch++;
					fWrapDefault = fTrue;
					fWysiwygDefault = fTrue;
				}
				else if(*pch == 'n' || *pch == 'N')
				{
					pch++;
					fWrapDefault = fFalse;
					fWysiwygDefault = fFalse;
				}
				else
				{
					fWrapDefault = fTrue;
					fWysiwygDefault = fFalse;
				}
				break;

			default:
				if(*pch >= TEXT('0') && *pch <= TEXT('9') && !cchTextMost)
				{
					while(*pch >= TEXT('0') && *pch <= TEXT('9'))
					{
						cchTextMost *= 10;

⌨️ 快捷键说明

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