Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12 kB · 536 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537/** 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){}
boolCCharMapWindow::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 **********************************************/
boolCCharMapWindow::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));}
voidCCharMapWindow::Uninitialize(void){ if (m_hRichEd) FreeLibrary(m_hRichEd);}
intCCharMapWindow::Run(void){ MSG Msg;
// Pump the message queue while (GetMessageW(&Msg, NULL, 0, 0) != 0) { TranslateMessage(&Msg); DispatchMessageW(&Msg); }
return 0;}
voidCCharMapWindow::UpdateStatusBar(_In_ bool InMenuLoop){ SendMessageW(m_hStatusBar, SB_SIMPLE, (WPARAM)InMenuLoop, 0);}
boolCCharMapWindow::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;}
boolCCharMapWindow::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;}
BOOLCCharMapWindow::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 list if (!CreateFontComboBox()) return FALSE;
ChangeMapFont();
// 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;}
BOOLCCharMapWindow::OnSize( _In_ WPARAM wParam ){ 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 gridview lvHeight = rcClient.bottom - iStatusHeight;
// Resize the grid view SendMessageW(m_GridView->GetHwnd(), WM_SIZE, wParam, 0);
return TRUE;}
BOOLCCharMapWindow::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;}
BOOLCCharMapWindow::OnContext(_In_ LPARAM lParam){ return 0;// m_GridView->OnContextMenu(lParam);}
BOOLCCharMapWindow::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;
case IDC_FONTCOMBO: if (HIWORD(wParam) == CBN_SELCHANGE) { ChangeMapFont(); } break;
default: // We didn't handle it RetCode = -1; break; }
return RetCode;}
BOOLCCharMapWindow::OnDestroy(void){ // Clear the user data pointer SetWindowLongPtr(m_hMainWnd, GWLP_USERDATA, 0);
// Break the message loop PostQuitMessage(0);
return TRUE;}
INT_PTR CALLBACKCCharMapWindow::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(wParam); }
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: MessageBoxW(This->m_hMainWnd, L"ReactOS Character Map\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;};
intCALLBACKCCharMapWindow::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;}
boolCCharMapWindow::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);}
boolCCharMapWindow::ChangeMapFont( ){ HWND hCombo; hCombo = GetDlgItem(m_hMainWnd, IDC_FONTCOMBO);
INT Length; Length = GetWindowTextLengthW(hCombo); if (!Length) return false;
CAtlStringW FontName; FontName.Preallocate(Length);
SendMessageW(hCombo, WM_GETTEXT, FontName.GetAllocLength(), (LPARAM)FontName.GetBuffer());
return m_GridView->SetFont(FontName);}