📄 winctrls.c
字号:
case CTRL_RADIO: if (msg == WM_COMMAND && (HIWORD(wParam) == BN_SETFOCUS || HIWORD(wParam) == BN_KILLFOCUS)) winctrl_set_focus(ctrl, dp, HIWORD(wParam) == BN_SETFOCUS); /* * We sometimes get spurious BN_CLICKED messages for the * radio button that is just about to _lose_ selection, if * we're switching using the arrow keys. Therefore we * double-check that the button in wParam is actually * checked before generating an event. */ if (msg == WM_COMMAND && (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) && IsDlgButtonChecked(dp->hwnd, LOWORD(wParam))) { ctrl->generic.handler(ctrl, dp, dp->data, EVENT_VALCHANGE); } break; case CTRL_CHECKBOX: if (msg == WM_COMMAND && (HIWORD(wParam) == BN_SETFOCUS || HIWORD(wParam) == BN_KILLFOCUS)) winctrl_set_focus(ctrl, dp, HIWORD(wParam) == BN_SETFOCUS); if (msg == WM_COMMAND && (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED)) { ctrl->generic.handler(ctrl, dp, dp->data, EVENT_VALCHANGE); } break; case CTRL_BUTTON: if (msg == WM_COMMAND && (HIWORD(wParam) == BN_SETFOCUS || HIWORD(wParam) == BN_KILLFOCUS)) winctrl_set_focus(ctrl, dp, HIWORD(wParam) == BN_SETFOCUS); if (msg == WM_COMMAND && (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED)) { ctrl->generic.handler(ctrl, dp, dp->data, EVENT_ACTION); } break; case CTRL_LISTBOX: if (msg == WM_COMMAND && ctrl->listbox.height != 0 && (HIWORD(wParam)==LBN_SETFOCUS || HIWORD(wParam)==LBN_KILLFOCUS)) winctrl_set_focus(ctrl, dp, HIWORD(wParam) == LBN_SETFOCUS); if (msg == WM_COMMAND && ctrl->listbox.height == 0 && (HIWORD(wParam)==CBN_SETFOCUS || HIWORD(wParam)==CBN_KILLFOCUS)) winctrl_set_focus(ctrl, dp, HIWORD(wParam) == CBN_SETFOCUS); if (msg == WM_COMMAND && id >= 2 && (HIWORD(wParam) == BN_SETFOCUS || HIWORD(wParam) == BN_KILLFOCUS)) winctrl_set_focus(ctrl, dp, HIWORD(wParam) == BN_SETFOCUS); if (ctrl->listbox.draglist) { int pret; pret = handle_prefslist(c->data, NULL, 0, (msg != WM_COMMAND), dp->hwnd, wParam, lParam); if (pret & 2) ctrl->generic.handler(ctrl, dp, dp->data, EVENT_VALCHANGE); ret = pret & 1; } else { if (msg == WM_COMMAND && HIWORD(wParam) == LBN_DBLCLK) { SetCapture(dp->hwnd); ctrl->generic.handler(ctrl, dp, dp->data, EVENT_ACTION); } else if (msg == WM_COMMAND && HIWORD(wParam) == LBN_SELCHANGE) { ctrl->generic.handler(ctrl, dp, dp->data, EVENT_SELCHANGE); } } break; case CTRL_FILESELECT: if (msg == WM_COMMAND && id == 1 && (HIWORD(wParam) == EN_SETFOCUS || HIWORD(wParam) == EN_KILLFOCUS)) winctrl_set_focus(ctrl, dp, HIWORD(wParam) == EN_SETFOCUS); if (msg == WM_COMMAND && id == 2 && (HIWORD(wParam) == BN_SETFOCUS || HIWORD(wParam) == BN_KILLFOCUS)) winctrl_set_focus(ctrl, dp, HIWORD(wParam) == BN_SETFOCUS); if (msg == WM_COMMAND && id == 1 && HIWORD(wParam) == EN_CHANGE) ctrl->generic.handler(ctrl, dp, dp->data, EVENT_VALCHANGE); if (id == 2 && (msg == WM_COMMAND && (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED))) { OPENFILENAME of; char filename[FILENAME_MAX]; int ret; memset(&of, 0, sizeof(of));#ifdef OPENFILENAME_SIZE_VERSION_400 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;#else of.lStructSize = sizeof(of);#endif of.hwndOwner = dp->hwnd; if (ctrl->fileselect.filter) of.lpstrFilter = ctrl->fileselect.filter; else of.lpstrFilter = "All Files (*.*)\0*\0\0\0"; of.lpstrCustomFilter = NULL; of.nFilterIndex = 1; of.lpstrFile = filename; GetDlgItemText(dp->hwnd, c->base_id+1, filename, lenof(filename)); filename[lenof(filename)-1] = '\0'; of.nMaxFile = lenof(filename); of.lpstrFileTitle = NULL; of.lpstrInitialDir = NULL; of.lpstrTitle = ctrl->fileselect.title; of.Flags = 0; if (ctrl->fileselect.for_writing) ret = GetSaveFileName(&of); else ret = GetOpenFileName(&of); if (ret) { SetDlgItemText(dp->hwnd, c->base_id + 1, filename); ctrl->generic.handler(ctrl, dp, dp->data, EVENT_VALCHANGE); } } break; case CTRL_FONTSELECT: if (msg == WM_COMMAND && id == 2 && (HIWORD(wParam) == BN_SETFOCUS || HIWORD(wParam) == BN_KILLFOCUS)) winctrl_set_focus(ctrl, dp, HIWORD(wParam) == BN_SETFOCUS); if (id == 2 && (msg == WM_COMMAND && (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED))) { CHOOSEFONT cf; LOGFONT lf; HDC hdc; FontSpec fs = *(FontSpec *)c->data; hdc = GetDC(0); lf.lfHeight = -MulDiv(fs.height, GetDeviceCaps(hdc, LOGPIXELSY), 72); ReleaseDC(0, hdc); lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0; lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0; lf.lfWeight = (fs.isbold ? FW_BOLD : 0); lf.lfCharSet = fs.charset; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE; strncpy(lf.lfFaceName, fs.name, sizeof(lf.lfFaceName) - 1); lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0'; cf.lStructSize = sizeof(cf); cf.hwndOwner = dp->hwnd; cf.lpLogFont = &lf; cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS; if (ChooseFont(&cf)) { strncpy(fs.name, lf.lfFaceName, sizeof(fs.name) - 1); fs.name[sizeof(fs.name) - 1] = '\0'; fs.isbold = (lf.lfWeight == FW_BOLD); fs.charset = lf.lfCharSet; fs.height = cf.iPointSize / 10; dlg_fontsel_set(ctrl, dp, fs); ctrl->generic.handler(ctrl, dp, dp->data, EVENT_VALCHANGE); } } break; } /* * If the above event handler has asked for a colour selector, * now is the time to generate one. */ if (dp->coloursel_wanted) { static CHOOSECOLOR cc; static DWORD custom[16] = { 0 }; /* zero initialisers */ cc.lStructSize = sizeof(cc); cc.hwndOwner = dp->hwnd; cc.hInstance = (HWND) hinst; cc.lpCustColors = custom; cc.rgbResult = RGB(dp->coloursel_result.r, dp->coloursel_result.g, dp->coloursel_result.b); cc.Flags = CC_FULLOPEN | CC_RGBINIT; if (ChooseColor(&cc)) { dp->coloursel_result.r = (unsigned char) (cc.rgbResult & 0xFF); dp->coloursel_result.g = (unsigned char) (cc.rgbResult >> 8) & 0xFF; dp->coloursel_result.b = (unsigned char) (cc.rgbResult >> 16) & 0xFF; dp->coloursel_result.ok = TRUE; } else dp->coloursel_result.ok = FALSE; ctrl->generic.handler(ctrl, dp, dp->data, EVENT_CALLBACK); } return ret;}/* * This function can be called to produce context help on a * control. Returns TRUE if it has actually launched WinHelp. */int winctrl_context_help(struct dlgparam *dp, HWND hwnd, int id){ int i; struct winctrl *c; char *cmd; /* * Look up the control ID in our data. */ c = NULL; for (i = 0; i < dp->nctrltrees; i++) { c = winctrl_findbyid(dp->controltrees[i], id); if (c) break; } if (!c) return 0; /* we have nothing to do */ /* * This is the Windows front end, so we're allowed to assume * `helpctx.p' is a context string. */ if (!c->ctrl || !c->ctrl->generic.helpctx.p) return 0; /* no help available for this ctrl */ cmd = dupprintf("JI(`',`%s')", c->ctrl->generic.helpctx.p); WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd); sfree(cmd); return 1;}/* * Now the various functions that the platform-independent * mechanism can call to access the dialog box entries. */static struct winctrl *dlg_findbyctrl(struct dlgparam *dp, union control *ctrl){ int i; for (i = 0; i < dp->nctrltrees; i++) { struct winctrl *c = winctrl_findbyctrl(dp->controltrees[i], ctrl); if (c) return c; } return NULL;}void dlg_radiobutton_set(union control *ctrl, void *dlg, int whichbutton){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_RADIO); CheckRadioButton(dp->hwnd, c->base_id + 1, c->base_id + c->ctrl->radio.nbuttons, c->base_id + 1 + whichbutton);}int dlg_radiobutton_get(union control *ctrl, void *dlg){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); int i; assert(c && c->ctrl->generic.type == CTRL_RADIO); for (i = 0; i < c->ctrl->radio.nbuttons; i++) if (IsDlgButtonChecked(dp->hwnd, c->base_id + 1 + i)) return i; assert(!"No radio button was checked?!"); return 0;}void dlg_checkbox_set(union control *ctrl, void *dlg, int checked){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_CHECKBOX); CheckDlgButton(dp->hwnd, c->base_id, (checked != 0));}int dlg_checkbox_get(union control *ctrl, void *dlg){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_CHECKBOX); return 0 != IsDlgButtonChecked(dp->hwnd, c->base_id);}void dlg_editbox_set(union control *ctrl, void *dlg, char const *text){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_EDITBOX); SetDlgItemText(dp->hwnd, c->base_id+1, text);}void dlg_editbox_get(union control *ctrl, void *dlg, char *buffer, int length){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_EDITBOX); GetDlgItemText(dp->hwnd, c->base_id+1, buffer, length); buffer[length-1] = '\0';}/* The `listbox' functions can also apply to combo boxes. */void dlg_listbox_clear(union control *ctrl, void *dlg){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); int msg; assert(c && (c->ctrl->generic.type == CTRL_LISTBOX || (c->ctrl->generic.type == CTRL_EDITBOX && c->ctrl->editbox.has_list))); msg = (c->ctrl->generic.type==CTRL_LISTBOX && c->ctrl->listbox.height!=0 ? LB_RESETCONTENT : CB_RESETCONTENT); SendDlgItemMessage(dp->hwnd, c->base_id+1, msg, 0, 0);}void dlg_listbox_del(union control *ctrl, void *dlg, int index){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); int msg; assert(c && (c->ctrl->generic.type == CTRL_LISTBOX || (c->ctrl->generic.type == CTRL_EDITBOX && c->ctrl->editbox.has_list))); msg = (c->ctrl->generic.type==CTRL_LISTBOX && c->ctrl->listbox.height!=0 ? LB_DELETESTRING : CB_DELETESTRING); SendDlgItemMessage(dp->hwnd, c->base_id+1, msg, index, 0);}void dlg_listbox_add(union control *ctrl, void *dlg, char const *text){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); int msg; assert(c && (c->ctrl->generic.type == CTRL_LISTBOX || (c->ctrl->generic.type == CTRL_EDITBOX && c->ctrl->editbox.has_list))); msg = (c->ctrl->generic.type==CTRL_LISTBOX && c->ctrl->listbox.height!=0 ? LB_ADDSTRING : CB_ADDSTRING); SendDlgItemMessage(dp->hwnd, c->base_id+1, msg, 0, (LPARAM)text);}/* * Each listbox entry may have a numeric id associated with it. * Note that some front ends only permit a string to be stored at * each position, which means that _if_ you put two identical * strings in any listbox then you MUST not assign them different * IDs and expect to get meaningful results back. */void dlg_listbox_addwithid(union control *ctrl, void *dlg, char const *text, int id){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); int msg, msg2, index; assert(c && (c->ctrl->generic.type == CTRL_LISTBOX || (c->ctrl->generic.type == CTRL_EDITBOX && c->ctrl->editbox.has_list))); msg = (c->ctrl->generic.type==CTRL_LISTBOX && c->ctrl->listbox.height!=0 ? LB_ADDSTRING : CB_ADDSTRING); msg2 = (c->ctrl->generic.type==CTRL_LISTBOX && c->ctrl->listbox.height!=0 ? LB_SETITEMDATA : CB_SETITEMDATA); index = SendDlgItemMessage(dp->hwnd, c->base_id+1, msg, 0, (LPARAM)text); SendDlgItemMessage(dp->hwnd, c->base_id+1, msg2, index, (LPARAM)id);}int dlg_listbox_getid(union control *ctrl, void *dlg, int index){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); int msg; assert(c && c->ctrl->generic.type == CTRL_LISTBOX); msg = (c->ctrl->listbox.height != 0 ? LB_GETITEMDATA : CB_GETITEMDATA); return SendDlgItemMessage(dp->hwnd, c->base_id+1, msg, index, 0);}/* dlg_listbox_index returns <0 if no single element is selected. */int dlg_listbox_index(union control *ctrl, void *dlg){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); int msg, ret; assert(c && c->ctrl->generic.type == CTRL_LISTBOX && !c->ctrl->listbox.multisel); msg = (c->ctrl->listbox.height != 0 ? LB_GETCURSEL : CB_GETCURSEL); ret = SendDlgItemMessage(dp->hwnd, c->base_id+1, msg, 0, 0); if (ret == LB_ERR) return -1; else return ret;}int dlg_listbox_issel(union control *ctrl, void *dlg, int index){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_LISTBOX && c->ctrl->listbox.multisel && c->ctrl->listbox.height != 0); return SendDlgItemMessage(dp->hwnd, c->base_id+1, LB_GETSEL, index, 0);}void dlg_listbox_select(union control *ctrl, void *dlg, int index){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); int msg; assert(c && c->ctrl->generic.type == CTRL_LISTBOX && !c->ctrl->listbox.multisel); msg = (c->ctrl->listbox.height != 0 ? LB_SETCURSEL : CB_SETCURSEL); SendDlgItemMessage(dp->hwnd, c->base_id+1, msg, index, 0);}void dlg_text_set(union control *ctrl, void *dlg, char const *text){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_TEXT); SetDlgItemText(dp->hwnd, c->base_id, text);}void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_FILESELECT); SetDlgItemText(dp->hwnd, c->base_id+1, fn.path);}void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn){ struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_FILESELECT); GetDlgItemText(dp->hwnd, c->base_id+1, fn->path, lenof(fn->path)); fn->path[lenof(fn->path)-1] = '\0';}void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec fs){ char *buf, *boldstr; struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_FONTSELECT); *(FontSpec *)c->data = fs; /* structure copy */ boldstr = (fs.isbold ? "bold, " : ""); if (fs.height == 0) buf = dupprintf("Font: %s, %sde
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -