test: editec.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# editec.c File Reference

`#include "precomp.h"`

Go to the source code of this file.

## Classes

struct | EditMenuItemState

## Defines

#define | umin(a, b) ((unsigned)(a) < (unsigned)(b) ? (unsigned)(a) : (unsigned)(b))
#define | umax(a, b) ((unsigned)(a) > (unsigned)(b) ? (unsigned)(a) : (unsigned)(b))
#define | UNICODE_CARRIAGERETURN ((WCHAR)0x0d)
#define | UNICODE_LINEFEED ((WCHAR)0x0a)
#define | UNICODE_TAB ((WCHAR)0x09)
#define | ID_IMEOPENCLOSE 10001
#define | ID_SOFTKBDOPENCLOSE 10002
#define | ID_RECONVERTSTRING 10003

## Functions

ICH | ECFindTabA (LPSTR lpstr, ICH cch)
ICH | ECFindTabW (LPWSTR lpstr, ICH cch)
PSTR | ECLock (PED ped)
void | ECUnlock (PED ped)
UINT | GetActualNegA (HDC hdc, PED ped, int x, LPSTR lpstring, ICH ichString, int nCount, LPSTRIPINFO NegAInfo)
BOOL | ECIsAncestorActive (HWND hwnd)
BOOL | ECSetIMEMenu (HMENU hMenu, HWND hwnd, EditMenuItemState state)
void | ECInOutReconversionMode (PED ped, BOOL fIn)
BOOL NEAR | ECDoIMEMenuCommand (PED ped, int cmd, HWND hwnd)
void | ECMenu (HWND hwnd, PED ped, LPPOINT pt)
void | ECClearText (PED ped)
void | ECCutText (PED ped)
int | ECGetModKeys (int keyMods)
UINT | ECTabTheTextOut (HDC hdc, int xClipStPos, int xClipEndPos, int xStart, int y, LPSTR lpstring, int nCount, ICH ichString, PED ped, int iTabOrigin, BOOL fDraw, LPSTRIPINFO NegCInfoForStrip)
ICH | ECCchInWidth (PED ped, HDC hdc, LPSTR lpText, ICH cch, int width, BOOL fForward)
HBRUSH | ECGetBrush (PED ped, HDC hdc)
void | NextWordCallBack (PED ped, ICH ichStart, BOOL fLeft, ICH *pichMin, ICH *pichMax)
void | NextWordLpkCallBack (PED ped, ICH ichStart, BOOL fLeft, ICH *pichMin, ICH *pichMax)
void | ECWord (PED ped, ICH ichStart, BOOL fLeft, ICH *pichMin, ICH *pichMax)
void | ECSaveUndo (PUNDO pundoFrom, PUNDO pundoTo, BOOL fClear)
void | ECEmptyUndo (PUNDO pundo)
void | ECMergeUndoInsertInfo (PUNDO pundo, ICH ichInsert, ICH cchInsert)\
BOOL | ECInsertText (PED ped, LPSTR lpText, ICH *pcchInsert)
ICH | ECDeleteText (PED ped)
void | ECNotifyParent (PED ped, int notificationCode)
void | ECSetEditClip (PED ped, HDC hdc, BOOL fLeftMargin)
HDC | ECGetEditDC (PED ped, BOOL fFastDC)
void | ECReleaseEditDC (PED ped, HDC hdc, BOOL fFastDC)
void | ECResetTextInfo (PED ped)
BOOL | ECSetText (PED ped, LPSTR lpstr)
void | ECInvalidateClient (PED ped, BOOL fErase)
ICH | ECCopy (PED ped)
LRESULT | EditWndProcA (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT | EditWndProcW (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT | EditWndProcWorker (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, DWORD fAnsi)
LRESULT | EditWndProc (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam)
void | ECFindXORblks (LPBLOCK lpOldBlk, LPBLOCK lpNewBlk, LPBLOCK lpBlk1, LPBLOCK lpBlk2)
BOOL | ECCalcChangeSelection (PED ped, ICH ichOldMinSel, ICH ichOldMaxSel, LPBLOCK OldBlk, LPBLOCK NewBlk)
HBRUSH | ECGetControlBrush (PED ped, HDC hdc, LONG message)
UINT WINAPI | QueryFontAssocStatus (void)
int | ECGetDBCSVector (PED ped, HDC hdc, BYTE CharSet)
LPSTR | ECAnsiNext (PED ped, LPSTR lpCurrent)
LPSTR | ECAnsiPrev (PED ped, LPSTR lpBase, LPSTR lpStr)
ICH | ECNextIch (PED ped, LPSTR pStart, ICH ichCurrent)
ICH | ECPrevIch (PED ped, LPSTR pStart, ICH ichCurrent)
BOOL | ECIsDBCSLeadByte (PED ped, BYTE cch)
WORD | DbcsCombine (HWND hwnd, WORD ch)
ICH | ECAdjustIch (PED ped, LPSTR lpstr, ICH ch)
ICH FAR PASCAL | ECAdjustIchNext (PED ped, LPSTR lpstr, ICH ch)
void | ECUpdateFormat (PED ped, DWORD dwStyle, DWORD dwExStyle)

## Variables

LOOKASIDE | EditLookaside
UINT | fFontAssocStatus = 0xffff

## Define Documentation

#define ID_IMEOPENCLOSE 10001

| Definition at line 31 of file editec.c. Referenced by ECDoIMEMenuCommand(), and ECSetIMEMenu().

#define ID_RECONVERTSTRING 10003

| Definition at line 33 of file editec.c. Referenced by ECDoIMEMenuCommand(), and ECSetIMEMenu().

#define ID_SOFTKBDOPENCLOSE 10002

| Definition at line 32 of file editec.c. Referenced by ECDoIMEMenuCommand(), and ECSetIMEMenu().

#define umax | ( | a,
|  | b |  | ) | ((unsigned)(a) > (unsigned)(b) ? (unsigned)(a) : (unsigned)(b))

| Definition at line 23 of file editec.c. Referenced by ECCchInWidth().

#define umin | ( | a,
|  | b |  | ) | ((unsigned)(a) < (unsigned)(b) ? (unsigned)(a) : (unsigned)(b))

| Definition at line 22 of file editec.c.

#define UNICODE_CARRIAGERETURN ((WCHAR)0x0d)

| Definition at line 25 of file editec.c.

#define UNICODE_LINEFEED ((WCHAR)0x0a)

| Definition at line 26 of file editec.c.

#define UNICODE_TAB ((WCHAR)0x09)

| Definition at line 27 of file editec.c.

## Function Documentation

WORD DbcsCombine | ( | HWND | hwnd,
|  | WORD | ch
| ) |

Definition at line 4109 of file editec.c.

References msg.

Referenced by ComboBoxDBCharHandler(), MLChar(), SLChar(), and xxxLBoxCtlCharInput().

    04110 {
    04111     MSG msg;
    04112     int i = 10; /* loop counter to avoid the infinite loop */
    04113
    04114     while (!PeekMessageA(&msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE)) {
    04115         if (--i == 0)
    04116             return 0;
    04117         Sleep(1);
    04118     }
    04119
    04120     return (WORD)ch | ((WORD)(msg.wParam) << 8);
    04121 }

ICH ECAdjustIch | ( | PED | ped,
|  | LPSTR | lpstr,
|  | ICH | ch
| ) |

Definition at line 4133 of file editec.c.

References ECIsDBCSLeadByte(), tagED::fAnsi, tagED::fDBCS, and ICH.

Referenced by ECAdjustIchNext(), ECCchInWidth(), ECInsertText(), MLBuildchLines(), MLDrawText(), MLInsertText(), MLMouseToIch(), MLSetSelection(), SLChangeSelection(), SLDrawText(), SLMouseToIch(), and SLScrollText().

    04134 {
    04135     ICH newch = ch;
    04136
    04137     if (!ped->fAnsi || !ped->fDBCS || newch == 0)
    04138         return ( ch );
    04139
    04140     if (!ECIsDBCSLeadByte(ped,lpstr[--newch]))
    04141         return ( ch );  // previous char is SBCS
    04142     while(1) {
    04143         if (!ECIsDBCSLeadByte(ped,lpstr[newch])) {
    04144             newch++;
    04145             break;
    04146         }
    04147         if (newch)
    04148             newch--;
    04149         else
    04150             break;
    04151     }
    04152     return ((ch - newch) & 1) ? ch-1 : ch;
    04153 }

ICH FAR PASCAL ECAdjustIchNext | ( | PED | ped,
|  | LPSTR | lpstr,
|  | ICH | ch
| ) |

Definition at line 4162 of file editec.c.

References ECAdjustIch(), ECAnsiNext(), FAR, and ICH.

Referenced by MLDrawText(), and SLScrollText().

    04163 {
    04164     ICH ichNew = ECAdjustIch(ped,lpstr,ch);
    04165     LPSTR lpnew = lpstr+ichNew;
    04166
    04167     // if ch > ichNew then ECAdjustIch adjusted ich.
    04168     if (ch > ichNew)
    04169        lpnew = ECAnsiNext(ped, lpnew);
    04170
    04171     return (ICH)(lpnew-lpstr);
    04172 }

LPSTR ECAnsiNext | ( | PED | ped,
|  | LPSTR | lpCurrent
| ) |

Definition at line 3926 of file editec.c.

References ECIsDBCSLeadByte(), and TRUE.

Referenced by ECAdjustIchNext(), ECWord(), and SLDrawLine().

    03927 {
    03928     return lpCurrent+((ECIsDBCSLeadByte(ped,*lpCurrent)==TRUE) ? 2 : 1);
    03929 }

LPSTR ECAnsiPrev | ( | PED | ped,
|  | LPSTR | lpBase,
|  | LPSTR | lpStr
| ) |

Definition at line 3938 of file editec.c.

References ECIsDBCSLeadByte(), and tagED::fDBCS.

Referenced by ECWord(), MLBuildchLines(), and SLDrawLine().

    03939 {
    03940     LPSTR lpCurrent = lpStr -1;
    03941
    03942     if (!ped->fDBCS)
    03943         return lpCurrent;                        // just return ( lpStr - 1 )
    03944
    03945     if (lpBase >= lpCurrent)
    03946         return lpBase;
    03947
    03948     if (ECIsDBCSLeadByte(ped, *lpCurrent))     // this check makes things faster
    03949         return (lpCurrent - 1);                  // 92/04/04 takaok
    03950
    03951     do {
    03952         lpCurrent--;
    03953         if (!ECIsDBCSLeadByte(ped, *lpCurrent)) {
    03954             lpCurrent++;
    03955             break;
    03956         }
    03957     } while(lpCurrent != lpBase);
    03958
    03959     return lpStr - (((lpStr - lpCurrent) & 1) ? 1 : 2);
    03960 }

BOOL ECCalcChangeSelection | ( | PED | ped,
|  | ICH | ichOldMinSel,
|  | ICH | ichOldMaxSel,
|  | LPBLOCK | OldBlk,
|  | LPBLOCK | NewBlk
| ) |

Definition at line 3692 of file editec.c.

References BLOCK, BOOL, ECFindXORblks(), tagBLOCK::EndPos, FALSE, tagED::ichMaxSel, tagED::ichMinSel, max, min, tagBLOCK::StPos, and TRUE.

Referenced by MLChangeSelection(), and SLChangeSelection().

    03698 {
    03699     BLOCK Blk[2];
    03700     int iBlkCount = 0;
    03701
    03702     Blk[0].StPos = Blk[0].EndPos = Blk[1].StPos = Blk[1].EndPos = 0xFFFFFFFF;
    03703
    03704     /*
    03705      * Check if the Old selection block existed
    03706      */
    03707     if (ichOldMinSel != ichOldMaxSel) {
    03708
    03709         /*
    03710          * Yes! Old block existed.
    03711          */
    03712         Blk[0].StPos = OldBlk->StPos;
    03713         Blk[0].EndPos = OldBlk->EndPos;
    03714         iBlkCount++;
    03715     }
    03716
    03717     /*
    03718      * Check if the new Selection block exists
    03719      */
    03720     if (ped->ichMinSel != ped->ichMaxSel) {
    03721
    03722         /*
    03723          * Yes! New block exists
    03724          */
    03725         Blk[1].StPos = NewBlk->StPos;
    03726         Blk[1].EndPos = NewBlk->EndPos;
    03727         iBlkCount++;
    03728     }
    03729
    03730     /*
    03731      * If both the blocks exist find the XOR of them
    03732      */
    03733     if (iBlkCount == 2) {
    03734
    03735         /*
    03736          * Check if both blocks start at the same character position
    03737          */
    03738         if (ichOldMinSel == ped->ichMinSel) {
    03739
    03740             /*
    03741              * Check if they end at the same character position
    03742              */
    03743             if (ichOldMaxSel == ped->ichMaxSel)
    03744                 return FALSE; /* Nothing changes */
    03745
    03746             Blk[0].StPos = min(NewBlk -> EndPos, OldBlk -> EndPos);
    03747             Blk[0].EndPos = max(NewBlk -> EndPos, OldBlk -> EndPos);
    03748             Blk[1].StPos = 0xFFFFFFFF;
    03749         } else {
    03750             if (ichOldMaxSel == ped->ichMaxSel) {
    03751                 Blk[0].StPos = min(NewBlk->StPos, OldBlk->StPos);
    03752                 Blk[0].EndPos = max(NewBlk->StPos, OldBlk->StPos);
    03753                 Blk[1].StPos = 0xFFFFFFFF;
    03754             } else {
    03755                 ECFindXORblks(OldBlk, NewBlk, &Blk[0], &Blk[1]);
    03756             }
    03757         }
    03758     }
    03759
    03760     RtlCopyMemory(OldBlk, &Blk[0], sizeof(BLOCK));
    03761     RtlCopyMemory(NewBlk, &Blk[1], sizeof(BLOCK));
    03762
    03763     return TRUE; /* Yup , There is something to paint */
    03764 }

ICH ECCchInWidth | ( | PED | ped,
|  | HDC | hdc,
|  | LPSTR | lpText,
|  | ICH | cch,
|  | int | width,
|  | BOOL | fForward
| ) |

Definition at line 1281 of file editec.c.

References tagED::aveCharWidth, tagED::cbChar, tagED::charPasswordChar, tagED::cPasswordCharWidth, ECAdjustIch(), ECT_CALC, ECTabTheTextOut(), tagED::fAnsi, tagED::fDBCS, tagED::fNonPropFont, tagED::fSingle, ICH, MAXLINELENGTH, NULL, umax, and umin.

Referenced by MLBuildchLines(), MLMouseToIch(), SLCalcXOffsetSpecial(), SLDrawText(), SLInsertText(), SLMouseToIch(), and SLScrollText().

    01288 {
    01289     int stringExtent;
    01290     int cchhigh;
    01291     int cchnew = 0;
    01292     int cchlow = 0;
    01293     SIZE size;
    01294     LPSTR lpStart;
    01295
    01296     if ((width <= 0) || !cch)
    01297         return (0);
    01298
    01299     /*
    01300      * Optimize nonproportional fonts for single line ec since they don't have
    01301      * tabs.
    01302      */
    01303     //
    01304     // Change optimize condition for fixed pitch font
    01305     //
    01306     if (ped->fNonPropFont && ped->fSingle && !ped->fDBCS) {
    01307         return (ECAdjustIch( ped, lpText, umin(width/ped->aveCharWidth,(int)cch)));
    01308     }
    01309
    01310     /*
    01311      * Check if password hidden chars are being used.
    01312      */
    01313     if (ped->charPasswordChar) {
    01314         return (umin(width / ped->cPasswordCharWidth, (int)cch));
    01315     }
    01316
    01317     /*
    01318      * ALWAYS RESTRICT TO AT MOST MAXLINELENGTH to avoid overflow...
    01319      */
    01320     cch = umin(MAXLINELENGTH, cch);
    01321
    01322     cchhigh = cch + 1;
    01323     while (cchlow < cchhigh - 1) {
    01324         cchnew = umax((cchhigh - cchlow) / 2, 1) + cchlow;
    01325
    01326         lpStart = lpText;
    01327
    01328         /*
    01329          * If we want to figure out how many fit starting at the end and moving
    01330          * backwards, make sure we move to the appropriate position in the
    01331          * string before calculating the text extent.
    01332          */
    01333         if (!fForward)
    01334             lpStart += (cch - cchnew)*ped->cbChar;
    01335
    01336         if (ped->fSingle) {
    01337             if (ped->fAnsi)
    01338                 GetTextExtentPointA(hdc, (LPSTR)lpStart, cchnew, &size);
    01339             else
    01340                 GetTextExtentPointW(hdc, (LPWSTR)lpStart, cchnew, &size);
    01341             stringExtent = size.cx;
    01342         } else {
    01343             stringExtent = ECTabTheTextOut(hdc, 0, 0, 0, 0,
    01344                 lpStart,
    01345                 cchnew, 0,
    01346                 ped, 0, ECT_CALC, NULL );
    01347         }
    01348
    01349         if (stringExtent > width) {
    01350             cchhigh = cchnew;
    01351         } else {
    01352             cchlow = cchnew;
    01353         }
    01354     }
    01355     //
    01356     // Call ECAdjustIch ( generic case )
    01357     //
    01358     cchlow = ECAdjustIch( ped, lpText, cchlow );
    01359     return (cchlow);
    01360 }

void ECClearText | ( | PED | ped | ) |

Definition at line 692 of file editec.c.

References tagED::fReadOnly, tagED::fSingle, tagED::hwnd, tagED::ichMaxSel, tagED::ichMinSel, L, MLEditWndProc(), and SLEditWndProc().

Referenced by ECCutText(), and EditWndProc().

    00692                             {
    00693     if (!ped->fReadOnly &&
    00694         (ped->ichMinSel < ped->ichMaxSel)) {
    00695         if (ped->fSingle)
    00696             SLEditWndProc(ped->hwnd, ped, WM_CHAR, VK_BACK, 0L );
    00697         else
    00698             MLEditWndProc(ped->hwnd, ped, WM_CHAR, VK_BACK, 0L );
    00699     }
    00700
    00701 }

ICH ECCopy | ( | PED | ped | ) |

Definition at line 2703 of file editec.c.

References tagED::cbChar, tagED::charPasswordChar, CI_16BIT, ECLock(), ECUnlock(), tagED::fAnsi, FAR, GetClientInfo, tagED::hwnd, ICH, tagED::ichMaxSel, tagED::ichMinSel, LHND, NtUserCloseClipboard(), NtUserEmptyClipboard(), NtUserMessageBeep, OpenClipboard(), pfnWowEmptyClipBoard, SetClipboardData(), UserGlobalAlloc, USERGLOBALLOCK, and USERGLOBALUNLOCK.

Referenced by EditWndProc().

    02705 {
    02706     HANDLE hData;
    02707     char *pchSel;
    02708     char FAR *lpchClip;
    02709     ICH cbData;
    02710
    02711     /*
    02712      * Don't allow copies from password style controls
    02713      */
    02714     if (ped->charPasswordChar) {
    02715         NtUserMessageBeep(0);
    02716         return 0;
    02717     }
    02718
    02719     cbData = (ped->ichMaxSel - ped->ichMinSel) * ped->cbChar;
    02720
    02721     if (!cbData)
    02722         return 0;
    02723
    02724     if (!OpenClipboard(ped->hwnd))
    02725         return 0;
    02726
    02727     NtUserEmptyClipboard();
    02728
    02729     /*
    02730      * If we just called EmptyClipboard in the context of a 16 bit
    02731      * app then we also have to tell WOW to nix its 16 handle copy of
    02732      * clipboard data.  WOW does its own clipboard caching because
    02733      * some 16 bit apps use clipboard data even after the clipboard
    02734      * has been emptied.  See the note in the server code.
    02735      *
    02736      * Note: this is the only place where EmptyClipboard is called
    02737      * for a 16 bit app not going through WOW.  If we added others
    02738      * we might want to move this into EmptyClipboard and have two
    02739      * versions.
    02740      */
    02741     if (GetClientInfo()->CI_flags & CI_16BIT) {
    02742         pfnWowEmptyClipBoard();
    02743     }
    02744
    02745
    02746     /*
    02747      * +1 for the terminating NULL
    02748      */
    02749     if (!(hData = UserGlobalAlloc(LHND, (LONG)(cbData + ped->cbChar)))) {
    02750         NtUserCloseClipboard();
    02751         return (0);
    02752     }
    02753
    02754     USERGLOBALLOCK(hData, lpchClip);
    02755     UserAssert(lpchClip);
    02756     pchSel = ECLock(ped);
    02757     pchSel = pchSel + (ped->ichMinSel * ped->cbChar);
    02758
    02759     RtlCopyMemory(lpchClip, pchSel, cbData);
    02760
    02761     if (ped->fAnsi)
    02762         *(lpchClip + cbData) = 0;
    02763     else
    02764         *(LPWSTR)(lpchClip + cbData) = (WCHAR)0;
    02765
    02766     ECUnlock(ped);
    02767     USERGLOBALUNLOCK(hData);
    02768
    02769     SetClipboardData( ped->fAnsi ? CF_TEXT : CF_UNICODETEXT, hData);
    02770
    02771     NtUserCloseClipboard();
    02772
    02773     return (cbData);
    02774 }

void ECCutText | ( | PED | ped | ) |

Definition at line 712 of file editec.c.

References ECClearText(), tagED::fReadOnly, tagED::hwnd, tagED::ichMaxSel, tagED::ichMinSel, L, and SendMessage().

Referenced by EditWndProc().

    00712                           {
    00713     // Cut selection--IE, remove and copy to clipboard, or if no selection,
    00714     // delete (clear) character left.
    00715     if (!ped->fReadOnly &&
    00716         (ped->ichMinSel < ped->ichMaxSel) &&
    00717         SendMessage(ped->hwnd, WM_COPY, 0, 0L)) {
    00718         // If copy was successful, delete the copied text by sending a
    00719         // backspace message which will redraw the text and take care of
    00720         // notifying the parent of changes.
    00721         ECClearText(ped);
    00722     }
    00723 }

ICH ECDeleteText | ( | PED | ped | ) |

Definition at line 2293 of file editec.c.

References tagED::cbChar, tagED::cch, tagED::cchAlloc, CCHALLOCEXTRA, DWORD, ECEmptyUndo(), ECGetEditDC(), ECLock(), ECReleaseEditDC(), ECUnlock(), tagLPKEDITCALLOUT::EditAdjustCaret, tagED::fDirty, tagED::hInstance, tagED::hText, ICH, tagED::ichCaret, tagED::ichMaxSel, tagED::ichMinSel, LHND, LOCALREALLOC, LOCALSIZE, NULL, tagED::pLpkEditCallout, Pundo, TRUE, UNDO_DELETE, UNDO_INSERT, UNDO_NONE, UserGlobalAlloc, and UserGlobalReAlloc.

Referenced by ECImeComposition(), EditWndProc(), MLDeleteText(), SLChar(), SLPaste(), SLReplaceSel(), and SLUndo().

    02295 {
    02296     PSTR pedText;
    02297     ICH cchDelete;
    02298     LPSTR lpDeleteSaveBuffer;
    02299     HANDLE hDeletedText;
    02300     DWORD bufferOffset;
    02301
    02302     cchDelete = ped->ichMaxSel - ped->ichMinSel;
    02303
    02304     if (!cchDelete)
    02305         return (0);
    02306
    02307     /*
    02308      * Ok, now lets delete the text.
    02309      */
    02310     pedText = ECLock(ped);
    02311
    02312     /*
    02313      * Adjust UNDO fields so that we can undo this delete...
    02314      */
    02315     if (ped->undoType == UNDO_NONE) {
    02316 UNDODELETEFROMSCRATCH:
    02317         if (ped->hDeletedText = UserGlobalAlloc(GPTR, (LONG)((cchDelete+1)*ped->cbChar))) {
    02318             ped->undoType = UNDO_DELETE;
    02319             ped->ichDeleted = ped->ichMinSel;
    02320             ped->cchDeleted = cchDelete;
    02321             lpDeleteSaveBuffer = ped->hDeletedText;
    02322             RtlCopyMemory(lpDeleteSaveBuffer, pedText + ped->ichMinSel*ped->cbChar, cchDelete*ped->cbChar);
    02323             lpDeleteSaveBuffer[cchDelete*ped->cbChar] = 0;
    02324         }
    02325     } else if (ped->undoType & UNDO_INSERT) {
    02326 UNDODELETE:
    02327         ECEmptyUndo(Pundo(ped));
    02328
    02329         ped->ichInsStart = ped->ichInsEnd = 0xFFFFFFFF;
    02330         ped->ichDeleted = 0xFFFFFFFF;
    02331         ped->cchDeleted = 0;
    02332         goto UNDODELETEFROMSCRATCH;
    02333     } else if (ped->undoType == UNDO_DELETE) {
    02334         if (ped->ichDeleted == ped->ichMaxSel) {
    02335
    02336             /*
    02337              * Copy deleted text to front of undo buffer
    02338              */
    02339             hDeletedText = UserGlobalReAlloc(ped->hDeletedText, (LONG)(cchDelete + ped->cchDeleted + 1)*ped->cbChar, GHND);
    02340             if (!hDeletedText)
    02341                 goto UNDODELETE;
    02342             bufferOffset = 0;
    02343             ped->ichDeleted = ped->ichMinSel;
    02344         } else if (ped->ichDeleted == ped->ichMinSel) {
    02345
    02346             /*
    02347              * Copy deleted text to end of undo buffer
    02348              */
    02349             hDeletedText = UserGlobalReAlloc(ped->hDeletedText, (LONG)(cchDelete + ped->cchDeleted + 1)*ped->cbChar, GHND);
    02350             if (!hDeletedText)
    02351                 goto UNDODELETE;
    02352             bufferOffset = ped->cchDeleted*ped->cbChar;
    02353         } else {
    02354
    02355             /*
    02356              * Clear the current UNDO delete and add the new one since
    02357                the deletes aren't contiguous.
    02358              */
    02359             goto UNDODELETE;
    02360         }
    02361
    02362         ped->hDeletedText = hDeletedText;
    02363         lpDeleteSaveBuffer = (LPSTR)hDeletedText;
    02364         if (!bufferOffset) {
    02365
    02366             /*
    02367              * Move text in delete buffer up so that we can insert the next
    02368              * text at the head of the buffer.
    02369              */
    02370             RtlMoveMemory(lpDeleteSaveBuffer + cchDelete*ped->cbChar, lpDeleteSaveBuffer,
    02371                     ped->cchDeleted*ped->cbChar);
    02372         }
    02373         RtlCopyMemory(lpDeleteSaveBuffer + bufferOffset, pedText + ped->ichMinSel*ped->cbChar,
    02374                 cchDelete*ped->cbChar);
    02375
    02376         lpDeleteSaveBuffer[(ped->cchDeleted + cchDelete)*ped->cbChar] = 0;
    02377         ped->cchDeleted += cchDelete;
    02378     }
    02379
    02380     if (ped->ichMaxSel != ped->cch) {
    02381
    02382         /*
    02383          * We are deleting text from the middle of the buffer so we have to
    02384            shift text to the left.
    02385          */
    02386         RtlMoveMemory(pedText + ped->ichMinSel*ped->cbChar, pedText + ped->ichMaxSel*ped->cbChar,
    02387                 (ped->cch - ped->ichMaxSel)*ped->cbChar);
    02388     }
    02389
    02390     if (ped->cchAlloc - ped->cch > CCHALLOCEXTRA) {
    02391
    02392         /*
    02393          * Free some memory since we deleted a lot
    02394          */
    02395         LOCALREALLOC(ped->hText, (DWORD)(ped->cch + (CCHALLOCEXTRA / 2))*ped->cbChar, LHND, ped->hInstance, NULL);
    02396         ped->cchAlloc = LOCALSIZE(ped->hText, ped->hInstance) / ped->cbChar;
    02397     }
    02398
    02399     ped->cch -= cchDelete;
    02400
    02401     if (ped->pLpkEditCallout) {
    02402         HDC     hdc;
    02403
    02404         hdc = ECGetEditDC (ped, TRUE);
    02405         ped->ichMinSel = ped->pLpkEditCallout->EditAdjustCaret (ped, hdc, pedText, ped->ichMinSel);
    02406         ECReleaseEditDC (ped, hdc, TRUE);
    02407     }
    02408
    02409     ped->ichCaret = ped->ichMaxSel = ped->ichMinSel;
    02410
    02411     ECUnlock(ped);
    02412
    02413     /*
    02414      * Set dirty bit
    02415      */
    02416     ped->fDirty = TRUE;
    02417
    02418     return (cchDelete);
    02419 }

BOOL NEAR ECDoIMEMenuCommand | ( | PED | ped,
|  | int | cmd,
|  | HWND | hwnd
| ) |

Definition at line 423 of file editec.c.

References BOOL, tagED::cbChar, DWORD, ECImmSetCompositionWindow(), ECInOutReconversionMode(), ECLock(), ECUnlock(), FALSE, tagED::fAnsi, fpImmEnumInputContext, fpImmGetContext, fpImmGetConversionStatus, fpImmGetOpenStatus, fpImmReleaseContext, fpImmSetCompositionStringA, fpImmSetCompositionStringW, fpImmSetOpenStatus, tagED::ichMaxSel, tagED::ichMinSel, ID_IMEOPENCLOSE, ID_RECONVERTSTRING, ID_SOFTKBDOPENCLOSE, L, lpDest, NULL, SyncSoftKbdState(), TRUE, UserLocalAlloc, and UserLocalFree.

Referenced by ECMenu().

    00424 {
    00425     HIMC hIMC;
    00426
    00427     // early out
    00428     switch (cmd) {
    00429     case ID_IMEOPENCLOSE:
    00430     case ID_SOFTKBDOPENCLOSE:
    00431     case ID_RECONVERTSTRING:
    00432         break;
    00433     default:
    00434         return FALSE;
    00435     }
    00436
    00437     // everybody needs hIMC, so get it here
    00438     hIMC = fpImmGetContext(hwnd);
    00439     if (hIMC == NULL) {
    00440         // indicate to caller, that no further command processing needed
    00441         return TRUE;
    00442     }
    00443
    00444     switch (cmd) {
    00445     case ID_IMEOPENCLOSE:
    00446         {
    00447             // switch IME Open/Close status
    00448             BOOL fOpen = fpImmGetOpenStatus(hIMC);
    00449
    00450             fpImmSetOpenStatus(hIMC, !fOpen);
    00451         }
    00452         break;
    00453
    00454     case ID_SOFTKBDOPENCLOSE:
    00455         {
    00456             DWORD fdwConversion;
    00457
    00458             if (fpImmGetConversionStatus(hIMC, &fdwConversion, NULL)) {
    00459                 //
    00460                 // Toggle soft keyboard Open/Close status
    00461                 //
    00462                 fpImmEnumInputContext(0, SyncSoftKbdState,
    00463                         (fdwConversion & IME_CMODE_SOFTKBD) != IME_CMODE_SOFTKBD);
    00464             }
    00465         }
    00466         break;
    00467
    00468     case ID_RECONVERTSTRING:
    00469         {
    00470             DWORD dwStrLen; // holds TCHAR count of recionversion string
    00471             DWORD cbLen;    // holds BYTE SIZE of reconversion string
    00472             DWORD dwSize;
    00473             LPRECONVERTSTRING lpRCS;
    00474
    00475             // pass current selection to IME for reconversion
    00476             dwStrLen = ped->ichMaxSel - ped->ichMinSel;
    00477             cbLen = dwStrLen * ped->cbChar;
    00478             dwSize = cbLen + sizeof(RECONVERTSTRING) + 8;
    00479
    00480             lpRCS = (LPRECONVERTSTRING)UserLocalAlloc(0, dwSize);
    00481
    00482             if (lpRCS) {
    00483                 LPBYTE pText;
    00484
    00485                 pText = ECLock(ped);
    00486                 if (pText != NULL) {
    00487                     LPBYTE lpDest;
    00488                     BOOL (WINAPI* fpSetCompositionStringAW)(HIMC, DWORD, LPCVOID, DWORD, LPCVOID, DWORD);
    00489
    00490                     lpRCS->dwSize = dwSize;
    00491                     lpRCS->dwVersion = 0;
    00492
    00493                     lpRCS->dwStrLen =
    00494                     lpRCS->dwCompStrLen =
    00495                     lpRCS->dwTargetStrLen = dwStrLen;
    00496
    00497                     lpRCS->dwStrOffset = sizeof(RECONVERTSTRING);
    00498                     lpRCS->dwCompStrOffset =
    00499                     lpRCS->dwTargetStrOffset = 0;
    00500
    00501                     lpDest = (LPBYTE)lpRCS + sizeof(RECONVERTSTRING);
    00502
    00503                     RtlCopyMemory(lpDest, pText + ped->ichMinSel * ped->cbChar, cbLen);
    00504                     if (ped->fAnsi) {
    00505                         LPBYTE psz = (LPBYTE)lpDest;
    00506                         psz[cbLen] = '\0';
    00507                         fpSetCompositionStringAW = fpImmSetCompositionStringA;
    00508                     } else {
    00509                         LPWSTR pwsz = (LPWSTR)lpDest;
    00510                         pwsz[dwStrLen] = L'\0';
    00511                         fpSetCompositionStringAW = fpImmSetCompositionStringW;
    00512                     }
    00513
    00514                     ECUnlock(ped);
    00515
    00516                     UserAssert(fpSetCompositionStringAW != NULL);
    00517
    00518                     ECInOutReconversionMode(ped, TRUE);
    00519                     ECImmSetCompositionWindow(ped, 0, 0); // x and y will be overriden anyway
    00520                     fpSetCompositionStringAW(hIMC, SCS_SETRECONVERTSTRING, lpRCS, dwSize, NULL, 0);
    00521                 } // pText
    00522                 UserLocalFree(lpRCS);
    00523             }
    00524         }
    00525         break;
    00526
    00527     default:
    00528         // should never reach here.
    00529         RIPMSG1(RIP_ERROR, "ECDoIMEMenuCommand: unknown command id %d; should never reach here.", cmd);
    00530         return FALSE;
    00531     }
    00532
    00533     UserAssert(hIMC != NULL);
    00534     fpImmReleaseContext(hwnd, hIMC);
    00535
    00536     return TRUE;
    00537 }

void ECEmptyUndo | ( | PUNDO | pundo | ) |

Definition at line 1977 of file editec.c.

References tagUNDO::hDeletedText, and UserGlobalFree.

Referenced by ECDeleteText(), ECResetTextInfo(), EditWndProc(), MLEditWndProc(), MLInsertText(), MLPasteText(), MLReplaceSel(), SLEditWndProc(), and SLReplaceSel().

    01979 {
    01980     if (pundo->hDeletedText)
    01981         UserGlobalFree(pundo->hDeletedText);
    01982
    01983     RtlZeroMemory(pundo, sizeof(UNDO) );
    01984 }

ICH ECFindTabA | ( | LPSTR | lpstr,
|  | ICH | cch
| ) |

Definition at line 1371 of file editec.c.

References ICH.

Referenced by ECTabTheTextOut().

    01374 {
    01375     LPSTR copylpstr = lpstr;
    01376
    01377     if (!cch)
    01378         return 0;
    01379
    01380     while (*lpstr != VK_TAB) {
    01381         lpstr++;
    01382         if (--cch == 0)
    01383             break;
    01384     }
    01385     return ((ICH)(lpstr - copylpstr));
    01386 }

ICH ECFindTabW | ( | LPWSTR | lpstr,
|  | ICH | cch
| ) |

Definition at line 1388 of file editec.c.

References ICH.

Referenced by ECTabTheTextOut().

    01391 {
    01392     LPWSTR copylpstr = lpstr;
    01393
    01394     if (!cch)
    01395         return 0;
    01396
    01397     while (*lpstr != VK_TAB) {
    01398         lpstr++;
    01399         if (--cch == 0)
    01400             break;
    01401     }
    01402     return ((ICH)(lpstr - copylpstr));
    01403 }

void ECFindXORblks | ( | LPBLOCK | lpOldBlk,
|  | LPBLOCK | lpNewBlk,
|  | LPBLOCK | lpBlk1,
|  | LPBLOCK | lpBlk2
| ) |

Definition at line 3652 of file editec.c.

References tagBLOCK::EndPos, LPBLOCK, max, min, and tagBLOCK::StPos.

Referenced by ECCalcChangeSelection().

    03657 {
    03658     if (lpOldBlk->StPos >= lpNewBlk->StPos) {
    03659         lpBlk1->StPos = lpNewBlk->StPos;
    03660         lpBlk1->EndPos = min(lpOldBlk->StPos, lpNewBlk->EndPos);
    03661     } else {
    03662         lpBlk1->StPos = lpOldBlk->StPos;
    03663         lpBlk1->EndPos = min(lpNewBlk->StPos, lpOldBlk->EndPos);
    03664     }
    03665
    03666     if (lpOldBlk->EndPos <= lpNewBlk->EndPos) {
    03667         lpBlk2->StPos = max(lpOldBlk->EndPos, lpNewBlk->StPos);
    03668         lpBlk2->EndPos = lpNewBlk->EndPos;
    03669     } else {
    03670         lpBlk2->StPos = max(lpNewBlk->EndPos, lpOldBlk->StPos);
    03671         lpBlk2->EndPos = lpOldBlk->EndPos;
    03672     }
    03673 }

HBRUSH ECGetBrush | ( | PED | ped,
|  | HDC | hdc
| ) |

Definition at line 1412 of file editec.c.

References BOOL, DWORD, ECGetControlBrush(), tagED::fDisabled, tagED::fReadOnly, tagED::fSingle, GETAPPVER, GetSysColor(), and VER40.

Referenced by MLDrawText(), MLScroll(), SLChangeSelection(), SLDrawLine(), SLDrawText(), SLPaint(), and SLScrollText().

    01413 {
    01414     HBRUSH  hbr;
    01415     BOOL    f40Compat;
    01416
    01417     f40Compat = (GETAPPVER() >= VER40);
    01418
    01419     // Get background brush
    01420     if ((ped->fReadOnly || ped->fDisabled) && f40Compat) {
    01421         hbr = ECGetControlBrush(ped, hdc, WM_CTLCOLORSTATIC);
    01422     } else
    01423         hbr = ECGetControlBrush(ped, hdc, WM_CTLCOLOREDIT);
    01424
    01425     if (ped->fDisabled && (ped->fSingle || f40Compat)) {
    01426         DWORD rgb;
    01427
    01428         // Change text color
    01429         rgb = GetSysColor(COLOR_GRAYTEXT);
    01430         if (rgb != GetBkColor(hdc))
    01431             SetTextColor(hdc, rgb);
    01432     }
    01433     return(hbr);
    01434 }

HBRUSH ECGetControlBrush | ( | PED | ped,
|  | HDC | hdc,
|  | LONG | message
| ) |

Definition at line 3776 of file editec.c.

References DefWindowProcWorker(), tagED::fAnsi, GETPTI, tagED::hwnd, NULL, PtiCurrent, REBASEPTR, SendMessageWorker(), tagWND::spwndOwner, tagWND::spwndParent, TestwndPopup, and ValidateHwnd.

Referenced by ECGetBrush().

    03780 {
    03781     PWND pwndSend;
    03782     PWND pwndEdit;
    03783
    03784     pwndEdit = ValidateHwnd(ped->hwnd);
    03785
    03786     if (pwndEdit == (PWND)NULL)
    03787         return (HBRUSH)0;
    03788
    03789     if ((pwndSend = (TestwndPopup(pwndEdit) ? pwndEdit->spwndOwner : pwndEdit->spwndParent)) == NULL)
    03790         pwndSend = pwndEdit;
    03791     else
    03792         pwndSend = REBASEPTR(pwndEdit, pwndSend);
    03793
    03794     UserAssert(pwndSend);
    03795
    03796     if (PtiCurrent() != GETPTI(pwndSend)) {
    03797         return (HBRUSH)DefWindowProcWorker(pwndSend, message,
    03798                 (WPARAM)hdc, (LPARAM)pwndEdit, ped->fAnsi);
    03799     }
    03800
    03801     /*
    03802      * By using the correct A/W call we avoid a c/s transition
    03803      * on this SendMessage().
    03804      */
    03805     return (HBRUSH)SendMessageWorker(pwndSend, message, (WPARAM)hdc,
    03806             (LPARAM)ped->hwnd, ped->fAnsi);
    03807 }

int ECGetDBCSVector | ( | PED | ped,
|  | HDC | hdc,
|  | BYTE | CharSet
| ) |

Definition at line 3820 of file editec.c.

References BOOL, BYTE, tagED::DBCSVector, DWORD, FALSE, tagED::fAnsi, FAREAST_CHARSET_BITS, fFontAssocStatus, GetACPCharSet(), QueryFontAssocStatus(), and TRUE.

Referenced by ECSetFont().

    03821 {
    03822     BOOL bDBCSCodePage = FALSE;
    03823     /*
    03824      * if DEFAUT_CHARSET was passed, we will convert that to Shell charset..
    03825      */
    03826     if (CharSet == DEFAULT_CHARSET) {
    03827         CharSet = (BYTE)GetTextCharset(hdc);
    03828
    03829         /*
    03830          * if CharSet is still DEFAULT_CHARSET, it means gdi has some problem..
    03831          * then just return default.. we get charset from CP_ACP..
    03832          */
    03833         if (CharSet == DEFAULT_CHARSET) {
    03834             CharSet = (BYTE)GetACPCharSet();
    03835         }
    03836     }
    03837
    03838     switch (CharSet) {
    03839     case SHIFTJIS_CHARSET:
    03840     case HANGEUL_CHARSET:
    03841     case CHINESEBIG5_CHARSET:
    03842     case GB2312_CHARSET:
    03843         bDBCSCodePage = TRUE;
    03844         break;
    03845
    03846     case ANSI_CHARSET:            // 0
    03847     case SYMBOL_CHARSET:          // 2
    03848     case OEM_CHARSET:             // 255
    03849         if (fFontAssocStatus == 0xffff)
    03850             fFontAssocStatus = QueryFontAssocStatus();
    03851
    03852         if ((((CharSet + 2) & 0xf) & fFontAssocStatus)) {
    03853             bDBCSCodePage = TRUE;
    03854             /*
    03855              * Bug 117558, etc.
    03856              * Try to get a meaningful character set for associated font.
    03857              */
    03858             CharSet = (BYTE)GetACPCharSet();
    03859         } else {
    03860             bDBCSCodePage = FALSE;
    03861         }
    03862         break;
    03863
    03864     default:
    03865         bDBCSCodePage = FALSE;
    03866     }
    03867
    03868     if (bDBCSCodePage) {
    03869         CHARSETINFO CharsetInfo;
    03870         DWORD CodePage;
    03871         CPINFO CPInfo;
    03872         int lbIX;
    03873
    03874         if (TranslateCharsetInfo((DWORD *)CharSet, &CharsetInfo, TCI_SRCCHARSET)) {
    03875             CodePage = CharsetInfo.ciACP;
    03876         } else {
    03877             CodePage = CP_ACP;
    03878         }
    03879
    03880         GetCPInfo(CodePage, &CPInfo);
    03881         for (lbIX=0 ; CPInfo.LeadByte[lbIX] != 0 ; lbIX+=2) {
    03882             ped->DBCSVector[lbIX  ] = CPInfo.LeadByte[lbIX];
    03883             ped->DBCSVector[lbIX+1] = CPInfo.LeadByte[lbIX+1];
    03884         }
    03885         ped->DBCSVector[lbIX  ] = 0x0;
    03886         ped->DBCSVector[lbIX+1] = 0x0;
    03887     } else {
    03888         ped->DBCSVector[0] = 0x0;
    03889         ped->DBCSVector[1] = 0x0;
    03890     }
    03891
    03892     //
    03893     // Final check: if the font supports DBCS glyphs
    03894     //
    03895     // If we've got a font with DBCS glyphs, let's mark PED so.
    03896     // But since the font's primary charset is the one other than FE,
    03897     // we can only support UNICODE Edit control.
    03898     //
    03899     //  a) GDI performs A/W conversion for ANSI apps based on the primary
    03900     //     character set in hDC, so it will break anyway.
    03901     //  b) ANSI applications are only supported on their native system locales:
    03902     //     GetACPCharSet() is expected to return a FE code page.
    03903     //  c) ANSI Edit control requires DBCSVector, which cannot be
    03904     //     initialized without a FE code page.
    03905     //
    03906     if (!ped->fAnsi) {
    03907         FONTSIGNATURE fontSig;
    03908
    03909         GetTextCharsetInfo(hdc, &fontSig, 0);
    03910         if (fontSig.fsCsb[0] & FAREAST_CHARSET_BITS) {
    03911             bDBCSCodePage = TRUE;
    03912             // Since this is UNICODE, we're not
    03913         }
    03914     }
    03915
    03916     return bDBCSCodePage;
    03917 }

HDC ECGetEditDC | ( | PED | ped,
|  | BOOL | fFastDC
| ) |

Definition at line 2492 of file editec.c.

References BOOL, ECSetEditClip(), tagED::hFont, tagED::hwnd, NtUserGetDC(), NtUserHideCaret(), and tagED::xOffset.

Referenced by ECCreate(), ECDeleteText(), ECImeComposition(), ECInsertText(), ECSetCaretHandler(), ECSetPasswordChar(), EditWndProc(), MLBuildchLines(), MLCalcXOffset(), MLDeleteText(), MLEditWndProc(), MLEnsureCaretVisible(), MLInsertText(), MLKeyDown(), MLKillFocus(), MLMouseMotion(), MLMoveSelectionRestricted(), MLScroll(), MLSetFocus(), MLSetSelection(), NextWordLpkCallBack(), SLChar(), SLEditWndProc(), SLInsertText(), SLKeyDown(), SLMouseMotion(), SLMoveSelectionRestricted(), SLPaste(), SLReplaceSel(), SLSetFocus(), and SLSetSelection().

    02495 {
    02496     HDC hdc;
    02497
    02498     if (!fFastDC)
    02499         NtUserHideCaret(ped->hwnd);
    02500
    02501     if ( hdc = NtUserGetDC(ped->hwnd) ) {
    02502         ECSetEditClip(ped, hdc, (BOOL)(ped->xOffset == 0));
    02503
    02504         /*
    02505          * Select the proper font for this edit control's dc.
    02506          */
    02507         if (ped->hFont)
    02508             SelectObject(hdc, ped->hFont);
    02509     }
    02510
    02511     return hdc;
    02512 }

int ECGetModKeys | ( | int | keyMods | ) |

Definition at line 733 of file editec.c.

References CTRLDOWN, GetKeyState(), NOMODIFY, and SHFTDOWN.

Referenced by MLChar(), MLKeyDown(), and SLKeyDown().

    00733                                 {
    00734     int scState;
    00735
    00736     scState = 0;
    00737
    00738     if (!keyMods) {
    00739         if (GetKeyState(VK_CONTROL) < 0)
    00740             scState |= CTRLDOWN;
    00741         if (GetKeyState(VK_SHIFT) < 0)
    00742             scState |= SHFTDOWN;
    00743     } else if (keyMods != NOMODIFY)
    00744         scState = keyMods;
    00745
    00746     return scState;
    00747 }

void ECInOutReconversionMode | ( | PED | ped,
|  | BOOL | fIn
| ) |

Definition at line 402 of file editec.c.

References FALSE, tagED::fFocus, tagED::fInReconversion, tagED::hwnd, NtUserHideCaret(), NtUserShowCaret(), and TRUE.

Referenced by ECDoIMEMenuCommand(), ECImeComposition(), EcImeRequestHandler(), EditWndProc(), MLChar(), MLEditWndProc(), and SLChar().

    00403 {
    00404     UserAssert(fIn == TRUE || fIn == FALSE);
    00405     if (fIn == ped->fInReconversion) {
    00406         return;
    00407     }
    00408     ped->fInReconversion = fIn;
    00409     if (ped->fFocus) {
    00410         (fIn ? NtUserHideCaret: NtUserShowCaret)(ped->hwnd);
    00411     }
    00412
    00413     return;
    00414 }

BOOL ECInsertText | ( | PED | ped,
|  | LPSTR | lpText,
|  | ICH * | pcchInsert
| ) |

Definition at line 2059 of file editec.c.

References BOOL, tagED::cbChar, tagED::cch, tagED::cchAlloc, CCHALLOCEXTRA, CharLowerBuffA(), CharLowerBuffW(), tagED::charSet, CharToOemBuffA(), CharToOemBuffW(), CharUpperBuffA(), CharUpperBuffW(), DWORD, ECAdjustIch(), ECGetEditDC(), ECIsDBCSLeadByte(), ECLock(), ECMergeUndoInsertInfo(), ECReleaseEditDC(), ECUnlock(), tagLPKEDITCALLOUT::EditAdjustCaret, tagLPKEDITCALLOUT::EditVerifyText, FALSE, tagED::fAnsi, tagED::fDirty, GETAPPVER, tagED::hInstance, tagED::hText, ICH, tagED::ichCaret, tagED::ichMaxSel, tagED::ichMinSel, INT, IS_DBCS_ENABLED, IsCharLowerA(), IsCharLowerW(), LHND, LOCALREALLOC, LOCALSIZE, OemToCharBuffA(), OemToCharBuffW(), tagED::pLpkEditCallout, Pundo, tagED::pwnd, strlen(), TRUE, UNICODE_CARRIAGERETURN, UNICODE_LINEFEED, UNICODE_TAB, and VER50.

Referenced by ECSetText(), MLInsertText(), and SLInsertText().

    02063 {
    02064     PSTR pedText;
    02065     PSTR pTextBuff;
    02066     LONG style;
    02067     HANDLE hTextCopy;
    02068     DWORD allocamt;
    02069
    02070     //
    02071     // If the last byte (lpText[cchInsert - 1]) is a DBCS leading byte
    02072     // we need to adjust it.
    02073     //
    02074     *pcchInsert = ECAdjustIch(ped, lpText, *pcchInsert);
    02075
    02076     if (!*pcchInsert)
    02077         return TRUE;
    02078
    02079     /*
    02080      * Do we already have enough memory??
    02081      */
    02082     if (*pcchInsert >= (ped->cchAlloc - ped->cch)) {
    02083
    02084         /*
    02085          * Allocate what we need plus a little extra. Return FALSE if we are
    02086          * unsuccessful.
    02087          */
    02088         allocamt = (ped->cch + *pcchInsert) * ped->cbChar;
    02089         allocamt += CCHALLOCEXTRA;
    02090
    02091 // if (!ped->fSingle) {
    02092               hTextCopy = LOCALREALLOC(ped->hText, allocamt, LHND, ped->hInstance, &lpText);
    02093               if (hTextCopy) {
    02094                   ped->hText = hTextCopy;
    02095               } else {
    02096                   return FALSE;
    02097               }
    02098 // } else {
    02099 // if (!LocalReallocSafe(ped->hText, allocamt, LHND, pped))
    02100 //                return FALSE;
    02101 // }
    02102
    02103         ped->cchAlloc = LOCALSIZE(ped->hText, ped->hInstance) / ped->cbChar;
    02104     }
    02105
    02106
    02107     /*
    02108      * Ok, we got the memory. Now copy the text into the structure
    02109      */
    02110     pedText = ECLock(ped);
    02111
    02112     if (ped->pLpkEditCallout) {
    02113         HDC     hdc;
    02114         INT     iResult;
    02115
    02116         hdc = ECGetEditDC (ped, TRUE);
    02117         iResult = ped->pLpkEditCallout->EditVerifyText (ped, hdc, pedText, ped->ichCaret, lpText, *pcchInsert);
    02118         ECReleaseEditDC (ped, hdc, TRUE);
    02119
    02120         if (iResult == 0) {
    02121             ECUnlock (ped);
    02122             return TRUE;
    02123         }
    02124     }
    02125
    02126     /*
    02127      * Get a pointer to the place where text is to be inserted
    02128      */
    02129     pTextBuff = pedText + ped->ichCaret * ped->cbChar;
    02130
    02131     if (ped->ichCaret != ped->cch) {
    02132
    02133         /*
    02134          * We are inserting text into the middle. We have to shift text to the
    02135          * right before inserting new text.
    02136          */
    02137          memmove(pTextBuff + *pcchInsert * ped->cbChar, pTextBuff, (ped->cch-ped->ichCaret) * ped->cbChar);
    02138     }
    02139
    02140     /*
    02141      * Make a copy of the text being inserted in the edit buffer.
    02142      * Use this copy for doing UPPERCASE/LOWERCASE ANSI/OEM conversions
    02143      * Fix for Bug #3406 -- 01/29/91 -- SANKAR --
    02144      */
    02145     memmove(pTextBuff, lpText, *pcchInsert * ped->cbChar);
    02146     ped->cch += *pcchInsert;
    02147
    02148     /*
    02149      * Get the control's style
    02150      */
    02151     style = ped->pwnd->style;
    02152
    02153     /*
    02154      * Do the Upper/Lower conversion
    02155      */
    02156     if (style & ES_LOWERCASE) {
    02157         if (ped->fAnsi)
    02158             CharLowerBuffA((LPSTR)pTextBuff, *pcchInsert);
    02159         else
    02160             CharLowerBuffW((LPWSTR)pTextBuff, *pcchInsert);
    02161     } else {
    02162         if (style & ES_UPPERCASE) {
    02163             if (ped->fAnsi) {
    02164                 CharUpperBuffA(pTextBuff, *pcchInsert);
    02165             } else {
    02166                 CharUpperBuffW((LPWSTR)pTextBuff, *pcchInsert);
    02167             }
    02168         }
    02169     }
    02170
    02171     /*
    02172      * Do the OEM conversion
    02173      */
    02174     if ((style & ES_OEMCONVERT) &&
    02175             // For backward compatibility with NT4, we don't perform OEM conversion
    02176             // for older apps if the system locale is FarEast.
    02177             //
    02178             (!IS_DBCS_ENABLED() || GETAPPVER() >= VER50 || GetOEMCP() != GetACP())) {
    02179
    02180         ICH i;
    02181
    02182         if (ped->fAnsi) {
    02183             for (i = 0; i < *pcchInsert; i++) {
    02184                 //
    02185                 // We don't need to call CharToOemBuff etc. if the character
    02186                 // is a double byte character.  And, calling ECIsDBCSLeadByte is
    02187                 // faster and less complicated because we don't have to deal
    02188                 // with the 2 byte dbcs cases.
    02189                 //
    02190                 if (IS_DBCS_ENABLED() && ECIsDBCSLeadByte(ped, *(lpText+i))) {
    02191                     i++;
    02192                     continue;
    02193                 }
    02194
    02195                 //
    02196                 // Windows Bug (Whistler) 35289
    02197                 // greek has funny rules for casing, so we need to check for it.
    02198                 // for nashville we should be doing something more appropriate
    02199                 // but for now, leave as Win95 golden
    02200                 //
    02201                 if (ped->charSet != GREEK_CHARSET && IsCharLowerA(*(pTextBuff + i))) {
    02202                     CharUpperBuffA(pTextBuff + i, 1);
    02203                     CharToOemBuffA(pTextBuff + i, pTextBuff + i, 1);
    02204                     OemToCharBuffA(pTextBuff + i, pTextBuff + i, 1);
    02205                     CharLowerBuffA(pTextBuff + i, 1);
    02206                 } else {
    02207                     CharToOemBuffA(pTextBuff + i, pTextBuff + i, 1);
    02208                     OemToCharBuffA(pTextBuff + i, pTextBuff + i, 1);
    02209                 }
    02210             }
    02211         } else {
    02212             //
    02213             // Because 'ch' may become DBCS, and have a space for NULL.
    02214             //
    02215             UCHAR ch[4];
    02216             LPWSTR lpTextW = (LPWSTR)pTextBuff;
    02217
    02218             for (i = 0; i < *pcchInsert; i++) {
    02219                 if (*(lpTextW + i) == UNICODE_CARRIAGERETURN ||
    02220                     *(lpTextW + i) == UNICODE_LINEFEED ||
    02221                     *(lpTextW + i) == UNICODE_TAB) {
    02222                     continue;
    02223                 }
    02224                 //
    02225                 // Windows Bug (Whistler) 35289
    02226                 // greek has funny rules for casing, so we need to check for it.
    02227                 // for nashville we should be doing something more appropriate
    02228                 // but for now, leave as Win95 golden
    02229                 //
    02230                 if (ped->charSet != GREEK_CHARSET && IsCharLowerW(*(lpTextW + i))) {
    02231                     CharUpperBuffW(lpTextW + i, 1);
    02232                     *(LPDWORD)ch = 0; // make sure the null-terminate.
    02233                     CharToOemBuffW(lpTextW + i, ch, 1);
    02234                     //
    02235                     // We assume any SBCS/DBCS character will converted
    02236                     // to 1 Unicode char, Otherwise, we may overwrite
    02237                     // next character...
    02238                     //
    02239                     OemToCharBuffW(ch, lpTextW + i, strlen(ch));
    02240                     CharLowerBuffW(lpTextW + i, 1);
    02241                 } else {
    02242                     *(LPDWORD)ch = 0; // make sure the null-terminate.
    02243                     CharToOemBuffW(lpTextW + i, ch, 1);
    02244                     //
    02245                     // We assume any SBCS/DBCS character will converted
    02246                     // to 1 Unicode char, Otherwise, we may overwrite
    02247                     // next character...
    02248                     //
    02249                     OemToCharBuffW(ch, lpTextW + i, strlen(ch));
    02250                 }
    02251             }
    02252         }
    02253     }
    02254
    02255     /* Adjust UNDO fields so that we can undo this insert... */
    02256     ECMergeUndoInsertInfo(Pundo(ped), ped->ichCaret, *pcchInsert);
    02257
    02258     ped->ichCaret += *pcchInsert;
    02259
    02260     if (ped->pLpkEditCallout) {
    02261         HDC     hdc;
    02262
    02263         hdc = ECGetEditDC (ped, TRUE);
    02264         ped->ichCaret = ped->pLpkEditCallout->EditAdjustCaret (ped, hdc, pedText, ped->ichCaret);
    02265         ECReleaseEditDC (ped, hdc, TRUE);
    02266     }
    02267
    02268     ped->ichMinSel = ped->ichMaxSel = ped->ichCaret;
    02269
    02270     ECUnlock(ped);
    02271
    02272     /*
    02273      * Set dirty bit
    02274      */
    02275     ped->fDirty = TRUE;
    02276
    02277     return TRUE;
    02278 }

void ECInvalidateClient | ( | PED | ped,
|  | BOOL | fErase
| ) |

Definition at line 2679 of file editec.c.

References _GetClientRect(), tagED::fFlatBorder, tagED::hwnd, InflateRect(), NtUserInvalidateRect(), NULL, tagED::pwnd, and SYSMET.

Referenced by ECResetTextInfo(), ECSetMargin(), ECUpdateFormat(), EditWndProc(), and SLUndo().

    02680 {
    02681     if (ped->fFlatBorder) {
    02682         RECT    rcT;
    02683
    02684         _GetClientRect(ped->pwnd, &rcT);
    02685         InflateRect(&rcT, -SYSMET(CXBORDER),
    02686             -SYSMET(CYBORDER));
    02687         NtUserInvalidateRect(ped->hwnd, &rcT, fErase);
    02688     } else {
    02689         NtUserInvalidateRect(ped->hwnd, NULL, fErase);
    02690     }
    02691 }

BOOL ECIsAncestorActive | ( | HWND | hwnd | ) |

Definition at line 242 of file editec.c.

References BOOL, GetParent(), NULL, TestWF, TRUE, ValidateHwnd, WFCHILD, WFCPRESENT, WFFRAMEON, and WFWIN40COMPAT.

Referenced by EditWndProc().

    00243 {
    00244     // We want to return TRUE always for top level windows.  That's because
    00245     // of how WM_MOUSEACTIVATE works.  If we see the click at all, the
    00246     // window is active.  However, if we reach a child ancestor that has
    00247     // a caption, return the frame-on style bit.
    00248     //
    00249     // Note that calling FlashWindow() will have an effect.  If the user
    00250     // clicks on an edit field in a child window that is flashed off, nothing
    00251     // will happen unless the window stops flashing and ncactivates first.
    00252
    00253     while (hwnd) {
    00254         PWND pwnd = ValidateHwnd( hwnd );
    00255         //
    00256         // Bail out if some parent window isn't 4.0 compatible or we've
    00257         // reached the top.  Fixes compatibility problems with 3.x apps,
    00258         // especially MFC samples.
    00259         //
    00260         if (!TestWF(pwnd, WFWIN40COMPAT) || !TestWF(pwnd, WFCHILD))
    00261             hwnd = NULL; // to break us out of the loop
    00262         else if (TestWF(pwnd, WFCPRESENT))
    00263             return(TestWF(pwnd, WFFRAMEON) != 0);
    00264         else
    00265             hwnd = GetParent(hwnd);
    00266     }
    00267
    00268     return(TRUE);
    00269 }

BOOL ECIsDBCSLeadByte | ( | PED | ped,
|  | BYTE | cch
| ) |

Definition at line 4083 of file editec.c.

References BOOL, tagED::DBCSVector, FALSE, tagED::fAnsi, tagED::fDBCS, and TRUE.

Referenced by ECAdjustIch(), ECAnsiNext(), ECAnsiPrev(), ECInsertText(), ECNextIch(), ECPrevIch(), ECTabTheTextOut(), ECWord(), MLBuildchLines(), MLChar(), MLMouseMotion(), SLChar(), SLMouseMotion(), and SLMouseToIch().

    04084 {
    04085     int i;
    04086
    04087     if (!ped->fDBCS || !ped->fAnsi)
    04088         return (FALSE);
    04089
    04090     for (i = 0; ped->DBCSVector[i]; i += 2) {
    04091         if ((ped->DBCSVector[i] <= cch) && (ped->DBCSVector[i+1] >= cch))
    04092             return (TRUE);
    04093     }
    04094
    04095     return (FALSE);
    04096 }

PSTR ECLock | ( | PED | ped | ) |

Definition at line 52 of file editec.c.

References tagED::cbChar, tagED::cch, FALSE, tagED::fEncoded, tagED::hInstance, tagED::hText, tagED::iLockLevel, LOCALLOCK, RtlRunDecodeUnicodeString(), tagED::seed, and USHORT.

Referenced by ECCopy(), ECDeleteText(), ECDoIMEMenuCommand(), ECGetText(), EcImeRequestHandler(), ECInsertText(), ECNextIch(), ECPrevIch(), ECSetCaretHandler(), ECWord(), HanjaKeyHandler(), MLBuildchLines(), MLCalcXOffset(), MLDrawText(), MLEditWndProc(), MLGetLine(), MLIchToXYPos(), MLIchToYPos(), MLInsertCrCrLf(), MLInsertText(), MLKeyDown(), MLLine(), MLMouseMotion(), MLMouseToIch(), MLMoveSelection(), MLMoveSelectionRestricted(), MLSetHandle(), MLSetSelection(), MLStripCrCrLf(), MLUpdateiCaretLine(), NextWordCallBack(), NextWordLpkCallBack(), SLCalcStringWidth(), SLCalcXOffsetSpecial(), SLChangeSelection(), SLDrawLine(), SLDrawText(), SLGetClipRect(), SLIchToLeftXPos(), SLInsertText(), SLMouseMotion(), SLMouseToIch(), SLMoveSelectionRestricted(), and SLScrollText().

    00054 {
    00055     PSTR ptext = LOCALLOCK(ped->hText, ped->hInstance);
    00056     ped->iLockLevel++;
    00057
    00058     /*
    00059      * If this is the first lock of the text and the text is encoded
    00060      * decode the text.
    00061      */
    00062     //RIPMSG2(RIP_VERBOSE, "lock  : %d '%10s'\n", ped->iLockLevel, ptext);
    00063     if (ped->iLockLevel == 1 && ped->fEncoded) {
    00064         /*
    00065          * rtlrundecode can't handle zero length strings
    00066          */
    00067         if (ped->cch != 0) {
    00068             STRING string;
    00069             string.Length = string.MaximumLength = (USHORT)(ped->cch * ped->cbChar);
    00070             string.Buffer = ptext;
    00071
    00072             RtlRunDecodeUnicodeString(ped->seed, (PUNICODE_STRING)&string);
    00073             //RIPMSG1(RIP_VERBOSE, "Decoding: '%10s'\n", ptext);
    00074         }
    00075         ped->fEncoded = FALSE;
    00076     }
    00077     return ptext;
    00078 }

void ECMenu | ( | HWND | hwnd,
|  | PED | ped,
|  | LPPOINT | pt
| ) |

Definition at line 548 of file editec.c.

References tagED::cch, tagED::charPasswordChar, ECDoIMEMenuCommand(), ECSetIMEMenu(), tagLPKEDITCALLOUT::EditProcessMenu, tagLPKEDITCALLOUT::EditSetMenu, EnableMenuItem(), FALSE, EditMenuItemState::fDisableCut, EditMenuItemState::fDisablePaste, tagED::fFocus, EditMenuItemState::fIME, EditMenuItemState::fNeedSeparatorBeforeImeMenu, fpImmIsIME, tagED::fReadOnly, GetMenuItemCount(), GetMenuState(), GetSubMenu(), GetWindowRect(), hmodUser, tagED::ichMaxSel, tagED::ichMinSel, ID_CNTX_DISPLAYCTRL, ID_CNTX_INSERTCTRL, ID_CNTX_RTL, ID_EC_PROPERTY_MENU, IS_IME_ENABLED, L, NtUserDeleteMenu(), NtUserDestroyMenu(), NtUserIsClipboardFormatAvailable(), NtUserSetFocus(), NtUserTrackPopupMenuEx(), NULL, tagED::pLpkEditCallout, SendMessage(), THREAD_HKL, TRUE, and UNDO_NONE.

Referenced by EditWndProc().

    00552 {
    00553     HMENU   hMenu;
    00554     int     cmd = 0;
    00555     int     x;
    00556     int     y;
    00557     EditMenuItemState state = {
    00558         FALSE,              // fDisableCut
    00559         TRUE,               // fDisablePaste
    00560         TRUE,               // fNeedSeparatorBeforeImeMenu
    00561         IS_IME_ENABLED() && fpImmIsIME(THREAD_HKL()), // fIME
    00562     };
    00563
    00564     // Set focus if we don't have it.
    00565     if (!ped->fFocus)
    00566         NtUserSetFocus(hwnd);
    00567
    00568     // Grab the menu from USER's resources...
    00569     if (!(hMenu = LoadMenu( hmodUser, MAKEINTRESOURCE( ID_EC_PROPERTY_MENU ))))
    00570         return ;
    00571
    00572
    00573     // Undo -- not allowed if we have no saved undo info
    00574     if (ped->undoType == UNDO_NONE)
    00575         EnableMenuItem(hMenu, WM_UNDO, MF_BYCOMMAND | MFS_GRAYED);
    00576
    00577     if (ped->fReadOnly || ped->charPasswordChar) {
    00578         // Cut and Delete -- not allowed if read-only or password
    00579         state.fDisableCut = TRUE;
    00580     } else {
    00581         // Cut, Delete -- not allowed if there's no selection
    00582         if (ped->ichMinSel == ped->ichMaxSel)
    00583             state.fDisableCut = TRUE;
    00584     }
    00585     // Paste -- not allowed if there's no text on the clipboard
    00586     // (this works for both OEM and Unicode)
    00587     // Used to be always disabled for password edits MCostea #221035
    00588
    00589     if (NtUserIsClipboardFormatAvailable(CF_TEXT))
    00590         state.fDisablePaste = FALSE;
    00591
    00592     if (state.fDisableCut) {
    00593         EnableMenuItem(hMenu, WM_CUT,   MF_BYCOMMAND | MFS_GRAYED);
    00594         EnableMenuItem(hMenu, WM_CLEAR, MF_BYCOMMAND | MFS_GRAYED);
    00595     }
    00596
    00597     if (state.fDisablePaste)
    00598         EnableMenuItem(hMenu, WM_PASTE, MF_BYCOMMAND | MFS_GRAYED);
    00599
    00600     // Copy -- not allowed if there's no selection or password ec
    00601     if ((ped->ichMinSel == ped->ichMaxSel) || (ped->charPasswordChar))
    00602         EnableMenuItem(hMenu, WM_COPY, MF_BYCOMMAND | MFS_GRAYED);
    00603
    00604     // Select All -- not allowed if there's no text or if everything is
    00605     // selected.   Latter case takes care of first one.
    00606     if ((ped->ichMinSel == 0) && (ped->ichMaxSel == ped->cch))
    00607         EnableMenuItem(hMenu, EM_SETSEL, MF_BYCOMMAND | MFS_GRAYED);
    00608
    00609     if (ped->pLpkEditCallout) {
    00610         ped->pLpkEditCallout->EditSetMenu(ped, hMenu);
    00611     } else {
    00612         NtUserDeleteMenu(hMenu, ID_CNTX_DISPLAYCTRL, MF_BYCOMMAND);
    00613         NtUserDeleteMenu(hMenu, ID_CNTX_RTL,         MF_BYCOMMAND);
    00614         NtUserDeleteMenu(hMenu, ID_CNTX_INSERTCTRL,  MF_BYCOMMAND);
    00615
    00616         if (state.fIME) {
    00617             // One separator is left in the menu,
    00618             // no need to add the one before IME menus
    00619             state.fNeedSeparatorBeforeImeMenu = FALSE;
    00620         } else {
    00621             // Extra separator is left. Remove it.
    00622             HMENU hmenuSub = GetSubMenu(hMenu, 0);
    00623             int nItems = GetMenuItemCount(hmenuSub) - 1;
    00624
    00625             UserAssert(nItems >= 0);
    00626             UserAssert(GetMenuState(hmenuSub, nItems, MF_BYPOSITION) & MF_SEPARATOR);
    00627             // remove needless separator
    00628             UserVerify(NtUserDeleteMenu(hmenuSub, nItems, MF_BYPOSITION));
    00629         }
    00630     }
    00631
    00632     // IME specific menu
    00633     if (state.fIME) {
    00634         ECSetIMEMenu(hMenu, hwnd, state);
    00635     }
    00636
    00637     // BOGUS
    00638     // We position the menu below & to the right of the point clicked on.
    00639     // Is this cool?  I think so.  Excel 4.0 does the same thing.  It
    00640     // seems like it would be neat if we could avoid obscuring the
    00641     // selection.  But in actuality, it seems even more awkward to move
    00642     // the menu out of the way of the selection.  The user can't click
    00643     // and drag that way, and they have to move the mouse a ton.
    00644     //
    00645     // We need to use TPM_NONOTIFY because VBRUN100 and VBRUN200 GP-fault
    00646     // on unexpected menu messages.
    00647     //
    00648
    00649     /*
    00650      *  if message came via the keyboard then center on the control
    00651      *  We use -1 && -1 here not 0xFFFFFFFF like Win95 becuase we
    00652      *  previously converted the lParam to a point with sign extending.
    00653      */
    00654     if (pt->x == -1 && pt->y == -1) {
    00655         RECT rc;
    00656
    00657         GetWindowRect(hwnd, &rc);
    00658         x = rc.left + (rc.right - rc.left) / 2;
    00659         y = rc.top + (rc.bottom - rc.top) / 2;
    00660     } else {
    00661         x = pt->x;
    00662         y = pt->y;
    00663     }
    00664
    00665     cmd = NtUserTrackPopupMenuEx(GetSubMenu(hMenu, 0), TPM_NONOTIFY |
    00666         TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON,
    00667         x, y, hwnd, NULL);
    00668
    00669     // Free our menu
    00670     NtUserDestroyMenu(hMenu);
    00671
    00672     if (cmd && (cmd != -1)) {
    00673         if (ped->pLpkEditCallout && cmd) {
    00674             ped->pLpkEditCallout->EditProcessMenu(ped, cmd);
    00675         }
    00676         if (!state.fIME || !ECDoIMEMenuCommand(ped, cmd, hwnd)) {
    00677             // if cmd is not IME specific menu, send it.
    00678             SendMessage(hwnd, cmd, 0, (cmd == EM_SETSEL) ? 0xFFFFFFFF : 0L );
    00679         }
    00680     }
    00681 }

void ECMergeUndoInsertInfo | ( | PUNDO | pundo,
|  | ICH | ichInsert,
|  | ICH | cchInsert
| ) |

Definition at line 1996 of file editec.c.

References NULL, UNDO_DELETE, UNDO_INSERT, UNDO_NONE, and UserGlobalFree.

Referenced by ECInsertText().

    01997 {
    01998     //
    01999     // If undo buffer is empty, just insert the new info as UNDO_INSERT
    02000     //
    02001     if (pundo->undoType == UNDO_NONE) {
    02002         pundo->undoType    = UNDO_INSERT;
    02003         pundo->ichInsStart = ichInsert;
    02004         pundo->ichInsEnd   = ichInsert+cchInsert;
    02005     } else if (pundo->undoType & UNDO_INSERT) {
    02006         //
    02007         // If there's already some undo insert info,
    02008         // try to merge the two.
    02009         //
    02010         if (pundo->ichInsEnd == ichInsert) // Check they are adjacent.
    02011             pundo->ichInsEnd += cchInsert; // if so, just concatenate.
    02012         else {
    02013                 // The new insert is not contiguous with the old one.
    02014 UNDOINSERT:
    02015             //
    02016             // If there is some UNDO_DELETE info already here, check to see
    02017             // if the new insert takes place at a point different from where
    02018             // that deletion occurred.
    02019             //
    02020             if ((pundo->undoType & UNDO_DELETE) && (pundo->ichDeleted != ichInsert)) {
    02021                 //
    02022                 // User is inserting into a different point; So, let us
    02023                 // forget any UNDO_DELETE info;
    02024                 //
    02025                 if (pundo->hDeletedText)
    02026                     UserGlobalFree(pundo->hDeletedText);
    02027
    02028                 pundo->hDeletedText = NULL;
    02029                 pundo->ichDeleted = 0xFFFFFFFF;
    02030                 pundo->undoType &= ~UNDO_DELETE;
    02031             }
    02032
    02033             // Since the old insert and new insert are not adjacent, let us
    02034             // forget everything about the old insert and keep just the new
    02035             // insert info as the UNDO_INSERT.
    02036             pundo->ichInsStart = ichInsert;
    02037             pundo->ichInsEnd   = ichInsert + cchInsert;
    02038             pundo->undoType |= UNDO_INSERT;
    02039         }
    02040     } else if (pundo->undoType == UNDO_DELETE) {
    02041         // If there is some Delete Info already present go and handle it.
    02042         goto UNDOINSERT;
    02043     }
    02044 }

ICH ECNextIch | ( | PED | ped,
|  | LPSTR | pStart,
|  | ICH | ichCurrent
| ) |

Definition at line 3969 of file editec.c.

References ECIsDBCSLeadByte(), ECLock(), ECUnlock(), tagED::fAnsi, tagED::fDBCS, and ICH.

Referenced by MLBuildchLines(), MLDeleteText(), MLMoveSelection(), and SLKeyDown().

    03970 {
    03971     if (!ped->fDBCS || !ped->fAnsi) {
    03972
    03973         return (ichCurrent + 1);
    03974
    03975     } else {
    03976
    03977         ICH ichRet;
    03978         LPSTR pText;
    03979
    03980         if (pStart)
    03981             pText = pStart + ichCurrent;
    03982         else
    03983             pText = (LPSTR)ECLock(ped) + ichCurrent;
    03984
    03985         ichRet = ichCurrent + ( ECIsDBCSLeadByte(ped, *pText) ? 2 : 1 );
    03986
    03987         if (!pStart)
    03988             ECUnlock(ped);
    03989
    03990         return (ichRet);
    03991     }
    03992 }

void ECNotifyParent | ( | PED | ped,
|  | int | notificationCode
| ) |

Definition at line 2429 of file editec.c.

References DWORD, tagED::hwnd, tagED::hwndParent, PTR_TO_ID, tagED::pwnd, SendMessage(), and tagWND::spmenu.

Referenced by ECImeComposition(), ECResetTextInfo(), ECSetText(), EditWndProc(), MLDeleteText(), MLInsertchLine(), MLInsertCrCrLf(), MLInsertText(), MLKillFocus(), MLScroll(), MLSetFocus(), SLChar(), SLInsertText(), SLKeyDown(), SLKillFocus(), SLPaste(), SLReplaceSel(), SLSetFocus(), and SLUndo().

    02432 {
    02433     /*
    02434      * wParam is NotificationCode (hiword) and WindowID (loword)
    02435      * lParam is HWND of control sending the message
    02436      * Windows 95 checks for hwndParent != NULL before sending the message, but
    02437      * this is surely rare, and SendMessage NULL hwnd does nowt anyway (IanJa)
    02438      */
    02439     SendMessage(ped->hwndParent, WM_COMMAND,
    02440             (DWORD)MAKELONG(PTR_TO_ID(ped->pwnd->spmenu), notificationCode),
    02441             (LPARAM)ped->hwnd);
    02442 }

ICH ECPrevIch | ( | PED | ped,
|  | LPSTR | pStart,
|  | ICH | ichCurrent
| ) |

Definition at line 4001 of file editec.c.

References ECIsDBCSLeadByte(), ECLock(), ECUnlock(), tagED::fAnsi, tagED::fDBCS, ICH, and tagED::pLpkEditCallout.

Referenced by MLMoveSelection(), SLChar(), and SLKeyDown().

    04002 {
    04003     LPSTR lpCurrent;
    04004     LPSTR lpStr;
    04005     LPSTR lpBase;
    04006
    04007 #ifdef SURROGATE
    04008     // Handle Unicode surrogates pairs when CSLPK is loaded
    04009     if (ped->fAnsi || !ped->pLpkEditCallout)  // if no surrogate processing required
    04010 #endif
    04011         if (!ped->fDBCS || !ped->fAnsi)
    04012             if ( ichCurrent )
    04013                 return (ichCurrent - 1);
    04014             else
    04015                 return (ichCurrent);
    04016
    04017     if (ichCurrent <= 1)
    04018         return 0;
    04019
    04020     if (pStart)
    04021         lpBase = pStart;
    04022     else
    04023         lpBase = ECLock(ped);
    04024
    04025 #ifdef SURROGATE
    04026
    04027     // Handle characters represented by multiple codepoints
    04028
    04029     if (ped->fAnsi) {
    04030
    04031         // ANSI PrevIch with DBCS support
    04032 #endif
    04033
    04034         lpStr = lpBase + ichCurrent;
    04035         lpCurrent = lpStr - 1;
    04036         if (ECIsDBCSLeadByte(ped,*lpCurrent)) {
    04037             if (!pStart)
    04038                 ECUnlock(ped);
    04039             return (ichCurrent - 2);
    04040         }
    04041
    04042         do {
    04043             lpCurrent--;
    04044             if (!ECIsDBCSLeadByte(ped, *lpCurrent)) {
    04045                 lpCurrent++;
    04046                 break;
    04047             }
    04048         } while(lpCurrent != lpBase);
    04049
    04050         if (!pStart)
    04051             ECUnlock(ped);
    04052         return (ichCurrent - (((lpStr - lpCurrent) & 1) ? 1 : 2));
    04053
    04054 #ifdef SURROGATE
    04055
    04056     } else {
    04057
    04058         // Unicode PrevIch with surrogate pair support
    04059
    04060         ichCurrent--;
    04061
    04062         if (    (((WCHAR*)lpBase)[ichCurrent]   & 0xFC00) == 0xDC00
    04063             &&  (((WCHAR*)lpBase)[ichCurrent-1] & 0xFC00) == 0xD800) {
    04064
    04065             ichCurrent--;
    04066         }
    04067
    04068         if (!pStart)
    04069             ECUnlock(ped);
    04070
    04071         return ichCurrent;
    04072     }
    04073 #endif
    04074 }

void ECReleaseEditDC | ( | PED | ped,
|  | HDC | hdc,
|  | BOOL | fFastDC
| ) |

Definition at line 2524 of file editec.c.

References tagED::hwnd, NtUserShowCaret(), and ReleaseDC().

Referenced by ECCreate(), ECDeleteText(), ECImeComposition(), ECInsertText(), ECSetCaretHandler(), ECSetPasswordChar(), EditWndProc(), MLBuildchLines(), MLCalcXOffset(), MLDeleteText(), MLEditWndProc(), MLEnsureCaretVisible(), MLInsertText(), MLKeyDown(), MLKillFocus(), MLMouseMotion(), MLMoveSelectionRestricted(), MLScroll(), MLSetFocus(), MLSetSelection(), NextWordLpkCallBack(), SLChar(), SLEditWndProc(), SLInsertText(), SLKeyDown(), SLMouseMotion(), SLMoveSelectionRestricted(), SLPaste(), SLReplaceSel(), SLSetFocus(), and SLSetSelection().

    02528 {
    02529     /*
    02530      * Restoring font not necessary
    02531      */
    02532
    02533     ReleaseDC(ped->hwnd, hdc);
    02534
    02535     if (!fFastDC)
    02536         NtUserShowCaret(ped->hwnd);
    02537 }

void ECResetTextInfo | ( | PED | ped | ) |

Definition at line 2547 of file editec.c.

References _IsWindowVisible(), BOOL, tagED::cLines, ECEmptyUndo(), ECInvalidateClient(), ECNotifyParent(), FALSE, tagED::fDirty, tagED::fSingle, tagED::fWin31Compat, FWINABLE, HW, tagED::hwnd, tagED::iCaretLine, tagED::ichCaret, tagED::ichLinesOnScreen, tagED::ichMaxSel, tagED::ichMinSel, tagED::ichScreenStart, tagED::listboxHwnd, MLBuildchLines(), MLStripCrCrLf(), NotifyWinEvent(), NULL, Pundo, tagED::pwnd, UpdateWindow(), and tagED::xOffset.

Referenced by ECSetText(), and MLSetHandle().

    02548 {
    02549     //
    02550     // Reset caret, selections, scrolling, and dirty information.
    02551     //
    02552     ped->iCaretLine = ped->ichCaret = 0;
    02553     ped->ichMinSel = ped->ichMaxSel = 0;
    02554     ped->xOffset = ped->ichScreenStart = 0;
    02555     ped->fDirty = FALSE;
    02556
    02557     ECEmptyUndo(Pundo(ped));
    02558
    02559     if (ped->fSingle) {
    02560         if (!ped->listboxHwnd)
    02561             ECNotifyParent(ped, EN_UPDATE);
    02562     } else {
    02563 #ifdef BOGUS
    02564         // B#14640
    02565         // We don't want to strip soft breaks or anything else from text
    02566         // that was passed in by the caller. - karlst.
    02567         MLStripCrCrLf(ped);
    02568 #endif
    02569         MLBuildchLines(ped, 0, 0, FALSE, NULL, NULL);
    02570     }
    02571
    02572     if (_IsWindowVisible(ped->pwnd)) {
    02573         BOOL fErase;
    02574
    02575         if (ped->fSingle)
    02576             fErase = FALSE;
    02577         else
    02578             fErase = ((ped->ichLinesOnScreen + ped->ichScreenStart) >= ped->cLines);
    02579
    02580         // Always redraw whether or not the insert was successful.  We might
    02581         // have NULL text.  Paint() will check the redraw flag for us.
    02582         ECInvalidateClient(ped, fErase);
    02583
    02584         // BACKWARD COMPAT HACK: RAID expects the text to have been updated,
    02585         // so we have to do an UpdateWindow here.  It moves an edit control
    02586         // around with fRedraw == FALSE, so it'll never get the paint message
    02587         // with the control in the right place.
    02588         if (!ped->fWin31Compat)
    02589             UpdateWindow(ped->hwnd);
    02590     }
    02591
    02592     if (ped->fSingle && !ped->listboxHwnd)
    02593         ECNotifyParent(ped, EN_CHANGE);
    02594
    02595     if (FWINABLE()) {
    02596         NotifyWinEvent(EVENT_OBJECT_VALUECHANGE, HW(ped->pwnd), OBJID_CLIENT,
    02597                 INDEXID_CONTAINER);
    02598     }
    02599 }

void ECSaveUndo | ( | PUNDO | pundoFrom,
|  | PUNDO | pundoTo,
|  | BOOL | fClear
| ) |

Definition at line 1955 of file editec.c.

References PUNDO, and UNDO.

Referenced by MLInsertText(), MLReplaceSel(), and SLReplaceSel().

    01956 {
    01957     /*
    01958      *  Save undo data
    01959      */
    01960     RtlCopyMemory(pundoTo, pundoFrom, sizeof(UNDO));
    01961
    01962     /*
    01963      *  Clear passed in undo buffer
    01964      */
    01965     if (fClear)
    01966         RtlZeroMemory(pundoFrom, sizeof(UNDO) );
    01967 }

void ECSetEditClip | ( | PED | ped,
|  | HDC | hdc,
|  | BOOL | fLeftMargin
| ) |

Definition at line 2452 of file editec.c.

References _GetClientRect(), CopyRect, tagED::fFlatBorder, tagED::fWrap, InflateRect(), IntersectRect(), tagED::pLpkEditCallout, tagED::pwnd, tagED::rcFmt, SYSMET, tagED::wLeftMargin, and tagED::wRightMargin.

Referenced by ECGetEditDC(), MLPaint(), MLScroll(), and SLDrawLine().

    02453 {
    02454     RECT rcClient;
    02455     RECT rcClip;
    02456
    02457     CopyRect(&rcClip, &ped->rcFmt);
    02458
    02459     if (ped->pLpkEditCallout) {
    02460         // Complex script handling chooses whether to write margins later
    02461         rcClip.left  -= ped->wLeftMargin;
    02462         rcClip.right += ped->wRightMargin;
    02463     } else {
    02464         if (fLeftMargin)  /* Should we consider the left margin?   */
    02465             rcClip.left  -= ped->wLeftMargin;
    02466         if (ped->fWrap)        /* Should we consider the right margin? */
    02467             rcClip.right += ped->wRightMargin;
    02468     }
    02469
    02470     /* Set clip rectangle to rectClient intersect rectClip */
    02471     /* We must clip for single line edits also. -- B#1360 */
    02472     _GetClientRect(ped->pwnd, &rcClient);
    02473     if (ped->fFlatBorder)
    02474         InflateRect(&rcClient, -SYSMET(CXBORDER), -SYSMET(CYBORDER));
    02475
    02476     IntersectRect(&rcClient, &rcClient, &rcClip);
    02477     IntersectClipRect(hdc,rcClient.left, rcClient.top,
    02478             rcClient.right, rcClient.bottom);
    02479 }

BOOL ECSetIMEMenu | ( | HMENU | hMenu,
|  | HWND | hwnd,
|  | EditMenuItemState | state
| ) |

Definition at line 278 of file editec.c.

References BOOL, DWORD, FALSE, EditMenuItemState::fDisableCut, EditMenuItemState::fIME, EditMenuItemState::fNeedSeparatorBeforeImeMenu, fpImmGetContext, fpImmGetConversionStatus, fpImmGetOpenStatus, fpImmGetProperty, fpImmIsIME, fpImmReleaseContext, GetMenuItemCount(), GetSubMenu(), hmodUser, ID_IMEOPENCLOSE, ID_RECONVERTSTRING, ID_SOFTKBDOPENCLOSE, InsertMenuItem(), IS_IME_ENABLED, NtUserDeleteMenu(), NULL, STR_IMECLOSE, STR_IMEOPEN, STR_RECONVERTSTRING, STR_SOFTKBDCLOSE, STR_SOFTKBDOPEN, THREAD_HKL, and TRUE.

Referenced by ECMenu().

    00282 {
    00283
    00284     MENUITEMINFO mii;
    00285     HIMC hIMC;
    00286     HKL hKL;
    00287     HMENU hmenuSub;
    00288     WCHAR szRes[32];
    00289     int nPrevLastItem;
    00290     int nItemsAdded = 0;
    00291
    00292     UserAssert(IS_IME_ENABLED() && state.fIME);
    00293
    00294     hKL = THREAD_HKL();
    00295     if (!fpImmIsIME(hKL))
    00296         return TRUE;
    00297
    00298     hIMC = fpImmGetContext(hwnd);
    00299     if (hIMC == NULL) {
    00300         // early out
    00301         return FALSE;
    00302     }
    00303
    00304     hmenuSub = GetSubMenu(hMenu, 0);
    00305
    00306     if (hmenuSub == NULL) {
    00307         return FALSE;
    00308     }
    00309
    00310     nPrevLastItem = GetMenuItemCount(hmenuSub);
    00311
    00312     if (hIMC) {
    00313         if (LOWORD(HandleToUlong(hKL)) != 0x412) {
    00314             //
    00315             // If Korean, do not show open/close menus
    00316             //
    00317             if (fpImmGetOpenStatus(hIMC))
    00318                 LoadString(hmodUser, STR_IMECLOSE, szRes, sizeof(szRes));
    00319             else
    00320                 LoadString(hmodUser, STR_IMEOPEN, szRes, sizeof(szRes));
    00321
    00322             mii.cbSize = sizeof(MENUITEMINFO);
    00323             mii.fMask = MIIM_STRING | MIIM_ID;
    00324             mii.dwTypeData = szRes;
    00325             mii.cch = 0xffff;
    00326             mii.wID = ID_IMEOPENCLOSE;
    00327             InsertMenuItem(hmenuSub, 0xffff, TRUE, &mii);
    00328             ++nItemsAdded;
    00329         }
    00330
    00331         if (fpImmGetProperty(hKL, IGP_CONVERSION) & IME_CMODE_SOFTKBD) {
    00332             DWORD fdwConversion;
    00333
    00334             fpImmGetConversionStatus(hIMC, &fdwConversion, NULL);
    00335
    00336             if (fdwConversion & IME_CMODE_SOFTKBD)
    00337                LoadString(hmodUser, STR_SOFTKBDCLOSE, szRes, sizeof(szRes));
    00338             else
    00339                LoadString(hmodUser, STR_SOFTKBDOPEN, szRes, sizeof(szRes));
    00340
    00341             mii.cbSize = sizeof(MENUITEMINFO);
    00342             mii.fMask = MIIM_STRING | MIIM_ID;
    00343             mii.dwTypeData = szRes;
    00344             mii.cch = 0xffff;
    00345             mii.wID = ID_SOFTKBDOPENCLOSE;
    00346             InsertMenuItem(hmenuSub, 0xffff, TRUE, &mii);
    00347             ++nItemsAdded;
    00348         }
    00349
    00350         if (LOWORD(HandleToUlong(hKL)) != 0x412) {
    00351             //
    00352             // If Korean, do not show reconversion menus
    00353             //
    00354             DWORD dwSCS = fpImmGetProperty(hKL, IGP_SETCOMPSTR);
    00355
    00356             LoadString(hmodUser, STR_RECONVERTSTRING, szRes, sizeof(szRes));
    00357
    00358             mii.cbSize = sizeof(MENUITEMINFO);
    00359             mii.fMask = MIIM_STRING | MIIM_ID | MIIM_STATE;
    00360             mii.dwTypeData = szRes;
    00361             mii.fState = 0;
    00362             mii.cch = 0xffff;
    00363             mii.wID = ID_RECONVERTSTRING;
    00364
    00365             if (state.fDisableCut ||
    00366                     !(dwSCS & SCS_CAP_SETRECONVERTSTRING) ||
    00367                     !(dwSCS & SCS_CAP_MAKEREAD)) {
    00368                 mii.fState |= MFS_GRAYED;
    00369             }
    00370
    00371             InsertMenuItem(hmenuSub, 0xffff, TRUE, &mii);
    00372             ++nItemsAdded;
    00373         }
    00374     }
    00375
    00376     //
    00377     // Add or remove the menu separator
    00378     //
    00379     if (state.fNeedSeparatorBeforeImeMenu && nItemsAdded != 0) {
    00380         //
    00381         // If the menu for Middle East has left a separator,
    00382         // fNeedSeparatorBeforeImeMenu is FALSE.
    00383         // I.e. we don't need to add more.
    00384         //
    00385         mii.cbSize = sizeof(MENUITEMINFO);
    00386         mii.fMask = MIIM_FTYPE;
    00387         mii.fType = MFT_SEPARATOR;
    00388         InsertMenuItem(hmenuSub, nPrevLastItem, TRUE, &mii);
    00389     }
    00390     else if (!state.fNeedSeparatorBeforeImeMenu && nItemsAdded == 0) {
    00391         //
    00392         // Extra separator is left by ME menus. Remove it.
    00393         //
    00394         UserVerify(NtUserDeleteMenu(hmenuSub, nPrevLastItem - 1, MF_BYPOSITION));
    00395     }
    00396
    00397     fpImmReleaseContext(hwnd, hIMC);
    00398
    00399     return TRUE;
    00400 }

BOOL ECSetText | ( | PED | ped,
|  | LPSTR | lpstr
| ) |

Definition at line 2612 of file editec.c.

References BOOL, tagED::cbChar, tagED::cch, tagED::cchAlloc, CCHALLOCEXTRA, ECInsertText(), ECNotifyParent(), ECResetTextInfo(), FALSE, tagED::fAnsi, tagED::fSingle, tagED::hInstance, tagED::hText, tagED::hwnd, ICH, tagED::ichCaret, IsWindow(), LHND, LOCALREALLOC, LOCALSIZE, min, NULL, StringLength(), and TRUE.

Referenced by EditWndProc(), MLCreate(), and SLCreate().

    02615 {
    02616     ICH cchLength;
    02617     ICH cchSave = ped->cch;
    02618     ICH ichCaretSave = ped->ichCaret;
    02619     HWND hwndSave    = ped->hwnd;
    02620     HANDLE hText;
    02621
    02622     ped->cch = ped->ichCaret = 0;
    02623
    02624     ped->cchAlloc = LOCALSIZE(ped->hText, ped->hInstance) / ped->cbChar;
    02625     if (!lpstr) {
    02626         hText = LOCALREALLOC(ped->hText, CCHALLOCEXTRA*ped->cbChar, LHND, ped->hInstance, &lpstr);
    02627         if (hText != NULL) {
    02628             ped->hText = hText;
    02629         } else {
    02630             return FALSE;
    02631         }
    02632     } else {
    02633         cchLength = StringLength(lpstr, ped->fAnsi);
    02634
    02635 #ifdef NEVER
    02636 // win3.1 does limit single line edit controls to 32K (minus 3) but NT doesn't
    02637
    02638         if (ped->fSingle) {
    02639             /*
    02640              * Limit single line edit controls to 32K
    02641              */
    02642             cchLength = min(cchLength, (ICH)(0x7FFD/ped->cbChar));
    02643         }
    02644 #endif
    02645
    02646         /*
    02647          * Add the text
    02648          */
    02649         if (cchLength && !ECInsertText(ped, lpstr, &cchLength)) {
    02650
    02651             /*
    02652              * Restore original state and notify parent we ran out of memory.
    02653              */
    02654             ped->cch = cchSave;
    02655             ped->ichCaret = ichCaretSave;
    02656             ECNotifyParent(ped, EN_ERRSPACE);
    02657             return FALSE;
    02658         }
    02659     }
    02660
    02661     ped->cchAlloc = LOCALSIZE(ped->hText, ped->hInstance) / ped->cbChar;
    02662
    02663     if (IsWindow(hwndSave))
    02664         ECResetTextInfo(ped);
    02665
    02666     return TRUE;
    02667 }

UINT ECTabTheTextOut | ( | HDC | hdc,
|  | int | xClipStPos,
|  | int | xClipEndPos,
|  | int | xStart,
|  | int | y,
|  | LPSTR | lpstring,
|  | int | nCount,
|  | ICH | ichString,
|  | PED | ped,
|  | int | iTabOrigin,
|  | BOOL | fDraw,
|  | LPSTRIPINFO | NegCInfoForStrip
| ) |

Definition at line 770 of file editec.c.

References tagED::aveCharWidth, BOOL, tagED::cbChar, CHAR_WIDTH_BUFFER_LENGTH, tagED::charOverhang, tagED::charWidthBuffer, ECFindTabA(), ECFindTabW(), ECIsDBCSLeadByte(), ECT_SELECTED, FALSE, tagED::fAnsi, tagED::fDBCS, tagED::fTrueType, GetActualNegA(), STRIPINFO::ichString, INT, L, tagED::lineHeight, STRIPINFO::lpString, max, MAXCLIPENDPOS, MAXLINELENGTH, min, STRIPINFO::nCount, NULL, PINT, tagED::pTabStops, TRUE, UINT, tagED::wMaxNegA, tagED::wMaxNegC, and STRIPINFO::XStartPos.

Referenced by ECCchInWidth(), MLDrawText(), and MLGetLineWidth().

    00783 {
    00784     int     nTabPositions;         // Count of tabstops in tabstop array.
    00785     LPINT   lpintTabStopPositions; // Tab stop positions in pixels.
    00786
    00787     int     cch;
    00788     UINT    textextent;
    00789     int     xEnd;
    00790     int     pixeltabstop = 0;
    00791     int     i;
    00792     int     cxCharWidth;
    00793     RECT    rc;
    00794     BOOL    fOpaque;
    00795     BOOL    fFirstPass = TRUE;
    00796     PINT    charWidthBuff;
    00797
    00798     int     iTabLength;
    00799     int     nConsecutiveTabs;
    00800     int     xStripStPos;
    00801     int     xStripEndPos;
    00802     int     xEndOfStrip;
    00803     STRIPINFO  RedrawStripInfo;
    00804     STRIPINFO  NegAInfo;
    00805     LPSTR    lpTab;
    00806     LPWSTR   lpwTab;
    00807     UINT     wNegCwidth, wNegAwidth;
    00808     int      xRightmostPoint = xClipStPos;
    00809     int      xTabStartPos;
    00810     int      iSavedBkMode = 0;
    00811     WCHAR    wchar;
    00812     SIZE     size;
    00813     ABC   abc ;
    00814
    00815     // Algorithm: Draw the strip opaquely first. If a tab length is so
    00816     // small that the portions of text on either side of a tab overlap with
    00817     // the other, then this will result in some clipping. So, such portion
    00818     // of the strip is remembered in "RedrawStripInfo" and redrawn
    00819     // transparently later to compensate the clippings.
    00820     //    NOTE: "RedrawStripInfo" can hold info about just one portion. So, if
    00821     // more than one portion of the strip needs to be redrawn transparently,
    00822     // then we "merge" all such portions into a single strip and redraw that
    00823     // strip at the end.
    00824
    00825     if (fDraw) {
    00826         // To begin with, let us assume that there is no Negative C for this
    00827         // strip and initialize the Negative Width Info structure.
    00828         NegCInfoForStrip->nCount = 0;
    00829         NegCInfoForStrip->XStartPos = xClipEndPos;
    00830
    00831         // We may not have to redraw any portion of this strip.
    00832         RedrawStripInfo.nCount = 0;
    00833
    00834         fOpaque = (GetBkMode(hdc) == OPAQUE) || (fDraw == ECT_SELECTED);
    00835     }
    00836 #if DBG
    00837     else {
    00838         //
    00839         // Both MLGetLineWidth() and ECCchInWidth() should be clipping
    00840         // nCount to avoid overflow.
    00841         //
    00842         if (nCount > MAXLINELENGTH)
    00843             RIPMSG0(RIP_WARNING, "ECTabTheTextOut: nCount > MAXLINELENGTH");
    00844     }
    00845 #endif
    00846
    00847     // Let us define the Clip rectangle.
    00848     rc.left   = xClipStPos;
    00849     rc.right  = xClipEndPos;
    00850     rc.top    = y;
    00851     rc.bottom = y + ped->lineHeight;
    00852
    00853     // Check if anything needs to be drawn.
    00854     if (!lpstring || !nCount) {
    00855         if (fDraw)
    00856             ExtTextOutW(hdc, xClipStPos, y,
    00857                   (fOpaque ? ETO_OPAQUE | ETO_CLIPPED : ETO_CLIPPED),
    00858                   &rc, L"", 0, 0L);
    00859         return(0L);
    00860     }
    00861
    00862     //
    00863     // Starting position
    00864     //
    00865     xEnd = xStart;
    00866
    00867     cxCharWidth  = ped->aveCharWidth;
    00868
    00869     nTabPositions = (ped->pTabStops ? *(ped->pTabStops) : 0);
    00870     if (ped->pTabStops) {
    00871         lpintTabStopPositions = (LPINT)(ped->pTabStops+1);
    00872         if (nTabPositions == 1) {
    00873             pixeltabstop = lpintTabStopPositions[0];
    00874             if (!pixeltabstop)
    00875                 pixeltabstop = 1;
    00876         }
    00877     } else {
    00878         lpintTabStopPositions = NULL;
    00879         pixeltabstop = 8*cxCharWidth;
    00880     }
    00881
    00882     // The first time we will draw the strip Opaquely. If some portions need
    00883     // to be redrawn , then we will set the mode to TRANSPARENT and
    00884     // jump to this location to redraw those portions.
    00885
    00886 RedrawStrip:
    00887     while (nCount) {
    00888         wNegCwidth = ped->wMaxNegC;
    00889
    00890         // Search for the first TAB in this strip; also compute the extent
    00891         // of the the strip upto and not including the tab character.
    00892         //
    00893         // Note - If the langpack is loaded, there will be no charWidthBuffer.
    00894         //
    00895         if (ped->charWidthBuffer) {     // Do we have a character width buffer?
    00896             textextent = 0;
    00897             cch = nCount;
    00898
    00899             if (ped->fTrueType) {     // If so, does it have ABC widths?
    00900
    00901                 UINT iRightmostPoint = 0;
    00902                 UINT wCharIndex;
    00903                 PABC pABCwidthBuff;
    00904
    00905                 pABCwidthBuff = (PABC) ped->charWidthBuffer;
    00906
    00907                 if ( ped->fAnsi ) {
    00908                     for (i = 0; i < nCount; i++) {
    00909
    00910                         if (lpstring[i] == VK_TAB) {
    00911                             cch = i;
    00912                             break;
    00913                         }
    00914
    00915                         wCharIndex = (UINT)(((unsigned char  *)lpstring)[i]);
    00916                         if (wCharIndex < CHAR_WIDTH_BUFFER_LENGTH) {
    00917                             textextent += (UINT)(pABCwidthBuff[wCharIndex].abcA +
    00918                                 pABCwidthBuff[wCharIndex].abcB);
    00919                         } else {    // not in cache, will ask driver
    00920                             GetCharABCWidthsA(hdc, wCharIndex, wCharIndex, &abc);
    00921                             textextent += abc.abcA + abc.abcB ;
    00922                         }
    00923
    00924                         if (textextent > iRightmostPoint)
    00925                             iRightmostPoint = textextent;
    00926
    00927                         if (wCharIndex < CHAR_WIDTH_BUFFER_LENGTH) {
    00928                             textextent += pABCwidthBuff[wCharIndex].abcC;
    00929                         } else {    // not in cache
    00930                             textextent += abc.abcC;
    00931                         }
    00932
    00933                         if (textextent > iRightmostPoint)
    00934                             iRightmostPoint = textextent;
    00935                     }
    00936
    00937                 } else {   // Unicode
    00938                     for (i = 0; i < nCount; i++) {
    00939                         WCHAR UNALIGNED * lpwstring = (WCHAR UNALIGNED *)lpstring;
    00940
    00941                         if (lpwstring[i] == VK_TAB) {
    00942                             cch = i;
    00943                             break;
    00944                         }
    00945
    00946                         wCharIndex = lpwstring[i] ;
    00947                         if ( wCharIndex < CHAR_WIDTH_BUFFER_LENGTH )
    00948                             textextent += pABCwidthBuff[wCharIndex].abcA +
    00949                                           pABCwidthBuff[wCharIndex].abcB;
    00950                         else {
    00951                             GetCharABCWidthsW(hdc, wCharIndex, wCharIndex, &abc) ;
    00952                             textextent += abc.abcA + abc.abcB ;
    00953                         }
    00954
    00955                         /*
    00956                          * Note that abcC could be negative so we need this
    00957                          * statement here *and* below
    00958                          */
    00959                         if (textextent > iRightmostPoint)
    00960                             iRightmostPoint = textextent;
    00961
    00962                         if ( wCharIndex < CHAR_WIDTH_BUFFER_LENGTH )
    00963                             textextent += pABCwidthBuff[wCharIndex].abcC;
    00964                         else
    00965                             textextent += abc.abcC ;
    00966
    00967                         if (textextent > iRightmostPoint)
    00968                             iRightmostPoint = textextent;
    00969                     }
    00970                 }
    00971
    00972                 wNegCwidth = (int)(iRightmostPoint - textextent);
    00973             } else {   // !ped->fTrueType
    00974                 // No! This is not a TrueType font; So, we have only character
    00975                 // width info in this buffer.
    00976
    00977                 charWidthBuff = ped->charWidthBuffer;
    00978
    00979                 if ( ped->fAnsi ) {
    00980                     // Initially assume no tabs exist in the text so cch=nCount.
    00981                     for (i = 0; i < nCount; i++) {
    00982                         if (lpstring[i] == VK_TAB) {
    00983                             cch = i;
    00984                             break;
    00985                         }
    00986
    00987                         //
    00988                         // Call GetTextExtentPoint for dbcs/hankaku characters
    00989                         //
    00990                         if (ped->fDBCS && (i+1 < nCount)
    00991                                 && ECIsDBCSLeadByte(ped,lpstring[i])) {
    00992                             GetTextExtentPointA(hdc, &lpstring[i], 2, &size);
    00993                             textextent += size.cx;
    00994                             i++;
    00995                         } else if ((UCHAR)lpstring[i] >= CHAR_WIDTH_BUFFER_LENGTH) {
    00996                             // Skip this GetExtentPoint call for non hankaku code points
    00997                             // Or if the character is in the width cache.
    00998                             GetTextExtentPointA(hdc, &lpstring[i], 1, &size);
    00999                             textextent += size.cx;
    01000                         } else {
    01001                             textextent += (UINT)(charWidthBuff[(UINT)(((unsigned char  *)lpstring)[i])]);
    01002                         }
    01003                     }
    01004                 } else {
    01005                     LPWSTR lpwstring = (LPWSTR) lpstring ;
    01006                     INT    cchUStart;  // start of unicode character count
    01007
    01008                     for (i = 0; i < nCount; i++) {
    01009                         if (lpwstring[i] == VK_TAB) {
    01010                             cch = i;
    01011                             break;
    01012                         }
    01013
    01014                         wchar = lpwstring[i];
    01015                         if (wchar >= CHAR_WIDTH_BUFFER_LENGTH) {
    01016
    01017                             /*
    01018                              * We have a Unicode character that is not in our
    01019                              * cache, get all the characters outside the cache
    01020                              * before getting the text extent on this part of the
    01021                              * string.
    01022                              */
    01023                             cchUStart = i;
    01024                             while (wchar >= CHAR_WIDTH_BUFFER_LENGTH &&
    01025                                     wchar != VK_TAB && i < nCount) {
    01026                                 wchar = lpwstring[++i];
    01027                             }
    01028
    01029                             GetTextExtentPointW(hdc, (LPWSTR)lpwstring + cchUStart,
    01030                                     i-cchUStart, &size);
    01031                             textextent += size.cx;
    01032
    01033
    01034                             if (wchar == VK_TAB || i >= nCount) {
    01035                                 cch = i;
    01036                                 break;
    01037                             }
    01038                             /*
    01039                              * We have a char that is in the cache, fall through.
    01040                              */
    01041                         }
    01042                         /*
    01043                          * The width of this character is in the cache buffer.
    01044                          */
    01045                         textextent += ped->charWidthBuffer[wchar];
    01046                     }
    01047                 }
    01048             } // fTrueType else.
    01049
    01050             nCount -= cch;
    01051         } else {  // If we don't have a buffer that contains the width info.
    01052             /*
    01053              * Gotta call the driver to do our text extent.
    01054              */
    01055
    01056             if ( ped->fAnsi ) {
    01057                 cch = (int)ECFindTabA(lpstring, nCount);
    01058                 GetTextExtentPointA(hdc, lpstring, cch, &size) ;
    01059             } else {
    01060                 cch = (int)ECFindTabW((LPWSTR) lpstring, nCount);
    01061                 GetTextExtentPointW(hdc, (LPWSTR)lpstring, cch, &size);
    01062             }
    01063             nCount -= cch;
    01064             //
    01065             // Subtruct Overhang for Italic fonts.
    01066             //
    01067             textextent = (size.cx - ped->charOverhang);
    01068         }
    01069
    01070         //
    01071         // textextent is computed.
    01072         //
    01073
    01074         xStripStPos = xEnd;
    01075         xEnd += (int)textextent;
    01076         xStripEndPos = xEnd;
    01077
    01078         // We will consider the negative widths only if when we draw opaquely.
    01079         if (fFirstPass && fDraw) {
    01080             xRightmostPoint = max(xStripEndPos + (int)wNegCwidth, xRightmostPoint);
    01081
    01082             // Check if this strip peeps beyond the clip region.
    01083             if (xRightmostPoint > xClipEndPos) {
    01084                 if (!NegCInfoForStrip->nCount) {
    01085                     NegCInfoForStrip->lpString = lpstring;
    01086                     NegCInfoForStrip->ichString = ichString;
    01087                     NegCInfoForStrip->nCount = nCount+cch;
    01088                     NegCInfoForStrip->XStartPos = xStripStPos;
    01089                 }
    01090             }
    01091         }  /* if (fFirstPass && fDraw) */
    01092
    01093         if ( ped->fAnsi )
    01094             lpTab = lpstring + cch; // Possibly Points to a tab character.
    01095         else
    01096             lpwTab = ((LPWSTR)lpstring) + cch ;
    01097
    01098         // we must consider all the consecutive tabs and calculate the
    01099         // the begining of next strip.
    01100         nConsecutiveTabs = 0;
    01101         while (nCount &&
    01102                (ped->fAnsi ? (*lpTab == VK_TAB) : (*lpwTab == VK_TAB))) {
    01103             // Find the next tab position and update the x value.
    01104             xTabStartPos = xEnd;
    01105             if (pixeltabstop)
    01106                 xEnd = (((xEnd-iTabOrigin)/pixeltabstop)*pixeltabstop) +
    01107                     pixeltabstop + iTabOrigin;
    01108             else {
    01109                 for (i = 0; i < nTabPositions; i++) {
    01110                     if (xEnd < (lpintTabStopPositions[i] + iTabOrigin)) {
    01111                         xEnd = (lpintTabStopPositions[i] + iTabOrigin);
    01112                         break;
    01113                     }
    01114                  }
    01115
    01116                 // Check if all the tabstops set are exhausted; Then start using
    01117                 // default tab stop positions.
    01118                 if (i == nTabPositions) {
    01119                     pixeltabstop = 8*cxCharWidth;
    01120                     xEnd = ((xEnd - iTabOrigin)/pixeltabstop)*pixeltabstop +
    01121                         pixeltabstop + iTabOrigin;
    01122                 }
    01123             }
    01124
    01125             if (fFirstPass && fDraw) {
    01126                 xRightmostPoint = max(xEnd, xRightmostPoint);
    01127
    01128                 /* Check if this strip peeps beyond the clip region */
    01129                 if (xRightmostPoint > xClipEndPos) {
    01130                     if (!NegCInfoForStrip->nCount) {
    01131                         NegCInfoForStrip->ichString = ichString + cch + nConsecutiveTabs;
    01132                         NegCInfoForStrip->nCount = nCount;
    01133                         NegCInfoForStrip->lpString = (ped->fAnsi ?
    01134                                                         lpTab : (LPSTR) lpwTab);
    01135                         NegCInfoForStrip->XStartPos = xTabStartPos;
    01136                     }
    01137                 }
    01138             }   /* if(fFirstPass) */
    01139
    01140             nConsecutiveTabs++;
    01141             nCount--;
    01142             ped->fAnsi ? lpTab++ : (LPSTR) (lpwTab++) ;  // Move to the next character.
    01143         }  // while(*lpTab == TAB) //
    01144
    01145         if (fDraw) {
    01146             if (fFirstPass) {
    01147                 // Is anything remaining to be drawn in this strip?
    01148                 if (!nCount)
    01149                     rc.right = xEnd;      // No! We are done.
    01150                 else {
    01151                     // "x" is the effective starting position of next strip.
    01152                     iTabLength = xEnd - xStripEndPos;
    01153
    01154                     // Check if there is a possibility of this tab length being too small
    01155                     // compared to the negative A and C widths if any.
    01156                     if ((wNegCwidth + (wNegAwidth = ped->wMaxNegA)) > (UINT)iTabLength) {
    01157                         // Unfortunately, there is a possiblity of an overlap.
    01158                         // Let us find out the actual NegA for the next strip.
    01159                         wNegAwidth = GetActualNegA(
    01160                               hdc,
    01161                               ped,
    01162                               xEnd,
    01163                               lpstring + (cch + nConsecutiveTabs)*ped->cbChar,
    01164                               ichString + cch + nConsecutiveTabs,
    01165                               nCount,
    01166                               &NegAInfo);
    01167                     }
    01168
    01169                     // Check if they actually overlap //
    01170                     if ((wNegCwidth + wNegAwidth) <= (UINT)iTabLength) {
    01171                         // No overlap between the strips. This is the ideal situation.
    01172                         rc.right = xEnd - wNegAwidth;
    01173                     } else {
    01174                         // Yes! They overlap.
    01175                         rc.right = xEnd;
    01176
    01177                         // See if negative C width is too large compared to tab length.
    01178                         if (wNegCwidth > (UINT)iTabLength) {
    01179                             // Must redraw transparently a part of the current strip later.
    01180                             if (RedrawStripInfo.nCount) {
    01181                                 // A previous strip also needs to be redrawn; So, merge this
    01182                                 // strip to that strip.
    01183                                 RedrawStripInfo.nCount = (ichString -
    01184                                     RedrawStripInfo.ichString) + cch;
    01185                             } else {
    01186                                 RedrawStripInfo.nCount = cch;
    01187                                 RedrawStripInfo.lpString = lpstring;
    01188                                 RedrawStripInfo.ichString = ichString;
    01189                                 RedrawStripInfo.XStartPos = xStripStPos;
    01190                             }
    01191                         }
    01192
    01193                         if (wNegAwidth) {
    01194                             // Must redraw transparently the first part of the next strip later.
    01195                             if (RedrawStripInfo.nCount) {
    01196                                 // A previous strip also needs to be redrawn; So, merge this
    01197                                 // strip to that strip.
    01198                                 RedrawStripInfo.nCount = (NegAInfo.ichString - RedrawStripInfo.ichString) +
    01199                                        NegAInfo.nCount;
    01200                             } else
    01201                                 RedrawStripInfo = NegAInfo;
    01202                         }
    01203                     }
    01204                 } // else (!nCount) //
    01205             }  // if (fFirstPass) //
    01206
    01207             if (rc.left < xClipEndPos) {
    01208                 if (fFirstPass) {
    01209                     // If this is the end of the strip, then complete the rectangle.
    01210                     if ((!nCount) && (xClipEndPos == MAXCLIPENDPOS))
    01211                         rc.right = max(rc.right, xClipEndPos);
    01212                     else
    01213                         rc.right = min(rc.right, xClipEndPos);
    01214                 }
    01215
    01216                 // Draw the current strip.
    01217                 if (rc.left < rc.right)
    01218                     if ( ped->fAnsi )
    01219                         ExtTextOutA(hdc,
    01220                                     xStripStPos,
    01221                                     y,
    01222                                     (fFirstPass && fOpaque ? (ETO_OPAQUE | ETO_CLIPPED) : ETO_CLIPPED),
    01223                                     (LPRECT)&rc, lpstring, cch, 0L);
    01224                     else
    01225                         ExtTextOutW(hdc,
    01226                                     xStripStPos,
    01227                                     y,
    01228                                     (fFirstPass && fOpaque ? (ETO_OPAQUE | ETO_CLIPPED) : ETO_CLIPPED),
    01229                                     (LPRECT)&rc, (LPWSTR)lpstring, cch, 0L);
    01230
    01231             }
    01232
    01233             if (fFirstPass)
    01234                 rc.left = max(rc.right, xClipStPos);
    01235             ichString += (cch+nConsecutiveTabs);
    01236         }  // if (fDraw) //
    01237
    01238         // Skip over the tab and the characters we just drew.
    01239         lpstring += (cch + nConsecutiveTabs) * ped->cbChar;
    01240     }  // while (nCount) //
    01241
    01242     xEndOfStrip = xEnd;
    01243
    01244     // check if we need to draw some portions transparently.
    01245     if (fFirstPass && fDraw && RedrawStripInfo.nCount) {
    01246         iSavedBkMode = SetBkMode(hdc, TRANSPARENT);
    01247         fFirstPass = FALSE;
    01248
    01249         nCount = RedrawStripInfo.nCount;
    01250         rc.left = xClipStPos;
    01251         rc.right = xClipEndPos;
    01252         lpstring = RedrawStripInfo.lpString;
    01253         ichString = RedrawStripInfo.ichString;
    01254         xEnd = RedrawStripInfo.XStartPos;
    01255         goto RedrawStrip;  // Redraw Transparently.
    01256     }
    01257
    01258     if (iSavedBkMode)             // Did we change the Bk mode?
    01259         SetBkMode(hdc, iSavedBkMode);  // Then, let us set it back!
    01260
    01261     return((UINT)(xEndOfStrip - xStart));
    01262 }

void ECUnlock | ( | PED | ped | ) |

Definition at line 86 of file editec.c.

References tagED::cbChar, tagED::cch, tagED::charPasswordChar, tagED::fEncoded, tagED::hInstance, tagED::hText, tagED::iLockLevel, LOCALLOCK, LOCALUNLOCK, RtlRunEncodeUnicodeString(), tagED::seed, TRUE, and USHORT.

Referenced by ECCopy(), ECDeleteText(), ECDoIMEMenuCommand(), ECGetText(), EcImeRequestHandler(), ECInsertText(), ECNextIch(), ECPrevIch(), ECSetCaretHandler(), ECWord(), HanjaKeyHandler(), MLBuildchLines(), MLCalcXOffset(), MLDrawText(), MLEditWndProc(), MLGetLine(), MLIchToXYPos(), MLIchToYPos(), MLInsertCrCrLf(), MLKeyDown(), MLLine(), MLMouseMotion(), MLMouseToIch(), MLMoveSelection(), MLMoveSelectionRestricted(), MLSetHandle(), MLSetSelection(), MLStripCrCrLf(), MLUpdateiCaretLine(), NextWordCallBack(), NextWordLpkCallBack(), SLCalcStringWidth(), SLCalcXOffsetSpecial(), SLChangeSelection(), SLDrawLine(), SLDrawText(), SLGetClipRect(), SLIchToLeftXPos(), SLInsertText(), SLMouseMotion(), SLMouseToIch(), SLMoveSelectionRestricted(), and SLScrollText().

    00088 {
    00089     /*
    00090      * if we are removing the last lock on the text and the password
    00091      * character is set then encode the text
    00092      */
    00093     //RIPMSG1(RIP_VERBOSE, "unlock: %d '%10s'\n", ped->iLockLevel, ped->ptext);
    00094     if (ped->charPasswordChar && ped->iLockLevel == 1 && ped->cch != 0) {
    00095         UNICODE_STRING string;
    00096         string.Length = string.MaximumLength = (USHORT)(ped->cch * ped->cbChar);
    00097         string.Buffer = LOCALLOCK(ped->hText, ped->hInstance);
    00098
    00099         RtlRunEncodeUnicodeString(&(ped->seed), &string);
    00100         //RIPMSG1(RIP_VERBOSE, "Encoding: '%10s'\n", ped->ptext);
    00101         ped->fEncoded = TRUE;
    00102         LOCALUNLOCK(ped->hText, ped->hInstance);
    00103     }
    00104     LOCALUNLOCK(ped->hText, ped->hInstance);
    00105     ped->iLockLevel--;
    00106 }

void ECUpdateFormat | ( | PED | ped,
|  | DWORD | dwStyle,
|  | DWORD | dwExStyle
| ) |

Definition at line 4185 of file editec.c.

References ECInvalidateClient(), FALSE, tagED::format, tagED::fRtoLReading, tagED::fWrap, MLBuildchLines(), MLScroll(), MLUpdateiCaretLine(), NULL, TRUE, and UINT.

Referenced by MLEditWndProc(), and SLEditWndProc().

    04189 {
    04190     UINT fNewRtoLReading;
    04191     UINT uiNewFormat;
    04192
    04193     // Extract new format and reading order from style
    04194
    04195     fNewRtoLReading = dwExStyle & WS_EX_RTLREADING ? 1 : 0;
    04196     uiNewFormat     = dwStyle & ES_FMTMASK;
    04197
    04198
    04199     // WS_EX_RIGHT is ignored unless dwStyle is ES_LEFT
    04200
    04201     if (uiNewFormat == ES_LEFT && dwExStyle & WS_EX_RIGHT) {
    04202         uiNewFormat = ES_RIGHT;
    04203     }
    04204
    04205
    04206     // Internally ES_LEFT and ES_RIGHT are swapped for RtoLReading order
    04207     // (Think of them as ES_LEADING and ES_TRAILING)
    04208
    04209     if (fNewRtoLReading) {
    04210         switch (uiNewFormat) {
    04211             case ES_LEFT:  uiNewFormat = ES_RIGHT; break;
    04212             case ES_RIGHT: uiNewFormat = ES_LEFT;  break;
    04213         }
    04214     }
    04215
    04216
    04217     // Format change does not cause redisplay by itself
    04218
    04219     ped->format = uiNewFormat;
    04220
    04221
    04222     // Refresh display on change of reading order
    04223
    04224     if (fNewRtoLReading != ped->fRtoLReading) {
    04225
    04226         ped->fRtoLReading = fNewRtoLReading;
    04227
    04228         if (ped->fWrap) {
    04229             // Redo wordwrap
    04230             MLBuildchLines(ped, 0, 0, FALSE, NULL, NULL);
    04231             MLUpdateiCaretLine(ped);
    04232         } else {
    04233             // Refresh horizontal scrollbar display
    04234             MLScroll(ped, FALSE, 0xffffffff, 0, TRUE);
    04235         }
    04236         ECInvalidateClient(ped, TRUE);
    04237     }
    04238 }

void ECWord | ( | PED | ped,
|  | ICH | ichStart,
|  | BOOL | fLeft,
|  | ICH * | pichMin,
|  | ICH * | pichMax
| ) |

Definition at line 1552 of file editec.c.

References BOOL, tagED::cbChar, tagED::cch, CHAR, tagED::charPasswordChar, ECAnsiNext(), ECAnsiPrev(), ECIsDBCSLeadByte(), ECLock(), ECUnlock(), FALSE, tagED::fAnsi, ICH, ISDELIMETERA, ISDELIMETERW, tagED::lpfnNextWord, min, NextWordCallBack(), NextWordLpkCallBack(), tagED::pLpkEditCallout, TRUE, and UserIsFullWidth().

Referenced by MLBuildchLines(), MLKeyDown(), MLMouseMotion(), SLKeyDown(), and SLMouseMotion().

    01558 {
    01559     BOOL charLocated = FALSE;
    01560     BOOL spaceLocated = FALSE;
    01561
    01562     if ((!ichStart && fLeft) || (ichStart == ped->cch && !fLeft)) {
    01563
    01564         /*
    01565          * We are at the beginning of the text (looking left) or we are at end
    01566          * of text (looking right), no word here
    01567          */
    01568         if (pichMin) *pichMin=0;
    01569         if (pichMax) *pichMax=0;
    01570         return;
    01571     }
    01572
    01573     /*
    01574      * Don't give out hints about word breaks if password chars are being used,
    01575      */
    01576     if (ped->charPasswordChar) {
    01577         if (pichMin) *pichMin=0;
    01578         if (pichMax) *pichMax=ped->cch;
    01579         return;
    01580     }
    01581
    01582     if (ped->fAnsi) {
    01583         PSTR pText;
    01584         PSTR pWordMinSel;
    01585         PSTR pWordMaxSel;
    01586         PSTR pPrevChar;
    01587
    01588         UserAssert(ped->cbChar == sizeof(CHAR));
    01589
    01590         if (ped->lpfnNextWord) {
    01591             NextWordCallBack(ped, ichStart, fLeft, pichMin, pichMax);
    01592             return;
    01593         }
    01594
    01595         if (ped->pLpkEditCallout) {
    01596             NextWordLpkCallBack(ped, ichStart, fLeft, pichMin, pichMax);
    01597             return;
    01598         }
    01599
    01600         pText = ECLock(ped);
    01601         pWordMinSel = pWordMaxSel = pText + ichStart;
    01602
    01603         /*
    01604          * if fLeft: Move pWordMinSel to the left looking for the start of a word.
    01605          * If we start at a space, we will include spaces in the selection as we
    01606          * move left untill we find a nonspace character. At that point, we continue
    01607          * looking left until we find a space. Thus, the selection will consist of
    01608          * a word with its trailing spaces or, it will consist of any leading at the
    01609          * beginning of a line of text.
    01610          */
    01611
    01612         /*
    01613          * if !fLeft: (ie. right word) Move pWordMinSel looking for the start of a
    01614          * word. If the pWordMinSel points to a character, then we move left
    01615          * looking for a space which will signify the start of the word. If
    01616          * pWordMinSel points to a space, we look right till we come upon a
    01617          * character. pMaxWord will look right starting at pMinWord looking for the
    01618          * end of the word and its trailing spaces.
    01619          */
    01620
    01621         if (fLeft || !ISDELIMETERA(*pWordMinSel) && *pWordMinSel != 0x0D) {
    01622
    01623             /*
    01624              * If we are moving left or if we are moving right and we are not on a
    01625              * space or a CR (the start of a word), then we was look left for the
    01626              * start of a word which is either a CR or a character. We do this by
    01627              * looking left till we find a character (or if CR we stop), then we
    01628              * continue looking left till we find a space or LF.
    01629              */
    01630             while (pWordMinSel > pText && ((!ISDELIMETERA(*(pWordMinSel - 1)) &&
    01631                     *(pWordMinSel - 1) != 0x0A) || !charLocated)) {
    01632
    01633                 /*
    01634                  * Treat double byte character as a word  ( in ansi pWordMinSel loop )
    01635                  */
    01636                 pPrevChar = ECAnsiPrev( ped, pText, pWordMinSel );
    01637
    01638                 /*
    01639                 ** we are looking right ( !fLeft ).
    01640                 ** if current character is a double byte chararacter or
    01641                 ** previous character is a double byte character, we
    01642                 ** are on the beggining of a word.
    01643                 */
    01644                 if ( !fLeft && ( ISDELIMETERA( *pPrevChar )           ||
    01645                                  *pPrevChar == 0x0A                   ||
    01646                                  ECIsDBCSLeadByte(ped, *pWordMinSel)  ||
    01647                                  pWordMinSel - pPrevChar == 2 ) ) {
    01648                     /*
    01649                      * If we are looking for the start of the word right, then we
    01650                      * stop when we have found it. (needed in case charLocated is
    01651                      * still FALSE)
    01652                      */
    01653                     break;
    01654                 }
    01655
    01656                 if ( pWordMinSel - pPrevChar == 2 ) {
    01657                     /*
    01658                     ** previous character is a double byte character.
    01659                     ** if we are in a word ( charLocated == TRUE )
    01660                     ** current position is the beginning of the word
    01661                     ** if we are not in a word ( charLocated == FALSE )
    01662                     ** the previous character is what we looking for.
    01663                     */
    01664                     if ( ! charLocated ) {
    01665                         pWordMinSel = pPrevChar;
    01666                     }
    01667                     break;
    01668                 }
    01669                 pWordMinSel = pPrevChar;
    01670
    01671                 if (!ISDELIMETERA(*pWordMinSel) && *pWordMinSel != 0x0A) {
    01672
    01673                     /*
    01674                      * We have found the last char in the word. Continue looking
    01675                      * backwards till we find the first char of the word
    01676                      */
    01677                     charLocated = TRUE;
    01678
    01679                     /*
    01680                      * We will consider a CR the start of a word
    01681                      */
    01682                     if (*pWordMinSel == 0x0D)
    01683                         break;
    01684                 }
    01685             }
    01686         } else {
    01687             while ((ISDELIMETERA(*pWordMinSel) || *pWordMinSel == 0x0A) && pWordMinSel < pText + ped->cch)
    01688                 pWordMinSel++;
    01689         }
    01690
    01691         /*
    01692          * Adjust the initial position of pWordMaxSel ( in ansi )
    01693          */
    01694         pWordMaxSel = ECAnsiNext(ped, pWordMinSel);
    01695         pWordMaxSel = min(pWordMaxSel, pText + ped->cch);
    01696
    01697         /*
    01698         ** If pWordMinSel points a double byte character AND
    01699         **    pWordMaxSel points non space
    01700         ** then
    01701         **    pWordMaxSel points the beggining of next word.
    01702         */
    01703         if ( ( pWordMaxSel - pWordMinSel == 2 ) && ! ISDELIMETERA(*pWordMaxSel) )
    01704             goto FastReturnA;
    01705         if (*pWordMinSel == 0x0D) {
    01706             if (pWordMinSel > pText && *(pWordMinSel - 1) == 0x0D)
    01707                 /* So that we can treat CRCRLF as one word also. */
    01708                 pWordMinSel--;
    01709             else if (*(pWordMinSel + 1) == 0x0D)
    01710                 /* Move MaxSel on to the LF */
    01711                 pWordMaxSel++;
    01712         }
    01713
    01714
    01715
    01716         /*
    01717          * Check if we have a one character word
    01718          */
    01719         if (ISDELIMETERA(*pWordMaxSel))
    01720             spaceLocated = TRUE;
    01721
    01722         /*
    01723          * Move pWordMaxSel to the right looking for the end of a word and its
    01724          * trailing spaces. WordMaxSel stops on the first character of the next
    01725          * word. Thus, we break either at a CR or at the first nonspace char after
    01726          * a run of spaces or LFs.
    01727          */
    01728         while ((pWordMaxSel < pText + ped->cch) && (!spaceLocated || (ISDELIMETERA(*pWordMaxSel)))) {
    01729             if (*pWordMaxSel == 0x0D)
    01730                 break;
    01731
    01732             /*
    01733              * Treat double byte character as a word ( in ansi pWordMaxSel loop )
    01734              */
    01735             /*
    01736             ** if it's a double byte character then
    01737             ** we are at the beginning of next word
    01738             ** which is a double byte character.
    01739             */
    01740             if (ECIsDBCSLeadByte( ped, *pWordMaxSel))
    01741                 break;
    01742
    01743             pWordMaxSel++;
    01744
    01745             if (ISDELIMETERA(*pWordMaxSel))
    01746                 spaceLocated = TRUE;
    01747
    01748             if (*(pWordMaxSel - 1) == 0x0A)
    01749                 break;
    01750         }
    01751
    01752         /*
    01753          * label for fast return ( for Ansi )
    01754          */
    01755 FastReturnA:
    01756         ECUnlock(ped);
    01757
    01758         if (pichMin)   *pichMin = (ICH)(pWordMinSel - pText);
    01759         if (pichMax)   *pichMax = (ICH)(pWordMaxSel - pText);
    01760         return;
    01761
    01762     } else {  // !fAnsi
    01763         LPWSTR pwText;
    01764         LPWSTR pwWordMinSel;
    01765         LPWSTR pwWordMaxSel;
    01766         BOOL charLocated = FALSE;
    01767         BOOL spaceLocated = FALSE;
    01768         PWSTR pwPrevChar;
    01769
    01770         UserAssert(ped->cbChar == sizeof(WCHAR));
    01771
    01772         if (ped->lpfnNextWord) {
    01773             NextWordCallBack(ped, ichStart, fLeft, pichMin, pichMax);
    01774             return;
    01775         }
    01776
    01777         if (ped->pLpkEditCallout) {
    01778             NextWordLpkCallBack(ped, ichStart, fLeft, pichMin, pichMax);
    01779             return;
    01780         }
    01781
    01782         pwText = (LPWSTR)ECLock(ped);
    01783         pwWordMinSel = pwWordMaxSel = pwText + ichStart;
    01784
    01785         /*
    01786          * if fLeft: Move pWordMinSel to the left looking for the start of a word.
    01787          * If we start at a space, we will include spaces in the selection as we
    01788          * move left untill we find a nonspace character. At that point, we continue
    01789          * looking left until we find a space. Thus, the selection will consist of
    01790          * a word with its trailing spaces or, it will consist of any leading at the
    01791          * beginning of a line of text.
    01792          */
    01793
    01794         /*
    01795          * if !fLeft: (ie. right word) Move pWordMinSel looking for the start of a
    01796          * word. If the pWordMinSel points to a character, then we move left
    01797          * looking for a space which will signify the start of the word. If
    01798          * pWordMinSel points to a space, we look right till we come upon a
    01799          * character. pMaxWord will look right starting at pMinWord looking for the
    01800          * end of the word and its trailing spaces.
    01801          */
    01802
    01803
    01804         if (fLeft || (!ISDELIMETERW(*pwWordMinSel) && *pwWordMinSel != 0x0D))
    01805          /* If we are moving left or if we are moving right and we are not on a
    01806           * space or a CR (the start of a word), then we was look left for the
    01807           * start of a word which is either a CR or a character. We do this by
    01808           * looking left till we find a character (or if CR we stop), then we
    01809           * continue looking left till we find a space or LF.
    01810           */ {
    01811             while (pwWordMinSel > pwText && ((!ISDELIMETERW(*(pwWordMinSel - 1)) && *(pwWordMinSel - 1) != 0x0A) || !charLocated)) {
    01812                 /*
    01813                  * Treat double byte character as a word  ( in unicode pwWordMinSel loop )
    01814                  */
    01815                 pwPrevChar = pwWordMinSel - 1;
    01816                 /*
    01817                 ** we are looking right ( !fLeft ).
    01818                 **
    01819                 ** if current character is a double width chararacter
    01820                 ** or previous character is a double width character,
    01821                 ** we are on the beggining of a word.
    01822                 */
    01823                 if (!fLeft && (ISDELIMETERW( *pwPrevChar)  ||
    01824                                *pwPrevChar == 0x0A         ||
    01825                                UserIsFullWidth(CP_ACP,*pwWordMinSel) ||
    01826                                UserIsFullWidth(CP_ACP,*pwPrevChar)))    {
    01827                     /*
    01828                      * If we are looking for the start of the word right, then we
    01829                      * stop when we have found it. (needed in case charLocated is
    01830                      * still FALSE)
    01831                      */
    01832                     break;
    01833                 }
    01834
    01835                 if (UserIsFullWidth(CP_ACP,*pwPrevChar)) {
    01836                     /*
    01837                     ** Previous character is a double width character.
    01838                     **
    01839                     ** if we are in a word ( charLocated == TRUE )
    01840                     ** current position is the beginning of the word
    01841                     ** if we are not in a word ( charLocated == FALSE )
    01842                     ** the previous character is what we looking for.
    01843                     */
    01844                     if ( ! charLocated ) {
    01845                         pwWordMinSel = pwPrevChar;
    01846                     }
    01847                     break;
    01848                 }
    01849                 pwWordMinSel = pwPrevChar;
    01850
    01851                 if (!ISDELIMETERW(*pwWordMinSel) && *pwWordMinSel != 0x0A)
    01852                  /*
    01853                   * We have found the last char in the word. Continue looking
    01854                   * backwards till we find the first char of the word
    01855                   */ {
    01856                     charLocated = TRUE;
    01857
    01858                     /*
    01859                      * We will consider a CR the start of a word
    01860                      */
    01861                     if (*pwWordMinSel == 0x0D)
    01862                         break;
    01863                 }
    01864             }
    01865         } else {
    01866
    01867             /*
    01868              * We are moving right and we are in between words so we need to move
    01869              * right till we find the start of a word (either a CR or a character.
    01870              */
    01871             while ((ISDELIMETERW(*pwWordMinSel) || *pwWordMinSel == 0x0A) && pwWordMinSel < pwText + ped->cch)
    01872                 pwWordMinSel++;
    01873         }
    01874
    01875         pwWordMaxSel = min((pwWordMinSel + 1), (pwText + ped->cch));
    01876
    01877         /*
    01878         ** If pwWordMinSel points a double width character AND
    01879         **    pwWordMaxSel points non space
    01880         ** then
    01881         **    pwWordMaxSel points the beggining of next word.
    01882         */
    01883         if (UserIsFullWidth(CP_ACP,*pwWordMinSel) && ! ISDELIMETERW(*pwWordMaxSel))
    01884             goto FastReturnW;
    01885         if (*pwWordMinSel == 0x0D) {
    01886             if (pwWordMinSel > pwText && *(pwWordMinSel - 1) == 0x0D)
    01887                 /* So that we can treat CRCRLF as one word also. */
    01888                 pwWordMinSel--;
    01889             else if (*(pwWordMinSel + 1) == 0x0D)
    01890                 /* Move MaxSel on to the LF */
    01891                 pwWordMaxSel++;
    01892         }
    01893
    01894
    01895
    01896         /*
    01897          * Check if we have a one character word
    01898          */
    01899         if (ISDELIMETERW(*pwWordMaxSel))
    01900             spaceLocated = TRUE;
    01901
    01902         /*
    01903          * Move pwWordMaxSel to the right looking for the end of a word and its
    01904          * trailing spaces. WordMaxSel stops on the first character of the next
    01905          * word. Thus, we break either at a CR or at the first nonspace char after
    01906          * a run of spaces or LFs.
    01907          */
    01908         while ((pwWordMaxSel < pwText + ped->cch) && (!spaceLocated || (ISDELIMETERW(*pwWordMaxSel)))) {
    01909             if (*pwWordMaxSel == 0x0D)
    01910                 break;
    01911
    01912             /*
    01913              * treat double byte character as a word ( in unicode pwWordMaxSel loop )
    01914              */
    01915             /*
    01916             ** if it's a double width character
    01917             ** then we are at the beginning of
    01918             ** the next word which is a double
    01919             ** width character.
    01920             */
    01921             if (UserIsFullWidth(CP_ACP,*pwWordMaxSel))
    01922                 break;
    01923
    01924             pwWordMaxSel++;
    01925
    01926             if (ISDELIMETERW(*pwWordMaxSel))
    01927                 spaceLocated = TRUE;
    01928
    01929
    01930             if (*(pwWordMaxSel - 1) == 0x0A)
    01931                 break;
    01932         }
    01933
    01934         /*
    01935          * label for fast return ( for Unicode )
    01936          */
    01937 FastReturnW:
    01938         ECUnlock(ped);
    01939
    01940         if (pichMin)   *pichMin = (ICH)(pwWordMinSel - pwText);
    01941         if (pichMax)   *pichMax = (ICH)(pwWordMaxSel - pwText);
    01942         return;
    01943     }
    01944 }

LRESULT EditWndProc | ( | PWND | pwnd,
|  | UINT | message,
|  | WPARAM | wParam,
|  | LPARAM | lParam
| ) |

Definition at line 2904 of file editec.c.

References _GetClientRect(), BOOL, tagED::cch, tagED::cchTextMax, tagED::charPasswordChar, CI_16BIT, ClearWindowState(), tagED::cLines, CopyRect, DefWindowProcWorker(), DWORD, ECClearText(), ECCopy(), ECCutText(), ECDeleteText(), ECEmptyUndo(), ECEnableDisableIME(), ECGetEditDC(), ECGetText(), ECImeComposition(), EcImeRequestHandler(), ECImmSetCompositionFont(), ECImmSetCompositionWindow(), ECInitInsert(), ECInOutReconversionMode(), ECInvalidateClient(), ECIsAncestorActive(), ECMenu(), ECNcCreate(), ECNcDestroyHandler(), ECNotifyParent(), ECReleaseEditDC(), ECSetCaretHandler(), ECSetFont(), ECSetMargin(), ECSetPasswordChar(), ECSetText(), EFREADONLY, tagED::fAllowRTL, FALSE, tagED::fAnsi, tagED::fDirty, tagED::fDisabled, tagED::fFocus, FindNCHit(), tagED::fInReconversion, tagED::fInsertCompChr, tagED::fKorea, tagED::fLShift, tagED::fMouseDown, tagED::format, fpImmGetContext, fpImmIsIME, fpImmLockIMC, fpImmNotifyIME, fpImmReleaseContext, fpImmUnlockIMC, tagED::fReadOnly, tagED::fReplaceCompChr, tagED::fRtoLReading, tagED::fSawRButtonDown, tagED::fSingle, tagED::fSwapRoOnUp, GetClientInfo, GetKeyState(), tagED::hFont, tagED::hwnd, HWq, ICH, tagED::ichCaret, tagED::ichMaxSel, tagED::ichMinSel, L, tagED::lpfnNextWord, MapVirtualKey(), min, MLDeleteText(), MLEditWndProc(), NtUserGetCaretPos(), NULL, NULL_HIMC, tagED::pLpkEditCallout, PtInRect(), tagED::ptScreenBounding, Pundo, tagED::rcFmt, SetWindowState(), SLDrawText(), SLEditWndProc(), SYS_ALTERNATE, TestWF, THREAD_HKL, TRUE, UINT, UNDO_NONE, WFOLDUI, tagED::wImeStatus, tagED::wLeftMargin, and tagED::wRightMargin.

Referenced by EditWndProcWorker().

    02909 {
    02910     HWND hwnd = HWq(pwnd);
    02911     LRESULT lreturn;
    02912     PED  ped;
    02913
    02914     /*
    02915      * Get the ped for the given window now since we will use it a lot in
    02916      * various handlers. This was stored using SetWindowLong(hwnd,0,hped) when
    02917      * we initially created the edit control.
    02918      */
    02919     ped = ((PEDITWND)pwnd)->ped;
    02920
    02921     /*
    02922      * Dispatch the various messages we can receive
    02923      */
    02924     lreturn = 1L;
    02925     switch (message) {
    02926
    02927     /*
    02928      * Messages which are handled the same way for both single and multi line
    02929      * edit controls.
    02930      */
    02931     case WM_KEYDOWN:
    02932          // LPK handling of Ctrl/LShift, Ctrl/RShift
    02933          if (ped && ped->pLpkEditCallout && ped->fAllowRTL) {
    02934
    02935              ped->fSwapRoOnUp = FALSE; // Any keydown cancels a ctrl/shift reading order change
    02936
    02937              switch (wParam) {
    02938                  case VK_SHIFT:
    02939                      if ((GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_MENU) & 0x8000)) {
    02940                          // Left shift or right shift pressed while control held down
    02941                          // Check that alt (VK_MENU) isn't down to avoid false firing on AltGr which equals Ctrl+Alt.
    02942                          if (MapVirtualKey((LONG)lParam>>16&0xff, 3) == VK_LSHIFT) {
    02943                              // User wants left to right reading order
    02944                              ped->fSwapRoOnUp = (ped->fRtoLReading)  || (ped->format & ES_RIGHT) ;
    02945                              ped->fLShift = TRUE;
    02946                          } else {
    02947                              // User wants right to left reading order
    02948                              ped->fSwapRoOnUp = (!ped->fRtoLReading) || (ped->format & ES_RIGHT);
    02949                              ped->fLShift = FALSE;
    02950                          }
    02951                      }
    02952                      break;
    02953
    02954                  case VK_LEFT:
    02955                      if (ped->fRtoLReading) {
    02956                         wParam = VK_RIGHT;
    02957                      }
    02958                      break;
    02959
    02960                  case VK_RIGHT:
    02961                      if (ped->fRtoLReading) {
    02962                          wParam = VK_LEFT;
    02963                      }
    02964                      break;
    02965              }
    02966          }
    02967          goto HandleEditMsg;
    02968
    02969     case WM_KEYUP:
    02970         if (ped && ped->pLpkEditCallout && ped->fAllowRTL && ped->fSwapRoOnUp) {
    02971
    02972             BOOL fReadingOrder;
    02973             // Complete reading order change detected earlier during keydown
    02974
    02975             ped->fSwapRoOnUp = FALSE;
    02976             fReadingOrder = ped->fRtoLReading;
    02977
    02978             // Remove any overriding ES_CENTRE or ES_RIGHT format from dwStyle
    02979             SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~ES_FMTMASK);
    02980
    02981             if (ped->fLShift) {
    02982                 // Set Left to Right reading order and right scrollbar in EX_STYLE
    02983                 SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE)
    02984                               & ~(WS_EX_RTLREADING | WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR));
    02985
    02986                 // Edit control is LTR now, then notify the parent.
    02987                 ECNotifyParent(ped, EN_ALIGN_LTR_EC);
    02988                 // ? Select a keyboard layout appropriate to LTR operation
    02989             } else {
    02990                 // Set Right to Left reading order, right alignment and left scrollbar
    02991                 SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE)
    02992                               | WS_EX_RTLREADING | WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR);
    02993
    02994                 // Edit control is RTL now, then notify the parent.
    02995                 ECNotifyParent(ped, EN_ALIGN_RTL_EC);
    02996                 // ? Select a keyboard layout appropriate to RTL operation
    02997             }
    02998
    02999             // If reading order didn't change, so we are sure the alignment changed and the edit window didn't invalidate yet.
    03000             if (fReadingOrder == (BOOL) ped->fRtoLReading) {
    03001               ECInvalidateClient(ped, TRUE);
    03002             }
    03003         }
    03004         goto HandleEditMsg;
    03005
    03006     case WM_INPUTLANGCHANGE:
    03007         if (ped) {
    03008             // EC_INSERT_COMPOSITION_CHAR : WM_INPUTLANGCHANGE - call ECInitInsert()
    03009             HKL hkl = THREAD_HKL();
    03010
    03011             ECInitInsert(ped, hkl);
    03012
    03013             if (ped->fInReconversion) {
    03014                 ECInOutReconversionMode(ped, FALSE);
    03015             }
    03016
    03017             //
    03018             // Font and caret position might be changed while
    03019             // another keyboard layout is active. Set those
    03020             // if the edit control has the focus.
    03021             //
    03022             if (ped->fFocus && fpImmIsIME(hkl)) {
    03023                 POINT pt;
    03024
    03025                 ECImmSetCompositionFont(ped);
    03026                 NtUserGetCaretPos(&pt);
    03027                 ECImmSetCompositionWindow(ped, pt.x, pt.y);
    03028             }
    03029         }
    03030
    03031         goto HandleEditMsg;
    03032
    03033     case WM_COPY:
    03034
    03035         /*
    03036          * wParam - not used
    03037          * lParam - not used
    03038          */
    03039         lreturn = (LONG)ECCopy(ped);
    03040         break;
    03041
    03042     case WM_CUT:
    03043         /*
    03044          *
    03045          * wParamLo --    unused
    03046          * lParam --    unused
    03047          */
    03048         ECCutText(ped);
    03049         return 0;
    03050
    03051     case WM_CLEAR:
    03052         /*
    03053          * wParamLo --    unused
    03054          * lParam --    unused
    03055          */
    03056         ECClearText(ped);
    03057         return 0;
    03058
    03059     case WM_ENABLE:
    03060
    03061         /*
    03062          * wParam - nonzero if window is enabled else disable window if 0.
    03063          * lParam - not used
    03064          */
    03065         lreturn = (LONG)(ped->fDisabled = !((BOOL)wParam));
    03066         ECInvalidateClient(ped, TRUE);
    03067         break;
    03068
    03069     case WM_SYSCHAR:
    03070         //
    03071         // wParamLo --    key value
    03072         // lParam --    unused
    03073         //
    03074
    03075         //
    03076         // If this is a WM_SYSCHAR message generated by the UNDO
    03077         // keystroke we want to EAT IT
    03078         //
    03079         if ((lParam & SYS_ALTERNATE) && ((WORD)wParam == VK_BACK))
    03080             return TRUE;
    03081         else {
    03082             return DefWindowProcWorker(pwnd, message, wParam, lParam, ped->fAnsi);
    03083         }
    03084         break;
    03085
    03086     case EM_GETLINECOUNT:
    03087
    03088         /*
    03089          * wParam - not used
    03090            lParam - not used
    03091          */
    03092         lreturn = (LONG)ped->cLines;
    03093         break;
    03094
    03095     case EM_GETMODIFY:
    03096
    03097         /*
    03098          * wParam - not used
    03099            lParam - not used
    03100          */
    03101
    03102         /*
    03103          * Gets the state of the modify flag for this edit control.
    03104          */
    03105         lreturn = (LONG)ped->fDirty;
    03106         break;
    03107
    03108     case EM_SETMODIFY:
    03109
    03110         /*
    03111          * wParam - specifies the new value for the modify flag
    03112            lParam - not used
    03113          */
    03114
    03115         /*
    03116          * Sets the state of the modify flag for this edit control.
    03117          */
    03118         ped->fDirty = (wParam != 0);
    03119         break;
    03120
    03121     case EM_GETRECT:
    03122
    03123         /*
    03124          * wParam - not used
    03125            lParam - pointer to a RECT data structure that gets the dimensions.
    03126          */
    03127
    03128         /*
    03129          * Copies the rcFmt rect to *lpRect.
    03130          */
    03131         CopyRect((LPRECT)lParam, (LPRECT)&ped->rcFmt);
    03132         lreturn = (LONG)TRUE;
    03133         break;
    03134
    03135     case WM_GETFONT:
    03136
    03137         /*
    03138          * wParam - not used
    03139            lParam - not used
    03140          */
    03141         lreturn = (LRESULT)ped->hFont;
    03142         break;
    03143
    03144     case WM_SETFONT:
    03145
    03146         /*
    03147          * wParam - handle to the font
    03148            lParam - redraw if true else don't
    03149          */
    03150         ECSetFont(ped, (HANDLE)wParam, (BOOL)LOWORD(lParam));
    03151         break;
    03152
    03153     case WM_GETTEXT:
    03154
    03155         /*
    03156          * wParam - max number of _bytes_ (not characters) to copy
    03157          * lParam - buffer to copy text to. Text is 0 terminated.
    03158          */
    03159         lreturn = (LRESULT)ECGetText(ped, (ICH)wParam, (LPSTR)lParam, TRUE);
    03160         break;
    03161
    03162     case WM_SETTEXT:
    03163         //
    03164         // wParamLo --    unused
    03165         // lParam --    LPSTR, null-terminated, with new text.
    03166         //
    03167         lreturn = (LRESULT)ECSetText(ped, (LPSTR)lParam);
    03168         break;
    03169
    03170     case WM_GETTEXTLENGTH:
    03171
    03172         /*
    03173          * Return count of CHARs!!!
    03174          */
    03175         lreturn = (LONG)ped->cch;
    03176         break;
    03177
    03178     case WM_NCDESTROY:
    03179     case WM_FINALDESTROY:
    03180
    03181         /*
    03182          * wParam - not used
    03183            lParam - not used
    03184          */
    03185         ECNcDestroyHandler(pwnd, ped);
    03186         return 0;
    03187
    03188     /*
    03189      * Most apps (i.e. everyone but Quicken) don't pass on the rbutton
    03190      * messages when they do something with 'em inside of subclassed
    03191      * edit fields.  As such, we keep track of whether we saw the
    03192      * down before the up.  If we don't see the up, then DefWindowProc
    03193      * won't generate the context menu message, so no big deal.  If
    03194      * we didn't see the down, then don't let WM_CONTEXTMENU do
    03195      * anything.
    03196      *
    03197      * We also might want to not generate WM_CONTEXTMENUs for old
    03198      * apps when the mouse is captured.
    03199      */
    03200
    03201     case WM_RBUTTONDOWN:
    03202         ped->fSawRButtonDown = TRUE;
    03203         goto HandleEditMsg;
    03204
    03205     case WM_RBUTTONUP:
    03206         if (ped->fSawRButtonDown) {
    03207             ped->fSawRButtonDown = FALSE;
    03208             if (!ped->fInReconversion) {
    03209                 goto HandleEditMsg;
    03210             }
    03211         }
    03212         // Don't pass this on to DWP so WM_CONTEXTMENU isn't generated.
    03213         return 0;
    03214
    03215     case WM_CONTEXTMENU: {
    03216             POINT pt ;
    03217             int nHit = FindNCHit(pwnd, (LONG)lParam);
    03218             if ((nHit == HTVSCROLL) || (nHit == HTHSCROLL)) {
    03219                 return DefWindowProcWorker(pwnd, message, wParam, lParam, ped->fAnsi);
    03220             }
    03221             POINTSTOPOINT(pt, lParam);
    03222             if (!TestWF(pwnd, WFOLDUI) && ECIsAncestorActive(hwnd))
    03223                 ECMenu(hwnd, ped, &pt);
    03224         }
    03225         return 0;
    03226
    03227     case EM_CANUNDO:
    03228
    03229         /*
    03230          * wParam - not used
    03231            lParam - not used
    03232          */
    03233         lreturn = (LONG)(ped->undoType != UNDO_NONE);
    03234         break;
    03235
    03236     case EM_EMPTYUNDOBUFFER:
    03237
    03238         /*
    03239          * wParam - not used
    03240            lParam - not used
    03241          */
    03242         ECEmptyUndo(Pundo(ped));
    03243         break;
    03244
    03245     case EM_GETMARGINS:
    03246         //
    03247         // wParam --    unused
    03248         // lParam --    unused
    03249         //
    03250         return(MAKELONG(ped->wLeftMargin, ped->wRightMargin));
    03251
    03252     case EM_SETMARGINS:
    03253         //
    03254         // wParam --    EC_ margin flags
    03255         // lParam --    LOWORD is left, HIWORD is right margin
    03256         //
    03257         ECSetMargin(ped, (UINT)wParam, (DWORD)lParam, TRUE);
    03258         return 0;
    03259
    03260     case EM_GETSEL:
    03261
    03262         /*
    03263          * Gets the selection range for the given edit control. The
    03264          * starting position is in the low order word. It contains the position
    03265          * of the first nonselected character after the end of the selection in
    03266          * the high order word.
    03267          */
    03268         if ((PDWORD)wParam != NULL) {
    03269            *((PDWORD)wParam) = ped->ichMinSel;
    03270         }
    03271         if ((PDWORD)lParam != NULL) {
    03272            *((PDWORD)lParam) = ped->ichMaxSel;
    03273         }
    03274         lreturn = MAKELONG(ped->ichMinSel,ped->ichMaxSel);
    03275         break;
    03276
    03277     case EM_GETLIMITTEXT:
    03278         //
    03279         // wParamLo --    unused
    03280         // lParam --    unused
    03281         //
    03282         return(ped->cchTextMax);
    03283
    03284     case EM_SETLIMITTEXT:        /* Renamed from EM_LIMITTEXT in Chicago */
    03285         /*
    03286          * wParam - max number of CHARACTERS that can be entered
    03287          * lParam - not used
    03288          */
    03289
    03290         /*
    03291          * Specifies the maximum number of characters of text the user may
    03292          * enter. If maxLength is 0, we may enter MAXINT number of CHARACTERS.
    03293          */
    03294         if (ped->fSingle) {
    03295             if (wParam) {
    03296                 wParam = min(0x7FFFFFFEu, wParam);
    03297             } else {
    03298                 wParam = 0x7FFFFFFEu;
    03299             }
    03300         }
    03301
    03302         if (wParam) {
    03303             ped->cchTextMax = (ICH)wParam;
    03304         } else {
    03305             ped->cchTextMax = 0xFFFFFFFFu;
    03306         }
    03307         break;
    03308
    03309     case EM_POSFROMCHAR:
    03310         //
    03311         // Validate that char index is within text range
    03312         //
    03313         if (wParam >= ped->cch) {
    03314             return(-1L);
    03315         }
    03316         goto HandleEditMsg;
    03317
    03318     case EM_CHARFROMPOS: {
    03319         // Validate that point is within client of edit field
    03320         RECT    rc;
    03321         POINT   pt;
    03322
    03323         POINTSTOPOINT(pt, lParam);
    03324         _GetClientRect(pwnd, &rc);
    03325         if (!PtInRect(&rc, pt)) {
    03326             return(-1L);
    03327         }
    03328         goto HandleEditMsg;
    03329     }
    03330
    03331     case EM_SETPASSWORDCHAR:
    03332
    03333         /*
    03334          * wParam - sepecifies the new char to display instead of the
    03335          * real text. if null, display the real text.
    03336          */
    03337         ECSetPasswordChar(ped, (UINT)wParam);
    03338         break;
    03339
    03340     case EM_GETPASSWORDCHAR:
    03341         lreturn = (DWORD)ped->charPasswordChar;
    03342         break;
    03343
    03344     case EM_SETREADONLY:
    03345
    03346         /*
    03347          * wParam - state to set read only flag to
    03348          */
    03349         ped->fReadOnly = (wParam != 0);
    03350         if (wParam)
    03351             SetWindowState(pwnd, EFREADONLY);
    03352         else
    03353             ClearWindowState(pwnd, EFREADONLY);
    03354         lreturn = 1L;
    03355
    03356         ECEnableDisableIME( ped );
    03357         // We need to redraw the edit field so that the background color
    03358         // changes.  Read-only edits are drawn in CTLCOLOR_STATIC while
    03359         // others are drawn with CTLCOLOR_EDIT.
    03360         ECInvalidateClient(ped, TRUE);
    03361         break;
    03362
    03363     case EM_SETWORDBREAKPROC:
    03364
    03365         /*
    03366          * wParam - unused
    03367          * lParam - FARPROC address of an app supplied call back function
    03368          */
    03369         ped->lpfnNextWord = (EDITWORDBREAKPROCA)lParam;
    03370         break;
    03371
    03372     case EM_GETWORDBREAKPROC:
    03373         lreturn = (LRESULT)ped->lpfnNextWord;
    03374         break;
    03375
    03376     // IME
    03377     case EM_GETIMESTATUS:
    03378         // wParam == sub command
    03379         switch (wParam) {
    03380         case  EMSIS_COMPOSITIONSTRING:
    03381             return ped->wImeStatus;
    03382 #if 0   // memphis
    03383         case  EMSIS_GETLBBIT:
    03384             return (DWORD)ped->bLBBit;
    03385 #endif
    03386         }
    03387         break;
    03388
    03389     case EM_SETIMESTATUS:
    03390         // wParam == sub command
    03391         switch (wParam) {
    03392         case EMSIS_COMPOSITIONSTRING:
    03393             ped->wImeStatus = (WORD)lParam;
    03394         }
    03395         break;
    03396
    03397
    03398     case WM_NCCREATE:
    03399         lreturn = ECNcCreate(ped, pwnd, (LPCREATESTRUCT)lParam);
    03400         break;
    03401
    03402     case WM_LBUTTONDOWN:
    03403         //
    03404         // B#3623
    03405         // Don't set focus to edit field if it is within an inactive,
    03406         // captioned child.
    03407         // We might want to version switch this...  I haven't found
    03408         // any problems by not, but you never know...
    03409         //
    03410         if (ECIsAncestorActive(hwnd)) {
    03411             /*
    03412              * Reconversion support: quit reconversion if left button is clicked.
    03413              * Otherwise, if the current KL is Korean, finailize the composition string.
    03414              */
    03415             if (ped->fInReconversion || ped->fKorea) {
    03416                 BOOLEAN fReconversion = (BOOLEAN)ped->fInReconversion;
    03417                 DWORD dwIndex = fReconversion ? CPS_CANCEL : CPS_COMPLETE;
    03418                 HIMC hImc;
    03419
    03420                 ped->fReplaceCompChr = FALSE;
    03421
    03422                 hImc = fpImmGetContext(ped->hwnd);
    03423                 if (hImc) {
    03424                     fpImmNotifyIME(hImc, NI_COMPOSITIONSTR, dwIndex, 0);
    03425                     fpImmReleaseContext(ped->hwnd, hImc);
    03426                 }
    03427
    03428                 if (fReconversion) {
    03429                     ECInOutReconversionMode(ped, FALSE);
    03430                 }
    03431
    03432                 ECSetCaretHandler(ped);
    03433             }
    03434
    03435             goto HandleEditMsg;
    03436         }
    03437         break;
    03438
    03439     case WM_MOUSEMOVE:
    03440         //
    03441         // We only care about mouse messages when mouse is down.
    03442         //
    03443         if (ped->fMouseDown)
    03444             goto HandleEditMsg;
    03445         break;
    03446
    03447     case WM_IME_SETCONTEXT:
    03448         //
    03449         // If ped->fInsertCompChr is TRUE, that means we will do
    03450         // all the composition character drawing by ourself.
    03451         //
    03452         if ( ped->fInsertCompChr ) {
    03453             lParam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
    03454         }
    03455
    03456         if ( wParam ) {
    03457
    03458             PINPUTCONTEXT pInputContext;
    03459             HIMC hImc;
    03460
    03461             hImc = fpImmGetContext( hwnd );
    03462             if ( (pInputContext = fpImmLockIMC( hImc )) != NULL ) {
    03463                 pInputContext->fdw31Compat &= ~F31COMPAT_ECSETCFS;
    03464                 fpImmUnlockIMC( hImc );
    03465             }
    03466             if (GetClientInfo()->CI_flags & CI_16BIT) {
    03467                 fpImmNotifyIME(hImc, NI_COMPOSITIONSTR, CPS_CANCEL, 0L);
    03468             }
    03469             fpImmReleaseContext( hwnd, hImc );
    03470         }
    03471         return DefWindowProcWorker(pwnd, message, wParam, lParam, ped->fAnsi);
    03472
    03473     case WM_IME_ENDCOMPOSITION:
    03474         ECInOutReconversionMode(ped, FALSE);
    03475
    03476         if (ped->fReplaceCompChr) {
    03477             ICH ich;
    03478             HDC hdc;
    03479             //
    03480             // we have a DBCS character to be replaced.
    03481             // let's delete it before inserting the new one.
    03482             //
    03483             ich = (ped->fAnsi) ? 2 : 1;
    03484             ped->fReplaceCompChr = FALSE;
    03485             ped->ichMaxSel = min(ped->ichCaret + ich, ped->cch);
    03486             ped->ichMinSel = ped->ichCaret;
    03487             if (ped->fSingle) {
    03488                 if (ECDeleteText( ped ) > 0) {
    03489                     //
    03490                     // Update the display
    03491                     //
    03492                     ECNotifyParent(ped, EN_UPDATE);
    03493                     hdc = ECGetEditDC(ped, FALSE);
    03494                     SLDrawText(ped, hdc, 0);
    03495                     ECReleaseEditDC(ped, hdc, FALSE);
    03496                     //
    03497                     // Tell parent our text contents changed.
    03498                     //
    03499                     ECNotifyParent(ped, EN_CHANGE);
    03500                 }
    03501             }
    03502             else {
    03503                 MLDeleteText(ped);
    03504             }
    03505
    03506             ECSetCaretHandler( ped );
    03507         }
    03508         return DefWindowProcWorker(pwnd, message, wParam, lParam, ped->fAnsi);
    03509
    03510     case WM_IME_STARTCOMPOSITION:
    03511         if ( ped->fInsertCompChr ) {
    03512             //
    03513             // BUG BUG
    03514             //
    03515             // sending WM_IME_xxxCOMPOSITION will let
    03516             // IME draw composition window. IME should
    03517             // not do that since we cleared
    03518             // ISC_SHOWUICOMPOSITIONWINDOW bit when
    03519             // we got WM_IME_SETCONTEXT message.
    03520             //
    03521             // Korean IME should be fixed in the future.
    03522             //
    03523             break;
    03524
    03525         } else {
    03526             return DefWindowProcWorker(pwnd, message, wParam, lParam, ped->fAnsi);
    03527         }
    03528
    03529     // simple composition character support for FE IME.
    03530     case WM_IME_COMPOSITION:
    03531         return ECImeComposition(ped, wParam, lParam);
    03532
    03533     case WM_KILLFOCUS:
    03534         //
    03535         // when focus is removed from the window,
    03536         // composition character should be finalized
    03537         //
    03538         if (ped && fpImmIsIME(THREAD_HKL())) {
    03539             HIMC hImc = fpImmGetContext(hwnd);
    03540
    03541             if (hImc != NULL_HIMC) {
    03542                 if (ped->fReplaceCompChr || (ped->wImeStatus & EIMES_COMPLETECOMPSTRKILLFOCUS)) {
    03543                     // If the composition string to be determined upon kill focus,
    03544                     // do it now.
    03545                     fpImmNotifyIME(hImc, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
    03546                 } else if (ped->fInReconversion) {
    03547                     // If the composition string it not to be determined,
    03548                     // and if we're in reconversion mode, cancel reconversion now.
    03549                     fpImmNotifyIME(hImc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
    03550                 }
    03551
    03552                 // Get out from reconversion mode
    03553                 if (ped->fInReconversion) {
    03554                     ECInOutReconversionMode(ped, FALSE);
    03555                 }
    03556
    03557                 fpImmReleaseContext(hwnd, hImc);
    03558             }
    03559         }
    03560         goto HandleEditMsg;
    03561         break;
    03562
    03563     case WM_SETFOCUS:
    03564         if (ped && !ped->fFocus) {
    03565             HKL hkl = THREAD_HKL();
    03566
    03567             if (fpImmIsIME(hkl)) {
    03568                 HIMC hImc;
    03569
    03570                 hImc = fpImmGetContext(hwnd);
    03571                 if (hImc) {
    03572                     LPINPUTCONTEXT lpImc;
    03573
    03574                     if (ped->wImeStatus & EIMES_CANCELCOMPSTRINFOCUS) {
    03575                         // cancel when in-focus
    03576                         fpImmNotifyIME(hImc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
    03577                     }
    03578
    03579                     ECImmSetCompositionFont(ped);
    03580
    03581                     if ((lpImc = fpImmLockIMC(hImc)) != NULL) {
    03582
    03583                         // We presume the CompForm will reset to CFS_DEFAULT,
    03584                         // when the edit control loses Focus.
    03585                         // IMEWndProc32 will call ImmSetCompositionWindow with
    03586                         // CFS_DEFAULT, when it receive WM_IME_SETCONTEXT.
    03587                         lpImc->fdw31Compat |= F31COMPAT_ECSETCFS;
    03588
    03589                         fpImmUnlockIMC(hImc);
    03590                     }
    03591                     fpImmReleaseContext(hwnd, hImc);
    03592                 }
    03593
    03594                 //
    03595                 // force to set IME composition window when
    03596                 // first getting focus.
    03597                 //
    03598                 ped->ptScreenBounding.x = -1;
    03599                 ped->ptScreenBounding.y = -1;
    03600             }
    03601             ECInitInsert(ped, hkl);
    03602         }
    03603         goto HandleEditMsg;
    03604         break;
    03605
    03606     case WM_IME_REQUEST:
    03607         // simple ImeRequest Handler
    03608         return EcImeRequestHandler(ped, wParam, lParam);
    03609
    03610     case WM_CREATE:
    03611         if (ped)
    03612             ECEnableDisableIME(ped);
    03613         goto HandleEditMsg;
    03614         break;
    03615
    03616     default:
    03617 HandleEditMsg:
    03618         /* (picked up from NT40FE SP3)
    03619          * HACK ALERT: We may receive messages before the PED has been
    03620          * allocated (eg: WM_GETMINMAXINFO is sent before WM_NCCREATE)
    03621          * so we must test ped before dreferencing.
    03622          */
    03623         if (ped != NULL) {
    03624             if (ped->fSingle) {
    03625                 lreturn = SLEditWndProc(hwnd, ped, message, wParam, lParam);
    03626             } else {
    03627                 lreturn = MLEditWndProc(hwnd, ped, message, wParam, lParam);
    03628             }
    03629         }
    03630     }
    03631
    03632     return lreturn;
    03633 }

LRESULT EditWndProcA | ( | HWND | hwnd,
|  | UINT | message,
|  | WPARAM | wParam,
|  | LPARAM | lParam
| ) |

Definition at line 2787 of file editec.c.

References DefWindowProcWorker(), EditWndProcWorker(), FNID_EDIT, FWINDOWMSG, NULL, TRUE, and ValidateHwnd.

Referenced by ClientThreadSetup(), and EditWndProcWorker().

    02792 {
    02793     PWND pwnd;
    02794
    02795     if ((pwnd = ValidateHwnd(hwnd)) == NULL)
    02796         return 0;
    02797
    02798     /*
    02799      * If the control is not interested in this message,
    02800      * pass it to DefWindowProc.
    02801      */
    02802     if (!FWINDOWMSG(message, FNID_EDIT))
    02803         return DefWindowProcWorker(pwnd, message, wParam, lParam, TRUE);
    02804
    02805     return EditWndProcWorker(pwnd, message, wParam, lParam, TRUE);
    02806 }

LRESULT EditWndProcW | ( | HWND | hwnd,
|  | UINT | message,
|  | WPARAM | wParam,
|  | LPARAM | lParam
| ) |

Definition at line 2808 of file editec.c.

References DefWindowProcWorker(), EditWndProcWorker(), FALSE, FNID_EDIT, FWINDOWMSG, NULL, and ValidateHwnd.

Referenced by ClientThreadSetup(), EditWndProcWorker(), and RW_RegisterControls().

    02813 {
    02814     PWND pwnd;
    02815
    02816     if ((pwnd = ValidateHwnd(hwnd)) == NULL)
    02817         return 0;
    02818
    02819     /*
    02820      * If the control is not interested in this message,
    02821      * pass it to DefWindowProc.
    02822      */
    02823     if (!FWINDOWMSG(message, FNID_EDIT)) {
    02824         return DefWindowProcWorker(pwnd, message, wParam, lParam, FALSE);
    02825     }
    02826
    02827     return EditWndProcWorker(pwnd, message, wParam, lParam, FALSE);
    02828 }

LRESULT EditWndProcWorker | ( | PWND | pwnd,
|  | UINT | message,
|  | WPARAM | wParam,
|  | LPARAM | lParam,
|  | DWORD | fAnsi
| ) |

Definition at line 2831 of file editec.c.

References BOOL, tagMSG_TABLE_ENTRY::bThunkMessage, CsSendMessage, ED, EditLookaside, EditWndProc(), EditWndProcA(), EditWndProcW(), FALSE, tagED::fAnsi, tagED::fInitialized, FNID_CALLWINDOWPROC, FNID_EDIT, HWq, INITCONTROLLOOKASIDE, MessageTable, PEDITWND, TestWF, TRUE, VALIDATECLASSANDSIZE, and WFANSICREATOR.

Referenced by ClientThreadSetup(), EditWndProcA(), and EditWndProcW().

    02837 {
    02838     PED ped;
    02839     HWND hwnd = HWq(pwnd);
    02840     static BOOL fInit = TRUE;
    02841
    02842     VALIDATECLASSANDSIZE(pwnd, FNID_EDIT);
    02843     INITCONTROLLOOKASIDE(&EditLookaside, ED, pwnd, 4);
    02844
    02845     /*
    02846      * Get the ped for the given window now since we will use it a lot in
    02847      * various handlers. This was stored using SetWindowLong(hwnd,0,hped) when
    02848      * we initially created the edit control.
    02849      */
    02850     ped = ((PEDITWND)pwnd)->ped;
    02851
    02852     /*
    02853      * Make sure the ANSI flag is set correctly.
    02854      */
    02855     if (!ped->fInitialized) {
    02856         ped->fInitialized = TRUE;
    02857         ped->fAnsi = TestWF(pwnd, WFANSICREATOR) ? TRUE : FALSE;
    02858     }
    02859
    02860     /*
    02861      * We just call the regular EditWndProc if the ped is not created, the
    02862      * incoming message type already matches the PED type or the message
    02863      * does not need any translation.
    02864      */
    02865     if (ped->fAnsi == fAnsi ||
    02866             (message >= WM_USER) ||
    02867             !MessageTable[message].bThunkMessage) {
    02868         return EditWndProc(pwnd, message, wParam, lParam);
    02869     }
    02870
    02871     return CsSendMessage(hwnd, message, wParam, lParam,
    02872                          fAnsi ? (ULONG_PTR)EditWndProcW : (ULONG_PTR)EditWndProcA,
    02873                          FNID_CALLWINDOWPROC, fAnsi);
    02874 }

UINT GetActualNegA | ( | HDC | hdc,
|  | PED | ped,
|  | int | x,
|  | LPSTR | lpstring,
|  | ICH | ichString,
|  | int | nCount,
|  | LPSTRIPINFO | NegAInfo
| ) |

Definition at line 117 of file editec.c.

References tagED::aveCharWidth, CHAR_WIDTH_BUFFER_LENGTH, tagED::charOverhang, tagED::charWidthBuffer, tagED::fAnsi, tagED::fTrueType, LPSTRIPINFO, min, UINT, and tagED::wMaxNegAcharPos.

Referenced by ECTabTheTextOut().

    00125 {
    00126     int iCharCount, i;
    00127     int iLeftmostPoint = x;
    00128     PABC  pABCwidthBuff;
    00129     UINT  wCharIndex;
    00130     int xStartPoint = x;
    00131     ABC abc;
    00132
    00133     // To begin with, let us assume that there is no negative A width for
    00134     // this strip and initialize accodingly.
    00135
    00136     NegAInfo->XStartPos = x;
    00137     NegAInfo->lpString = lpstring;
    00138     NegAInfo->nCount  = 0;
    00139     NegAInfo->ichString = ichString;
    00140
    00141     // If the current font is not a TrueType font, then there can not be any
    00142     // negative A widths.
    00143     if (!ped->fTrueType) {
    00144         if(!ped->charOverhang) {
    00145             return 0;
    00146         } else {
    00147             NegAInfo->nCount = min(nCount, (int)ped->wMaxNegAcharPos);
    00148             return ped->charOverhang;
    00149         }
    00150     }
    00151
    00152     // How many characters are to be considered for computing Negative A ?
    00153     iCharCount = min(nCount, (int)ped->wMaxNegAcharPos);
    00154
    00155     // Do we have the info on individual character's widths?
    00156     if(!ped->charWidthBuffer) {
    00157         // No! So, let us tell them to consider all the characters.
    00158         NegAInfo->nCount = iCharCount;
    00159         return(iCharCount * ped->aveCharWidth);
    00160     }
    00161
    00162     pABCwidthBuff = (PABC) ped->charWidthBuffer;
    00163
    00164     if (ped->fAnsi) {
    00165         for (i = 0; i < iCharCount; i++) {
    00166             wCharIndex = (UINT)(*((unsigned char *)lpstring));
    00167             if (*lpstring == VK_TAB) {
    00168                 // To play it safe, we assume that this tab results in a tab length of
    00169                 // 1 pixel because this is the minimum possible tab length.
    00170                 x++;
    00171             } else {
    00172                 if ( wCharIndex < CHAR_WIDTH_BUFFER_LENGTH )
    00173                     x += pABCwidthBuff[wCharIndex].abcA;  // Add the 'A' width.
    00174                 else {
    00175                     GetCharABCWidthsA(hdc, wCharIndex, wCharIndex, &abc) ;
    00176                     x += abc.abcA;
    00177                 }
    00178
    00179                 if (x < iLeftmostPoint)
    00180                     iLeftmostPoint = x;             // Reset the leftmost point.
    00181                 if (x < xStartPoint)
    00182                     NegAInfo->nCount = i+1;   // 'i' is index; To get the count add 1.
    00183
    00184                 if ( wCharIndex < CHAR_WIDTH_BUFFER_LENGTH ) {
    00185                     x += pABCwidthBuff[wCharIndex].abcB + pABCwidthBuff[wCharIndex].abcC;
    00186                 } else {
    00187                     x += abc.abcB + abc.abcC;
    00188                 }
    00189             }
    00190
    00191             lpstring++;
    00192         }
    00193     } else {   // Unicode
    00194         LPWSTR lpwstring = (LPWSTR) lpstring ;
    00195
    00196         for (i = 0; i < iCharCount; i++) {
    00197             wCharIndex = *lpwstring ;
    00198             if (*lpwstring == VK_TAB) {
    00199                 // To play it safe, we assume that this tab results in a tab length of
    00200                 // 1 pixel because this is the minimum possible tab length.
    00201                 x++;
    00202             } else {
    00203                 if ( wCharIndex < CHAR_WIDTH_BUFFER_LENGTH )
    00204                     x += pABCwidthBuff[wCharIndex].abcA;  // Add the 'A' width.
    00205                 else {
    00206                     GetCharABCWidthsW(hdc, wCharIndex, wCharIndex, &abc) ;
    00207                     x += abc.abcA ;
    00208                 }
    00209
    00210                 if (x < iLeftmostPoint)
    00211                     iLeftmostPoint = x;             // Reset the leftmost point.
    00212                 if (x < xStartPoint)
    00213                     NegAInfo->nCount = i+1;   // 'i' is index; To get the count add 1.
    00214
    00215                 if ( wCharIndex < CHAR_WIDTH_BUFFER_LENGTH )
    00216                     x += pABCwidthBuff[wCharIndex].abcB +
    00217                          pABCwidthBuff[wCharIndex].abcC;
    00218                 else
    00219                     x += abc.abcB + abc.abcC ;
    00220             }
    00221
    00222             lpwstring++;
    00223         }
    00224     }
    00225
    00226     // Let us return the negative A for the whole strip as a positive value.
    00227     return((UINT)(xStartPoint - iLeftmostPoint));
    00228 }

void NextWordCallBack | ( | PED | ped,
|  | ICH | ichStart,
|  | BOOL | fLeft,
|  | ICH * | pichMin,
|  | ICH * | pichMax
| ) |

Definition at line 1446 of file editec.c.

References BOOL, CALLWORDBREAKPROC, tagED::cch, ECLock(), ECUnlock(), tagED::fAnsi, ICH, tagED::lpfnNextWord, and min.

Referenced by ECWord().

    01452 {
    01453     ICH ichMinSel;
    01454     ICH ichMaxSel;
    01455     LPSTR pText;
    01456
    01457     pText = ECLock(ped);
    01458
    01459     if (fLeft || (!(BOOL)CALLWORDBREAKPROC(ped->lpfnNextWord, (LPSTR)pText,
    01460             ichStart, ped->cch, WB_ISDELIMITER) &&
    01461             (ped->fAnsi ? (*(pText + ichStart) != VK_RETURN) : (*((LPWSTR)pText + ichStart) != VK_RETURN))
    01462         ))
    01463         ichMinSel = CALLWORDBREAKPROC(*ped->lpfnNextWord, (LPSTR)pText, ichStart, ped->cch, WB_LEFT);
    01464     else
    01465         ichMinSel = CALLWORDBREAKPROC(*ped->lpfnNextWord, (LPSTR)pText, ichStart, ped->cch, WB_RIGHT);
    01466
    01467     ichMaxSel = min(ichMinSel + 1, ped->cch);
    01468
    01469     if (ped->fAnsi) {
    01470         if (*(pText + ichMinSel) == VK_RETURN) {
    01471             if (ichMinSel > 0 && *(pText + ichMinSel - 1) == VK_RETURN) {
    01472
    01473                 /*
    01474                  * So that we can treat CRCRLF as one word also.
    01475                  */
    01476                 ichMinSel--;
    01477             } else if (*(pText+ichMinSel + 1) == VK_RETURN) {
    01478
    01479                 /*
    01480                  * Move MaxSel on to the LF
    01481                  */
    01482                 ichMaxSel++;
    01483             }
    01484         }
    01485     } else {
    01486         if (*((LPWSTR)pText + ichMinSel) == VK_RETURN) {
    01487             if (ichMinSel > 0 && *((LPWSTR)pText + ichMinSel - 1) == VK_RETURN) {
    01488
    01489                 /*
    01490                  * So that we can treat CRCRLF as one word also.
    01491                  */
    01492                 ichMinSel--;
    01493             } else if (*((LPWSTR)pText+ichMinSel + 1) == VK_RETURN) {
    01494
    01495                 /*
    01496                  * Move MaxSel on to the LF
    01497                  */
    01498                 ichMaxSel++;
    01499             }
    01500         }
    01501     }
    01502     ichMaxSel = CALLWORDBREAKPROC(ped->lpfnNextWord, (LPSTR)pText, ichMaxSel, ped->cch, WB_RIGHT);
    01503     ECUnlock(ped);
    01504
    01505     if (pichMin)  *pichMin = ichMinSel;
    01506     if (pichMax)  *pichMax = ichMaxSel;
    01507 }

void NextWordLpkCallBack | ( | PED | ped,
|  | ICH | ichStart,
|  | BOOL | fLeft,
|  | ICH * | pichMin,
|  | ICH * | pichMax
| ) |

Definition at line 1518 of file editec.c.

References ECGetEditDC(), ECLock(), ECReleaseEditDC(), ECUnlock(), tagLPKEDITCALLOUT::EditNextWord, tagED::pLpkEditCallout, and TRUE.

Referenced by ECWord().

    01524 {
    01525     PSTR pText = ECLock(ped);
    01526     HDC  hdc   = ECGetEditDC(ped, TRUE);
    01527
    01528     ped->pLpkEditCallout->EditNextWord(ped, hdc, pText, ichStart, fLeft, pichMin, pichMax);
    01529
    01530     ECReleaseEditDC(ped, hdc, TRUE);
    01531     ECUnlock(ped);
    01532 }

UINT WINAPI QueryFontAssocStatus | ( | void |  | ) |

| Referenced by ECGetDBCSVector().

## Variable Documentation

LOOKASIDE EditLookaside

| Definition at line 17 of file editec.c. Referenced by ECNcCreate(), ECNcDestroyHandler(), and EditWndProcWorker().

UINT fFontAssocStatus = 0xffff

| Definition at line 3810 of file editec.c. Referenced by ECGetDBCSVector().