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

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

📁 详细的介绍了minigui的原理及其在linux上的实现.
💻 HTM
📖 第 1 页 / 共 4 页
字号:
          <TD>其他</TD>
          <TD>可以利用 PostSyncMessage 函数跨线程发送消息,并等待消息的处理结果</TD>
          <TD>不能使用 PostSyncMessage、SendAsynMessage 
      等消息。</TD></TR></TBODY></TABLE><BR><BR>
      <P><A id=5 name=5><SPAN class=atitle2>5 窗口的建立和销毁</SPAN></A></P>
      <P><SPAN class=atitle3>5.1 窗口的建立</SPAN><BR>我们知道,MiniGUI 的 API 类似 Win32 的 
      API。因此,窗口的建立过程和 Windows 程序基本类似。不过也有一些差别。首先我们回顾一下 Windows 应用程序的框架:</P>
      <OL class=n01>
        <LI>在 WinMain () 中创建窗口,使用以下步骤:创建窗口类、登记窗口类、创建并显示窗口、启动消息循环。 
        <LI>在 WndProc () 中,负责对发到窗口中的各种消息进行响应。 </LI></OL>在 MiniGUI 
      中也同样要有这两个函数。不过稍微有点不同。程序的入口函数名字叫MiniGUIMain 
      (),它负责创建程序的主窗口。在建立主窗口之后,程序进入消息循环。<BR><BR>
      <P>在 Win32 程序中,在建立一个主窗口之前,程序首先要注册一个窗口类,然后创建一个属于该窗口类的主窗口。MiniGUI 
      却没有在主窗口中使用窗口类的概念。在 MiniGUI 程序中,首先初始化一个 MAINWINCREATE 结构,该结构中元素的含义是:</P>
      <TABLE cellSpacing=0 cellPadding=5 border=0>
        <TBODY>
        <TR>
          <TD>CreateInfo.dwStyle:</TD>
          <TD>窗口风格</TD></TR>
        <TR>
          <TD>CreateInfo.spCaption:</TD>
          <TD>窗口的标题</TD></TR>
        <TR>
          <TD>CreateInfo.dwExStyle :</TD>
          <TD>窗口的附加风格</TD></TR>
        <TR>
          <TD>CreateInfo.hMenu:</TD>
          <TD>附加在窗口上的菜单句柄</TD></TR>
        <TR>
          <TD>CreateInfo.hCursor:</TD>
          <TD>在窗口中所使用的鼠标光标句柄</TD></TR>
        <TR>
          <TD>CreateInfo.hIcon:</TD>
          <TD>程序的图标</TD></TR>
        <TR>
          <TD>CreateInfo.MainWindowProc:</TD>
          <TD>该窗口的消息处理函数指针</TD></TR>
        <TR>
          <TD>CreateInfo.lx:</TD>
          <TD>窗口左上角相对屏幕的绝对横坐标,以象素点表示</TD></TR>
        <TR>
          <TD>CreateInfo.ty:</TD>
          <TD>窗口左上角相对屏幕的绝对纵坐标,以象素点表示</TD></TR>
        <TR>
          <TD>CreateInfo.rx:</TD>
          <TD>窗口的长,以象素点表示</TD></TR>
        <TR>
          <TD>CreateInfo.by:</TD>
          <TD>窗口的高,以象素点表示</TD></TR>
        <TR>
          <TD>CreateInfo.iBkColor:</TD>
          <TD>窗口背景颜色</TD></TR>
        <TR>
          <TD>CreateInfo.dwAddData:</TD>
          <TD>附带给窗口的一个 32 位值</TD></TR>
        <TR>
          <TD>CreateInfo.hHosting:</TD>
          <TD>窗口消息队列所属</TD></TR></TBODY></TABLE><BR><BR>
      <P>其中有如下几点要特别说明:</P>
      <OL class=n01>
        <LI>CreateInfo.dwAddData:在程序编制过程中,应该尽量减少静态变量,但是如何不使用静态变量而给窗口传递参数呢?这时可以使用这个域。该域是一个 
        32 位的值,因此可以把所有需要传递给窗口的参数编制成一个结构,而将结构的指针赋予该域。在窗口过程中,可以使用 
        GetWindowAdditionalData 函数获取该指针,从而获得所需要传递的参数。 
        <LI>CreateInfo.hHosting:该域表示的是将要建立的主窗口使用哪个主窗口的消息队列。使用其他主窗口消息队列的主窗口,我们称为"被托管"的主窗口。当然,这只在 
        MiniGUI-Threads 版本中有效。 
        <LI>MainWinProc 
        函数负责处理窗口消息。这个函数就是主窗口的"窗口过程"。窗口过程一般有四个入口参数,第一个是窗口句柄,第二个是消息类型,第三个和第四个是消息的两个参数。 
        </LI></OL><BR><BR>
      <P>在准备好MAINWINCREATE 结构之后,就可以调用 CreateMainWindow 
      函数建立主窗口了。在建立主窗口之后,典型的程序将进入消息循环。如下所示:</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>int MiniGUIMain (int args, const char* arg[])
{
    MSG Msg;
    MAINWINCREATE CreateInfo;
    HWND hWnd;

    // 初始化 MAINWINCREATE 结构
    CreateInfo.dwStyle = WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | WS_CAPTION;
    CreateInfo.spCaption= "MiniGUI step three";
    CreateInfo.dwExStyle = WS_EX_NONE;
    CreateInfo.hMenu = createmenu();
    CreateInfo.hCursor = GetSystemCursor(0);
    CreateInfo.hIcon = 0;
    CreateInfo.MainWindowProc = MainWinProc;
    CreateInfo.lx = 0;
    CreateInfo.ty = 0;
    CreateInfo.rx = 640;
    CreateInfo.by = 480;
    CreateInfo.iBkColor = COLOR_lightwhite;
    CreateInfo.dwAddData = 0;
    CreateInfo.hHosting = HWND_DESKTOP;

    // 建立主窗口
    hWnd = CreateMainWindow(&amp;CreateInfo);
    if (hWnd == HWND_INVALID)
        return 0;

    // 显示主窗口
    ShowWindow (hWnd, SW_SHOWNORMAL);

    //  进入消息循环
    while (GetMessage(&amp;Msg, hWnd)) {
        TranslateMessage (&amp;Msg);
        DispatchMessage(&amp;Msg);
    }

    MainWindowThreadCleanup (hWnd);
    return 0;
}
</CODE>
</PRE></TD></TR></TBODY></TABLE>注意,和 Windows 程序不同的是,在退出消息循环之后,还要调用一个函数,即 
      MainWindowThreadCleaup 函数。该函数的工作是销毁主窗口的消息队列,一般在线程或者进程的最后调用。<BR><BR>
      <P><SPAN class=atitle3>5.2 窗口的销毁</SPAN><BR>要销毁一个主窗口,可以利用 DestroyMainWindow 
      (hWnd) 函数。该函数将销毁主窗口,但不会销毁主窗口所使用的消息队列,而要使用MainWindowThreadCleaup 
      最终清除主窗口所使用的消息队列。</P>
      <P>一般而言,一个主窗口过程在接收到 MSG_CLOSE 消息之后会销毁主窗口,并调用 PostQuitMessage 
      消息终止消息循环。如下所示:</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>case MSG_CLOSE:
    // 销毁窗口使用的资源
    DestroyLogFont (logfont1);
    DestroyLogFont (logfont2);
    DestroyLogFont (logfont3);
    
    // 销毁子窗口
    DestroyWindow(hWndButton);
    DestroyWindow(hWndEdit);
    // 销毁主窗口
    DestroyMainWindow (hWnd);
    // 发送 MSG_QUIT 消息
    PostQuitMessage(hWnd);
    return 0;
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
      <P><A id=6 name=6><SPAN class=atitle2>6 
      几个重要消息</SPAN></A><BR>在窗口(包括主窗口和子窗口在内)的生存周期当中,有几个重要的消息需要仔细处理。下面描述这些消息的概念和典型处理。</P>
      <P><SPAN class=atitle3>6.1 MSG_NCCREATE</SPAN><BR>该消息在 MiniGUI 
      建立主窗口的过程中发送到窗口过程。lParam 中包含了由 CreateMainWindow 传递进入的 pCreateInfo 
      结构指针。您可以在该消息的处理过程中修改 pCreateInfo 结构中的某些值。</P>
      <P><SPAN class=atitle3>6.2 
      MSG_SIZECHANGING</SPAN><BR>该消息窗口尺寸发生变化时,或者建立窗口时发送到窗口过程,用来确定窗口大小。wParam 
      包含预期的窗口尺寸值,而 lParam 用来保存结果值。MiniGUI 的默认处理是,</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>case MSG_SIZECHANGING:
    memcpy ((PRECT)lParam, (PRECT)wParam, sizeof (RECT));
    return 0;
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
      <P>你可以截获该消息的处理,从而让即将创建的窗口位于指定的位置,或者具有固定的大小,比如在 SPINBOX 
      控件中,就处理了该消息,使之具有固定的大小:</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>case MSG_SIZECHANGING:
{
    const RECT* rcExpect = (const RECT*) wParam;
    RECT* rcResult = (RECT*) lPraram;

    rcResult-&gt;left = rcExpect-&gt;left;
    rcResult-&gt;top = rcExpect-&gt;top;
    rcResult-&gt;right = rcExpect-&gt;left +  _WIDTH;
    rcResult-&gt;bottom = rcExpect-&gt;left +  _HEIGHT;
    return 0;
}
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
      <P><SPAN class=atitle3>6.3 
      MSG_CHANGESIZE</SPAN><BR>在确立窗口大小之后,该消息被发送到窗口过程,用来通知确定之后的窗口大小。wParam 
      包含了窗口大小 RECT 的指针。注意应用程序应该将该消息传递给 MiniGUI 进行默认处理。</P>
      <P><SPAN class=atitle3>6.4 MSG_SIZECHANGED</SPAN><BR>该消息用来确定窗口客户区的大小,和 
      MSG_SIZECHANGING 消息类似。wParam 参数包含窗口大小信息,lParam 参数是用来保存窗口客户区大小的 RECT 
      指针,并且具有默认值。如果该消息的处理返回非零值,则将采用 lParam 当中包含的大小值作为客户区的大小;否则,将忽略该消息的处理。比如在 
      SPINBOX 控件中,就处理了该消息,并使客户区占具所有的窗口范围:</P>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>case MSG_SIZECHANGED
{
    RECT* rcClient = (RECT*) lPraram;

    rcClient-&gt;right = rcClient-&gt;left  +  _WIDTH;
    rcClient-&gt;bottom = rcClient-&gt;top +  _HEIGHT;
    return 0;
}
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>

⌨️ 快捷键说明

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