guixmdi.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 426 行
C
426 行
/****************************************************************************
*
* 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 processing.
*
****************************************************************************/
#include "guiwind.h"
#include <stdlib.h>
#include <string.h>
#include "wmdisim.h"
#include "guixutil.h"
#include "guixhook.h"
#include "guixmdi.h"
#include "guimdi.h"
#include "guiscrol.h"
#include "guixwind.h"
#include "guistyle.h"
#define MAX_LENGTH 256
typedef struct {
int height;
int width;
int num;
int mod;
gui_rect rect;
gui_coord bump;
} cascade_info;
static mdi_info MDIInfo;
static char Buffer[MAX_LENGTH];
static bool DoneMDIInit = FALSE;
static bool DoingMaxRestore = FALSE;
static bool ArrangeIcons = FALSE;
extern WPI_INST GUIMainHInst;
static void StartMaxRestore( HWND hwnd )
{
hwnd = hwnd;
DoingMaxRestore = TRUE;
}
static void SetStyle( HWND hwnd, int max )
{
#ifndef __OS2_PM__
DWORD style;
gui_window *wnd;
wnd = GUIGetWindow( hwnd );
style = _wpi_getwindowlong( hwnd, GWL_STYLE );
if( max ) {
style |= WS_VSCROLL+WS_HSCROLL;
style &= ~( COMMON_STYLES | WS_THICKFRAME | WS_CAPTION );
} else {
if( wnd->scroll & GUI_HSCROLL ) {
style |= WS_HSCROLL;
}
if( wnd->scroll & GUI_VSCROLL ) {
style |= WS_VSCROLL;
}
if( wnd->style & GUI_RESIZEABLE ) {
style |= WS_THICKFRAME;
}
if( !(wnd->style & GUI_NOFRAME) ) {
style |= WS_CAPTION;
}
style |= COMMON_STYLES;
}
_wpi_setwindowlong( hwnd, GWL_STYLE, style );
#else
hwnd = hwnd;
max = max;
#endif
}
static void EndMaxRestore( HWND hwnd )
{
gui_window *wnd;
WPI_RECT rect;
gui_coord size;
wnd = GUIGetWindow( hwnd );
if( GUI_HSCROLL_ON( wnd ) ) {
GUISetRangePos( wnd, SB_HORZ );
}
if( GUI_VSCROLL_ON( wnd ) ) {
GUISetRangePos( wnd, SB_VERT );
}
DoingMaxRestore = FALSE;
_wpi_getwindowrect( hwnd, &rect );
size.x = _wpi_getwidthrect( rect );
size.y = _wpi_getheightrect( rect );
GUIDoResize( wnd, hwnd, &size );
}
static void SetWindowTitle( HWND hwnd )
{
char buffer[MAX_LENGTH];
_wpi_getwindowtext( hwnd, &buffer, MAX_LENGTH - 1 );
MDISetMainWindowTitle( &buffer );
}
void XChangeTitle( gui_window *wnd )
{
if( wnd->root != NULLHANDLE ) {
_wpi_getwindowtext( wnd->root, &Buffer, MAX_LENGTH - 1 );
MDIInitMenu();
} else {
SetWindowTitle( wnd->hwnd );
}
}
static bool IsMaximized( gui_window *wnd )
{
HWND hwnd;
if( MDIIsMaximized() ) {
hwnd = GUIGetParentFrameHWND( wnd );
if( GUIIsMDIChildWindow( wnd ) ) {
return( MDIIsWndMaximized( hwnd ) );
} else {
return( _wpi_iszoomed( hwnd ) );
}
} else {
return( FALSE );
}
}
static bool UpdatedMenu( void )
{
return( MDIUpdatedMenu() );
}
static void MDIMaximize( bool max, gui_window *wnd )
{
#ifndef __OS2_PM__
if( max ) {
GUISendMessage( wnd->hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0L );
} else {
GUISendMessage( wnd->hwnd, WM_SYSCOMMAND, SC_RESTORE, 0L );
}
#else
max = max;
wnd = wnd;
#endif
}
static void SetMDIRestoredSize( HWND hwnd, WPI_RECT *rect )
{
MDISetOrigSize( hwnd, rect );
}
static bool IsMDIChildWindow( gui_window *wnd )
{
return( GUIGetParentWindow( wnd ) == GUIGetRootWindow() );
}
bool XInitMDI( gui_window *wnd )
{
if( wnd->root != NULLHANDLE ) {
/* root window */
memset( &MDIInfo, 0, sizeof( mdi_info ) );
MDIInfo.root = wnd->root;
MDIInfo.container = wnd->hwnd;
MDIInfo.data_off = GUI_MDI_WORD * EXTRA_SIZE;
_wpi_getwindowtext( wnd->root, &Buffer, MAX_LENGTH - 1 );
MDIInfo.main_name = &Buffer;
MDIInfo.start_max_restore = &StartMaxRestore;
MDIInfo.end_max_restore = &EndMaxRestore;
MDIInfo.set_window_title = SetWindowTitle;
MDIInfo.set_style = &SetStyle;
MDIInfo.hinstance = GUIMainHInst;
MDIInit( &MDIInfo );
DoneMDIInit = TRUE;
return( FALSE );
} else {
/* child window */
return( TRUE );
}
}
void GUIMDIBringToFront( gui_window *wnd )
{
if( wnd != NULL ) {
if( MDIIsMaximized() && GUIIsMinimized( wnd ) ) {
GUIMDIMaximize( TRUE, wnd );
}
if( GUIIsMinimized( wnd ) ) {
GUIRestoreWindow( wnd );
}
GUIBringToFront( wnd );
}
}
static bool MDIProcessMessage( gui_window *wnd, HWND hwnd, WPI_MSG msg, WPI_PARAM1 wparam,
WPI_PARAM2 lparam, WPI_MRESULT *ret )
{
WORD param;
#ifndef __OS2_PM__
WINDOWPOS *pos;
#endif
if( wnd->root == hwnd ) {
/* message for root window */
switch( msg ) {
case WM_DESTROY :
MDIClearMaximizedMenuConfig();
break;
#ifndef __OS2_PM__
case WM_NCLBUTTONDBLCLK:
if( MDIHitClose( hwnd, msg, wparam, lparam ) ) {
*ret = 0;
return( TRUE );
}
break;
#endif
case WM_COMMAND :
if( DoneMDIInit && MDIIsSysCommand( hwnd, msg, wparam, lparam ) ) {
*ret = 0;
return( TRUE );
}
param = _wpi_getid( wparam );
if( _wpi_ismenucommand( wparam, lparam ) &&
( param >= GUI_MDI_MENU_FIRST ) &&
( param <= GUI_MDI_MENU_LAST ) ) {
switch( param ) {
case GUI_MDI_CASCADE :
MDICascade();
break;
case GUI_MDI_TILE_HORZ :
MDITile( TRUE );
break;
case GUI_MDI_TILE_VERT :
MDITile( FALSE );
break;
case GUI_MDI_ARRANGE_ICONS :
ArrangeIcons = TRUE;
MDICascade();
ArrangeIcons = FALSE;
break;
case GUI_MDI_MORE_WINDOWS :
GUIMDIMoreWindows();
break;
default :
if( ( param >= GUI_MDI_FIRST_WINDOW ) &&
( param <= GUI_MDI_FIRST_WINDOW + MAX_NUM_MDI_WINDOWS ) ) {
/* window selected */
GUIMDIBringToFront( GUIMDIGetWindow( param ) );
}
}
return( TRUE );
}
}
} else if( wnd->root == NULLHANDLE ) {
/* child window */
switch( msg ) {
#ifndef __OS2_PM__
case WM_WINDOWPOSCHANGING :
if( ArrangeIcons ) {
/* arrange icons is really a cascade but don't allow
no-iconic windows to move */
if( !_wpi_isiconic( hwnd ) ) {
pos = (WINDOWPOS *)lparam;
pos->flags |= SWP_NOMOVE | SWP_NOSIZE;
*ret = 0;
return( TRUE );
}
}
break;
case WM_SYSCHAR:
case WM_SYSKEYDOWN :
case WM_SYSKEYUP :
*ret = GUISendMessage( GUIGetTopParentHWND( hwnd ), msg, wparam, lparam );
return( TRUE );
break;
#endif
case WM_MOVE :
case WM_SIZE :
if( DoingMaxRestore ) {
*ret = 0;
return( TRUE );
}
break;
#ifndef __OS2_PM__
case WM_MOUSEACTIVATE :
SetFocus( hwnd );
*ret = MA_ACTIVATE;
return( TRUE );
#else
case WM_ACTIVATE :
if( wparam ) {
SetFocus( hwnd );
return( TRUE );
}
#endif
case WM_GETMINMAXINFO :
/* don't want app to fool with this */
*ret = _wpi_defwindowproc( hwnd, msg, wparam, lparam );
return( TRUE );
}
if( DoneMDIInit ) {
return( MDIChildHandleMessage( hwnd, msg, wparam, lparam, ret ) );
}
} else if( wnd->hwnd == hwnd ) {
/* container window */
switch( msg ) {
case WM_SIZE :
MDIContainerResized();
break;
}
}
return( FALSE );
}
void GUIXMDIInit( void )
{
GUISetMDIProcessMessage( &MDIProcessMessage );
GUISetMDIMaximized( &IsMaximized );
GUISetMDIUpdatedMenu( &UpdatedMenu );
GUISetMDINewWindow( &MDINewWindow );
GUISetMDIMaximize( &MDIMaximize );
GUISetSetMDIRestoredSize( &SetMDIRestoredSize );
GUISetIsMDIChildWindow( &IsMDIChildWindow );
}
static void GUIInternalCascadeWindows( gui_window *wnd, void *param )
{
cascade_info *info;
gui_rect rect;
if( GUIIsMinimized( wnd ) ) {
return;
}
info = (cascade_info *)param;
rect.width = info->width;
rect.height = info->height;
rect.x = info->num * info->bump.x;
rect.y = info->num * info->bump.y;
GUISetRedraw( wnd, FALSE );
GUIResizeWindow( wnd, &rect );
GUISetRedraw( wnd, TRUE );
GUIBringToFront( wnd );
info->num++;
info->num = info->num % info->mod;
}
static void Cascade( gui_window *root, int num_windows, gui_rect *rect,
gui_coord *min_size )
{
cascade_info info;
int mod;
gui_text_metrics metrics;
gui_system_metrics sys_metrics;
GUIGetSystemMetrics( &sys_metrics );
GUIGetTextMetrics( root, &metrics );
info.bump.y = sys_metrics.caption_size + sys_metrics.resize_border.y;
info.height = rect->height - info.bump.y * ( num_windows - 1 );
info.mod = num_windows;
if( info.height < min_size->y ) {
info.height = min_size->y;
info.mod = ( rect->height - min_size->y ) / info.bump.y + 1;
}
info.bump.x = info.bump.y;
info.width = rect->width - info.bump.x * ( info.mod - 1 );
if( info.width < min_size->x ) {
info.width = min_size->x;
mod = ( rect->width - min_size->x ) / info.bump.x + 1;
if( mod < info.mod ) {
info.mod = mod;
}
}
info.rect = *rect;
info.num = 0;
GUIEnumChildWindows( root, &GUIInternalCascadeWindows, &info );
}
bool GUICascadeWindows( void )
{
gui_rect rect;
int num_windows;
gui_window *root;
gui_coord min_size;
int total_icons;
root = GUIGetRootWindow();
total_icons = GUIGetNumIconicWindows();
num_windows = GUIGetNumChildWindows() - total_icons;
if( ( root == NULL ) || ( num_windows <= 1 ) ) {
return( FALSE );
}
GUIGetClientRect( root, &rect );
GUIGetMinSize( &min_size );
Cascade( root, num_windows, &rect, &min_size );
GUIWndDirty( root );
return( TRUE );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?