guixwind.c

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

C
1,469
字号
/****************************************************************************
*
*                            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:  GUI library window proc and other assorted guts.
*
****************************************************************************/


#include "guiwind.h"
#include <stdlib.h>
#include <stdio.h>
#include "guiscale.h"
#include "guiutil.h"
#include "guixutil.h"
#include "guimenus.h"
#include "guipaint.h"
#include "guixwind.h"
#include "guimapky.h"
#include "guisysin.h"
#include "guisysfi.h"
#include "guitool.h"
#include "guixdraw.h"
#include "guifloat.h"
#include "guiscrol.h"
#include "guiwinlp.h"
#include "guifont.h"
#include "guistr.h"
#include "guixhook.h"
#include "guihook.h"
#include "guicolor.h"
#include "guicontr.h"
#include "guixdlg.h"
#include "guistyle.h"
#include "guideath.h"
#include "guidead.h"
#include "guifront.h"
#include "guiwinlp.h"

extern bool     GUIMainTouched;

#if !(defined(__NT__) || defined(WILLOWS))
#define WM_PAINTICON            0x0026
#endif
#define WM_GUI_USEREVENT        (WM_USER+0x654)
        bool                    EditControlHasFocus     = FALSE;
extern  bool                    GUIMDI;
static  int                     NumWindows      =       0;
static  gui_window_styles       Style;
static  bool                    Posted          =       FALSE;
static  bool                    FirstInstance   =       TRUE;

#ifdef __OS2_PM__
static  WPI_PROC                oldFrameProc;
WPI_MRESULT CALLBACK GUIFrameProc( HWND, WPI_MSG msg, WPI_PARAM1 wparam, WPI_PARAM2 lparam );
#endif

typedef struct wmcreate_info {
    int                 size;
    gui_window          *wnd;
    gui_create_info     *info;
} wmcreate_info;

/* forward reference */

WPI_MRESULT CALLBACK GUIWindowProc( HWND, WPI_MSG msg, WPI_PARAM1 wparam, WPI_PARAM2 lparam );

/* include from the app */
extern void GUImain( void );
extern bool GUIFirstCrack( void );

/* Changes added to enable use of the system tray */
// Mmessage sent when system tray is accessed
#define WM_TRAYCALLBACK WM_USER + 666
// Function called to process system tray messages. - include in app
extern void TrayCallBack( HWND hwnd, WPI_PARAM1 wParam, WPI_PARAM2 lParam );
// Function to allow use of system tray when objects are minimized - include in app
extern void WndSizeChange( HWND hwnd, WPI_PARAM1 wParam, WPI_PARAM2 lParam );

#ifdef __NT__
#if !defined(WM_MOUSEWHEEL)
#define WM_MOUSEWHEEL (WM_MOUSELAST + 1)
#endif
#endif

gui_window      *GUICurrWnd     = NULL;
WPI_INST        GUIMainHInst;
extern WPI_INST GUIResHInst;

#define GUI_CLASSNAME_MAX       64

char GUIClass[GUI_CLASSNAME_MAX];
char GUIDialogClass[GUI_CLASSNAME_MAX] = "GUIDialogClass";
char GUIDefaultClassName[] = "GUIClass";
extern char *GUIGetWindowClassName( void );

#define BACKGROUND_STYLES       WS_CHILD | WS_VISIBLE
#define GUI_DIALOG_STYLE        DS_MODALFRAME

#define REGISTER_STYLE          CS_DBLCLKS
#define REGISTER_DIALOG_STYLE   CS_PARENTDC

/*
 * GUIXSetupWnd -- set the default values in the gui_window structure
 *                 struct will have been memset to 0
 */

void GUIXSetupWnd( gui_window *wnd )
{
    wnd->flags = NONE_SET;
    wnd->vrange = -1;
    wnd->hrange = -1;
}

static void GUISetWindowClassName( void )
{
    char        *class_name;

    class_name = GUIGetWindowClassName();
    if( !class_name || !*class_name ) {
        class_name = GUIDefaultClassName;
    }
    strncpy( GUIClass, class_name, GUI_CLASSNAME_MAX-1 );
    GUIClass[ GUI_CLASSNAME_MAX-1 ] = '\0';
}

void GUIWantPartialRows( gui_window *wnd, bool want )
{
    if( wnd ) {
        if( want ) {
            wnd->flags |= PARTIAL_ROWS;
        } else {
            wnd->flags &= ~PARTIAL_ROWS;
        }
    }
}

void GUISetCheckResizeAreaForChildren( gui_window *wnd, bool check )
{
    wnd=wnd;
    check=check;
}

/*
 * GUIDestroyWnd -- Destroy given window or all windows if NULL.
 *                  Window will not get WM_CLOSE message.
 */

void GUIDestroyWnd( gui_window *wnd )
{
    HWND        hwnd;
    gui_window  *curr;

    if( wnd == NULL ) {
        curr = GUIGetFront();
        while( curr != NULL ) {
            if( curr->flags & DOING_CLOSE ) {
                curr = GUIGetNextWindow( curr );
            } else if( _wpi_getparent( GUIGetParentFrameHWND( curr ) ) == HWND_DESKTOP ) {
                GUIDestroyWnd( curr );
                curr = GUIGetFront();
            } else {
                curr = GUIGetNextWindow( curr );
            }
        }
    } else {
        if ( GUIIsOpen( wnd ) ) {
            /* this will make a new window be chosen as current if this
             * window was current */
            hwnd = GUIGetParentFrameHWND( wnd );
            wnd->flags |= DOING_CLOSE;
            if( NumWindows == 1 || ( _wpi_getparent( hwnd ) == HWND_DESKTOP ) &&
                !( wnd->style & GUI_POPUP ) ) {
                _wpi_sendmessage( hwnd, WM_CLOSE, 0, 0 );
            } else {
                DestroyWindow( hwnd );
            }
        }
    }
}

static bool DoRegisterClass( WPI_INST hinst, char *class_name,
                             WPI_CLASSPROC call_back, UINT style, int extra )
{
#ifndef __OS2_PM__
    WNDCLASS    wc;

    wc.style = style;
    wc.lpfnWndProc = call_back;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = extra;
    wc.hInstance = hinst;
    wc.hIcon = _wpi_loadicon( NULL, IDI_APPLICATION );
    wc.hCursor = LoadCursor( (WPI_INST) NULL, IDC_ARROW );
    wc.hbrBackground = NULL;
    wc.lpszMenuName = NULL;
    wc.lpszClassName = class_name;

    return( RegisterClass( &wc ) != 0 );
#else
    return( WinRegisterClass( hinst.hab, class_name, call_back,
                              CS_CLIPCHILDREN | CS_SIZEREDRAW | CS_MOVENOTIFY |
                              style, extra ) );
#endif
}
/*
 * SetupClass - Register the GUIClass class
 */

static bool SetupClass( void )

{
    if( DoRegisterClass( GUIMainHInst, GUIClass, (WPI_CLASSPROC)GUIWindowProc,
                         REGISTER_STYLE, EXTRA_SIZE * NUM_EXTRA_WORDS ) ) {

        return( DoRegisterClass( GUIMainHInst, GUIDialogClass, (WPI_CLASSPROC)GUIWindowProc,
                                 REGISTER_DIALOG_STYLE,
                                 EXTRA_SIZE * NUM_EXTRA_WORDS ) );
    }
    return( FALSE );
}

void GUICleanup( void )
{
    GUIDeath();
    GUICleanupHotSpots();
    GUIFreeStatus();
    GUIFiniInternalStringTable();
    GUILoadStrFini();
    GUISysFini();
    GUIFiniDialog();
#if defined( __WINDOWS__ ) || defined( __NT__ ) || defined(WILLOWS)
    GUICtl3dUnregister();
#endif
}

#ifdef __OS2_PM__

HMQ             GUIPMmq;        /* debugger needs access to this */

int GUIXMain( int argc, char *argv[] )
{
    bool        ok;
    int         ret;
    bool        register_done;
    HAB         inst;

    inst = WinInitialize( NULL );
    if( !inst ) {
        return( 0 );
    }

    GUIPMmq = WinCreateMsgQueue( inst, 0 );
    if( !GUIPMmq ) {
        return( 0 );
    }

    register_done = FALSE;

#else

int GUIXMain( int argc, char *argv[],
              WPI_INST inst, WPI_INST hPrevInstance, LPSTR lpCmdLine,
              int nShowCmd )
{
    bool        ok;
    int         ret;
    bool        register_done;

    ret = 0;
    lpCmdLine = lpCmdLine;
    nShowCmd = nShowCmd;
    register_done = ( hPrevInstance != 0 );
    FirstInstance = ( hPrevInstance == 0 );

#endif

    GUIMainTouched = TRUE;

    GUIStoreArgs( argv, argc );

    _wpi_setwpiinst( inst, 0, &GUIMainHInst );
    memcpy( &GUIResHInst, &GUIMainHInst, sizeof( WPI_INST ) ) ;

    ok = TRUE;

    GUISetWindowClassName();
    GUIMemOpen();

    ok = GUIFirstCrack();

    if( ok ) {
        if( !register_done ) {
            ok = SetupClass();
        }
    }

    if( ok ) {
        ok = GUILoadStrInit( argv[0] );
    }

    if( ok ) {
        ok = GUIInitInternalStringTable();
    }

    if( ok ) {
        GUIInitGUIMenuHint();
        GUImain();
    }

    if( GUIGetFront() == NULL && !Posted ) {  /* no windows created */
        _wpi_postquitmessage( 0 );
    }

    if( NumWindows ) {
        ret = GUIWinMessageLoop();
    }

#ifdef __OS2_PM__
    WinDestroyMsgQueue( GUIPMmq );
    WinTerminate( inst );
#endif
    GUICleanup();
    GUIDead();
    GUIMemClose();
    return( ret );
}

/*
 * ShowWnd
 */

static void ShowWnd( HWND hwnd )
{
    if( hwnd == NULLHANDLE ) {
        GUIError( LIT( Open_Failed ) );
    } else {
        _wpi_showwindow( hwnd, SW_SHOWNORMAL );
        _wpi_updatewindow( hwnd );
    }
}

void GUIShowWindow( gui_window *wnd )
{
    GUIInvalidatePaintHandles( wnd );
    if( wnd->root != NULLHANDLE ) {
        ShowWnd( wnd->root_frame );
    }
    if( wnd->hwnd != NULLHANDLE ) {
        ShowWnd( wnd->hwnd_frame );
    }
}

void GUIShowWindowNA( gui_window *wnd )
{
    int flags;

    flags = SW_SHOWNA;
#ifdef __OS2_PM__
    flags |= SWP_ACTIVATE;
#endif

    GUIInvalidatePaintHandles( wnd );
    if( wnd->root_frame != NULLHANDLE ) {
        _wpi_showwindow( wnd->root_frame, flags );
    }
    if( ( wnd->hwnd_frame != NULLHANDLE ) &&
        ( wnd->hwnd_frame != wnd->root_frame ) ) {
        _wpi_showwindow( wnd->hwnd_frame, flags );
    }
}

/*
 * GUIWndInit -- initialize display windows
 */

bool GUIWndInit( unsigned DClickInterval, gui_window_styles style )
{
    GUIMemOpen();
    Style = style;
    GUISysInit( 0 );
    _wpi_setdoubleclicktime( DClickInterval );
    GUISetScreen( 0, 0, _wpi_getsystemmetrics( SM_CXSCREEN ),
                        _wpi_getsystemmetrics( SM_CYSCREEN ) );
    GUIInitDialog();
    return( TRUE );
}

static bool CreateBackgroundWnd( gui_window *wnd, gui_create_info *info )
{
    DWORD               style;
    wmcreate_info       wmcreateinfo;
    HWND                frame_hwnd;
    GUI_RECTDIM         left, top, right, bottom;

    _wpi_getclientrect( wnd->root, &wnd->hwnd_client );
    _wpi_getrectvalues( wnd->hwnd_client, &left, &top, &right, &bottom );

    style = BACKGROUND_STYLES;

    wmcreateinfo.size = sizeof(wmcreate_info);
    wmcreateinfo.wnd = wnd;
    wmcreateinfo.info = info;

    wnd->hwnd = NULLHANDLE;
    frame_hwnd = NULLHANDLE;

    _wpi_createanywindow( GUIClass, NULL, style,
                          0, 0, right-left, bottom-top,
                          wnd->root, NULL, GUIMainHInst,
                          &wmcreateinfo, &wnd->hwnd, 0, &frame_hwnd );

    wnd->hwnd_frame = wnd->root_frame;

    return( wnd->hwnd != NULLHANDLE );
}

static void DoSetWindowLong( HWND hwnd, gui_window *wnd )
{
    _wpi_setwindowlong( hwnd, GUI_CONTAINER_WORD1 * EXTRA_SIZE, 0L );
    _wpi_setwindowlong( hwnd, GUI_CONTAINER_WORD2 * EXTRA_SIZE, 0L );
    _wpi_setwindowlong( hwnd, GUI_EXTRA_WORD * EXTRA_SIZE, (LONG)wnd );
}

/*
 * GUIXCreateWindow
 */

bool GUIXCreateWindow( gui_window *wnd, gui_create_info *info,
                       gui_window *parent )
{
    DWORD               style;
    HMENU               hmenu;
    gui_coord           pos;
    gui_coord           size;
    HWND                parent_hwnd;
    LPSTR               class_name;
    HWND                hwnd;
    wmcreate_info       wmcreateinfo;
    HWND                frame_hwnd;
    HWND                client_hwnd;
#ifdef __OS2_PM__
    ULONG               frame_flags;
    ULONG               flags;
    ULONG               show_flags;
    WPI_RECT            rect;
    WPI_RECT            parent_client;
#endif

#ifdef __OS2_PM__
// Get rid of the changable font style for PM GUI app's
    info->style &= ~GUI_CHANGEABLE_FONT;
#endif

    wnd->root_pinfo.force_count = NUMBER_OF_FORCED_REPAINTS;
    wnd->hwnd_pinfo.force_count = NUMBER_OF_FORCED_REPAINTS;

    wnd->parent = parent;
    style = COMMON_STYLES;
    if( parent == NULL ) {
        parent_hwnd = HWND_DESKTOP;
        if( !( info->style & GUI_POPUP ) ) {
            wnd->flags |= IS_ROOT;
        }
    } else {
        parent_hwnd = parent->hwnd;
        if( !( info->style & GUI_POPUP ) ) {
            style |= CHILD_STYLE;

⌨️ 快捷键说明

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