一、什么是事件驱动编程:

MinGUI是一个图形用户界面支持系统。通常的GUI编程概念均适用于MiniGUI编程。

二、焦点和光标:

焦点和光标的概念用于管理输入设备和输入事件的传送。鼠标光标是一个绘制在屏幕上的小位图,指示当前的鼠标位置,应用程序可以绘制哪一个位图以及是否显示光标。应用程序还可以捕捉光标并获取光标事件。

三、MINIGUI的三种运行模式

① MiniGUI-Threads,运行在MiniGUI-Threads上的程序可以在不同的线程中建立多个窗口,但是所有窗口在一个进程或者地址空间中运行。

②MiniGUI-Process。MiniGUI-Process上的每个程序是独立的进程,每个进程也可以建立多个窗口,这种模式适用于具有完整UNIX特性的嵌入式操作系统。

③MiniGUI-Standalone。这种模式下,MiniGUI可以以独立进程的方式运行,不需要多线程,这种模式适合功能单一的场合

MiniGUI-Standalone模式适应面最广,几乎支持所有操作系统。

四、MiniGUI-Lite

Lite模式下,的MiniGui使用嵌入式的linux的进程机制,使得MiniGui更稳定,能充分利用类似地址控件保护的高级性能。我们可以在MiniGui-Lite模式下运行多个MiniGui客户进程,当其中一个进程不正常终止,其他进程将不受影响。

MiniGui-Lite模式下,客户端创建的窗口不是一个全局对象。

五、helloworld程序

#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>static LRESULT HelloWinProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{HDC hdc;switch (message) {case MSG_PAINT:hdc = BeginPaint (hWnd);TextOut (hdc, 60, 60, "Hello, world!");EndPaint (hWnd, hdc);return 0;case MSG_CLOSE:DestroyMainWindow (hWnd);PostQuitMessage (hWnd);return 0;}return DefaultMainWinProc (hWnd, message, wParam, lParam);
}int MiniGUIMain (int argc, const char* argv[])
{MSG Msg;HWND hMainWnd;MAINWINCREATE CreateInfo;#ifdef _MGRM_PROCESSESJoinLayer (NAME_DEF_LAYER , "helloworld" , 0 , 0);
#endifCreateInfo.dwStyle = WS_VISIBLE | WS_BORDER | WS_CAPTION;CreateInfo.dwExStyle = WS_EX_NONE;CreateInfo.spCaption = "Hello, world!";CreateInfo.hMenu = 0;CreateInfo.hCursor = GetSystemCursor (0);CreateInfo.hIcon = 0;CreateInfo.MainWindowProc = HelloWinProc;CreateInfo.lx = 0;CreateInfo.ty = 0;CreateInfo.rx = 240;CreateInfo.by = 180;CreateInfo.iBkColor = COLOR_lightwhite;CreateInfo.dwAddData = 0;CreateInfo.hHosting = HWND_DESKTOP;hMainWnd = CreateMainWindow (&CreateInfo);if (hMainWnd == HWND_INVALID)return -1;ShowWindow (hMainWnd, SW_SHOWNORMAL);while (GetMessage (&Msg, hMainWnd)) {TranslateMessage (&Msg);DispatchMessage (&Msg);}MainWindowThreadCleanup (hMainWnd);return 0;
}#ifndef _MGRM_PROCESSES
#include <minigui/dti.c>
#endif

程序创建一个大小为 320x240 像素的应用程序窗口,并显示“Hello world!” 在窗口客户区的中心。

所有MiniGUI都必须包含的四个头文件M<minigui/common.h>,<minigui/minigui.h>,<minigui/gdi.h>,和<minigui/window.h>、<control.h>

  • common.h: 包括 MiniGUI 中常用的宏和数据类型的定义。
  • minigui.h:包括全局和通用接口函数和一些杂项函数的定义。
  • gdi.h:包括MiniGUI图形功能的接口定义。
  • window.h: 包括宏、数据类型、数据结构的定义,这些都与窗口和函数接口的声明有关。

使用预定义控件的 MiniGUI 应用程序必须包含另一个头文件 -- minigui/control.h

  • control.h:包括minigui库中所有内置控件的接口定义。

C 程序的入口是主程序,而 MiniGUI 程序的入口是MiniGUIMain,程序原型如下:

int  MiniGUIMain ( int argc, const  char * argv[]);

该函数是mainANSI C 的(入口函数)封装的宏。所以每个MiniGUI 应用程序(无论是服务器功能mginit还是客户端应用程序)的入口 都是该MiniGUIMain函数。和的参数 argc与C程序中函数的argv含义相同main,分别是命令行参数的个数和指向参数的字符串数组指针。

在 MiniGUI-Processes 中加入一个层

# ifdef _MGRM_PROCESSESJoinLayer (NAME_DEF_LAYER, " helloworld " , 0 , 0 );
#ENDIF

JoinLayer是 MiniGUI-Processes 的一个特殊功能,因此包含在_MGRM_PROCESSES. 在 MiniGUI-Processes 运行模式下,每个 MiniGUI 客户端程序在调用其他 MiniGUI 函数之前,必须先调用该函数加入一个层(或创建一个新层)。

如果程序是 MiniGUI-Processes 的服务器,你应该调用 ServerStartup

if (!ServerStartup ( 0 , 0 , 0 )) {fprintf (stderr, "无法启动 MiniGUI-Processes 的服务器: mginit. \n " );返回 1 ;
}

注意MiniGUI 为三种运行模式定义了不同的宏:

  • MiniGUI 线程:_MGRM_THREADS;
  • MiniGUI-Processes:_MGRM_PROCESSES_LITE_VERSION;
  • MiniGUI-Standalone: _MGRM_STANDALONE_LITE_VERSION, 和_STAND_ALONE.

创建和显示主窗口

    hMainWnd = CreateMainWindow (&CreateInfo);

每个 MiniGUI 应用程序的初始用户界面通常是一个主窗口;您可以通过调用CreateMainWindow函数创建一个主窗口。CreateMainWindow函数的参数是一个指向MAINWINCREATE 结构体的指针,CreatInfo在这个例子中就是这个结构体,返回值是创建的主窗口的句柄。MAINWINCREAT结构体描述了主窗口的属性,在CreatInfo创建主窗口之前需要设置其属性。

    CreateInfo.dwStyle = WS_VISIBLE | WS_BORDER | WS_CAPTION;

上面的语句设置了主窗口的样式,这里的窗口设置为初始可见,并有边框和标题栏。

    CreateInfo.dwExStyle = WS_EX_NONE;

以上语句设置了主窗口的扩展样式,窗口没有扩展样式。

    CreateInfo.spCaption = "Hello, world!" ;

该语句将主窗口的标题设置为“Hello, world!”。

  CreateInfo.hMenu = 0 ;
该语句设置主窗口的主菜单,窗口没有主菜单。
    CreateInfo.hCursor = GetSystemCursor ( 0 );

该语句设置主窗口的光标,该窗口的光标是默认的系统光标。

    CreateInfo.hIcon = 0 ;

该语句设置主窗口的图标,窗口没有图标。

    CreateInfo.MainWindowProc = HelloWinProc;

该语句将主窗口的窗口过程函数设置为 HelloWinProc,所有发送到该窗口的消息都由该函数处理。

   创建信息.lx = 0 ; 创建信息.ty = 0 ; 创建信息.rx = 320 ; CreateInfo.by = 240 ;

以上语句设置了主窗口在屏幕上的位置和大小,左上角和右下角分别位于(0, 0)和(320, 240)。

   CreateInfo.iBkColor = PIXEL_lightwhite;

该语句将主窗口的背景色设置为白色,PIXEL_lightwhite是 MiniGUI 预定义的像素值。

   CreateInfo.dwAddData = 0 ;

该语句设置主窗口的附加数据,窗口没有附加数据。

   CreateInfo.hHosting = HWND_DESKTOP;

此语句将主窗口的托管窗口设置为桌面窗口。

   ShowWindow (hMainWnd, SW_SHOWNORMAL);

ShowWindow创建主窗口后,需要调用函数将创建的窗口显示在屏幕上。

的第一个参数hMainWnd是要显示的窗口的句柄,

第二个参数指定显示窗口的动作(显示或隐藏)。SW_SHOWNORMAL表示显示主窗口并将其设置为最顶部的窗口。

进入消息循环

ShowWindow函数被调用时,主窗口将显示在屏幕上。和其他 GUI 一样,是时候进入消息循环了。MiniGUI 为每个 MiniGUI 程序维护一个消息队列。事件发生后,MiniGUI 将事件转化为消息,并将消息放入目标窗口的消息队列中。那么应用程序的任务就是执行下面的消息循环代码,不断地从消息队列中获取消息并进行处理。

    while (GetMessage (&Msg, hMainWnd)) {TranslateMessage (&Msg);DispatchMessage (&Msg); }

Msg变量类型为 MSG 结构体,定义 minigui/window.h如下:

/*** 消息结构。
* \sa GetMessage, PostMessage, msgs */
typedef struct _MSG
{/** 接收此消息的窗口句柄。*/HWND hwnd;    UINT  message;         /** 消息标识符 */WPARAM wParam;         /** 消息的第一个参数(具有指针精度的无符号整数)。 */LPARAM lParam;         /** 消息的第二个参数(具有指针精度的无符号整数) */DWORD time;            /**时间*/#ifdef _MGRM_THREADSvoid*  pAdd;          /** 附加数据*/
#endif
} MSG;
typedef MSG* PMSG;

GetMessage 函数从应用程序的消息队列中获取一条消息。

     GetMessage (&Msg, hMainWnd);

此函数的第二个参数是主窗口的句柄,第一个参数是指向 MSG 结构的指针。GetMessage函数用从消息队列中得到的消息填充 MSG 结构的字段,其中包括:

  • hwnd: 消息发送到的窗口句柄。该值是相同hMainWndhelloworld.c程序。
  • message: 消息标识符。这是用于标识消息的整数。每条消息都有一个对应的预定义标识符,这些标识符定义在minigui/window.h并带有MSG_ 前缀。
  • wParam:第一个消息参数,不同的消息含义和取值不同。
  • lParam: 第二个消息参数,其含义和取值取决于消息。
  • time:消息放入消息队列的时间(tick count)。

只要从消息队列中得到的消息不是MSG_QUIT, GetMessage则返回一个非0值,消息循环将继续。MSG_QUITmessage 消息使GetMessage返回为零,并导致消息循环终止。

      TranslateMessage (&Msg);

TranslateMessage函数将击键消息转换为MSG_CHAR 消息,然后将消息发送给窗口过程函数。

      DispatchMessage (&Msg);

DispatchMessage函数最终将消息发送到目标窗口的窗口过程,并让它处理消息。

在这个例子中,窗口过程是HelloWinProc。也就是说,MiniGUI 在函数中调用主窗口的窗口过程函数(回调函数)DispatchMessage来处理发送到这个主窗口的消息。处理完消息后,应用程序的窗口过程函数返回DispatchMessage函数中,而DispatchMessage function最终返回应用程序代码,应用程序通过调用下一个GetMessage 函数开始新的消息循环。

窗口过程函数

窗口过程函数是 MiniGUI 程序的主体。一个应用程序的大部分工作实际上发生在窗口过程函数中,因为GUI程序的主要任务是接收和处理窗口接收到的各种消息。

helloworld.c 程序中,窗口过程是名为HelloWinProc的函数,窗口过程函数可以由程序员任意命名,CreateMainWindow函数根据MAINWINCREATE结构中指定的窗口过程创建主窗口。

窗口过程函数定义如下:

static LRESULT HelloWinProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

窗口过程函数的四个参数与 MSG 结构的前四个域相同,第一个参数hWnd是接收消息的窗口句柄,与CreateMainWindow函数的返回值相同, 表示接收消息的具体窗口。第二个参数与MSG结构的message字段相同,是一个整数值,表示接收到的消息。最后两个参数都是消息参数(两个具有指针精度的整数),提供与消息相关的特殊信息。

窗口过程函数通常不是由程序直接调用,而是由MiniGUI 调用,即回调函数。

窗口过程函数不予处理的消息应该传给DefaultMainWinProc函数进行缺省处理,从DefaultMainWinProc返回的值必须由窗口过程返回。

屏幕输出

程序在响应MSG_PAINT 消息时执行屏幕输出。应用程序首先通过调用BeginPaint函数获取设备上下文句柄 ,并使用它来调用GDI函数来执行绘图操作。这里,程序使用TextOut文本输出函数来显示“Hello, world!” 字符串。绘制完成后,应用程序调用EndPaint函数释放设备上下文句柄。

我们将在本指南的第三部分详细介绍 MiniGUI 图形设备接口。

退出程序

当用户单击窗口右上角的关闭按钮时,窗口过程函数将收到一条MSG_CLOSE消息。helloworld程序在收到MSG_CLOSE消息时调用DestroyMainWindow函数销毁主窗口,并且调用PostQuitMessage 函数将MSG_QUIT投入到到消息队列中。GetMessage 函数在接收到MSG_QUIT消息时会返回0 ,最终导致程序退出消息循环。

程序最后调用MainWindowThreadCleanup清理主窗口使用的消息队列等系统资源,并最终由MiniGUIMain finally返回。

编译、链接和运行

可以在命令行中输入以下命令进行编译 helloworld.c,并链接生成执行文件helloworld

$ gcc -o helloworld helloworld.c -lpthread -lminigui_ths -ljpeg -lpng -lz

如果将 MiniGUI 配置为 MiniGUI-Processes,则需要以下编译选项:

$ gcc -o helloworld helloworld.c -lminigui_procs -ljpeg -lpng -lz

 -o告诉 编译器 ( gcc) 要生成的目标文件名,这里是helloworld-l选项 指定生成helloworld时需要链接的一个库,这里连接的是minigui库和pthread 库,如果 MiniGUI 配置为 MiniGUI-Threads时。还需要链接pthread库。 pthread 是提供 POSIX 兼容线程支持的函数库,编译 MiniGUI-Threads 程序时必须链接这个函数库。我们所编译的程序只使用MiniGUI核心库minigui中的函数,没有使用MiniGUI其他库提供的组件(如libmgext或libvcongui),因此只需要链接minigui库或链其他要链接的函数库如jpeg、png、z 等都是MiniGUI 内部依赖的函数库(这里假设您在配置MiniGUI 时已经开启了JPEG 和PNG 图像支持)。

如果将 MiniGUI 配置为 MiniGUI-Processes,则在运行helloworld程序之前,必须先确保已经启动了MiniGUI的服务器端程序mginit。例如,你可以在 启动MED的mginit程序,然后进入helloworld文件所在目录,在命令行中输入./helloworld即可启动helloworld程序。

$ ./helloworld

