home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
windows
/
tiler.zip
/
TILER.C
< prev
next >
Wrap
Text File
|
1987-09-05
|
13KB
|
427 lines
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *\
* Tiler.c *
* Windows 2.0 Tiling Utility *
* Written by Michael Geary *
\* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <windows.h>
#include "Tiler.h"
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define MAXINT 32767
/* Menu command definitions */
#define CMD_TILECOLS 1
#define CMD_TILEROWS 2
#define CMD_MARGINS 3
#define CMD_ABOUT 4
/* Code macros */
#define ROUNDUP( n ) ( ( (n) | 7 ) + 1 )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
HANDLE hInstance; /* Our instance handle */
int hWndTiler; /* hWnd of our icon */
typedef struct {
HWND hWnd;
RECT rect;
} WINDOW;
WINDOW Window[4]; /* Window info for each tiled window */
int nWindows; /* How many windows we will tile */
RECT rcTile1; /* Top-left tiling rectangle */
RECT rcTile2; /* Bottom-right tiling rectangle */
BOOL bMargins = TRUE; /* Provide margins? */
char szClass[] = "Tiler!"; /* Our window class name */
char szTitle[] = "Tiler"; /* Our window title */
char szTileCols[] = "&Tile Columns";
char szTileRows[] = "Tile &Rows";
char szMargins[] = "M&argins";
char szAbout[] = "A&bout Tiler...";
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Declare full templates for all our functions. This gives us strong type
* checking on our functions.
*/
BOOL FAR PASCAL AboutBox( HWND, unsigned, WORD, LONG );
void CalcTileRects( void );
void CalcWindowRects( BOOL );
BOOL Initialize( void );
BOOL IsTileable( HWND );
long FAR PASCAL TilerWndProc( HWND, unsigned, WORD, LONG );
void TileWindows( BOOL );
int PASCAL WinMain( HANDLE, HANDLE, LPSTR, int );
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Dialog function for the About box.
* Since this is a simple box with only one button, WM_COMMAND is assumed
* to be a click on that button (the command number is not checked).
*/
BOOL FAR AboutBox( hDlg, wMsg, wParam, lParam )
HWND hDlg; /* Window handle */
unsigned wMsg; /* Message number */
WORD wParam; /* Word parameter for the message */
LONG lParam; /* Long parameter for the message */
{
switch( wMsg ) {
case WM_COMMAND:
EndDialog( hDlg, TRUE );
return TRUE;
}
return FALSE;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Calculate the outer tiling rectangle and center point according to
* the current setting of bMargins. rcTile2.bottom is set up during
* initialization, so we leave it alone here.
*/
void CalcTileRects()
{
POINT ptFrameSize; /* X and Y window frame sizes */
POINT ptFrameBytes; /* ditto, rounded up to byte value */
POINT ptMargin; /* X and Y margin sizes */
int nScreenWidth; /* Screen width in pixels */
ptFrameSize.x = GetSystemMetrics( SM_CXFRAME );
ptFrameBytes.x = ROUNDUP( ptFrameSize.x );
ptMargin.x = ptFrameBytes.x - ptFrameSize.x;
ptFrameSize.y = GetSystemMetrics( SM_CYFRAME );
ptFrameBytes.y = ROUNDUP( ptFrameSize.y );
ptMargin.y = ptFrameBytes.y - ptFrameSize.y;
nScreenWidth = GetSystemMetrics( SM_CXSCREEN );
if( bMargins ) {
rcTile1.left = ptMargin.x;
rcTile1.top = ptMargin.y;
rcTile2.right = nScreenWidth - ptMargin.x;
rcTile2.left =
ROUNDUP( ( ( rcTile2.right - rcTile1.left ) >> 1 ) + ptMargin.x )
- ptFrameSize.x;
rcTile1.right = rcTile2.left - ptMargin.x;
rcTile2.top =
( rcTile2.bottom - rcTile1.top - ptMargin.y ) >> 1;
rcTile1.bottom = rcTile2.top - ptMargin.y;
} else {
rcTile1.left = -ptFrameSize.x;
rcTile1.top = -ptFrameSize.y;
rcTile2.right = nScreenWidth + ptFrameSize.x;
rcTile2.left =
ROUNDUP( ( rcTile2.right - rcTile1.left + ptFrameSize.x ) >> 1 )
- ptFrameSize.x;
rcTile1.right = rcTile2.left + ptFrameSize.x;
rcTile2.top =
( rcTile2.bottom - rcTile1.top + ptFrameSize.y ) >> 1;
rcTile1.bottom = rcTile2.top + ptFrameSize.y;
}
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Calculate window rectangles for the four topmost tileable windows
* and set up the Window array for them. This is a very simpleminded
* tiling algorithm that simply divides the tiling area into equal
* rows and columns.
*/
void CalcWindowRects( bColumns )
BOOL bColumns;
{
HWND hWnd;
int n;
n = 0;
for(
hWnd = GetWindow( hWndTiler, GW_HWNDFIRST );
hWnd;
hWnd = GetWindow( hWnd, GW_HWNDNEXT )
) {
if( ! IsTileable( hWnd ) )
continue;
Window[n].hWnd = hWnd;
/* Assume full screen to start with */
Window[n].rect.left = rcTile1.left;
Window[n].rect.top = rcTile1.top;
Window[n].rect.right = rcTile2.right;
Window[n].rect.bottom = rcTile2.bottom;;
switch( n ) {
case 0:
break;
case 1:
if( bColumns ) {
Window[0].rect.right = rcTile1.right;
Window[1].rect.left = rcTile2.left;
} else {
Window[0].rect.bottom = rcTile1.bottom;
Window[1].rect.top = rcTile2.top;
}
break;
case 2:
if( bColumns ) {
Window[2].rect.left = rcTile2.left;
Window[1].rect.bottom = rcTile1.bottom;
Window[2].rect.top = rcTile2.top;
} else {
Window[2].rect.top = rcTile2.top;
Window[1].rect.right = rcTile1.right;
Window[2].rect.left = rcTile2.left;
}
break;
case 3:
if( bColumns ) {
Window[3].rect.right = rcTile1.right;
Window[0].rect.bottom = rcTile1.bottom;
Window[3].rect.top = rcTile2.top;
} else {
Window[3].rect.bottom = rcTile1.bottom;
Window[0].rect.right = rcTile1.right;
Window[3].rect.left = rcTile2.left;
}
break;
}
if( ++n == 4 )
break;
}
nWindows = n;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Initialize TILER. Assumes a single instance.
* Returns TRUE if initialization succeeded, FALSE if failed.
*/
BOOL Initialize()
{
WNDCLASS Class; /* Class structure for RegisterClass */
HMENU hMenu; /* Menu handle of system menu */
/* Register our window class */
Class.style = 0;
Class.cbClsExtra = 0;
Class.cbWndExtra = 0;
Class.lpfnWndProc = TilerWndProc;
Class.hInstance = hInstance;
Class.hIcon = LoadIcon( hInstance, szClass );
Class.hCursor = LoadCursor( NULL, IDC_ARROW );
Class.hbrBackground = COLOR_WINDOW + 1;
Class.lpszMenuName = NULL;
Class.lpszClassName = szClass;
if( ! RegisterClass( &Class ) )
return FALSE;
/* Create our window but don't iconize it yet */
hWndTiler = CreateWindow(
szClass, szTitle,
WS_OVERLAPPED | WS_SYSMENU,
CW_USEDEFAULT, 0,
CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL
);
if( ! hWndTiler )
return FALSE;
/* Since we took the default size, the bottom of our window is the
* base Y coordinate for tiling */
GetWindowRect( hWndTiler, &rcTile2 );
/* Add our menu items to the System (Control) menu, at the top of
* the menu, so "Tile Columns" becomes the default choice */
hMenu = GetSystemMenu( hWndTiler, FALSE );
ChangeMenu( hMenu, 0, NULL, MAXINT, MF_APPEND | MF_SEPARATOR );
ChangeMenu( hMenu, 0, szTileCols, CMD_TILECOLS, MF_APPEND );
ChangeMenu( hMenu, 0, szTileRows, CMD_TILEROWS, MF_APPEND );
ChangeMenu( hMenu, 0, NULL, MAXINT, MF_APPEND | MF_SEPARATOR );
ChangeMenu( hMenu, 0, szMargins, CMD_MARGINS, MF_APPEND | MF_CHECKED );
ChangeMenu( hMenu, 0, NULL, MAXINT, MF_APPEND | MF_SEPARATOR );
ChangeMenu( hMenu, 0, szAbout, CMD_ABOUT, MF_APPEND );
/* Now display our window as an icon */
ShowWindow( hWndTiler, SW_SHOWMINIMIZED );
return TRUE;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Tells whether a window can be tiled, returns TRUE if so.
* We will tile only top level, resizable windows that are not
* minimized and not maximized.
*/
BOOL IsTileable( hWnd )
HWND hWnd;
{
DWORD dwStyle;
dwStyle = GetWindowLong( hWnd, GWL_STYLE );
return(
! ( dwStyle & ( WS_POPUP | WS_MINIMIZE | WS_MAXIMIZE ) ) &&
( dwStyle & WS_SIZEBOX ) &&
( dwStyle & WS_VISIBLE )
);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Tiler's window function.
*/
long FAR PASCAL TilerWndProc( hWnd, wMsg, wParam, lParam )
HWND hWnd; /* Window handle */
unsigned wMsg; /* Message number */
WORD wParam; /* Word parameter for the message */
LONG lParam; /* Long parameter for the message */
{
FARPROC lpProc; /* ProcInstance for AboutBox */
switch( wMsg ) {
/* Destroy-window message - time to quit the application */
case WM_DESTROY:
PostQuitMessage( 0 );
return 0L;
/* Query open icon message - don't allow icon to be opened! */
case WM_QUERYOPEN:
return 0L;
/* System menu command message - process the command if ours */
case WM_SYSCOMMAND:
switch( wParam ) {
case CMD_MARGINS:
bMargins = ! bMargins;
CheckMenuItem(
GetSystemMenu( hWnd, FALSE ),
wParam,
bMargins ? MF_CHECKED : MF_UNCHECKED
);
return 0L;
case CMD_TILECOLS:
TileWindows( TRUE );
return 0L;
case CMD_TILEROWS:
TileWindows( FALSE );
return 0L;
case CMD_ABOUT:
lpProc = MakeProcInstance( (FARPROC)AboutBox, hInstance );
if( ! lpProc )
return 0L;
DialogBox(
hInstance,
MAKEINTRESOURCE(ABOUTBOX),
hWnd,
lpProc
);
FreeProcInstance( lpProc );
return 0L;
}
break;
}
/* For all other messages, we pass them on to DefWindowProc */
return DefWindowProc( hWnd, wMsg, wParam, lParam );
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* This function actually tiles the windows. First, it calculates the
* tiling rectangles for the windows. Then, it loops through the windows
* and moves them into place.
*/
void TileWindows( bColumns )
BOOL bColumns; /* TRUE = tile columns; FALSE = rows */
{
int n;
HWND hWnd = NULL;
CalcTileRects(); /* Calculate tiling rectangle for current settings */
CalcWindowRects( bColumns ); /* Assign window rectangles */
if( nWindows == 0 ) {
MessageBox(
hWndTiler,
"There are no windows that can be tiled.",
szTitle,
MB_OK | MB_ICONEXCLAMATION
);
return;
}
for( n = 0; n < nWindows; ++n ) { /* Move, size, and reorder windows */
SetWindowPos(
Window[n].hWnd,
hWnd,
Window[n].rect.left,
Window[n].rect.top,
Window[n].rect.right - Window[n].rect.left,
Window[n].rect.bottom - Window[n].rect.top,
SWP_NOACTIVATE
);
}
SetActiveWindow( Window[0].hWnd ); /* Activate the first window */
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Application main program.
*/
int PASCAL WinMain( hInst, hPrevInst, lpszCmdLine, nCmdShow )
HANDLE hInst; /* Our instance handle */
HANDLE hPrevInst; /* Previous instance of this application */
LPSTR lpszCmdLine; /* Pointer to any command line params */
int nCmdShow; /* Parameter to use for first ShowWindow */
{
MSG msg; /* Message structure */
/* Allow only a single instance */
if( hPrevInst ) {
MessageBeep( 0 );
return 0;
}
/* Save our instance handle in static variable */
hInstance = hInst;
/* Initialize application, quit if any errors */
if( ! Initialize() )
return FALSE;
/* Main message processing loop */
while( GetMessage( &msg, NULL, 0, 0 ) ) {
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return msg.wParam;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */