第一次在Linux环境下编程,使用minigui做个界面显示位置和速度曲线。Windows下写过一些C程序,minigui学习了两个礼拜,研究了点Emacs,边写边学习。
在104系统上运行,与底层FPGA通信,将其采集到的数据读入并显示。FPGA此处不谈,记录下minigui,以helloworld为例。
/**********************************************************************************/
#include <stdio.h>
#include <minigui/common.h> //包括minigui常用的宏以及数据类型的定义
#include <minigui/minigui.h> //包含全局的和通用的接口函数以及某些杂项函数的定义
#include <minigui/gdi.h> //包含minigui绘图函数的接口定义
#include <minigui/window.h> //包含窗口有关的宏、数据类型、数据接口定义以及函数接口声明
//#include <minigui/control.h> //包含libminigui中所有内建控件的接口定义
/*程序入口*/
int MiniGUIMain (int argc, const char* argv[]) //argc:命令行参数个数 argv参数字符串数组指针
{
MSG Msg; //window.h中
HWND hMainWnd;
MAINWINCREATE CreateInfo; //描述一个主窗口的属性
//const char* old_renderer;
#ifdef _MGRM_PROCESSES
JoinLayer(NAME_DEF_LAYER , "helloworld" , 0 , 0); //MiniGUI-Processes模式下加入层(客户端)
#endif
CreateInfo.dwStyle = WS_VISIBLE | WS_BORDER | WS_CAPTION; //设置主窗口风格:可见|有边框|有标题栏
CreateInfo.dwExStyle = WS_EX_NONE; //扩展风格:无
CreateInfo.spCaption = "HelloWorld"; //标题
CreateInfo.hMenu = 0; //主菜单:无
CreateInfo.hCursor = GetSystemCursor(0); //设置主窗口的光标为系统缺省光标
CreateInfo.hIcon = 0; //图标:无
CreateInfo.MainWindowProc = HelloWinProc; //设置主窗口的窗口函数,所有发往该窗口的消息由该函数处理
CreateInfo.lx = 0; //屏幕上的位置(0,0)、(320,240)
CreateInfo.ty = 0;
CreateInfo.rx = 320;
CreateInfo.by = 240;
CreateInfo.iBkColor = COLOR_lightwhite; //背景色
CreateInfo.dwAddData = 0; //附加数据:无
//在窗口过程中,可以使用GetWindowAdditionalData函数获取该指针,从而获得所需要传递的参数。
CreateInfo.hHosting = HWND_DESKTOP; //设置主窗口的托管窗口为桌面窗口
//MiniGUI-Threads 中每个线程创建的第一个主窗口,其托管窗口必须是桌面,即 HWND_DESKTOP,
//该线程的其他窗口,必须由属于同一线程的已有主窗口作为托管窗口。
//系统在托管窗口为 HWND_DESKTOP 时创建新的消息队列,
//而在指定非桌面的窗口作为托管窗口时,使用该托管窗口的消息队列,
//也就是说,同一线程中的所有主窗口应该使用同一个消息队列。
//在调用 MiniGUIMain 之前,MiniGUI 启动自己的桌面窗口(Desktop)。
//old_renderer = SetDefaultWindowElementRender("classic");
hMainWnd = CreateMainWindow (&CreateInfo); //创建一个主窗口,返回值为所创建主窗口的句柄
if (hMainWnd == HWND_INVALID)
return -1;
ShowWindow(hMainWnd, SW_SHOWNORMAL); //显示:参数1:所要显示的窗口句柄 参数2:显示窗口的方式(显示/隐藏)
while (GetMessage(&Msg, hMainWnd)) { //参数1:要获取消息的主窗口的句柄 参数2:指向MSG结构的指针
//GetMessage函数将用从消息队列中取出的消息来填充该消息结构的各个域
TranslateMessage(&Msg); //把击键消息转换为MSG_CHAR消息,然后直接发送到窗口过程函数
DispatchMessage(&Msg); //把消息发往该消息的目标窗口的窗口过程,让其处理。
//处理完消息后,应用程序的窗口函数将返回到DispatchMessage函数,再返回到应用程序代码,
//应用程序又从下一个GetMessage函数调用开始消息循环。
}
//SetDefaultWindowElementRenderer(old_renderer);
MainWindowThreadCleanup (hMainWnd); //清除主窗口所使用消息队列系统资源
return 0;
}
/*窗口函数*/
//窗口过程是一个特定类型的函数,用来接收和处理所有发送到该窗口的消息。
//每个控件类有一个窗口过程,属于同一控件类的所有控件共用同一个窗口过程来处理消息。
static int HelloWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
//窗口过称函数,参数与MSG结构的前4个域相同 //由minigui调用,是一个回调函数
{
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); //在消息队列中投入一个MSG_QUIT消息,
//当GetMessage函数取出MSG_QUIT消息时将返回0.,最终导致程序退出消息循环
return 0;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam); //默认处理
}
/**********************************************************************************/
以上是完整的helloworld程序,可以直接用。
接下来是对话框,有模态对话框和非模态对话框之分。
模态对话框就是显示之后,用户不能再切换到其他主窗口进行工作的对话框,而只能在关闭之后,才能使用其他的主窗口。MiniGUI 中,使用 DialogBoxIndirectParam 函数建立的对话框就是模态对话框。实际上,该对话框首先根据模板建立对话框,然后禁止其托管主窗口,并在主窗口的 MSG_CREATE 消息中创建控件,之后发送 MSG_INITDIALOG 消息给回调函数,最终建立一个新的消息循环,并进入该消息循环,直到程序调用 EndDialog 函数为止。
非模态对话框在利用对话框模板中的数据建立主窗口之后,会立即返回。使用 CreateMainWindowIndirect函数建立普通的主窗口。
对话框模板
在 MiniGUI 中,用两个结构来表示对话框模板(<minigui/window.h>) ,如下所示:
typedef struct
{
char* class_name; // control class