MiniGUI学习日记一----MiniGUI基础编程篇相关推荐

  1. 210学习日记(18)_ARM基础知识

    210学习日记(18) --ARM基础知识 注意: 以下大部分类容都来自网上现成的(直接拷贝过来的,然后经整理)!!!! 问1:ARM处理器工作模式有几种?各种工作模式下分别有什么特点? 答1:ARM ...

  2. 深度学习小白入门教程-基础环境篇

    深度学习小白入门教程-基础环境篇 如有图片显示失败,请回小主主页查看~ Anaconda 安装包下载方式一:官网(科学上网比较慢,不推荐) 安装包下载方式二:清华镜像(推荐) 具体安装步骤(跟着箭头来 ...

  3. 10.16 my学习日记 (XPath的基础语法,lxml库的应用)

    10.16 my学习日记(XPath的基础语法,lxml库的应用) XPath的基础语法 XPath查找标签 XPath谓语 lxml库在爬虫中的应用 etree库etree_Element对象 使用 ...

  4. 生信小白学习日记Day2-2——NGS基础 NGS分析

    2019年5月26日下午,无意中看到hanli0902的关于NGS分析的博文https://blog.csdn.net/hanli1992/article/details/82790386有很多需要学 ...

  5. 数据结构与算法——从零开始学习(一)基础概念篇

    系列文章 第一章:基础知识 第二章:线性表 第三章:栈和队列 第四章:字符串和数组 第五章:树和二叉树 第六章:图 第七章:排序算法 前言 数据结构:是指相互之间存在一种或多种特定关系的数据元素的集合 ...

  6. 生信小白学习日记Day3——NGS基础 NGS分析注解(质量分析软件)

    2019年5月27日,天气舒适,忙碌一天之后开始今天的生信学习.今天就昨天Day2-2的一些标记加以查询说明,仅供参考. NGS基础 NGS分析注解 1. 质量分析软件 昨天提到,拿到数据后可以通过一 ...

  7. Ubuntu学习日记--Lesson1:Linux基础和常用命令

    版权生命:文章系原创,转载请注明出处,多谢! 为了在Linux系统下用深度学习框架caffe,系统补习了一下Linux操作的知识,做些笔记,以备复习,或随时查看. Lesson1:Linux基础和常用 ...

  8. 生信小白学习日记Day2——NGS基础 illumina高通量测序原理

    2019年5月26日,周日,小雨 说明:阅读生信宝典和查阅文章的总结,原文请关注公众号生信宝典,参考的博文都附有链接,仅供参考. 生信宝典 NGS基础--高通量测序原理 本文介绍了测序文库构建原理.链 ...

  9. 生信小白学习日记Day4Day5——NGS基础 NGS分析注释(BWA软件)

    2019年5月30日,晚上,心情变好,好几天没更新了,看到男朋友在学一款软件,我也近朱者赤,来继续注释Day2-2中NGS分析流程中的一个重要软件--BWA NGS基础 NGS分析注释 BWA 对应于 ...

最新文章

  1. 祝贺!清华大学姚期智教授荣获2021届京都奖:“日本的诺贝尔奖”
  2. MSC EASY5 2020中文版
  3. 9.25-CSS样式以及结构布局
  4. MyBatis学习总结(24)——Mybatis常见问题汇总
  5. python权威指南 pdf_Python高级编程(第2版) 中文完整pdf扫描版[76MB]
  6. Android新的menu实现——ActionMode
  7. 阿里云服务器下安装LAMP环境(CentOS Linux 6.3)(1)
  8. 区块链开发(一)搭建基于以太坊go-ethereum的私有链环境
  9. 乌龟git安装和使用
  10. 常见的图标库有哪些?
  11. vant显示日期格式_使用Vant完成DatetimePicker 日期的选择器操作
  12. pxe服务器 安装系统,通过PXE网络安装windows系统
  13. JavaSE_day11【内部类、注解】
  14. 可视化常见绘图(四)柱状图
  15. 中国版的日和-十万个冷笑话
  16. Ubuntu界面显示不全的解决方法
  17. 数据分析报告中如何选择合适的统计图表
  18. 正则校验字符串中汉字数量及总数量
  19. 关于川大667和972自命题考试的心得
  20. 华数工业机器人教学视频_华数六轴工业机器人技术知识讲解介绍

热门文章

  1. 用iperf在ambarella s2l上进行网络性能测试
  2. 以太坊的POS共识机制(二)理解 Serenity :Casper
  3. 大数据具备的5大发展爆点,你准备抓住哪个呢?
  4. ITX迷你主机的优点及缺点
  5. linux内部网关协议igp,在自治系统内部的各个路由器之间,运行的是内部网关协议IGP。早期的IGP叫做【11】 ,它执行 【12】 。_考题宝...
  6. ChatGPT 之后,再玩玩 Stable-Diffusion
  7. ztack怎么生成虚拟服务器,在ZStack中使用ISO文件安装虚拟机模板
  8. Java--实现简单的音频(mp3格式)播放
  9. JAVA学习3-抽象类、内部类、数组、Object、System、String、基本包装类型
  10. 数据库实验 MySQL查询语句练习