diff options
Diffstat (limited to 'app/wlib/mswlib/mswchoic.c')
-rw-r--r-- | app/wlib/mswlib/mswchoic.c | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/app/wlib/mswlib/mswchoic.c b/app/wlib/mswlib/mswchoic.c new file mode 100644 index 0000000..2ac391a --- /dev/null +++ b/app/wlib/mswlib/mswchoic.c @@ -0,0 +1,423 @@ +#include <windows.h> +#include <string.h> +#include <malloc.h> +#include <stdlib.h> +#include <commdlg.h> +#include <math.h> +#include "i18n.h" +#include "mswint.h" + +/* + ***************************************************************************** + * + * Choice Boxes + * + ***************************************************************************** + */ + +int CHOICE_HEIGHT=(17); +int CHOICE_MIN_WIDTH=25; + +static XWNDPROC oldChoiceItemProc = NULL; +static XWNDPROC newChoiceItemProc; + +typedef struct { + WOBJ_COMMON + wChoice_p owner; + } wChoiceItem_t, * wChoiceItem_p; + +struct wChoice_t { + WOBJ_COMMON + const char * * labels; + wChoiceItem_p *buttList; + long *valueP; + long oldVal; + wChoiceCallBack_p action; + HWND hBorder; + }; + +static FARPROC oldChoiceProc; + +void wRadioSetValue( + wChoice_p bc, + long val ) +{ + const char ** labels; + long cnt; + wChoiceItem_p * butts; + + butts = (wChoiceItem_p*)bc->buttList; + for (labels = bc->labels, cnt=0; *labels; labels++, cnt++, butts++ ) + SendMessage( (*butts)->hWnd, BM_SETCHECK, + (val==cnt)?1:0, 0L ); + bc->oldVal = val; + if (bc->valueP) + *bc->valueP = val; +} + +long wRadioGetValue( + wChoice_p bc ) +{ + return bc->oldVal; +} + + + +void wToggleSetValue( + wChoice_p bc, + long val ) +{ + const char ** labels; + long cnt; + wChoiceItem_p * butts; + + butts = (wChoiceItem_p*)bc->buttList; + for (labels = bc->labels, cnt=0; *labels; labels++, cnt++, butts++ ) + SendMessage( (*butts)->hWnd, BM_SETCHECK, + (val & (1L<<cnt)) != 0, 0L ); + bc->oldVal = val; + if (bc->valueP) + *bc->valueP = val; +} + + +long wToggleGetValue( + wChoice_p bc ) +{ + return bc->oldVal; +} + + +static void choiceSetBusy( + wControl_p b, + BOOL_T busy) +{ + wChoiceItem_p * butts; + wChoice_p bc = (wChoice_p)b; + + for (butts = (wChoiceItem_p*)bc->buttList; *butts; butts++ ) + EnableWindow( (*butts)->hWnd, !(BOOL)busy ); +} + +static void choiceShow( + wControl_p b, + BOOL_T show) +{ + wChoice_p bc = (wChoice_p)b; + wChoiceItem_p * butts; + + if ((bc->option & BC_NOBORDER)==0) + ShowWindow( bc->hBorder, show?SW_SHOW:SW_HIDE ); + + for (butts = (wChoiceItem_p*)bc->buttList; *butts; butts++ ) + ShowWindow( (*butts)->hWnd, show?SW_SHOW:SW_HIDE ); +} + +static void choiceSetPos( + wControl_p b, + wPos_t x, + wPos_t y ) +{ + wChoice_p bc = (wChoice_p)b; + wChoiceItem_p * butts; + wPos_t dx, dy; + + dx = x - bc->x; + dy = y - bc->y; + if ((bc->option & BC_NOBORDER)==0) + SetWindowPos( bc->hBorder, HWND_TOP, x, y, CW_USEDEFAULT, CW_USEDEFAULT, + SWP_NOSIZE|SWP_NOZORDER ); + + for (butts = (wChoiceItem_p*)bc->buttList; *butts; butts++ ) { + SetWindowPos( (*butts)->hWnd, HWND_TOP, + (*butts)->x+=dx, (*butts)->y+=dy, + CW_USEDEFAULT, CW_USEDEFAULT, + SWP_NOSIZE|SWP_NOZORDER ); + } + bc->x = x; + bc->y = y; +} + +long FAR PASCAL _export pushChoiceItem( + HWND hWnd, + UINT message, + UINT wParam, + LONG lParam ) +{ + /* Catch <Return> and cause focus to leave control */ +#ifdef WIN32 + long inx = GetWindowLong( hWnd, GWL_ID ); +#else + short inx = GetWindowWord( hWnd, GWW_ID ); +#endif + + wControl_p b = mswMapIndex( inx ); + + switch (message) { + case WM_CHAR: + if ( b != NULL) { + switch( wParam ) { + case 0x0D: + case 0x1B: + case 0x09: + SetFocus( ((wControl_p)(b->parent))->hWnd ); + SendMessage( ((wControl_p)(b->parent))->hWnd, WM_CHAR, + wParam, lParam ); + /*SendMessage( ((wControl_p)(b->parent))->hWnd, WM_COMMAND, + inx, MAKELONG( hWnd, EN_KILLFOCUS ) );*/ + return 0L; + } + } + break; + } + return CallWindowProc( oldChoiceItemProc, hWnd, message, wParam, lParam ); +} + +LRESULT choiceItemProc( + wControl_p b, + HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam ) +{ + wChoiceItem_p me = (wChoiceItem_p)b, *rest; + wChoice_p bc; + int num; + + switch( message ) { + + case WM_COMMAND: + switch (WCMD_PARAM_NOTF) { + case BN_CLICKED: + bc = me->owner; + num = -1; + for (rest = (wChoiceItem_p*)bc->buttList; *rest; rest++ ) { + switch (bc->type) { + case B_TOGGLE: + num = rest-(wChoiceItem_p*)bc->buttList; + if (*rest == me) { + bc->oldVal ^= (1L<<num); + } + SendMessage( (*rest)->hWnd, BM_SETCHECK, + (bc->oldVal & (1L<<num)) != 0, 0L ); + break; + + case B_RADIO: + if (*rest != me) { + SendMessage( (*rest)->hWnd, BM_SETCHECK, 0, 0L ); + } else { + bc->oldVal = rest-(wChoiceItem_p*)bc->buttList; + SendMessage( (*rest)->hWnd, BM_SETCHECK, 1, 0L ); + } + break; + } + } + if (bc->valueP) + *bc->valueP = bc->oldVal; + if (bc->action) + bc->action( bc->oldVal, bc->data ); + break; + + } + break; + } + + return DefWindowProc( hWnd, message, wParam, lParam ); +} + + +static callBacks_t choiceCallBacks = { + mswRepaintLabel, + NULL, + NULL, + choiceSetBusy, + choiceShow, + choiceSetPos }; + +static callBacks_t choiceItemCallBacks = { + NULL, + NULL, + choiceItemProc }; + +/** + * Creates choice buttons. This function is used to create a group of + * radio buttons and checkboxes. + * + * \param type IN type of button + * \param parent IN parent window + * \param x, y IN position of group + * \param helpStr IN index string to find help + * \param labelStr IN label for group + * \param option IN ? + * \param labels IN labels for individual choices + * \param valueP OUT pointer for return value + * \param action IN ? + * \param data IN ? + * \return created choice button group + */ + +static wChoice_p choiceCreate( + wType_e type, + wWin_p parent, + POS_T x, + POS_T y, + const char * helpStr, + const char * labelStr, + long option, + const char **labels, + long *valueP, + wChoiceCallBack_p action, + void *data ) +{ + wChoice_p b; + const char ** lp; + int cnt; + wChoiceItem_p * butts; + int ppx, ppy; + int bs; + HDC hDc; + HWND hButt; + int lab_l; + DWORD dw; + int w, maxW; + int pw, ph; + int index; + char * helpStrCopy; + HFONT hFont; + + b = mswAlloc( parent, type, mswStrdup(labelStr), sizeof *b, data, &index ); + mswComputePos( (wControl_p)b, x, y ); + b->option = option; + b->valueP = valueP; + b->action = action; + b->labels = labels; + b->labelY += 6; + + ppx = b->x; + ppy = b->y; + + switch (b->type) { + case B_TOGGLE: + bs = BS_CHECKBOX; + break; + case B_RADIO: + bs = BS_RADIOBUTTON; + break; + } + for (lp = b->labels,cnt=0; *lp; lp++,cnt++ ); + butts = (wChoiceItem_p*)malloc( (cnt+1) * sizeof *butts ); + b->buttList = butts; + b->oldVal = (b->valueP?*b->valueP:0); + ph = pw = 2; + maxW = 0; + if (helpStr) + helpStrCopy = mswStrdup( helpStr ); + for (lp = b->labels, cnt=0; *lp; lp++, cnt++, butts++ ) { + *butts = (wChoiceItem_p)mswAlloc( parent, B_CHOICEITEM, + mswStrdup(_((char *)*lp)), sizeof( wChoiceItem_t ), data, &index ); + (*butts)->owner = b; + (*butts)->hWnd = hButt = CreateWindow( "BUTTON", (*butts)->labelStr, + bs | WS_CHILD | WS_VISIBLE | mswGetBaseStyle(parent), b->x+pw, b->y+ph, + 80, CHOICE_HEIGHT, + ((wControl_p)parent)->hWnd, (HMENU)index, mswHInst, NULL ); + if ( hButt == (HWND)0 ) { + mswFail( "choiceCreate button" ); + return b; + } + (*butts)->x = b->x+pw; + (*butts)->y = b->y+ph; + if (b->hWnd == 0) + b->hWnd = (*butts)->hWnd; + (*butts)->helpStr = helpStrCopy; + + hDc = GetDC( hButt ); + lab_l = strlen((*butts)->labelStr); + + if (!mswThickFont) {hFont = SelectObject( hDc, mswLabelFont );} + dw = GetTextExtent( hDc, (char *)((*butts)->labelStr), lab_l ); + if (!mswThickFont) {SelectObject( hDc, hFont );} + + w = LOWORD(dw) + CHOICE_MIN_WIDTH; + + if (w > maxW) + maxW = w; + SetBkMode( hDc, TRANSPARENT ); + ReleaseDC( hButt, hDc ); + if (b->option & BC_HORZ) { + pw += w; + } else { + ph += CHOICE_HEIGHT; + } + if (!SetWindowPos( hButt, HWND_TOP, 0, 0, + w, CHOICE_HEIGHT, SWP_NOMOVE|SWP_NOZORDER)) { + mswFail("Create CHOICE: SetWindowPos"); + } + mswChainFocus( (wControl_p)*butts ); + newChoiceItemProc = MakeProcInstance( (XWNDPROC)pushChoiceItem, mswHInst ); + oldChoiceItemProc = (XWNDPROC)GetWindowLong( (*butts)->hWnd, GWL_WNDPROC ); + SetWindowLong( (*butts)->hWnd, GWL_WNDPROC, (LONG)newChoiceItemProc ); + if ( !mswThickFont ) + SendMessage( (*butts)->hWnd, WM_SETFONT, (WPARAM)mswLabelFont, 0L ); + } + *butts = NULL; + switch (b->type) { + case B_TOGGLE: + wToggleSetValue( b, (b->valueP?*b->valueP:0L) ); + break; + case B_RADIO: + wRadioSetValue( b, (b->valueP?*b->valueP:0L) ); + break; + } + if (b->option & BC_HORZ) { + ph = CHOICE_HEIGHT; + } else { + pw = maxW; + } + pw += 4; ph += 4; + b->w = pw; + b->h = ph; + +#define FRAME_STYLE SS_ETCHEDFRAME + + if ((b->option & BC_NOBORDER)==0) { + b->hBorder = CreateWindow( "STATIC", NULL, WS_CHILD | WS_VISIBLE | FRAME_STYLE, + b->x, b->y, pw, ph, ((wControl_p)parent)->hWnd, 0, mswHInst, NULL ); + } + mswAddButton( (wControl_p)b, TRUE, helpStr ); + mswCallBacks[ B_CHOICEITEM ] = &choiceItemCallBacks; + mswCallBacks[ type ] = &choiceCallBacks; + return b; +} + + +wChoice_p wRadioCreate( + wWin_p parent, + POS_T x, + POS_T y, + const char * helpStr, + const char * labelStr, + long option, + const char **labels, + long *valueP, + wChoiceCallBack_p action, + void *data ) +{ + return choiceCreate( B_RADIO, parent, x, y, helpStr, labelStr, + option, labels, valueP, action, data ); +} + +wChoice_p wToggleCreate( + wWin_p parent, + POS_T x, + POS_T y, + const char * helpStr, + const char * labelStr, + long option, + const char **labels, + long *valueP, + wChoiceCallBack_p action, + void *data ) +{ + return choiceCreate( B_TOGGLE, parent, x, y, helpStr, labelStr, + option, labels, valueP, action, data ); +} |