📄 reitp.c
字号:
/*
* 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 + -