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

📄 基于 linux 和 minigui 的嵌入式系统软件开发指南(三).htm

📁 详细的介绍了minigui的原理及其在linux上的实现.
💻 HTM
📖 第 1 页 / 共 4 页
字号:
                                        "This is child static control", 
                                        WS_CHILD | SS_NOTIFY | SS_SIMPLE | WS_VISIBLE | WS_BORDER,
                                        IDC_STATIC1, 
                                        20, 110, 100, 50, hStaticWnd1, 0);
            hEdit2      = CreateWindow (CTRL_EDIT,
                                        "Edit Box 2", 
                                        WS_CHILD | WS_VISIBLE | WS_BORDER, 
                                        IDC_EDIT2, 
                                        0, 20, 100, 24, hStaticWnd2, 0);
           break;
          }
.......
    }
    return DefaultMainWinProc (hWnd, message, wParam, lParam);
}
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
      <P>用户也可以通过 RegisterWindowClass 
      函数注册自己的控件类,并建立该控件类的控件实例。如果程序不再使用某个自定义的控件类,则应该使用 UnregisterWindowClass 
      函数注销自定义的控件类。上述两个函数以及和窗口类相关函数的原型如下(include/window.h):</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>897 BOOL GUIAPI RegisterWindowClass (PWNDCLASS pWndClass);
 898 BOOL GUIAPI UnregisterWindowClass (const char* szClassName);
 899 char* GUIAPI GetClassName (HWND hWnd);
 900 BOOL GUIAPI GetWindowClassInfo (PWNDCLASS pWndClass);
 901 BOOL GUIAPI SetWindowClassInfo (const WNDCLASS* pWndClass);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
      <P>RegisterWindowClass 通过 pWndClass 结构注册一个控件类;UnregisterWindowClass 
      函数则注销指定的控件类;GetClassName 
      活得窗口的对应窗口类名称,对主窗口而言,窗口类名称为"MAINWINDOW";GetWindowClassInfo 
      分别用来获取和指定特定窗口类的属性。</P>
      <P>清单 2 中的程序,定义并注册了一个自己的控件类。该控件用来显示安装程序的步骤信息,MSG_SET_STEP_INFO 
      消息用来定义该控件中显示的所有步骤信息,包括所有步骤名称及其简单描述。MSG_SET_CURR_STEP 
      消息用来指定当前步骤,控件将高亮显示当前步骤。</P>
      <P>清单2 定义并注册自定义控件类</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>#define STEP_CTRL_NAME "mystep"
#define MSG_SET_STEP_INFO   (MSG_USER + 1)
#define MSG_SET_CURR_STEP   (MSG_USER + 2)
static int StepControlProc (HWND hwnd, 
                int message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    HELPWININFO* info;
    
    switch (message) {
    case MSG_PAINT:
        hdc = BeginPaint (hwnd);
        /* 获取步骤控件信息 */
        info = (HELPWININFO*)GetWindowAdditionalData (hwnd);
        /* 绘制步骤内容 */
        ......
        EndPaint (hwnd, hdc);
        break;
    /* 控件自定义的消息:用来设置步骤信息 */
    case MSG_SET_STEP_INFO:
        SetWindowAdditionalData (hwnd, (DWORD)lParam);
        InvalidateRect (hwnd, NULL, TRUE);
        break;
    /* 控件自定义的消息:用来设置当前步骤信息 */
    case MSG_SET_CURR_STEP:
        InvalidateRect (hwnd, NULL, FALSE);
        break;
    case MSG_DESTROY:
        break;
    }
    return DefaultControlProc (hwnd, message, wParam, lParam);
}
static BOOL RegisterStepControl ()
{
    int result;
    WNDCLASS StepClass;
    StepClass.spClassName = STEP_CTRL_NAME;
    StepClass.dwStyle     = 0;
    StepClass.hCursor     = GetSystemCursor (IDC_ARROW);
    StepClass.iBkColor    = COLOR_lightwhite;
    StepClass.WinProc     = StepControlProc;
    return RegisterWindowClass (&amp;StepClass);
}
static void UnregisterStepControl ()
{
    UnregisterWindowClass (STEP_CTRL_NAME);
}
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
      <P><A id=3 name=3><SPAN class=atitle2>3 
      控件子类化</SPAN></A><BR>采用控件类和控件实例的结构,不仅可以提高代码的可重用性,而且还可以方便地对已有控件类进行扩展。比如,在需要建立一个只允许输入数字的编辑框时,就可以通过重载已有编辑框控件类而实现,而不需要重新编写一个新的控件类。在 
      MiniGUI 中,这种技术称为子类化或者窗口派生。子类化的方法有三种:</P>
      <OL class=n01>
        <LI>一种是对已经建立的控件实例进行子类化,子类化的结果是只影响这一个控件实例; 
        <LI>一种是对某个控件类进行子类化,将影响其后创建的所有该控件类的控件实例; 
        <LI>最后一种是在某个控件类的基础上新注册一个子类化的控件类,不会影响原有控件类。在 Windows 中,这种技术又称为超类化。 
      </LI></OL>
      <P>在 MiniGUI 中,控件的子类化实际是通过替换已有的窗口过程实现的。清单 3 
      中的代码就通过控件类创建了两个子类化的编辑框,一个只能输入数字,而另一个只能输入字母:</P>
      <P>清单 3 控件的子类化</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>#define IDC_CTRL1     100
#define IDC_CTRL2     110
#define IDC_CTRL3     120
#define IDC_CTRL4     130
#define MY_ES_DIGIT_ONLY    0x0001
#define MY_ES_ALPHA_ONLY    0x0002
static WNDPROC old_edit_proc;
static int RestrictedEditBox (HWND hwnd, int message, WPARAM wParam, LPARAM lParam)
{
    if (message == MSG_CHAR) {
        DWORD my_style = GetWindowAdditionalData (hwnd);
        /* 确定被屏蔽的按键类型 */
        if ((my_style &amp; MY_ES_DIGIT_ONLY) &amp;&amp; (wParam &lt; '0' || wParam &gt; '9'))
            return 0;
        else if (my_style &amp; MY_ES_ALPHA_ONLY)
            if (!((wParam &gt;= 'A' &amp;&amp; wParam &lt;= 'Z') || (wParam &gt;= 'a' &amp;&amp; wParam &lt;= 'z')))
                /* 收到被屏蔽的按键消息,直接返回 */
                return 0;
    }
    /* 由老的窗口过程处理其余消息 */
    return (*old_edit_proc) (hwnd, message, wParam, lParam);
}
static int ControlTestWinProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
    switch (message) {
    case MSG_CREATE:
    {
        HWND hWnd1, hWnd2, hWnd3;
        CreateWindow (CTRL_STATIC, "Digit-only box:", WS_CHILD | WS_VISIBLE | SS_RIGHT, 0, 
                    10, 10, 180, 24, hWnd, 0);
        hWnd1 = CreateWindow (CTRL_EDIT, "", WS_CHILD | WS_VISIBLE | WS_BORDER, IDC_CTRL1, 
                    200, 10, 180, 24, hWnd, MY_ES_DIGIT_ONLY);
        CreateWindow (CTRL_STATIC, "Alpha-only box:", WS_CHILD | WS_VISIBLE | SS_RIGHT, 0, 
                    10, 40, 180, 24, hWnd, 0);
        hWnd2 = CreateWindow (CTRL_EDIT, "", WS_CHILD | WS_BORDER | WS_VISIBLE, IDC_CTRL2, 
                    200, 40, 180, 24, hWnd, MY_ES_ALPHA_ONLY);
        CreateWindow (CTRL_STATIC, "Normal edit box:", WS_CHILD | WS_VISIBLE | SS_RIGHT, 0, 
                    10, 70, 180, 24, hWnd, 0);
        hWnd3 = CreateWindow (CTRL_EDIT, "", WS_CHILD | WS_BORDER | WS_VISIBLE, IDC_CTRL2, 
                    200, 70, 180, 24, hWnd, MY_ES_ALPHA_ONLY);
        CreateWindow ("button", "Close", WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, IDC_CTRL4, 
                    100, 100, 60, 24, hWnd, 0);
        /* 用自定义的窗口过程替换编辑框的窗口过程,并保存老的窗口过程。*/
        old_edit_proc = SetWindowCallbackProc (hWnd1, RestrictedEditBox);
        SetWindowCallbackProc (hWnd2, RestrictedEditBox);
        break;
    }
    ......
    }
    return DefaultMainWinProc (hWnd, message, wParam, lParam);
}
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
      <P><A id=4 name=4><SPAN class=atitle2>4 对话框和对话框模板</SPAN></A><BR>在 MiniGUI 
      中,对话框是一类特殊的主窗口,这种主窗口只关注与用户的交互――向用户提供输出信息,但更多的是用于用户输入。对话框可以理解为子类化之后的主窗口类。它针对对话框的特殊性(即用户交互)进行了特殊设计。比如用户可以使用 
      TAB 键遍历控件、可以利用 ENTER 键表示默认输入等等。在 MiniGUI 
      当中,在建立对话框之前,首先需要定义一个对话框模板,该模板中定义了对话框本身的一些属性,比如位置和大小等等,同时定义了对话框中所有控件的初始信息,包括位置、大小、风格等等。在 
      MiniGUI 中,用两个结构来表示对话框模板(src/window.h):</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>1172 typedef struct
