memo.c
来自「MinGUI 可视化程序代码」· C语言 代码 · 共 1,029 行 · 第 1/3 页
C
1,029 行
else
{ bNeedScroll=true;
}
MemoGetLineInfo(pMLEditData,curLineIndex-1,&linehead,&linesize,&linewidth);
chars=pMLEditData->editPos-(linehead+linesize);
pMLEditData->editPos = linehead+linesize;
pMLEditData->caretx=pMLEditData->textArea.left+linewidth;
if(bNeedScroll)
{ Invalidate(hWnd);
pMLEditData->pageTopLine--;
pMLEditData->startPos=linehead;
}
}
if(Key==VK_BACK && chars>0)
{ MLEdit_DeleteChars(hWnd,chars,!bNeedScroll);
if(WndGetAttr(hWnd,WS_VSCROLL|WS_BORDER)==(WS_VSCROLL|WS_BORDER))
{ ScrollBar_Synchronize2(hWnd,pMLEditData->pageTopLine,Memo_GetLineCount(hWnd));
}
}
else if(bNeedScroll)
{ if(WndGetAttr(hWnd,WS_VSCROLL|WS_BORDER)==(WS_VSCROLL|WS_BORDER))
ScrollBar_Synchronize(hWnd,pMLEditData->pageTopLine);
}
SetCaretPos(hWnd,pMLEditData->caretx-1,pMLEditData->carety-CARET_HEIGHT_OVERLAP);
}
return;
case VK_RIGHT:
if (!WndGetAttr(hWnd,ES_READONLY))
{ BOOL bScroll=false,newline=false;
if (pMLEditData->editPos == pMLEditData->dataEnd)return;
if(pMLEditData->buffer[pMLEditData->editPos]=='\n' || pMLEditData->buffer[pMLEditData->editPos]=='\r')
{ newline=true;
if(pMLEditData->buffer[pMLEditData->editPos+1]=='\n')
{ if(pMLEditData->buffer[pMLEditData->editPos]=='\r')pMLEditData->editPos++;
}
pMLEditData->editPos++;
}
else
{ int newcx,chars;
chars=(EdtIsACCharAtPosition(pMLEditData->buffer, pMLEditData->editPos))?2:1;
pMLEditData->editPos+=chars;
newcx= pMLEditData->caretx+chars*GetSysCharWidth(hWnd)+pMLEditData->colspace;
if(newcx>pMLEditData->textArea.right)
{ newline=true;
}
else if(pMLEditData->editPos != pMLEditData->dataEnd && pMLEditData->buffer[pMLEditData->editPos]!=0x0A)
{ chars=(EdtIsACCharAtPosition(pMLEditData->buffer,pMLEditData->editPos))?2:1;
if(newcx+chars*GetSysCharWidth(hWnd)>pMLEditData->textArea.right)newline=true;
}
if(!newline) pMLEditData->caretx=newcx;
}
if(newline)
{ pMLEditData->caretx=pMLEditData->textArea.left;
if(pMLEditData->carety+GetSysCharHeight(hWnd)+pMLEditData->rowspace+GetSysCharHeight(hWnd)>pMLEditData->textArea.bottom)
{ bScroll=true;
pMLEditData->pageTopLine++;
ScrollBar_Synchronize(hWnd,pMLEditData->pageTopLine);
MemoGetLineInfo(pMLEditData,pMLEditData->pageTopLine,&pMLEditData->startPos,NULL,NULL);
}
else
{ pMLEditData->carety += (GetSysCharHeight(hWnd)+pMLEditData->rowspace);
}
}
SetCaretPos(hWnd,pMLEditData->caretx-1,pMLEditData->carety-CARET_HEIGHT_OVERLAP);
if (bScroll) Invalidate(hWnd);
}
return;
case VK_UP:
if (!WndGetAttr(hWnd,ES_READONLY))
{ int bScroll=false,curLineIndex,linehead;
curLineIndex=GetLineIndexByCarret(hWnd,pMLEditData);
if(pMLEditData->carety > pMLEditData->textArea.top)
{ pMLEditData->carety-= (GetSysCharHeight(hWnd)+pMLEditData->rowspace);
}
else
{ if(curLineIndex>0)bScroll=true;
else return;
}
MemoGetLineInfo(pMLEditData,curLineIndex-1,&linehead,NULL,NULL);
if(bScroll)
{ Invalidate(hWnd);
pMLEditData->startPos=linehead;
pMLEditData->pageTopLine--;
ScrollBar_Synchronize(hWnd,pMLEditData->pageTopLine);
}
pMLEditData->caretx=pMLEditData->textArea.left;
pMLEditData->editPos=linehead;
SetCaretPos(hWnd,pMLEditData->caretx-1,pMLEditData->carety-CARET_HEIGHT_OVERLAP);
}
else if(pMLEditData->pageTopLine>0)
{ Invalidate(hWnd);
pMLEditData->pageTopLine--;
ScrollBar_Synchronize(hWnd,pMLEditData->pageTopLine);
MemoGetLineInfo(pMLEditData,pMLEditData->pageTopLine,&pMLEditData->startPos,NULL,NULL);
pMLEditData->editPos=pMLEditData->startPos;
pMLEditData->caretx=pMLEditData->textArea.left;
pMLEditData->carety=pMLEditData->textArea.top;
}
return;
case VK_DOWN:
if (!WndGetAttr(hWnd,ES_READONLY))
{ int bScroll=false,curLineIndex,linehead;
curLineIndex=GetLineIndexByCarret(hWnd,pMLEditData);
if(MemoGetLineInfo(pMLEditData,curLineIndex+1,&linehead,NULL,NULL))
{ if(pMLEditData->carety+GetSysCharHeight(hWnd)+GetSysCharHeight(hWnd)+pMLEditData->rowspace>pMLEditData->textArea.bottom)
{ bScroll=true;
Invalidate(hWnd);
pMLEditData->pageTopLine++;
ScrollBar_Synchronize(hWnd,pMLEditData->pageTopLine);
MemoGetLineInfo(pMLEditData,pMLEditData->pageTopLine,&pMLEditData->startPos,NULL,NULL);
}
else
{ pMLEditData->carety+=GetSysCharHeight(hWnd)+pMLEditData->rowspace;
}
pMLEditData->caretx=pMLEditData->textArea.left;
pMLEditData->editPos=linehead;
SetCaretPos(hWnd,pMLEditData->caretx-1,pMLEditData->carety-CARET_HEIGHT_OVERLAP);
}
}
else
{ int newlinepos;
if(MemoGetLineInfo(pMLEditData,pMLEditData->pageTopLine+1,&newlinepos,NULL,NULL))
{ Invalidate(hWnd);
pMLEditData->pageTopLine++;
ScrollBar_Synchronize(hWnd,pMLEditData->pageTopLine);
pMLEditData->editPos=pMLEditData->startPos=newlinepos;
pMLEditData->caretx=pMLEditData->textArea.left;
pMLEditData->carety=pMLEditData->textArea.top;
}
}
return;
case VK_INSERT:
WNDPTR(hWnd)->Style ^= ES_REPLACE;
return;
case VK_DELETE:
if (!WndGetAttr(hWnd,ES_READONLY) && (pMLEditData->editPos != pMLEditData->dataEnd))
{ int deleted=(EdtIsACCharAtPosition(pMLEditData->buffer,pMLEditData->editPos))?2:1;;
MLEdit_DeleteChars(hWnd,deleted,true);
if(WndGetAttr(hWnd,WS_VSCROLL|WS_BORDER)==(WS_VSCROLL|WS_BORDER))
{ ScrollBar_Synchronize2(hWnd,pMLEditData->pageTopLine,Memo_GetLineCount(hWnd));
}
}
return;
}
}
static HRESULT CALLBACK MLEditCtrlProc(HWND hWnd,UINT Message,WPARAM WParam,LPARAM LParam)
{
switch (Message)
{ case WM_CHAR:
if (!WndGetAttr(hWnd,ES_READONLY))
{ BYTE wordlo=LOBYTE(WParam),wordhi=HIBYTE(WParam);
if(wordlo>0xA0 && wordhi==0)
{ BYTE savedchar=(BYTE)IME_PopChar();
if(savedchar>0xA0)
{ MLEdit_GetChar(hWnd,savedchar,wordlo,LParam);
}
else
{ IME_PushChar(wordlo);
}
return 0;
}
if(IME_Window && WNDPTR(IME_Window)->UserData==1)/*中文输入法*/
{ if(SendMessage((HWND)IME_Window,WM_CHAR,WParam,LParam)==0)return 0;
}
MLEdit_GetChar(hWnd,wordlo,wordhi,LParam);
}
return 0;
case WM_COMMAND:
if(LParam==WM_CHAR && !WndGetAttr(hWnd,ES_READONLY))
{ MLEdit_GetChar(hWnd,LOBYTE(WParam),HIBYTE(WParam),0);
}
return 0;
case WM_KEYDOWN:
if(WParam!=VK_TAB)
{ if(IME_Window && WNDPTR(IME_Window)->UserData==1)/*中文输入法*/
{ if(!IME_isEmpty()) return SendMessage((HWND)IME_Window,WM_KEYDOWN,WParam,LParam);
}
MLEdit_GetKeyDown(hWnd,WParam);
return 0;
}
break;
case WM_GETTEXTLENGTH:
{ TMultiEdit *pMLEditData = (TMultiEdit *)WndClsBuf(hWnd);
return pMLEditData->dataEnd;
}
case WM_GETTEXT:
{ char* buffer = (char*)LParam;
int len;
TMultiEdit *pMLEditData =(TMultiEdit *)WndClsBuf(hWnd);
len = min ((int)WParam, pMLEditData->dataEnd);
memcpy (buffer, pMLEditData->buffer, len);
buffer [len] = '\0';
return len;
}
case WM_SETTEXT:
{ int len;
TMultiEdit *pMLEditData = (TMultiEdit *)WndClsBuf(hWnd);
len = strlen ((char*)LParam);
len = min (len, pMLEditData->bufferLen);
if (pMLEditData->hardLimit >= 0)
len = min (len, pMLEditData->hardLimit);
pMLEditData->dataEnd = len;
memcpy (pMLEditData->buffer, (char*)LParam, len);
pMLEditData->buffer[len]='\0';
pMLEditData->editPos = 0;
pMLEditData->caretx=pMLEditData->textArea.left;
pMLEditData->carety=pMLEditData->textArea.top;
SetCaretPos(hWnd, pMLEditData->caretx-1,pMLEditData->carety-CARET_HEIGHT_OVERLAP);
pMLEditData->startPos = 0;
pMLEditData->pageTopLine =0;
Invalidate(hWnd);
if(WndGetAttr(hWnd,WS_VSCROLL|WS_BORDER)==(WS_VSCROLL|WS_BORDER))
{ ScrollBar_Synchronize2(hWnd,0,Memo_GetLineCount(hWnd));
}
}
return 0;
case WM_LBUTTONDOWN:
if (!WndGetAttr(hWnd,ES_READONLY))
{ int xpos=LOWORD(LParam),ypos=HIWORD(LParam);
if(PointInRect(xpos, ypos, &WNDPTR(hWnd)->ClientRect))
{ TMultiEdit *pMLEditData = (TMultiEdit *)WndClsBuf(hWnd);
pMLEditData->editPos=BoxLocateCursor(pMLEditData,xpos-WNDPTR(hWnd)->ClientRect.left,ypos-WNDPTR(hWnd)->ClientRect.top,&pMLEditData->caretx,&pMLEditData->carety,NULL,NULL);
SetCaretPos(hWnd, pMLEditData->caretx-1,pMLEditData->carety-CARET_HEIGHT_OVERLAP);
}
}
break;
case EM_SETREADONLY:
if (WParam)
{ WndAddAttr(hWnd,ES_READONLY);
DestroyCaret(hWnd);
}
else
{ WndSubAttr(hWnd,ES_READONLY);
if(WndGetAttr(hWnd,WS_FOCUS))
{ TMultiEdit *pMLEditData = (TMultiEdit *)WndClsBuf(hWnd);
CreateCaret (hWnd, 1 /*+ GetSysCharWidth(hWnd)*/, pMLEditData->caretheight);
SetCaretPos(hWnd, pMLEditData->caretx-1,pMLEditData->carety-CARET_HEIGHT_OVERLAP);
}
}
return 0;
case EM_LIMITTEXT:
{ int newLimit = (int)WParam;
if (newLimit >= 0)
{ TMultiEdit *pMLEditData = (TMultiEdit *)WndClsBuf(hWnd);
if (newLimit <= pMLEditData->bufferLen)
{ pMLEditData->hardLimit = newLimit;
}
else
{ char *oldtext=(char *)GetMem(pMLEditData->dataEnd);
memcpy(oldtext,pMLEditData->buffer,pMLEditData->dataEnd);
CM_AllocateWindowText(hWnd,oldtext,newLimit);
pMLEditData->bufferLen=newLimit;
pMLEditData->hardLimit = -1;
FreeMem(oldtext);
}
}
}
return 0;
case WM_VSCROLL:
MLEdit_PageScroll(hWnd,(int)WParam);
return 0;
case WM_CREATE:
MLEdit_OnCreate(hWnd);
return 0;
case WM_SETFOCUS:
{ TMultiEdit *pMLEditData=(TMultiEdit *)WndClsBuf(hWnd);
// only implemented for ES_LEFT align format.
if (!WndGetAttr(hWnd,ES_READONLY))
{ CreateCaret (hWnd, 1 /*+ GetSysCharWidth(hWnd)*/, pMLEditData->caretheight);
SetCaretPos (hWnd, pMLEditData->caretx-1,pMLEditData->carety-CARET_HEIGHT_OVERLAP);
}
CMD_NotifyParent(hWnd,CM_SETFOCUS);
}
return 0;
case WM_KILLFOCUS:
if (!WndGetAttr(hWnd,ES_READONLY))
{ DestroyCaret(hWnd);
}
CMD_NotifyParent(hWnd,CM_KILLFOCUS);
return 0;
case WM_ENABLE:
Invalidate(hWnd);
return 0;
case WM_PAINT:
MLEdit_Repaint(hWnd);
return 0;
}
return DefWindowProc(hWnd, Message, WParam, LParam);
}
//---------------------------------------------------------------------------
void CM_RegisterMultiLineEdit(void)
{ TWNDCLASS wc;
memset(&wc,0,sizeof(wc));
wc.dwStyle=WS_BORDER_LOWERED;
wc.clForeground=CL_WINDOWTEXT;
wc.clBackground=CL_WHITE;
wc.cbTextHeap=LEN_MLEDIT_BUFFER;
wc.cbWndExtra=sizeof(TMultiEdit);
wc.lpfnWndProc=MLEditCtrlProc;
wc.lpszClassName="Memo";
RegisterClass(&wc);
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?