⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winctrls.c

📁 远程登陆工具软件源码 用于远程登陆unix
💻 C
📖 第 1 页 / 共 5 页
字号:

    /* Squirrel away IDs. */
    hdl->listid = listid;
    hdl->upbid  = upbid;
    hdl->dnbid  = dnbid;

    /* The static label. */
    if (stext != NULL) {
	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);
    }

    if (listheight > BTNSHEIGHT) {
        totalheight = listheight;
	buttonpos = (listheight - BTNSHEIGHT) / 2;
    } else {
        totalheight = BTNSHEIGHT;
	buttonpos = 0;
    }

    for (i=0; i<3; i++) {
        int left, wid;
        xpos = (cp->width + GAPBETWEEN) * percent / 100;
        left = xpos + GAPBETWEEN;
        percent += percents[i];
        xpos = (cp->width + GAPBETWEEN) * percent / 100;
        wid = xpos - left;

        switch (i) {
          case 1:
            /* The drag list box. */
            r.left = left; r.right = wid;
            r.top = cp->ypos; r.bottom = listheight;
            {
                HWND ctl;
                ctl = doctl(cp, r, "LISTBOX",
                            WS_CHILD | WS_VISIBLE | WS_TABSTOP |
			    WS_VSCROLL | LBS_HASSTRINGS | LBS_USETABSTOPS,
                            WS_EX_CLIENTEDGE,
                            "", listid);
		MakeDragList(ctl);
            }
            break;

          case 2:
            /* The "Up" and "Down" buttons. */
	    /* XXX worry about accelerators if we have more than one
	     * prefslist on a panel */
            r.left = left; r.right = wid;
            r.top = cp->ypos + buttonpos; r.bottom = PUSHBTNHEIGHT;
            doctl(cp, r, "BUTTON",
                  BS_NOTIFY | WS_CHILD | WS_VISIBLE |
		  WS_TABSTOP | BS_PUSHBUTTON,
                  0, "&Up", upbid);

            r.left = left; r.right = wid;
            r.top = cp->ypos + buttonpos + PUSHBTNHEIGHT + GAPBETWEEN;
            r.bottom = PUSHBTNHEIGHT;
            doctl(cp, r, "BUTTON",
                  BS_NOTIFY | WS_CHILD | WS_VISIBLE |
		  WS_TABSTOP | BS_PUSHBUTTON,
                  0, "&Down", dnbid);

            break;

        }
    }

    cp->ypos += totalheight + GAPBETWEEN;

}

/*
 * Helper function for prefslist: move item in list box.
 */
static void pl_moveitem(HWND hwnd, int listid, int src, int dst)
{
    int tlen, val;
    char *txt;
    /* Get the item's data. */
    tlen = SendDlgItemMessage (hwnd, listid, LB_GETTEXTLEN, src, 0);
    txt = snewn(tlen+1, char);
    SendDlgItemMessage (hwnd, listid, LB_GETTEXT, src, (LPARAM) txt);
    val = SendDlgItemMessage (hwnd, listid, LB_GETITEMDATA, src, 0);
    /* Deselect old location. */
    SendDlgItemMessage (hwnd, listid, LB_SETSEL, FALSE, src);
    /* Delete it at the old location. */
    SendDlgItemMessage (hwnd, listid, LB_DELETESTRING, src, 0);
    /* Insert it at new location. */
    SendDlgItemMessage (hwnd, listid, LB_INSERTSTRING, dst,
			(LPARAM) txt);
    SendDlgItemMessage (hwnd, listid, LB_SETITEMDATA, dst,
			(LPARAM) val);
    /* Set selection. */
    SendDlgItemMessage (hwnd, listid, LB_SETCURSEL, dst, 0);
    sfree (txt);
}

int pl_itemfrompt(HWND hwnd, POINT cursor, BOOL scroll)
{
    int ret;
    POINT uppoint, downpoint;
    int updist, downdist, upitem, downitem, i;

    /*
     * Ghastly hackery to try to figure out not which
     * _item_, but which _gap between items_, the user
     * is pointing at. We do this by first working out
     * which list item is under the cursor, and then
     * working out how far the cursor would have to
     * move up or down before the answer was different.
     * Then we put the insertion point _above_ the
     * current item if the upper edge is closer than
     * the lower edge, or _below_ it if vice versa.
     */
    ret = LBItemFromPt(hwnd, cursor, scroll);
    if (ret == -1)
	return ret;
    ret = LBItemFromPt(hwnd, cursor, FALSE);
    updist = downdist = 0;
    for (i = 1; i < 4096 && (!updist || !downdist); i++) {
	uppoint = downpoint = cursor;
	uppoint.y -= i;
	downpoint.y += i;
	upitem = LBItemFromPt(hwnd, uppoint, FALSE);
	downitem = LBItemFromPt(hwnd, downpoint, FALSE);
	if (!updist && upitem != ret)
	    updist = i;
	if (!downdist && downitem != ret)
	    downdist = i;
    }
    if (downdist < updist)
	ret++;
    return ret;
}

/*
 * Handler for prefslist above.
 * 
 * Return value has bit 0 set if the dialog box procedure needs to
 * return TRUE from handling this message; it has bit 1 set if a
 * change may have been made in the contents of the list.
 */
int handle_prefslist(struct prefslist *hdl,
                     int *array, int maxmemb,
                     int is_dlmsg, HWND hwnd,
		     WPARAM wParam, LPARAM lParam)
{
    int i;
    int ret = 0;

    if (is_dlmsg) {

        if ((int)wParam == hdl->listid) {
            DRAGLISTINFO *dlm = (DRAGLISTINFO *)lParam;
            int dest = 0;	       /* initialise to placate gcc */
            switch (dlm->uNotification) {
              case DL_BEGINDRAG:
		hdl->dummyitem =
		    SendDlgItemMessage(hwnd, hdl->listid,
				       LB_ADDSTRING, 0, (LPARAM) "");

                hdl->srcitem = LBItemFromPt(dlm->hWnd, dlm->ptCursor, TRUE);
		hdl->dragging = 0;
		/* XXX hack Q183115 */
		SetWindowLong(hwnd, DWL_MSGRESULT, TRUE);
                ret |= 1; break;
              case DL_CANCELDRAG:
		DrawInsert(hwnd, dlm->hWnd, -1);     /* Clear arrow */
		SendDlgItemMessage(hwnd, hdl->listid,
				   LB_DELETESTRING, hdl->dummyitem, 0);
		hdl->dragging = 0;
                ret |= 1; break;
              case DL_DRAGGING:
		hdl->dragging = 1;
		dest = pl_itemfrompt(dlm->hWnd, dlm->ptCursor, TRUE);
		if (dest > hdl->dummyitem) dest = hdl->dummyitem;
		DrawInsert (hwnd, dlm->hWnd, dest);
		if (dest >= 0)
		    SetWindowLong(hwnd, DWL_MSGRESULT, DL_MOVECURSOR);
		else
		    SetWindowLong(hwnd, DWL_MSGRESULT, DL_STOPCURSOR);
                ret |= 1; break;
              case DL_DROPPED:
		if (hdl->dragging) {
		    dest = pl_itemfrompt(dlm->hWnd, dlm->ptCursor, TRUE);
		    if (dest > hdl->dummyitem) dest = hdl->dummyitem;
		    DrawInsert (hwnd, dlm->hWnd, -1);
		}
		SendDlgItemMessage(hwnd, hdl->listid,
				   LB_DELETESTRING, hdl->dummyitem, 0);
		if (hdl->dragging) {
		    hdl->dragging = 0;
		    if (dest >= 0) {
			/* Correct for "missing" item. */
			if (dest > hdl->srcitem) dest--;
			pl_moveitem(hwnd, hdl->listid, hdl->srcitem, dest);
		    }
		    ret |= 2;
		}
                ret |= 1; break;
            }
        }

    } else {

        if (((LOWORD(wParam) == hdl->upbid) ||
             (LOWORD(wParam) == hdl->dnbid)) &&
            ((HIWORD(wParam) == BN_CLICKED) ||
             (HIWORD(wParam) == BN_DOUBLECLICKED))) {
            /* Move an item up or down the list. */
            /* Get the current selection, if any. */
            int selection = SendDlgItemMessage (hwnd, hdl->listid, LB_GETCURSEL, 0, 0);
            if (selection == LB_ERR) {
                MessageBeep(0);
            } else {
                int nitems;
                /* Get the total number of items. */
                nitems = SendDlgItemMessage (hwnd, hdl->listid, LB_GETCOUNT, 0, 0);
                /* Should we do anything? */
		if (LOWORD(wParam) == hdl->upbid && (selection > 0))
		    pl_moveitem(hwnd, hdl->listid, selection, selection - 1);
		else if (LOWORD(wParam) == hdl->dnbid && (selection < nitems - 1))
		    pl_moveitem(hwnd, hdl->listid, selection, selection + 1);
		ret |= 2;
            }

        }

    }

    if (array) {
	/* Update array to match the list box. */
	for (i=0; i < maxmemb; i++)
	    array[i] = SendDlgItemMessage (hwnd, hdl->listid, LB_GETITEMDATA,
					   i, 0);
    }

    return ret;
}

/*
 * 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);
}

/* ----------------------------------------------------------------------
 * Platform-specific side of portable dialog-box mechanism.
 */

/*
 * This function takes a string, escapes all the ampersands, and
 * places a single (unescaped) ampersand in front of the first
 * occurrence of the given shortcut character (which may be
 * NO_SHORTCUT).
 * 
 * Return value is a malloc'ed copy of the processed version of the
 * string.
 */
static char *shortcut_escape(char *text, char shortcut)
{
    char *ret;
    char *p, *q;

    if (!text)
	return NULL;		       /* sfree won't choke on this */

    ret = snewn(2*strlen(text)+1, char);   /* size potentially doubles! */
    shortcut = tolower((unsigned char)shortcut);

    p = text;
    q = ret;
    while (*p) {
	if (shortcut != NO_SHORTCUT &&
	    tolower((unsigned char)*p) == shortcut) {
	    *q++ = '&';
	    shortcut = NO_SHORTCUT;    /* stop it happening twice */
	} else if (*p == '&') {
	    *q++ = '&';
	}
	*q++ = *p++;
    }
    *q = '\0';
    return ret;
}

void winctrl_add_shortcuts(struct dlgparam *dp, struct winctrl *c)
{
    int i;
    for (i = 0; i < lenof(c->shortcuts); i++)
	if (c->shortcuts[i] != NO_SHORTCUT) {
	    unsigned char s = tolower((unsigned char)c->shortcuts[i]);
	    assert(!dp->shortcuts[s]);
	    dp->shortcuts[s] = TRUE;
	}
}

void winctrl_rem_shortcuts(struct dlgparam *dp, struct winctrl *c)
{
    int i;
    for (i = 0; i < lenof(c->shortcuts); i++)
	if (c->shortcuts[i] != NO_SHORTCUT) {
	    unsigned char s = tolower((unsigned char)c->shortcuts[i]);
	    assert(dp->shortcuts[s]);
	    dp->shortcuts[s] = FALSE;
	}
}

static int winctrl_cmp_byctrl(void *av, void *bv)
{
    struct winctrl *a = (struct winctrl *)av;
    struct winctrl *b = (struct winctrl *)bv;
    if (a->ctrl < b->ctrl)
	return -1;
    else if (a->ctrl > b->ctrl)
	return +1;
    else
	return 0;
}
static int winctrl_cmp_byid(void *av, void *bv)
{
    struct winctrl *a = (struct winctrl *)av;
    struct winctrl *b = (struct winctrl *)bv;
    if (a->base_id < b->base_id)
	return -1;
    else if (a->base_id > b->base_id)
	return +1;
    else
	return 0;
}
static int winctrl_cmp_byctrl_find(void *av, void *bv)
{
    union control *a = (union control *)av;
    struct winctrl *b = (struct winctrl *)bv;
    if (a < b->ctrl)
	return -1;
    else if (a > b->ctrl)
	return +1;
    else
	return 0;
}
static int winctrl_cmp_byid_find(void *av, void *bv)
{
    int *a = (int *)av;
    struct winctrl *b = (struct winctrl *)bv;
    if (*a < b->base_id)
	return -1;
    else if (*a >= b->base_id + b->num_ids)
	return +1;
    else
	return 0;
}

void winctrl_init(struct winctrls *wc)
{
    wc->byctrl = newtree234(winctrl_cmp_byctrl);
    wc->byid = newtree234(winctrl_cmp_byid);
}
void winctrl_cleanup(struct winctrls *wc)
{
    struct winctrl *c;

    while ((c = index234(wc->byid, 0)) != NULL) {
	winctrl_remove(wc, c);
	sfree(c->data);
	sfree(c);
    }

    freetree234(wc->byctrl);
    freetree234(wc->byid);
    wc->byctrl = wc->byid = NULL;
}

void winctrl_add(struct winctrls *wc, struct winctrl *c)
{
    struct winctrl *ret;
    if (c->ctrl) {
	ret = add234(wc->byctrl, c);
	assert(ret == c);
    }
    ret = add234(wc->byid, c);
    assert(ret == c);
}

void winctrl_remove(struct winctrls *wc, struct winctrl *c)
{
    struct winctrl *ret;
    ret = del234(wc->byctrl, c);
    ret = del234(wc->byid, c);
    assert(ret == c);
}

struct winctrl *winctrl_findbyctrl(struct winctrls *wc, union control *ctrl)
{
    return find234(wc->byctrl, ctrl, winctrl_cmp_byctrl_find);
}

struct winctrl *winctrl_findbyid(struct winctrls *wc, int id)
{
    return find234(wc->byid, &id, winctrl_cmp_byid_find);
}

struct winctrl *winctrl_findbyindex(struct winctrls *wc, int index)
{
    return index234(wc->byid, index);
}

void winctrl_layout(struct dlgparam *dp, struct winctrls *wc,
		    struct ctlpos *cp, struct controlset *s, int *id)
{
    struct ctlpos columns[16];
    int ncols, colstart, colspan;

    struct ctlpos tabdelays[16];
    union control *tabdelayed[16];
    int ntabdelays;

    struct ctlpos pos;

    char shortcuts[MAX_SHORTCUTS_PER_CTRL];
    int nshortcuts;
    char *escaped;
    int i, actual_base_id, base_id, num_ids;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -