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 + -
显示快捷键?