SOL9 Sample: RichTextEditor

SOL9 2.0 Samples

1 Screenshot


2 Source code

/*
 * RichTextEditor.cpp 
 * Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// SOL++2000
// 2000.02.18

// 2008/09/16 Modified to use restoreFileFolder/saveFileFolder for the directory
// of FileDialog.

#include <sol\ApplicationView.h>
#include <sol\FileDialog.h>
#include <sol\ScrolledRichText.h>
#include <sol\Font.h>
#include <sol\FontDialog.h>
#include <sol\ClientDC.h>
#include <sol\FileStream.h>
#include <sol/MessageFont.h>
#include "resource.h"

namespace SOL {

class RichTextEditor :public ApplicationView {
private:
  ScrolledRichText  text;
  MessageFont      font;
  FileDialog      filedlg;
  FontDialog      fontdlg;


public:
  /*
   * Constructor
   */
  RichTextEditor(Application& applet, const TCHAR* name, Args& args)
  :ApplicationView(applet, name, args)
  {
    Args  ar;
    ar.set(XmNexStyle, (ulong)WS_EX_ACCEPTFILES);
    text.create(this, NULL, ar);
    add(text);

    text.setEventMask(ENM_DROPFILES);
    text.addCallback(XmNdropFilesCallback, this,
      (Callback)&RichTextEditor::dropped, NULL);

    addCallback(XmNmenuCallback, ID_NEW, this,
      (Callback)&RichTextEditor::clear, NULL);
    addCallback(XmNmenuCallback, ID_OPENRTF, this,
      (Callback)&RichTextEditor::openRTF, NULL);
    addCallback(XmNmenuCallback, ID_OPENTEXT, this,
      (Callback)&RichTextEditor::openText, NULL);
    addCallback(XmNmenuCallback, ID_SAVEASRTF, this,
      (Callback)&RichTextEditor::saveAsRTF, NULL);
    addCallback(XmNmenuCallback, ID_SAVEASTEXT, this,
      (Callback)&RichTextEditor::saveAsText, NULL);
    addCallback(XmNmenuCallback, ID_EXIT, this,
      (Callback)&RichTextEditor::exit, NULL);

    addCallback(XmNmenuCallback, ID_BOLD, this,
      (Callback)&RichTextEditor::bold, NULL);
    addCallback(XmNmenuCallback, ID_ITALIC, this,
      (Callback)&RichTextEditor::italic, NULL);
    addCallback(XmNmenuCallback, ID_UNDERLINE, this,
      (Callback)&RichTextEditor::underline, NULL);

    addCallback(XmNmenuCallback, ID_INCSIZE, this,
      (Callback)&RichTextEditor::incSize, NULL);
    addCallback(XmNmenuCallback, ID_DECSIZE, this,
      (Callback)&RichTextEditor::decSize, NULL);

    addCallback(XmNmenuCallback, ID_CHANGEFONT, this,
      (Callback)&RichTextEditor::changeFont, NULL);

    ar.reset();
    filedlg.create(this, NULL, ar);
  
    ar.reset();
    fontdlg.create(this, NULL, ar);

    ClientDC dc(this);


    font.create(9);
    text.setFont(font);
  }


private:

  void setCaption(TCHAR* filename)
  {
    if(filename) {
      TCHAR text[MAX_PATH];
      _stprintf_s(text, CountOf(text), _T("%s - RichTextEditor"), filename);
      setText(text);
    }
  }

  void clear(Action& action)
  {
    text.clear();
  }

  void openRTF(Action& action)
  {
    TCHAR dir[_MAX_PATH];
    if (restoreFileFolder(dir, CountOf(dir))) {
      Args ar;
      ar.set(XmNdirectory, dir);
      filedlg.setValues(ar);
    }

    filedlg.setCaption(_T("Open as RTF"));
    if(filedlg.open()) {
      TCHAR* filename  = filedlg.getFileName();
      text.streamIn(filename, SF_RTF);
      setCaption(filename);
      saveFileFolder(filename);
    }
  }

  void openText(Action& action)
  {
    TCHAR dir[_MAX_PATH];
    if (restoreFileFolder(dir, CountOf(dir))) {
      Args ar;
      ar.set(XmNdirectory, dir);
      filedlg.setValues(ar);
    }

    filedlg.setCaption(_T("Open as Text"));
    if(filedlg.open()) {
      TCHAR* filename  = filedlg.getFileName();
      text.streamIn(filename, SF_TEXT);
      setCaption(filename);
      saveFileFolder(filename);

    }
  }


  void saveAsRTF(Action& action)
  {
    TCHAR dir[_MAX_PATH];
    if (restoreFileFolder(dir, CountOf(dir))) {
      Args ar;
      ar.set(XmNdirectory, dir);
      filedlg.setValues(ar);
    }

    filedlg.setCaption(_T("Sava as RTF"));
    if(filedlg.save()) {
      TCHAR* filename  = filedlg.getFileName();
      text.streamOut(filename, SF_RTF);
      setCaption(filename);
      saveFileFolder(filename);

    }
  }


  void saveAsText(Action& action)
  {
    TCHAR dir[_MAX_PATH];
    if (restoreFileFolder(dir, CountOf(dir))) {
      Args ar;
      ar.set(XmNdirectory, dir);
      filedlg.setValues(ar);
    }

    filedlg.setCaption(_T("Sava as Text"));
    if(filedlg.save()) {
      TCHAR* filename  = filedlg.getFileName();
      text.streamOut(filename, SF_TEXT);
      setCaption(filename);
      saveFileFolder(filename);

    }
  }


  void dropped(Action& action)
  {
    Event& event = action.getEvent();
    ENDROPFILES* endrop = (ENDROPFILES*)event.getLParam();
    HDROP hdrop = (HDROP)endrop->hDrop;
    TCHAR filename[_MAX_PATH];
    ::DragQueryFile(hdrop, 0, filename, CountOf(filename));

    text.streamIn(filename, SF_TEXT|SFF_SELECTION);

  }


  void bold(Action& action)
  {
    CHARFORMAT cf;
    cf.cbSize = sizeof(cf);

    text.getCharFormat(TRUE, &cf);
    cf.dwMask      |= CFM_BOLD;
    cf.dwEffects  ^= CFE_BOLD;  
    text.setCharFormat(SCF_SELECTION, &cf);
  }


  void italic(Action& action)
  {
    CHARFORMAT cf;
    cf.cbSize = sizeof(cf);
    text.getCharFormat(TRUE, &cf);

    cf.dwMask      |= CFM_ITALIC;
    cf.dwEffects  ^= CFE_ITALIC;  
    text.setCharFormat(SCF_SELECTION, &cf);
  }

  void underline(Action& action)
  {
    CHARFORMAT cf;
    cf.cbSize = sizeof(cf);
    text.getCharFormat(TRUE, &cf);

    cf.dwMask      |= CFM_UNDERLINE;
    cf.dwEffects  ^= CFE_UNDERLINE;  
    text.setCharFormat(SCF_SELECTION, &cf);
  }


  void incSize(Action& action)
  {
    CHARFORMAT cf;
    cf.cbSize = sizeof(cf);
    text.getCharFormat(TRUE, &cf);
    cf.dwMask      = CFM_SIZE;

    cf.yHeight += 20*2;

    text.setCharFormat(SCF_SELECTION, &cf);
  }

  void decSize(Action& action)
  {
    CHARFORMAT cf;
    cf.cbSize = sizeof(cf);
    text.getCharFormat(TRUE, &cf);
    cf.dwMask      = CFM_SIZE;

    cf.yHeight += 20*(-2);
    text.setCharFormat(SCF_SELECTION, &cf);
  }


  void changeFont(Action& action)
  {
    CHARFORMAT cf;
    cf.cbSize = sizeof(cf);
    text.getCharFormat(TRUE, &cf);
    LOGFONT lf;

    ClientDC dc(this);
    int logPixelInY = dc.getDeviceCaps(LOGPIXELSY);

    memset(&lf, 0, sizeof(lf));
    lf.lfHeight = MulDiv(cf.yHeight, logPixelInY, -1440);

    if (cf.dwEffects & CFE_BOLD) {
      lf.lfWeight = FW_BOLD;
    }
    else {
      lf.lfWeight = FW_NORMAL;
    }
    lf.lfItalic = (BOOL)(cf.dwEffects & CFE_ITALIC);
    lf.lfUnderline = (BOOL)(cf.dwEffects & CFE_UNDERLINE);
    lf.lfQuality   = DEFAULT_QUALITY;
    lf.lfPitchAndFamily = cf.bPitchAndFamily;
    strcpy_s(lf.lfFaceName, CountOf(lf.lfFaceName), cf.szFaceName);

    //2009/11/04
    CHOOSEFONT* chooseFont = (CHOOSEFONT*)fontdlg.getCallData();
    chooseFont->lpLogFont = &lf;
    chooseFont->Flags = CF_BOTH | CF_SCALABLEONLY | CF_EFFECTS 
                       | CF_NOVECTORFONTS | CF_INITTOLOGFONTSTRUCT;
    chooseFont->rgbColors = cf.crTextColor;
    chooseFont->nFontType = 0;

    if (fontdlg.choose()) {
      cf.dwMask = CFM_BOLD | CFM_FACE | CFM_ITALIC | CFM_COLOR |
          CFM_CHARSET| CFM_STRIKEOUT |
                    CFM_OFFSET | CFM_SIZE | CFM_UNDERLINE;
      cf.yHeight = 2 * chooseFont->iPointSize;
      cf.crTextColor = chooseFont->rgbColors;
      cf.dwEffects = 0;
   
      ClientDC dc(this);

      cf.bCharSet = dc.getTextCharsetInfo(NULL);

      if (lf.lfWeight >= FW_BOLD) {
        cf.dwEffects |= CFE_BOLD;
      }
      if (lf.lfItalic) {
        cf.dwEffects |= CFE_ITALIC;
      }
      if (lf.lfUnderline) {
        cf.dwEffects |= CFE_UNDERLINE;
      }
      cf.bPitchAndFamily = lf.lfPitchAndFamily;
      strcpy_s(cf.szFaceName,  CountOf(cf.szFaceName), lf.lfFaceName);
      //Printf("%s\r\n", cf.szFaceName);

      text.setCharFormat(SCF_SELECTION, &cf);
    }
  }
};

}


//////////////////////////////////////////////////////
// Program Main
void  Main(int argc, TCHAR** argv)
{
  ModuleFileName module(argv[0]);
  const TCHAR* name = module.getFileName();

  try {
    Application applet(name, argc, argv);
    Args args;
    RichTextEditor richTextEditor(applet, name, args);
    richTextEditor.realize();
    applet.run();

  } catch (Exception& ex) {
    caught(ex);
  } catch (...) {
    caught(UnknownException());
  }
}


Last modified: 1 Feb 2017

Copyright (c) 2017 Antillia.com ALL RIGHTS RESERVED.