📄 mledit.c
字号:
edtPenDown(hWnd,x,y); break; } case LMSG_PENUP: break; case LMSG_PENMOVE: break; case LMSG_KEYDOWN: { switch LOWORD(wParam){ case SCANCODE_ENTER: edtScanCodeEnter(hWnd); break; case SCANCODE_HOME: edtScanCodeHome(hWnd); break; case SCANCODE_END: edtScanCodeEnd(hWnd); break; case SCANCODE_LEFT: edtScanCodeLeft(hWnd); break; case SCANCODE_RIGHT: edtScanCodeRight(hWnd); break; case SCANCODE_UP: edtScanCodeUp(hWnd); break; case SCANCODE_DOWN: edtScanCodeDown(hWnd); break; case SCANCODE_INS: edtScanCodeIns(hWnd); break; case SCANCODE_DEL: edtScanCodeDel(hWnd); break; case SCANCODE_BACKSPACE: edtScanCodeBackSpace(hWnd); break; case SCANCODE_PAGEUP: edtScanCodePageUp(hWnd); break; case SCANCODE_PAGEDOWN: edtScanCodePageDown(hWnd); break; default: break; } return 0; } case LMSG_CHAR: { int chars; char charBuffer[3]; if(edtIsReadOnly(hWnd)) return true; if (HIBYTE (wParam)) { charBuffer [0] = LOBYTE (wParam); charBuffer [1] = HIBYTE (wParam); chars = 2; } else{ charBuffer [0] = LOBYTE (wParam); chars = 1; } if (chars == 1) { switch (charBuffer [0]) { case 0x00: // NULL case 0x07: // BEL case 0x08: // BS case 0x09: // HT case 0x0A: // LF case 0x0B: // VT case 0x0C: // FF case 0x0D: // CR case 0x1B: // Escape return 0; } } edtProChar(hWnd, charBuffer, chars); break; } //scroll event case LMSG_VSCROLL: { int x,y; PMLEditData pEditData; int iLineNumber, iStartPos; PLineData pLineData; char pDispString[LEN_MLEDIT_LINEBUFFER]; pEditData = (PMLEditData)(pWin->dwData); switch((int)wParam){ case SB_LINEUP: pEditData->iDispPos -= 1; break; case SB_LINEDOWN: pEditData->iDispPos += 1; break; case SB_THUMBTRACK: pEditData->iDispPos = pWin->pVScroll->nPos; break; } edtReCalTopLine(hWnd); //caret position#if 0 if(!edtGetBoxTopLineInfo(pEditData, &pLineData, &iStartPos)) return false; iLineNumber = pEditData->iDispPos + pEditData->iCaretYPos; if(!edtGetDispString(&pLineData,iLineNumber, pDispString)) return false; pEditData->iCaretXPos = strlen(pDispString);#endif if(!edtReCalCaretXPos(pEditData, pEditData->iCaretYPos, &x)) return false; pEditData->iCaretXPos = x; edtSetEditPos(hWnd); edtCalCaretPos(hWnd,&x,&y); SetCaretPos(hWnd,x,y); winInvalidateRect(hWnd,NULL,true); break; } default: return DefWindowProc(hWnd, iMsg, wParam, lParam); } return 0;}static BOOLedtGetBoxTopLineInfo( PMLEditData pEditData, PLineData* ppRetLineData, int* pStartPos);//Get display string by line numberstatic BOOLedtGetDispString( PLineData* ppLineData, int iLineNumber, char* pStrDisp);static BOOLedtInitFixData( HWND hWnd){ PMLEditData pEditData; RECT rect; PWindowsTree pWin; pWin = (PWindowsTree)hWnd; pEditData = (PMLEditData)(pWin->dwData); pEditData->iBufferLimit = LEN_MLEDIT_LINEBUFFER; pEditData->iLeftMargin = MLEDIT_LEFTMARGIN; pEditData->iTopMargin = MLEDIT_TOPMARGIN; pEditData->iRightMargin = MLEDIT_RIGHTMARGIN; pEditData->iBottomMargin = MLEDIT_BOTTOMMARGIN; pEditData->iCharSpace = MLEDIT_CHARSPACE; pEditData->iLineSpace = MLEDIT_LINESPACE; pEditData->iLineHeight = GetSysCharHeight() + pEditData->iLineSpace; pEditData->iCharWidth = GetSysCharWidth() + pEditData->iCharSpace; //Get lines and chars per line which can be displayed in the current box. edtGetValidRect(hWnd,&rect); pEditData->iDispLines = (rect.bottom - rect.top + 1)/pEditData->iLineHeight; pEditData->iDispChars = (rect.right - rect.left + 1)/pEditData->iCharWidth; return true;}//called by init box data function to get a line from init stringstatic BOOLedtGetALineFromString( char* lpString, char* pLine){ int iLen; char* pString; pString = lpString; while(*pString){ if(edtIsCarry(pString)) break; pString ++ ; } iLen = (int)pString - (int)lpString; iLen = min(iLen, LEN_MLEDIT_LINEBUFFER); strncpy(pLine,lpString,iLen); pLine[iLen] = '\0'; return true;}//set init string to the editboxstatic BOOLedtInitVarData( HWND hWnd, char* lpString){ int iLineNumber,iChars,iWrapLines,iPos; PLineData pLineData; PMLEditData pEditData; char *pString,*pLine; int iTotalLen,iTotalLines; char strLine[LEN_MLEDIT_LINEBUFFER]; PWindowsTree pWin; pWin = (PWindowsTree)hWnd; pEditData = (PMLEditData)(pWin->dwData); // initialize an empty multiline edit box. if(!lpString){ pLineData = (PLineData)malloc(sizeof(LineData)); if(!pLineData) return false; memset(pLineData,0,sizeof(LineData)); pEditData->pHead = pEditData->pTail = pLineData; pEditData->iTotalLines = 1; pEditData->pDispPointer = pLineData; pEditData->pEditPos = pLineData->pString; return true; } pString = lpString; iLineNumber = 0; iWrapLines = -1; iTotalLen = iTotalLines = 0; while(*pString){ edtGetALineFromString(pString, strLine); pLineData = (PLineData)malloc(sizeof(LineData)); if(!pLineData) return false; memset(pLineData,0,sizeof(LineData)); strcpy(pLineData->pString,strLine); iLineNumber += iWrapLines + 1; pLineData->iLineNumber = iLineNumber; pLine = strLine; 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; } } pLineData->iWrapLineNumber = iWrapLines; iTotalLines += iWrapLines + 1; iTotalLen += strlen(strLine); //insert into pEditData structure if(pEditData->pHead){ pEditData->pTail->pNext = pLineData; pLineData->pPrev = pEditData->pTail; pEditData->pTail = pLineData; } else pEditData->pHead = pEditData->pTail = pLineData; pString += strlen(strLine) + 1; //skip last carry character } pEditData->iTotalLen = iTotalLen; pEditData->iTotalLines = iTotalLines; pEditData->pDispPointer = pEditData->pHead; return true;}//destroy the editbox datastatic BOOLedtDestroyData( HWND hWnd){ PMLEditData pEditData; PLineData pLineData,pNext; PWindowsTree pWin; pWin = (PWindowsTree)hWnd; if(!pWin) return false; pEditData = (PMLEditData)pWin->dwData; pLineData = pEditData->pHead; while(pLineData){ pNext = pLineData->pNext; free(pLineData); pLineData = pNext; } free(pEditData); return true;}static BOOLedtGetText( HWND hWnd, int iLimitLen, char* buffer){ PWindowsTree pWin; PMLEditData pEditData; PLineData pLineData; char *pointer,*pCurLine; int iCurTotalLen,iStrLen,iCharWidth; pWin = (PWindowsTree)hWnd; pEditData = (PMLEditData)(pWin->dwData); if(!pEditData){ *buffer = '\0'; return false; } pointer = buffer; pLineData = pEditData->pHead; iCurTotalLen = 0; while(pLineData){ iStrLen = strlen(pLineData->pString); if((iCurTotalLen + iStrLen) < iLimitLen){ memcpy(pointer,pLineData->pString,iStrLen); } else{ pCurLine = pLineData->pString; while(pCurLine){ if(edtIsACChar(pCurLine)) iCharWidth = 2; else iCharWidth = 1; if((iCurTotalLen + iCharWidth) > iLimitLen){ //buffer[iCurTotalLen] = '\0'; break; } memcpy(pointer,pCurLine,iCharWidth); pointer += iCharWidth; pCurLine += iCharWidth; iCurTotalLen += iCharWidth; } break; } iCurTotalLen += iStrLen; if(pLineData->pNext){ buffer[iCurTotalLen] = '\n'; iCurTotalLen += 1; pointer += iStrLen + 1; } pLineData = pLineData->pNext; } buffer[iCurTotalLen] = '\0'; return true;}static BOOLedtPenDown( HWND hWnd, int xPos, int yPos){ PMLEditData pEditData; PLineData pLineData; char pDispString[LEN_MLEDIT_LINEBUFFER]; int x, y, iLineHeight, iStartPos, iStrLen, iTotalLen; PWindowsTree pWin; pWin = (PWindowsTree)hWnd; if(!pWin) return false; pEditData = (PMLEditData)pWin->dwData; if(!pEditData) return false; //Set caret and edit position according to the pen down position ScreenToClient(hWnd,&xPos,&yPos); iLineHeight = pEditData->iLineHeight; for(y=0;y<pEditData->iDispLines;y++){ if((y+1)* iLineHeight > yPos) break; } if(y == pEditData->iDispLines) return true; //then y should be the caret Y position //get the string of this line if(!edtGetBoxTopLineInfo(pEditData,&pLineData,&iStartPos)) return false; if(!edtGetDispString(&pLineData,pEditData->iDispPos + y, pDispString)) return false; //calculate the x position iStrLen = strlen(pDispString); iTotalLen = 0; x = 0; while(pDispString[x]){ if(iTotalLen >= xPos) break; if(edtIsACChar(pDispString+x)){ iTotalLen += GetSysCCharWidth(); x += 2; } else{ iTotalLen += GetSysCharWidth(); x++; } } //then x should be the caret x position pEditData->iCaretXPos = x; pEditData->iCaretYPos = y; edtCalCaretPos(hWnd,&x,&y); SetCaretPos(hWnd,x,y); //set edit position according caret position edtSetEditPos(hWnd); return true;}//Draw EditBox Textstatic BOOLedtDrawEditBoxText( HWND hWnd, HDC hDC){ char pDispString[LEN_MLEDIT_LINEBUFFER]; RECT rtBox,rtLine; PMLEditData pEditData; PLineData pLineData; int i; int iWinHeight, iWinWidth; PWindowsTree pWin; pWin = (PWindowsTree)hWnd; pEditData = (PMLEditData)(pWin->dwData); if(!pEditData) return false; edtGetValidRect(hWnd,&rtBox); iWinHeight = rtBox.bottom - rtBox.top + 1; iWinWidth = rtBox.right - rtBox.left + 1; rtBox.top = 0; rtBox.left = 0; rtBox.right = iWinWidth - 1; rtBox.bottom = iWinHeight - 1; if(!edtGetBoxTopLineInfo(pEditData,&pLineData,&i))//i represent inline position, not used return false; for(i = 0; i < pEditData->iDispLines; i++){ //for pLineData may pointer to its subsequence, so pass a pointer to function if(!edtGetDispString(&pLineData,pEditData->iDispPos + i, pDispString)) return false; //Draw the String rtLine.left = rtBox.left; rtLine.right = rtBox.right; rtLine.top = rtBox.top + i * pEditData->iLineHeight; rtLine.bottom = rtLine.top + pEditData->iLineHeight; //DrawText(hDC,pDispString,strlen(pDispString),&rtLine,DT_LEFT|DT_TOP); DrawText(hDC,pDispString,strlen(pDispString),&rtLine,DT_LEFT|DT_TOP); } return true;}//////////////////////////////////////////////////////////////////////////BASE FUNCTION////////////////////////////////////////////////////////////////////////recalculate the top line pointer after scrollstatic BOOLedtReCalTopLine( HWND hWnd){ PMLEditData pEditData; PLineData pLineData; PWindowsTree pWin; pWin = (PWindowsTree)hWnd; pEditData = (PMLEditData)pWin->dwData; if(!pEditData) return false; pLineData = pEditData->pDispPointer; if(pEditData->iDispPos > pLineData->iLineNumber){//after scroll down while(pLineData){ if(pLineData->iLineNumber + pLineData->iWrapLineNumber >= pEditData->iDispPos) break; pLineData = pLineData->pNext; } } else{//after scroll up while(pLineData){ if((pLineData->iLineNumber + pLineData->iWrapLineNumber >= pEditData->iDispPos) && (pLineData->iLineNumber <= pEditData->iDispPos)) break; pLineData = pLineData->pPrev; } } pEditData->pDispPointer = pLineData; return true;}//get line data pointer and start position static BOOLedtGetBoxTopLineInfo( PMLEditData pEditData, PLineData* ppRetLineData, int* pStartPos){ int iDispPos; PLineData pLineData; if(!pEditData) return false; pLineData = pEditData->pDispPointer; if(!pLineData) return false; iDispPos = pEditData->iDispPos; if(pLineData->iLineNumber == iDispPos) *pStartPos = 0; else *pStartPos = pLineData->WrapStartPos[iDispPos - pLineData->iLineNumber]; *ppRetLineData = pLineData; return true;}//Get display string by line numberstatic BOOLedtGetDispString( PLineData* ppLineData, int iLineNumber, char* pStrDisp){ int iStrLen; int iSubValue; int iStrSub; 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 if(pLineData->iWrapLineNumber == 0) iStrLen = strlen(pLineData->pString); else iStrLen = pLineData->WrapStartPos[0]; strncpy(pStrDisp, pLineData->pString, iStrLen); pStrDisp[iStrLen] = '\0'; } else if(iSubValue == pLineData->iWrapLineNumber){ iStrSub = pLineData->WrapStartPos[iSubValue-1]; iStrLen = strlen(pLineData->pString) - pLineData->WrapStartPos[iSubValue-1]; strncpy(pStrDisp,&pLineData->pString[iStrSub],iStrLen); pStrDisp[iStrLen] = '\0'; } else{ iStrLen = pLineData->WrapStartPos[iSubValue] - pLineData->WrapStartPos[iSubValue - 1]; iStrSub = pLineData->WrapStartPos[iSubValue-1]; strncpy(pStrDisp,&pLineData->pString[iStrSub],iStrLen); pStrDisp[iStrLen] = '\0'; } *ppLineData = pLineData; return true;}//Get Client Position of caretstatic BOOLedtCalCaretPos( HWND hWnd, int* px, int* py){ PWindowsTree pWin; pWin = (PWindowsTree)hWnd;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -