⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mdisim.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*
*                            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:  MDI window simulator.
*
****************************************************************************/


#define OEMRESOURCE
#include <windows.h>
#include <string.h>
#include "mdisim.h"
#ifdef __WINDOWS_386__
#include <stdio.h>
#include <malloc.h>
#endif

typedef char    bool;

#define MAX_STR         256
#define STATE_NORMAL    0x00
#define STATE_MAX       0x01
#define CLOSE_BITMAP_X  18
#define CLOSE_BITMAP_Y  18

typedef struct mdi_data {
    struct mdi_data     *next;
    HWND                hwnd;
    RECT                orig_size;
    char                orig_state;
    char                curr_state;
} mdi_data;

extern LPVOID   MemAlloc( UINT );
extern void     MemFree( LPVOID );

static mdi_info mdiInfo;
static char     childrenMaximized;
static char     updatedMenu;
static char     insertedItems;
static HBITMAP  closeBitmap;
static HBITMAP  restoreBitmap;
static HBITMAP  restoredBitmap;
static mdi_data *mdiHead;
static mdi_data *mdiTail;
static HWND     currentWindow;
//static RECT   minChildRect;
//static char   haveMinChildRect;

#define MDI_DATA_FROM_HWND( hwnd ) ((mdi_data *) GetWindowLong( hwnd, mdiInfo.data_off ))

/*
 * MDIInit - initialize MDI
 */
void MDIInit( mdi_info *mi )
{
    mdiInfo = *mi;

} /* MDIInit */

/*
 * MDIInitMenu - initialize menu for MDI
 */
void MDIInitMenu( void )
{

    if( childrenMaximized ) {
        MDIClearMaximizedMenuConfig();
        deleteMaximizedMenuConfig();
        setMaximizedMenuConfig( currentWindow );
        if( currentWindow != NULL ) {
            mdiInfo.set_window_title( currentWindow );
        }
    } else {
        DrawMenuBar( mdiInfo.root );
    }

} /* MDIInitMenu */

void MDISetOrigSize( HWND hwnd, RECT *rect )
{
    mdi_data    *md;

    md = MDI_DATA_FROM_HWND( hwnd );

    CopyRect( &md->orig_size, rect );
}

/*
 * doMaximize - handle maximizing an edit window
 */
static void doMaximize( HWND hwnd )
{
    DWORD               style;
    mdi_data            *md;
    RECT                r;
    WINDOWPLACEMENT     place;
    bool                iconic;

    setMaximizedMenuConfig( hwnd );

    md = MDI_DATA_FROM_HWND( hwnd );

    if( mdiInfo.start_max_restore != NULL ) {
        mdiInfo.start_max_restore( hwnd );
    }

    iconic = IsIconic( hwnd );
    if( iconic ) {
        place.length = sizeof( WINDOWPLACEMENT );
        GetWindowPlacement( hwnd, &place );
        CopyRect( &md->orig_size, &place.rcNormalPosition );
    } else {
        GetWindowRect( hwnd, &md->orig_size );
    }
    md->orig_state = md->curr_state;
    md->curr_state = STATE_MAX;

    if( mdiInfo.set_style != NULL ) {
        (mdiInfo.set_style)( hwnd, TRUE );
    } else {
        style = GetWindowLong( hwnd, GWL_STYLE );
        style &= ~mdiInfo.reg_style;
        style |= mdiInfo.max_style;
        SetWindowLong( hwnd, GWL_STYLE, style );
    }
    SetScrollRange( hwnd, SB_VERT, 1, 1, TRUE );
    SetScrollRange( hwnd, SB_HORZ, 1, 1, TRUE );
    GetWindowRect( mdiInfo.container, &r );

    if( !iconic ) {
        OffsetRect( &md->orig_size, -r.left, -r.top );
    }

    OffsetRect( &r, -r.left, -r.top );
    r.right++;
    r.bottom++;

    if( iconic ) {
        CopyRect( &place.rcNormalPosition, &r );
        place.showCmd = SW_SHOWNORMAL;
        SetWindowPlacement( hwnd, &place );
    } else {
        MoveWindow( hwnd, r.left, r.top, r.right, r.bottom, TRUE );
    }

    if( mdiInfo.end_max_restore != NULL ) {
        mdiInfo.end_max_restore( hwnd );
    }

    InvalidateRect( hwnd, NULL, NULL );

} /* doMaximize */

/*
 * doRestore - handle restoring an edit window
 */
static void doRestore( HWND hwnd )
{
    DWORD       style;
    mdi_data    *md;

    md = MDI_DATA_FROM_HWND( hwnd );

    if( md->curr_state == STATE_NORMAL ) {
        return;
    }

    if( mdiInfo.start_max_restore != NULL ) {
        mdiInfo.start_max_restore( hwnd );
    }

    md->curr_state = md->orig_state = STATE_NORMAL;

    if( mdiInfo.set_style != NULL ) {
        (mdiInfo.set_style)( hwnd, FALSE );
    } else {
        style = GetWindowLong( hwnd, GWL_STYLE );
        style &= ~mdiInfo.max_style;
        style |= mdiInfo.reg_style;
        SetWindowLong( hwnd, GWL_STYLE, style );
    }

    SetScrollRange( hwnd, SB_VERT, 1, 1, TRUE );
    SetScrollRange( hwnd, SB_HORZ, 1, 1, TRUE );
    // unnecessarily messy as the MoveWindow repaints
    //UpdateWindow( hwnd );
    MoveWindow( hwnd, md->orig_size.left, md->orig_size.top,
                md->orig_size.right - md->orig_size.left,
                md->orig_size.bottom - md->orig_size.top, TRUE );
    if( mdiInfo.end_max_restore != NULL ) {
        mdiInfo.end_max_restore( hwnd );
    }

} /* doRestore */

/*
 * doRestoreAll - set all children as needing restoration
 */
static void doRestoreAll( void )
{
    mdi_data    *md;

    if( !childrenMaximized ) {
        return;
    }
    SetWindowText( mdiInfo.root, mdiInfo.main_name );
    childrenMaximized = FALSE;
    md = mdiHead;
    while( md != NULL ) {
        doRestore( md->hwnd );
        md = md->next;
    }
    MDIClearMaximizedMenuConfig();
    deleteMaximizedMenuConfig();

} /* doRestoreAll */

/*
 * doMaximizeAll - maximize all children
 */
static void doMaximizeAll( HWND first )
{
    mdi_data    *md;
    bool        was_max;

    was_max = childrenMaximized;

    childrenMaximized = TRUE;

    doMaximize( first );

    if( !was_max ) {
        md = mdiHead;
        while( md != NULL ) {
            if( md->hwnd != first ) {
                if( !IsIconic( md->hwnd ) ) {
                    doMaximize( md->hwnd );
                }
            }
            md = md->next;
        }
    }

    SetSystemMenu( first );

} /* doMaximizeAll */

/*
 * getMenuBitmaps - load restore/restored bitmaps, and
 *                  get a bitmap for the close gadget (ack pft)
 */
static void getMenuBitmaps( void )
{
    #if 0
        HBITMAP hbmp;
        BITMAP  bmp;
        WORD    new_real_width;
        WORD    old_real_width;
        WORD    new_width;
        LPSTR   bits;
        LPSTR   new_bits;
        LPSTR   old_bits;
        LPSTR   bmp_bits;
        WORD    size;
        int             x,y;
    #endif

    if( restoreBitmap == NULL ) {
        restoreBitmap = LoadBitmap( (HANDLE) NULL, MAKEINTRESOURCE( OBM_RESTORE ) );
    }
    if( restoredBitmap == NULL ) {
        restoredBitmap = LoadBitmap( (HANDLE) NULL, MAKEINTRESOURCE( OBM_RESTORED ) );
    }

    if( closeBitmap == NULL ) {
        closeBitmap = LoadBitmap( mdiInfo.hinstance, "CLOSEBMP" );
    }
    updatedMenu = TRUE;

} /* getMenuBitmaps */

static HMENU DuplicateMenu( HMENU orig )
{
    int         num;
    UINT        id;
    UINT        flags;
    char        name[MAX_STR];
    int         i;
    HMENU       copy;
    HMENU       sub;

    if( orig != NULL ) {
        copy = CreatePopupMenu();
        if( copy == NULL ) {
            return( NULL );
        }
        num = GetMenuItemCount( orig );
        for( i = 0; i < num; i++ ) {
            flags = GetMenuState( orig, i, MF_BYPOSITION );
            if( flags & MF_SEPARATOR ) {
                AppendMenu( copy, flags, 0, 0 );
            } else if( flags & MF_POPUP ) {
                sub = DuplicateMenu( GetSubMenu( orig, i ) );
                GetMenuString( orig, i, name, MAX_STR - 1, MF_BYPOSITION );
                AppendMenu( copy, flags, (UINT)sub, name );
            } else {
                id = GetMenuItemID( orig, i );
                GetMenuString( orig, i, name, MAX_STR - 1, MF_BYPOSITION );
                AppendMenu( copy, flags, id, name );
            }
        }
    }
    return( copy );
}

/*
 * generateSystemMenu - generate a copy of the system menu for given window
 */
static HMENU generateSystemMenu( HWND hwnd )
{
    HMENU       sys_menu;

    sys_menu = GetSystemMenu( hwnd, FALSE );
    if( sys_menu != NULL ) {
        return( DuplicateMenu( sys_menu ) );
    } else {
        return( NULL );
    }

} /* generateSystemMenu */

/*
 * modifyChildSystemMenu - adjust system menu to make it a child system menu
 */
static HMENU modifyChildSystemMenu( HMENU sys_menu )
{
    if( sys_menu == NULL ) {
        return( NULL );
    }

    /* fix hotkey designation for close
    */
    ModifyMenu( sys_menu, SC_CLOSE, MF_BYCOMMAND | MF_STRING,
                                    SC_CLOSE, "&Close\tCtrl+F4" );

    /* remove task switch option
    */
    DeleteMenu( sys_menu, SC_TASKLIST, MF_BYCOMMAND );

    /* add next window option
    */
    AppendMenu( sys_menu, MF_STRING, SC_NEXTWINDOW, "Nex&t\tCtrl+F6" );

    return( sys_menu );
}

/*
 * SetSystemMenu -- make the system menu showing belong to the current window
 */
void SetSystemMenu( HWND hwnd )
{
    HMENU       sys_menu;
    HMENU       menu;

    sys_menu = NULL;
    if( hwnd != NULL ) {
        sys_menu = generateSystemMenu( hwnd );
    }
    menu = GetMenu( mdiInfo.root );
    getMenuBitmaps();
    if( sys_menu != NULL ) {
        ModifyMenu( menu, 0, MF_POPUP | MF_BYPOSITION | MF_BITMAP,
                    (UINT) sys_menu, (LPVOID)closeBitmap );
    } else {
        ModifyMenu( menu, 0, MF_BYPOSITION | MF_BITMAP, -1,
                    (LPVOID)closeBitmap );
    }
    DrawMenuBar( mdiInfo.root );
}

/*
 * hitSysMenu - check if a specified point hit the system menu
 */
static bool hitSysMenu( HWND hwnd, LONG lparam )
{
    RECT        r;
    POINT       pt;

    GetWindowRect( hwnd, &r );
    r.top += GetSystemMetrics( SM_CYCAPTION ) + GetSystemMetrics( SM_CYFRAME );
    r.left += GetSystemMetrics( SM_CXFRAME );
    r.bottom = r.top + CLOSE_BITMAP_Y;
    r.right = r.left + CLOSE_BITMAP_X;
    pt.x = LOWORD( lparam );
    pt.y = HIWORD( lparam );
    return( PtInRect( &r, pt ) );

} /* hitSysMenu */

#if 0
/*
 * HitRestoreButton - check if a specified point hit the restore button
 */
bool HitRestoreButton( HWND hwnd, LONG lparam )
{
    RECT        r;

    GetWindowRect( hwnd, &r );
    r.top += GetSystemMetrics( SM_CYCAPTION ) + GetSystemMetrics( SM_CYFRAME );
    r.bottom = r.top + CLOSE_BITMAP_Y;
    r.right -= GetSystemMetrics( SM_CXFRAME );
    r.left = r.right - CLOSE_BITMAP_X;
    return( PtInRect( &r, MAKEPOINT( lparam ) ) );

} /* HitRestoreButton */

/*
 * SetRestoreBitmap - set the bitmap on our restore menu item
 */
void SetRestoreBitmap( bool pressed )
{
    HMENU       menu;

    menu = GetMenu( mdiInfo.root );
    if( pressed ) {
        ModifyMenu( menu, 7, MF_BYPOSITION | MF_BITMAP | MF_HELP,
                        SC_RESTORE, (LPVOID) restoredBitmap );
    } else {
        ModifyMenu( menu, 7, MF_BYPOSITION | MF_BITMAP | MF_HELP,
                        SC_RESTORE, (LPVOID) restoreBitmap );
    }
    DrawMenuBar( mdiInfo.root );

} /* SetRestoreBitmap */
#endif

/*
 * setMaximizedMenuConfig - set up main menu in the maximized configuration
 */
static void setMaximizedMenuConfig( HWND hwnd )
{
    HMENU       menu;
    HMENU       sys_menu;

    if( insertedItems ) {
        SetSystemMenu( hwnd );
    } else {
        getMenuBitmaps();
        menu = GetMenu( mdiInfo.root );
        insertedItems = TRUE;
        sys_menu = generateSystemMenu( hwnd );
        if( sys_menu != NULL ) {
            InsertMenu( menu, 0, MF_POPUP | MF_BYPOSITION | MF_BITMAP,
                        (UINT) sys_menu, (LPVOID) closeBitmap );
        } else {
            InsertMenu( menu, 0, MF_BYPOSITION | MF_BITMAP, -1,
                        (LPVOID) closeBitmap );
        }
        InsertMenu( menu, -1, MF_HELP | MF_BYPOSITION | MF_BITMAP, SC_RESTORE,
                    (LPVOID) restoreBitmap );
        DrawMenuBar( mdiInfo.root );
    }

} /* setMaximizedMenuConfig */

/*
 * MDIClearMaximizedMenuConfig - done with maximized menu configuration
 */
void MDIClearMaximizedMenuConfig( void )
{
    updatedMenu = FALSE;
    if( closeBitmap != NULL ) {
        DeleteObject( closeBitmap );
        closeBitmap = NULL;
    }
    if( restoreBitmap != NULL ) {
        DeleteObject( restoreBitmap );
        restoreBitmap = NULL;

⌨️ 快捷键说明

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