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

📄 simedit.c

📁 在ADS环境下MiniGUI的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
** $Id: simedit.c,v 1.24 2004/07/22 09:36:44 snig Exp $
**
** simedit.c: the Simple Edit Control module.
**
** Copyright (C) 2003 Feynman Software.
** Copyright (C) 1999 ~ 2002 Wei Yongming.
** 
** Current maintainer: Wei Yongming.
*/

/*
** 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:
*/

#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_SIMEDIT

#include "ctrlmisc.h"
#include "simedit.h"

#ifdef _FLAT_WINDOW_STYLE
#define WIDTH_EDIT_BORDER       1
#else
#define WIDTH_EDIT_BORDER       2
#endif

#define MARGIN_EDIT_LEFT        1
#define MARGIN_EDIT_TOP         1
#define MARGIN_EDIT_RIGHT       2
#define MARGIN_EDIT_BOTTOM      1

#define EST_FOCUSED     0x00000001L
#define EST_MODIFY      0x00000002L
#define EST_REPLACE     0x00000008L

#define EDIT_OP_NONE    0x00
#define EDIT_OP_DELETE  0x01
#define EDIT_OP_INSERT  0x02
#define EDIT_OP_REPLACE 0x03

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

BOOL RegisterSIMEditControl (void)
{
    WNDCLASS WndClass;

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

    return AddNewControlClass (&WndClass) == ERR_OK;
}

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

static inline int edtGetOutWidth (const CONTROL* pCtrl)
{
    return pCtrl->cr - pCtrl->cl 
            - ((PSIMEDITDATA)(pCtrl->dwAddData2))->leftMargin
            - ((PSIMEDITDATA)(pCtrl->dwAddData2))->rightMargin;
}

static int edtGetStartDispPosAtEnd (const CONTROL* pCtrl,
            PSIMEDITDATA simed)
{
    int         nOutWidth = edtGetOutWidth (pCtrl);
    int         endPos  = simed->dataEnd;
    int         newStartPos = simed->startPos;
    const char* buffer = simed->buffer;

    while (TRUE) {
        if ((endPos - newStartPos) * simed->charWidth < nOutWidth)
            break;
        
        if ((BYTE)buffer [newStartPos] > 0xA0) {
            newStartPos ++;
            if (newStartPos < simed->dataEnd) {
                if ((BYTE)buffer [newStartPos] > 0xA0)
                    newStartPos ++;
            }
        }
        else
            newStartPos ++;
    }

    return newStartPos;
}

static int edtGetDispLen (const CONTROL* pCtrl)
{
    int i, n = 0;
    int nOutWidth = edtGetOutWidth (pCtrl);
    int nTextWidth = 0;
    PSIMEDITDATA simed = (PSIMEDITDATA)(pCtrl->dwAddData2);
    const char* buffer = simed->buffer;

    for (i = simed->startPos; i < simed->dataEnd; i++) {
        if ((BYTE)buffer [i] > 0xA0) {
            i++;
            if (i < simed->dataEnd) {
                if ((BYTE)buffer [i] > 0xA0) {
                    nTextWidth += simed->charWidth * 2;
                    n += 2;
                }
                else
                    i--;
            }
            else {
                nTextWidth += simed->charWidth;
                n++;
            }
        }
        else {
            nTextWidth += simed->charWidth;
            n++;
        }

        if (nTextWidth > nOutWidth)
            break;
    }

    return n;
}

static int edtGetOffset (const SIMEDITDATA* simed, int x)
{
    int i;
    int newOff = 0;
    int nTextWidth = 0;
    const char* buffer = simed->buffer;

    x -= simed->leftMargin;
    for (i = simed->startPos; i < simed->dataEnd; i++) {
        if ((nTextWidth + (simed->charWidth >> 1)) >= x)
            break;

        if ((BYTE)buffer [i] > 0xA0) {
            i++;
            if (i < simed->dataEnd) {
                if ((BYTE)buffer [i] > 0xA0) {
                    nTextWidth += simed->charWidth * 2;
                    newOff += 2;
                }
                else
                    i --;
            }
            else {
                nTextWidth += simed->charWidth;
                newOff ++;
            }
        }
        else {
            nTextWidth += simed->charWidth;
            newOff ++;
        }

    }

    return newOff;
}

static BOOL edtIsACCharBeforePosition (const char* string, int pos)
{
    if (pos < 2)
        return FALSE;

    if ((BYTE)string [pos - 2] > 0xA0 && (BYTE)string [pos - 1] > 0xA0)
        return TRUE;

    return FALSE;
}

static BOOL edtIsACCharAtPosition (const char* string, int len, int pos)
{
    if (pos > (len - 2))
        return FALSE;

    if ((BYTE)string [pos] > 0xA0 && (BYTE)string [pos + 1] > 0xA0)
        return TRUE;

    return FALSE;
}

static int SIMEditCtrlProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{   
    PCONTROL    pCtrl;
    DWORD       dwStyle;
    HDC         hdc;
    PSIMEDITDATA simed;

    pCtrl       = Control(hWnd);
    dwStyle     = pCtrl->dwStyle;

    switch (message)
    {
        case MSG_CREATE:
            if (!(simed = calloc (1, sizeof (SIMEDITDATA)))) {
                return -1;
            }

            simed->status         = 0;
            simed->bufferLen      = LEN_SIMEDIT_BUFFER;
            simed->buffer         = calloc (LEN_SIMEDIT_BUFFER, sizeof (char));

            if (simed->buffer == NULL) {
                free (simed);
                return -1;
            }

            if (!CreateCaret (hWnd, NULL, 1, GetSysFontHeight (SYSLOGFONT_FIXED))) {
                free (simed->buffer);
                free (simed);
                return -1;
            }
           
            simed->editPos        = 0;
            simed->caretOff       = 0;
            simed->startPos       = 0;
            
            simed->passwdChar     = '*';
            simed->leftMargin     = MARGIN_EDIT_LEFT;
            simed->topMargin      = MARGIN_EDIT_TOP;
            simed->rightMargin    = MARGIN_EDIT_RIGHT;
            simed->bottomMargin   = MARGIN_EDIT_BOTTOM;

            simed->hardLimit      = -1;
            
            simed->dataEnd        = strlen (pCtrl->spCaption);
            memcpy (simed->buffer, pCtrl->spCaption, MIN (LEN_SIMEDIT_BUFFER, simed->dataEnd));
            simed->dataEnd        = MIN (LEN_SIMEDIT_BUFFER, simed->dataEnd);
            
            pCtrl->dwAddData2 = (DWORD) simed;
            pCtrl->pLogFont = GetSystemFont (SYSLOGFONT_FIXED);
            simed->charWidth = GetSysFontMaxWidth (SYSLOGFONT_FIXED);
            break;

        case MSG_DESTROY:
            simed = (PSIMEDITDATA) (pCtrl->dwAddData2);
            DestroyCaret (hWnd);
            free (simed->buffer);
            free (simed);
            break;

        case MSG_ERASEBKGND:
            EditOnEraseBackground (hWnd, (HDC)wParam, (const RECT*)lParam);
            return 0;

        case MSG_FONTCHANGING:
            return -1;
        
        case MSG_SETCURSOR:
            if (dwStyle & WS_DISABLED) {
                SetCursor (GetSystemCursor (IDC_ARROW));
                return 0;
            }
            break;

        case MSG_KILLFOCUS:
            simed = (PSIMEDITDATA) (pCtrl->dwAddData2);
            if (simed->status & EST_FOCUSED) {
                simed->status &= ~EST_FOCUSED;
                HideCaret (hWnd);
                NotifyParent (hWnd, pCtrl->id, EN_KILLFOCUS);
            }
            break;
        
        case MSG_SETFOCUS:
            simed = (PSIMEDITDATA) (pCtrl->dwAddData2);
            if (simed->status & EST_FOCUSED)
                break;
            
            simed->status |= EST_FOCUSED;

            /* only implemented for ES_LEFT align format. */
            SetCaretPos (hWnd, simed->caretOff * simed->charWidth + simed->leftMargin, 
                simed->topMargin);
                
            ShowCaret (hWnd);
            ActiveCaret (hWnd);

            NotifyParent (hWnd, pCtrl->id, EN_SETFOCUS);
            break;
        
        case MSG_ENABLE:
            if ( (!(dwStyle & WS_DISABLED) && !wParam)
                    || ((dwStyle & WS_DISABLED) && wParam) ) {
                if (wParam)

⌨️ 快捷键说明

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