SOL9 Sample: SolCompoundFileViewer

SOL9 2.0 Samples

1 Screenshot


2 Source code

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



// SOL9
// 2008/09/05
// 2008/09/16 Modified to use restoreFileFolder/saveFileFolder.
// 2008/12/08 Modified to show a filename to the caption.
// 2008/12/15 Modified to accept a dropfile from Windows-Explorer 
// in the left tree-view pane.
// 2009/11/01 Modified to accept a drop file from Windows Explorer.

#define COMMONCONTROLS_V6

#include <sol\ApplicationView.h>
#include <sol\StatusBar.h>
#include <sol\FileDialog.h>

#include <sol\StringConverter.h>
#include <sol\TreeView.h>
#include <sol\HexView.h>
#include <sol\SmartPtr.h>
#include <sol\DropTarget.h>
#include <sol\SystemImageList.h>
#include <sol\FileVersionDialog.h>

#include "resource.h"

#include "SolStorageWalker.h"

namespace SOL {

/**
 * SolCompoundFileViewer class
 */
class SolCompoundFileViewer :public ApplicationView {
private:
  TreeView  treev;
  SystemImageList  imageList;

  HexView   hexv;
  StatusBar  statusbar;

  SolStorageWalker walker;

  FileDialog fileDialog;
  CDropTarget  dropTarget;

  FileVersionDialog fileVersion;

public:
  /**
   * Constructor
   */
  SolCompoundFileViewer(Application& applet, const TCHAR* name, Args& args)
  :ApplicationView(applet, name, 
    args.set(XmNbackground, (ulong)(COLOR_BTNFACE+1))  ),
    walker(treev, hexv, statusbar)
  {
    Args ar;

    ar.reset();
    ar.set(XmNexStyle, (ulong)WS_EX_CLIENTEDGE);
    ar.set(XmNstyle, (ulong)(TVS_HASBUTTONS|TVS_SHOWSELALWAYS|
      TVS_HASLINES|TVS_LINESATROOT));
    treev.create(this, NULL, ar);
    
    treev.setImageList(&imageList, TVSIL_NORMAL);

    HWND htreev = treev.getWindow();
    
    dropTarget.setTarget(htreev);

    dropTarget.setEventReceiver(getWindow());

    ar.reset();
    ar.set(XmNexStyle, (ulong)WS_EX_CLIENTEDGE);
    ar.set(XmNstyle,  (ulong)WS_BORDER|LVS_REPORT);
    hexv.create(this, NULL, ar);  

    ar.reset();
    statusbar.create(this, NULL, ar);

    treev.addCallback(XmNselChangedCallback, this, 
      (Callback)&SolCompoundFileViewer::selChanged, NULL);

    ar.reset();
    ar.set(XmNaccessMode, FileDialog::OPEN);
    fileDialog.create(this, NULL, ar);

    fileVersion.create(this);

    addCallback(XmNmenuCallback, IDM_OPEN, this, 
      (Callback)&SolCompoundFileViewer::open, NULL);
    addCallback(XmNmenuCallback, IDM_EXIT, this, 
      (Callback)&SolCompoundFileViewer::exit, NULL);

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

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

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

    addEventHandler(WM_SOL_DROPFILES, this, 
      (Handler)&SolCompoundFileViewer::dropFiles, NULL);
  
    restorePlacement();
  }



private:
  void setToWalker(const TCHAR* path) {
    if (walker.isStorageFile(path)) {
      DWORD attr = GetFileAttributes(path);
      int iconIndex = imageList.getIconIndex(path, attr, 0);

      walker.walk(path, iconIndex);
      saveFileFolder(path);
      TCHAR caption[1024];
      
      _stprintf_s(caption, CountOf(caption),
        _T("%s - SolCompoundFileViewer"), path);
      this->setText(caption);
    } else {
      TCHAR message[1024];
      _stprintf_s(message, CountOf(message), 
        _T("Failed to open a compound file.\r\n\r\n%s"), path);
      MessageBox(NULL, message, _T("SolCompoundFileViewer"), MB_ICONERROR|MB_OK);
    }
  }

public:
  /**
   * WM_SIZE eventhandler.
   */
  long dropFiles(Event& event)
  {
    WPARAM wParam = event.getWParam();
    //MessageBox(NULL, "DropFiles", "DEBUG", MB_OK);
    HDROP hDrop = (HDROP)wParam;
    if (hDrop) {
      int n = DragQueryFile(hDrop, 0xffffffff, NULL, 0);
      if (n >0) {

        //Get the first file only
        int i = 0;
        TCHAR path[_MAX_PATH];
        DragQueryFile(hDrop, i, path, CountOf(path));
        DWORD attr = GetFileAttributes(path);

        if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
          setToWalker(path);
        }
      }
    }
    return 0;
  }

public:
  /**
   * WM_SIZE eventhandler.
   */
  long size(Event& event)
  {
    LPARAM l = event.getLParam();
    
    statusbar.send(WM_SIZE, event.getWParam(), event.getLParam());
    int w, h;
    statusbar.getSize(w, h);
    
    treev.reshape(0, 0, w*1/3-1,  HIWORD(l) - h);
    
    hexv.reshape(w/3, 0, w*2/3-2, HIWORD(l) - h);
    
    return 0;
  }

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

public:
  /**
   * File menu [Open] callback.
   */
  void open(Action& action)
  {
    //2008/09/16
    TCHAR dir[_MAX_PATH];
    if (restoreFileFolder(dir, CountOf(dir))) {
      Args ar;
      ar.set(XmNdirectory, dir);
      fileDialog.setValues(ar);
    }
    int rc = fileDialog.open();
    if (rc == IDOK) {
      const TCHAR* fileName = fileDialog.getFileName();
      setToWalker(fileName);
    }
  }

public:
  /**
   * File menu [Version] callback.
   */
  void version(Action& action)
  {
    fileVersion.popupAt(action);
  }

public:
  /**
   * Callback for selection-change in a TreeView. 
   * If a stream is selected, displays its hexdecimal data in SOL::HexView by using SolStorageWalker.
   */
  void selChanged(Action& action)
  {
    Event& event = action.getEvent();
    NM_TREEVIEW* nmtr  = (NM_TREEVIEW*)event.getLParam();

    TV_ITEM tvItem     = nmtr -> itemNew;
    HTREEITEM hItem = tvItem.hItem;
    int count = 0;
  
    HTREEITEM* items = treev.getItemsListFromRoot(hItem, count);
    if (items) {

      walker.displayStreamData(items, count);
      delete [] items;
    }
  }
};

}


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

    Args args;
  
    SolCompoundFileViewer fileViewer(applet, name, args);
    fileViewer.realize();

    applet.run();

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


Last modified: 1 Feb 2017

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