⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 medit.c

📁 在ADS环境下MiniGUI的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
** $Id: medit.c,v 1.76 2004/06/26 07:49:31 weiym Exp $
**
** medit.c: the Multi-Line Edit control
**
** Copyright (C) 2003 Feynman Software.
** Copyright (C) 1999 ~ 2002 Chen Lei and Wei Yongming.
** 
** Current maintainer: Chen Lei (leon@minigui.org).
**
** Create date: 1999/8/26
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/*
** TODO:
**    * Selection.
**    * Undo.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "common.h"
#include "minigui.h"
#include "gdi.h"
#include "window.h"
#include "control.h"
#include "cliprect.h"
#include "internals.h"
#include "ctrlclass.h"

#ifdef _CTRL_OLDMEDIT

#include "ctrlmisc.h"
#include "medit.h"

static int MLEditCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam);

BOOL RegisterMLEditControl (void)
{
    // This control class has two names: "medit" and "mledit"

    WNDCLASS WndClass;

    WndClass.spClassName = CTRL_OLDMEDIT;
    WndClass.dwStyle     = WS_NONE;
    WndClass.dwExStyle   = WS_EX_NONE;
    WndClass.hCursor     = GetSystemCursor (IDC_IBEAM);
    WndClass.iBkColor    = GetWindowElementColor (BKC_EDIT_DEF);
    WndClass.WinProc     = MLEditCtrlProc;

    return AddNewControlClass (&WndClass) == ERR_OK;
}

#if 0
void MLEditControlCleanup (void)
{
    // do nothing
    return;
}
#endif

//FIXME
static inline int edtGetOutWidth (HWND hWnd)
{
    PMLEDITDATA pMLEditData =(PMLEDITDATA) GetWindowAdditionalData2(hWnd);
    RECT rc;
    GetClientRect(hWnd,&rc);

    return RECTW(rc) - pMLEditData->leftMargin - pMLEditData->rightMargin;
}

static int edtGetLineNO (const MLEDITDATA* pMLEditData, int y)
{
    int nline = 0;
    if(y>=0)
    {
        nline = (y - pMLEditData->topMargin) / pMLEditData->lineHeight;
        if (nline <= pMLEditData->linesDisp)
               return nline;
    }
    return -1;
}

int GetRETURNPos(char *str, int len)
{
    int i;

    for(i=0;i<len;i++)
    {    
        if(str[i]==10)
            return i;
    }
    return -1;
}

void MLEditEmptyBuffer(PMLEDITDATA pMLEditData)
{
    PLINEDATA temp;
    PLINEDATA  pLineData;
    pLineData = pMLEditData->head;
    while(pLineData)
    {
        temp = pLineData->next;
        free(pLineData);
        pLineData = temp;
    }
    pMLEditData->head = NULL;
}

// get next wrap line start address according to startPos
// > 0 : next start position
// -1  : end of current line
static int edtGetnextStartPos (HWND hWnd, PMLEDITDATA pMLEditData, int startPos)
{
    int        i = 0;
    
    if (!pMLEditData->dx_chars) return -1;

    if (pMLEditData->sz.cx - pMLEditData->dx_chars[startPos] 
                                            <= edtGetOutWidth (hWnd))
        return -1;
    
    for (i = startPos; i < pMLEditData->fit_chars+1; i++) {
        if (pMLEditData->dx_chars[i]-pMLEditData->dx_chars[startPos] >= edtGetOutWidth (hWnd))
            return i-1;
    }
    return -1;
}

static void edtGetLineInfoEx (HWND hWnd, PMLEDITDATA pMLEditData, PLINEDATA pLineData)
{
    HDC hdc = GetClientDC (hWnd);
    if (!pMLEditData) pMLEditData = (PMLEDITDATA) GetWindowAdditionalData2(hWnd);

#if 0
    if (pMLEditData->logfont)
        SelectFont (hdc, pMLEditData->logfont);
#endif

    GetTextExtentPoint (hdc,
                        pLineData->buffer, 
                        pLineData->dataEnd,  
                        GetMaxFontWidth (hdc)*LEN_MLEDIT_BUFFER,
                        &(pMLEditData->fit_chars), 
                        pMLEditData->pos_chars, 
                        pMLEditData->dx_chars, 
                        &(pMLEditData->sz));
    ReleaseDC (hdc);

    if (pMLEditData->pos_chars)
        pMLEditData->pos_chars[pMLEditData->fit_chars] = pLineData->dataEnd;
    if (pMLEditData->dx_chars)
        pMLEditData->dx_chars[pMLEditData->fit_chars] = pMLEditData->sz.cx;
}

static void edtGetLineInfo (HWND hWnd, PLINEDATA pLineData)
{
    edtGetLineInfoEx (hWnd, NULL, pLineData);
}

static int edtGetStartDispPosAtEnd (HWND hWnd,
            PLINEDATA pLineData)
{
    PMLEDITDATA pMLEditData =(PMLEDITDATA) GetWindowAdditionalData2(hWnd);
    int            i = 0;
    int         dist = MAX_IMPOSSIBLE;
    int         newdist = 0;
    
    edtGetLineInfo (hWnd, pLineData);

    if (pMLEditData->sz.cx <= edtGetOutWidth (hWnd)) 
        return 0;
    
    for (i = 0; i < pMLEditData->fit_chars-1; i++) {
        newdist = (pMLEditData->sz.cx - edtGetOutWidth (hWnd)) - pMLEditData->dx_chars[i];
        if (newdist >= 0 && newdist < dist) {
            dist = newdist;
            if (dist == 0) { return i; } 
        }else { return i; }
    }
    return 0;
}

void calcLineInfo (HWND hWnd, PMLEDITDATA pMLEditData, PLINEDATA pLineData)
{
    int i;

    edtGetLineInfoEx (hWnd, pMLEditData, pLineData);

    for ( i=0,pLineData->nwrapline=1,pLineData->wrapStartPos[0]=0; 
                    (i = edtGetnextStartPos(hWnd, pMLEditData,i)) > 0; 
                    pLineData->nwrapline++ )
    {
        pLineData->wrapStartPos[pLineData->nwrapline] = i;
    }
    pLineData->wrapStartPos[pLineData->nwrapline] = pMLEditData->fit_chars; 
}

void MLEditInitBuffer (HWND hWnd, PMLEDITDATA pMLEditData, const char *spcaption, DWORD dwStyle)
{
    char *caption=(char*)spcaption; 
    int off1;
    int lineNO=0;
    int pace=0;
    int totallen=0;

    PLINEDATA  pLineData;

    if (!(pMLEditData->head = malloc (sizeof (LINEDATA)))) {
        return ;
    }
    pMLEditData->head->previous = NULL;
    pLineData = pMLEditData->head;    
    pMLEditData->wraplines = 0;

    totallen = strlen(caption);

    while ( (off1 = GetRETURNPos(caption, totallen)) != -1)
    {
        int off;
        off1 = MIN (off1, LEN_MLEDIT_BUFFER);
        if ((char)caption[off1-1] == '\r')
            off = off1-1;
        else
            off = off1;
#if 0
        if ((pMLEditData->curtotalLen + MIN (off,LEN_MLEDIT_BUFFER) >= pMLEditData->totalLimit)
            && pMLEditData->totalLimit != -1)
        {
            pLineData->dataEnd = pMLEditData->totalLimit-pMLEditData->curtotalLen;

            pace = MIN (pLineData->dataEnd, LEN_MLEDIT_BUFFER) + 1;
            caption += pace;
			totallen -= pace;

            if (pLineData->dataEnd-2 > 0 && (char)caption[pLineData->dataEnd-2] == '\r')
                pLineData->dataEnd -= 2;
            else if (pLineData->dataEnd-1 > 0 && (char)caption[pLineData->dataEnd-1] == '\n')
                pLineData->dataEnd --;

            printf ("dateEnd = %d\n", pLineData->dataEnd);

            memcpy(pLineData->buffer,caption, pLineData->dataEnd);
            pLineData->buffer[pLineData->dataEnd] = '\0';
            pLineData->lineNO  = lineNO++;
            pMLEditData->curtotalLen += pLineData->dataEnd;
            
            if (!pLineData->dataEnd)
            {
                pLineData->nwrapline = 1;
                pLineData->wrapStartPos[0] = 0;
                pLineData->wrapStartPos[1] = 0;
            } else
                calcLineInfo (hWnd, pMLEditData, pLineData);

            pMLEditData->wraplines += pLineData->nwrapline;
            pLineData->lineNO  = lineNO++;    

            if (pMLEditData->curtotalLen == pMLEditData->totalLimit)
            {
                pLineData->next = NULL;
                break;
            } else if (pMLEditData->curtotalLen + 1 < pMLEditData->totalLimit)
                pMLEditData->curtotalLen ++;
            pLineData->next    = malloc (sizeof (LINEDATA));
            pLineData->next->previous = pLineData; 
            pLineData->next->next = NULL;
            pLineData = pLineData->next;
            break;
        }
#endif
        memcpy(pLineData->buffer,caption, off1);
        if (pLineData->buffer[off1-1] == '\r')
            pLineData->buffer[off1-1] = '\0';
        else
            pLineData->buffer[off1] = '\0';
        
        pace = MIN (off1,LEN_MLEDIT_BUFFER)+1;
        caption += pace;
        
        pLineData->lineNO  = lineNO++;    
        pLineData->dataEnd = strlen(pLineData->buffer); 
        if (!pLineData->dataEnd)
        {
            pLineData->nwrapline = 1;
            pLineData->wrapStartPos[0] = 0;
            pLineData->wrapStartPos[1] = 0;
        } else
            calcLineInfo (hWnd, pMLEditData, pLineData);

        pMLEditData->wraplines += pLineData->nwrapline;

        pMLEditData->curtotalLen += pLineData->dataEnd;
        if (pMLEditData->curtotalLen == pMLEditData->totalLimit)
        {
            pLineData->next = NULL;
            break;
        } else if (pMLEditData->curtotalLen + 1 < pMLEditData->totalLimit)
            pMLEditData->curtotalLen ++;

        pLineData->next    = malloc (sizeof (LINEDATA));
        pLineData->next->previous = pLineData; 
        pLineData->next->next = NULL;
        pLineData = pLineData->next;
    }
    if (pMLEditData->totalLimit > 0 && pMLEditData->curtotalLen < pMLEditData->totalLimit)
    {
        int off=0;
        off1 = MIN (strlen(caption),LEN_MLEDIT_BUFFER);
        if (off1 && (char)caption[off1-1] == '\r')
            off = off1-1;
        else
            off = off1;
        if (pMLEditData->curtotalLen + MIN (off,LEN_MLEDIT_BUFFER) >= pMLEditData->totalLimit)
        {
            pLineData->dataEnd = pMLEditData->totalLimit-pMLEditData->curtotalLen;
            if (pLineData->dataEnd-2 > 0 && (char)caption[pLineData->dataEnd-2] == '\r')
                pLineData->dataEnd -= 2;
            else if (pLineData->dataEnd-1 > 0 && (char)caption[pLineData->dataEnd-1] == '\n')
                pLineData->dataEnd --;

            memcpy(pLineData->buffer,caption, pLineData->dataEnd);
            pLineData->buffer[pLineData->dataEnd] = '\0';

        }else {
            memcpy(pLineData->buffer,caption,off1);
            if (off1 && pLineData->buffer[off1-1] == '\r')
                pLineData->buffer[off1-1] = '\0';
            else
                pLineData->buffer[off1] = '\0';
            pLineData->dataEnd         = strlen(pLineData->buffer); 
            pLineData->next            = NULL; 

        }
        pMLEditData->curtotalLen += pLineData->dataEnd;
        if (pMLEditData->curtotalLen == pMLEditData->totalLimit-1)
            pMLEditData->curtotalLen = pMLEditData->totalLimit;
        if (!pLineData->dataEnd)
        {
            pLineData->nwrapline = 1;
            pLineData->wrapStartPos[0] = 0;
            pLineData->wrapStartPos[1] = 0;
        } else
              calcLineInfo (hWnd, pMLEditData, pLineData);

        pMLEditData->wraplines += pLineData->nwrapline;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -