| /* dialog management for wineconsole |
| * (c) 2001 Eric Pouech |
| */ |
| |
| #include <stdio.h> |
| #include "winecon_private.h" |
| #include "commctrl.h" |
| #include "prsht.h" |
| |
| /* FIXME: so far, part of the code is made in ASCII because the Uncode property sheet functions |
| * are not implemented yet |
| */ |
| struct dialog_info |
| { |
| struct inner_data* data; /* pointer to current winecon info */ |
| HWND hDlg; /* handle to window dialog */ |
| int nFont; /* number of font size in size LB */ |
| struct font_info |
| { |
| TEXTMETRIC tm; |
| LOGFONT lf; |
| } *font; /* array of nFont. index sync'ed with SIZE LB */ |
| }; |
| |
| /****************************************************************** |
| * WCUSER_OptionDlgProc |
| * |
| * Dialog prop for the option property sheet |
| */ |
| static BOOL WINAPI WCUSER_OptionDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) |
| { |
| struct dialog_info* di; |
| unsigned idc; |
| |
| switch (msg) |
| { |
| case WM_INITDIALOG: |
| di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam; |
| di->hDlg = hDlg; |
| SetWindowLongA(hDlg, DWL_USER, (DWORD)di); |
| if (di->data->cursor_size < 33) idc = IDC_OPT_CURSOR_SMALL; |
| else if (di->data->cursor_size < 66) idc = IDC_OPT_CURSOR_MEDIUM; |
| else idc = IDC_OPT_CURSOR_LARGE; |
| SendDlgItemMessage(hDlg, idc, BM_SETCHECK, BST_CHECKED, 0L); |
| SetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, WINECON_GetHistorySize(di->data->hConIn), FALSE); |
| if (WINECON_GetHistoryMode(di->data->hConIn)) |
| SendDlgItemMessage(hDlg, IDC_OPT_HIST_DOUBLE, BM_SETCHECK, BST_CHECKED, 0L); |
| return FALSE; /* because we set the focus */ |
| case WM_COMMAND: |
| break; |
| case WM_NOTIFY: |
| { |
| NMHDR* nmhdr = (NMHDR*)lParam; |
| |
| di = (struct dialog_info*)GetWindowLongA(hDlg, DWL_USER); |
| switch (nmhdr->code) |
| { |
| case PSN_SETACTIVE: |
| /* needed in propsheet to keep properly the selected radio button |
| * otherwise, the focus would be set to the first tab stop in the |
| * propsheet, which would always activate the first radio button |
| */ |
| if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED) |
| idc = IDC_OPT_CURSOR_SMALL; |
| else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED) |
| idc = IDC_OPT_CURSOR_MEDIUM; |
| else |
| idc = IDC_OPT_CURSOR_LARGE; |
| PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, idc), TRUE); |
| break; |
| case PSN_APPLY: |
| { |
| int curs_size; |
| int hist_size; |
| BOOL done; |
| |
| if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED) curs_size = 33; |
| else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED) curs_size = 66; |
| else curs_size = 99; |
| if (curs_size != di->data->cursor_size) |
| { |
| CONSOLE_CURSOR_INFO cinfo; |
| cinfo.dwSize = curs_size; |
| cinfo.bVisible = di->data->cursor_visible; |
| SetConsoleCursorInfo(di->data->hConOut, &cinfo); |
| } |
| hist_size = GetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, &done, FALSE); |
| if (done) WINECON_SetHistorySize(di->data->hConIn, hist_size); |
| SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR); |
| WINECON_SetHistoryMode(di->data->hConIn, |
| IsDlgButtonChecked(hDlg, IDC_OPT_HIST_DOUBLE) & BST_CHECKED); |
| return TRUE; |
| } |
| default: |
| return FALSE; |
| } |
| break; |
| } |
| default: |
| return FALSE; |
| } |
| return TRUE; |
| } |
| |
| /****************************************************************** |
| * WCUSER_FontPreviewProc |
| * |
| * Window proc for font previewer in font property sheet |
| */ |
| static LRESULT WINAPI WCUSER_FontPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) |
| { |
| switch (msg) |
| { |
| case WM_PAINT: |
| { |
| PAINTSTRUCT ps; |
| int font_idx; |
| int size_idx; |
| struct dialog_info* di; |
| |
| di = (struct dialog_info*)GetWindowLong(GetParent(hWnd), DWL_USER); |
| BeginPaint(hWnd, &ps); |
| |
| font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L); |
| size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L); |
| |
| if (font_idx >= 0 && size_idx >= 0 && size_idx < di->nFont) |
| { |
| HFONT hFont, hOldFont; |
| WCHAR buf1[256]; |
| WCHAR buf2[256]; |
| int len1, len2; |
| |
| hFont = CreateFontIndirect(&di->font[size_idx].lf); |
| len1 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_1, |
| buf1, sizeof(buf1) / sizeof(WCHAR)); |
| len2 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_2, |
| buf2, sizeof(buf2) / sizeof(WCHAR)); |
| if (hFont && len1) |
| { |
| hOldFont = SelectObject(ps.hdc, hFont); |
| SetBkColor(ps.hdc, RGB(0x00, 0x00, 0x00)); |
| SetTextColor(ps.hdc, RGB(0xFF, 0xFF, 0xFF)); |
| TextOut(ps.hdc, 0, 0, buf1, len1); |
| if (len2) |
| TextOut(ps.hdc, 0, di->font[size_idx].tm.tmHeight, buf2, len2); |
| SelectObject(ps.hdc, hOldFont); |
| DeleteObject(hFont); |
| } |
| } |
| EndPaint(hWnd, &ps); |
| break; |
| } |
| default: |
| return DefWindowProc(hWnd, msg, wParam, lParam); |
| } |
| return 0L; |
| } |
| |
| /****************************************************************** |
| * font_enum |
| * |
| * |
| */ |
| static int CALLBACK font_enum_size2(const LOGFONT* lf, const TEXTMETRIC* tm, |
| DWORD FontType, LPARAM lParam) |
| { |
| struct dialog_info* di = (struct dialog_info*)lParam; |
| |
| if (WCUSER_ValidateFontMetric(di->data, tm)) |
| { |
| di->nFont++; |
| } |
| return 1; |
| } |
| |
| static int CALLBACK font_enum(const LOGFONT* lf, const TEXTMETRIC* tm, |
| DWORD FontType, LPARAM lParam) |
| { |
| struct dialog_info* di = (struct dialog_info*)lParam; |
| HDC hdc; |
| |
| if (WCUSER_ValidateFont(di->data, lf) && (hdc = GetDC(di->hDlg))) |
| { |
| di->nFont = 0; |
| EnumFontFamilies(hdc, lf->lfFaceName, font_enum_size2, (LPARAM)di); |
| if (di->nFont) |
| { |
| int idx; |
| idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_ADDSTRING, |
| 0, (LPARAM)lf->lfFaceName); |
| } |
| ReleaseDC(di->hDlg, hdc); |
| } |
| return 1; |
| } |
| |
| /****************************************************************** |
| * font_enum_size |
| * |
| * |
| */ |
| static int CALLBACK font_enum_size(const LOGFONT* lf, const TEXTMETRIC* tm, |
| DWORD FontType, LPARAM lParam) |
| { |
| struct dialog_info* di = (struct dialog_info*)lParam; |
| |
| if (WCUSER_ValidateFontMetric(di->data, tm)) |
| { |
| WCHAR buf[32]; |
| WCHAR fmt[] = {'%','l','d',0}; |
| int idx; |
| |
| /* we want the string to be sorted with a numeric order, not a lexicographic... |
| * do the job by hand... get where to insert the new string |
| */ |
| for (idx = 0; idx < di->nFont && tm->tmHeight > di->font[idx].tm.tmHeight; idx++); |
| wsprintfW(buf, fmt, tm->tmHeight); |
| SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, idx, (LPARAM)buf); |
| |
| /* now grow our arrays and insert to values at the same index than in the list box */ |
| di->font = HeapReAlloc(GetProcessHeap(), 0, di->font, sizeof(*di->font) * (di->nFont + 1)); |
| if (idx != di->nFont) |
| memmove(&di->font[idx + 1], &di->font[idx], (di->nFont - idx) * sizeof(*di->font)); |
| di->font[idx].tm = *tm; |
| di->font[idx].lf = *lf; |
| di->nFont++; |
| |
| } |
| return 1; |
| } |
| |
| /****************************************************************** |
| * select_font |
| * |
| * |
| */ |
| static BOOL select_font(struct dialog_info* di) |
| { |
| int idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L); |
| WCHAR buf[256]; |
| WCHAR fmt[128]; |
| |
| if (idx < 0 || idx >= di->nFont) |
| return FALSE; |
| |
| LoadString(GetModuleHandle(NULL), IDS_FNT_DISPLAY, fmt, sizeof(fmt) / sizeof(WCHAR)); |
| wsprintfW(buf, fmt, di->font[idx].tm.tmMaxCharWidth, di->font[idx].tm.tmHeight); |
| |
| SendDlgItemMessage(di->hDlg, IDC_FNT_FONT_INFO, WM_SETTEXT, 0, (LPARAM)buf); |
| InvalidateRect(GetDlgItem(di->hDlg, IDC_FNT_PREVIEW), NULL, TRUE); |
| UpdateWindow(GetDlgItem(di->hDlg, IDC_FNT_PREVIEW)); |
| return TRUE; |
| } |
| |
| /****************************************************************** |
| * fill_list_size |
| * |
| * fills the size list box according to selected family in font LB |
| */ |
| static BOOL fill_list_size(struct dialog_info* di, BOOL doInit) |
| { |
| HDC hdc; |
| int idx; |
| WCHAR lfFaceName[LF_FACESIZE]; |
| |
| idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L); |
| if (idx < 0) return FALSE; |
| |
| hdc = GetDC(di->hDlg); |
| if (!hdc) return FALSE; |
| |
| SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETTEXT, idx, (LPARAM)lfFaceName); |
| SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_RESETCONTENT, 0L, 0L); |
| if (di->font) HeapFree(GetProcessHeap(), 0, di->font); |
| di->nFont = 0; |
| di->font = NULL; |
| |
| EnumFontFamilies(hdc, lfFaceName, font_enum_size, (LPARAM)di); |
| ReleaseDC(di->hDlg, hdc); |
| |
| if (doInit) |
| { |
| for (idx = 0; idx < di->nFont; idx++) |
| { |
| if (memcmp(&di->data->logFont, &di->font[idx].lf, sizeof(LOGFONT)) == 0) |
| break; |
| } |
| if (idx == di->nFont) idx = 0; |
| } |
| else |
| idx = 0; |
| SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_SETCURSEL, idx, 0L); |
| select_font(di); |
| return TRUE; |
| } |
| |
| /****************************************************************** |
| * fill_list_font |
| * |
| * Fills the font LB |
| */ |
| static BOOL fill_list_font(struct dialog_info* di) |
| { |
| HDC hdc; |
| |
| hdc = GetDC(di->hDlg); |
| if (!hdc) return FALSE; |
| |
| SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_RESETCONTENT, 0L, 0L); |
| EnumFontFamilies(hdc, NULL, font_enum, (LPARAM)di); |
| ReleaseDC(di->hDlg, hdc); |
| if (SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SELECTSTRING, |
| (WPARAM)-1, (LPARAM)di->data->logFont.lfFaceName) == LB_ERR) |
| SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SETCURSEL, 0L, 0L); |
| fill_list_size(di, TRUE); |
| return TRUE; |
| } |
| |
| /****************************************************************** |
| * WCUSER_FontDlgProc |
| * |
| * Dialog proc for the Font property sheet |
| */ |
| static BOOL WINAPI WCUSER_FontDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) |
| { |
| struct dialog_info* di; |
| |
| switch (msg) |
| { |
| case WM_INITDIALOG: |
| di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam; |
| di->hDlg = hDlg; |
| SetWindowLong(hDlg, DWL_USER, (DWORD)di); |
| fill_list_font(di); |
| break; |
| case WM_COMMAND: |
| di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER); |
| switch (LOWORD(wParam)) |
| { |
| case IDC_FNT_LIST_FONT: |
| if (HIWORD(wParam) == LBN_SELCHANGE) |
| { |
| fill_list_size(di, FALSE); |
| } |
| break; |
| case IDC_FNT_LIST_SIZE: |
| if (HIWORD(wParam) == LBN_SELCHANGE) |
| { |
| select_font(di); |
| } |
| break; |
| } |
| break; |
| case WM_NOTIFY: |
| { |
| NMHDR* nmhdr = (NMHDR*)lParam; |
| |
| di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER); |
| switch (nmhdr->code) |
| { |
| case PSN_APPLY: |
| { |
| int idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L); |
| |
| if (idx >= 0 && idx < di->nFont) |
| { |
| WCUSER_SetFont(di->data, &di->font[idx].lf, &di->font[idx].tm); |
| } |
| SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR); |
| return TRUE; |
| } |
| default: |
| return FALSE; |
| } |
| break; |
| } |
| default: |
| return FALSE; |
| } |
| return TRUE; |
| } |
| |
| /****************************************************************** |
| * WCUSER_ConfigDlgProc |
| * |
| * Dialog proc for the config property sheet |
| */ |
| static BOOL WINAPI WCUSER_ConfigDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) |
| { |
| struct dialog_info* di; |
| |
| switch (msg) |
| { |
| case WM_INITDIALOG: |
| di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam; |
| di->hDlg = hDlg; |
| SetWindowLong(hDlg, DWL_USER, (DWORD)di); |
| SetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, di->data->sb_width, FALSE); |
| SetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, di->data->sb_height, FALSE); |
| SetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, di->data->win_width, FALSE); |
| SetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, di->data->win_height, FALSE); |
| break; |
| case WM_COMMAND: |
| di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER); |
| switch (LOWORD(wParam)) |
| { |
| } |
| break; |
| case WM_NOTIFY: |
| { |
| NMHDR* nmhdr = (NMHDR*)lParam; |
| |
| di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER); |
| switch (nmhdr->code) |
| { |
| case PSN_APPLY: |
| { |
| COORD sb; |
| SMALL_RECT pos; |
| BOOL st_w, st_h; |
| |
| sb.X = GetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH, &st_w, FALSE); |
| sb.Y = GetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, &st_h, FALSE); |
| if (st_w && st_h && (sb.X != di->data->sb_width || sb.Y != di->data->sb_height)) |
| { |
| SetConsoleScreenBufferSize(di->data->hConOut, sb); |
| } |
| |
| pos.Right = GetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH, &st_w, FALSE); |
| pos.Bottom = GetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, &st_h, FALSE); |
| if (st_w && st_h && |
| (pos.Right != di->data->win_width || pos.Bottom != di->data->win_height)) |
| { |
| pos.Left = pos.Top = 0; |
| pos.Right--; pos.Bottom--; |
| SetConsoleWindowInfo(di->data->hConOut, FALSE, &pos); |
| } |
| |
| SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR); |
| return TRUE; |
| } |
| default: |
| return FALSE; |
| } |
| break; |
| } |
| default: |
| return FALSE; |
| } |
| return TRUE; |
| } |
| |
| /****************************************************************** |
| * WCUSER_GetProperties |
| * |
| * Runs the dialog box to set up the winconsole options |
| */ |
| BOOL WCUSER_GetProperties(struct inner_data* data) |
| { |
| HPROPSHEETPAGE psPage[3]; |
| PROPSHEETPAGEA psp; |
| PROPSHEETHEADERA psHead; |
| WNDCLASS wndclass; |
| static WCHAR szFntPreview[] = {'W','i','n','e','C','o','n','F','o','n','t','P','r','e','v','i','e','w',0}; |
| struct dialog_info di; |
| |
| InitCommonControls(); |
| |
| di.data = data; |
| di.nFont = 0; |
| di.font = NULL; |
| |
| wndclass.style = 0; |
| wndclass.lpfnWndProc = WCUSER_FontPreviewProc; |
| wndclass.cbClsExtra = 0; |
| wndclass.cbWndExtra = 0; |
| wndclass.hInstance = GetModuleHandle(NULL); |
| wndclass.hIcon = 0; |
| wndclass.hCursor = LoadCursor(0, IDC_ARROW); |
| wndclass.hbrBackground = GetStockObject(BLACK_BRUSH); |
| wndclass.lpszMenuName = NULL; |
| wndclass.lpszClassName = szFntPreview; |
| RegisterClass(&wndclass); |
| |
| memset(&psp, 0, sizeof(psp)); |
| psp.dwSize = sizeof(psp); |
| psp.dwFlags = 0; |
| psp.hInstance = wndclass.hInstance; |
| psp.lParam = (LPARAM)&di; |
| |
| psp.u.pszTemplate = MAKEINTRESOURCEA(IDD_OPTION); |
| psp.pfnDlgProc = WCUSER_OptionDlgProc; |
| psPage[0] = CreatePropertySheetPageA(&psp); |
| |
| psp.u.pszTemplate = MAKEINTRESOURCEA(IDD_FONT); |
| psp.pfnDlgProc = WCUSER_FontDlgProc; |
| psPage[1] = CreatePropertySheetPageA(&psp); |
| |
| psp.u.pszTemplate = MAKEINTRESOURCEA(IDD_CONFIG); |
| psp.pfnDlgProc = WCUSER_ConfigDlgProc; |
| psPage[2] = CreatePropertySheetPageA(&psp); |
| |
| memset(&psHead, 0, sizeof(psHead)); |
| psHead.dwSize = sizeof(psHead); |
| psHead.pszCaption = "Setup"; |
| psHead.nPages = 3; |
| psHead.hwndParent = data->hWnd; |
| psHead.u3.phpage = psPage; |
| |
| PropertySheetA(&psHead); |
| |
| return TRUE; |
| } |
| |