📄 reitp.c
字号:
if(CheckRevert(predoc) <= 0)
return 0;
lstrcpy(szT, predoc->szFile);
dwError = ReadREDoc(predoc, szT, NULL, predoc->dwFormat, FALSE);
if(!dwError)
return 0;
wsprintf(szT, TEXT("Error reading document. [%ld]"), dwError);
MessageBox(hwndMain, szT, NULL, MB_OK);
return -1;
}
LOCAL DWORD ReadREDoc(REDOC *predoc, LPCSTR szFile, LPCSTR szTitle,
DWORD dwFormat, BOOL fInsert)
{
LONG cch;
HCURSOR hcur;
EDITSTREAM es;
TCHAR szType[cchRTFSig + 1];
hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
es.dwCookie = (DWORD) _lopen(szFile, OF_READ);
if(es.dwCookie == (DWORD) HFILE_ERROR)
{
return GetLastError();
}
if(!fInsert)
{
// save read-only flag across NewREDoc()
const BOOL fReadOnlySave = predoc->fReadOnly;
if(NewREDoc(predoc, fFalse, fFalse) < 0)
{
_lclose((HFILE) es.dwCookie);
return (DWORD) -1;
}
predoc->fReadOnly = fReadOnlySave;
}
if(dwFormat == 0) // unknown format, figure out what it is
{
UINT cb = cchRTFSig * sizeof(TCHAR);
cb = _lread((HFILE) es.dwCookie, szType, cb);
szType[cb / sizeof(TCHAR)] = TEXT('\0');
if(cb == cchRTFSig * sizeof(TCHAR))
dwFormat = lstrcmpi(szRTFSig, szType) ? SF_TEXT : SF_RTF;
else
dwFormat = SF_TEXT; // not big enough to be RTF, assume text
// move back to the beginning of the file
_llseek((HFILE) es.dwCookie, 0, 0);
}
SendMessage(predoc->hwndRE, WM_SETREDRAW, (WPARAM) fFalse, 0);
es.dwError = 0;
es.pfnCallback = MyRead;
cch = SendMessage(predoc->hwndRE, EM_STREAMIN,
(WPARAM) (fInsert ? dwFormat | SFF_SELECTION : dwFormat),
(LPARAM) &es);
_lclose((HFILE) es.dwCookie);
#ifdef DEBUG
if(predoc->hwndRE)
SendMessage(predoc->hwndRE, EM_REQUESTRESIZE, 0, 0);
#endif // DEBUG
SendMessage(predoc->hwndRE, EM_SETMODIFY, (WPARAM) fFalse, 0);
predoc->dwFormat = dwFormat;
lstrcpy(predoc->szFile, szFile);
if(szTitle)
lstrcpy(predoc->szTitle, szTitle);
else
GetFileTitle(szFile, predoc->szTitle, sizeof(predoc->szTitle));
SendMessage(predoc->hwndRE, WM_SETREDRAW, (WPARAM) fTrue, 0);
InvalidateRect(predoc->hwndRE, NULL, fTrue);
UpdateWindow(predoc->hwndRE);
SetCursor(hcur);
UpdateFormatBar(predoc);
return 0;
}
DWORD CALLBACK MyWrite(DWORD dwCookie, LPBYTE pbBuffer, LONG cb, LONG *pcb)
{
HFILE hf = (HFILE) dwCookie;
if(hf == HFILE_ERROR)
return (DWORD) E_FAIL;
*pcb = _lwrite(hf, pbBuffer, cb);
return (DWORD) (*pcb == cb ? NOERROR : E_FAIL);
}
LOCAL LRESULT SaveREDoc(REDOC *predoc)
{
HCURSOR hcur;
LONG cch;
DWORD dwError;
EDITSTREAM es;
if(!predoc->szFile[0])
return SaveREDocAs(predoc, FALSE);
hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
es.dwCookie = _lcreat(predoc->szFile, 0);
if(es.dwCookie == (DWORD) HFILE_ERROR)
{
dwError = GetLastError();
goto err;
}
es.dwError = 0;
es.pfnCallback = MyWrite;
cch = SendMessage(predoc->hwndRE, EM_STREAMOUT, (WPARAM) predoc->dwFormat,
(LPARAM) &es);
_lclose((HFILE) es.dwCookie);
SendMessage(predoc->hwndRE, EM_SETMODIFY, (WPARAM) fFalse, 0);
SendMessage(predoc->hwndRE, EM_SETREADONLY, (WPARAM) fFalse, 0);
predoc->fReadOnly = fFalse;
EnableWindow(predoc->hwndFormatBar, TRUE);
SetCursor(hcur);
return 0;
err:
{
TCHAR szT[64];
wsprintf(szT, TEXT("Error saving document. [%ld]"), dwError);
MessageBox(hwndMain, szT, NULL, MB_OK);
}
return -1;
}
LOCAL LRESULT SaveREDocAs(REDOC *predoc, BOOL fSelect)
{
HCURSOR hcur;
LONG cch;
DWORD dwError;
EDITSTREAM es;
OPENFILENAME ofn;
TCHAR szTitle[64];
TCHAR szT[256];
ofn.lStructSize = sizeof(ofn);
ofn.hInstance = 0;
ofn.lpstrFilter = szFilterSave;
ofn.lpstrCustomFilter = NULL;
ofn.nMaxCustFilter = 0;
ofn.nFilterIndex = 0;
ofn.lpstrFileTitle = szTitle;
ofn.nMaxFileTitle = sizeof(szTitle);
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = fSelect ? "Save Selection As": NULL;
ofn.nFileOffset = 0;
ofn.nFileExtension = 0;
ofn.lpstrDefExt = NULL;
ofn.lCustData = 0L;
ofn.lpfnHook = NULL;
ofn.lpTemplateName = NULL;
ofn.hwndOwner = hwndMain;
ofn.lpstrFile = szT;
ofn.nMaxFile = sizeof(szT);
ofn.Flags = OFN_CREATEPROMPT | OFN_HIDEREADONLY |
OFN_OVERWRITEPROMPT;
szT[0] = TEXT('\0');
szTitle[0] = TEXT('\0');
// Query user for filename for input
if(!GetSaveFileName(&ofn))
{
if((dwError = CommDlgExtendedError()) != 0)
goto err;
return -1;
}
hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
es.dwCookie = _lcreat(szT, 0);
if(es.dwCookie == (DWORD) HFILE_ERROR)
{
dwError = GetLastError();
goto err;
}
es.dwError = 0;
es.pfnCallback = MyWrite;
cch = SendMessage(predoc->hwndRE, EM_STREAMOUT,
(WPARAM) (fSelect ? ofn.nFilterIndex | SFF_SELECTION
: ofn.nFilterIndex),
(LPARAM) &es);
_lclose((HFILE) es.dwCookie);
// Don't mark the doc as clean, nor remember format if only selection
if(fSelect)
goto Quit;
SendMessage(predoc->hwndRE, EM_SETMODIFY, (WPARAM) fFalse, 0);
predoc->dwFormat = (DWORD) ofn.nFilterIndex;
predoc->fReadOnly = fFalse;
EnableWindow(predoc->hwndFormatBar, TRUE);
lstrcpy(predoc->szFile, szT);
lstrcpy(predoc->szTitle, szTitle);
wsprintf(szT, szFmtTitle, szTitle);
SetWindowText(predoc->hwndParent, szT);
SendMessage(predoc->hwndRE, EM_SETMODIFY, (WPARAM) fFalse, 0);
SendMessage(predoc->hwndRE, EM_SETREADONLY, (WPARAM) fFalse, 0);
Quit:
SetCursor(hcur);
return 0;
err:
wsprintf(szT, TEXT("Error saving document. [%ld]"), dwError);
MessageBox(hwndMain, szT, NULL, MB_OK);
return -1;
}
LOCAL LRESULT InsertObject(REDOC *predoc)
{
#ifdef NO_OLE
MessageBox(NULL, "Not yet implemented", NULL, MB_OK);
return 0;
#else // NO_OLE
const LPRICHEDITOLE preole = predoc->preole;
LPOLECLIENTSITE polesite = NULL;
LPSTORAGE pstgItem = NULL;
OLEUIINSERTOBJECT ouio = { 0 };
REOBJECT reobj = { 0 };
LPOLEOBJECT poleobj = NULL;
CHAR szFileA[OLEUI_CCHPATHMAX];
WCHAR szItemW[OLEUI_CCHPATHMAX];
DWORD dwRet;
RECT rect;
if(!preole)
return 0;
if(preole->lpVtbl->SetHostNames(preole, "REITP", predoc->szTitle))
{
MessageBoxA(hwndMain, "Can't set host name", NULL, MB_OK);
goto error;
}
if(preole->lpVtbl->GetClientSite(preole, (LPOLECLIENTSITE FAR *) &polesite))
{
MessageBoxA(hwndMain, "No client site!", NULL, MB_OK);
goto error;
}
wsprintfW(szItemW, L"REOBJ%ld", ++predoc->cItem);
if(!(pstgItem = OleStdCreateChildStorage(predoc->pstg, szItemW)))
{
MessageBoxW(hwndMain, szItemW, L"No item storage!", MB_OK);
goto error;
}
szFileA[0] = '\0';
ouio.cbStruct = sizeof(ouio);
ouio.dwFlags = IOF_SHOWHELP | IOF_CREATENEWOBJECT | IOF_CREATEFILEOBJECT |
IOF_CREATELINKOBJECT | IOF_SELECTCREATENEW;
// IOF_VERIFYSERVERSEXIST;
# ifdef MAC // Mac version doesn't have the same members
ouio.pszFile = szFileA;
# else // MAC
ouio.hWndOwner = hwndMain;
ouio.lpszFile = szFileA;
# endif // MAC, else
ouio.lpszCaption = "Insert Object (REITP)";
ouio.cchFile = OLEUI_CCHPATHMAX;
ouio.iid = IID_IOleObject;
ouio.oleRender = OLERENDER_DRAW;
ouio.lpIOleClientSite = polesite;
ouio.lpIStorage = pstgItem;
ouio.ppvObj = (LPVOID FAR *) &poleobj;
ouio.clsid = CLSID_NULL;
if((dwRet = OleUIInsertObject(&ouio)) != OLEUI_SUCCESS)
{
if(dwRet == OLEUI_CANCEL)
goto error;
if(dwRet == OLEUI_IOERR_SCODEHASERROR)
wsprintfA(szFileA, "OleUIInsertObject scode is %lx", ouio.sc);
else
wsprintfA(szFileA, "OleUIInsertObject returned %ld", dwRet);
MessageBoxA(hwndMain, szFileA, NULL, MB_OK);
goto error;
}
AssertSz(ouio.sc == S_OK, "Object wasn't created properly");
reobj.cbStruct = sizeof(REOBJECT);
reobj.clsid = ouio.clsid;
reobj.cp = REO_CP_SELECTION;
reobj.poleobj = poleobj;
reobj.pstg = pstgItem;
reobj.polesite = polesite;
reobj.dvaspect = DVASPECT_CONTENT;
reobj.dwFlags = REO_RESIZABLE;
reobj.dwUser = 0;
if(ouio.dwFlags & IOF_SELECTCREATENEW)
reobj.dwFlags |= REO_BLANK;
//$ Raid 101: RichEdit doesn't setup advises if reobj.clsid == CLSID_NULL
// Try our darnest to get a CLSID
if(IsEqualCLSID(&reobj.clsid, &CLSID_NULL) &&
HrGetClassFileA(szFileA, &reobj.clsid))
{
MessageBoxA(hwndMain, "No CLSID, but forging on", "Insert Object",
MB_OK);
}
// Do we want an iconized version ?
if(ouio.dwFlags & IOF_CHECKDISPLAYASICON)
{
BOOL fUpdate; // Can't pass in NULL instead of &this
// OLE call will update dvaspect on success
# ifdef MAC
// NOTE : There presently is no Mac equivalent of the <.hMetaPict>
// member of the tagOleUIInsertObject structure. This is certainly
// a problem. For now just pass in NULL since the Mac routines will
// not try to use this member.
DebugStr("\pBefore OleStdSwitchDisplayAspect() call");
if(OleStdSwitchDisplayAspect(poleobj, &reobj.dvaspect,
DVASPECT_ICON, (Handle) NULL,
TRUE, FALSE, NULL, &fUpdate))
# else // MAC
if(OleStdSwitchDisplayAspect(poleobj, &reobj.dvaspect,
DVASPECT_ICON, ouio.hMetaPict,
TRUE, FALSE, NULL, &fUpdate))
# endif // MAC, else
{
// How much do we care about reporting errors? Alot!! {Mac will have more}
MessageBoxA(hwndMain, "Object couldn't be displayed as an icon.",
"Insert Object", MB_OK);
}
AssertSz(!fUpdate, "We gave it an hMetaPict, should not need updating");
}
// Put the thing in the edit control
if(preole->lpVtbl->InsertObject(preole, &reobj))
{
MessageBoxA(hwndMain, "Object couldn't be inserted",
"Insert object", MB_OK);
goto error;
}
// Do show verb only on new objects
if(ouio.dwFlags & IOF_SELECTCREATENEW)
{
rect.top = rect.left = 0;
rect.bottom = rect.right = 50;
dwRet = (ULONG) poleobj->lpVtbl->DoVerb(poleobj, OLEIVERB_SHOW, NULL,
polesite, 0, hwndMain,
(LPCRECT) &rect);
}
error:
# ifndef MAC
if(ouio.hMetaPict)
OleUIMetafilePictIconFree(ouio.hMetaPict);
# endif // !MAC
if(polesite)
polesite->lpVtbl->Release(polesite);
if(pstgItem)
pstgItem->lpVtbl->Release(pstgItem);
if(poleobj)
poleobj->lpVtbl->Release(poleobj);
return 0;
#endif // NO_OLE, else
}
#ifdef DEBUG
LOCAL LRESULT GetText(REDOC *predoc)
{
HWND hwndEdit;
LONG cch;
TCHAR *pch;
if(!hwndGT)
{
hwndGT = CreateDialog(HinstFromHwnd(hwndMain), TEXT("GETTEXT"),
hwndMain, (DLGPROC) GTDlgProc);
if(!hwndGT)
{
MessageBoxA(hwndMain, "Unable to create dialog", NULL, MB_ICONSTOP | MB_OK);
return 0;
}
}
hwndEdit = GetDlgItem(hwndGT, GTCTRL);
cch = SendMessage(predoc->hwndRE, WM_GETTEXTLENGTH, 0, 0);
# ifdef WIN16
if(cch > 65000)
{
MessageBoxA(hwndMain, "Text too big, truncating", NULL,
MB_ICONSTOP | MB_OK);
cch = 65000;
}
# endif // WIN16
pch = GlobalAllocPtr(GHND, cch + 1);
if(!pch)
{
MessageBoxA(hwndMain, "Not enough memory to hold text", NULL,
MB_ICONSTOP | MB_OK);
return 0;
}
GetWindowText(predoc->hwndRE, pch, (int) cch + 1);
*pch = toupper(*pch);
SetWindowText(hwndEdit, pch);
GlobalFreePtr(pch);
return 0;
}
LRESULT CALLBACK GTDlgProc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch(msg)
{
case WM_INITDIALOG:
return 1;
case WM_SIZE:
MoveWindow(GetDlgItem(hdlg, GTCTRL), 5, 5, LOWORD(lparam)-10,
HIWORD(lparam)-10, TRUE);
return 0;
case WM_CLOSE:
EndDialog(hdlg, 0);
hwndGT = NULL;
return 1;
}
return 0;
}
LOCAL VOID ClearDebugScreen(void)
{
HFILE hf;
hf = _lopen("COM1", OF_WRITE);
if(hf)
{
_lwrite(hf, "\x1B[H\x1B[J", 6);
_lclose(hf);
}
}
#endif // DEBUG
LOCAL VOID SelectCharFormat(REDOC *predoc)
{
LOGFONT lf;
CHOOSEFONT csf = {0};
CHARFORMAT cf;
LONG yPerInch;
HDC hdc;
cf.cbSize = sizeof(CHARFORMAT);
hdc = GetDC(hwndMain);
yPerInch = GetDeviceCaps(hdc, LOGPIXELSY);
ReleaseDC(hwndMain, hdc);
(void) SendMessage(predoc->hwndRE, EM_GETCHARFORMAT, (WPARAM) fTrue,
(LPARAM) &cf);
csf.lStructSize = sizeof(csf);
csf.hwndOwner = hwndMain;
csf.hDC = 0;
csf.lpLogFont = &lf;
csf.Flags = CF_EFFECTS | CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT |
CF_LIMITSIZE;
csf.nSizeMin = 1;
csf.nSizeMax = yHeightCharPtsMost;
csf.rgbColors = cf.crTextColor;
csf.lpszStyle = NULL;
csf.nFontType = REGULAR_FONTTYPE | SCREEN_FONTTYPE;
lf.lfHeight = -(INT) ((cf.yHeight * yPerInch) / 1440);
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfO
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -