📄 mdisim.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 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 + -