[CHARMAP]
authorGed Murphy <gedmurphy@reactos.org>
Wed, 18 Nov 2015 19:24:08 +0000 (19:24 +0000)
committerGed Murphy <gedmurphy@reactos.org>
Wed, 18 Nov 2015 19:24:08 +0000 (19:24 +0000)
- Start to implement the charmap required for the 0.4 release
- We now have a basic dialog with the grid in place

CORE-10518

svn path=/trunk/; revision=69931

13 files changed:
reactos/base/applications/charmap_new/CMakeLists.txt [new file with mode: 0644]
reactos/base/applications/charmap_new/Cell.cpp [new file with mode: 0644]
reactos/base/applications/charmap_new/Cell.h [new file with mode: 0644]
reactos/base/applications/charmap_new/GridView.cpp [new file with mode: 0644]
reactos/base/applications/charmap_new/GridView.h [new file with mode: 0644]
reactos/base/applications/charmap_new/MainWindow.cpp [new file with mode: 0644]
reactos/base/applications/charmap_new/MainWindow.h [new file with mode: 0644]
reactos/base/applications/charmap_new/charmap.cpp [new file with mode: 0644]
reactos/base/applications/charmap_new/charmap.rc [new file with mode: 0644]
reactos/base/applications/charmap_new/lang/en-US.rc [new file with mode: 0644]
reactos/base/applications/charmap_new/precomp.h [new file with mode: 0644]
reactos/base/applications/charmap_new/res/charmap.ico [new file with mode: 0644]
reactos/base/applications/charmap_new/resource.h [new file with mode: 0644]

diff --git a/reactos/base/applications/charmap_new/CMakeLists.txt b/reactos/base/applications/charmap_new/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6b57187
--- /dev/null
@@ -0,0 +1,27 @@
+PROJECT(CHARMAP)
+
+set_cpp(WITH_RTTI WITH_RUNTIME WITH_EXCEPTIONS)
+
+if(NOT MSVC)
+    # HACK: this should be enabled globally!
+    add_compile_flags_language("-std=c++11" "CXX")
+endif()
+
+include_directories(
+    ${REACTOS_SOURCE_DIR}/lib/atl 
+    includes)
+
+list(APPEND SOURCE
+    precomp.h
+    MainWindow.cpp
+       )
+
+add_library(charmap SHARED
+    ${SOURCE}
+    charmap.rc)
+
+set_module_type(charmap win32gui UNICODE)
+target_link_libraries(charmap uuid atlnew wine)
+add_importlibs(charmap advapi32 user32 gdi32 comctl32 version msvcrt kernel32 ole32 uxtheme ntdll)
+add_pch(charmap precomp.h SOURCE)
+add_cd_file(TARGET charmap DESTINATION reactos/system32 FOR all)
diff --git a/reactos/base/applications/charmap_new/Cell.cpp b/reactos/base/applications/charmap_new/Cell.cpp
new file mode 100644 (file)
index 0000000..7eacc89
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+* PROJECT:     ReactOS Character Map
+* LICENSE:     GPL - See COPYING in the top level directory
+* FILE:        base/applications/charmap/cell.cpp
+* PURPOSE:     Class for each individual cell
+* COPYRIGHT:   Copyright 2015 Ged Murphy <gedmurphy@reactos.org>
+*/
+
+
+#include "precomp.h"
+#include "Cell.h"
+
+
+/* DATA *****************************************************/
+
+
+/* PUBLIC METHODS **********************************************/
+
+CCell::CCell(
+    _In_ HWND hParent
+    ) :
+    CCell(hParent, RECT{0})
+{
+}
+
+CCell::CCell(
+    _In_ HWND hParent,
+    _In_ RECT& CellCoordinates
+    ) :
+    m_hParent(hParent),
+    m_CellCoordinates(CellCoordinates),
+    ch(L'*'),
+    m_bHasFocus(false),
+    m_bIsLarge(false)
+{
+}
+
+CCell::~CCell()
+{
+}
+
+bool
+CCell::OnPaint(_In_ PAINTSTRUCT &PaintStruct)
+{
+    // Check if this cell is in our paint region
+    BOOL NeedsPaint; RECT rect;
+    NeedsPaint = IntersectRect(&rect,
+                               &PaintStruct.rcPaint,
+                               &m_CellCoordinates);
+    if (NeedsPaint == FALSE)
+        return false;
+
+    // Draw the cell border
+    BOOL b = Rectangle(PaintStruct.hdc,
+              m_CellCoordinates.left,
+              m_CellCoordinates.top,
+              m_CellCoordinates.right,
+              m_CellCoordinates.bottom);
+
+    // Check if this cell has focus
+    if (m_bHasFocus)
+    {
+        // Take a copy of the border dims and make it slightly smaller
+        RECT Internal;
+        CopyRect(&Internal, &m_CellCoordinates);
+        InflateRect(&Internal, -1, -1);
+
+        // Draw the smaller cell to make it look selected
+        Rectangle(PaintStruct.hdc,
+                  Internal.left,
+                  Internal.top,
+                  Internal.right,
+                  Internal.bottom);
+    }
+
+    return true;
+}
+
+void
+CCell::SetCellCoordinates(
+    _In_ RECT& Coordinates
+    )
+{
+    m_CellCoordinates = Coordinates;
+}
\ No newline at end of file
diff --git a/reactos/base/applications/charmap_new/Cell.h b/reactos/base/applications/charmap_new/Cell.h
new file mode 100644 (file)
index 0000000..406dddf
--- /dev/null
@@ -0,0 +1,35 @@
+#pragma once
+class CCell
+{
+private:
+    HWND m_hParent;
+    RECT m_CellCoordinates;
+
+    bool m_bHasFocus;
+    bool m_bIsLarge;
+    WCHAR ch;
+
+public:
+    CCell(
+        _In_ HWND hParent
+        );
+
+    CCell(
+        _In_ HWND hParent,
+        _In_ RECT& CellLocation
+        );
+
+    ~CCell();
+
+    LPRECT GetCellCoordinates() { return &m_CellCoordinates; }
+    void SetFocus(_In_ bool HasFocus) { m_bHasFocus = HasFocus; }
+
+    bool OnPaint(
+        _In_ PAINTSTRUCT &PaintStruct
+        );
+
+    void SetCellCoordinates(
+        _In_ RECT& Coordinates
+        );
+};
+
diff --git a/reactos/base/applications/charmap_new/GridView.cpp b/reactos/base/applications/charmap_new/GridView.cpp
new file mode 100644 (file)
index 0000000..8dbf8b4
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+* PROJECT:     ReactOS Character Map
+* LICENSE:     GPL - See COPYING in the top level directory
+* FILE:        base/applications/charmap/GridView.cpp
+* PURPOSE:     Class for for the window which contains the font matrix
+* COPYRIGHT:   Copyright 2015 Ged Murphy <gedmurphy@reactos.org>
+*/
+
+
+#include "precomp.h"
+#include "GridView.h"
+#include "Cell.h"
+
+
+/* DATA *****************************************************/
+
+extern HINSTANCE g_hInstance;
+
+
+/* PUBLIC METHODS **********************************************/
+
+CGridView::CGridView() :
+    m_xNumCells(20),
+    m_yNumCells(10)
+{
+    m_szMapWndClass = L"CharGridWClass";
+}
+
+CGridView::~CGridView()
+{
+}
+
+bool
+CGridView::Create(
+    _In_ HWND hParent
+    )
+{
+    WNDCLASSW wc = { 0 };
+    wc.style = CS_DBLCLKS;
+    wc.lpfnWndProc = MapWndProc;
+    wc.cbWndExtra = sizeof(CGridView *);
+    wc.hInstance = g_hInstance;
+    wc.hCursor = LoadCursorW(NULL, (LPWSTR)IDC_ARROW);
+    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+    wc.lpszClassName = m_szMapWndClass;
+
+    if (RegisterClassW(&wc))
+    {
+        m_hwnd = CreateWindowExW(0,
+                                 m_szMapWndClass,
+                                 NULL,
+                                 WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL,
+                                 0,0,0,0,
+                                 hParent,
+                                 NULL,
+                                 g_hInstance,
+                                 this);
+
+    }
+
+    return !!(m_hwnd != NULL);
+}
+
+bool
+CGridView::UpdateGridLayout(
+    )
+{
+    // Go through all the cells and calculate
+    // their coordinates within the grid 
+    for (int y = 0; y < m_yNumCells; y++)
+    for (int x = 0; x < m_xNumCells; x++)
+    {
+        RECT CellCoordinates;
+        CellCoordinates.left = x * m_CellSize.cx + 1;
+        CellCoordinates.top = y * m_CellSize.cy + 1;
+        CellCoordinates.right = (x + 1) * m_CellSize.cx + 2;
+        CellCoordinates.bottom = (y + 1) * m_CellSize.cy + 2;
+
+        m_Cells[y][x]->SetCellCoordinates(CellCoordinates);
+    }
+
+    return true;
+}
+
+LRESULT
+CGridView::OnCreate(
+    _In_ HWND hwnd,
+    _In_ HWND hParent
+    )
+{
+    m_hwnd = hwnd;
+    m_hParent = hParent;
+
+    // C++ doesn't allow : "CCells ***C = new CCell***[x * y]"
+    // so we have to build the 2d array up manually
+    m_Cells = new CCell**[m_yNumCells]; // rows
+    for (int i = 0; i < m_yNumCells; i++)
+        m_Cells[i] = new CCell*[m_xNumCells]; // columns
+
+    for (int y = 0; y < m_yNumCells; y++)
+    for (int x = 0; x < m_xNumCells; x++)
+    {
+        m_Cells[y][x] = new CCell(m_hwnd);
+    }
+
+    // Give the first cell focus
+    SetCellFocus(m_Cells[0][0]);
+
+    return 0;
+}
+
+LRESULT
+CGridView::OnSize(
+    _In_ INT Width,
+    _In_ INT Height
+    )
+{
+    // Get the client area of the main dialog
+    RECT ParentRect;
+    GetClientRect(m_hParent, &ParentRect);
+
+    // Calculate the grid size using the parent
+    m_ClientCoordinates.left = ParentRect.left + 25;
+    m_ClientCoordinates.top = ParentRect.top + 50;
+    m_ClientCoordinates.right = ParentRect.right - m_ClientCoordinates.left - 10;
+    m_ClientCoordinates.bottom = ParentRect.bottom - m_ClientCoordinates.top - 70;
+
+    SetWindowPos(m_hwnd,
+                 NULL,
+                 m_ClientCoordinates.left,
+                 m_ClientCoordinates.top,
+                 m_ClientCoordinates.right,
+                 m_ClientCoordinates.bottom,
+                 SWP_NOZORDER | SWP_SHOWWINDOW);
+
+    // Get the client area we can draw on. The position we set above
+    // includes a scrollbar. GetClientRect gives us the size without
+    // the scroll, and it more efficient than getting the scroll
+    // metrics and calculating the size
+    RECT ClientRect;
+    GetClientRect(m_hwnd, &ClientRect);
+    m_CellSize.cx = ClientRect.right / m_xNumCells;
+    m_CellSize.cy = ClientRect.bottom / m_yNumCells;
+
+    UpdateGridLayout();
+
+    return 0;
+}
+
+LRESULT
+CGridView::OnPaint(
+    _In_opt_ HDC hdc
+    )
+{
+    PAINTSTRUCT PaintStruct = { 0 };
+    HDC LocalHdc = NULL;
+    BOOL bSuccess = FALSE;
+
+    // Check if we were passed a DC
+    if (hdc == NULL)
+    {
+        // We weren't, let's get one
+        LocalHdc = BeginPaint(m_hwnd, &PaintStruct);
+        if (LocalHdc) bSuccess = TRUE;
+    }
+    else
+    {
+        // Use the existing DC and just get the region to paint
+        bSuccess = GetUpdateRect(m_hwnd,
+                                 &PaintStruct.rcPaint,
+                                 TRUE);
+        if (bSuccess)
+        {
+            // Update the struct with the DC we were passed
+            PaintStruct.hdc = (HDC)hdc;
+        }
+    }
+
+    if (bSuccess)
+    {
+        DrawGrid(&PaintStruct);
+
+        if (LocalHdc)
+        {
+            EndPaint(m_hwnd, &PaintStruct);
+        }
+    }
+
+    return 0;
+}
+
+LRESULT
+CALLBACK
+CGridView::MapWndProc(
+    HWND hwnd,
+    UINT uMsg,
+    WPARAM wParam,
+    LPARAM lParam
+    )
+{
+    CGridView *This;
+    LRESULT RetCode = 0;
+
+    // Get the object pointer from window context
+    This = (CGridView *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+    if (This == NULL)
+    {
+        // Check that this isn't a create message
+        if (uMsg != WM_CREATE)
+        {
+            // Don't handle null info pointer
+            goto HandleDefaultMessage;
+        }
+    }
+
+    switch (uMsg)
+    {
+    case WM_CREATE:
+    {
+        // Get the object pointer from the create param
+        This = (CGridView *)((LPCREATESTRUCT)lParam)->lpCreateParams;
+
+        // Store the pointer in the window's global user data
+        SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)This);
+
+        This->OnCreate(hwnd, ((LPCREATESTRUCTW)lParam)->hwndParent);
+        break;
+    }
+
+    case WM_SIZE:
+    {
+        INT Width, Height;
+        Width = LOWORD(lParam);
+        Height = HIWORD(lParam);
+
+        This->OnSize(Width, Height);
+        break;
+    }
+
+    case WM_PAINT:
+    {
+        This->OnPaint((HDC)wParam);
+        break;
+    }
+
+    case WM_DESTROY:
+    {
+        This->DeleteCells();
+        break;
+    }
+
+    default:
+    {
+HandleDefaultMessage:
+        RetCode = DefWindowProcW(hwnd, uMsg, wParam, lParam);
+        break;
+    }
+    }
+
+    return RetCode;
+}
+
+
+void
+CGridView::DrawGrid(
+    _In_ LPPAINTSTRUCT PaintStruct
+    )
+{
+    // Traverse all the cells and tell them to paint themselves
+    for (int y = 0; y < m_yNumCells; y++)
+    for (int x = 0; x < m_xNumCells; x++)
+    {
+        m_Cells[y][x]->OnPaint(*PaintStruct);
+    }
+}
+
+void
+CGridView::DeleteCells()
+{
+    if (m_Cells == nullptr)
+        return;
+
+    // Free cells withing the 2d array
+    for (int i = 0; i < m_yNumCells; i++)
+        delete[] m_Cells[i];
+    delete[] m_Cells;
+
+    m_Cells = nullptr;
+}
+
+void
+CGridView::SetCellFocus(
+    _In_ CCell* NewActiveCell
+    )
+{
+    if (m_ActiveCell)
+    {
+        // Remove focus from any existing cell
+        m_ActiveCell->SetFocus(false);
+    }
+
+    // Set the new active cell and give it focus
+    m_ActiveCell = NewActiveCell;
+    m_ActiveCell->SetFocus(true);
+}
\ No newline at end of file
diff --git a/reactos/base/applications/charmap_new/GridView.h b/reactos/base/applications/charmap_new/GridView.h
new file mode 100644 (file)
index 0000000..acc2615
--- /dev/null
@@ -0,0 +1,85 @@
+#pragma once
+#include "Cell.h"
+
+//typedef struct _CELL
+//{
+//    RECT CellExt;
+//    RECT CellInt;
+//    BOOL bActive;
+//    BOOL bLarge;
+//    WCHAR ch;
+//
+//} CELL, *PCELL;
+
+#define MAX_GLYPHS 0xFFFF
+
+
+class CGridView
+{
+private:
+    CAtlStringW m_szMapWndClass;
+
+    HWND m_hwnd;
+    HWND m_hParent;
+
+    int m_xNumCells;
+    int m_yNumCells;
+
+    RECT m_ClientCoordinates;
+    //SIZE ClientSize;
+    SIZE m_CellSize;
+    CCell*** m_Cells; // m_Cells[][];
+    CCell *m_ActiveCell;
+
+    HFONT hFont;
+    LOGFONTW CurrentFont;
+    INT iYStart;
+
+    USHORT ValidGlyphs[MAX_GLYPHS];
+    USHORT NumValidGlyphs;
+
+public:
+    CGridView();
+    ~CGridView();
+
+    bool Create(
+        _In_ HWND hParent
+        );
+
+private:
+    static LRESULT
+        CALLBACK
+        MapWndProc(HWND hwnd,
+                   UINT uMsg,
+                   WPARAM wParam,
+                   LPARAM lParam);
+
+    LRESULT OnCreate(
+        _In_ HWND hwnd,
+        _In_ HWND hParent
+        );
+
+
+    LRESULT OnSize(
+        _In_ INT Width,
+        _In_ INT Height
+        );
+
+    LRESULT OnPaint(
+        _In_opt_ HDC hdc
+        );
+
+    bool UpdateGridLayout(
+        );
+
+    void DrawGrid(
+        _In_ LPPAINTSTRUCT PaintStruct
+        );
+
+    void DeleteCells();
+
+    void SetCellFocus(
+        _In_ CCell* NewActiveCell
+        );
+};
+
diff --git a/reactos/base/applications/charmap_new/MainWindow.cpp b/reactos/base/applications/charmap_new/MainWindow.cpp
new file mode 100644 (file)
index 0000000..82f0796
--- /dev/null
@@ -0,0 +1,507 @@
+/*
+* PROJECT:     ReactOS Character Map
+* LICENSE:     GPL - See COPYING in the top level directory
+* FILE:        base/applications/charmap/MainWindow.cpp
+* PURPOSE:     Implements the main dialog window
+* COPYRIGHT:   Copyright 2015 Ged Murphy <gedmurphy@reactos.org>
+*/
+
+
+#include "precomp.h"
+#include "MainWindow.h"
+
+
+/* DATA *****************************************************/
+
+#define ID_ABOUT    0x1
+
+HINSTANCE g_hInstance = NULL;
+
+
+/* PUBLIC METHODS **********************************************/
+
+CCharMapWindow::CCharMapWindow(void) :
+    m_hMainWnd(NULL),
+    m_hStatusBar(NULL),
+    m_CmdShow(0),
+    m_hRichEd(NULL),
+    m_GridView(nullptr)
+{
+    m_GridView = new CGridView();
+}
+
+CCharMapWindow::~CCharMapWindow(void)
+{
+}
+
+bool
+CCharMapWindow::Create(_In_ HINSTANCE hInst,
+                       _In_ int nCmdShow)
+{
+    INITCOMMONCONTROLSEX icex;
+    CAtlStringW szAppName;
+    int Ret = 1;
+
+    // Store the instance
+    g_hInstance = hInst;
+    m_CmdShow = nCmdShow;
+
+    // Initialize common controls
+    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
+    icex.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES;
+    InitCommonControlsEx(&icex);
+
+    // Load the application name
+    if (szAppName.LoadStringW(g_hInstance, IDS_TITLE))
+    {
+        // Initialize the main window
+        if (Initialize(szAppName, nCmdShow))
+        {
+            // Run the application
+            Ret = Run();
+
+            // Uninitialize the main window
+            Uninitialize();
+        }
+    }
+
+    return (Ret == 0);
+}
+
+
+
+/* PRIVATE METHODS **********************************************/
+
+bool
+CCharMapWindow::Initialize(_In_z_ LPCTSTR lpCaption,
+                           _In_ int nCmdShow)
+{
+    // The dialog has a rich edit text box
+    m_hRichEd = LoadLibraryW(L"riched20.DLL");
+    if (m_hRichEd == NULL) return false;
+
+    return !!(CreateDialogParamW(g_hInstance,
+                                 MAKEINTRESOURCE(IDD_CHARMAP),
+                                 NULL,
+                                 DialogProc,
+                                 (LPARAM)this));
+}
+
+void
+CCharMapWindow::Uninitialize(void)
+{
+    if (m_hRichEd)
+        FreeLibrary(m_hRichEd);
+}
+
+int
+CCharMapWindow::Run(void)
+{
+    MSG Msg;
+
+    // Pump the message queue 
+    while (GetMessageW(&Msg, NULL, 0, 0) != 0)
+    {
+        TranslateMessage(&Msg);
+        DispatchMessageW(&Msg);
+    }
+
+    return 0;
+}
+
+void
+CCharMapWindow::UpdateStatusBar(_In_ bool InMenuLoop)
+{
+    SendMessageW(m_hStatusBar,
+                 SB_SIMPLE,
+                 (WPARAM)InMenuLoop,
+                 0);
+}
+
+bool
+CCharMapWindow::CreateStatusBar(void)
+{
+    int StatWidths[] = { 110, -1 }; // widths of status bar
+    bool bRet = FALSE;
+
+    // Create the status bar
+    m_hStatusBar = CreateWindowExW(0,
+                                   STATUSCLASSNAME,
+                                   NULL,
+                                   WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
+                                   0, 0, 0, 0,
+                                   m_hMainWnd,
+                                   (HMENU)IDD_STATUSBAR,
+                                   g_hInstance,
+                                   NULL);
+    if (m_hStatusBar)
+    {
+        // Create the sections
+        bRet = (SendMessageW(m_hStatusBar,
+                             SB_SETPARTS,
+                             sizeof(StatWidths) / sizeof(int),
+                             (LPARAM)StatWidths) != 0);
+
+        // Set the status bar for multiple parts output
+        SendMessage(m_hStatusBar, SB_SIMPLE, (WPARAM)FALSE, (LPARAM)0);
+    }
+
+    return bRet;
+}
+
+bool
+CCharMapWindow::StatusBarLoadString(_In_ HWND hStatusBar,
+                                    _In_ INT PartId,
+                                    _In_ HINSTANCE hInstance,
+                                    _In_ UINT uID)
+{
+    CAtlStringW szMessage;
+    bool bRet = false;
+
+    // Load the string from the resource
+    if (szMessage.LoadStringW(hInstance, uID))
+    {
+        // Display it on the status bar
+        bRet = (SendMessageW(hStatusBar,
+                             SB_SETTEXT,
+                             (WPARAM)PartId,
+                             (LPARAM)szMessage.GetBuffer()) != 0);
+    }
+
+    return bRet;
+}
+
+BOOL
+CCharMapWindow::OnCreate(_In_ HWND hDlg)
+{
+    m_hMainWnd = hDlg;
+
+    if (!CreateStatusBar())
+        return FALSE;
+
+    if (!m_GridView->Create(hDlg))
+        return FALSE;
+
+    // Load an 'about' option into the system menu
+    HMENU hSysMenu;
+    hSysMenu = GetSystemMenu(m_hMainWnd, FALSE);
+    if (hSysMenu != NULL)
+    {
+        CAtlStringW AboutText;
+        if (AboutText.LoadStringW(IDS_ABOUT))
+        {
+            AppendMenuW(hSysMenu, MF_SEPARATOR, 0, NULL);
+            AppendMenuW(hSysMenu, MF_STRING, ID_ABOUT, AboutText);
+        }
+    }
+
+    // Add all the fonts to the 
+    if (!CreateFontComboBox())
+        return FALSE;
+
+    // Configure Richedit control for sending notification changes.
+    DWORD evMask;
+    evMask = SendDlgItemMessage(hDlg, IDC_TEXTBOX, EM_GETEVENTMASK, 0, 0);
+    evMask |= ENM_CHANGE;
+    SendDlgItemMessage(hDlg, IDC_TEXTBOX, EM_SETEVENTMASK, 0, (LPARAM)evMask);
+
+    // Display the window according to the user request
+    ShowWindow(m_hMainWnd, m_CmdShow);
+
+    return TRUE;
+}
+
+BOOL
+CCharMapWindow::OnSize(void)
+{
+    RECT rcClient, rcStatus;
+    INT lvHeight, iStatusHeight;
+
+    // Resize the status bar
+    SendMessage(m_hStatusBar, WM_SIZE, 0, 0);
+
+    // Get the statusbar rect and save the height
+    GetWindowRect(m_hStatusBar, &rcStatus);
+    iStatusHeight = rcStatus.bottom - rcStatus.top;
+
+    // Get the full client rect
+    GetClientRect(m_hMainWnd, &rcClient);
+
+    // Calculate the remaining height for the treeview
+    lvHeight = rcClient.bottom - iStatusHeight;
+
+    // Resize the device view
+    //m_GridView->OnSize(0,
+    //                     iToolHeight,
+    //                     rcClient.right,
+    //                     lvHeight);
+
+    return TRUE;
+}
+
+BOOL
+CCharMapWindow::OnNotify(_In_ LPARAM lParam)
+{
+    LPNMHDR NmHdr = (LPNMHDR)lParam;
+    LRESULT Ret = 0;
+
+    switch (NmHdr->code)
+    {
+    case NM_RCLICK:
+    {
+        break;
+    }
+
+    case NM_DBLCLK:
+    case NM_RETURN:
+    {
+        break;
+    }
+    }
+
+    return Ret;
+}
+
+BOOL
+CCharMapWindow::OnContext(_In_ LPARAM lParam)
+{
+    return 0;// m_GridView->OnContextMenu(lParam);
+}
+
+BOOL
+CCharMapWindow::OnCommand(_In_ WPARAM wParam,
+                          _In_ LPARAM /*lParam*/)
+{
+    LRESULT RetCode = 0;
+    WORD Msg;
+
+    // Get the message
+    Msg = LOWORD(wParam);
+
+    switch (Msg)
+    {
+    case IDC_CHECK_ADVANCED:
+        break;
+
+    default:
+        // We didn't handle it
+        RetCode = -1;
+        break;
+    }
+
+    return RetCode;
+}
+
+BOOL
+CCharMapWindow::OnDestroy(void)
+{
+    // Clear the user data pointer
+    SetWindowLongPtr(m_hMainWnd, GWLP_USERDATA, 0);
+
+    // Break the message loop
+    PostQuitMessage(0);
+
+    return TRUE;
+}
+
+INT_PTR CALLBACK
+CCharMapWindow::DialogProc(
+    _In_ HWND   hwndDlg,
+    _In_ UINT   Msg,
+    _In_ WPARAM wParam,
+    _In_ LPARAM lParam
+    )
+{
+    CCharMapWindow *This;
+    LRESULT RetCode = 0;
+
+    // Get the object pointer from window context
+    This = (CCharMapWindow *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+    if (This == NULL)
+    {
+        // Check that this isn't a create message
+        if (Msg != WM_INITDIALOG)
+        {
+            // Don't handle null info pointer
+            return FALSE;
+        }
+    }
+
+    switch (Msg)
+    {
+    case WM_INITDIALOG:
+    {
+        // Get the object pointer from the create param
+        This = (CCharMapWindow *)lParam;
+
+        // Store the pointer in the window's global user data
+        SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)This);
+
+        // Call the create handler
+        return This->OnCreate(hwndDlg);
+    }
+
+    case WM_SIZE:
+    {
+        return This->OnSize();
+    }
+
+    case WM_NOTIFY:
+    {
+        return This->OnNotify(lParam);
+    }
+
+    case WM_CONTEXTMENU:
+    {
+        return This->OnContext(lParam);
+    }
+
+    case WM_COMMAND:
+    {
+        return This->OnCommand(wParam, lParam);
+    }
+
+    case WM_SYSCOMMAND:
+        switch (wParam)
+        {
+        case ID_ABOUT:
+            // Apportion blame
+            MessageBoxW(This->m_hMainWnd,
+                        L"ReactOS Character Map\r\nCopyright Ged Murphy 2015",
+                        L"About",
+                        MB_OK | MB_APPLMODAL);
+            break;
+        }
+        break;
+
+    case WM_ENTERMENULOOP:
+    {
+        This->UpdateStatusBar(true);
+        return TRUE;
+    }
+
+    case WM_EXITMENULOOP:
+    {
+        This->UpdateStatusBar(false);
+        return TRUE;
+    }
+
+    case WM_CLOSE:
+    {
+        // Destroy the main window
+        return DestroyWindow(hwndDlg);
+    }
+
+
+    case WM_DESTROY:
+    {
+        // Call the destroy handler
+        return This->OnDestroy();
+    }
+    }
+
+    return FALSE;
+}
+
+struct EnumFontParams
+{
+    CCharMapWindow *This;
+    HWND hCombo;
+};
+
+int
+CALLBACK
+CCharMapWindow::EnumDisplayFont(ENUMLOGFONTEXW *lpelfe,
+                                NEWTEXTMETRICEXW *lpntme,
+                                DWORD FontType,
+                                LPARAM lParam)
+{
+    EnumFontParams *Params = (EnumFontParams *)lParam;
+    LPWSTR pszName = lpelfe->elfLogFont.lfFaceName;
+
+    /* Skip rotated font */
+    if (pszName[0] == L'@') return 1;
+
+    /* make sure font doesn't already exist in our list */
+    if (SendMessageW(Params->hCombo,
+                     CB_FINDSTRINGEXACT,
+                     0,
+                     (LPARAM)pszName) == CB_ERR)
+    {
+        INT idx;
+        idx = (INT)SendMessageW(Params->hCombo,
+                                CB_ADDSTRING,
+                                0,
+                                (LPARAM)pszName);
+
+        /* record the font's attributes (Fixedwidth and Truetype) */
+        BOOL fFixed = (lpelfe->elfLogFont.lfPitchAndFamily & FIXED_PITCH) ? TRUE : FALSE;
+        BOOL fTrueType = (lpelfe->elfLogFont.lfOutPrecision == OUT_STROKE_PRECIS) ? TRUE : FALSE;
+
+        /* store this information in the list-item's userdata area */
+        SendMessageW(Params->hCombo,
+                     CB_SETITEMDATA,
+                     idx,
+                     MAKEWPARAM(fFixed, fTrueType));
+    }
+
+    return 1;
+}
+
+
+bool
+CCharMapWindow::CreateFontComboBox()
+{
+    HWND hCombo;
+    hCombo = GetDlgItem(m_hMainWnd, IDC_FONTCOMBO);
+
+    NONCLIENTMETRICSW NonClientMetrics;
+    NonClientMetrics.cbSize = sizeof(NONCLIENTMETRICSW);
+    SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
+                          sizeof(NONCLIENTMETRICSW),
+                          &NonClientMetrics,
+                          0);
+
+    // Get a handle to the font
+    HFONT GuiFont;
+    GuiFont = CreateFontIndirectW(&NonClientMetrics.lfMessageFont);
+
+    // Set the font used in the combo box
+    SendMessageW(hCombo,
+                 WM_SETFONT,
+                 (WPARAM)GuiFont,
+                 0);
+
+    // Set the fonts which we want to enumerate
+    LOGFONTW FontsToEnum;
+    ZeroMemory(&FontsToEnum, sizeof(LOGFONTW));
+    FontsToEnum.lfCharSet = DEFAULT_CHARSET;
+
+    // Set the params we want to pass to the callback
+    EnumFontParams Params;
+    Params.This = this;
+    Params.hCombo = hCombo;
+
+    // Get a DC for combo box
+    HDC hdc;
+    hdc = GetDC(hCombo);
+
+    // Enumerate all the fonts
+    int ret;
+    ret = EnumFontFamiliesExW(hdc,
+                              &FontsToEnum,
+                              (FONTENUMPROCW)EnumDisplayFont,
+                              (LPARAM)&Params,
+                              0);
+
+    ReleaseDC(hCombo, hdc);
+    DeleteObject(GuiFont);
+
+    // Select the first item in the list
+    SendMessageW(hCombo,
+                 CB_SETCURSEL,
+                 0,
+                 0);
+
+    return (ret == 1);
+}
\ No newline at end of file
diff --git a/reactos/base/applications/charmap_new/MainWindow.h b/reactos/base/applications/charmap_new/MainWindow.h
new file mode 100644 (file)
index 0000000..72a0290
--- /dev/null
@@ -0,0 +1,81 @@
+#pragma once
+#include "GridView.h"
+
+class CCharMapWindow
+{
+    HWND m_hMainWnd;
+    HWND m_hStatusBar;
+    int m_CmdShow;
+    HMODULE m_hRichEd;
+
+    CGridView *m_GridView;
+
+public:
+    CCharMapWindow(void);
+    ~CCharMapWindow(void);
+
+    bool Create(
+        _In_ HINSTANCE hInst,
+        _In_ int nCmdShow
+        );
+
+private:
+    static INT_PTR CALLBACK DialogProc(
+        _In_ HWND   hwndDlg,
+        _In_ UINT   uMsg,
+        _In_ WPARAM wParam,
+        _In_ LPARAM lParam
+        );
+
+    bool Initialize(
+        _In_z_ LPCTSTR lpCaption,
+        _In_ int nCmdShow
+        );
+
+    int Run();
+    void Uninitialize(void);
+
+    BOOL OnCreate(
+        _In_ HWND hwnd
+        );
+
+    BOOL OnDestroy(void);
+    BOOL OnSize(void);
+
+    BOOL OnNotify(
+        _In_ LPARAM lParam
+        );
+
+    BOOL OnContext(
+        _In_ LPARAM lParam
+        );
+
+    BOOL OnCommand(
+        _In_ WPARAM wParam,
+        LPARAM lParam
+        );
+
+    bool CreateStatusBar(void);
+
+    bool StatusBarLoadString(
+        _In_ HWND hStatusBar,
+        _In_ INT PartId,
+        _In_ HINSTANCE hInstance,
+        _In_ UINT uID
+        );
+
+    void UpdateStatusBar(
+        _In_ bool InMenuLoop
+        );
+
+    static int CALLBACK
+    EnumDisplayFont(
+        ENUMLOGFONTEXW *lpelfe,
+        NEWTEXTMETRICEXW *lpntme,
+        DWORD FontType,
+        LPARAM lParam
+        );
+
+    bool CreateFontComboBox(
+        );
+};
\ No newline at end of file
diff --git a/reactos/base/applications/charmap_new/charmap.cpp b/reactos/base/applications/charmap_new/charmap.cpp
new file mode 100644 (file)
index 0000000..e445f9f
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+* PROJECT:     ReactOS Device Managment
+* LICENSE:     GPL - See COPYING in the top level directory
+* FILE:        base/applications/mscutils/devmgmt/devmgmt.c
+* PURPOSE:     Bootstrap for the device manager
+* COPYRIGHT:   Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
+*/
+
+#include "precomp.h"
+#include "MainWindow.h"
+
+int WINAPI
+wWinMain(HINSTANCE hThisInstance,
+         HINSTANCE hPrevInstance,
+         LPWSTR lpCmdLine,
+         int nCmdShow)
+{
+    CCharMapWindow CharMap;
+    return CharMap.Create(hThisInstance, nCmdShow);
+}
diff --git a/reactos/base/applications/charmap_new/charmap.rc b/reactos/base/applications/charmap_new/charmap.rc
new file mode 100644 (file)
index 0000000..878a785
--- /dev/null
@@ -0,0 +1,101 @@
+#include <windef.h>
+#include <winuser.h>
+#include <richedit.h>
+
+#include "resource.h"
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+IDI_ICON ICON "res/charmap.ico"
+
+#define REACTOS_STR_FILE_DESCRIPTION  "ReactOS Character Map"
+#define REACTOS_STR_INTERNAL_NAME     "charmap"
+#define REACTOS_STR_ORIGINAL_FILENAME "charmap.exe"
+//#include <reactos/version.rc>
+
+//#include <reactos/manifest_exe.rc>
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+#ifdef LANGUAGE_BG_BG
+#include "lang/bg-BG.rc"
+#endif
+#ifdef LANGUAGE_CA_ES
+#include "lang/ca-ES.rc"
+#endif
+#ifdef LANGUAGE_CS_CZ
+#include "lang/cs-CZ.rc"
+#endif
+#ifdef LANGUAGE_DE_DE
+#include "lang/de-DE.rc"
+#endif
+#ifdef LANGUAGE_EN_US
+#include "lang/en-US.rc"
+#endif
+#ifdef LANGUAGE_EL_GR
+#include "lang/el-GR.rc"
+#endif
+#ifdef LANGUAGE_ES_ES
+#include "lang/es-ES.rc"
+#endif
+#ifdef LANGUAGE_FR_FR
+#include "lang/fr-FR.rc"
+#endif
+#ifdef LANGUAGE_HE_IL
+#include "lang/he-IL.rc"
+#endif
+#ifdef LANGUAGE_ID_ID
+#include "lang/id-ID.rc"
+#endif
+#ifdef LANGUAGE_IT_IT
+#include "lang/it-IT.rc"
+#endif
+#ifdef LANGUAGE_JA_JP
+#include "lang/ja-JP.rc"
+#endif
+#ifdef LANGUAGE_KO_KR
+#include "lang/ko-KR.rc"
+#endif
+#ifdef LANGUAGE_LT_LT
+#include "lang/lt-LT.rc"
+#endif
+#ifdef LANGUAGE_NL_NL
+#include "lang/nl-NL.rc"
+#endif
+#ifdef LANGUAGE_NB_NO
+#include "lang/no-NO.rc"
+#endif
+#ifdef LANGUAGE_PL_PL
+#include "lang/pl-PL.rc"
+#endif
+#ifdef LANGUAGE_PT_BR
+#include "lang/pt-BR.rc"
+#endif
+#ifdef LANGUAGE_RO_RO
+#include "lang/ro-RO.rc"
+#endif
+#ifdef LANGUAGE_RU_RU
+#include "lang/ru-RU.rc"
+#endif
+#ifdef LANGUAGE_SK_SK
+#include "lang/sk-SK.rc"
+#endif
+#ifdef LANGUAGE_SQ_AL
+#include "lang/sq-AL.rc"
+#endif
+#ifdef LANGUAGE_SV_SE
+#include "lang/sv-SE.rc"
+#endif
+#ifdef LANGUAGE_TR_TR
+#include "lang/tr-TR.rc"
+#endif
+#ifdef LANGUAGE_UK_UA
+#include "lang/uk-UA.rc"
+#endif
+#ifdef LANGUAGE_ZH_CN
+#include "lang/zh-CN.rc"
+#endif
+#ifdef LANGUAGE_ZH_TW
+#include "lang/zh-TW.rc"
+#endif
diff --git a/reactos/base/applications/charmap_new/lang/en-US.rc b/reactos/base/applications/charmap_new/lang/en-US.rc
new file mode 100644 (file)
index 0000000..f0106ec
--- /dev/null
@@ -0,0 +1,33 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+IDD_CHARMAP DIALOGEX 6, 6, 292, 224
+FONT 8, "MS Shell Dlg", 0, 0
+STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
+CAPTION "ReactOS Character Map"
+BEGIN
+    LTEXT "Font:", IDC_STATIC, 6, 7, 24, 9
+    COMBOBOX IDC_FONTCOMBO, 36, 5, 210, 210, WS_CHILD | WS_VISIBLE |
+             WS_VSCROLL | CBS_DROPDOWNLIST | CBS_SORT | CBS_HASSTRINGS
+    LTEXT "Characters to copy:", IDC_STATIC, 6, 188, 66, 9
+    CONTROL "", IDC_TEXTBOX, RICHEDIT_CLASS, ES_AUTOHSCROLL | WS_BORDER |
+            WS_CHILD | WS_VISIBLE | WS_TABSTOP, 74, 186, 114, 13
+    DEFPUSHBUTTON "Select", IDC_SELECT, 194, 186, 44, 13
+    PUSHBUTTON "Copy", IDC_COPY, 242, 186, 44, 13, WS_DISABLED
+    //CONTROL "Advanced view", IDC_CHECK_ADVANCED, "Button", BS_AUTOCHECKBOX |
+    //        WS_TABSTOP, 8, 208, 95, 10
+    //LTEXT "Charset:", IDC_STATIC, 8, 8, 48, 8
+    //COMBOBOX IDC_COMBO_CHARSET, 72, 4, 116, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    //LTEXT "Group by:", IDC_STATIC, 8, 28, 50, 8
+    //COMBOBOX IDC_COMBO_GROUPBY, 72, 24, 116, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+    //PUSHBUTTON "Search", IDC_BUTTON_SEARCH, 200, 44, 50, 14
+    //EDITTEXT IDC_EDIT_SEARCH, 72, 44, 116, 14, ES_AUTOHSCROLL
+    //LTEXT "Search for:", IDC_STATIC, 8, 48, 42, 8
+    //LTEXT "Unicode:", IDC_STATIC, 200, 8, 30, 8
+    //EDITTEXT IDC_EDIT_UNICODE, 236, 4, 28, 12, ES_AUTOHSCROLL
+END
+
+STRINGTABLE
+BEGIN
+    IDS_ABOUT "A&bout..."
+    IDS_TITLE "Character Map"
+END
diff --git a/reactos/base/applications/charmap_new/precomp.h b/reactos/base/applications/charmap_new/precomp.h
new file mode 100644 (file)
index 0000000..2a1d322
--- /dev/null
@@ -0,0 +1,54 @@
+//#pragma once
+
+#ifndef __REACTOS__
+
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#include <windowsx.h>
+#include <setupapi.h>
+#include <cfgmgr32.h>
+#include <commctrl.h>
+#include <Uxtheme.h>
+#include <richedit.h>
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // some CString constructors will be explicit
+#include <tchar.h>
+#include <atlbase.h>
+#include <atlstr.h>
+#include <atlcoll.h>
+
+#include <strsafe.h>
+
+
+#define WINE_DEFAULT_DEBUG_CHANNEL(t)
+
+#include "resource.h"
+
+
+#else
+
+#include <string.h>
+#include <wchar.h>
+
+#include <tchar.h>
+#include <windef.h>
+#include <winbase.h>
+#include <winreg.h>
+#include <wingdi.h>
+#include <winnls.h>
+#include <wincon.h>
+#include <shlobj.h>
+#include <shlwapi.h>
+#include <strsafe.h>
+
+#include <commctrl.h>
+#include <cfgmgr32.h>
+#include <uxtheme.h>
+
+#include <atlbase.h>
+#include <atlstr.h>
+#include <atlcoll.h>
+
+//WINE_DEFAULT_DEBUG_CHANNEL(charmap);
+
+#endif
\ No newline at end of file
diff --git a/reactos/base/applications/charmap_new/res/charmap.ico b/reactos/base/applications/charmap_new/res/charmap.ico
new file mode 100644 (file)
index 0000000..50bdac5
Binary files /dev/null and b/reactos/base/applications/charmap_new/res/charmap.ico differ
diff --git a/reactos/base/applications/charmap_new/resource.h b/reactos/base/applications/charmap_new/resource.h
new file mode 100644 (file)
index 0000000..212f210
--- /dev/null
@@ -0,0 +1,30 @@
+#pragma once
+
+#define IDC_STATIC -1
+
+#define IDI_ICON 100
+
+#define IDD_CHARMAP   200
+#define IDD_ABOUTBOX  201
+#define IDD_STATUSBAR 202
+#define IDD_ADVANCED  203
+
+#define IDC_FONTCOMBO      1001
+#define IDC_CMHELP         1002
+#define IDC_FONTMAP        1003
+#define IDC_TEXTBOX        1004
+#define IDC_SELECT         1005
+#define IDC_COPY           1006
+#define IDC_ADVVIEW        1007
+#define IDC_DISPLAY        1008
+#define IDC_LICENSE_EDIT   1009
+#define IDC_COMBO_CHARSET  1010
+#define IDC_COMBO_GROUPBY  1011
+#define IDC_BUTTON_SEARCH  1012
+#define IDC_EDIT_SEARCH    1013
+#define IDC_EDIT_UNICODE   1014
+#define IDC_CHECK_ADVANCED 1017
+
+#define IDS_LICENSE 2010
+#define IDS_ABOUT   2011
+#define IDS_TITLE   2012