wwindow.cpp

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 1,324 行 · 第 1/3 页

CPP
1,324
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Window class definition.
*
****************************************************************************/

#include <ctype.h>

#include "wwindow.hpp"
#include "wvlist.hpp"
#include "wmenu.hpp"
#include "wcontrol.hpp"
#include "wpopmenu.hpp"
#include "wmenuitm.hpp"
#include "wwinmain.hpp"
#include "wkeydefs.hpp"
#include "wtoolbar.hpp"
#include "wbaritem.hpp"
#include "wmetrics.hpp"

/***************************************************************************/

WObjectMap      WWindow::_idMap;
WObjectMap      WWindow::_toolBarIdMap;
WObjectMap      WWindow::_popupIdMap;
unsigned        WWindow::_idMaster = 1;

/***************************************************************************/

WCLASS AccelKey : public WObject {
public:
    AccelKey( WKeyCode key, WObject* client, bcbk callback );
    ~AccelKey( void ) {}

    bool callClient( WKeyCode kc ) { return( (_client->*_callback)( kc ) ); }

    WKeyCode _key;
    WObject  *_client;
    bcbk     _callback;
};

AccelKey::AccelKey( WKeyCode key, WObject* client, bcbk callback )
    : _key( key )
    , _client( client )
    , _callback( callback )
{
}

/***************************************************************************/

bool WEXPORT WWindow::processMsg( gui_event msg, void *parm )
{
    gui_point           point;
    gui_coord           size;
    unsigned            control_id;
    int                 scroll_position;

    switch( msg ) {
    case GUI_CLICKED: {
        GUI_GETID( parm, control_id );
        WMenuItem* menu = (WMenuItem*)WWindow::_idMap.findThis( (WHANDLE)control_id );
        if( menu != NULL ) {
            menu->picked();
            return( TRUE );
        }
        // a popup menu with no menu items will generate GUI_CLICKED
        // - simulate a GUI_INITMENUPOPUP
        WPopupMenu* pop = (WPopupMenu*)WWindow::_popupIdMap.findThis( (WHANDLE)control_id );
        if( pop != NULL ) {
            pop->popup();
            return( TRUE );
        }
        WToolBarItem* tool =(WToolBarItem*)WWindow::_toolBarIdMap.findThis( (WHANDLE)control_id );
        if( tool != NULL ) {
            tool->picked();
            return( TRUE );
        }
    }
    case GUI_CONTROL_CLICKED:
    case GUI_CONTROL_DCLICKED: {
        GUI_GETID( parm, control_id );
        WControl* control = getControl( control_id );
        if( control != NULL ) {
            return( control->processMsg( msg ) );
        } else {
            return( FALSE );
        }
    }
    case GUI_LBUTTONUP: {
        GUI_GET_POINT( parm, point );
        return( leftBttnUp( point.x, point.y, 0 ) );
    }
    case GUI_LBUTTONDOWN: {
        GUI_GET_POINT( parm, point );
        return( leftBttnDn( point.x, point.y, 0 ) );
    }
    case GUI_LBUTTONDBLCLK: {
        GUI_GET_POINT( parm, point );
        return( leftBttnDbl( point.x, point.y, 0 ) );
    }
    case GUI_RBUTTONUP: {
        GUI_GET_POINT( parm, point );
        return( rightBttnUp( point.x, point.y, 0 ) );
    }
    case GUI_CONTROL_RCLICKED: {
        GUI_GETID( parm, control_id );
        WControl* control = getControl( control_id );
        if( control != NULL ) {
            return( control->rightBttnUp( 0, 0, 0 ) );
        } else {
            return FALSE;
        }
    }
    case GUI_RBUTTONDOWN: {
        GUI_GET_POINT( parm, point );
        return( rightBttnDn( point.x, point.y, 0 ) );
    }
    case GUI_RBUTTONDBLCLK: {
        GUI_GET_POINT( parm, point );
        return( rightBttnDbl( point.x, point.y, 0 ) );
    }
    case GUI_MOUSEMOVE: {
        GUI_GET_POINT( parm, point );
        return( mouseMove( point.x, point.y, 0 ) );
    }
    case GUI_VSCROLL_NOTIFY: {
        return( scrollPosChanged( WScrollBarVertical ) );
    }
    case GUI_HSCROLL_NOTIFY: {
        return( scrollPosChanged( WScrollBarHorizontal ) );
    }
    case GUI_NOW_ACTIVE: {
        return( gettingFocus( NULL ) );
    }
    case GUI_NOT_ACTIVE: {
        return( losingFocus( NULL ) );
    }
    case GUI_KEYDOWN: {
        _keyHandled = FALSE;
        WWindow *p = this;
        while( p != NULL ) {
            _keyHandled = p->keyDown( ((gui_key_state *)parm)->key,
                                      ((gui_key_state *)parm)->state );
            if( _keyHandled ) break;
            p = p->parent();
        }
        return( _keyHandled );
    }
    case GUI_KEY_CONTROL: {
        return( FALSE );
    }
    case GUI_KEYUP: {
        // we don't care about GUI_KEYUP messages; however we want to
        // return whether the GUI_KEYDOWN message was handled or not
        return( _keyHandled );
    }
    case GUI_CLOSE: {
        return( reallyClose() );
    }
    case GUI_DESTROY: {
        setHandle( NULL );
        return( TRUE );
    }
    case GUI_ICONIFIED: {
        minimized();
        return( TRUE );
    }
    case GUI_MOVE:
        moved( 0, 0 );
        enumChildren();
        return( TRUE );
    case GUI_RESIZE: {
        GUI_GET_SIZE( parm, size );
        resized( size.x, size.y );
        enumChildren();
        return( TRUE );
    }
    case GUI_PAINT: {
        _painting = TRUE;
        GUI_GET_ROWS( parm, _firstDirtyRow, _numDirtyRows );
        bool ret = paint();
        _firstDirtyRow = 0;
        _numDirtyRows = 0;
        _painting = FALSE;
        return( ret );
    }
    case GUI_INITMENUPOPUP: {
        GUI_GETID( parm, control_id );
        WPopupMenu *pop = (WPopupMenu *)WWindow::_popupIdMap.findThis( (WHANDLE)control_id );
        pop->popup();
        return( TRUE );
    }
    case GUI_TOOLBAR_DESTROYED:
        if( !_toolBar->changed( WToolBarClosed ) ) {
            clearToolBar();
        }
        return( TRUE );
    case GUI_TOOLBAR_FLOATING:
        if( !_toolBar->changed( WToolBarFloating ) ) {
            enumChildren();
        }
        return( TRUE );
    case GUI_TOOLBAR_FIXED:
        if( !_toolBar->changed( WToolBarFixed ) ) {
            enumChildren();
        }
        return( TRUE );
    case GUI_SCROLL_UP:
        return( scrollNotify( WScrollUp, 0 ) );
    case GUI_SCROLL_PAGE_UP:
        return( scrollNotify( WScrollPageUp, 0 ) );
    case GUI_SCROLL_DOWN:
        return( scrollNotify( WScrollDown, 0 ) );
    case GUI_SCROLL_PAGE_DOWN:
        return( scrollNotify( WScrollPageDown, 0 ) );
    case GUI_SCROLL_TOP:
        return( scrollNotify( WScrollTop, 0 ) );
    case GUI_SCROLL_BOTTOM:
        return( scrollNotify( WScrollBottom, 0 ) );
    case GUI_SCROLL_VERTICAL:
        GUI_GET_SCROLL( parm, scroll_position );
        return( scrollNotify( WScrollVertical, scroll_position ) );
    case GUI_SCROLL_LEFT:
        return( scrollNotify( WScrollLeft, 0 ) );
    case GUI_SCROLL_PAGE_LEFT:
        return( scrollNotify( WScrollPageLeft, 0 ) );
    case GUI_SCROLL_RIGHT:
        return( scrollNotify( WScrollRight, 0 ) );
    case GUI_SCROLL_PAGE_RIGHT:
        return( scrollNotify( WScrollPageRight, 0 ) );
    case GUI_SCROLL_FULL_LEFT:
        return( scrollNotify( WScrollFullLeft, 0 ) );
    case GUI_SCROLL_FULL_RIGHT:
        return( scrollNotify( WScrollFullRight, 0 ) );
    case GUI_SCROLL_HORIZONTAL:
        GUI_GET_SCROLL( parm, scroll_position );
        return( scrollNotify( WScrollHorizontal, scroll_position ) );
    case GUI_STATUS_CLEARED:
        return( statusWindowCleared() );
    case GUI_QUERYENDSESSION:
        return( !queryEndSession() );
    case GUI_ENDSESSION:
        bool ending;
        GUI_GET_BOOL( parm, ending );
        endSession( ending );
    case GUI_ACTIVATEAPP:
        bool activated;
        GUI_GET_BOOL( parm, activated );
        return( appActivate( activated ) );
    case GUI_CONTEXTHELP:
        bool isactwin;
        GUI_GET_BOOL( parm, isactwin );
        return( contextHelp( isactwin ) );
    }
    return( TRUE );
}


extern "C" void EnumChildProc( gui_window *hwin, void * ) {
/*********************************************************/

    WWindow *win = (WWindow*)GUIGetExtra( hwin );
    win->autosize();
}


extern "C" void EnumControlProc( gui_window *hwin, unsigned id, void * ) {
/************************************************************************/

    WWindow *win = (WWindow*)GUIGetExtra( hwin );
    WControl* control = win->getControl( id );
    if( control != NULL ) {
        control->autosize();
    }
}


void WWindow::enumChildren() {
/****************************/

    GUIEnumChildWindows( _handle, EnumChildProc, NULL );
    GUIEnumControls( _handle, EnumControlProc, NULL );
}


extern "C" bool WinProc( gui_window *hwin, gui_event msg, void *parm ) {
/**********************************************************************/

    WWindow* win = (WWindow *)GUIGetExtra( hwin );
    if( msg == GUI_INIT_WINDOW ) {
        win->setHandle( hwin );
    }
    return( win->processMsg( msg, parm ) );
}


virtual bool WWindow::mouseMove( int, int, WMouseKeyFlags ) {
/***********************************************************/

    GUISetMouseCursor( _currCursor );
    return( FALSE );
}


void WWindow::makeWindow( const char *text, WStyle style ) {
/**********************************************************/

    gui_create_info     create_info;
    unsigned long       gui_style;

    WRect r;
    autoPosition( r );
    gui_window *hparent = NULL;
    if( _parent != NULL ) {
        hparent = _parent->_handle;
    }
    create_info.text = (char *)text;
    create_info.rect.x = r.x();
    create_info.rect.y = r.y();
    create_info.rect.width = r.w();
    create_info.rect.height = r.h();
    create_info.scroll = _WStyleToScrollStyle( style );
    gui_style = GUI_INIT_INVISIBLE | GUI_VISIBLE | _WStyleToCreateStyle( style );
    create_info.style = (gui_create_styles)gui_style;
    create_info.parent = hparent;
    create_info.num_menus = 0;
    create_info.menu = NULL;
    create_info.num_attrs = 0;
    create_info.colours = NULL;
    create_info.call_back = WinProc;
    create_info.extra = this;
    create_info.icon = NULL;
    _handle = GUICreateWindow( &create_info );
    if( _parent != NULL ) {
        _parent->addChild( this );
    }
}


WEXPORT WWindow::WWindow( WWindow *parent )
    : _painting( FALSE )
    , _firstDirtyRow( 0 )
    , _numDirtyRows( 0 )
    , _currCursor( GUI_ARROW_CURSOR )
    , _parent( parent )
    , _menu( NULL )
    , _popup( NULL )
    , _toolBar( NULL )
    , _handle( NULL ) {
/*********************/

}

WEXPORT WWindow::WWindow( const char *text, WStyle style )
    : _painting( FALSE )
    , _firstDirtyRow( 0 )
    , _numDirtyRows( 0 )
    , _currCursor( GUI_ARROW_CURSOR )
    , _parent( NULL )
    , _menu( NULL )
    , _popup( NULL )
    , _toolBar( NULL )
    , _handle( NULL ) {
/*********************/

    WSystemMetrics::defaultRectangle( _autosize );
    makeWindow( text, style );
}


WEXPORT WWindow::WWindow( WWindow *parent, const char *text, WStyle style )
    : _painting( FALSE )
    , _firstDirtyRow( 0 )
    , _numDirtyRows( 0 )
    , _currCursor( GUI_ARROW_CURSOR )
    , _parent( parent )
    , _menu( NULL )
    , _popup( NULL )
    , _toolBar( NULL )
    , _handle( NULL ) {
/*********************/

    WSystemMetrics::defaultRectangle( _autosize );
    makeWindow( text, style );
}


WEXPORT WWindow::WWindow( WWindow* parent, const WRect& r, const char *text,
                          WStyle style )
    : _painting( FALSE )
    , _firstDirtyRow( 0 )
    , _numDirtyRows( 0 )
    , _currCursor( GUI_ARROW_CURSOR )
    , _parent( parent )
    , _menu( NULL )
    , _popup( NULL )
    , _toolBar( NULL )
    , _autosize( r )
    , _handle( NULL ) {
/*********************/

    makeWindow( text, style );
}


void WWindow::destroyWindow() {
/*****************************/

    _accelKeys.deleteContents();
    delete clearMenu();
    delete clearToolBar();
    while( _children.count() > 0 ) {
        delete _children[ _children.count()-1 ];
    }
    if( _parent != NULL ) {
        _parent->removeChild( this );
        _parent = NULL;
    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?