我的第一个minigui程序

   第一次在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

    
DWORD       dwStyle;               
// control style

    
int         x, y, w, h;             // control
position in dialog

    
int         id;                    
// control identifier

    
const char* caption;                // control caption

    
DWORD       dwAddData;             
// additional data

 

    
DWORD       dwExStyle;             
// control extended style

} CTRLDATA;
                    //用来定义控件

typedef CTRLDATA*
PCTRLDATA;

 

typedef struct

{

   
DWORD       dwStyle;               
// dialog box style

   
DWORD       dwExStyle;             
// dialog box extended style

   
int         x, y, w, h;            
// dialog box position

  
 const char* caption;               
// dialog box caption

   
HICON       hIcon;                 
// dialog box icon

   
HMENU       hMenu;                 
// dialog box menu

   
int         controlnr;             
// number of controls

   
PCTRLDATA   controls;              
// poiter to control array

   
DWORD       dwAddData;             
// addtional data, must be zero

} DLGTEMPLATE;
                //用来定义对话框本身

typedef DLGTEMPLATE*
PDLGTEMPLATE;

 

        在程序中,应该首先利用 CTRLDATA 
定义对话框中所有的控件,并用数组表示。控件在该数组中的顺序,也就是对话框中用户按TAB键时的控件切换顺序。然后定义对话框,指定对话框中的控件数目,并指定 DLGTEMPLATE 
结构中的 controls 
指针指向定义控件的数组。

例如:

static CTRLDATA ButtonCtrls[BUTTONNUM];
static DLGTEMPLATE ButtonPanel = {
    WS_VISIBLE | WS_THINFRAME,
    WS_EX_NONE, 0,0,0,0,
    "buttonlist",
    0,0,
    BUTTONNUM, ButtonCtrls,
    0
};

 

ButtonPanel.controls = ButtonCtrls;

 

定义完对话框模板数据后,需要定义对话框的回调函数。

 

 

对话框操作函数
(不一定仅在对话框中可用)

函数名称 
用途 
备注

DestroyAllControls 
销毁所有的子窗口  

GetDlgCtrlID 
根据控件句柄获取控件标识符  

GetDlgItem 
根据控件标识符获取控件句柄  

GetDlgItemInt 
获取控件文本并转换为整数值  

SetDlgItemInt 
根据整数值设置控件文本  

GetDlgItemText 
获取子控件文本 
功能同 GetWindowText

GetDlgItemText2 
获取子控件文本 
根据文本长度自动分配内存,应用程序负责释放该内存

SetDlgItemText 
设置子控件文本 
功能同 SetWindowText

GetNextDlgGroupItem 
获取下一个同组子控件 
用于遍历同组控件,参阅 WS_GROUP
风格

GetNextDlgTabItem 
获取下一个“TAB
键停止”子控件
 用于TAB键游历控件,参阅WS_TABSTOP风格

SendDlgItemMessage 
向子控件发送消息 
功能同 SendMessage

CheckDlgButton 
设置检查框子控件的选中状态  

CheckRadioButton 
设置单选按钮子控件的选中状态

IsDlgButtonChecked 
检查子按钮是否选中  

GetDlgDefPushButton 
获取当前默认子按钮  

 

 

通用窗口操作函数

函数名称 
用途 
备注

UpdateWindow 
立即更新某个窗口  

ShowWindow 
显示或隐藏某个窗口  

IsWindowVisible 
判断某个窗口是否可见 
控件和主窗口均可用

EnableWindow 
使能或禁止某个窗口  

IsWindowEnabled 
判断某个窗口是否可用  

GetClientRect 
获取窗口客户区矩形  

GetWindowRect 
获取窗口矩形 
屏幕坐标系中的窗口尺寸

GetWindowBkColor 
获取窗口背景色  

SetWindowBkColor 
设置窗口背景色  

GetWindowFont 
获取窗口默认字体  

SetWindowFont 
设置窗口默认字体  

