SOL9 2.0 Class: ApplicationView

 SOL9 C++ Class Library  SOL9 Samples  SOL9 Tutorial  SOL9 FAQ  SOL9 ClassTree  SOL9 ClassList 

Source code

/******************************************************************************
 *
 * Copyright (c) 1999-2008 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 *  
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 *  ApplicationView.h
 *
 *****************************************************************************/

// SOL++2000
// 2008/07/13
// 2008/09/16 Added Profile instance variable to store user's application setting
// such as a window's geomery, a file folder selected in FileDialog.
//  Two methods saveFileFolder/restoreFileFolder, and modified savePlacement and restorePlacement
// methods not to take any arguments.
// 2017/01/29 Updated Constructor to use the following XmNclassName:
//         .set(XmNclassName, _T("ApplicationView") )), //2017/01/29

#pragma once

#include <sol\Application.h>
#include <sol\Composite.h>
#include <sol\MenuBar.h>
#include <sol\Accelerator.h>
#include <sol\ToolBar.h>
#include <sol\StatusBar.h>
#include <sol\DefaultLayout.h>
//2008/09/16
#include <sol\Profile.h>

//2009/10/08
#include <sol/AppEntry.h>



/**
 * ApplicationView class.
 */
namespace SOL {

class ApplicationView :public Composite {
private:
  Application&   application;
  MenuBar*       menuBar;
  Accelerator*   accel;
  ToolBar*    toolBar;
  StatusBar*    statusBar;
  DefaultLayout*  defaultLayout;
  //2008/09/16
  Profile      profile;

protected:
//    virtual long size(Event& event);
  virtual long size(Event& event)
  {
    int  w, h;
    event.getSize(w, h);

    int  top = 0;
    if (toolBar) {
      toolBar -> send(event.getMessage(), 
      event.getWParam(), event.getLParam());
      top = toolBar -> getHeight();
    }

    if(statusBar) {
      statusBar -> send(event.getMessage(),
      event.getWParam(), event.getLParam());
      h = h - top - statusBar -> getHeight();
    }
    justifyScrollRange();
    layout(0, top, w, h);
    return 0L;
  }


public:
  //2017/03/10
  ApplicationView(Application& applet)
  :Composite(NULL),
  application(applet),
    menuBar(NULL),
    accel(NULL),
    toolBar(NULL),
    statusBar(NULL),
    defaultLayout(NULL)
  {
  }
  
public:
  ApplicationView(Application& applet, const TCHAR* name,
        Args& args)
  :Composite(NULL, name,
    args.set(XmNx,      (LONG_PTR)CW_USEDEFAULT)
        .set(XmNy,      (LONG_PTR)CW_USEDEFAULT)
        .set(XmNwidth,  (LONG_PTR)CW_USEDEFAULT)
        .set(XmNheight, (LONG_PTR)CW_USEDEFAULT)
        .set(XmNstyle,  (LONG_PTR)WS_OVERLAPPEDWINDOW)
      //  .set(XmNpredefined,  False)
        .set(XmNclassName, _T("ApplicationView") )), //2017/01/29
    application(applet),
    menuBar(NULL),
    accel(NULL),
    toolBar(NULL),
    statusBar(NULL),
    defaultLayout(NULL)
  {
    defaultLayout = new DefaultLayout();
    setLayout(defaultLayout);
    applet.setToplevel(this);

    LONG_PTR val;
    const TCHAR* menuName = name;
    if (args.get(XmNmenuName, &val)) {
      menuName = (const TCHAR*)val;
    }
    menuBar = new MenuBar(this, menuName);

    const TCHAR* accelName = name;
    if (args.get(XmNacceleratorName, &val)) {
      accelName = (const TCHAR*)val;
    }
    accel   = new Accelerator(accelName);

    Args ar;
    if (args.get(XmNdefaultToolBar)) {
      LONG_PTR id = args.get(XmNtoolBarBitmapID);
      ar.set(XmNtoolBarBitmapID,  id);
      toolBar = new ToolBar(this, _T(""), ar);
    }
    if(args.get(XmNdefaultStatusBar)) {
      ar.reset();
      statusBar = new StatusBar(this, _T(""), ar);  
    }

    //<added date="2009/09/08">
    const TCHAR* iconName = name;
    if (args.get(XmNiconName, &val)) {
      iconName = (const TCHAR*)val;
    }
    int iconId = 0;
    if (args.get(XmNiconId, &val)) {
      iconId = (int)val;
    }
    
    if (setIcon(iconName) == false) {
      setIcon(iconId);
    }
    //addEventHandler(WM_ERASEBKGND, this, (Handler)&ApplicationView::erase, NULL);

  }

public:
  ~ApplicationView() 
  { 
    // Don't delete the application
    delete defaultLayout;
    delete accel;  
    delete menuBar; 
    delete toolBar;
    delete statusBar;
  }
  
public:
  // For compatibility Oz++ class library on Motif.
  void  realize()
  {
    int cmdShow = SW_SHOWNORMAL;
  
    cmdShow = application.getShowCommand();
    show(cmdShow);
    //2017/03/22
    raise();
    setFocus();
  }

