📄 wmdisim.c
字号:
/****************************************************************************
*
* 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 implementation for Windows and OS/2.
*
****************************************************************************/
#include <string.h>
#include <stdio.h>
#ifdef __OS2_PM__
#define INCL_PM
#include "os2.h"
#else
#define OEMRESOURCE
#include <windows.h>
#ifdef __WINDOWS_386__
#include <malloc.h>
#endif
#endif
#include "wmdisim.h"
extern LPVOID MemAlloc( UINT );
extern void MemFree( LPVOID );
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;
WPI_RECT orig_size;
char orig_state;
char curr_state;
} mdi_data;
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 WPI_RECT minChildRect;
//static char haveMinChildRect;
#define MDI_DATA_FROM_HWND( hwnd ) ((mdi_data *) _wpi_getwindowlong( hwnd, mdiInfo.data_off ))
static void deleteMaximizedMenuConfig( void );
void SetSystemMenu( HWND hwnd );
static void setMaximizedMenuConfig( HWND hwnd );
/*
* 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 {
_wpi_drawmenubar( mdiInfo.root );
}
} /* MDIInitMenu */
void MDISetOrigSize( HWND hwnd, WPI_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;
WPI_RECT r;
bool iconic;
WPI_RECTDIM left, top, right, bottom;
setMaximizedMenuConfig( hwnd );
md = MDI_DATA_FROM_HWND( hwnd );
if( mdiInfo.start_max_restore != NULL ) {
mdiInfo.start_max_restore( hwnd );
}
iconic = _wpi_isiconic( hwnd );
if( iconic ) {
_wpi_getrestoredrect( hwnd, &md->orig_size );
} else {
_wpi_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 = _wpi_getwindowlong( hwnd, GWL_STYLE );
style &= ~mdiInfo.reg_style;
style |= mdiInfo.max_style;
_wpi_setwindowlong( hwnd, GWL_STYLE, style );
}
_wpi_setscrollrange( hwnd, SB_VERT, 1, 1, TRUE );
_wpi_setscrollrange( hwnd, SB_HORZ, 1, 1, TRUE );
_wpi_getwindowrect( mdiInfo.container, &r );
_wpi_getrectvalues( r, &left, &top, &right, &bottom );
if( !iconic ) {
_wpi_offsetrect( mdiInfo.hinstance, &md->orig_size, -left, -top );
}
_wpi_setrectvalues( &r, 0, 0, right-left+1, bottom-top+1 );
if( iconic ) {
_wpi_setrestoredrect( hwnd, &r );
} else {
_wpi_getrectvalues( r, &left, &top, &right, &bottom );
_wpi_movewindow( hwnd, left, top, right, bottom, TRUE );
}
if( mdiInfo.end_max_restore != NULL ) {
mdiInfo.end_max_restore( hwnd );
}
_wpi_invalidaterect( hwnd, NULL, FALSE );
} /* doMaximize */
/*
* doRestore - handle restoring an edit window
*/
static void doRestore( HWND hwnd )
{
DWORD style;
mdi_data *md;
WPI_RECTDIM left, top, right, bottom;
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 = _wpi_getwindowlong( hwnd, GWL_STYLE );
style &= ~mdiInfo.max_style;
style |= mdiInfo.reg_style;
_wpi_setwindowlong( hwnd, GWL_STYLE, style );
}
_wpi_setscrollrange( hwnd, SB_VERT, 1, 1, TRUE );
_wpi_setscrollrange( hwnd, SB_HORZ, 1, 1, TRUE );
_wpi_updatewindow( hwnd );
_wpi_getrectvalues( md->orig_size, &left, &top, &right, &bottom );
_wpi_movewindow( hwnd, left, top, right - left, bottom - 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;
}
_wpi_setwindowtext( mdiInfo.root, mdiInfo.main_name );
childrenMaximized = FALSE;
md = mdiHead;
while( md != NULL ) {
doRestore( md->hwnd );
md = md->next;
}
MDIClearMaximizedMenuConfig();
deleteMaximizedMenuConfig();
} /* doRestoreAll */
#ifndef __OS2_PM__
/*
* 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( _wpi_isiconic( md->hwnd ) ) {
doMaximize( md->hwnd );
}
}
md = md->next;
}
}
SetSystemMenu( first );
} /* doMaximizeAll */
#endif
/*
* getMenuBitmaps - load restore/restored bitmaps, and
* get a bitmap for the close gadget (ack pft)
*/
static void getMenuBitmaps( void )
{
if( restoreBitmap == NULL ) {
#ifdef __OS2_PM__
restoreBitmap = WinGetSysBitmap( HWND_DESKTOP, SBMP_RESTOREBUTTON );
#else
restoreBitmap = LoadBitmap( (HANDLE) NULL, MAKEINTRESOURCE( OBM_RESTORE ) );
#endif
}
if( restoredBitmap == NULL ) {
#ifdef __OS2_PM__
restoredBitmap = WinGetSysBitmap( HWND_DESKTOP, SBMP_RESTOREBUTTONDEP );
#else
restoredBitmap = LoadBitmap( (HANDLE) NULL, MAKEINTRESOURCE( OBM_RESTORED ) );
#endif
}
if( closeBitmap == NULL ) {
#ifdef __OS2_PM__
closeBitmap = WinGetSysBitmap( HWND_DESKTOP, SBMP_SYSMENU );
#else
closeBitmap = LoadBitmap( mdiInfo.hinstance, "CLOSEBMP" );
#endif
}
updatedMenu = TRUE;
} /* getMenuBitmaps */
static HMENU DuplicateMenu( HMENU orig )
{
WPI_MENUSTATE mstate;
int num;
unsigned menu_flags;
unsigned attr_flags;
UINT id;
char name[MAX_STR];
int i;
HMENU copy;
HMENU sub;
if( orig != NULL ) {
copy = _wpi_createpopupmenu();
if( copy == NULL ) {
return( NULL );
}
num = (int)_wpi_getmenuitemcount( orig );
for( i = 0; i < num; i++ ) {
if( _wpi_getmenustate( orig, i, &mstate, TRUE ) ) {
_wpi_getmenuflagsfromstate( &mstate, &menu_flags, &attr_flags );
if( _wpi_ismenuseparatorfromstate( &mstate ) ) {
_wpi_appendmenu( copy, menu_flags, attr_flags, 0, NULL, NULL );
} else if( _wpi_ismenupopupfromstate( &mstate ) ) {
sub = DuplicateMenu( _wpi_getsubmenu( orig, i ) );
name[0] = 0;
_wpi_getmenutext( orig, i, name, MAX_STR-1, TRUE );
_wpi_appendmenu( copy, menu_flags, attr_flags, 0, sub, name );
} else {
id = _wpi_getmenuitemid( orig, i );
_wpi_getmenutext( orig, i, name, MAX_STR-1, TRUE );
_wpi_appendmenu( copy, menu_flags, attr_flags, id, NULL, name );
}
}
}
}
return( copy );
}
/*
* generateSystemMenu - generate a copy of the system menu for given window
*/
static HMENU generateSystemMenu( HWND hwnd )
{
HMENU sys_menu;
sys_menu = _wpi_getsystemmenu( hwnd );
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
*/
_wpi_setmenutext( sys_menu, SC_CLOSE, "&Close\tCtrl+F4", FALSE );
/* remove task switch option
*/
_wpi_deletemenu( sys_menu, SC_TASKLIST, FALSE );
/* add next window option
*/
_wpi_appendmenu( sys_menu, MF_STRING, 0, SC_NEXTWINDOW, NULL, "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 = _wpi_getmenu( mdiInfo.root );
getMenuBitmaps();
#ifndef __OS2_PM__
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 );
}
#else
if( sys_menu != NULL ) {
_wpi_modifymenu( menu, 0, MF_POPUP | MF_STRING, 0, 0, sys_menu, "SYSMENU", TRUE );
} else {
_wpi_modifymenu( menu, 0, MF_STRING, 0, 0, NULL, "SYSMENU", TRUE );
}
#endif
_wpi_drawmenubar( mdiInfo.root );
}
#ifndef __OS2_PM__
/*
* hitSysMenu - check if a specified point hit the system menu
*/
static bool hitSysMenu( HWND hwnd, WPI_PARAM2 lparam )
{
WPI_RECT r;
WPI_POINT pt;
int left, top, right, bottom;
_wpi_getwindowrect( hwnd, &r );
_wpi_getrectvalues( r, &left, &top, &right, &bottom );
top += _wpi_getsystemmetrics( SM_CYCAPTION ) +
_wpi_getsystemmetrics( SM_CYFRAME );
left += _wpi_getsystemmetrics( SM_CXFRAME );
bottom = top + CLOSE_BITMAP_Y;
right = left + CLOSE_BITMAP_X;
_wpi_setrectvalues( &r, left, top, right, bottom );
WPI_MAKEPOINT(lparam, lparam, pt);
return( _wpi_ptinrect( &r, pt ) );
} /* hitSysMenu */
#endif
#if 0
/*
* HitRestoreButton - check if a specified point hit the restore button
*/
bool HitRestoreButton( HWND hwnd, WPI_PARAM2 lparam )
{
WPI_RECT r;
WPI_POINT pt;
int left, top, right, bottom;
_wpi_getwindowrect( hwnd, &r );
_wpi_getrectvalues( r, &left, &top, &right, &bottom );
top += _wpi_getsystemmetrics( SM_CYCAPTION ) +
_wpi_getsystemmetrics( SM_CYFRAME );
bottom = top + CLOSE_BITMAP_Y;
right -= _wpi_getsystemmetrics( SM_CXFRAME );
left = right - CLOSE_BITMAP_X;
_wpi_setrectvalues( &r, left, top, right, bottom );
WPI_MAKEPOINT(lparam, lparam, pt);
return( _wpi_ptinrect( &r, pt ) );
} /* HitRestoreButton */
/*
* SetRestoreBitmap - set the bitmap on our restore menu item
*/
void SetRestoreBitmap( bool pressed )
{
HMENU menu;
menu = _wpi_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 );
}
_wpi_drawmenubar( mdiInfo.root );
} /* SetRestoreBitmap */
#endif
/*
* setMaximizedMenuConfig - set up main menu in the maximized configuration
*/
static void setMaximizedMenuConfig( HWND hwnd )
{
#ifndef __OS2_PM__
HMENU menu;
HMENU sys_menu;
if( insertedItems ) {
SetSystemMenu( hwnd );
} else {
getMenuBitmaps();
menu = _wpi_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 );
_wpi_drawmenubar( mdiInfo.root );
}
#else
hwnd = hwnd;
#endif
} /* setMaximizedMenuConfig */
/*
* MDIClearMaximizedMenuConfig - done with maximized menu configuration
*/
void MDIClearMaximizedMenuConfig( void )
{
updatedMenu = FALSE;
if( closeBitmap != NULL ) {
_wpi_deletebitmap( closeBitmap );
closeBitmap = NULL;
}
if( restoreBitmap != NULL ) {
_wpi_deletebitmap( restoreBitmap );
restoreBitmap = NULL;
}
if( restoredBitmap != NULL ) {
_wpi_deletebitmap( restoredBitmap );
restoredBitmap = NULL;
}
} /* MDIClearMaximizedMenuConfig */
/*
* deleteMaxinimizedMenuConfig - delete the maximized menu configuration
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -