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

📄 winctrls.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	union control *ctrl = s->ctrls[i];	/*	 * Generic processing that pertains to all control types.	 * At the end of this if statement, we'll have produced	 * `ctrl' (a pointer to the control we have to create, or	 * think about creating, in this iteration of the loop),	 * `pos' (a suitable ctlpos with which to position it), and	 * `c' (a winctrl structure to receive details of the	 * dialog IDs). Or we'll have done a `continue', if it was	 * CTRL_COLUMNS and doesn't require any control creation at	 * all.	 */	if (ctrl->generic.type == CTRL_COLUMNS) {	    assert((ctrl->columns.ncols == 1) ^ (ncols == 1));	    if (ncols == 1) {		/*		 * We're splitting into multiple columns.		 */		int lpercent, rpercent, lx, rx, i;		ncols = ctrl->columns.ncols;		assert(ncols <= lenof(columns));		for (i = 1; i < ncols; i++)		    columns[i] = columns[0];   /* structure copy */		lpercent = 0;		for (i = 0; i < ncols; i++) {		    rpercent = lpercent + ctrl->columns.percentages[i];		    lx = columns[i].xoff + lpercent *			(columns[i].width + GAPBETWEEN) / 100;		    rx = columns[i].xoff + rpercent *			(columns[i].width + GAPBETWEEN) / 100;		    columns[i].xoff = lx;		    columns[i].width = rx - lx - GAPBETWEEN;		    lpercent = rpercent;		}	    } else {		/*		 * We're recombining the various columns into one.		 */		int maxy = columns[0].ypos;		int i;		for (i = 1; i < ncols; i++)		    if (maxy < columns[i].ypos)			maxy = columns[i].ypos;		ncols = 1;		columns[0] = *cp;      /* structure copy */		columns[0].ypos = maxy;	    }	    continue;	} else if (ctrl->generic.type == CTRL_TABDELAY) {	    int i;	    assert(!ctrl->generic.tabdelay);	    ctrl = ctrl->tabdelay.ctrl;	    for (i = 0; i < ntabdelays; i++)		if (tabdelayed[i] == ctrl)		    break;	    assert(i < ntabdelays);    /* we have to have found it */	    pos = tabdelays[i];	       /* structure copy */	    colstart = colspan = -1;   /* indicate this was tab-delayed */	} else {	    /*	     * If it wasn't one of those, it's a genuine control;	     * so we'll have to compute a position for it now, by	     * checking its column span.	     */	    int col;	    colstart = COLUMN_START(ctrl->generic.column);	    colspan = COLUMN_SPAN(ctrl->generic.column);	    pos = columns[colstart];   /* structure copy */	    pos.width = columns[colstart+colspan-1].width +		(columns[colstart+colspan-1].xoff - columns[colstart].xoff);	    for (col = colstart; col < colstart+colspan; col++)		if (pos.ypos < columns[col].ypos)		    pos.ypos = columns[col].ypos;	    /*	     * If this control is to be tabdelayed, add it to the	     * tabdelay list, and unset pos.hwnd to inhibit actual	     * control creation.	     */	    if (ctrl->generic.tabdelay) {		assert(ntabdelays < lenof(tabdelays));		tabdelays[ntabdelays] = pos;   /* structure copy */		tabdelayed[ntabdelays] = ctrl;		ntabdelays++;		pos.hwnd = NULL;	    }	}	/* Most controls don't need anything in c->data. */	data = NULL;	/* And they all start off with no shortcuts registered. */	memset(shortcuts, NO_SHORTCUT, lenof(shortcuts));	nshortcuts = 0;	/* Almost all controls start at base_id. */	actual_base_id = base_id;	/*	 * Now we're ready to actually create the control, by	 * switching on its type.	 */	switch (ctrl->generic.type) {	  case CTRL_TEXT:	    {		char *wrapped, *escaped;		int lines;		num_ids = 1;		wrapped = staticwrap(&pos, cp->hwnd,				     ctrl->generic.label, &lines);		escaped = shortcut_escape(wrapped, NO_SHORTCUT);		statictext(&pos, escaped, lines, base_id);		sfree(escaped);		sfree(wrapped);	    }	    break;	  case CTRL_EDITBOX:	    num_ids = 2;	       /* static, edit */	    escaped = shortcut_escape(ctrl->editbox.label,				      ctrl->editbox.shortcut);	    shortcuts[nshortcuts++] = ctrl->editbox.shortcut;	    if (ctrl->editbox.percentwidth == 100) {		if (ctrl->editbox.has_list)		    combobox(&pos, escaped,			     base_id, base_id+1);		else		    multiedit(&pos, ctrl->editbox.password, escaped,			      base_id, base_id+1, 100, NULL);	    } else {		if (ctrl->editbox.has_list) {		    staticcombo(&pos, escaped, base_id, base_id+1,				ctrl->editbox.percentwidth);		} else {		    (ctrl->editbox.password ? staticpassedit : staticedit)			(&pos, escaped, base_id, base_id+1,			 ctrl->editbox.percentwidth);		}	    }	    sfree(escaped);	    break;	  case CTRL_RADIO:	    num_ids = ctrl->radio.nbuttons + 1;   /* label as well */	    {		struct radio *buttons;		int i;		escaped = shortcut_escape(ctrl->radio.label,					  ctrl->radio.shortcut);		shortcuts[nshortcuts++] = ctrl->radio.shortcut;		buttons = snewn(ctrl->radio.nbuttons, struct radio);		for (i = 0; i < ctrl->radio.nbuttons; i++) {		    buttons[i].text =			shortcut_escape(ctrl->radio.buttons[i],					(char)(ctrl->radio.shortcuts ?					       ctrl->radio.shortcuts[i] :					       NO_SHORTCUT));		    buttons[i].id = base_id + 1 + i;		    if (ctrl->radio.shortcuts) {			assert(nshortcuts < MAX_SHORTCUTS_PER_CTRL);			shortcuts[nshortcuts++] = ctrl->radio.shortcuts[i];		    }		}		radioline_common(&pos, escaped, base_id,				 ctrl->radio.ncolumns,				 buttons, ctrl->radio.nbuttons);		for (i = 0; i < ctrl->radio.nbuttons; i++) {		    sfree(buttons[i].text);		}		sfree(buttons);		sfree(escaped);	    }	    break;	  case CTRL_CHECKBOX:	    num_ids = 1;	    escaped = shortcut_escape(ctrl->checkbox.label,				      ctrl->checkbox.shortcut);	    shortcuts[nshortcuts++] = ctrl->checkbox.shortcut;	    checkbox(&pos, escaped, base_id);	    sfree(escaped);	    break;	  case CTRL_BUTTON:	    escaped = shortcut_escape(ctrl->button.label,				      ctrl->button.shortcut);	    shortcuts[nshortcuts++] = ctrl->button.shortcut;	    if (ctrl->button.iscancel)		actual_base_id = IDCANCEL;	    num_ids = 1;	    button(&pos, escaped, actual_base_id, ctrl->button.isdefault);	    sfree(escaped);	    break;	  case CTRL_LISTBOX:	    num_ids = 2;	    escaped = shortcut_escape(ctrl->listbox.label,				      ctrl->listbox.shortcut);	    shortcuts[nshortcuts++] = ctrl->listbox.shortcut;	    if (ctrl->listbox.draglist) {		data = snew(struct prefslist);		num_ids = 4;		prefslist(data, &pos, ctrl->listbox.height, escaped,			  base_id, base_id+1, base_id+2, base_id+3);		shortcuts[nshortcuts++] = 'u';   /* Up */		shortcuts[nshortcuts++] = 'd';   /* Down */	    } else if (ctrl->listbox.height == 0) {		/* Drop-down list. */		if (ctrl->listbox.percentwidth == 100) {		    staticddlbig(&pos, escaped,				 base_id, base_id+1);		} else {		    staticddl(&pos, escaped, base_id,			      base_id+1, ctrl->listbox.percentwidth);		}	    } else {		/* Ordinary list. */		listbox(&pos, escaped, base_id, base_id+1,			ctrl->listbox.height, ctrl->listbox.multisel);	    }	    if (ctrl->listbox.ncols) {		/*		 * This method of getting the box width is a bit of		 * a hack; we'd do better to try to retrieve the		 * actual width in dialog units from doctl() just		 * before MapDialogRect. But that's going to be no		 * fun, and this should be good enough accuracy.		 */		int width = cp->width * ctrl->listbox.percentwidth;		int *tabarray;		int i, percent;		tabarray = snewn(ctrl->listbox.ncols-1, int);		percent = 0;		for (i = 0; i < ctrl->listbox.ncols-1; i++) {		    percent += ctrl->listbox.percentages[i];		    tabarray[i] = width * percent / 10000;		}		SendDlgItemMessage(cp->hwnd, base_id+1, LB_SETTABSTOPS,				   ctrl->listbox.ncols-1, (LPARAM)tabarray);		sfree(tabarray);	    }	    sfree(escaped);	    break;	  case CTRL_FILESELECT:	    num_ids = 3;	    escaped = shortcut_escape(ctrl->fileselect.label,				      ctrl->fileselect.shortcut);	    shortcuts[nshortcuts++] = ctrl->fileselect.shortcut;	    editbutton(&pos, escaped, base_id, base_id+1,		       "Bro&wse...", base_id+2);	    shortcuts[nshortcuts++] = 'w';	    sfree(escaped);	    break;	  case CTRL_FONTSELECT:	    num_ids = 3;	    escaped = shortcut_escape(ctrl->fontselect.label,				      ctrl->fontselect.shortcut);	    shortcuts[nshortcuts++] = ctrl->fontselect.shortcut;	    statictext(&pos, escaped, 1, base_id);	    staticbtn(&pos, "", base_id+1, "Change...", base_id+2);	    sfree(escaped);	    data = snew(FontSpec);	    break;	  default:	    assert(!"Can't happen");	    num_ids = 0;	       /* placate gcc */	    break;	}	/*	 * Create a `struct winctrl' for this control, and advance	 * the dialog ID counter, if it's actually been created	 * (and isn't tabdelayed).	 */	if (pos.hwnd) {	    struct winctrl *c = snew(struct winctrl);	    c->ctrl = ctrl;	    c->base_id = actual_base_id;	    c->num_ids = num_ids;	    c->data = data;	    memcpy(c->shortcuts, shortcuts, sizeof(shortcuts));	    winctrl_add(wc, c);	    winctrl_add_shortcuts(dp, c);	    if (actual_base_id == base_id)		base_id += num_ids;	}	if (colstart >= 0) {	    /*	     * Update the ypos in all columns crossed by this	     * control.	     */	    int i;	    for (i = colstart; i < colstart+colspan; i++)		columns[i].ypos = pos.ypos;	}    }    /*     * We've now finished laying out the controls; so now update     * the ctlpos and control ID that were passed in, terminate     * any containing box, and return.     */    for (i = 0; i < ncols; i++)	if (cp->ypos < columns[i].ypos)	    cp->ypos = columns[i].ypos;    *id = base_id;    if (s->boxname && *s->boxname)	endbox(cp);}static void winctrl_set_focus(union control *ctrl, struct dlgparam *dp,			      int has_focus){    if (has_focus) {	if (dp->focused)	    dp->lastfocused = dp->focused;	dp->focused = ctrl;    } else if (!has_focus && dp->focused == ctrl) {	dp->lastfocused = dp->focused;	dp->focused = NULL;    }}union control *dlg_last_focused(union control *ctrl, void *dlg){    struct dlgparam *dp = (struct dlgparam *)dlg;    return dp->focused == ctrl ? dp->lastfocused : dp->focused;}/* * The dialog-box procedure calls this function to handle Windows * messages on a control we manage. */int winctrl_handle_command(struct dlgparam *dp, UINT msg,			   WPARAM wParam, LPARAM lParam){    struct winctrl *c;    union control *ctrl;    int i, id, ret;    static UINT draglistmsg = WM_NULL;    /*     * Filter out pointless window messages. Our interest is in     * WM_COMMAND and the drag list message, and nothing else.     */    if (draglistmsg == WM_NULL)	draglistmsg = RegisterWindowMessage (DRAGLISTMSGSTRING);    if (msg != draglistmsg && msg != WM_COMMAND && msg != WM_DRAWITEM)	return 0;    /*     * Look up the control ID in our data.     */    c = NULL;    for (i = 0; i < dp->nctrltrees; i++) {	c = winctrl_findbyid(dp->controltrees[i], LOWORD(wParam));	if (c)	    break;    }    if (!c)	return 0;		       /* we have nothing to do */    if (msg == WM_DRAWITEM) {	/*	 * Owner-draw request for a panel title.	 */	LPDRAWITEMSTRUCT di = (LPDRAWITEMSTRUCT) lParam;	HDC hdc = di->hDC;	RECT r = di->rcItem;	SIZE s;	SetMapMode(hdc, MM_TEXT);      /* ensure logical units == pixels */	GetTextExtentPoint32(hdc, (char *)c->data,				 strlen((char *)c->data), &s);	DrawEdge(hdc, &r, EDGE_ETCHED, BF_ADJUST | BF_RECT);	TextOut(hdc,		r.left + (r.right-r.left-s.cx)/2,		r.top + (r.bottom-r.top-s.cy)/2,		(char *)c->data, strlen((char *)c->data));	return TRUE;    }    ctrl = c->ctrl;    id = LOWORD(wParam) - c->base_id;    if (!ctrl || !ctrl->generic.handler)	return 0;		       /* nothing we can do here */    /*     * From here on we do not issue `return' statements until the     * very end of the dialog box: any event handler is entitled to     * ask for a colour selector, so we _must_ always allow control     * to reach the end of this switch statement so that the     * subsequent code can test dp->coloursel_wanted().     */    ret = 0;    dp->coloursel_wanted = FALSE;    /*     * Now switch on the control type and the message.     */    switch (ctrl->generic.type) {      case CTRL_EDITBOX:	if (msg == WM_COMMAND && !ctrl->editbox.has_list &&	    (HIWORD(wParam) == EN_SETFOCUS || HIWORD(wParam) == EN_KILLFOCUS))	    winctrl_set_focus(ctrl, dp, HIWORD(wParam) == EN_SETFOCUS);	if (msg == WM_COMMAND && ctrl->editbox.has_list &&	    (HIWORD(wParam)==CBN_SETFOCUS || HIWORD(wParam)==CBN_KILLFOCUS))	    winctrl_set_focus(ctrl, dp, HIWORD(wParam) == CBN_SETFOCUS);	if (msg == WM_COMMAND && !ctrl->editbox.has_list &&	    HIWORD(wParam) == EN_CHANGE)	    ctrl->generic.handler(ctrl, dp, dp->data, EVENT_VALCHANGE);	if (msg == WM_COMMAND &&	    ctrl->editbox.has_list) {	    if (HIWORD(wParam) == CBN_SELCHANGE) {		int index, len;		char *text;		index = SendDlgItemMessage(dp->hwnd, c->base_id+1,					   CB_GETCURSEL, 0, 0);		len = SendDlgItemMessage(dp->hwnd, c->base_id+1,					 CB_GETLBTEXTLEN, index, 0);		text = snewn(len+1, char);		SendDlgItemMessage(dp->hwnd, c->base_id+1, CB_GETLBTEXT,				   index, (LPARAM)text);		SetDlgItemText(dp->hwnd, c->base_id+1, text);		sfree(text);		ctrl->generic.handler(ctrl, dp, dp->data, EVENT_VALCHANGE);	    } else if (HIWORD(wParam) == CBN_EDITCHANGE) {		ctrl->generic.handler(ctrl, dp, dp->data, EVENT_VALCHANGE);	    } else if (HIWORD(wParam) == CBN_KILLFOCUS) {		ctrl->generic.handler(ctrl, dp, dp->data, EVENT_REFRESH);	    }	}	break;

⌨️ 快捷键说明

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