guicontr.c

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

C
839
字号
/****************************************************************************
*
*                            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 <stdlib.h>
#include "guistyle.h"
#include "guixutil.h"
#include "guiscale.h"
#include "guicontr.h"
#include "guixwind.h"
#include "guicombo.h"
#include "guimapky.h"
#include "guixdlg.h"
#include "guixhook.h"
#include "guirdlg.h"

extern  WPI_INST        GUIMainHInst;
extern  gui_window      *GUICurrWnd;
extern  bool            EditControlHasFocus;

#if defined( UNIX )
long GUIEditFunc( HWND, WPI_MSG, WPI_PARAM1, WPI_PARAM2 );
long GUIGroupBoxFunc( HWND, WPI_MSG, WPI_PARAM1, WPI_PARAM2 );
#else
WPI_MRESULT CALLBACK GUIEditFunc( HWND, WPI_MSG, WPI_PARAM1, WPI_PARAM2 );
WPI_MRESULT CALLBACK GUIGroupBoxFunc( HWND, WPI_MSG, WPI_PARAM1, WPI_PARAM2 );
#endif

#ifdef __WINDOWS_386__
// See guicontr.h
#define CBC     (void *)
#else
#define CBC     
#endif

controls_struct GUIControls[GUI_NUM_CONTROL_CLASSES] = {
    /* classname           style              call_back         gui_control_classs  */
    { WC_BUTTON,        PUSH_STYLE,             NULL             }, /* GUI_PUSH_BUTTON    */
    { WC_BUTTON,        DEFPUSH_STYLE,          NULL             }, /* GUI_DEFPUSH_BUTTON */
    { WC_BUTTON,        RADIO_STYLE,            NULL             }, /* GUI_RADIO_BUTTON   */
    { WC_BUTTON,        CHECK_STYLE,            NULL             }, /* GUI_CHECK_BOX      */
    { WC_COMBOBOX,      COMBOBOX_STYLE,         NULL             }, /* GUI_COMBOBOX       */
    { WC_ENTRYFIELD,    EDIT_STYLE,             CBC &GUIEditFunc }, /* GUI_EDIT           */
    { WC_LISTBOX,       LISTBOX_STYLE,          NULL             }, /* GUI_LISTBOX        */
    { WC_SCROLLBAR,     SCROLLBAR_STYLE,        NULL             }, /* GUI_SCROLLBAR      */
    { WC_STATIC,        STATIC_STYLE,           NULL             }, /* GUI_STATIC         */
    { WC_GROUPBOX,      GROUPBOX_STYLE,         CBC &GUIGroupBoxFunc }, /* GUI_GROUPBOX   */
    { WC_COMBOBOX,      EDIT_COMBOBOX_STYLE,    NULL             }, /* GUI_EDIT_COMBOBOX  */
    { WC_MLE,           EDIT_MLE_STYLE,         CBC &GUIEditFunc }  /* GUI_MLE            */
};

typedef struct dialog_node {
    gui_window          *wnd;
    struct dialog_node  *next;
} dialog_node;

static  dialog_node     *DialogHead     = NULL;

bool GUIInsertCtrlWnd( gui_window *wnd )
{
    dialog_node *node;

    node = (dialog_node *)GUIMemAlloc( sizeof( dialog_node ) );
    if( node != NULL ) {
        node->wnd = wnd;
        node->next = DialogHead;
        DialogHead = node;
        return( TRUE );
    }
    return( FALSE );
}

gui_window *GUIGetCtrlWnd( HWND hwnd )
{
    dialog_node **owner;
    dialog_node *curr;

    owner = &DialogHead;
    while( *owner != NULL ) {
        curr = *owner;
        if( curr->wnd->hwnd == hwnd ) {
            return( curr->wnd );
        }
        owner = &curr->next;
    }
    return( NULL );
}

static void GUIDeleteCtrlWnd( gui_window *wnd )
{
    dialog_node **owner;
    dialog_node **prev_owner;
    dialog_node *curr;

    prev_owner = NULL;
    owner = &DialogHead;
    while( *owner != NULL ) {
        curr = *owner;
        if( curr->wnd == wnd ) {
            if( prev_owner == NULL ) {
                DialogHead = curr->next;
            } else {
                (*prev_owner)->next = curr->next;
            }
            GUIMemFree( curr );
            break;
        }
        prev_owner = owner;
        owner = &curr->next;
    }
}

/*
 * GUIGetControlByID - get the first control_item* in the given HWND with the
 *                     given id
 */

control_item *GUIGetControlByID( gui_window *parent, unsigned id )
{
    control_item * curr;

    for( curr = parent->controls; curr != NULL; curr = curr->next ) {
        if( curr->id == id ) {
            return( curr );
        }
    }
    return( NULL );
}

/*
 * GUIGetControlByHWND - get the first control_item * in the given HWND with the
 *                       given HWND
 */

control_item * GUIGetControlByHwnd( gui_window *parent, HWND control )
{
    control_item        *curr;

    for( curr = parent->controls; curr != NULL; curr = curr->next ) {
        if( curr->hwnd == control ) {
            return( curr );
        }
    }
    return( NULL );
}

/*
 * GUIControlInsert - insert a control_item associated with the given
 *                    gui_window for the given class
 */

control_item *GUIControlInsert( gui_window *parent, gui_control_class control_class,
                                HWND hwnd, gui_control_info *info,
                                WPI_PROC call_back )
{
    control_item        *item;

    item = ( control_item * )GUIMemAlloc( sizeof( control_item ) );
    if( item == NULL ) {
        return( NULL );
    }
    item->control_class = control_class;
    item->text = info->text;
    item->style = info->style;
    item->checked = info->style & GUI_CHECKED;
    item->id = info->id;
    item->next = NULL;
    item->hwnd = hwnd;
    item->call_back = call_back;
    item->next = parent->controls;
    parent->controls = item;
    return( item );
}

control_item *GUIControlInsertByHWND( HWND hwnd, gui_window *parent )
{
    control_item        *item;
    HWND                phwnd;

    phwnd = _wpi_getparent( hwnd );
    if( ( parent == NULL ) || ( phwnd != parent->hwnd ) ) {
        return( NULL );
    }
    item = ( control_item * )GUIMemAlloc( sizeof( control_item ) );
    if( item == NULL ) {
        return( NULL );
    }
    memset( item, 0, sizeof( control_item ) );
    item->control_class = GUIGetControlClassFromHWND( hwnd );
    if( item->control_class == GUI_BAD_CLASS ) {
        GUIMemFree( item );
        return( NULL );
    }

    item->style = GUIGetControlStylesFromHWND( hwnd, item->control_class );

    item->id = _wpi_getdlgctrlid( hwnd );
    item->next = NULL;
    item->hwnd = hwnd;
    item->next = parent->controls;
    parent->controls = item;

    return( item );
}

/*
 * GUIControlDelete - delete the control_item with the given it which is
 *                 associated with the given window handle
 */

void GUIControlDelete( gui_window *wnd, unsigned id )
{
    control_item        *curr;
    control_item        *prev;
    control_item        *next;

    prev = NULL;
    for( curr = wnd->controls; curr != NULL; curr = next ) {
        next = curr->next;
        if( curr->id == id ) {
            if( prev == NULL ) {
                wnd->controls = next;
            } else {
                prev->next = next;
            }
            GUIMemFree( curr );
            break;
        }
        prev = curr;
    }
    if( wnd->controls == NULL ) {
        GUIDeleteCtrlWnd( wnd );
    }
}

/*
 * GUIControlDeleteAll -- delete all control_item structs that are associated
 *                        with the given window
 */

void GUIControlDeleteAll( gui_window *wnd )
{
    control_item        *curr;
    control_item        *next;

    for( curr = wnd->controls; curr != NULL; curr = next ) {
        next = curr->next;
        GUIMemFree( curr );
    }
    wnd->controls = NULL;
    GUIDeleteCtrlWnd( wnd );
}

/*
 * GUIEditFunc - callback function for all edit windows
 */

#if defined( UNIX )
long GUIEditFunc( HWND hwnd, WPI_MSG message, WPI_PARAM1 wparam, WPI_PARAM2 lparam )
#else
WPI_MRESULT CALLBACK GUIEditFunc( HWND hwnd, WPI_MSG message, WPI_PARAM1 wparam, WPI_PARAM2 lparam )
#endif
{
    control_item        *info;
    WPI_PROC            call_back;
    HWND                parent;
    HWND                grand_parent;
    gui_window          *wnd;
    gui_key_control     key_control;
#ifdef __OS2_PM__
    WORD                key_flags;
#endif

    parent = _wpi_getparent( hwnd );
    wnd = GUIGetCtrlWnd( parent );
    info = NULL;
    if( wnd == NULL ) { /* needed for GUI_EDIT_COMBOBOX */
        grand_parent = _wpi_getframe( _wpi_getparent( parent ) );
        wnd = GUIGetCtrlWnd( grand_parent );
        if( wnd != NULL ) {
            info = GUIGetControlByHwnd( wnd, parent );
        }
        parent = grand_parent;
    } else {
        info = GUIGetControlByHwnd( wnd, hwnd );
    }
    if( info == NULL ) {
        return( 0L );
    }
    call_back = info->call_back;
    switch( message ) {
#ifndef __OS2_PM__
    case WM_SETFOCUS :
        EditControlHasFocus = TRUE;
        break;
    case WM_KILLFOCUS :
        EditControlHasFocus = FALSE;
        break;
    case WM_MOUSEACTIVATE :
        return( TRUE );
        break;
    case WM_CHAR :
        if( EditControlHasFocus ) {
            if( GUIWindowsMapKey( wparam, lparam, &key_control.key_state.key ) ) {
                GUIGetKeyState( &key_control.key_state.state );
                if( key_control.key_state.key == GUI_KEY_ENTER ) {
                    key_control.id = info->id;
                    if( GUIEVENTWND( wnd, GUI_KEY_CONTROL, &key_control ) ) {
                        return( 0L );
                    }
                }
            }
        //} else {
            //if( GUICurrWnd != NULL ) {
                //GUISendMessage( GUICurrWnd->hwnd, message, wparam, lparam );
            //}
        }
        break;
    case WM_KEYDOWN :
        if( EditControlHasFocus ) {
            if( GUIWindowsMapKey( wparam, lparam, &key_control.key_state.key ) ) {
                switch( key_control.key_state.key ) {
                case GUI_KEY_UP :
                case GUI_KEY_DOWN :
                    key_control.id = info->id;
                    GUIGetKeyState( &key_control.key_state.state );
                    GUIEVENTWND( wnd, GUI_KEY_CONTROL, &key_control );
                }
            }
        //} else {
            //if( GUICurrWnd != NULL ) {
                //GUISendMessage( GUICurrWnd->hwnd, message, wparam, lparam );
            //}
        }
        break;
#else
    case WM_CHAR :
        if( EditControlHasFocus ) {
            key_flags = SHORT1FROMMP( wparam );
            if( !( key_flags & KC_KEYUP ) &&
                GUIWindowsMapKey( wparam, lparam, &key_control.key_state.key ) ) {
                switch( key_control.key_state.key ) {
                //case GUI_KEY_ENTER :
                case GUI_KEY_UP :
                case GUI_KEY_DOWN :
                    key_control.id = info->id;
                    GUIGetKeyState( &key_control.key_state.state );
                    if( GUIEVENTWND( wnd, GUI_KEY_CONTROL, &key_control ) ) {
                        return( 0L );
                    }
                }
            }
        //} else {
            //if( GUICurrWnd != NULL ) {
                //GUISendMessage( GUICurrWnd->hwnd, message, wparam, lparam );
            //}
        }
        break;
#endif
    case WM_RBUTTONUP:
        break;
    case WM_NCDESTROY:
        GUIControlDelete( wnd, info->id );
        _wpi_subclasswindow( hwnd, call_back );
        break;
    }
    return( (WPI_MRESULT)_wpi_callwindowproc( (WPI_WNDPROC)call_back, hwnd, message, wparam, lparam ) );
}

/*
 * GUIGroupBoxFunc - callback function for all GroupBox windows
 */

#if defined( UNIX )
long GUIGroupBoxFunc( HWND hwnd, WPI_MSG message, WPI_PARAM1 wparam, WPI_PARAM2 lparam )
#else
WPI_MRESULT CALLBACK GUIGroupBoxFunc( HWND hwnd, WPI_MSG message, WPI_PARAM1 wparam, WPI_PARAM2 lparam )
#endif
{
    control_item        *info;
    WPI_PROC            call_back;
    WPI_PRES            hdc;
    WPI_RECT            rect;
    HWND                parent;
    gui_window          *wnd;

    parent = _wpi_getparent( hwnd );
    wnd = GUIGetCtrlWnd( parent );
    info = NULL;
    if( wnd != NULL ) {

⌨️ 快捷键说明

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