289 lines
8.4 KiB
C
289 lines
8.4 KiB
C
/*++
|
||
*
|
||
* WOW v1.0
|
||
*
|
||
* Copyright (c) 1991, Microsoft Corporation
|
||
*
|
||
* EDSLRARE.C
|
||
* Win16 edit control code
|
||
*
|
||
* History:
|
||
*
|
||
* Created 28-May-1991 by Jeff Parsons (jeffpar)
|
||
* Copied from WIN31 and edited (as little as possible) for WOW16.
|
||
--*/
|
||
|
||
/****************************************************************************/
|
||
/* edslRare.c - SL Edit controls Routines Called rarely are to be */
|
||
/* put in a seperate segment _EDSLRare. This file contains */
|
||
/* these routines. */
|
||
/* */
|
||
/* */
|
||
/* Created: 02-08-89 sankar */
|
||
/****************************************************************************/
|
||
|
||
#define NO_LOCALOBJ_TAGS
|
||
#include "user.h"
|
||
#include "edit.h"
|
||
|
||
/****************************************************************************/
|
||
/* Single-Line Support Routines called Rarely */
|
||
/****************************************************************************/
|
||
|
||
void FAR PASCAL SLSetSelectionHandler(ped, ichSelStart, ichSelEnd)
|
||
register PED ped;
|
||
ICH ichSelStart;
|
||
ICH ichSelEnd;
|
||
/* effects: Sets the PED to have the new selection specified.
|
||
*/
|
||
{
|
||
register HDC hdc = ECGetEditDC(ped, FALSE);
|
||
|
||
if (ichSelStart == 0xFFFF)
|
||
/* Set no selection if we specify -1 */
|
||
ichSelStart = ichSelEnd = ped->ichCaret;
|
||
|
||
/* Bounds ichSelStart, ichSelEnd are checked in SLChangeSelection... */
|
||
SLChangeSelection(ped, hdc, ichSelStart, ichSelEnd);
|
||
/* Put the caret at the end of the selected text */
|
||
ped->ichCaret = ped->ichMaxSel;
|
||
|
||
SLSetCaretPosition(ped,hdc);
|
||
|
||
/* We may need to scroll the text to bring the caret into view... */
|
||
SLScrollText(ped,hdc);
|
||
|
||
ECReleaseEditDC(ped,hdc,FALSE);
|
||
}
|
||
|
||
|
||
void FAR PASCAL SLSizeHandler(ped)
|
||
register PED ped;
|
||
/* effects: Handles sizing of the edit control window and properly updating
|
||
* the fields that are dependent on the size of the control. ie. text
|
||
* characters visible etc.
|
||
*/
|
||
{
|
||
RECT rc;
|
||
GetClientRect(ped->hwnd, &rc);
|
||
if (!(rc.right-rc.left) || !(rc.bottom-rc.top))
|
||
{
|
||
if (ped->rcFmt.right-ped->rcFmt.left)
|
||
/* Don't do anything if we are becomming zero width or height and
|
||
out formatting rect is already set... */
|
||
return;
|
||
/* Otherwise set some initial values to avoid divide by zero problems
|
||
later... */
|
||
SetRect((LPRECT)&rc,0,0,10,10);
|
||
}
|
||
|
||
CopyRect(&ped->rcFmt, &rc);
|
||
if (ped->fBorder)
|
||
/* Shrink client area to make room for the border */
|
||
InflateRect((LPRECT)&ped->rcFmt,
|
||
-(min(ped->aveCharWidth,ped->cxSysCharWidth)/2),
|
||
-(min(ped->lineHeight,ped->cySysCharHeight)/4));
|
||
|
||
#ifdef BROKEN
|
||
ped->rcFmt.bottom = min(ped->rcFmt.top+
|
||
max(ped->lineHeight,ped->cySysCharHeight),
|
||
ped->rcFmt.bottom);
|
||
#else
|
||
ped->rcFmt.bottom = min(ped->rcFmt.top+
|
||
ped->lineHeight,
|
||
ped->rcFmt.bottom);
|
||
#endif
|
||
}
|
||
|
||
|
||
BOOL FAR PASCAL SLSetTextHandler(ped, lpstr)
|
||
register PED ped;
|
||
LPSTR lpstr;
|
||
/* effects: Copies the null terminated text in lpstr to the ped. Notifies the
|
||
* parent if there isn't enough memory. Returns TRUE if successful else
|
||
* FALSE.
|
||
*/
|
||
{
|
||
BOOL fInsertSuccessful;
|
||
RECT rcEdit;
|
||
|
||
SwapHandle(&lpstr);
|
||
ECEmptyUndo(ped);
|
||
SwapHandle(&lpstr);
|
||
|
||
/* Add the text and update the window if text was added. The parent is
|
||
* notified of no memory in ECSetText.
|
||
*/
|
||
if (fInsertSuccessful = ECSetText(ped, lpstr))
|
||
ped->fDirty = FALSE;
|
||
|
||
ECEmptyUndo(ped);
|
||
|
||
if (!ped->listboxHwnd)
|
||
ECNotifyParent(ped, EN_UPDATE);
|
||
|
||
#ifndef WOW
|
||
if (FChildVisible(ped->hwnd))
|
||
#else
|
||
if (IsWindowVisible(GetParent(ped->hwnd)))
|
||
#endif
|
||
{
|
||
/* We will always redraw the text whether or not the insert was
|
||
* successful since we may set to null text.
|
||
*/
|
||
GetClientRect(ped->hwnd, (LPRECT)&rcEdit);
|
||
if (ped->fBorder &&
|
||
rcEdit.right-rcEdit.left && rcEdit.bottom-rcEdit.top)
|
||
{
|
||
/* Don't invalidate the border so that we avoid flicker */
|
||
InflateRect((LPRECT)&rcEdit, -1, -1);
|
||
}
|
||
InvalidateRect(ped->hwnd, (LPRECT)&rcEdit, FALSE);
|
||
UpdateWindow(ped->hwnd);
|
||
}
|
||
|
||
if (!ped->listboxHwnd)
|
||
ECNotifyParent(ped, EN_CHANGE);
|
||
|
||
return(fInsertSuccessful);
|
||
}
|
||
|
||
|
||
LONG FAR PASCAL SLCreateHandler(hwnd, ped, lpCreateStruct)
|
||
HWND hwnd;
|
||
register PED ped;
|
||
LPCREATESTRUCT lpCreateStruct;
|
||
|
||
/* effects: Creates the edit control for the window hwnd by allocating memory
|
||
* as required from the application's heap. Notifies parent if no memory
|
||
* error (after cleaning up if needed). Returns TRUE if no error else returns
|
||
* -1.
|
||
*/
|
||
{
|
||
LPSTR lpWindowText = lpCreateStruct->lpszName;
|
||
LONG windowStyle = GetWindowLong(hwnd, GWL_STYLE);
|
||
|
||
/* Save text across the local allocs in ECNcCreate */
|
||
SwapHandle(&lpWindowText);
|
||
|
||
/* Do the standard creation stuff */
|
||
if (!ECCreate(hwnd, ped, lpCreateStruct))
|
||
return(-1);
|
||
|
||
ped->fSingle = TRUE; /* Set single line edit control */
|
||
|
||
/* Single lines always have no undo and 1 line */
|
||
ped->cLines = 1;
|
||
ped->undoType = UNDO_NONE;
|
||
|
||
/* Check if this edit control is part of a combobox and get a pointer to the
|
||
* combobox structure.
|
||
*/
|
||
if (windowStyle & ES_COMBOBOX)
|
||
ped->listboxHwnd = GetDlgItem(lpCreateStruct->hwndParent,CBLISTBOXID);
|
||
|
||
/* Set the default font to be the system font.
|
||
*/
|
||
ECSetFont(ped, NULL, FALSE);
|
||
|
||
/* Set the window text if needed. Return false if we can't set the text
|
||
* SLSetText notifies the parent in case there is a no memory error.
|
||
*/
|
||
/* Restore text */
|
||
SwapHandle(&lpWindowText);
|
||
if (lpWindowText && *lpWindowText && !SLSetTextHandler(ped, lpWindowText))
|
||
return(-1);
|
||
|
||
if (windowStyle & ES_PASSWORD)
|
||
ECSetPasswordChar(ped, (WORD)'*');
|
||
|
||
return(TRUE);
|
||
}
|
||
|
||
|
||
|
||
BOOL FAR PASCAL SLUndoHandler(ped)
|
||
register PED ped;
|
||
/* effects: Handles UNDO for single line edit controls. */
|
||
{
|
||
HANDLE hDeletedText = ped->hDeletedText;
|
||
BOOL fDelete = (BOOL)(ped->undoType & UNDO_DELETE);
|
||
WORD cchDeleted = ped->cchDeleted;
|
||
WORD ichDeleted = ped->ichDeleted;
|
||
BOOL fUpdate = FALSE;
|
||
RECT rcEdit;
|
||
|
||
|
||
if (ped->undoType == UNDO_NONE)
|
||
/* No undo... */
|
||
return(FALSE);
|
||
|
||
ped->hDeletedText = NULL;
|
||
ped->cchDeleted = 0;
|
||
ped->ichDeleted = -1;
|
||
ped->undoType &= ~UNDO_DELETE;
|
||
|
||
if (ped->undoType == UNDO_INSERT)
|
||
{
|
||
ped->undoType = UNDO_NONE;
|
||
/* Set the selection to the inserted text */
|
||
SLSetSelectionHandler(ped, ped->ichInsStart, ped->ichInsEnd);
|
||
ped->ichInsStart = ped->ichInsEnd = -1;
|
||
|
||
#ifdef NEVER
|
||
/* Now send a backspace to deleted and save it in the undo buffer... */
|
||
SLCharHandler(ped, VK_BACK, NOMODIFY);
|
||
fUpdate = TRUE;
|
||
#else
|
||
/* Delete the selected text and save it in undo buff */
|
||
/* Call ECDeleteText() instead of sending a VK_BACK message which
|
||
* results in a EN_UPDATE notification sent even before we insert
|
||
* the deleted chars. This results in Bug #6610.
|
||
* Fix for Bug #6610 -- SANKAR -- 04/19/91 --
|
||
*/
|
||
if (ECDeleteText(ped))
|
||
fUpdate = TRUE;
|
||
#endif
|
||
}
|
||
|
||
if (fDelete)
|
||
{
|
||
/* Insert deleted chars */
|
||
/* Set the selection to the inserted text */
|
||
SLSetSelectionHandler(ped, ichDeleted, ichDeleted);
|
||
SLInsertText(ped, GlobalLock(hDeletedText), cchDeleted);
|
||
GlobalUnlock(hDeletedText);
|
||
GlobalFree(hDeletedText);
|
||
SLSetSelectionHandler(ped, ichDeleted, ichDeleted+cchDeleted);
|
||
fUpdate=TRUE;
|
||
}
|
||
|
||
if(fUpdate)
|
||
{
|
||
/* If we have something to update, send EN_UPDATE before and EN_CHANGE
|
||
* after the actual update.
|
||
* A part of the Fix for Bug #6610 -- SANKAR -- 04/19/91 --
|
||
*/
|
||
ECNotifyParent(ped, EN_UPDATE);
|
||
#ifndef WOW
|
||
if (FChildVisible(ped->hwnd))
|
||
#else
|
||
if (IsWindowVisible(GetParent(ped->hwnd)))
|
||
#endif
|
||
{
|
||
GetClientRect(ped->hwnd, (LPRECT)&rcEdit);
|
||
if (ped->fBorder && rcEdit.right-rcEdit.left &&
|
||
rcEdit.bottom-rcEdit.top)
|
||
{
|
||
/* Don't invalidate the border so that we avoid flicker */
|
||
InflateRect((LPRECT)&rcEdit, -1, -1);
|
||
}
|
||
InvalidateRect(ped->hwnd, (LPRECT)&rcEdit, FALSE);
|
||
UpdateWindow(ped->hwnd);
|
||
}
|
||
ECNotifyParent(ped,EN_CHANGE);
|
||
}
|
||
return(TRUE);
|
||
}
|
||
|