SOL9 Sample: ImageViewer

SOL9 2.0 Samples

1 Screenshot


2 Source code

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


// SOL9

// 2012/04/15 Updated to accept dropfiles.
// 2012/04/15 Updated to be able to select gif files in a fileDialog.
// 2012/07/14 Added an eventHandler for WM_ERASEBKGND message to avoid fiickering,
//      and updated paint method. 

#define COMMONCONTROLS_V6

#include <sol\ApplicationView.h>
#include <sol\PaintDC.h>
#include <sol\Brush.h>
#include <sol\FileDialog.h>
#include <sol\DropFiles.h>
#include <sol\Profile.h>
#include <sol\Folder.h>
#include <comutil.h>
#include "resource.h"


using namespace Gdiplus;

namespace SOL {

class ImageViewer :public ApplicationView {

private:
  FileDialog    fileDialog;

  _bstr_t imageFileName;

  Image*  image;

public:
  /**
   * Constructor
   */
  ImageViewer(Application& applet, const TCHAR* name, Args& args)
  :ApplicationView(applet, name,
    args.set(XmNstyle,  (ulong)WS_VSCROLL|WS_HSCROLL|WS_CLIPCHILDREN)
        .set(XmNexStyle,(ulong)WS_EX_ACCEPTFILES) ) //2012/04/15 Accept dropFiles
  {
    addCallback(XmNmenuCallback, IDM_OPEN, this,
      (Callback)&ImageViewer::open, NULL);
    addCallback(XmNmenuCallback, IDM_EXIT, this,
      (Callback)&ImageViewer::exit, NULL);

    addCallback(XmNmenuCallback, IDM_VERSION, this,
      (Callback)&ImageViewer::version, NULL);

    addEventHandler(WM_PAINT, this, 
      (Handler)&ImageViewer::paint, NULL);
    //2012/07/14
    addEventHandler(WM_ERASEBKGND, this, 
      (Handler)&ImageViewer::erase, NULL);

    addEventHandler(WM_DROPFILES, this, 
      (Handler)&ImageViewer::dropFiles, NULL);

    addEventHandler(WM_SIZE, this, 
      (Handler)&ImageViewer::size, NULL);

    addEventHandler(WM_CLOSE, this, 
      (Handler)&ImageViewer::close, NULL);

  
    Args ar;
    //2012/04/16 Updated to incude gif fies.
    ar.set(XmNfilter, 
      _T("Image File(*.bmp,*.jpg,*.png,*.tif,*.ico,*.gif)\0*.bmp;*.jpg;*.png;*.tif;*.ico;*.gif\0JPEG File*.jpg)\0*.jpg\0PNG File(*.png)\0*.png\0Tiff File(*.tif)\0*.tif\0Icon File(*.ico)\0*.ico;\0GIF File(*.gif)\0*.gif;\0"));

    fileDialog.create(this, _T(""), ar);
    image = NULL;

    restorePlacement();
  }

public:
  ~ImageViewer()
  {
    clear();
  }

private:
  void clear()
  {
    if (image) {
      delete image;
      image = NULL;
    }
  }

private:
  bool isTransparentImage(Gdiplus::Image* image)
  {
    bool rc = false;
    if (image) {
      GUID guid;
      Gdiplus::Status stat = image->GetRawFormat(&guid);
      if (guid == Gdiplus::ImageFormatIcon ||
        guid == Gdiplus::ImageFormatPNG ||
        guid == Gdiplus::ImageFormatTIFF) {
          rc = true;
      }
    }
    return rc;
  }

private:
  //2012/07/14
  long erase(Event& event)
  {
    if (image) {
      if (isTransparentImage(image)) {
        //If the image has a transparent attribute, you need to erase
        //the background of this window.
        return defaultProc(event);
      }
    } 
    
    return TRUE;
  }
  
public:
  //2012/07/15
  virtual void doHorizScroll(Action& action)
  {
    int diff = (int)action.getValue();
    if (diff) {
      if (isTransparentImage(image)) {
        invalidateAll();
      }
      scroll(diff, 0, NULL, NULL);
      update();
    }
  }

public:
  //2012/07/15
  virtual void doVertScroll(Action& action)
  {
    int diff = (int)action.getValue();
    if (diff) {
      if (isTransparentImage(image)) {
        invalidateAll();
      }
      scroll(0, diff, NULL, NULL);
      update();
    }
  }

private:
  void drawImage(_bstr_t& imageFieName)
  {
    TCHAR title[MAX_PATH];
    clear();
    try {
      image = new Image((const wchar_t*)imageFileName, TRUE);
      if (image) {
        _stprintf_s(title, CountOf(title), _T("%s - ImageViewer"), (const TCHAR*)imageFileName);
        setText(title);

        setScrollPos(HORIZONTAL, 0);
        setScrollPos(VERTICAL, 0);

        UINT width  = image->GetWidth();
        UINT height = image->GetHeight();

        setScrollExtent(width, height);
        invalidateAll();
        update();
      }
    } catch (...) {

    }
  }

private:
  //2012/04/16 EventHandler for WM_DROPFILES
  long dropFiles(Event& event) 
  {
    TCHAR fileName[1024];
    DropFiles drop((HDROP)event.getWParam());
    fileName[0] = ZERO;
    int num = drop.queryFile(0, fileName, CountOf(fileName));

    if(num > 0) {
      imageFileName = fileName;
      drawImage(imageFileName);
    }
    return 0;
  }

private:
  long close(Event& event)
  {
    savePlacement();
    return defaultProc(event);
  }

private:
  void  open(Action& action)
  {
    Args ar;
    
    TCHAR dir[MAX_PATH];
    memset(dir, (TCHAR)0, CountOf(dir));
    //Call getFileFolder method in SOL::ApplicationView.
    //This gets a previously select folder from a registry(profile of this application) for fileDialog
    if (restoreFileFolder(dir, CountOf(dir))) {
      ar.set(XmNdirectory, dir);
      fileDialog.setValues(ar);
    }
  
    if(fileDialog.open()){
      TCHAR title[MAX_PATH];

      imageFileName = fileDialog.getFileName();
      TCHAR* filename = fileDialog.getFileName();

      TCHAR* ftitle = fileDialog.getFileTitle();
    
      File file;
      if (file.isExistent(filename)) {
        //Call saveFileFolder method in SOL::ApplicationView.
        saveFileFolder(filename);

        drawImage(imageFileName);
      }
    }  
  }


private:
  void updateScrollRange()
  {
    if (image) {
      UINT width = image->GetWidth();
      UINT height = image->GetHeight();
      setScrollExtent(width, height);
    }
  }

private:
  long size(Event& event)
  {
    updateScrollRange();
    return 0;
  }

private:
  void version(Action& action)
  {
    showMessageDialog(_T("Version"),
      _T("ImageViewer 1.0.0.4 \r\n Copyright(c) 2012 Antillia.com"), MB_ICONINFORMATION|MB_OK);
  }

private:
  long paint(Event& event)
  {
    PaintDC pdc(this);

    Graphics graphics(pdc.get());

        //Image image((const wchar_t*)imageFileName);
    if (image) {
      int x = getScrollPos(Composite::HORIZONTAL);
      int y = getScrollPos(Composite::VERTICAL);
      UINT width = image->GetWidth();
      UINT height = image->GetHeight();
      RECT r;
      getClientRect(&r);
      uint w = r.right - r.left;
      uint h = r.bottom - r.top;

      graphics.DrawImage(image, -x, -y, width, height );

      //Clean dirty areas out of imageArea drawn by above method call.
      if (w>width) {
        RECT rr= {width, 0, w, height};
        if (h>height) {
          rr.bottom = h;
        }
        Brush br(GetSysColor(COLOR_BTNFACE));
        pdc.fillRect(&rr, br);
      }
      if (h>height) {
        RECT rr = {0, height, width, h};
        if (w>width) {
          rr.right = w;
        }
        Brush br(GetSysColor(COLOR_BTNFACE));
        pdc.fillRect(&rr, br);
      }
    }

    return 0;
  }

};

}


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

    Args args;
    
    //2012/06/24
    //args.set(XmNclassStyle, 0);
    
    ImageViewer imageViewer(applet, name, args);
    imageViewer.realize();

    applet.run();

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


Last modified: 1 Feb 2017

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