1173 {
1174     char*       class_name;             // control class
1175     DWORD       dwStyle;                // control style
1176     int         x, y, w, h;             // control position in dialog
1177     int         id;                     // control identifier
1178     const char* caption;                // control caption
1179     DWORD       dwAddData;              // additional data
1180 
1181     DWORD       dwExStyle;              // control extended style
1182 } CTRLDATA;
1183 typedef CTRLDATA* PCTRLDATA;
1184 
1185 typedef struct
1186 {
1187     DWORD       dwStyle;                // dialog box style
1188     DWORD       dwExStyle;              // dialog box extended style
1189     int         x, y, w, h;             // dialog box position
1190     const char* caption;                // dialog box caption
1191     HICON       hIcon;                  // dialog box icon
1192     HMENU       hMenu;                  // dialog box menu
1193     int         controlnr;              // number of controls
1194     PCTRLDATA   controls;               // poiter to control array
1195     DWORD       dwAddData;              // addtional data, must be zero
1196 } DLGTEMPLATE;
1197 typedef DLGTEMPLATE* PDLGTEMPLATE;
1198 
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
      <P>结构 CTRLDATA 用来定义控件,DLGTEMPLATE 用来定义对话框本身。在程序中,应该首先利用 CTRLDATA 
      定义对话框中所有的控件,并用数组表示。控件在该数组中的顺序,也就是对话框中用户按 TAB 
      键时的控件切换顺序。然后定义对话框,指定对话框中的控件数目,并指定 DLGTEMPLATE 结构中的 controls 
      指针指向定义控件的数组。如清单 4 所示。</P>
      <P>清单 4 对话框模板的定义</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>DLGTEMPLATE DlgInitProgress =
{
    WS_BORDER | WS_CAPTION, 
    WS_EX_NONE,
    120, 150, 400, 130, 
    "VAM-CNC 正在进行初始化,
    0, 0,
    3, NULL,
    0
};

CTRLDATA CtrlInitProgress [] =
{ 
    {
        "static",
        WS_VISIBLE | SS_SIMPLE,
        10, 10, 380, 16, 
        IDC_PROMPTINFO, 
        "正在...",

⌨️ 快捷键说明

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