X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/8c3cd914db62fcba242eba74eba223c1c927aaa5..ff89646a8828ce862d53b96a19ee6469dabce71a:/winctrls.c diff --git a/winctrls.c b/winctrls.c index 3a595034..0e85dbe4 100644 --- a/winctrls.c +++ b/winctrls.c @@ -4,6 +4,7 @@ */ #include +#include #include "winstuff.h" @@ -18,6 +19,7 @@ #define EDITHEIGHT 12 #define COMBOHEIGHT 12 #define PUSHBTNHEIGHT 14 +#define PROGBARHEIGHT 14 void ctlposinit(struct ctlpos *cp, HWND hwnd, int leftborder, int rightborder, int topborder) { @@ -70,17 +72,16 @@ void bartitle(struct ctlpos *cp, char *name, int id) { /* * Begin a grouping box, with or without a group title. */ -void beginbox(struct ctlpos *cp, char *name, int idbox, int idtext) { - if (name) - cp->ypos += STATICHEIGHT/2; +void beginbox(struct ctlpos *cp, char *name, int idbox) { cp->boxystart = cp->ypos; + if (!name) + cp->boxystart -= STATICHEIGHT/2; if (name) - cp->ypos += STATICHEIGHT - (STATICHEIGHT/2); + cp->ypos += STATICHEIGHT; cp->ypos += GAPYBOX; cp->width -= 2*GAPXBOX; cp->xoff += GAPXBOX; cp->boxid = idbox; - cp->boxtextid = idtext; cp->boxtext = name; } @@ -94,25 +95,8 @@ void endbox(struct ctlpos *cp) { cp->ypos += GAPYBOX - GAPBETWEEN; r.left = GAPBETWEEN; r.right = cp->width; r.top = cp->boxystart; r.bottom = cp->ypos - cp->boxystart; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE | SS_ETCHEDFRAME, 0, - "", cp->boxid); - if (cp->boxtext) { - SIZE s; - HDC hdc; - HFONT oldfont, dlgfont; - hdc = GetDC(cp->hwnd); - dlgfont = (HFONT)cp->font; - oldfont = SelectObject(hdc, dlgfont); - GetTextExtentPoint32(hdc, cp->boxtext, strlen(cp->boxtext), &s); - SelectObject(hdc, oldfont); - DeleteDC(hdc); - r.left = GAPXBOX + GAPBETWEEN; - r.right = (s.cx * 4 + cp->dlu4inpix-1) / cp->dlu4inpix; - - r.top = cp->boxystart - STATICHEIGHT/2; r.bottom = STATICHEIGHT; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, - cp->boxtext, cp->boxtextid); - } + doctl(cp, r, "BUTTON", BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 0, + cp->boxtext ? cp->boxtext : "", cp->boxid); cp->ypos += GAPYBOX; } @@ -161,6 +145,13 @@ void multiedit(struct ctlpos *cp, ...) { * (you might want this not to equal the number of buttons if you * needed to line up some 2s and some 3s to look good in the same * panel). + * + * There's a bit of a hack in here to ensure that if nacross + * exceeds the actual number of buttons, the rightmost button + * really does get all the space right to the edge of the line, so + * you can do things like + * + * (*) Button1 (*) Button2 (*) ButtonWithReallyLongTitle */ void radioline(struct ctlpos *cp, char *text, int id, int nacross, ...) { @@ -168,6 +159,7 @@ void radioline(struct ctlpos *cp, va_list ap; int group; int i; + char *btext; r.left = GAPBETWEEN; r.top = cp->ypos; r.right = cp->width; r.bottom = STATICHEIGHT; @@ -176,15 +168,23 @@ void radioline(struct ctlpos *cp, va_start(ap, nacross); group = WS_GROUP; i = 0; + btext = va_arg(ap, char *); while (1) { - char *btext; + char *nextbtext; int bid; - btext = va_arg(ap, char *); if (!btext) break; + if (i==nacross) { + cp->ypos += r.bottom + GAPBETWEEN; + i=0; + } bid = va_arg(ap, int); + nextbtext = va_arg(ap, char *); r.left = GAPBETWEEN + i * (cp->width+GAPBETWEEN)/nacross; - r.right = (i+1) * (cp->width+GAPBETWEEN)/nacross - r.left; + if (nextbtext) + r.right = (i+1) * (cp->width+GAPBETWEEN)/nacross - r.left; + else + r.right = cp->width - r.left; r.top = cp->ypos; r.bottom = RADIOHEIGHT; doctl(cp, r, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP | group, @@ -192,6 +192,7 @@ void radioline(struct ctlpos *cp, btext, bid); group = 0; i++; + btext = nextbtext; } va_end(ap); cp->ypos += r.bottom + GAPBETWEEN; @@ -247,6 +248,18 @@ void checkbox(struct ctlpos *cp, char *text, int id) { } /* + * A single standalone static text control. + */ +void statictext(struct ctlpos *cp, char *text, int id) { + RECT r; + + r.left = GAPBETWEEN; r.top = cp->ypos; + r.right = cp->width; r.bottom = STATICHEIGHT; + cp->ypos += r.bottom + GAPBETWEEN; + doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, id); +} + +/* * A button on the right hand side, with a static to its left. */ void staticbtn(struct ctlpos *cp, char *stext, int sid, @@ -277,8 +290,9 @@ void staticbtn(struct ctlpos *cp, char *stext, int sid, /* * An edit control on the right hand side, with a static to its left. */ -void staticedit(struct ctlpos *cp, char *stext, - int sid, int eid, int percentedit) { +static void staticedit_internal(struct ctlpos *cp, char *stext, + int sid, int eid, int percentedit, + int style) { const int height = (EDITHEIGHT > STATICHEIGHT ? EDITHEIGHT : STATICHEIGHT); RECT r; @@ -295,13 +309,44 @@ void staticedit(struct ctlpos *cp, char *stext, r.left = rpos; r.top = cp->ypos + (height-EDITHEIGHT)/2; r.right = rwid; r.bottom = EDITHEIGHT; doctl(cp, r, "EDIT", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL, + WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL | style, WS_EX_CLIENTEDGE, "", eid); cp->ypos += height + GAPBETWEEN; } +void staticedit(struct ctlpos *cp, char *stext, + int sid, int eid, int percentedit) { + staticedit_internal(cp, stext, sid, eid, percentedit, 0); +} + +void staticpassedit(struct ctlpos *cp, char *stext, + int sid, int eid, int percentedit) { + staticedit_internal(cp, stext, sid, eid, percentedit, ES_PASSWORD); +} + +/* + * A big multiline edit control with a static labelling it. + */ +void bigeditctrl(struct ctlpos *cp, char *stext, + int sid, int eid, int lines) { + RECT r; + + r.left = GAPBETWEEN; r.top = cp->ypos; + r.right = cp->width; r.bottom = STATICHEIGHT; + cp->ypos += r.bottom + GAPWITHIN; + doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid); + + r.left = GAPBETWEEN; r.top = cp->ypos; + r.right = cp->width; r.bottom = EDITHEIGHT + (lines-1) * STATICHEIGHT; + cp->ypos += r.bottom + GAPBETWEEN; + doctl(cp, r, "EDIT", + WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | ES_MULTILINE, + WS_EX_CLIENTEDGE, + "", eid); +} + /* * A tab-control substitute when a real tab control is unavailable. */ @@ -600,7 +645,7 @@ void colouredit(struct ctlpos *cp, char *stext, int sid, int listid, r.right = lwid; r.bottom = LISTHEIGHT; doctl(cp, r, "LISTBOX", WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_HASSTRINGS | - LBS_USETABSTOPS, + LBS_USETABSTOPS | LBS_NOTIFY, WS_EX_CLIENTEDGE, "", listid); @@ -633,3 +678,22 @@ void colouredit(struct ctlpos *cp, char *stext, int sid, int listid, cp->ypos += LISTHEIGHT + GAPBETWEEN; } +/* + * A progress bar (from Common Controls). We like our progress bars + * to be smooth and unbroken, without those ugly divisions; some + * older compilers may not support that, but that's life. + */ +void progressbar(struct ctlpos *cp, int id) { + RECT r; + + r.left = GAPBETWEEN; r.top = cp->ypos; + r.right = cp->width; r.bottom = PROGBARHEIGHT; + cp->ypos += r.bottom + GAPBETWEEN; + + doctl(cp, r, PROGRESS_CLASS, + WS_CHILD | WS_VISIBLE +#ifdef PBS_SMOOTH + | PBS_SMOOTH +#endif + , WS_EX_CLIENTEDGE, "", id); +}