437 lines
11 KiB
C
437 lines
11 KiB
C
|
/************************************************************/
|
|||
|
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
|||
|
/************************************************************/
|
|||
|
|
|||
|
/* The routines in this file roughly correspond to the routines in the original
|
|||
|
Mac Word file, sand.c. But since that name is confusing, and most of these
|
|||
|
routine deal with the mouse, the name was changed to protect the innocent. */
|
|||
|
|
|||
|
#define NOGDICAPMASKS
|
|||
|
#define NOWINSTYLES
|
|||
|
#define NOCLIPBOARD
|
|||
|
#define NOCTLMGR
|
|||
|
#define NOSYSMETRICS
|
|||
|
#define NOMENUS
|
|||
|
#define NOSOUND
|
|||
|
#define NOCOMM
|
|||
|
//#define NOMETAFILE
|
|||
|
#include <windows.h>
|
|||
|
#include "mw.h"
|
|||
|
#include "dispdefs.h"
|
|||
|
#define NOUAC
|
|||
|
#include "cmddefs.h"
|
|||
|
#include "wwdefs.h"
|
|||
|
#include "fmtdefs.h"
|
|||
|
#include "propdefs.h"
|
|||
|
|
|||
|
#if defined(OLE)
|
|||
|
#include "obj.h"
|
|||
|
#include "winddefs.h"
|
|||
|
#include "str.h"
|
|||
|
#endif
|
|||
|
|
|||
|
/* cpNil is defined in docdefs.h, but to include the whole file will cause the
|
|||
|
symbol table to overflow, so it is redefined here. */
|
|||
|
#define cpNil ((typeCP) -1)
|
|||
|
|
|||
|
|
|||
|
extern struct WWD rgwwd[];
|
|||
|
extern struct WWD *pwwdCur;
|
|||
|
extern int wwCur;
|
|||
|
extern struct SEL selCur;
|
|||
|
extern int docCur;
|
|||
|
extern int vfShiftKey;
|
|||
|
extern int vfOptionKey;
|
|||
|
extern int vfCommandKey;
|
|||
|
extern int vfDoubleClick;
|
|||
|
extern typeCP vcpFirstParaCache;
|
|||
|
extern typeCP vcpLimParaCache;
|
|||
|
extern struct PAP vpapAbs;
|
|||
|
extern typeCP cpWall;
|
|||
|
extern int vfDidSearch;
|
|||
|
extern typeCP vcpSelect;
|
|||
|
extern int vfSelAtPara;
|
|||
|
extern int vfPictSel;
|
|||
|
extern long tickOld;
|
|||
|
|
|||
|
#ifdef PENWIN
|
|||
|
extern int vcFakeMessage;
|
|||
|
extern LONG FAR PASCAL GetMessageExtraInfo( void ); // Defined in Win 3.1
|
|||
|
#endif
|
|||
|
|
|||
|
/* G L O B A L S */
|
|||
|
|
|||
|
int vfSelecting = false;
|
|||
|
int vstyCur;
|
|||
|
int vpsmCur;
|
|||
|
int vfObjOpen=0,vfObjProps=0,vfObjSel=0;
|
|||
|
int vfAwfulNoise = false;
|
|||
|
struct SEL selPend;
|
|||
|
|
|||
|
/* MB_STANDARD is the same as in diaalert.c */
|
|||
|
#define MB_STANDARD (MB_OK | MB_SYSTEMMODAL | MB_ICONEXCLAMATION)
|
|||
|
|
|||
|
/* _ B E E P */
|
|||
|
_beep()
|
|||
|
{
|
|||
|
/* Beeps once */
|
|||
|
if (!vfAwfulNoise)
|
|||
|
{
|
|||
|
beep();
|
|||
|
vfAwfulNoise = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
beep()
|
|||
|
{
|
|||
|
MessageBeep(MB_STANDARD);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/* D O C O N T E N T H I T */
|
|||
|
DoContentHit(pt)
|
|||
|
POINT pt;
|
|||
|
{
|
|||
|
|
|||
|
/* This routine process everything from a mouse-down click to the
|
|||
|
corresponding mouse-up click. */
|
|||
|
|
|||
|
int dlMouse;
|
|||
|
|
|||
|
/* Ignore mouse hits in the page area & above the first line*/
|
|||
|
if ( (pt.y >= wwdCurrentDoc.ypMac) ||
|
|||
|
(pt.y < wwdCurrentDoc.ypMin) )
|
|||
|
return;
|
|||
|
|
|||
|
/* Check for a special selection, i.e. move, copy or format text. */
|
|||
|
if (FSetPsm())
|
|||
|
{
|
|||
|
blt(&selCur, &selPend, cwSEL);
|
|||
|
vfDoubleClick = vfCommandKey = vfShiftKey = false;
|
|||
|
vstyCur = vpsmCur != psmLooks ? StyFromPt(pt) : styChar;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
vstyCur = StyFromPt(pt);
|
|||
|
}
|
|||
|
|
|||
|
dlMouse = DlFromYp(pt.y, pwwdCur);
|
|||
|
vcpSelect = cpNil;
|
|||
|
vfSelAtPara = false;
|
|||
|
|
|||
|
#ifdef ENABLE
|
|||
|
if (vfPictSel)
|
|||
|
{
|
|||
|
/* Check for a picture modification (moving, sizing). */
|
|||
|
if (FHitPictFrame(dlMouse, pt))
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
/* Remove the picture frame */
|
|||
|
ToggleSel(selCur.cpFirst, selCur.cpLim, false);
|
|||
|
vfPictSel = false;
|
|||
|
ToggleSel(selCur.cpFirst, selCur.cpLim, true);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
vfSelecting = true;
|
|||
|
SelectDlXp(dlMouse, pt.x, vstyCur, vfShiftKey);
|
|||
|
|
|||
|
/* Now we sit in a loop processing all mouse events in all windows until a
|
|||
|
mouse-up click. */
|
|||
|
SetCapture(wwdCurrentDoc.wwptr);
|
|||
|
while( FStillDown( &pt ) )
|
|||
|
{
|
|||
|
/* If the mouse is above or below the window, then scroll the window and
|
|||
|
pretend the mouse is in the window. */
|
|||
|
if (pt.y > (int)wwdCurrentDoc.ypMac)
|
|||
|
{
|
|||
|
ScrollDownCtr( 1 );
|
|||
|
goto DoCont1;
|
|||
|
}
|
|||
|
else if (pt.y < (int)wwdCurrentDoc.ypMin)
|
|||
|
{
|
|||
|
ScrollUpCtr( 1 );
|
|||
|
DoCont1: UpdateWw(wwCur, false);
|
|||
|
}
|
|||
|
|
|||
|
/* Get a valid dl and xp. */
|
|||
|
dlMouse = DlFromYp(pt.y, pwwdCur);
|
|||
|
if (pt.x < 0)
|
|||
|
pt.x = 0;
|
|||
|
else if (pt.x > wwdCurrentDoc.xpMac)
|
|||
|
pt.x = wwdCurrentDoc.xpMac;
|
|||
|
|
|||
|
/* Update the selection. */
|
|||
|
if (vfOptionKey)
|
|||
|
{
|
|||
|
vcpSelect = cpNil;
|
|||
|
}
|
|||
|
SelectDlXp(dlMouse, pt.x, vstyCur, !vfOptionKey);
|
|||
|
} /* End of for ( ; ; ) */
|
|||
|
|
|||
|
/* Release all of the mouse events. */
|
|||
|
ReleaseCapture();
|
|||
|
|
|||
|
/* Process Mouse Up */
|
|||
|
DoContentHitEnd( pt );
|
|||
|
SetFocus( wwdCurrentDoc.wwptr );
|
|||
|
|
|||
|
/* If the selection is an insertion bar, start it flashing. */
|
|||
|
if (selCur.cpFirst == selCur.cpLim)
|
|||
|
{
|
|||
|
extern int vfSkipNextBlink;
|
|||
|
vfSkipNextBlink = true;
|
|||
|
}
|
|||
|
|
|||
|
#if defined(OLE)
|
|||
|
if (ObjQueryCpIsObject(docCur,selCur.cpFirst) && (vfObjProps || vfObjOpen))
|
|||
|
/* doubleclick and maybe alt key */
|
|||
|
{
|
|||
|
/* set whether link or emb selected */
|
|||
|
ObjSetSelectionType(docCur,selCur.cpFirst,selCur.cpLim);
|
|||
|
if (vfObjProps)
|
|||
|
/* alt + double click */
|
|||
|
{
|
|||
|
switch(OBJ_SELECTIONTYPE)
|
|||
|
{
|
|||
|
#if 0 // do nothing if embedded
|
|||
|
case EMBEDDED:
|
|||
|
{
|
|||
|
struct PICINFOX picInfo;
|
|||
|
GetPicInfo(selCur.cpFirst,selCur.cpLim, docCur, &picInfo);
|
|||
|
ObjEditObjectInDoc(&picInfo, docCur, vcpFirstParaCache);
|
|||
|
}
|
|||
|
break;
|
|||
|
#endif
|
|||
|
|
|||
|
case LINK:
|
|||
|
/* bring up properties dlg */
|
|||
|
fnObjProperties();
|
|||
|
break;
|
|||
|
}
|
|||
|
CachePara(docCur,selCur.cpFirst);
|
|||
|
}
|
|||
|
else if (vfObjOpen) // edit object
|
|||
|
/* double click */
|
|||
|
{
|
|||
|
if (OBJ_SELECTIONTYPE == STATIC)
|
|||
|
Error(IDPMTStatic);
|
|||
|
else
|
|||
|
{
|
|||
|
struct PICINFOX picInfo;
|
|||
|
GetPicInfo(selCur.cpFirst,selCur.cpLim, docCur, &picInfo);
|
|||
|
ObjPlayObjectInDoc(&picInfo, docCur, vcpFirstParaCache);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* D O C O N T E N T H I T E N D */
|
|||
|
DoContentHitEnd(pt)
|
|||
|
POINT pt;
|
|||
|
{
|
|||
|
int dlMouse;
|
|||
|
int cch;
|
|||
|
|
|||
|
dlMouse = DlFromYp(min(pt.y, wwdCurrentDoc.ypMac), pwwdCur);
|
|||
|
SelectDlXp(dlMouse, pt.x, vstyCur, vpsmCur == psmNil);
|
|||
|
|
|||
|
switch (vpsmCur)
|
|||
|
{
|
|||
|
default:
|
|||
|
case psmNil:
|
|||
|
break;
|
|||
|
|
|||
|
case psmLooks:
|
|||
|
LooksMouse();
|
|||
|
break;
|
|||
|
|
|||
|
case psmCopy:
|
|||
|
#if defined(OLE)
|
|||
|
/* we'll disable CopyMouse if any objects are in dest */
|
|||
|
vfObjSel = ObjQueryCpIsObject(docCur,selCur.cpFirst);
|
|||
|
|
|||
|
if (!vfObjSel)
|
|||
|
// !!! disable because for objects this
|
|||
|
// interferes with Alt-DoubleClick (2.20.91) D. Kent
|
|||
|
#endif
|
|||
|
CopyMouse();
|
|||
|
break;
|
|||
|
|
|||
|
case psmMove:
|
|||
|
MoveMouse();
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
#ifdef ENABLE
|
|||
|
CachePara(docCur, selCur.cpFirst);
|
|||
|
|
|||
|
if (vpapAbs.fGraphics && selCur.cpLim == vcpLimParaCache)
|
|||
|
{
|
|||
|
/* Selected a picture, do special selection stuff. */
|
|||
|
Assert(selCur.cpFirst == vcpFirstParaCache);
|
|||
|
|
|||
|
/* Turn off the selection, indicate that it is a picture, then turn it
|
|||
|
back on. */
|
|||
|
ToggleSel(selCur.cpFirst, selCur.cpLim, false);
|
|||
|
vfPictSel = true;
|
|||
|
ToggleSel(selCur.cpFirst, selCur.cpLim, true);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
vfPictSel = false;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
vfDidSearch = false;
|
|||
|
cpWall = selCur.cpLim;
|
|||
|
vfSelecting = false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* S T Y F R O M P T */
|
|||
|
int StyFromPt(pt)
|
|||
|
POINT pt;
|
|||
|
{
|
|||
|
/* Return the style code associated with the selection made at point pt. */
|
|||
|
if (pt.x > xpSelBar)
|
|||
|
{
|
|||
|
return vfCommandKey ? stySent : (vfDoubleClick ? styWord : styChar);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return vfCommandKey ? styDoc : (vfDoubleClick ? styPara : styLine);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* F S E T P S M */
|
|||
|
int FSetPsm()
|
|||
|
{
|
|||
|
/* Sets vpsmCur according to the states of the shift, commad, and option
|
|||
|
keys. True is returned if vpsmCur is not nil; false otherwise. */
|
|||
|
|
|||
|
vpsmCur = psmNil;
|
|||
|
|
|||
|
if (vfOptionKey)
|
|||
|
{
|
|||
|
if (vfShiftKey && !vfCommandKey)
|
|||
|
{
|
|||
|
vpsmCur = psmMove;
|
|||
|
}
|
|||
|
else if (vfCommandKey && !vfShiftKey)
|
|||
|
{
|
|||
|
vpsmCur = psmLooks;
|
|||
|
}
|
|||
|
else if (!vfCommandKey && !vfShiftKey)
|
|||
|
{
|
|||
|
vfObjProps = vfDoubleClick;
|
|||
|
vfObjOpen = FALSE;
|
|||
|
vpsmCur = psmCopy;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
vfObjOpen = vfDoubleClick;
|
|||
|
vfObjProps = FALSE;
|
|||
|
}
|
|||
|
return (vpsmCur != psmNil);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/* D L F R O M Y P */
|
|||
|
int DlFromYp(yp, pwwd)
|
|||
|
int yp;
|
|||
|
struct WWD *pwwd;
|
|||
|
{
|
|||
|
/* Return the dl that contains yp */
|
|||
|
int dlT;
|
|||
|
int ypSum;
|
|||
|
struct EDL *pedl;
|
|||
|
int dlMac;
|
|||
|
|
|||
|
/* Clean up a dirty window. */
|
|||
|
if (pwwd->fDirty)
|
|||
|
{
|
|||
|
UpdateWw(pwwd - &rgwwd[0] /* = ww; grr.. */, false);
|
|||
|
}
|
|||
|
|
|||
|
/* Loop throught the EDLs summing up the heights utill the sum is greater
|
|||
|
than yp. */
|
|||
|
ypSum = pwwd->ypMin;
|
|||
|
pedl = &(**(pwwd->hdndl))[0];
|
|||
|
dlMac = pwwd->dlMac;
|
|||
|
|
|||
|
for (dlT = 0; dlT < dlMac; ++dlT, pedl++)
|
|||
|
{
|
|||
|
ypSum += pedl->dyp;
|
|||
|
if (ypSum > yp)
|
|||
|
{
|
|||
|
return dlT;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return dlMac - 1;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
FStillDown( ppt )
|
|||
|
POINT *ppt;
|
|||
|
{ /* This is roughly equivalent to a Mac routine that returns whether
|
|||
|
the mouse button is down. We look for one mouse message from our
|
|||
|
window's queue, and return FALSE if it is a BUTTONUP. We return the
|
|||
|
point at which the mouse event occurred through a pointer. If no
|
|||
|
message occurred, we return TRUE and do not store into the pointer */
|
|||
|
MSG msg;
|
|||
|
|
|||
|
retry_peek:
|
|||
|
|
|||
|
if ( PeekMessage( (LPMSG)&msg, (HWND)NULL, NULL, NULL, PM_REMOVE ) )
|
|||
|
{
|
|||
|
extern WORD wWinVer;
|
|||
|
switch (msg.message) {
|
|||
|
default:
|
|||
|
TranslateMessage( (LPMSG)&msg );
|
|||
|
DispatchMessage( (LPMSG)&msg );
|
|||
|
return TRUE;
|
|||
|
|
|||
|
case WM_MOUSEMOVE:
|
|||
|
case WM_LBUTTONUP:
|
|||
|
case WM_LBUTTONDOWN:
|
|||
|
#ifdef PENWIN
|
|||
|
if (((wWinVer & 0xFF) >= 3) && ((wWinVer & 0xFF00) >= 0x0A00))
|
|||
|
/* Windows Version >= 3.10 */
|
|||
|
if( vcFakeMessage > 0 )
|
|||
|
{
|
|||
|
static FARPROC MessageExtraInfo = NULL;
|
|||
|
|
|||
|
if (MessageExtraInfo == NULL)
|
|||
|
MessageExtraInfo = GetProcAddress(GetModuleHandle((LPSTR)"USER"),(LPSTR)288L);
|
|||
|
|
|||
|
if( MessageExtraInfo() != 0 )
|
|||
|
goto retry_peek;
|
|||
|
vcFakeMessage--;
|
|||
|
}
|
|||
|
#endif
|
|||
|
/* A Mouse Move, Mouse Down, or Mouse Up is waiting */
|
|||
|
ppt->x = MAKEPOINT(msg.lParam).x;
|
|||
|
ppt->y = MAKEPOINT(msg.lParam).y;
|
|||
|
|
|||
|
return (msg.message != WM_LBUTTONUP);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
return GetKeyState( VK_LBUTTON ) < 0;
|
|||
|
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|