 void  realize(int cmdShow)
  {
    //int cmdShow = SW_SHOWNORMAL;
  
    //cmdShow = application.getShowCommand();
    show(cmdShow);
  }
  
public:
  Boolean  translate(MSG* msg)
  {
    HACCEL haccel = NULL;
    if(accel) haccel = accel->get();
    if(haccel && ::TranslateAccelerator(getWindow(), haccel, msg)) {
      return TRUE;
    } else {
      return FALSE;
    }
  }

public:
  virtual long erase(Event& ev)
  {
    return TRUE;
  }

public:
  void getClientRect(RECT* r)
  {
    View::getClientRect(r);
    if(toolBar) {
      RECT rt;
      toolBar -> getClientRect(&rt);
      r->top = (rt.bottom - rt.top);      
    }
    if(statusBar) {
      RECT rs;
      statusBar -> getClientRect(&rs);
      r->bottom -= (rs.bottom - rs.top);      
    }
  }

public:
  int  showMessageDialog(const TCHAR* message, int flag = MB_OK)
  {
    if(isIconic()) {
      show(SW_NORMAL);
    }

    TCHAR path[_MAX_PATH];
    ::GetModuleFileName(NULL, path, _MAX_PATH);
    Folder folder(path);
    String progname = _T("");
    folder.getName(progname);
    int rc = ::MessageBox(getWindow(), message, (const TCHAR*)progname, flag);
    return rc;
  }
// 2009/10/19
public:
  int showMessageDialog(const wchar_t* title, const wchar_t* message, int flag = MB_OK)
  {
    if(isIconic()) {
      show(SW_NORMAL);
    }
    return ::MessageBoxW(getWindow(), message, title,  flag);
  }


public:
  int showErrorDialog(const wchar_t* title, const wchar_t* message, int flag = MB_OK)
  {
    if(isIconic()) {
      show(SW_NORMAL);
    }
    return ::MessageBoxW(getWindow(), message, title, MB_ICONERROR|flag);
  }

public:
  int showInformationDialog(const wchar_t* title, const wchar_t* message, int flag = MB_OK)
  {
    if(isIconic()) {
      show(SW_NORMAL);
    }
    return ::MessageBoxW(getWindow(), message, title, MB_ICONINFORMATION|flag);
  }

public:
  int showQuestionDialog(const wchar_t* title, const wchar_t* message, int flag = MB_OK)
  {
    if(isIconic()) {
      show(SW_NORMAL);
    }
    return ::MessageBoxW(getWindow(), message, title, MB_ICONQUESTION|flag);  
  }

// 2009/10/19
public:
  int showMessageDialog(const char* title, const char* message, int flag = MB_OK)
  {
    if(isIconic()) {
      show(SW_NORMAL);
    }
    return ::MessageBoxA(getWindow(), message, title,  flag);
  }


public:
  int showErrorDialog(const char* title, const char* message, int flag = MB_OK)
  {
    if(isIconic()) {
      show(SW_NORMAL);
    }
    return ::MessageBoxA(getWindow(), message, title, MB_ICONERROR|flag);
  }

public:
  int showInformationDialog(const char* title, const char* message, int flag = MB_OK)
  {
    if(isIconic()) {
      show(SW_NORMAL);
    }
    return ::MessageBoxA(getWindow(), message, title, MB_ICONINFORMATION|flag);
  }

public:
  int showQuestionDialog(const char* title, const char* message, int flag = MB_OK)
  {
    if(isIconic()) {
      show(SW_NORMAL);
    }
    return ::MessageBoxA(getWindow(), message, title, MB_ICONQUESTION|flag);  
  }


