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 + -
显示快捷键?