自定义的小型调试器,类似于printf(基于emwin),通过屏幕显示

可供外部使用的函数有

Hide_Debug()
Show_Debug()
GUI_Printf(const char*,…)

程序代码

#include <stdarg.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include "GUI.h"
#include "WM.h"
//需要中文字库的支持才可以打印中文信息
//仅需要在需要调试信息的部分调用GUI_Printf(const char* fmt,...)进行显示
//与printf的用法一致
//通过调用Show_debug()创建调试窗口
//通过调用Hide_debug()删除窗口
#define MAX_BUF         1024*4
#define ID_FRAMEWIN_0 (GUI_ID_USER+0)
#define ID_MULTIEDIT_0 (GUI_ID_USER+1)
static WM_HWIN error_hwin;
static WM_HTIMER hTimer;
static char debug_infomation[MAX_BUF];
struct __Debug_Ctrl
{
    const uint32_t DEBUG_MAX_BUF;
    char* const Debug_Buffer;
    bool fresh_flag;
}Debug_Ctrl;
struct __Debug_Ctrl Debug_Ctrl=
{
    .DEBUG_MAX_BUF=MAX_BUF,
    .Debug_Buffer=debug_infomation,
    .fresh_flag=false
};
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 300, 300, 300, 0, 0x0, 0 },
  { MULTIEDIT_CreateIndirect, "Multipage", ID_MULTIEDIT_0, 0, 0, 290, 280, 0, 0x0, 0 },
  // USER START (Optionally insert additional widgets)
  // USER END
};
static void _cbDialog(WM_MESSAGE * pMsg) 
{
    WM_HWIN hItem;
    switch (pMsg->MsgId) 
    {
        case WM_PRE_PAINT:
            GUI_MULTIBUF_Begin();
            break;
        case WM_POST_PAINT:
            GUI_MULTIBUF_End();
            break;
        case WM_INIT_DIALOG:
            //
            // Initialization of 'Framewin'
            //
            hItem = pMsg->hWin;
            FRAMEWIN_SetFont(hItem, &GUI_FontHZ16);
            FRAMEWIN_SetText(hItem,"调试信息");
            //
            // Initialization of 'Multipage'
            //
            hItem = WM_GetDialogItem(pMsg->hWin, ID_MULTIEDIT_0);
            MULTIEDIT_SetFont(hItem, &GUI_FontHZ16);
            MULTIEDIT_SetAutoScrollV(hItem,1);
            MULTIEDIT_SetAutoScrollH(hItem,1);
            MULTIEDIT_SetMaxNumChars(hItem,Debug_Ctrl.DEBUG_MAX_BUF);
            MULTIEDIT_SetBufferSize(hItem,Debug_Ctrl.DEBUG_MAX_BUF);
            MULTIEDIT_SetText(hItem,Debug_Ctrl.Debug_Buffer);
            MULTIEDIT_SetFocussable(hItem,0);
            break;
        case WM_NOTIFY_PARENT:
            break;
        case WM_TIMER:
            if(Debug_Ctrl.fresh_flag==true)
            {
                hItem = WM_GetDialogItem(pMsg->hWin, ID_MULTIEDIT_0);
                MULTIEDIT_SetText(hItem,Debug_Ctrl.Debug_Buffer);
                Debug_Ctrl.fresh_flag=false;
            }
            WM_RestartTimer(hTimer,200);
            break;
        default:
            WM_DefaultProc(pMsg);
            break;
    }
}
void Hide_debug(void)
{
    WM_DeleteWindow(error_hwin);
}
void Show_debug(void)
{
    WM_HWIN hwin;
    error_hwin=GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);

    WM_SetStayOnTop(error_hwin,1);
    hwin=WM_GetClientWindow(error_hwin);
    hTimer=WM_CreateTimer(hwin,0,200,0);
}
void GUI_Printf(const char* fmt,...)
{
    static uint16_t Debug_num=0;
    va_list args;
    if(Debug_Ctrl.DEBUG_MAX_BUF-Debug_num<64)//预留出64字节的缓冲区,因此单次使用GUI_Printf不能超过64个字节
    {
        memset(Debug_Ctrl.Debug_Buffer,'\0',Debug_Ctrl.DEBUG_MAX_BUF);
        Debug_num=0;
    }
    va_start(args,fmt);                                 //取出可变参数
    Debug_num+=vsprintf(&Debug_Ctrl.Debug_Buffer[Debug_num],fmt,args);
    va_end(args);                                       //恢复堆栈的数据
    Debug_Ctrl.Debug_Buffer[Debug_num]='\n';          //向末尾添加换行符
    Debug_num++;
    Debug_Ctrl.fresh_flag=true;
}