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,
 )     ((unsigned)(a) > (unsigned)(b) ? (unsigned)(a) : (unsigned)(b))
 

Definition at line 23 of file editec.c.

Referenced by ECCchInWidth().

#define umin a,
 )     ((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().


Generated on Sat May 15 19:43:31 2004 for test by doxygen 1.3.7