MiniGUI学习日记一----MiniGUI基础编程篇
一、什么是事件驱动编程:
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[]);
该函数是main
ANSI 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
: 消息发送到的窗口句柄。该值是相同hMainWnd
的helloworld.c
程序。message
: 消息标识符。这是用于标识消息的整数。每条消息都有一个对应的预定义标识符,这些标识符定义在minigui/window.h
并带有MSG_
前缀。wParam
:第一个消息参数,不同的消息含义和取值不同。lParam
: 第二个消息参数,其含义和取值取决于消息。- time:消息放入消息队列的时间(tick count)。
只要从消息队列中得到的消息不是MSG_QUIT
, GetMessage
则返回一个非0值,消息循环将继续。MSG_QUIT
message 消息使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基础编程篇相关推荐
- 210学习日记(18)_ARM基础知识
210学习日记(18) --ARM基础知识 注意: 以下大部分类容都来自网上现成的(直接拷贝过来的,然后经整理)!!!! 问1:ARM处理器工作模式有几种?各种工作模式下分别有什么特点? 答1:ARM ...
- 深度学习小白入门教程-基础环境篇
深度学习小白入门教程-基础环境篇 如有图片显示失败,请回小主主页查看~ Anaconda 安装包下载方式一:官网(科学上网比较慢,不推荐) 安装包下载方式二:清华镜像(推荐) 具体安装步骤(跟着箭头来 ...
- 10.16 my学习日记 (XPath的基础语法,lxml库的应用)
10.16 my学习日记(XPath的基础语法,lxml库的应用) XPath的基础语法 XPath查找标签 XPath谓语 lxml库在爬虫中的应用 etree库etree_Element对象 使用 ...
- 生信小白学习日记Day2-2——NGS基础 NGS分析
2019年5月26日下午,无意中看到hanli0902的关于NGS分析的博文https://blog.csdn.net/hanli1992/article/details/82790386有很多需要学 ...
- 数据结构与算法——从零开始学习(一)基础概念篇
系列文章 第一章:基础知识 第二章:线性表 第三章:栈和队列 第四章:字符串和数组 第五章:树和二叉树 第六章:图 第七章:排序算法 前言 数据结构:是指相互之间存在一种或多种特定关系的数据元素的集合 ...
- 生信小白学习日记Day3——NGS基础 NGS分析注解(质量分析软件)
2019年5月27日,天气舒适,忙碌一天之后开始今天的生信学习.今天就昨天Day2-2的一些标记加以查询说明,仅供参考. NGS基础 NGS分析注解 1. 质量分析软件 昨天提到,拿到数据后可以通过一 ...
- Ubuntu学习日记--Lesson1:Linux基础和常用命令
版权生命:文章系原创,转载请注明出处,多谢! 为了在Linux系统下用深度学习框架caffe,系统补习了一下Linux操作的知识,做些笔记,以备复习,或随时查看. Lesson1:Linux基础和常用 ...
- 生信小白学习日记Day2——NGS基础 illumina高通量测序原理
2019年5月26日,周日,小雨 说明:阅读生信宝典和查阅文章的总结,原文请关注公众号生信宝典,参考的博文都附有链接,仅供参考. 生信宝典 NGS基础--高通量测序原理 本文介绍了测序文库构建原理.链 ...
- 生信小白学习日记Day4Day5——NGS基础 NGS分析注释(BWA软件)
2019年5月30日,晚上,心情变好,好几天没更新了,看到男朋友在学一款软件,我也近朱者赤,来继续注释Day2-2中NGS分析流程中的一个重要软件--BWA NGS基础 NGS分析注释 BWA 对应于 ...
最新文章
- 祝贺!清华大学姚期智教授荣获2021届京都奖:“日本的诺贝尔奖”
- MSC EASY5 2020中文版
- 9.25-CSS样式以及结构布局
- MyBatis学习总结(24)——Mybatis常见问题汇总
- python权威指南 pdf_Python高级编程(第2版) 中文完整pdf扫描版[76MB]
- Android新的menu实现——ActionMode
- 阿里云服务器下安装LAMP环境(CentOS Linux 6.3)(1)
- 区块链开发(一)搭建基于以太坊go-ethereum的私有链环境
- 乌龟git安装和使用
- 常见的图标库有哪些?
- vant显示日期格式_使用Vant完成DatetimePicker 日期的选择器操作
- pxe服务器 安装系统,通过PXE网络安装windows系统
- JavaSE_day11【内部类、注解】
- 可视化常见绘图(四)柱状图
- 中国版的日和-十万个冷笑话
- Ubuntu界面显示不全的解决方法
- 数据分析报告中如何选择合适的统计图表
- 正则校验字符串中汉字数量及总数量
- 关于川大667和972自命题考试的心得
- 华数工业机器人教学视频_华数六轴工业机器人技术知识讲解介绍
热门文章
- 用iperf在ambarella s2l上进行网络性能测试
- 以太坊的POS共识机制(二)理解 Serenity :Casper
- 大数据具备的5大发展爆点,你准备抓住哪个呢?
- ITX迷你主机的优点及缺点
- linux内部网关协议igp,在自治系统内部的各个路由器之间,运行的是内部网关协议IGP。早期的IGP叫做【11】 ,它执行 【12】 。_考题宝...
- ChatGPT 之后,再玩玩 Stable-Diffusion
- ztack怎么生成虚拟服务器,在ZStack中使用ISO文件安装虚拟机模板
- Java--实现简单的音频(mp3格式)播放
- JAVA学习3-抽象类、内部类、数组、Object、System、String、基本包装类型
- 数据库实验 MySQL查询语句练习