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

📄 map.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
字号:
/*
 * PROJECT:     ReactOS Character Map
 * LICENSE:     GPL - See COPYING in the top level directory
 * FILE:        base/applications/charmap/map.c
 * PURPOSE:     class implementation for painting glyph region
 * COPYRIGHT:   Copyright 2007 Ged Murphy <gedmurphy@reactos.org>
 *
 */

#include <precomp.h>

static const TCHAR szMapWndClass[] = TEXT("FontMapWnd");
static const TCHAR szLrgCellWndClass[] = TEXT("LrgCellWnd");

static VOID
TagFontToCell(PCELL pCell,
              TCHAR ch)
{
    pCell->ch = ch;
}


static VOID
SetGrid(PMAP infoPtr)
{
    INT x, y;

    for (y = 0; y < YCELLS; y++)
    for (x = 0; x < XCELLS; x++)
    {
        infoPtr->Cells[y][x].CellExt.left = x * infoPtr->CellSize.cx + 1;
        infoPtr->Cells[y][x].CellExt.top = y * infoPtr->CellSize.cy + 1;
        infoPtr->Cells[y][x].CellExt.right = (x + 1) * infoPtr->CellSize.cx + 2;
        infoPtr->Cells[y][x].CellExt.bottom = (y + 1) * infoPtr->CellSize.cy + 2;

        CopyRect(&infoPtr->Cells[y][x].CellInt,
                 &infoPtr->Cells[y][x].CellExt);

        InflateRect(&infoPtr->Cells[y][x].CellInt,
                    -1,
                    -1);
    }
}

static VOID
DrawActiveCell(PMAP infoPtr,
               HDC hdc)
{
    Rectangle(hdc,
              infoPtr->pActiveCell->CellInt.left,
              infoPtr->pActiveCell->CellInt.top,
              infoPtr->pActiveCell->CellInt.right,
              infoPtr->pActiveCell->CellInt.bottom);

}


static VOID
DrawGrid(PMAP infoPtr,
         HDC hdc)
{
    INT x, y;

    for (y = 0; y < YCELLS; y++)
    for (x = 0; x < XCELLS; x++)
    {
        Rectangle(hdc,
                  infoPtr->Cells[y][x].CellExt.left,
                  infoPtr->Cells[y][x].CellExt.top,
                  infoPtr->Cells[y][x].CellExt.right,
                  infoPtr->Cells[y][x].CellExt.bottom);
    }

    if (infoPtr->pActiveCell)
        DrawActiveCell(infoPtr,
                       hdc);
}


static VOID
FillGrid(PMAP infoPtr,
         HDC hdc)
{
    HFONT hOldFont;
    TCHAR ch;
    INT x, y;

    hOldFont = SelectObject(hdc,
                            infoPtr->hFont);

    for (y = 0; y < YCELLS; y++)
    for (x = 0; x < XCELLS; x++)
    {
        ch = (TCHAR)((256 * infoPtr->iPage) + (XCELLS * y) + x);

        TagFontToCell(&infoPtr->Cells[y][x], ch);

        DrawText(hdc,
                 &ch,
                 1,
                 &infoPtr->Cells[y][x].CellInt,
                 DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    }

    SelectObject(hdc,
                 hOldFont);
}


static BOOL
CreateLargeCell(PMAP infoPtr)
{
    RECT rLarge;

    CopyRect(&rLarge,
             &infoPtr->pActiveCell->CellExt);

    MapWindowPoints(infoPtr->hMapWnd,
                    infoPtr->hParent,
                    (LPPOINT)&rLarge,
                    2);

    InflateRect(&rLarge,
                XLARGE - XCELLS,
                YLARGE - YCELLS);

    infoPtr->hLrgWnd = CreateWindowEx(0,
                                      szLrgCellWndClass,
                                      NULL,
                                      WS_CHILDWINDOW | WS_VISIBLE,
                                      rLarge.left,
                                      rLarge.top,
                                      rLarge.right - rLarge.left,
                                      rLarge.bottom - rLarge.top,
                                      infoPtr->hParent,
                                      NULL,
                                      hInstance,
                                      infoPtr);
    if (!infoPtr->hLrgWnd)
        return FALSE;

    return TRUE;
}


static VOID
MoveLargeCell(PMAP infoPtr)
{
    RECT rLarge;

    CopyRect(&rLarge,
             &infoPtr->pActiveCell->CellExt);

    MapWindowPoints(infoPtr->hMapWnd,
                    infoPtr->hParent,
                    (LPPOINT)&rLarge,
                    2);

    InflateRect(&rLarge,
                XLARGE - XCELLS,
                YLARGE - YCELLS);

    MoveWindow(infoPtr->hLrgWnd,
               rLarge.left,
               rLarge.top,
               rLarge.right - rLarge.left,
               rLarge.bottom - rLarge.top,
               TRUE);

    InvalidateRect(infoPtr->hLrgWnd,
                   NULL,
                   TRUE);
}


static VOID
SetFont(PMAP infoPtr,
        LPTSTR lpFontName)
{
    HDC hdc;

    if (infoPtr->hFont)
        DeleteObject(infoPtr->hFont);

    ZeroMemory(&infoPtr->CurrentFont,
               sizeof(LOGFONT));

    hdc = GetDC(infoPtr->hMapWnd);
    infoPtr->CurrentFont.lfHeight = GetDeviceCaps(hdc,
                                                  LOGPIXELSY) / 5;
    ReleaseDC(infoPtr->hMapWnd, hdc);

    infoPtr->CurrentFont.lfCharSet =  DEFAULT_CHARSET;
    lstrcpy(infoPtr->CurrentFont.lfFaceName,
            lpFontName);

    infoPtr->hFont = CreateFontIndirect(&infoPtr->CurrentFont);

    InvalidateRect(infoPtr->hMapWnd,
                   NULL,
                   TRUE);
}


static LRESULT
NotifyParentOfSelection(PMAP infoPtr,
                        UINT code,
                        TCHAR ch)
{
    LRESULT Ret = 0;

    if (infoPtr->hParent != NULL)
    {
        MAPNOTIFY mnmh;

        mnmh.hdr.hwndFrom = infoPtr->hMapWnd;
        mnmh.hdr.idFrom = GetWindowLongPtr(infoPtr->hMapWnd,
                                           GWLP_ID);
        mnmh.hdr.code = code;

        mnmh.ch = ch;

        Ret = SendMessage(infoPtr->hParent,
                          WM_NOTIFY,
                          (WPARAM)mnmh.hdr.idFrom,
                          (LPARAM)&mnmh);
    }

    return Ret;
}


static VOID
OnClick(PMAP infoPtr,
        WORD ptx,
        WORD pty)
{
    POINT pt;
    INT x, y;

    pt.x = ptx;
    pt.y = pty;

    for (x = 0; x < XCELLS; x++)
    for (y = 0; y < YCELLS; y++)
    {
        if (PtInRect(&infoPtr->Cells[y][x].CellInt,
                     pt))
        {
            /* if the cell is not already active */
            if (!infoPtr->Cells[y][x].bActive)
            {
                /* set previous active cell to inactive */
                if (infoPtr->pActiveCell)
                {
                    /* invalidate normal cells, required when
                     * moving a small active cell via keyboard */
                    if (!infoPtr->pActiveCell->bLarge)
                    {
                        InvalidateRect(infoPtr->hMapWnd,
                                       &infoPtr->pActiveCell->CellInt,
                                       TRUE);
                    }

                    infoPtr->pActiveCell->bActive = FALSE;
                    infoPtr->pActiveCell->bLarge = FALSE;
                }

                /* set new cell to active */
                infoPtr->pActiveCell = &infoPtr->Cells[y][x];
                infoPtr->pActiveCell->bActive = TRUE;
                infoPtr->pActiveCell->bLarge = TRUE;
                if (infoPtr->hLrgWnd)
                    MoveLargeCell(infoPtr);
                else
                    CreateLargeCell(infoPtr);
            }
            else
            {
                /* flick between large and small */
                if (infoPtr->pActiveCell->bLarge)
                {
                    DestroyWindow(infoPtr->hLrgWnd);
                    infoPtr->hLrgWnd = NULL;
                }
                else
                {
                    CreateLargeCell(infoPtr);
                }

                infoPtr->pActiveCell->bLarge = (infoPtr->pActiveCell->bLarge) ? FALSE : TRUE;
            }

            break;
        }
    }
}


static BOOL
OnCreate(PMAP infoPtr,
         HWND hwnd,
         HWND hParent)
{
    RECT rc;
    BOOL Ret = FALSE;

    infoPtr = HeapAlloc(GetProcessHeap(),
                        0,
                        sizeof(MAP));
    if (infoPtr)
    {
        SetLastError(0);
        SetWindowLongPtr(hwnd,
                         0,
                         (DWORD_PTR)infoPtr);
        if (GetLastError() == 0)
        {
            ZeroMemory(infoPtr,
                       sizeof(MAP));

            infoPtr->hMapWnd = hwnd;
            infoPtr->hParent = hParent;

            GetClientRect(hwnd, &rc);
            infoPtr->ClientSize.cx = rc.right;
            infoPtr->ClientSize.cy = rc.bottom;
            infoPtr->CellSize.cx = infoPtr->ClientSize.cx / XCELLS;
            infoPtr->CellSize.cy = infoPtr->ClientSize.cy / YCELLS;

            infoPtr->pActiveCell = NULL;

            SetGrid(infoPtr);

            SetScrollRange(hwnd, SB_VERT, 0, 255, FALSE);
            SetScrollPos(hwnd, SB_VERT, 0, TRUE);

            Ret = TRUE;
        }
    }

    return Ret;
}


static VOID
OnVScroll(PMAP infoPtr,
          INT Value,
          INT Pos)
{
    switch (Value)
    {
        case SB_LINEUP:
            infoPtr->iPage -=  1;
            break;

        case SB_LINEDOWN:
            infoPtr->iPage +=  1;
            break;

        case SB_PAGEUP:
            infoPtr->iPage -= 16;
            break;

        case SB_PAGEDOWN:
            infoPtr->iPage += 16;
            break;

        case SB_THUMBPOSITION:
            infoPtr->iPage = Pos;
            break;

       default:
            break;
       }

    infoPtr->iPage = max(0,
                         min(infoPtr->iPage,
                             255));

    SetScrollPos(infoPtr->hMapWnd,
                 SB_VERT,
                 infoPtr->iPage,
                 TRUE);

    InvalidateRect(infoPtr->hMapWnd,
                   NULL,
                   TRUE);
}


static VOID
OnPaint(PMAP infoPtr,
        WPARAM wParam)
{
    PAINTSTRUCT ps;
    HDC hdc;


    if (wParam != 0)
    {
        if (!GetUpdateRect(infoPtr->hMapWnd,
                           &ps.rcPaint,
                           TRUE))
        {
            return;
        }
        hdc = (HDC)wParam;
    }
    else
    {
        hdc = BeginPaint(infoPtr->hMapWnd,
                         &ps);
        if (hdc == NULL)
        {
            return;
        }
    }

    DrawGrid(infoPtr,
             hdc);

    FillGrid(infoPtr,
             hdc);

    if (wParam == 0)
    {
        EndPaint(infoPtr->hMapWnd,
                 &ps);
    }
}


LRESULT CALLBACK
MapWndProc(HWND hwnd,
           UINT uMsg,
           WPARAM wParam,
           LPARAM lParam)
{
    PMAP infoPtr;
    LRESULT Ret = 0;

    infoPtr = (PMAP)GetWindowLongPtr(hwnd,
                                     0);

    switch (uMsg)
    {
        case WM_CREATE:
        {
            if (!OnCreate(infoPtr,
                          hwnd,
                          ((LPCREATESTRUCTW)lParam)->hwndParent))
            {
                return (LRESULT)-1;
            }

            break;
        }

        case WM_LBUTTONDOWN:
        {
            OnClick(infoPtr,
                    LOWORD(lParam),
                    HIWORD(lParam));

            break;
        }

        case WM_LBUTTONDBLCLK:
        {
            NotifyParentOfSelection(infoPtr,
                                    FM_SETCHAR,
                                    infoPtr->pActiveCell->ch);


            break;
        }

        case WM_VSCROLL:
        {
            OnVScroll(infoPtr,
                      LOWORD(wParam),
                      HIWORD(wParam));

            break;
        }

        case FM_SETFONT:
        {
            LPTSTR lpFontName = (LPTSTR)lParam;

            SetFont(infoPtr,
                    lpFontName);

            HeapFree(GetProcessHeap(),
                     0,
                     lpFontName);

            break;
        }

        case FM_GETCHAR:
        {
            if (!infoPtr->pActiveCell) return 0;
            return infoPtr->pActiveCell->ch;
        }

        case WM_PAINT:
        {
            OnPaint(infoPtr,
                    wParam);
            break;
        }

        case WM_DESTROY:
        {
            DeleteObject(infoPtr->hFont);
            HeapFree(GetProcessHeap(),
                     0,
                     infoPtr);
            SetWindowLongPtr(hwnd,
                             0,
                             (DWORD_PTR)NULL);
            break;
        }

        default:
        {
            Ret = DefWindowProc(hwnd,
                                uMsg,
                                wParam,
                                lParam);
            break;
        }
    }

    return Ret;
}


BOOL
RegisterMapClasses(HINSTANCE hInstance)
{
    WNDCLASS wc = {0};

    wc.style = CS_DBLCLKS;
    wc.lpfnWndProc = MapWndProc;
    wc.cbWndExtra = sizeof(PMAP);
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL,
                            (LPTSTR)IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszClassName = szMapWndClass;

    if (RegisterClass(&wc))
    {
        wc.lpfnWndProc = LrgCellWndProc;
        wc.cbWndExtra = 0;
        wc.lpszClassName = szLrgCellWndClass;

        return RegisterClass(&wc) != 0;
    }

    return FALSE;
}

VOID
UnregisterMapClasses(HINSTANCE hInstance)
{
    UnregisterClass(szMapWndClass,
                    hInstance);

    UnregisterClass(szLrgCellWndClass,
                    hInstance);
}

⌨️ 快捷键说明

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