GetWindowCursor 
获取窗口光标  

SetWindowCursor 
设置窗口光标  

GetWindowStyle 
获取窗口风格  

GetWindowExStyle 
获取窗口扩展风格  

GetFocusChild 
获取拥有输入焦点的子窗口  

SetFocusChild 
设置焦点子窗口  

GetWindowCallbackProc 
获取窗口过程函数  

SetWindowCallbackProc 
设置窗口过程函数  

GetWindowAdditionalData 
获取窗口附加数据一

SetWindowAdditionalData 
设置窗口附加数据一

GetWindowAdditionalData2 
获取窗口附加数据二

SetWindowAdditionalData2 
设置窗口附加数据二

对话框和控件在内部已使用附加数据二,保留附加数据一给应用程序使用

GetWindowCaption 
获取窗口标题   
通常用于主窗口

SetWindowCaption 
设置窗口标题
   通常用于主窗口

InvalidateRect 
使窗口的给定矩形区域无效 
将引发窗口重绘

GetUpdateRect 
获取窗口当前的无效区域外包矩形

ClientToScreen 
将窗口客户区坐标转换为屏幕坐标

ScreenToClient 
将屏幕坐标转换为客户区坐标  

WindowToScreen 
将窗口坐标转换为屏幕坐标  

ScreenToWindow 
将屏幕坐标转换为窗口坐标  

IsMainWindow 
判断给定窗口是否为主窗口  

IsControl 
判断给定窗口是否为控件  

IsDialog 
判断给定窗口是否为对话框  

GetParent 
获取窗口的父窗口句柄 
主窗口的父窗口永远为HWND_DESKTOP

GetMainWindowHandle 
返回包含某个窗口的主窗口句柄  

GetNextChild 
获取下一个子窗口 
用于遍历某个窗口的所有子窗口

GetNextMainWindow 
获取下一个主窗口句柄 
用于遍历所有主窗口

GetHosting 
获取某个主窗口的托管窗口  

GetFirstHosted 
获取某个主窗口的第一个被托管窗口

GetNextHosted 
获取下一个被托管窗口
 用于遍历某个主窗口的所有被托管窗口

GetActiveWindow 
获取当前活动主窗口  

SetActiveWindow 
设置当前活动主窗口  

GetCapture 
获取当前捕获鼠标的窗口

SetCapture 
捕获鼠标

ReleaseCapture 
释放鼠标

MoveWindow 
移动窗口或改变窗口大小  

ScrollWindow 
滚动窗口客户区的内容 

 

 

事件钩子

        通常情况下,键盘事件和鼠标事件以其正常的途径从底层设备传递到最终的应用程序窗口过程中进行处理。MiniGUI
提供了一种机制,使得我们可以在这些事件转换成相应的消息并传递到具体的窗口之前截获这些事件,然后有两种选择:让事件继续沿着正常的路径传递;或者打断事件的传递。这种机制就是钩子机制。

       钩子其实是一个回调函数,如果应用程序注册有钩子,系统就会在传递消息的中途调用这个回调函数,然后根据该回调函数的返回值来判断是否继续传递消息。

MiniGUI-Threads 
和 MiniGUI-Standalone 
模式下定义的钩子回调函数的原型如下所示:

typedef int (*
MSGHOOK)(void* context, HWND dst_wnd, int msg, WPARAM wparam, LPARAM lparam);

 

其中,context 
是注册钩子时传入的一个上下文信息,可以是一个指针;dst_wnd 
是该消息的目标主窗口;msg 是消息标识符;wparam
和 lparam 是消息的两个参数。钩子函数的返回值决定了系统是否继续传递事件:返回 HOOK_GOON 
将继续传递事件;返回 HOOK_STOP 
将停止事件的继续传递。

 

注册键盘和鼠标事件的钩子函数:

MSGHOOK GUIAPI
RegisterKeyMsgHook (void* context, MSGHOOK hook);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值