home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
slfinsta.zip
/
dw.c
next >
Wrap
C/C++ Source or Header
|
2000-03-27
|
36KB
|
1,311 lines
/* $Id: dw.c,v 1.2 2000/03/27 19:04:07 bsmith Exp $ */
/*
* Dynamic Windows:
* A GTK like implementation of the PM GUI
*
* (C) 2000 Brian Smith <dbsoft@technologist.com>
* (C) 2000 Achim Hasenmueller <achimha@innotek.de>
*
*/
#define INCL_DOS
#define INCL_WIN
#define INCL_GPI
#include <os2.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <io.h>
#include "dw.h"
#define QWP_USER 0
char ClassName[] = "dynamicwindows";
/* this is the callback handle for the window procedure */
/* make sure you always match the calling convention! */
int (* EXPENTRY filterfunc)(HWND, ULONG, MPARAM, MPARAM) = 0L;
HAB dwhab = 0;
HMQ dwhmq = 0;
#ifdef DEBUG
FILE *f;
void reopen(void)
{
fclose(f);
f = fopen("dw.log", "at");
}
#endif
/* This function calculates how much space the widgets and boxes require
* and does expansion as necessary.
*/
int _resize_box(Box *thisbox, int *depth, int x, int y, int *usedx, int *usedy,
int pass, int *usedpadx, int *usedpady)
{
int z, currentx = 0, currenty = 0;
int vectorx = 0, vectory = 0;
int uymax = 0, uxmax = 0;
int upymax = 0, upxmax = 0;
/* Used for the SIZEEXPAND */
int nux = *usedx, nuy = *usedy;
int nupx = *usedpadx, nupy = *usedpady;
(*usedx) += (thisbox->pad * 2);
(*usedy) += (thisbox->pad * 2);
for(z=0;z<thisbox->count;z++)
{
if(thisbox->items[z].type == TYPEBOX)
{
int initialx, initialy;
Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
initialx = x - (*usedx);
initialy = y - (*usedy);
if(tmp)
{
int newx, newy;
int nux = *usedx, nuy = *usedy;
int upx = *usedpadx + (tmp->pad*2), upy = *usedpady + (tmp->pad*2);
/* On the second pass we know how big the box needs to be and how
* much space we have, so we can calculate a ratio for the new box.
*/
if(pass == 2)
{
int deep = *depth + 1;
_resize_box(tmp, &deep, x, y, &nux, &nuy, 1, &upx, &upy);
tmp->upx = upx - *usedpadx;
tmp->upy = upy - *usedpady;
newx = x - nux;
newy = y - nuy;
tmp->width = thisbox->items[z].width = initialx - newx;
tmp->height = thisbox->items[z].height = initialy - newy;
tmp->parentxratio = thisbox->xratio;
tmp->parentyratio = thisbox->yratio;
tmp->parentpad = tmp->pad;
/* Just in case */
tmp->xratio = thisbox->xratio;
tmp->yratio = thisbox->yratio;
#ifdef DEBUG
if(pass > 1)
{
fprintf(f, "FARK! depth %d\r\nwidth = %d, height = %d, nux = %d, nuy = %d, upx = %d, upy = %d xratio = %f, yratio = %f\r\n\r\n",
*depth, thisbox->items[z].width, thisbox->items[z].height, nux, nuy, tmp->upx, tmp->upy, tmp->xratio, tmp->yratio);
reopen();
}
#endif
if(thisbox->type == BOXVERT)
{
if((thisbox->items[z].width-((thisbox->items[z].pad*2)+(tmp->pad*2)))!=0)
tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(tmp->pad*2))))/((float)(thisbox->items[z].width-((thisbox->items[z].pad*2)+(tmp->pad*2))));
}
else
{
if((thisbox->items[z].width-tmp->upx)!=0)
tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx))/((float)(thisbox->items[z].width-tmp->upx));
}
if(thisbox->type == BOXHORZ)
{
if((thisbox->items[z].height-((thisbox->items[z].pad*2)+(tmp->pad*2)))!=0)
tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(tmp->pad*2))))/((float)(thisbox->items[z].height-((thisbox->items[z].pad*2)+(tmp->pad*2))));
}
else
{
if((thisbox->items[z].height-tmp->upy)!=0)
tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(thisbox->items[z].height-tmp->upy));
}
nux = *usedx; nuy = *usedy;
upx = *usedpadx + (tmp->pad*2); upy = *usedpady + (tmp->pad*2);
}
(*depth)++;
#ifdef DEBUG
if(pass > 1)
{
fprintf(f, "Before Resize Box depth %d\r\nx = %d, y = %d, usedx = %d, usedy = %d, usedpadx = %d, usedpady = %d xratio = %f, yratio = %f\r\n\r\n",
*depth, x, y, *usedx, *usedy, *usedpadx, *usedpady, tmp->xratio, tmp->yratio);
reopen();
}
#endif
_resize_box(tmp, depth, x, y, &nux, &nuy, pass, &upx, &upy);
(*depth)--;
newx = x - nux;
newy = y - nuy;
tmp->minwidth = thisbox->items[z].width = initialx - newx;
tmp->minheight = thisbox->items[z].height = initialy - newy;
#ifdef DEBUG
if(pass > 1)
{
fprintf(f, "After Resize Box depth %d\r\nx = %d, y = %d, usedx = %d, usedy = %d, usedpadx = %d, usedpady = %d width = %d, height = %d\r\n\r\n",
*depth, x, y, *usedx, *usedy, *usedpadx, *usedpady, thisbox->items[z].width, thisbox->items[z].height);
reopen();
}
#endif
}
}
if(pass > 1 && *depth > 0)
{
if(thisbox->type == BOXVERT)
thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-((thisbox->items[z].pad*2)+(thisbox->parentpad*2))))/((float)(thisbox->minwidth-((thisbox->items[z].pad*2)+(thisbox->parentpad*2))));
else
thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-thisbox->upx))/((float)(thisbox->minwidth-thisbox->upx));
if(thisbox->type == BOXHORZ)
thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-((thisbox->items[z].pad*2)+(thisbox->parentpad*2))))/((float)(thisbox->minheight-((thisbox->items[z].pad*2)+(thisbox->parentpad*2))));
else
thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy));
#ifdef DEBUG
fprintf(f, "RATIO- xratio = %f, yratio = %f, width = %d, height = %d, pad = %d, box xratio = %f, box yratio = %f, parent xratio = %f, parent yratio = %f, minwidth = %d, minheight = %d, width = %d, height = %d, upx = %d, upy = %d\r\n\r\n",
thisbox->items[z].xratio, thisbox->items[z].yratio, thisbox->items[z].width, thisbox->items[z].height, thisbox->items[z].pad, thisbox->xratio, thisbox->yratio, thisbox->parentxratio, thisbox->parentyratio, thisbox->minwidth, thisbox->minheight, thisbox->width, thisbox->height, thisbox->upx, thisbox->upy);
reopen();
#endif
}
else
{
thisbox->items[z].xratio = thisbox->xratio;
thisbox->items[z].yratio = thisbox->yratio;
}
if(thisbox->type == BOXVERT)
{
if((thisbox->items[z].width + (thisbox->items[z].pad*2)) > uxmax)
uxmax = (thisbox->items[z].width + (thisbox->items[z].pad*2));
if(thisbox->items[z].size != SIZEEXPAND)
{
if(((thisbox->items[z].pad*2) + thisbox->items[z].width) > upxmax)
upxmax = (thisbox->items[z].pad*2) + thisbox->items[z].width;
}
else
{
if(thisbox->items[z].pad*2 > upxmax)
upxmax = thisbox->items[z].pad*2;
}
}
else
{
if(thisbox->items[z].width == -1)
{
/* figure out how much space this item requires */
/* thisbox->items[z].width = */
}
else
{
(*usedx) += thisbox->items[z].width + (thisbox->items[z].pad*2);
if(thisbox->items[z].size != SIZEEXPAND)
(*usedpadx) += (thisbox->items[z].pad*2) + thisbox->items[z].width;
else
(*usedpadx) += thisbox->items[z].pad*2;
}
}
if(thisbox->type == BOXHORZ)
{
if((thisbox->items[z].height + (thisbox->items[z].pad*2)) > uymax)
uymax = (thisbox->items[z].height + (thisbox->items[z].pad*2));
if(thisbox->items[z].size != SIZEEXPAND)
{
if(((thisbox->items[z].pad*2) + thisbox->items[z].height) > upymax)
upymax = (thisbox->items[z].pad*2) + thisbox->items[z].height;
}
else
{
if(thisbox->items[z].pad*2 > upymax)
upymax = thisbox->items[z].pad*2;
}
}
else
{
if(thisbox->items[z].height == -1)
{
/* figure out how much space this item requires */
/* thisbox->items[z].height = */
}
else
{
(*usedy) += thisbox->items[z].height + (thisbox->items[z].pad*2);
if(thisbox->items[z].size != SIZEEXPAND)
(*usedpady) += (thisbox->items[z].pad*2) + thisbox->items[z].height;
else
(*usedpady) += thisbox->items[z].pad*2;
}
}
}
(*usedx) += uxmax;
(*usedy) += uymax;
(*usedpadx) += upxmax;
(*usedpady) += upymax;
currentx += thisbox->pad;
currenty += thisbox->pad;
#ifdef DEBUG
fprintf(f, "Done Calc depth %d\r\nusedx = %d, usedy = %d, usedpadx = %d, usedpady = %d, currentx = %d, currenty = %d, uxmax = %d, uymax = %d\r\n\r\n",
*depth, *usedx, *usedy, *usedpadx, *usedpady, currentx, currenty, uxmax, uymax);
reopen();
#endif
/* The second pass is for expansion and actual placement. */
if(pass > 1)
{
/* Any SIZEEXPAND items should be set to uxmax/uymax */
for(z=0;z<thisbox->count;z++)
{
if(thisbox->items[z].size == SIZEEXPAND)
{
if(thisbox->type == BOXVERT)
thisbox->items[z].width = uxmax-(thisbox->items[z].pad*2);
if(thisbox->type == BOXHORZ)
thisbox->items[z].height = uymax-(thisbox->items[z].pad*2);
}
/* Run this code segment again to finalize the sized after setting uxmax/uymax values. */
if(thisbox->items[z].type == TYPEBOX)
{
Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
if(tmp)
{
if(*depth > 0)
{
if(thisbox->type == BOXVERT)
{
tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/((float)(tmp->minwidth-((thisbox->items[z].pad*2)+(thisbox->pad*2))));
tmp->width = thisbox->items[z].width;
}
if(thisbox->type == BOXHORZ)
{
tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/((float)(tmp->minheight-((thisbox->items[z].pad*2)+(thisbox->pad*2))));
tmp->height = thisbox->items[z].height;
}
}
(*depth)++;
/*tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx) )/((float)(tmp->minwidth-tmp->upx));
tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(tmp->minheight-tmp->upy));*/
#ifdef DEBUG
fprintf(f, "2- Resize Box depth %d\r\nx = %d, y = %d, usedx = %d, usedy = %d, usedpadx = %d, usedpady = %d xratio = %f, yratio = %f,\r\nupx = %d, upy = %d, width = %d, height = %d, minwidth = %d, minheight = %d, box xratio = %f, box yratio = %f\r\n\r\n",
*depth, x, y, *usedx, *usedy, *usedpadx, *usedpady, tmp->xratio, tmp->yratio, tmp->upx, tmp->upy, thisbox->items[z].width, thisbox->items[z].height, tmp->minwidth, tmp->minheight, thisbox->xratio, thisbox->yratio);
reopen();
#endif
_resize_box(tmp, depth, x, y, &nux, &nuy, 3, &nupx, &nupy);
(*depth)--;
}
}
}
for(z=0;z<(thisbox->count);z++)
{
int height = thisbox->items[z].height;
int width = thisbox->items[z].width;
int pad = thisbox->items[z].pad;
HWND handle = thisbox->items[z].hwnd;
/* When upxmax != pad*2 then ratios are incorrect. */
vectorx = (int)((width*thisbox->items[z].xratio)-width);
vectory = (int)((height*thisbox->items[z].yratio)-height);
if(width > 0 && height > 0)
{
/* This is a hack to fix rounding of the sizing */
if (*depth == 0)
{
vectorx++;
vectory++;
}
/* If this item isn't going to expand... reset the vectors to 0 */
if(thisbox->items[z].size != SIZEEXPAND)
{
vectorx = vectory = 0;
}
WinSetWindowPos(handle, HWND_TOP, currentx + pad, currenty + pad,
width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
#ifdef DEBUG
fprintf(f, "Window Pos depth %d\r\ncurrentx = %d, currenty = %d, pad = %d, width = %d, height = %d, vectorx = %d, vectory = %d, Box type = %s\r\n\r\n",
*depth, currentx, currenty, pad, width, height, vectorx, vectory,thisbox->type == BOXHORZ ? "Horizontal" : "Vertical");
reopen();
#endif
if(thisbox->type == BOXHORZ)
currentx += width + vectorx + (pad * 2);
if(thisbox->type == BOXVERT)
currenty += height + vectory + (pad * 2);
}
}
}
return 0;
}
/* The main window procedure for Dynamic Windows, all the resizing code is done here. */
MRESULT EXPENTRY wndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
int result = 0;
if(filterfunc)
result = filterfunc(hWnd, msg, mp1, mp2);
switch( msg )
{
case WM_PAINT:
{
HPS hps;
RECTL rc;
hps = WinBeginPaint(hWnd, 0L, &rc);
WinEndPaint(hps);
break;
}
case WM_SIZE:
{
Box *thisbox = WinQueryWindowPtr(hWnd, QWP_USER);
int x, y, usedx = 0, usedy = 0, depth = 0;
x=SHORT1FROMMP(mp2); y=SHORT2FROMMP(mp2);
if(x != 0 && y != 0) {
if(thisbox)
{
int usedpadx = 0, usedpady = 0;
_resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady);
thisbox->xratio = ((float)(x-usedpadx))/((float)(usedx-usedpadx));
thisbox->yratio = ((float)(y-usedpady))/((float)(usedy-usedpady));
#ifdef DEBUG
fprintf(f, "WM_SIZE Resize Box Pass 1\r\nx = %d, y = %d, usedx = %d, usedy = %d, usedpadx = %d, usedpady = %d xratio = %f, yratio = %f\r\n\r\n",
x, y, usedx, usedy, usedpadx, usedpady, thisbox->xratio, thisbox->yratio);
reopen();
#endif
usedpadx = usedpady = usedx = usedy = depth = 0;
_resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady);
#ifdef DEBUG
fprintf(f, "WM_SIZE Resize Box Pass 2\r\nx = %d, y = %d, usedx = %d, usedy = %d, usedpadx = %d, usedpady = %d\r\n",
x, y, usedx, usedy, usedpadx, usedpady);
reopen();
#endif
}
}
}
break;
case WM_QUIT:
{
/* Free memory before destroying */
HENUM henum;
HWND child;
void *tmp;
henum = WinBeginEnumWindows(hWnd);
while((child = WinGetNextWindow(henum)) != NULLHANDLE)
{
tmp = WinQueryWindowPtr(child, QWP_USER);
if(tmp)
free(tmp);
}
WinEndEnumWindows(henum);
tmp = WinQueryWindowPtr(hWnd, QWP_USER);
if(tmp)
free(tmp);
}
break;
}
if(filterfunc && result != -1)
return (MRESULT)result;
else
return WinDefWindowProc(hWnd, msg, mp1, mp2);
}
/*
* Initializes the Dynamic Windows engine.
* Parameters:
* newthread: True if this is the only thread.
* False if there is already a message loop running.
*/
int dw_init(int newthread)
{
APIRET rc;
if(newthread)
{
dwhab = WinInitialize(0);
dwhmq = WinCreateMsgQueue(dwhab, 0);
}
rc = WinRegisterClass(dwhab, ClassName, wndproc, CS_SIZEREDRAW, 32);
#ifdef DEBUG
f = fopen("dw.log", "wt");
#endif
return rc;
}
/*
* Runs a message loop for Dynamic Windows.
* Parameters:
* currenthab: The handle to the current anchor block
* or NULL if this DW is handling the message loop.
* func: Function pointer to the message filter function.
*/
void dw_main(HAB currenthab, int (* EXPENTRY func)(HWND, ULONG, MPARAM, MPARAM))
{
QMSG qmsg;
HAB habtouse;
if(!currenthab)
habtouse = dwhab;
else
habtouse = currenthab;
/* Setup the filter function */
filterfunc = func;
while (WinGetMsg(habtouse, &qmsg, 0, 0, 0))
WinDispatchMsg(habtouse, &qmsg);
#ifdef DEBUG
fclose(f);
#endif
if(!currenthab)
{
WinDestroyMsgQueue(dwhmq);
WinTerminate(dwhab);
}
}
/*
* Makes the window visible.
* Parameters:
* handle: The window handle to make visible.
*/
int dw_window_show(HWND handle)
{
WinSetFocus(HWND_DESKTOP, handle);
return WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_SHOW);
}
/*
* Makes the window invisible.
* Parameters:
* handle: The window handle to make visible.
*/
int dw_window_hide(HWND handle)
{
return WinShowWindow(handle, FALSE);
}
/*
* Destroys a window and all of it's children.
* Parameters:
* handle: The window handle to destroy.
*/
int dw_window_destroy(HWND handle)
{
return WinDestroyWindow(handle);
}
/*
* Sets the font used by a specified window (widget) handle.
* Parameters:
* handle: The window (widget) handle.
* fontname: Name and size of the font in the form "size.fontname"
*/
int dw_window_set_font(HWND handle, char *fontname)
{
return WinSetPresParam(handle, PP_FONTNAMESIZE, strlen(fontname)+1, fontname);
}
/*
* Sets the colors used by a specified window (widget) handle.
* Parameters:
* handle: The window (widget) handle.
* fore: Foreground color in RGB format.
* back: Background color in RGB format.
*/
int dw_window_set_color(HWND handle, ULONG fore, ULONG back)
{
return (WinSetPresParam(handle, PP_FOREGROUNDCOLORINDEX, sizeof(ULONG), &fore) |
WinSetPresParam(handle, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back));
}
/*
* Create a new Window Frame.
* Parameters:
* owner: The Owner's window handle or HWND_DESKTOP.
* title: The Window title.
* flStyle: Style flags, see the PM reference.
*/
HWND dw_window_new(HWND hwndOwner, PSZ title, ULONG flStyle)
{
HWND hwndclient = 0, hwndframe;
Box *newbox = malloc(sizeof(Box));
newbox->pad = 0;
newbox->type = BOXVERT;
newbox->count = 0;
hwndframe = WinCreateStdWindow(hwndOwner, 0L, &flStyle, ClassName, title, 0L, NULLHANDLE, 0L, &hwndclient);
WinSetWindowPtr(hwndclient, QWP_USER, newbox);
return hwndframe;
}
/*
* Create a new Box to be packed.
* Parameters:
* type: Either BOXVERT (vertical) or BOXHORZ (horizontal).
* pad: Number of pixels to pad around the box.
*/
HWND dw_box_new(int type, int pad)
{
Box *newbox = malloc(sizeof(Box));
HWND hwndframe;
newbox->pad = pad;
newbox->type = type;
newbox->count = 0;
hwndframe = WinCreateWindow(HWND_OBJECT,
WC_FRAME,
NULL,
WS_VISIBLE,
0, 0, 2000, 1000,
NULLHANDLE,
HWND_TOP,
0L,
NULL,
NULL);
WinSetWindowPtr(hwndframe, QWP_USER, newbox);
return hwndframe;
}
/*
* Create a new Group Box to be packed.
* Parameters:
* type: Either BOXVERT (vertical) or BOXHORZ (horizontal).
* pad: Number of pixels to pad around the box.
*/
HWND dw_groupbox_new(int type, int pad)
{
Box *newbox = malloc(sizeof(Box));
HWND hwndframe;
newbox->pad = pad;
newbox->type = type;
newbox->count = 0;
hwndframe = WinCreateWindow(HWND_OBJECT,
WC_STATIC,
NULL,
WS_VISIBLE | SS_GROUPBOX,
0, 0, 2000, 1000,
NULLHANDLE,
HWND_TOP,
0L,
NULL,
NULL);
WinSetWindowPtr(hwndframe, QWP_USER, newbox);
return hwndframe;
}
/*
* Create a bitmap object to be packed.
* Parameters:
* id: An ID to be used for getting the resource from the
* resource file.
*/
HWND dw_bitmap_new(ULONG id)
{
return WinCreateWindow(HWND_OBJECT,
WC_STATIC,
NULL,
WS_VISIBLE | SS_TEXT,
0, 0, 2000, 1000,
NULLHANDLE,
HWND_TOP,
id,
NULL,
NULL);
}
/*
* Create a container object to be packed.
* Parameters:
* id: An ID to be used for getting the resource from the
* resource file.
*/
HWND dw_container_new(ULONG id)
{
return WinCreateWindow(HWND_OBJECT,
WC_CONTAINER,
NULL,
WS_VISIBLE | CCS_READONLY |
CCS_SINGLESEL | CCS_AUTOPOSITION,
0, 0, 2000, 1000,
NULLHANDLE,
HWND_TOP,
id,
NULL,
NULL);
}
/*
* Create a new static text window (widget) to be packed.
* Parameters:
* text: The text to be display by the static text widget.
* id: An ID to be used with WinWindowFromID() or 0L.
*/
HWND dw_text_new(char *text, ULONG id)
{
return WinCreateWindow(HWND_OBJECT,
WC_STATIC,
text,
WS_VISIBLE | SS_TEXT,
0,0,2000,1000,
NULLHANDLE,
HWND_TOP,
id,
NULL,
NULL);
}
/*
* Create a new Multiline Editbox window (widget) to be packed.
* Parameters:
* id: An ID to be used with WinWindowFromID() or 0L.
*/
HWND dw_mle_new(ULONG id)
{
return WinCreateWindow(HWND_OBJECT,
WC_MLE,
"",
WS_VISIBLE |
MLS_BORDER | MLS_IGNORETAB |
MLS_READONLY | MLS_VSCROLL |
MLS_WORDWRAP | WS_TABSTOP,
0,0,2000,1000,
NULLHANDLE,
HWND_TOP,
id,
NULL,
NULL);
}
/*
* Create a new Entryfield window (widget) to be packed.
* Parameters:
* text: The default text to be in the entryfield widget.
* id: An ID to be used with WinWindowFromID() or 0L.
*/
HWND dw_entryfield_new(char *text, ULONG id)
{
return WinCreateWindow(HWND_OBJECT,
WC_ENTRYFIELD,
text,
WS_VISIBLE | ES_MARGIN |
ES_AUTOSCROLL | WS_TABSTOP,
0,0,2000,1000,
NULLHANDLE,
HWND_TOP,
id,
NULL,
NULL);
}
/*
* Create a new Combobox window (widget) to be packed.
* Parameters:
* text: The default text to be in the combpbox widget.
* id: An ID to be used with WinWindowFromID() or 0L.
*/
HWND dw_combobox_new(char *text, ULONG id)
{
return WinCreateWindow(HWND_OBJECT,
WC_COMBOBOX,
text,
WS_VISIBLE,
0,0,2000,1000,
NULLHANDLE,
HWND_TOP,
id,
NULL,
NULL);
}
/*
* Create a new button window (widget) to be packed.
* Parameters:
* text: The text to be display by the static text widget.
* id: An ID to be used with WinWindowFromID() or 0L.
*/
HWND dw_button_new(char *text, ULONG id)
{
return WinCreateWindow(HWND_OBJECT,
WC_BUTTON,
text,
WS_VISIBLE,
0,0,2000,1000,
NULLHANDLE,
HWND_TOP,
id,
NULL,
NULL);
}
/*
* Create a new spinbutton window (widget) to be packed.
* Parameters:
* text: The text to be display by the static text widget.
* id: An ID to be used with WinWindowFromID() or 0L.
*/
HWND dw_spinbutton_new(char *text, ULONG id)
{
return WinCreateWindow(HWND_OBJECT,
WC_SPINBUTTON,
text,
WS_VISIBLE,
0,0,2000,1000,
NULLHANDLE,
HWND_TOP,
id,
NULL,
NULL);
}
/*
* Create a new slider window (widget) to be packed.
* Parameters:
* id: An ID to be used with WinWindowFromID() or 0L.
*/
HWND dw_slider_new(ULONG id)
{
return WinCreateWindow(HWND_OBJECT,
WC_SLIDER,
NULL,
WS_VISIBLE,
0,0,2000,1000,
NULLHANDLE,
HWND_TOP,
id,
NULL,
NULL);
}
/*
* Create a new checkbox window (widget) to be packed.
* Parameters:
* text: The text to be display by the static text widget.
* id: An ID to be used with WinWindowFromID() or 0L.
*/
HWND dw_checkbox_new(char *text, ULONG id)
{
return WinCreateWindow(HWND_OBJECT,
WC_BUTTON,
text,
WS_VISIBLE | BS_AUTOCHECKBOX,
0,0,2000,1000,
NULLHANDLE,
HWND_TOP,
id,
NULL,
NULL);
}
/*
* Create a new listbox window (widget) to be packed.
* Parameters:
* id: An ID to be used with WinWindowFromID() or 0L.
*/
HWND dw_listbox_new(ULONG id)
{
return WinCreateWindow(HWND_OBJECT,
WC_LISTBOX,
NULL,
WS_VISIBLE,
0,0,2000,1000,
NULLHANDLE,
HWND_TOP,
0L,
NULL,
NULL);
}
/*
* Sets the icon used for a given window.
* Parameters:
* handle: Handle to the window.
* id: An ID to be used to specify the icon.
*/
void dw_window_set_icon(HWND handle, ULONG id)
{
HPOINTER icon;
icon = WinLoadPointer(HWND_DESKTOP,NULLHANDLE,id);
WinSendMsg(handle, WM_SETICON, (MPARAM)icon, 0);
}
/*
* Sets the bitmap used for a given static window.
* Parameters:
* handle: Handle to the window.
* id: An ID to be used to specify the icon.
*/
void dw_window_set_bitmap(HWND handle, ULONG id)
{
HBITMAP hbm;
HPS hps = WinGetPS(handle);
hbm = GpiLoadBitmap(hps, NULLHANDLE, id, 0, 0);
WinSetWindowBits(handle,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f);
WinSendMsg( handle, SM_SETHANDLE, MPFROMP(hbm), NULL );
/*WinSetWindowULong( hwndDlg, QWL_USER, (ULONG) hbm );*/
WinReleasePS(hps);
}
/*
* Sets the text used for a given window.
* Parameters:
* handle: Handle to the window.
* text: The text associsated with a given window.
*/
void dw_window_set_text(HWND handle, char *text)
{
WinSetWindowText(handle, text);
}
/*
* Disables given window (widget).
* Parameters:
* handle: Handle to the window.
*/
void dw_window_disable(HWND handle)
{
WinEnableWindow(handle, FALSE);
}
/*
* Enables given window (widget).
* Parameters:
* handle: Handle to the window.
*/
void dw_window_enable(HWND handle)
{
WinEnableWindow(handle, TRUE);
}
/*
* Pack windows (widgets) into a box from the end (or bottom).
* Parameters:
* box: Window handle of the box to be packed into.
* item: Window handle of the item to be back.
* width: Width in pixels of the item or -1 to be self determined.
* height: Height in pixels of the item or -1 to be self determined.
* size: TRUE if the window (widget) should expand to fill space given.
* pad: Number of pixels of padding around the item.
*/
void dw_box_pack_end(HWND box, HWND item, int width, int height, int size, int pad)
{
Box *thisbox;
thisbox = WinQueryWindowPtr(box, QWP_USER);
if(!thisbox)
{
box = WinWindowFromID(box, FID_CLIENT);
if(box)
thisbox = WinQueryWindowPtr(box, QWP_USER);
}
if(thisbox)
{
if(thisbox->type == BOXHORZ)
dw_box_pack_start_stub(box, item, width, height, size, pad);
else
dw_box_pack_end_stub(box, item, width, height, size, pad);
}
}
void dw_box_pack_end_stub(HWND box, HWND item, int width, int height, int size, int pad)
{
HWND boxowner = NULLHANDLE;
Box *thisbox;
thisbox = WinQueryWindowPtr(box, QWP_USER);
if(!thisbox)
{
box = WinWindowFromID(box, FID_CLIENT);
if(box)
thisbox = WinQueryWindowPtr(box, QWP_USER);
}
if(thisbox)
{
int z;
Item *tmpitem, *thisitem = thisbox->items;
char tmpbuf[100];
tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
for(z=0;z<thisbox->count;z++)
{
tmpitem[z] = thisitem[z];
}
WinQueryClassName(item, 99, tmpbuf);
if(strncmp(tmpbuf, "#1", 2)==0)
tmpitem[thisbox->count].type = TYPEBOX;
else
tmpitem[thisbox->count].type = TYPEITEM;
tmpitem[thisbox->count].hwnd = item;
tmpitem[thisbox->count].width = width;
tmpitem[thisbox->count].height = height;
tmpitem[thisbox->count].pad = pad;
if(size)
tmpitem[thisbox->count].size = SIZEEXPAND;
else
tmpitem[thisbox->count].size = SIZESTATIC;
thisbox->items = tmpitem;
if(thisbox->count)
free(thisitem);
thisbox->count++;
/* Don't set the ownership if it's an entryfield */
WinQueryClassName(item, 99, tmpbuf);
if(strncmp(tmpbuf, "#6", 2)!=0)
{
if((boxowner = WinQueryWindow(box, QW_OWNER)))
WinSetOwner(item, boxowner);
else
WinSetOwner(item, box);
}
WinSetParent(item, box, FALSE);
}
}
/*
* Sets the size of a given window (widget).
* Parameters:
* handle: Window (widget) handle.
* width: New width in pixels.
* height: New height in pixels.
*/
void dw_window_set_usize(HWND handle, ULONG width, ULONG height)
{
WinSetWindowPos(handle, NULLHANDLE, 0, 0, width, height, SWP_SHOW | SWP_SIZE);
}
/*
* Returns the width of the screen.
*/
int dw_screen_width(void)
{
return WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN);
}
/*
* Returns the height of the screen.
*/
int dw_screen_height(void)
{
return WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN);
}
/*
* Sets the position of a given window (widget).
* Parameters:
* handle: Window (widget) handle.
* x: X location from the bottom left.
* y: Y location from the bottom left.
*/
void dw_window_set_pos(HWND handle, ULONG x, ULONG y)
{
WinSetWindowPos(handle, NULLHANDLE, x, y, 0, 0, SWP_MOVE);
}
/*
* Sets the position and size of a given window (widget).
* Parameters:
* handle: Window (widget) handle.
* x: X location from the bottom left.
* y: Y location from the bottom left.
* width: Width of the widget.
* height: Height of the widget.
*/
void dw_window_set_pos_size(HWND handle, ULONG x, ULONG y, ULONG width, ULONG height)
{
WinSetWindowPos(handle, NULLHANDLE, x, y, width, height, SWP_MOVE | SWP_SIZE | SWP_SHOW);
}
/*
* Sets the style of a given window (widget).
* Parameters:
* handle: Window (widget) handle.
* width: New width in pixels.
* height: New height in pixels.
*/
void dw_window_set_style(HWND handle, ULONG style, ULONG mask)
{
WinSetWindowBits(handle, QWL_STYLE, style, mask);
}
/*
* Pack windows (widgets) into a box from the start (or top).
* Parameters:
* box: Window handle of the box to be packed into.
* item: Window handle of the item to be back.
* width: Width in pixels of the item or -1 to be self determined.
* height: Height in pixels of the item or -1 to be self determined.
* size: TRUE if the window (widget) should expand to fill space given.
* pad: Number of pixels of padding around the item.
*/
void dw_box_pack_start(HWND box, HWND item, int width, int height, int size, int pad)
{
Box *thisbox;
thisbox = WinQueryWindowPtr(box, QWP_USER);
if(!thisbox)
{
box = WinWindowFromID(box, FID_CLIENT);
if(box)
thisbox = WinQueryWindowPtr(box, QWP_USER);
}
if(thisbox)
{
if(thisbox->type == BOXHORZ)
dw_box_pack_end_stub(box, item, width, height, size, pad);
else
dw_box_pack_start_stub(box, item, width, height, size, pad);
}
}
void dw_box_pack_start_stub(HWND box, HWND item, int width, int height, int size, int pad)
{
HWND boxowner = NULLHANDLE;
Box *thisbox;
thisbox = WinQueryWindowPtr(box, QWP_USER);
if(!thisbox)
{
box = WinWindowFromID(box, FID_CLIENT);
if(box)
thisbox = WinQueryWindowPtr(box, QWP_USER);
}
if(thisbox)
{
int z;
Item *tmpitem, *thisitem = thisbox->items;
char tmpbuf[100];
tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
for(z=0;z<thisbox->count;z++)
{
tmpitem[z+1] = thisitem[z];
}
WinQueryClassName(item, 99, tmpbuf);
if(strncmp(tmpbuf, "#1", 2)==0)
tmpitem[0].type = TYPEBOX;
else
tmpitem[0].type = TYPEITEM;
tmpitem[0].hwnd = item;
tmpitem[0].width = width;
tmpitem[0].height = height;
tmpitem[0].pad = pad;
if(size)
tmpitem[0].size = SIZEEXPAND;
else
tmpitem[0].size = SIZESTATIC;
thisbox->items = tmpitem;
if(thisbox->count)
free(thisitem);
thisbox->count++;
WinQueryClassName(item, 99, tmpbuf);
/* Don't set the ownership if it's an entryfield */
if(strncmp(tmpbuf, "#6", 2)!=0)
{
if((boxowner = WinQueryWindow(box, QW_OWNER)))
WinSetOwner(item, boxowner);
else
WinSetOwner(item, box);
}
WinSetParent(item, box, FALSE);
}
}
#ifdef TEST
HWND mainwindow,
listbox,
okbutton,
cancelbutton,
lbbox,
stext,
buttonbox,
testwindow,
testbox,
testok,
testcancel,
testbox2,
testok2,
testcancel2;
/* Do any handling you need in the filter function */
LONG testfilter(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
switch(msg)
{
case WM_COMMAND:
switch (COMMANDMSG(&msg)->cmd)
{
case 1001L:
case 1002L:
dw_window_destroy(mainwindow);;
break;
case 1003L:
case 1004L:
dw_window_destroy(testwindow);;
break;
}
break;
}
/* Return -1 to allow the default handlers to return. */
return -1;
}
/*
* Let's demonstrate the functionality of this library. :)
*/
int main(void)
{
ULONG flStyle = FCF_SYSMENU | FCF_TITLEBAR |
FCF_SHELLPOSITION | FCF_TASKLIST | FCF_DLGBORDER;
dw_init(TRUE);
/* Try a little server dialog. :) */
mainwindow = dw_window_new(HWND_DESKTOP, "Server", flStyle | FCF_SIZEBORDER | FCF_MINMAX);
lbbox = dw_box_new(BOXVERT, 10);
dw_box_pack_start(mainwindow, lbbox, 0, 0, TRUE, 0);
stext = dw_text_new("Choose a server:", 0);
dw_window_set_style(stext, DT_VCENTER, DT_VCENTER);
dw_box_pack_start(lbbox, stext, 130, 10, FALSE, 10);
listbox = dw_listbox_new(100L);
dw_box_pack_start(lbbox, listbox, 130, 200, TRUE, 10);
buttonbox = dw_box_new(BOXHORZ, 0);
dw_box_pack_start(lbbox, buttonbox, 0, 0, TRUE, 0);
okbutton = dw_button_new("Ok", 1001L);
dw_box_pack_start(buttonbox, okbutton, 50, 30, TRUE, 5);
cancelbutton = dw_button_new("Cancel", 1002L);
dw_box_pack_start(buttonbox, cancelbutton, 50, 30, TRUE, 5);
/* Set some nice fonts and colors */
dw_window_set_color(lbbox, CLR_PALEGRAY, CLR_PALEGRAY);
dw_window_set_color(buttonbox, CLR_PALEGRAY, CLR_PALEGRAY);
dw_window_set_font(stext, "9.WarpSans");
dw_window_set_color(stext, CLR_BLACK, CLR_PALEGRAY);
dw_window_set_font(listbox, "9.WarpSans");
dw_window_set_font(okbutton, "9.WarpSans");
dw_window_set_font(cancelbutton, "9.WarpSans");
dw_window_show(mainwindow);
dw_window_set_usize(mainwindow, 170, 340);
/* Another small example */
flStyle |= FCF_MINMAX | FCF_SIZEBORDER;
testwindow = dw_window_new(HWND_DESKTOP, "Wow a test dialog! :) yay!", flStyle);
testbox = dw_box_new(BOXVERT, 10);
dw_box_pack_start(testwindow, testbox, 0, 0, TRUE, 0);
testok = dw_button_new("Ok", 1003L);
dw_box_pack_start(testbox, testok, 60, 40, TRUE, 10);
testcancel = dw_button_new("Cancel", 1004L);
dw_box_pack_start(testbox, testcancel, 60, 40, TRUE, 10);
testbox2 = dw_box_new(BOXHORZ, 0);
dw_box_pack_start(testbox, testbox2, 0, 0, TRUE, 0);
testok2 = dw_button_new("Ok", 1003L);
dw_box_pack_start(testbox2, testok2, 60, 40, TRUE, 10);
testcancel2 = dw_button_new("Cancel", 1004L);
dw_box_pack_start(testbox2, testcancel2, 60, 40, TRUE, 10);
/* Set some nice fonts and colors */
dw_window_set_color(testbox, CLR_PALEGRAY, CLR_PALEGRAY);
dw_window_set_color(testbox2, CLR_PALEGRAY, CLR_PALEGRAY);
dw_window_set_font(testok, "9.WarpSans");
dw_window_set_font(testcancel, "9.WarpSans");
dw_window_set_font(testok2, "9.WarpSans");
dw_window_set_font(testcancel2, "9.WarpSans");
dw_window_show(testwindow);
dw_main(0L, (void *)testfilter);
return 0;
}
#endif