guimenus.c

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

C
1,025
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "guiwind.h"
#include <string.h>
#include "guimenus.h"
#include "guixwind.h"
#include "guixutil.h"
#include "guifloat.h"
#include "guifont.h"
#include "guistr.h"
#include "guixhook.h"
#include "guihook.h"

#define MAX_STR 256

gui_menu_struct GUIHint[] = {
 { NULL, GUI_CHANGE_FONT, GUI_ENABLED, NULL },
 { NULL, GUI_FIX_TOOLBAR, GUI_ENABLED, NULL }
};
#define NUM_GUI_HINT ( sizeof( GUIHint ) / sizeof( gui_menu_struct ) )

void GUIInitGUIMenuHint( void )
{
    GUIHint[0].label = LIT( Change_XFont_ );
    GUIHint[0].hinttext = LIT( Change_Font_for_this_window  );
    GUIHint[1].label = LIT( XFix_Tool_Bar );
    GUIHint[1].hinttext = LIT( Make_Tool_Bar_Fixed );
}

extern  bool    GUIMDI;

typedef struct popup_info {
    HMENU               popup;
    unsigned            id;
    bool                floating;
    hint_type           type;
    struct popup_info   *next;
};

static bool GetMenuFlags( HMENU hmenu, unsigned id, bool by_position,
                          unsigned *menu_flags, unsigned *attr_flags )
{
    WPI_MENUSTATE       mstate;

    if( hmenu != NULLHANDLE ) {
        _wpi_getmenustate( hmenu, id, &mstate, by_position );
        _wpi_getmenuflagsfromstate( &mstate, menu_flags, attr_flags );
        return( TRUE );
    }

    return( FALSE );
}

static bool GetParentOffset( HMENU hmenu, HMENU popup, HMENU *parent,
                             int *offset )
{
    int         num;
    int         i;
    HMENU       submenu;

    num = (int) _wpi_getmenuitemcount( hmenu );
    for( i = 0; i < num; i++ ) {
        submenu = _wpi_getsubmenu( hmenu, i );
        if( submenu != NULLHANDLE ) {
            if( submenu == popup ) {
                if( parent != NULL ) {
                    *parent = hmenu;
                }
                if( offset != NULL ) {
                    *offset = i;
                }
                return( TRUE );
            } else {
                if( GetParentOffset( submenu, popup, parent, offset ) ) {
                    return( TRUE );
                }
            }
        }
    }
    return( FALSE );
}

static HMENU GetPopupHMENU( gui_window *wnd, HMENU hmenu, unsigned id,
                            HMENU *parent, int *offset, hint_type type )
{
    popup_info  *info;

    if( parent ) {
        *parent = NULL;
    }
    if( offset ) {
        *offset = 0;
    }
    for( info = wnd->popup; info != NULL; info = info->next ) {
        if( ( info->id == id ) && ( info->type == type ) ) {
            if( ( parent != NULL ) || ( offset != NULL ) ) {
                GetParentOffset( hmenu, info->popup, parent, offset );
                if( parent && !*parent ) {
                    return( NULLHANDLE );
                }
            }
            return( info->popup );
        }
    }
    return( NULLHANDLE );
}

void GetStateForMenu( gui_window *wnd, int id, WPI_MENUSTATE *mstate )
{
    HMENU               hmenu, popup, parent;
    int                 offset;

    hmenu = GUIGetHMENU( wnd );
    if( hmenu == NULLHANDLE ) {
        return;
    }

    popup = GetPopupHMENU( wnd, hmenu, id, &parent, &offset, MENU_HINT );

    if( popup ) {
        _wpi_getmenustate( parent, offset, mstate, TRUE );
    } else {
        _wpi_getmenustate( hmenu, id, mstate, FALSE );
    }
}

bool GUIIsMenuItemChecked( gui_window *wnd, int id )
{
    WPI_MENUSTATE       mstate;

    GetStateForMenu( wnd, id, &mstate );

    return( (bool)_wpi_ismenucheckedfromstate( &mstate ) );
}

bool GUIIsMenuItemEnabled( gui_window *wnd, int id )
{
    WPI_MENUSTATE       mstate;

    GetStateForMenu( wnd, id, &mstate );

    return( (bool)_wpi_ismenuenabledfromstate( &mstate ) );
}

void GUISetMenu( gui_window *wnd, HMENU hmenu )
{
    HWND        frame;
    WPI_RECT    rect;
    gui_coord   size;
    int         height;
#ifndef __OS2_PM__
    HMENU       omenu;
#endif

#ifndef __OS2_PM__
    omenu = GUIGetHMENU( wnd );
#endif
    frame = GUIGetParentFrameHWND( wnd );
    _wpi_getclientrect( frame, &rect );
    height = _wpi_getheightrect( rect );
    _wpi_setmenu( frame, hmenu );
    _wpi_getclientrect( frame, &rect );
    if( height != ( size.y = _wpi_getheightrect( rect ) ) ) {
        size.x = _wpi_getwidthrect( rect );
        GUIDoResize( wnd, GUIGetParentHWND( wnd ), &size );
    }
#ifndef __OS2_PM__
    if( omenu != (HMENU)NULL ) {
        _wpi_destroymenu( omenu );
    }
#endif
}

static bool GetPopupId( gui_window *wnd, HMENU hmenu, unsigned *id )
{
    popup_info  *info;

    for( info = wnd->popup; info != NULL; info = info->next ) {
        if( info->popup == hmenu ) {
            *id = info->id;
            return( TRUE );
        }
    }
    return( FALSE );
}


static bool InsertPopup( gui_window *wnd, unsigned id, HMENU popup,
                         hint_type type )
{
    popup_info  *info;
    HMENU       hmenu;

    hmenu = GetPopupHMENU( wnd, GUIGetHMENU( wnd ), id, NULL, NULL, type );
    if( hmenu != popup ) {
        info = (popup_info *)GUIMemAlloc( sizeof( popup_info ) );
        if( info != NULL ) {
            info->next = wnd->popup;
            wnd->popup = info;
            info->id = id;
            info->popup = popup;
            info->type = type;
            return( TRUE );
        } else {
            return( FALSE );
        }
    }
    return( TRUE );
}

static void DeletePopup( gui_window *wnd, unsigned id )
{
    popup_info  *curr;
    popup_info  *prev;

    prev = NULL;
    for( curr = wnd->popup; curr != NULL; prev = curr, curr=curr->next ) {
        if( ( curr->id == id ) && ( curr->type == MENU_HINT ) ) break;
    }
    if( curr != NULL ) {
        if( prev != NULL ) {
            prev->next = curr->next;
        } else {
            wnd->popup = curr->next;
        }
        GUIMemFree( curr );
    }
}

void GUIDeleteFloatingPopups( gui_window *wnd )
{
    popup_info  *curr;
    popup_info  *prev;
    popup_info  *tmp;

    prev = NULL;
    for( curr = wnd->popup; curr != NULL; ) {
        if( curr->type == FLOAT_HINT ) {
            if( prev != NULL ) {
                prev->next = curr->next;
            } else {
                wnd->popup = curr->next;
            }
            tmp = curr->next;
            GUIMemFree( curr );
            curr = tmp;
        } else {
            prev = curr;
            curr = curr->next;
        }
    }
}

void GUIFreePopupList( gui_window *wnd )
{
    popup_info  *curr;
    popup_info  *next;

    for( curr = wnd->popup; curr != NULL; curr = next ) {
        next = curr->next;
        GUIMemFree( curr );
    }
    wnd->popup = NULLHANDLE;
}

void GUISetGUIHint( gui_window *wnd )
{
    GUIInitHint( wnd, NUM_GUI_HINT, GUIHint, GUI_HINT );
}

HMENU   GUIHFloatingPopup       = NULLHANDLE;

/*
 * GUIGetHMENU -- return the HMENU that the user can change
 */

HMENU GUIGetHMENU( gui_window *wnd )
{
    HMENU hmenu;

    if( wnd->root_frame == NULLHANDLE ) { /* child window */
        if( wnd->hwnd_frame == NULLHANDLE ) return( NULLHANDLE );
        hmenu = _wpi_getsystemmenu( wnd->hwnd_frame );
    } else {
        hmenu = _wpi_getmenu( wnd->root_frame );
    }
    return( hmenu );
}

static void GUIDrawMenuBar( gui_window *wnd )
{
    if( wnd->root_frame != NULLHANDLE ) {
        if( _wpi_getmenu( wnd->root_frame ) != NULLHANDLE ) {
            _wpi_drawmenubar( wnd->root_frame );
        }
    } else {
        if( wnd->style & GUI_POPUP ) {
            if( _wpi_getmenu( wnd->hwnd_frame ) != NULLHANDLE ) {
                _wpi_drawmenubar( wnd->hwnd_frame );
            }
        }
    }
}

int GUIGetMenuPopupCount( gui_window *wnd, int id )
{
    HMENU       hmenu, popup;
    int         count;

    hmenu = GUIGetHMENU( wnd );
    if( hmenu == NULLHANDLE ) {
        return( FALSE );
    }

    popup = GetPopupHMENU( wnd, hmenu, id, NULL, NULL, MENU_HINT );

    if( popup ) {
        count = (int)_wpi_getmenuitemcount( popup );
    } else {
        count = -1;
    }

    return( count );
}

static HMENU GetOrMakeHMENU( gui_window *wnd, bool floating, bool *made_root )
{
    HMENU       hmenu;

    if( made_root ) {
        *made_root = FALSE;
    }
    if( floating ) {
        if( GUIHFloatingPopup == NULLHANDLE ) {
            GUIHFloatingPopup = _wpi_createpopupmenu();
        }
        hmenu = GUIHFloatingPopup;
    } else {
        hmenu = GUIGetHMENU( wnd );
        if( hmenu == NULLHANDLE ) {
            if( wnd->root_frame != NULLHANDLE ) {
                hmenu = _wpi_createmenu();
                if( hmenu != NULLHANDLE ) {
                    //GUISetMenu( wnd, hmenu );
                    if( made_root ) {
                        *made_root = TRUE;
                    }
                }
            }
        }
    }
    return( hmenu );
}

/*
 * GUIDeleteMenuItem -- delete the given menu item
 */

bool GUIDeleteMenuItem( gui_window *wnd, int id, bool floating )
{
    HMENU       hmenu, popup, parent;
    int         offset;
    hint_type   type;

    if( floating ) {
        type = FLOAT_HINT;
    } else {
        type = MENU_HINT;
    }
    hmenu = GetOrMakeHMENU( wnd, floating, NULL );
    if( hmenu == NULLHANDLE ) {
        return( FALSE );
    }

    popup = GetPopupHMENU( wnd, hmenu, id, &parent, &offset, type );

    if( popup ) {
        _wpi_deletemenu( parent, offset, TRUE );
    } else {
        _wpi_deletemenu( hmenu, id, FALSE );
    }

    GUIDeleteHintText( wnd, id );
    DeletePopup( wnd, id );
    GUIMDIDeleteMenuItem( id );

    if( hmenu == parent ) {
        GUIDrawMenuBar( wnd );
    }

    return( TRUE );
}

void CheckItem( HMENU hmenu, int id, bool check )
{
    _wpi_checkmenuitem( hmenu, id, check, FALSE );
}

void CheckPopup( HMENU hmenu, int offset, bool check )
{
    _wpi_checkmenuitem( hmenu, offset, check, TRUE );
}

/*
 * GUICheckMenuItem -- check or uncheck a menu item
 */

bool GUICheckMenuItem( gui_window *wnd, int id, bool check, bool floating )
{
    HMENU       hmenu, popup, parent;
    int         offset;
    hint_type   type;

    if( floating ) {
        type = FLOAT_HINT;
    } else {
        type = MENU_HINT;
    }
    hmenu = GetOrMakeHMENU( wnd, floating, NULL );
    if( hmenu == NULLHANDLE ) {
        return( FALSE );
    }

    popup = GetPopupHMENU( wnd, hmenu, id, &parent, &offset, MENU_HINT );

    if( popup ) {
        CheckPopup( parent, offset, check );
    } else {
        CheckItem( hmenu, id, check );
    }

    if( hmenu == parent ) {
        GUIDrawMenuBar( wnd );
    }

    return( TRUE );
}

void EnableItem( HMENU hmenu, int id, bool enable )
{
    _wpi_enablemenuitem( hmenu, id, enable, FALSE );
}

void EnablePopup( HMENU hmenu, int offset, bool enable )
{
    _wpi_enablemenuitem( hmenu, offset, enable, TRUE );
}

/*
 * GUIEnableSysMenuItem -- enable or disable a system menu item.  Used
 *                         by GUI library only
 */

bool GUIEnableSysMenuItem( gui_window *wnd, int id, bool enable )
{
    HMENU       hmenu;

    hmenu = _wpi_getsystemmenu( GUIGetParentFrameHWND( wnd ) );
    if( hmenu != (HMENU)NULL ) {
        EnableItem( hmenu, id, enable );
    }
    return( TRUE );
}

/*
 * GUIEnableMenuItem -- enable or disable a menu item
 */

bool GUIEnableMenuItem( gui_window *wnd, int id, bool enable, bool floating )
{
    HMENU       hmenu, popup, parent;
    int         offset;
    hint_type   type;

    if( floating ) {
        type = FLOAT_HINT;
    } else {
        type = MENU_HINT;
    }
    hmenu = GetOrMakeHMENU( wnd, floating, NULL );
    if( hmenu == NULLHANDLE ) {
        return( FALSE );
    }

⌨️ 快捷键说明

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