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

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

📁 Programming Embedded Systems in C and C
💻 HTM
📖 第 1 页 / 共 3 页
字号:
            MiniGUI-Threads 
            当中,如果发送消息的线程和接收消息的线程不是同一个线程,发送消息的线程将阻塞并等待另一个线程的处理结果,然后继续运行;否则,SendMessage 
            函数将直接调用接收消息窗口的窗口过程函数。MiniGUI-Lite 
            则和上面的第二种情况一样,直接调用接收消息窗口的窗口过程函数。&nbsp;</P>
            <P>&nbsp;&nbsp;&nbsp; <B>SendNotifyMessage:</B>该函数和 PostMessage 
            消息类似,也是不等待消息被处理即返回。但和 PostMessage 
            消息不同,通过该函数发送的消息不会因为缓冲区满而丢失,因为系统采用链表的形式处理这种消息。通过该函数发送的消息一般称为"通知消息",一般用来从控件向其父窗口发送通知消息。&nbsp;</P>
            <P>&nbsp;&nbsp;&nbsp; <B>PostQuitMessage:</B>该消息在消息队列中设置一个 QS_QUIT 
            标志。GetMessage 在从指定消息队列中获取消息时,会检查该标志,如果有 QS_QUIT 标志,GetMessage 消息将返回 
            FALSE,从而可以利用该返回值终止消息循环。&nbsp;</P>
            <P><B>4 MiniGUI-Threads 和 MiniGUI-Lite 
            在消息处理上的不同&nbsp;<BR></B>&nbsp;&nbsp;&nbsp; 表 1 总结了 MiniGUI-Threads 和 
            MiniGUI-Lite 在消息处理上的不同</P>
            <P>&nbsp;&nbsp;&nbsp; 表 1 MiniGUI-Threads 和 MiniGUI-Lite 
            在消息处理上的不同&nbsp;</P>
            <TABLE>
              <TBODY>
              <TR>
                <TD></TD>
                <TD>MiniGUI-Threads</TD>
                <TD>MiniGUI-Lite</TD></TR>
              <TR>
                <TD>多消息队列</TD>
                <TD>每个创建窗口的线程拥有独立的消息队列</TD>
                <TD>只有一个消息队列。所有窗口共享一个消息队列。除非嵌套消息循环,否则一个程序中只有一个消息循环。</TD></TR>
              <TR>
                <TD>内建多线程处理</TD>
                <TD>是。可以自动处理跨线程的消息传递</TD>
                <TD>不能。从一个线程向另外一个线程发送或者邮寄消息时,必须通过互斥处理保护消息队列。</TD></TR>
              <TR>
                <TD>其他</TD>
                <TD>可以利用 PostSyncMessage 函数跨线程发送消息,并等待消息的处理结果</TD>
                <TD>不能使用 PostSyncMessage、SendAsynMessage</TD></TR></TBODY></TABLE>
            <P><B>5 窗口的建立和销毁</B></P>
            <P><B>5.1 窗口的建立<BR></B>&nbsp;&nbsp;&nbsp; 我们知道,MiniGUI 的 API 类似 
            Win32 的 API。因此,窗口的建立过程和 Windows 程序基本类似。不过也有一些差别。首先我们回顾一下 Windows 
            应用程序的框架:&nbsp;</P>
            <P>&nbsp;&nbsp;&nbsp; 在 WinMain () 
            中创建窗口,使用以下步骤:创建窗口类、登记窗口类、创建并显示窗口、启动消息循环。&nbsp;</P>
            <P>&nbsp;&nbsp;&nbsp; 在 WndProc () 中,负责对发到窗口中的各种消息进行响应。<BR>在 MiniGUI 
            中也同样要有这两个函数。不过稍微有点不同。程序的入口函数名字叫MiniGUIMain 
            (),它负责创建程序的主窗口。在建立主窗口之后,程序进入消息循环。</P>
            <P>&nbsp;&nbsp;&nbsp; 在 Win32 
            程序中,在建立一个主窗口之前,程序首先要注册一个窗口类,然后创建一个属于该窗口类的主窗口。MiniGUI 
            却没有在主窗口中使用窗口类的概念。在 MiniGUI 程序中,首先初始化一个 MAINWINCREATE 
            结构,该结构中元素的含义是:</P>
            <P>&nbsp;CreateInfo.dwStyle: 窗口风格&nbsp;<BR>CreateInfo.spCaption: 
            窗口的标题&nbsp;<BR>CreateInfo.dwExStyle : 
            窗口的附加风格&nbsp;<BR>CreateInfo.hMenu: 
            附加在窗口上的菜单句柄&nbsp;<BR>CreateInfo.hCursor: 
            在窗口中所使用的鼠标光标句柄&nbsp;<BR>CreateInfo.hIcon: 
            程序的图标&nbsp;<BR>CreateInfo.MainWindowProc: 
            该窗口的消息处理函数指针&nbsp;<BR>CreateInfo.lx: 
            窗口左上角相对屏幕的绝对横坐标,以象素点表示&nbsp;<BR>CreateInfo.ty: 
            窗口左上角相对屏幕的绝对纵坐标,以象素点表示&nbsp;<BR>CreateInfo.rx: 
            窗口的长,以象素点表示&nbsp;<BR>CreateInfo.by: 
            窗口的高,以象素点表示&nbsp;<BR>CreateInfo.iBkColor: 
            窗口背景颜色&nbsp;<BR>CreateInfo.dwAddData: 附带给窗口的一个 32 
            位值&nbsp;<BR>CreateInfo.hHosting: 窗口消息队列所属&nbsp;</P>
            <P>其中有如下几点要特别说明:&nbsp;</P>
            <OL>
              <LI>CreateInfo.dwAddData:在程序编制过程中,应该尽量减少静态变量,但是如何不使用静态变量而给窗口传递参数呢?这时可以使用这个域。该域是一个 
              32 位的值,因此可以把所有需要传递给窗口的参数编制成一个结构,而将结构的指针赋予该域。在窗口过程中,可以使用 
              GetWindowAdditionalData 函数获取该指针,从而获得所需要传递的参数。 
              <LI>CreateInfo.hHosting:该域表示的是将要建立的主窗口使用哪个主窗口的消息队列。使用其他主窗口消息队列的主窗口,我们称为"被托管"的主窗口。当然,这只在 
              MiniGUI-Threads 版本中有效。&nbsp; 
              <LI>MainWinProc 
              函数负责处理窗口消息。这个函数就是主窗口的"窗口过程"。窗口过程一般有四个入口参数,第一个是窗口句柄,第二个是消息类型,第三个和第四个是消息的两个参数。 
              </LI></OL>
            <P>&nbsp;&nbsp;&nbsp; 在准备好MAINWINCREATE 结构之后,就可以调用 CreateMainWindow 
            函数建立主窗口了。在建立主窗口之后,典型的程序将进入消息循环。如下所示:&nbsp;</P>
            <DIV align=center>
            <TABLE cellSpacing=1 width="90%" border=0>
              <TBODY>
              <TR>
                <TD width="100%" bgColor=#c0c0c0>int MiniGUIMain (int args, 
                  const char* arg[])<BR>{<BR>MSG Msg;<BR>MAINWINCREATE 
                  CreateInfo;<BR>HWND hWnd;<BR><BR>// 初始化 MAINWINCREATE 
                  结构<BR>CreateInfo.dwStyle = WS_VISIBLE | WS_VSCROLL | 
                  WS_HSCROLL | WS_CAPTION;<BR>CreateInfo.spCaption= "MiniGUI 
                  step three";<BR>CreateInfo.dwExStyle = 
                  WS_EX_NONE;<BR>CreateInfo.hMenu = 
                  createmenu();<BR>CreateInfo.hCursor = 
                  GetSystemCursor(0);<BR>CreateInfo.hIcon = 
                  0;<BR>CreateInfo.MainWindowProc = 
                  MainWinProc;<BR>CreateInfo.lx = 0;<BR>CreateInfo.ty = 
                  0;<BR>CreateInfo.rx = 640;<BR>CreateInfo.by = 
                  480;<BR>CreateInfo.iBkColor = 
                  COLOR_lightwhite;<BR>CreateInfo.dwAddData = 
                  0;<BR>CreateInfo.hHosting = HWND_DESKTOP;<BR><BR>// 
                  建立主窗口<BR>hWnd = CreateMainWindow(&amp;CreateInfo);<BR>if (hWnd 
                  == HWND_INVALID)<BR>return 0;<BR><BR>// 显示主窗口<BR>ShowWindow 
                  (hWnd, SW_SHOWNORMAL);<BR><BR>// 进入消息循环<BR>while 
                  (GetMessage(&amp;Msg, hWnd)) {<BR>TranslateMessage 
                  (&amp;Msg);<BR>DispatchMessage(&amp;Msg);<BR>}<BR><BR>MainWindowThreadCleanup 
                  (hWnd);<BR>return 0;<BR>}</TD></TR></TBODY></TABLE></DIV>
            <P>&nbsp;&nbsp;&nbsp; 注意,和 Windows 程序不同的是,在退出消息循环之后,还要调用一个函数,即 
            MainWindowThreadCleaup 函数。该函数的工作是销毁主窗口的消息队列,一般在线程或者进程的最后调用。</P>
            <P><B>5.2 窗口的销毁&nbsp;<BR></B>&nbsp;&nbsp;&nbsp; 要销毁一个主窗口,可以利用 
            DestroyMainWindow (hWnd) 
            函数。该函数将销毁主窗口,但不会销毁主窗口所使用的消息队列,而要使用MainWindowThreadCleaup 
            最终清除主窗口所使用的消息队列。</P>
            <P>&nbsp;&nbsp;&nbsp; 一般而言,一个主窗口过程在接收到 MSG_CLOSE 消息之后会销毁主窗口,并调用 
            PostQuitMessage 消息终止消息循环。如下所示:&nbsp;</P>
            <DIV align=center>
            <TABLE cellSpacing=1 width="90%" border=0>
              <TBODY>
              <TR>
                <TD width="100%" bgColor=#c0c0c0>case MSG_CLOSE:<BR>// 
                  销毁窗口使用的资源<BR>DestroyLogFont (logfont1);<BR>DestroyLogFont 
                  (logfont2);<BR>DestroyLogFont (logfont3);<BR><BR>// 
                  销毁子窗口<BR>DestroyWindow(hWndButton);<BR>DestroyWindow(hWndEdit);<BR>// 
                  销毁主窗口<BR>DestroyMainWindow (hWnd);<BR>// 发送 MSG_QUIT 
                  消息<BR>PostQuitMessage(hWnd);<BR>return 
            0;</TD></TR></TBODY></TABLE></DIV>
            <P><B>6 几个重要消息&nbsp;<BR></B>&nbsp;&nbsp;&nbsp; 
            在窗口(包括主窗口和子窗口在内)的生存周期当中,有几个重要的消息需要仔细处理。下面描述这些消息的概念和典型处理。<BR><BR><B>6.1 
            MSG_NCCREATE&nbsp;<BR></B>&nbsp;&nbsp;&nbsp; 该消息在 MiniGUI 
            建立主窗口的过程中发送到窗口过程。lParam 中包含了由 CreateMainWindow 传递进入的 pCreateInfo 
            结构指针。您可以在该消息的处理过程中修改 pCreateInfo 结构中的某些值。</P>
            <P><B>6.2 MSG_SIZECHANGING&nbsp;<BR></B>&nbsp;&nbsp;&nbsp; 
            该消息窗口尺寸发生变化时,或者建立窗口时发送到窗口过程,用来确定窗口大小。wParam 包含预期的窗口尺寸值,而 lParam 
            用来保存结果值。MiniGUI 的默认处理是,&nbsp;</P>
            <DIV align=center>
            <TABLE cellSpacing=1 width="90%" border=0>
              <TBODY>
              <TR>
                <TD width="100%" bgColor=#c0c0c0>case 
                  MSG_SIZECHANGING:<BR>memcpy ((PRECT)lParam, (PRECT)wParam, 
                  sizeof (RECT));<BR>return 0;</TD></TR></TBODY></TABLE></DIV>
            <P>&nbsp;&nbsp;&nbsp; 你可以截获该消息的处理,从而让即将创建的窗口位于指定的位置,或者具有固定的大小,比如在 
            SPINBOX 控件中,就处理了该消息,使之具有固定的大小:&nbsp;</P>
            <DIV align=center>
            <TABLE cellSpacing=1 width="90%" border=0>
              <TBODY>
              <TR>
                <TD width="100%" bgColor=#c0c0c0>case 
                  MSG_SIZECHANGING:<BR>{<BR>const RECT* rcExpect = (const RECT*) 

⌨️ 快捷键说明

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