SOL9 2.0 Class: PopupView

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

Source code

/*
 * PopupView.h 
 * Copyright (c) 2011 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// SOL++2000
// 1999.10.09 Added a layout method.
// 2000.02.18
// 2001.03.11 Added a create method.
#pragma once

#include <sol\Composite.h>

namespace SOL {

class PopupView    :public Composite {
private:
    int    focusId;
    View*    owner;
  
protected:
    virtual long defaultProc(Event& event) 
    {
        return FALSE;
    }

protected:
    void disableOwner()
    {
        if(owner) {
            owner ->enableWindow(FALSE);
        }
    }

protected:
    void enableOwner()
    {
        if(owner) {
            owner -> enableWindow(TRUE);
        }
    }

protected:
    long close(Event& event)
    {
        Action action(NULL, event);
        popdown(action);
        return 0L;
    }

protected:
    long command(Event& event) 
    {
        WORD controlId = event.getControlId();
// PopupView has no menuCallbacks.
        HWND child     = event.getChild();
        if(controlId > 0) {
            HWND item = getItem(controlId);
            if(::IsWindow(item))
                child = item;
        }

        UINT notify = event.getNotification();
        const TCHAR* name = findCallbackName(event, child);

        WPARAM wParam = event.getWParam();
        if(name == XmNactivateCallback  && wParam ==IDOK) {
            child = ::GetFocus();
        }
        callCallback(name, (Key)child, NULL, event);

        return 0;
    }

protected:
    void resize()
    {
        RECT r;
        getClientRect(&r);
        int w = r.right-r.left;
        int h = r.bottom-r.top;
        send(WM_SIZE, 0, MAKELONG(w, h));
    }

// 1999.10.09 Added the following method to fix a problem on Layoutmanager.
protected:
    virtual void layout(int x, int y, int w, int h)
    {
        /*if (getParent() != NULL) {
            reshape(x, y, w, h);
        }*/
        LayoutManager* layoutManager = getLayoutManager();
        if (layoutManager) {
            layoutManager->layout(0, 0, w, h);
        }
    }

public:
    PopupView() :Composite() { }

public:
    PopupView(View* parent)
        :Composite(parent) 
{ 
    owner = NULL;
    focusId = 0;
}

public:
// 2001/03/11
    virtual Boolean create(View* parent)
    {
        Boolean rc = Composite::create(parent) ;
 
        owner = NULL;
        focusId = 0;
        return rc;
    }

public:
    PopupView(View* parent, const TCHAR* name, Args& args)
    :Composite(parent, name,
             args.set(XmNstyle, 
                        (ulong)(WS_POPUP|WS_SYSMENU|WS_CAPTION))
                 .set(XmNpredefined, TRUE)
                 .set(XmNclassName, (ulong)WC_DIALOG))
    {
        owner  = NULL;
        focusId = 0;

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

        setWindowLong(DWL_DLGPROC, (LPARAM)PopupView::procedure);
        ulong val;
        if (args.get(XmNfocusId, &val)) {
            focusId = (int)val;
        }
    }

public:
    virtual Boolean create(View* parent, const TCHAR* name, Args& args)
    {
        Boolean rc = Composite::create(parent, name,
             args.set(XmNstyle, 
                        (ulong)(WS_POPUP|WS_SYSMENU|WS_CAPTION))
                 .set(XmNpredefined, TRUE)
                 .set(XmNclassName, (ulong)WC_DIALOG));

        owner  = NULL;
        focusId = 0;

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

        setWindowLong(DWL_DLGPROC, (LPARAM)PopupView::procedure);
        ulong val;
        if (args.get(XmNfocusId, &val)) {
            focusId = (int)val;
        }
        return rc;
    }


    void    setFocusId(int id) { focusId = id; }

    void    setOwner(View* view) { owner = view; }

public:
    void popup(Action& action)
    {
        RECT rect;
        getWindowRect(&rect);
        int x        = 0;
        int y        = 0;
        int width  = rect.right - rect.left;
        int height = rect.bottom - rect.top;
        int scWidth  = ::GetSystemMetrics(SM_CXSCREEN);
        int scHeight = ::GetSystemMetrics(SM_CYSCREEN);
    
        View* parent = getParent();
        if(parent) {
        // Move to the center of a parent.
            RECT pr;
            parent -> getWindowRect(&pr);
            x = pr.left + (pr.right - pr.left - width)/2;
            y = pr.top  + (pr.bottom - pr.top - height)/2;
        }
        if((x+width) >scWidth) x = scWidth - width;
        if(x <0 ) x = 0;

        if((y+height) >scHeight) y = scHeight - height;
        if(y < 0) y = 0;

        disableOwner();
        reshape(x, y, width, height);
        raise();
        show(SW_SHOWNORMAL);
    }

public:
    void setPopupFocus()
    {
        if(focusId) {
            HWND child = getItem(focusId);
            if(child) {
                ::SetFocus(child);
            }
        }
    }

public:
    void popdown(Action& action)
    {
        enableOwner();
        show(SW_HIDE);
    }

public:
    void popupAt(Action& action)
    {
        RECT rect;
        getWindowRect(&rect);
        int w   = rect.right - rect.left;
        int h   = rect.bottom - rect.top;
        int x = (::GetSystemMetrics(SM_CXSCREEN) - w)/2;
        int y = (::GetSystemMetrics(SM_CYSCREEN) - h)/2;
        reshape(x, y,  w, h);
        disableOwner();
        raise();
        show(SW_SHOWNORMAL);
    }

public:
    void popupAsItIs(Action& action)
    {
        disableOwner();
        raise();
        show(SW_SHOWNORMAL);
    }

public:
    static BOOL CALLBACK procedure(HWND hwnd, 
        UINT message, WPARAM wParam, LPARAM lParam)
    {
        Event event(message, wParam, lParam);

        View* view = Application::lookup(hwnd);
        BOOL result = FALSE;
        if (view) {
            result = (BOOL) view -> dispatch(event);
        }
        return result;
    }

public:
    void setViewId(int vid)
    {
        setId(vid);
    }

public:
    void PopupView::centerOn()
    {
        RECT rect;
        getWindowRect(&rect);
        int x        = 0;
        int y        = 0;
        int width  = rect.right - rect.left;
        int height = rect.bottom - rect.top;
        int scWidth  = ::GetSystemMetrics(SM_CXSCREEN);
        int scHeight = ::GetSystemMetrics(SM_CYSCREEN);
    
        View* parent = getParent();
        if(parent) {
            RECT pr;
            parent -> getWindowRect(&pr);
            x = pr.left + (pr.right - pr.left - width)/2;
            y = pr.top  + (pr.bottom - pr.top - height)/2;
        }
        if((x+width) >scWidth) {
            x = scWidth - width;
        }
        if(x <0 ) { 
            x = 0;
        }
        if((y+height) >scHeight){
            y = scHeight - height;
        }
        if(y < 0) { 
            y = 0;
        }

        reshape(x, y, width, height);
    }    

    /*
    */
};

}



Last modified: 1 Feb 2012

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