  //
public:
  // 1996.12.01 to-arai
  void wait(LONG interval) 
  {
    DWORD startedTime = ::GetTickCount();
    while(::GetTickCount() - startedTime < (DWORD)interval){
      MSG msg;
      if (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
      }
    }
  }


public:
  void restorePlacement()
  {
    //Profile profile(name);
    WINDOWPLACEMENT pl;
    memset(&pl, 0, sizeof(pl));
    pl.length = sizeof(pl); 

    int x, y, w, h;
    profile.getGeometry(&x, &y, &w, &h);

    RECT r;
    r.left     = x;
    r.right    = x+ w;
    r.top      = y;
    r.bottom   = y+h;
    pl.showCmd = SW_SHOWNORMAL; 
    pl.rcNormalPosition = r;

    if(x > 0 && y > 0) {
      setPlacement(&pl);
    }
  }

public:
  void savePlacement()
  {
    //Profile profile(name);
    WINDOWPLACEMENT pl;

    //  memset(&pl, 0, sizeof(pl));
    pl.length = sizeof(pl); 

    getPlacement(&pl);
    RECT r = pl.rcNormalPosition;
    profile.setGeometry(&r);
  }

public:
  bool restoreFileFolder(TCHAR* folder, size_t size)
  {
    bool rc = false;
    if (folder != NULL && size >0) {
      rc = profile.getFileFolder(folder, (UINT)size);
    }
    return rc;
  }

public:
  bool saveFileFolder(const TCHAR* filePath)
  {
    bool rc = false;
    if (filePath != NULL && strlen(filePath)>0) {
    
      Folder folder(filePath);
      String dirOnly = _T("");
    
      folder.getDirectory(dirOnly);
      const TCHAR* dir = (const TCHAR*)dirOnly;
      if (dir) {
        rc = profile.setFileFolder(dir);
      }
    }
    return rc;
  }


  void    exit(Action& action) {
    //2009/10/14
    savePlacement();
      post(WM_CLOSE, 0, 0L);
  }


  StatusBar* getStatusBar() { return statusBar; }

  StatusBar& getStatusBarRef() { return *statusBar; }

  ToolBar*   getToolBar() { return toolBar; }
  ToolBar&   getToolBarRef() { return *toolBar; }

  MenuBar*  getMenuBar()  { return menuBar; }

  BOOL  isIconic() { return ::IsIconic(getWindow()); }

  BOOL  isZoomed() { return ::IsZoomed(getWindow()); }

//  void  realize();

  void  setToolBar(ToolBar* bar)   { toolBar = bar; }
  void  setStatusBar(StatusBar* bar) { statusBar = bar; }


  Profile& getProfile() { return profile; }

public:
  //2009/11/16
  void  waitForThread(HANDLE hThread){
    HANDLE handle[1];
    handle[0] = hThread;

    bool looping = true;    
    while (looping)  { 
    
      if (MsgWaitForMultipleObjects(1, handle, FALSE,   
        INFINITE, QS_ALLINPUT|QS_ALLEVENTS) == WAIT_OBJECT_0+1 ) {
        MSG msg;

        while(PeekMessage (&msg,NULL,0,0,PM_REMOVE)) {
          SleepEx(0, TRUE);
          if (msg.message == WM_QUIT) {
            //Repost WM_QUIT message to your application message queue.
            PostMessage(NULL, WM_QUIT, 0, 0);
            looping = false;
            break;
          }  
          TranslateMessage(&msg);
          DispatchMessage(&msg);
        }

      }else {
        break;   
      }
    }
  }

public:
  //2012/04/07
  String getModuleDirectory()
  {
    const int size = 1024;
    wchar_t base[size];
    memset(base, (wchar_t)0, size);
    GetModuleFileNameW(NULL, base, size);
    wchar_t* sl = strrchr(base, L'\\');
    if (sl) {
      *sl = NULL;
    }

    return String(base);
  }
  
};

}



Last modified: 5 May 2019

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