📄 mledit.c
字号:
int x,y; PMLEditData pEditData; pEditData = (PMLEditData)pWin->dwData; if(!pEditData) return false; x = pEditData->iCaretXPos; y = pEditData->iCaretYPos; *px = x * pEditData->iCharWidth + pEditData->iLeftMargin; *py = y * pEditData->iLineHeight + pEditData->iTopMargin; return true;}//Calculate edit position according caret positonstatic BOOLedtSetEditPos( HWND hWnd){ char* pEditString; PMLEditData pEditData; PLineData pLineData; int iStartPos; PWindowsTree pWin; pWin = (PWindowsTree)hWnd; pEditData = (PMLEditData)pWin->dwData; if(!pEditData) return false; if(!edtGetBoxTopLineInfo(pEditData,&pLineData,&iStartPos)) return false; if(!pLineData) return false; if(!edtGetStrPointerByLineNumber(&pLineData, pEditData->iDispPos + pEditData->iCaretYPos, &pEditString)) return false; pEditData->pEditPos = pEditString + pEditData->iCaretXPos; //pEditString pointer to the begin of edit string return true;}static BOOLedtGetStrPointerByLineNumber( PLineData* ppLineData, int iLineNumber, char** ppString //return the string pointer ){ int iSubValue; PLineData pLineData; pLineData = *ppLineData; while(iLineNumber > pLineData->iLineNumber + pLineData->iWrapLineNumber){ pLineData = pLineData->pNext; if(!pLineData) return false; } iSubValue = iLineNumber - pLineData->iLineNumber; if(iSubValue == 0){//Should begin from start position of this string *ppString = pLineData->pString; } else *ppString = pLineData->pString + pLineData->WrapStartPos[iSubValue - 1]; return true; } static BOOLedtGetValidRect( HWND hWnd, LPRECT lpRect){ PWindowsTree pWin; pWin = (PWindowsTree)hWnd; if(!pWin) return false; GetClientRect(hWnd,lpRect); lpRect->left += MLEDIT_LEFTMARGIN; lpRect->right -= MLEDIT_RIGHTMARGIN; lpRect->top += MLEDIT_TOPMARGIN; lpRect->bottom -= MLEDIT_BOTTOMMARGIN; return true;}static BOOLedtIsACChar( char* pString){ if(!*pString) return false; if(!*(pString+1)) return false; if(((unsigned char)*pString > 0xA0) && ((unsigned char)*(pString+1) > 0xA0)) return true; return false; }static BOOLedtIsACCharBeforePos( char* pBuffer){ //if(!*pBuffer) // return false; if(((unsigned char)*(pBuffer-1) > 0xA0) && ((unsigned char)*(pBuffer-2) > 0xA0)) return true; return false;}static BOOLedtIsCarry( char* pString){ if(((unsigned char)*pString == '\n') || ((unsigned char)*pString == '\r')) return true; else return false;}static BOOLedtIsFocus( HWND hWnd){ PMLEditData pEditData; PWindowsTree pWin; pWin = (PWindowsTree)hWnd; pEditData = (PMLEditData)pWin->dwData; if(!pEditData) return false; if(pEditData->dwStatus & EST_FOCUSED) return true; return false;}static BOOLedtIsVScroll( HWND hWnd){ PWindowsTree pWin; pWin = (PWindowsTree)hWnd; if(pWin->dwStyle & WS_VSCROLL) return true; else return false;}static BOOLedtIsReadOnly( HWND hWnd){ PMLEditData pEditData; PWindowsTree pWin; pWin = (PWindowsTree)hWnd; pEditData = (PMLEditData)pWin->dwData; if(!pEditData) return false; if(pEditData->dwStatus & EST_READONLY) return true; return false;}static BOOLedtIsReplace( HWND hWnd){ PMLEditData pEditData; PWindowsTree pWin; pWin = (PWindowsTree)hWnd; pEditData = (PMLEditData)pWin->dwData; if(!pEditData) return false; if(pEditData->dwStatus & EST_REPLACE) return true; return false;}//get pLineData by edit positionstatic BOOLedtGetCurLineData( PMLEditData pEditData, PLineData* ppLineData){ PLineData pLineData; if(!pEditData) return false; pLineData = pEditData->pDispPointer; while(pLineData){ if(pLineData->iLineNumber + pLineData->iWrapLineNumber >= pEditData->iDispPos + pEditData->iCaretYPos) break; pLineData = pLineData->pNext; } *ppLineData = pLineData; return true;}//whether caret at begin position of pLineData->pStringstatic BOOL edtIsCaretAtLineBegin( PMLEditData pEditData){ PLineData pLineData; pLineData = pEditData->pDispPointer; while(pLineData){ if(pLineData->iLineNumber + pLineData->iWrapLineNumber >= pEditData->iDispPos + pEditData->iCaretYPos) break; pLineData = pLineData->pNext; } if(pEditData->pEditPos == pLineData->pString) return true; return false;}//whether caret at end position of pLineData->pStringstatic BOOLedtIsCaretAtLineEnd( PMLEditData pEditData){ PLineData pLineData; pLineData = pEditData->pDispPointer; while(pLineData){ if(pLineData->iLineNumber + pLineData->iWrapLineNumber >= pEditData->iDispPos + pEditData->iCaretYPos) break; pLineData = pLineData->pNext; } if(pEditData->pEditPos == pLineData->pString + strlen(pLineData->pString)) return true; return false;}//recalculate pCurLineData line wrap position//and recode the line numberstatic BOOLedtReIndexDataAfterInsLine( PMLEditData pEditData, PLineData pCurLineData){ PLineData pLineData; int iChars, iWrapLines, iPos, iLineNumber; char* pLine; int iIncrement; //get previous line data pLineData = pCurLineData->pPrev; if(!pLineData){ iLineNumber = 0; pEditData->pDispPointer = pCurLineData; } else{ iLineNumber = pLineData->iLineNumber + pLineData->iWrapLineNumber + 1; } pCurLineData->iLineNumber = iLineNumber; //recalculate pCurLinedata line wrap position pLine = pCurLineData->pString; iChars = 0; iWrapLines = 0; iPos = 0; while(*pLine){ if(edtIsACChar(pLine)){ iChars += 2; if(iChars > pEditData->iDispChars){ pLineData->WrapStartPos[iWrapLines] = iPos; iWrapLines ++; iChars = 2; } iPos += 2; pLine += 2; } else { iChars += 1; if(iChars > pEditData->iDispChars){ pLineData->WrapStartPos[iWrapLines] = iPos; iWrapLines ++; iChars = 1; } iPos += 1; pLine += 1; } } pCurLineData->iWrapLineNumber = iWrapLines; iIncrement = iWrapLines + 1; //recode following pLineData line number pLineData = pCurLineData->pNext; while(pLineData){ pLineData->iLineNumber += iIncrement; pLineData = pLineData->pNext; } pEditData->iTotalLines += iIncrement; pEditData->iTotalLen += strlen(pCurLineData->pString); return true;}static BOOLedtInsLineDataAfter( PMLEditData pEditData, PLineData pCurLineData){ PLineData pLineData; if(!pEditData) return false; if(!pCurLineData) return false; pLineData = (PLineData)malloc(sizeof(LineData)); if(!pLineData) return false; memset(pLineData,0,sizeof(LineData)); if(pCurLineData->pNext){ pCurLineData->pNext->pPrev = pLineData; pLineData->pPrev = pCurLineData; pLineData->pNext = pCurLineData->pNext; pCurLineData->pNext = pLineData; } else{ pCurLineData->pNext = pLineData; pLineData->pPrev = pCurLineData; pEditData->pTail = pLineData; } edtReIndexDataAfterInsLine(pEditData, pLineData); return true;}static BOOLedtInsLineDataBefore( PMLEditData pEditData, PLineData pCurLineData){ PLineData pLineData; if(!pEditData) return false; if(!pCurLineData) return false; pLineData = (PLineData)malloc(sizeof(LineData)); if(!pLineData) return false; memset(pLineData,0,sizeof(LineData)); if(pCurLineData->pPrev){ pCurLineData->pPrev->pNext = pLineData; pLineData->pPrev = pCurLineData->pPrev; pCurLineData->pPrev = pLineData; pLineData->pNext = pCurLineData; } else{//first line data of pEditData pLineData->pNext = pCurLineData; pCurLineData->pPrev = pLineData; pEditData->pHead = pLineData; } edtReIndexDataAfterInsLine(pEditData, pLineData); return true;}//recalculate pCurLineData line wrap position//and recode the line numberstatic BOOLedtReIndexDataAfterBreak( PMLEditData pEditData, PLineData pCurLineData){ PLineData pLineData; int iChars, iWrapLines, iPos; char* pLine; int iIncrement; int i; //recalculate pCurLinedata line wrap position iIncrement = (-1) * (pCurLineData->iWrapLineNumber + 1); //this field not updated when this function called for(i=0; i<2; i++){ pLine = pCurLineData->pString; iChars = 0; iWrapLines = 0; iPos = 0; while(*pLine){ if(edtIsACChar(pLine)){ iChars += 2; if(iChars > pEditData->iDispChars){ pCurLineData->WrapStartPos[iWrapLines] = iPos; iWrapLines ++; iChars = 2; } iPos += 2; pLine += 2; } else { iChars += 1; if(iChars > pEditData->iDispChars){ pCurLineData->WrapStartPos[iWrapLines] = iPos; iWrapLines ++; iChars = 1; } iPos += 1; pLine += 1; } } pCurLineData->iWrapLineNumber = iWrapLines; iIncrement += iWrapLines + 1; if(i == 1){ pCurLineData->iLineNumber = pCurLineData->pPrev->iLineNumber + pCurLineData->pPrev->iWrapLineNumber + 1; break; } pCurLineData = pCurLineData->pNext; } //recode following pLineData line number pLineData = pCurLineData->pNext; while(pLineData){ pLineData->iLineNumber += iIncrement; pLineData = pLineData->pNext; } pEditData->iTotalLines += iIncrement; return true;}static BOOLedtBreakLineAtCurPos( PMLEditData pEditData, PLineData pCurLineData){ PLineData pLineData; if(!pEditData) return false; pLineData = (PLineData)malloc(sizeof(LineData)); if(!pLineData) return false; memset(pLineData, 0, sizeof(LineData)); strcpy(pLineData->pString, pEditData->pEditPos); *(pEditData->pEditPos) = '\0'; if(pCurLineData->pNext){ pCurLineData->pNext->pPrev = pLineData; pLineData->pPrev = pCurLineData; pLineData->pNext = pCurLineData->pNext; pCurLineData->pNext = pLineData; } else{ pLineData->pNext = NULL; pLineData->pPrev = pCurLineData; pCurLineData->pNext = pLineData; } edtReIndexDataAfterBreak(pEditData,pCurLineData); return true;}//////////////////////////////////////////////////////////////////////////////Key Down/////////////////////////////////////////////////////////////////////////////==================== ENTER ========================static BOOLedtScanCodeEnter( HWND hWnd){ int iWinHeight, iWinWidth; RECT rtInvalid; PMLEditData pEditData; PLineData pCurLineData; int x, y; PWindowsTree pWin; pWin = (PWindowsTree)hWnd; BOOL bScroll = false; if(edtIsReadOnly(hWnd)) return true; pEditData = (PMLEditData)pWin->dwData; if(!pEditData) return false; //in replace mode if(edtIsReplace(hWnd)){ if(pEditData->iCaretYPos + 1 == pEditData->iDispLines){ //caret at the bottom of the edit box if(pEditData->iDispPos + pEditData->iDispLines == pEditData->iTotalLines) return true; else{ pEditData->iCaretXPos = 0; pEditData->iDispPos += 1; bScroll = true; } } else{//caret not at the bottom of the edit box //move caret to the begin of next line pEditData->iCaretXPos = 0; pEditData->iCaretYPos ++; } if(bScroll){ edtReCalTopLine(hWnd); edtSetVScrollInfo(hWnd, pEditData, true); InvalidateRect(hWnd,NULL,true); } edtSetEditPos(hWnd); edtCalCaretPos(hWnd,&x,&y); SetCaretPos(hWnd,x,y); return true; } //in insert mode //Get current line data if(!edtGetCurLineData(pEditData, &pCurLineData)) return false; //caret position is an important reference value if(edtIsCaretAtLineEnd(pEditData)){ //insert a new line after current position edtInsLineDataAfter(pEditData, pCurLineData); } else if(edtIsCaretAtLineBegin(pEditData)){ //insert a new line before current position edtInsLineDataBefore(pEditData, pCurLineData); } else{ //break the current line into two lines at current position edtBreakLineAtCurPos(pEditData,pCurLineData); } edtSetVScrollInfo(hWnd, pEditData, true);// if(pEditData->iCaretYPos == 0){// pEditData->pDispPointer == pCurLineData; if(pEditData->iCaretYPos + 1 == pEditData->iDispLines){ pEditData->iCaretXPos = 0; pEditData->iDispPos += 1; //bScroll = true; edtReCalTopLine(hWnd); InvalidateRect(hWnd,NULL,true); } else{//caret not at the bottom of the edit box //move caret to the begin of next line GetWindowRect(hWnd,&rtInvalid); iWinHeight = rtInvalid.bottom - rtInvalid.top + 1; iWinWidth = rtInvalid.right - rtInvalid.left + 1; rtInvalid.top = 0; rtInvalid.left = 0; rtInvalid.right = iWinWidth - 1; rtInvalid.bottom = iWinHeight - 1; rtInvalid.top += (pEditData->iCaretYPos * pEditData->iLineHeight); pEditData->iCaretXPos = 0; pEditData->iCaretYPos ++; InvalidateRect(hWnd,&rtInvalid,true); } edtSetEditPos(hWnd); edtCalCaretPos(hWnd,&x,&y); SetCaretPos(hWnd,x,y); NotifyParent(hWnd,EN_CHANGE); return true;}//==================== HOME ========================static BOOLedtScanCodeHome( HWND hWnd){ PMLEditData pEditData; int x, y; PWindowsTree pWin; pWin = (PWindowsTree)hWnd; //move caret and edit position to the begin of this line pEditData = (PMLEditData)pWin->dwData; if(!pEditData) return false; pEditData->iCaretXPos = 0; edtSetEditPos(hWnd); edtCalCaretPos(hWnd,&x,&y); SetCaretPos(hWnd,x,y); return true;}//==================== END ========================static BOOL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -