SOL9 Sample: DIBitmapViewer

SOL9 2.0 Samples

1 Screenshot


2 Source code

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



// SOL++2000 
// 2000.02.18
// 2008/09/13 Modified to use DIBSection class

#include <sol\MdiFrame.h>
#include <sol\MdiChild.h>
#include <sol\PaintDC.h>
#include <sol\FileDialog.h>
//#include <sol\Dibitmap.h>
#include <sol\ClientDC.h>
//#include <sol\DIBitmapFile.h>
#include "resource.h"
#include <sol\DIBSection.h>
#include <sol\Profile.h>
#include <sol\Folder.h>

namespace SOL {

// class MdiDIBitmap

class MdiDIBitmap :public MdiChild {
private:
  BOOL  alive;
  DIBSection  dibSection;
  Profile profile;


public:
  /**
   * Construcotr
   */

  MdiDIBitmap(MdiClient* parent, const TCHAR* caption, Args& args)
  :MdiChild(parent, caption, 
    args.set(XmNstyle, 
      (ulong)WS_VISIBLE|WS_CHILD|WS_VSCROLL|WS_HSCROLL))
  {
    alive  = TRUE;
    addEventHandler(WM_PAINT, this,
      (Handler)&MdiDIBitmap::paint, NULL);
    addEventHandler(WM_CLOSE, this,
      (Handler)&MdiDIBitmap::close, NULL);
    addEventHandler(WM_QUERYNEWPALETTE, this,
      (Handler)&MdiDIBitmap::queryNewPalette, NULL);

  }

public:
  ~MdiDIBitmap() 
  {
  }

public:
  BOOL  isAlive() 
  { 
    return alive; 
  }


private:
  long paint(Event& event)
  {
    PaintDC pdc(this);
    int x = getScrollPos(HORIZONTAL);
    int y = getScrollPos(VERTICAL);
    dibSection.draw(pdc, -x, -y);

    return 0L;
  }

private:
  long close(Event& event)
  {
    TCHAR title[256];
    getText(title, CountOf(title));
    int rc = MessageBox(getWindow(), 
      _T("This will close MdiDIBitmap Window."), 
      title, MB_OKCANCEL);
    if(rc == IDOK) {
      defaultProc(event);
      alive  = FALSE;
      return TRUE;
    }
    return FALSE;
  }

private:
  long queryNewPalette(Event& event)
  {
    redraw();
    return 0L;
  }

private:

  void redraw()
  {    
    int w = dibSection.getWidth();
    int h = dibSection.getHeight();

    setScrollExtent(w, h);

    update();
  }

private:
  long mdiActivate(Event& event)
  {
    MdiChild::mdiActivate(event);
    redraw();

    MdiFrame* frame =getMdiFrame();
     frame -> childActivated(this);
    return 0L;
  }

public:
  void load(TCHAR* filename)
  {
    ClientDC cdc(this);
    dibSection.load(cdc, filename);

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

};


/**
 * class DIBitmapViewer
 */
class DIBitmapViewer :public MdiFrame {
private:
  int      max;
  int      num;
  MdiDIBitmap**  images;
  FileDialog filedlg;
  Profile    profile;

public:
  DIBitmapViewer(Application& applet, const TCHAR* caption, Args& args)
  :MdiFrame(applet, caption, args.set(XmNstyle, WS_CLIPCHILDREN|WS_CLIPSIBLINGS))
  {
    addCallback(XmNmenuCallback, ID_OPEN, this, 
      (Callback)&DIBitmapViewer::open, NULL);
    addCallback(XmNmenuCallback, ID_EXIT, this, 
      (Callback)&DIBitmapViewer::exit, NULL);

    addCallback(XmNmenuCallback, ID_TILE, this, 
      (Callback)&DIBitmapViewer::tile, NULL);
    addCallback(XmNmenuCallback, ID_CASCADE, this, 
      (Callback)&DIBitmapViewer::cascade, NULL);
    addCallback(XmNmenuCallback, ID_ICONARRANGE, this, 
      (Callback)&DIBitmapViewer::iconArrange, NULL);
    addEventHandler(WM_CLOSE, this,
      (Handler)&DIBitmapViewer::close, NULL);

    max = 100;
    num = 0;
    images = new MdiDIBitmap*[max];
    for(int i = 0; i<max; i++) { 
      images[i] = NULL;
    }

    Args ar;
    ar.set(XmNfilter, _T("Bitmap (*.bmp)\0 *.bmp\0"));
    filedlg.create(this, _T(""), ar);
  }

public:
  ~DIBitmapViewer()
  {
    for(int i = 0; i<num; i++) {
      if(images[i]) delete images[i];
    }
  }

private:
  long paletteChanged(Event& event)
  {
    HWND hwnd =  (HWND)event.getWParam();
    if(hwnd != getWindow()) {
      return ::SendMessage(hwnd, WM_QUERYNEWPALETTE,
          event.getWParam(), event.getLParam());
    }  
    else { 
      return 0L;
    }
  }

public:
  void childActivated(View* view)
  {
    MdiDIBitmap* sender = (MdiDIBitmap*)view;
  
    for(int i = 0; i<num; i++) {
      if(images[i] && images[i]!=sender) {
          images[i]->update();
      }
    }
  }

private:
  long close(Event& event)
  {
    int flag = TRUE;
    for(int i = 0; i<num; i++) {
      if(images[i] && images[i]->isAlive()) {
        int rc = (int)images[i]->send(WM_CLOSE, 0, 0L);
        if (rc == TRUE) {
          delete images[i];
          images[i] = NULL;
        }
        else {
          flag = FALSE;
        }
      }
    }
    if(flag) {
      num = 0;
      return defaultProc(event);
    }
    else {
      return 0L;
    }
  }

private:
  void saveFileFolder(const TCHAR* filePath)
  {
    if (strlen(filePath)>0) {
    
      Folder folder(filePath);
      String dirOnly = _T("");
    
      folder.getDirectory(dirOnly);
      const TCHAR* dir = (const TCHAR*)dirOnly;
      profile.setFileFolder(dir);
    }
  }

private:
  void open(Action& action)
  {
    Args ar;
    
    TCHAR dir[MAX_PATH];
    memset(dir, (TCHAR)0, CountOf(dir));
    //Restore previously select folder from a registry(profile of this application) for fileDialog
    if (profile.getFileFolder(dir, CountOf(dir))) {
      ar.set(XmNdirectory, dir);
      filedlg.setValues(ar);
    }
    
    if(filedlg.open() && num < max) {
      int n = num;
      for(int i = 0; i<num; i++) {
        if(images[i] && 
          images[i]->isAlive() == FALSE) {
          delete images[i];
          images[i] = NULL;
        }
        if(images[i] == NULL) {
          n = i;
          break;
        }
      }
    
      TCHAR* filename = filedlg.getFileName();
      saveFileFolder(filename);

      MdiClient* mdiClient = getClient();
      Args ar;
      ar.set(XmNx,     (int)CW_USEDEFAULT);
      ar.set(XmNy,     (int)CW_USEDEFAULT);
      ar.set(XmNwidth, (int)CW_USEDEFAULT);
      ar.set(XmNheight,(int)CW_USEDEFAULT);
      ar.set(XmNmenuId, 1);
      ar.set(XmNmenuName, _T("ImageChild"));
      images[n] = new MdiDIBitmap(mdiClient, _T("MdiDIBitmap"), ar);
      images[n] -> setText(filename);

      images[n] -> load(filename);

      if(n == num) num++;
      for(int j = 0; j<num; j++) {
        if(images[j]) {
        images[j]->update();
        }
      }
    }
  }
};

}


////////////////////////////////////////////////
//

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

  try {
    Application applet(name, argc, argv);

    Args args;
    args.set(XmNchildId, 100);
    args.set(XmNmenuId,    0);
    args.set(XmNmenuName, name);
    DIBitmapViewer DIBitmapViewer(applet, name, args);
    DIBitmapViewer.realize();

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

Last modified: 1 Feb 2017

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