SOL9 2.0 Sample: SolCompoundFileViewer

SOL9 2.0 Samples

1 Screenshot


2 Source code

/*
 * SolCompoundFileViewer.cpp 
 * Copyright (c) 2009 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.

#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, SizeOf(caption),
                _T("%s - SolCompoundFileViewer"), path);
            this->setText(caption);
        } else {
            TCHAR message[1024];
            _stprintf_s(message, SizeOf(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, sizeof(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, sizeof(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);
    const String appClass = "SolCompoundFileViewer";
    try {
    
        Application applet(appClass, argc, argv);

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

        applet.run();
    } catch (...) {

    }
    OleUninitialize();
}


Last modified: 11 Nov 2009

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