📄 windlg.c
字号:
/* * windlg.c * * Microwindows Dialog function * * Copyright (C) 2003 - Gabriele Brugnoni * * gabrielebrugnoni@dveprojects.com * DVE Prog. El. - Varese, Italy */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#define MWINCLUDECOLORS#include "windows.h" /* windef.h, winuser.h */#include "wintools.h"#include "wintern.h"#include "device.h"#define DEFAULT_FONT DEFAULT_GUI_FONT#define DEFDLG_FONT_QUALITY ANTIALIASED_QUALITY#define DWL_DLGDATA 12#define DLG_DEF_STYLE (0)#define ISDLGCONTROL(hDlg, hCtrl) (((hCtrl) != NULL) && ((hDlg) != (hCtrl)) && \ (MwGetTopWindow((hCtrl)) == (hDlg)))#define MulDiv(x,m,d) ( ((((x)<0) && ((m)<0)) || (((x)>=0) && ((m)>=0))) ? \ ((((long)(x)*(long)(m))+(long)((d)/2))/(long)(d)) : \ ((((long)(x)*(long)(m))-(long)((d)/2))/(long)(d)) )#define MulDivRD(x,m,d) ( ((long)(x) * (long)(m))/(long)(d) )/* * Struct with information about DLG */typedef struct tagMWDLGDATA { HFONT hFnt; DWORD flags; BOOL running; HWND hWndFocus; int nResult;} MWDLGDATA, *PMWDLGDATA;#define DLGF_DESTROYFONT 0x80000000L#define DLG_PMWDLGDATA(dlg) ((PMWDLGDATA)GetWindowLong(dlg, DWL_DLGDATA))#define DLG_DLGPROC(dlg) ((DLGPROC)GetWindowLong(dlg, DWL_DLGPROC))#define DLG_MSGRESULT(dlg) ((LRESULT)GetWindowLong(dlg, DWL_MSGRESULT))static LRESULT CALLBACK mwDialogProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);/* * Used to find the top-control in dialogs. * (focus in a COMBOBOX is on a CBB's child) */static HWNDdlgGetCtrlTop(HWND hDlg, HWND hChild){ HWND hwnd = hChild; while ((hwnd != NULL)) { if (hwnd->parent == hDlg) return hwnd; hwnd = hwnd->parent; } return hChild;}#define dlgGetCtrlFocus(hDlg) dlgGetCtrlTop(hDlg, GetFocus())/* * Initialize module */BOOL WINAPIMwInitializeDialogs(HINSTANCE hInstance){#ifdef WNDCLASSEX WNDCLASSEX wcl;#else WNDCLASS wcl;#endif MwRegisterStaticControl(hInstance); MwRegisterButtonControl(hInstance); MwRegisterEditControl(hInstance); MwRegisterListboxControl(hInstance); MwRegisterProgressBarControl(hInstance); MwRegisterComboboxControl(hInstance); memset(&wcl, 0, sizeof(wcl));#ifdef WNDCLASSEX wcl.cbSize = sizeof(wcl);#endif wcl.style = CS_BYTEALIGNCLIENT; wcl.cbWndExtra = DWL_DLGDATA + 4; wcl.lpfnWndProc = (WNDPROC) mwDialogProc; wcl.hInstance = hInstance; wcl.lpszClassName = "GDLGCLASS"; wcl.hbrBackground = GetStockObject(LTGRAY_BRUSH);#ifdef WNDCLASSEX return (RegisterClassEx(&wcl) != 0);#else return (RegisterClass(&wcl) != 0);#endif}LRESULT WINAPISendDlgItemMessage(HWND hwnd, int id, UINT Msg, WPARAM wParam, LPARAM lParam){ HWND hctl = GetDlgItem(hwnd, id); if (hctl == NULL) return 0; return SendMessage(hctl, Msg, wParam, lParam);}UINT WINAPIGetDlgItemText(HWND hwnd, int id, LPTSTR pStr, int nSize){ return GetWindowText(GetDlgItem(hwnd, id), pStr, nSize);}BOOL WINAPISetDlgItemText(HWND hwnd, int id, LPTSTR pStr){ return SetWindowText(GetDlgItem(hwnd, id), pStr);}BOOL WINAPISetDlgItemInt(HWND hwnd, int id, UINT val, BOOL bSigned){ char s[64]; if (bSigned) sprintf(s, "%d", val); else sprintf(s, "%u", val); return SetWindowText(GetDlgItem(hwnd, id), s);}UINT WINAPIGetDlgItemInt(HWND hwnd, int id, BOOL * pbTransl, BOOL bSigned){ int x, n; UINT ux; char s[64]; GetWindowText(GetDlgItem(hwnd, id), s, sizeof(s)); if (bSigned) n = sscanf(s, "%d", &x); else n = sscanf(s, "%u", &ux); if (pbTransl != NULL) *pbTransl = (n == 1); if (n != 1) return 0; return (bSigned) ? (UINT) x : ux;}UINTIsDlgButtonChecked(HWND hDlg, int id){ return SendMessage(GetDlgItem(hDlg, id), BM_GETCHECK, 0, 0);}BOOL WINAPICheckDlgButton(HWND hDlg, int id, UINT mode){ return SendMessage(GetDlgItem(hDlg, id), BM_SETCHECK, mode, 0);}BOOL WINAPICheckRadioButton(HWND hDlg, int idFirst, int idLast, int idCheck){ HWND hCheck; HWND obj; UINT dc; hCheck = GetDlgItem(hDlg, idCheck); if (hCheck == NULL) return FALSE; /* First, remove all from previuos in group. */ obj = GetNextDlgGroupItem(hDlg, hCheck, TRUE); while (obj) { if ((idFirst == -1 || (obj->id >= idFirst && obj->id <= idLast)) && (((dc = SendMessage(obj, WM_GETDLGCODE, 0, 0)) & DLGC_RADIOBUTTON) != 0)) SendMessage(obj, BM_SETCHECK, BST_UNCHECKED, 0); obj = GetNextDlgGroupItem(hDlg, obj, TRUE); } /* Remove on next */ obj = GetNextDlgGroupItem(hDlg, hCheck, FALSE); while (obj) { if ((idFirst == -1 || (obj->id >= idFirst && obj->id <= idLast)) && (((dc = SendMessage(obj, WM_GETDLGCODE, 0, 0)) & DLGC_RADIOBUTTON) != 0)) SendMessage(obj, BM_SETCHECK, BST_UNCHECKED, 0); obj = GetNextDlgGroupItem(hDlg, obj, FALSE); } SendMessage(hCheck, BM_SETCHECK, BST_CHECKED, 0); return TRUE;}/* * Return previous or next control in a dialog box group controls */HWND WINAPIGetNextDlgGroupItem(HWND hDlg, HWND hCtl, BOOL bPrevious){ HWND obj, nobj; /* Note that child list starts from last to first */ if (!bPrevious) { nobj = hCtl; for (;;) { obj = hDlg->children; while (obj) { if (obj->siblings == nobj) break; obj = obj->siblings; } if (obj == NULL) break; if ((obj->style & WS_GROUP)) return NULL; if (IsWindowEnabled(obj) && IsWindowVisible(obj) && !(SendMessage(obj, WM_GETDLGCODE, 0, 0) & DLGC_STATIC)) return obj; nobj = obj; } } else { /* the siblings ptr is the previuos control in order */ if ((hCtl->style & WS_GROUP) != 0) return NULL; obj = hCtl->siblings; while (obj) { if (IsWindowEnabled(obj) && IsWindowVisible(obj) && !(SendMessage(obj, WM_GETDLGCODE, 0, 0) & DLGC_STATIC)) return obj; else if ((obj->style & WS_GROUP)) return NULL; obj = obj->siblings; } } return NULL;}/* * Search the first button in the childrens list. */static HWNDfirstDefButton(HWND hdlg){ HWND hwnd = hdlg->children; while (hwnd) { if (hwnd->pClass && !strcasecmp(hwnd->pClass->szClassName, "BUTTON") && (hwnd->style & BS_DEFPUSHBUTTON)) return hwnd; hwnd = hwnd->siblings; } return NULL;}/* * Find the next children in the dialogbox. */static HWNDnextTabStop(HWND hDlg, HWND hChild, BOOL bPrevious){ HWND *pControls; HWND obj; UINT dlgCode; int n, i; pControls = (HWND *) malloc(256 * sizeof(HWND)); if (pControls == NULL) return NULL; bPrevious = !bPrevious; /* next ptr is previous in order list */ n = 0; i = -1; obj = hDlg->children; while (obj && (n < 256)) { if ((obj == hChild)) i = n; if ((obj->style & WS_TABSTOP) && IsWindowEnabled(obj) && IsWindowVisible(obj)) pControls[n++] = obj; obj = obj->siblings; } if (n > 0) { if (bPrevious) { if ((i == -1) || (i - 1 < 0)) obj = pControls[n - 1]; else obj = pControls[i - 1]; } else { if ((i == -1) || (i + 1 >= n)) obj = pControls[0]; else obj = pControls[i + 1]; } } free(pControls); dlgCode = SendMessage(obj, WM_GETDLGCODE, 0, 0); /* If it's a RB, find the one checked. */ if ((dlgCode & DLGC_RADIOBUTTON)) { /* Go back until found object */ HWND found = NULL; HWND sobj = hDlg->children; while (sobj && sobj != obj) { if (sobj->style & WS_GROUP) found = NULL; dlgCode = SendMessage(sobj, WM_GETDLGCODE, 0, 0); if ((dlgCode & DLGC_RADIOBUTTON) && IsDlgButtonChecked(hDlg, sobj->id) == BST_CHECKED) found = sobj; sobj = sobj->siblings; } if (found) obj = found; } return obj;}static BOOLparseAccelerator(HWND hWnd, int key){ HWND obj; obj = hWnd->children; while (obj) { int dlgCode = SendMessage(obj, WM_GETDLGCODE, 0, 0); if (IsWindowVisible(obj)) { if ((dlgCode & DLGC_STATIC) || ((dlgCode & (DLGC_BUTTON | DLGC_RADIOBUTTON)) != 0 && IsWindowEnabled(obj))) { LPCTSTR pCaption = obj->szTitle; /*FIXME: strchr don't works with WCHAR */ LPCTSTR pAccel = strchr(pCaption, '&'); while ((pAccel != NULL) && (pAccel[1] == '&')) pAccel = strchr(pCaption, '&'); if ((pAccel != NULL) && (toupper(pAccel[1]) == toupper(key))) { if ((dlgCode & (DLGC_STATIC | DLGC_RADIOBUTTON)) != 0) { obj = nextTabStop(hWnd, obj, FALSE); if (obj) PostMessage(hWnd, WM_NEXTDLGCTL, (WPARAM) obj, 1); } else PostMessage(hWnd, WM_COMMAND, obj->id, (LPARAM) obj); return TRUE; } } } obj = obj->siblings; } return FALSE;}/* * Restore focus to last control */static voiddlgRestoreCtrlFocus(HWND hWnd){ PMWDLGDATA pData; pData = DLG_PMWDLGDATA(hWnd); if (pData == NULL) return; if (pData->hWndFocus != NULL) SetFocus(pData->hWndFocus);}static voiddlgSaveCtrlFocus(HWND hWnd, HWND hFocus){ PMWDLGDATA pData; pData = DLG_PMWDLGDATA(hWnd); if (pData == NULL) return; if (!ISDLGCONTROL(hWnd, hFocus)) return; pData->hWndFocus = hFocus;}/* * Handles default dialog messages */BOOL CALLBACKDefDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam){ HWND hChild; RECT rc; switch (Msg) { case WM_COMMAND: if (wParam == IDCANCEL) EndDialog(hDlg, TRUE); return FALSE; case WM_ERASEBKGND: GetClientRect(hDlg, &rc); FastFillRect((HDC) wParam, &rc, GetSysColor(COLOR_BTNFACE)); return TRUE; case WM_CTLCOLORSTATIC: return DefWindowProc(hDlg, Msg, wParam, lParam); case WM_INITDIALOG: return TRUE; case WM_NEXTDLGCTL: if ((LOWORD(lParam) != FALSE)) { if (IsWindow((HWND) wParam)) SetFocus((HWND) wParam); } else { hChild = nextTabStop(hDlg, dlgGetCtrlFocus(hDlg), (wParam != 0)); if (hChild) SetFocus(hChild); } dlgSaveCtrlFocus(hDlg, GetFocus()); break; } return FALSE;}/* * Destroy initial font if was created. */static voiddlgDestroyInitFont(HWND hWnd, PMWDLGDATA pData){ if ((pData->flags & DLGF_DESTROYFONT) != 0) { HDC hdc = GetDC(hWnd); SelectObject(hdc, GetStockObject(DEFAULT_FONT)); DeleteObject(pData->hFnt); ReleaseDC(hWnd, hdc); pData->flags &= ~DLGF_DESTROYFONT; }}/* * Returns the name of class found in item. */static LPCSTRdlgGetItemClass(PMWDLGITEMTEMPLEXTRA pItem){ static LPCSTR defClass[] = { "BUTTON", "EDIT", "STATIC", "LISTBOX", "SCROLLBAR", "COMBOBOX" }; if ((pItem->szClassName == NULL) || (strlen(pItem->szClassName) < 2)) return ""; if ((pItem->szClassName[0] == (TCHAR) - 1)) { unsigned idx = ((unsigned char) pItem->szClassName[1]) - DLGITEM_CLASS_FIRSTID; if ((idx < (sizeof(defClass) / sizeof(defClass[0])))) return defClass[idx]; return ""; } return pItem->szClassName;}DWORDdlgItemStyle(PMWDLGITEMTEMPLATE pItem, PMWDLGITEMTEMPLEXTRA pItemExtra){ if (((pItemExtra->szClassName[0] == (TCHAR)-1) && (pItemExtra->szClassName[1] == (TCHAR) DLGITEM_CLASS_LISTBOX)) || !strcmp(pItemExtra->szClassName, "LISTBOX")) { return pItem->style & ~(LBS_CHECKBOX | LBS_USEICON | LBS_AUTOCHECK); } return pItem->style;}/* * Check if it should return a long value */static BOOLdlgReturnLValue(UINT msg){ if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) || (msg == WM_CTLCOLOR) || (msg == WM_INITDIALOG) || (msg == WM_DRAWITEM) || (msg == WM_MEASUREITEM) /*|| (msg == WM_VKEYTOITEM) || (msg == WM_CHARTOITEM) || (msg == WM_QUERYDRAGICON) ||(msg == WM_COMPAREITEM)*/ ) return FALSE; return TRUE;}/* * Handler for dialog windows
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -