bokee.net

电子/电气工程师博客

正文 更多文章

用VC模拟单片机多层菜单的实现思路

                用VC模拟单片机多层菜单的实现思路

                           王佰营  徐丽红

                     wbymcs51.blog.bokee.net
                     
     以下程序为用VC模拟实现多层菜单思想的主要程序代码。其界面如下图:

       
    将该代码很容易翻译为单片机C51语言或汇编语言用于液晶显示系统。

  一、头文件部分:MenuDlg.h
// MenuDlg.h : header file
#if !defined(AFX_MENUDLG_H__56153AA4_DEB7_4C7E_AC99_60BCC65471C8__INCLUDED_)
#define AFX_MENUDLG_H__56153AA4_DEB7_4C7E_AC99_60BCC65471C8__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//类CMenuDlg的定义部分
/////////////////////////////////////////////////////////////////////////////
// CMenuDlg dialog

class CMenuDlg : public CDialog
{
// Construction
public:
 CMenuDlg(CWnd* pParent = NULL); // standard constructor
 char** get_item_what(int igrade);
 UINT nDelay1;  //延时变量;
 bool bflash ; //菜单闪烁脉冲;
 bool bflash_allow; //允许菜单闪烁;
 int  nFlash_Pos; //菜单闪烁位置;
 
// Dialog Data
 //{{AFX_DATA(CMenuDlg)
 enum { IDD = IDD_MENU_DIALOG };
 CString m_sLine1;
 CString m_sLine2;
 CString m_sLine3;
 CString m_sLine4;
 //}}AFX_DATA

 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CMenuDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:
 HICON m_hIcon;

 // Generated message map functions
 //{{AFX_MSG(CMenuDlg)
 virtual BOOL OnInitDialog();
 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 afx_msg void OnButAdd();
 afx_msg void OnButBack();
 afx_msg void OnButDec();
 afx_msg void OnButOnward();
 afx_msg void OnClose();
 afx_msg void OnTimer(UINT nIDEvent);
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MENUDLG_H__56153AA4_DEB7_4C7E_AC99_60BCC65471C8__INCLUDED_)

二、源文件部分:MenuDlg.cpp
//CMenuDlg类的实现部分
// MenuDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Menu.h"
#include "MenuDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

 int index;  //某层所选菜单项索引;
 int  grade;  //当前层数;
 int item_index[4]; //item_index[1]第一层所选的项;
 int item_max[4]; //某层所选菜单最多项数;
 bool bgrade_end; //是否到最底层标志;

 CString sLine[4];
 char **show;

 //0
 char *menu_0[4] =
 {
  "爷爷",
  "",
  "",
  ""
 };

 //grade:1
 //x-0-0;

 char* menu_1_x[7] =
 {
  "大儿子",
  "二儿子",
  "三儿子",
  "四儿子",
  "大女儿",
  "二女儿",
  "三女儿"
 };


 //grade:2
 //1-x-0;
 //item_max:5
 //char menu_1_1[16] = "大儿子";
 char* menu_1_1_x[5] =
 {
  "孙子一",
  "孙子二",
  "孙子三",
  "孙子四",
  "孙子五"
 };

 
 //2-x-0;
 //item_max:5
 //char menu_1_2[16] = "二儿子";
 char* menu_1_2_x[5] =
 {
  "孙子六",
  "孙子七",
  "孙子八",
  "孙子九",
  "孙子十"
 };

 
 //3-x-0
 //item_max:5
 //char menu_1_3[16] = "三儿子";
 char* menu_1_3_x[5] =
 {
  "孙子十一",
  "孙子十二",
  "孙子十三",
  "孙子十四",
  "孙子十五"
 };


 //4-x-0;
 //item_max:5
 //char menu_1_4[16] = "四儿子";
 char* menu_1_4_x[5] =
 {
  "孙子十六",
  "孙子十七",
  "孙子十八",
  "孙子十九",
  "孙子二十"
 };


 //5-x-0
 //item_max:6
 //char menu_1_5[16] = "大女儿";
 char* menu_1_5_x[6] =
 {
  "外孙一",
  "外孙二",
  "外孙三",
  "外孙四",
  "外孙五",
  "外孙六"
 };


 //6-x-0
 //item_max:5
 //char menu_1_6[16] = "二女儿";
 char* menu_1_6_x[5] =
 {
  "外孙七",
  "外孙八",
  "外孙九",
  "外孙十",
  "外孙十一",
 };


 //7-x-0
 //item_max:4
 //char menu_1_7[16] = "三女儿";
 char* menu_1_7_x[4] =
 {
  "外孙十二",
  "外孙十三",
  "外孙十四",
  "外孙十五",
 };


 char* menu_1_1_1_x[11] =
 {
  "姓名:王大宝",
  "年龄:30岁",
  "身高:1.7米",
  "体重: 68公斤",
  "性格: 开朗",
  "婚姻:已婚",
  "单位:电子研究所",
  "职业:电子工程师",
  "政治:共产党员",
  "工龄:5年",
  "工资:1500元",
 };

 char* menu_1_1_2_x[11] =
 {
  "姓名:王二宝",
  "年龄:25岁",
  "身高:1.8米",
  "体重: 78公斤",
  "性格: 开朗",
  "婚姻:未婚",
  "单位:中国银行",
  "职业:会计师",
  "政治:共产党员",
  "工龄:2年",
  "工资:2000元",
 };
/* char menu_1_7_1[16]="外孙十二";
 char menu_1_7_2[16]="外孙十三";
 char menu_1_7_3[16]="外孙十四";
 char menu_1_7_4[16]="外孙十五";
*/
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
 CAboutDlg();

// Dialog Data
 //{{AFX_DATA(CAboutDlg)
 enum { IDD = IDD_ABOUTBOX };
 //}}AFX_DATA

 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CAboutDlg)
 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
 //}}AFX_VIRTUAL

// Implementation
protected:
 //{{AFX_MSG(CAboutDlg)
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};

void CMenuDlg::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
 switch(nIDEvent)
 {
 case 1:
  show = get_item_what(grade);
  if(index<=3)
  {
   sLine[0] = *(show+0);
   sLine[1] = *(show+1);
   sLine[2] = *(show+2);
   sLine[3] = *(show+3);
  }
  else
  {
   sLine[0] = *(show+index-3);
   sLine[1] = *(show+index-2);
   sLine[2] = *(show+index-1);
   sLine[3] = *(show+index);
  }


  if(bflash_allow)
  {
   if(bflash)
   {
    if(index<=3)
     sLine[index] = *(show+index);
    else
    {
     sLine[3] = *(show+index);
    }
   }
   else
   {
    if(index<=3) sLine[index] = "";
    else sLine[3] = "";
   }
  }

  m_sLine1 = sLine[0];
  m_sLine2 = sLine[1];
  m_sLine3 = sLine[2];
  m_sLine4 = sLine[3];


  UpdateData(false);
  break;
 case 2:
  if(bflash_allow)
  {
   nDelay1++;
   if(nDelay1>=7)
   {
    nDelay1 = 0;
    bflash = !bflash;
   }
  }
  else
  {
   bflash = true;
  }
  break;
 default:

  break;

 }
 CDialog::OnTimer(nIDEvent);
}


CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
 //{{AFX_DATA_INIT(CAboutDlg)
 //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CAboutDlg)
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
 //{{AFX_MSG_MAP(CAboutDlg)
  // No message handlers
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMenuDlg dialog

CMenuDlg::CMenuDlg(CWnd* pParent /*=NULL*/)
 : CDialog(CMenuDlg::IDD, pParent)
{
 //{{AFX_DATA_INIT(CMenuDlg)
 m_sLine1 = _T("");
 m_sLine2 = _T("");
 m_sLine3 = _T("");
 m_sLine4 = _T("");
 //}}AFX_DATA_INIT
 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMenuDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 //{{AFX_DATA_MAP(CMenuDlg)
 DDX_Text(pDX, IDC_STATIC_LINE1, m_sLine1);
 DDX_Text(pDX, IDC_STATIC_LINE2, m_sLine2);
 DDX_Text(pDX, IDC_STATIC_LINE3, m_sLine3);
 DDX_Text(pDX, IDC_STATIC_LINE4, m_sLine4);
 //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMenuDlg, CDialog)
 //{{AFX_MSG_MAP(CMenuDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_BN_CLICKED(IDC_BUT_ADD, OnButAdd)
 ON_BN_CLICKED(IDC_BUT_BACK, OnButBack)
 ON_BN_CLICKED(IDC_BUT_DEC, OnButDec)
 ON_BN_CLICKED(IDC_BUT_ONWARD, OnButOnward)
 ON_WM_CLOSE()
 ON_WM_TIMER()
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMenuDlg message handlers

BOOL CMenuDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // Add "About..." menu item to system menu.

 // IDM_ABOUTBOX must be in the system command range.
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }

 // Set the icon for this dialog.  The framework does this automatically
 //  when the application’s main window is not a dialog
 SetIcon(m_hIcon, TRUE);   // Set big icon
 SetIcon(m_hIcon, FALSE);  // Set small icon
 
 // TODO: Add extra initialization here
 m_sLine1= _T("爷爷");
 m_sLine2= _T("");
 m_sLine3= _T("");
 m_sLine4= _T("");

 nDelay1 = 0;   //延时计数变量;
 bflash = true;   //菜单闪烁脉冲;
 bflash_allow = false; //允许菜单闪烁;
 nFlash_Pos = 0;   //菜单闪烁位置;

 grade=0;
 for(int i = 0; i < 4; i++)
 {
  item_index[i] = 1;
 }

 for(i = 0; i < 4; i++)
 {
  item_max[i] = 0;
 }

 SetTimer(1,30,0);
 SetTimer(2,50,0);
 return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMenuDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CMenuDlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // device context for painting

  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  // Center icon in client rectangle
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // Draw the icon
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CDialog::OnPaint();
 }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMenuDlg::OnQueryDragIcon()
{
 return (HCURSOR) m_hIcon;
}

void CMenuDlg::OnButAdd() //↑
{
 // TODO: Add your control notification handler code here
 if(bgrade_end)
 {
  if(item_index[grade] == 3) item_index[grade] = 0;
  else item_index[grade] = item_index[grade]-1;
  if(item_index[grade] < 1) item_index[grade] = item_max[grade];  
 }
 else
 {
  item_index[grade]--;
  if(item_index[grade] < 1) item_index[grade] = item_max[grade];
 }

}

void CMenuDlg::OnButBack() //Back
{
 // TODO: Add your control notification handler code here
 if(grade>0)grade--; 
}

void CMenuDlg::OnButDec() //↓
{
 // TODO: Add your control notification handler code here
 if(bgrade_end)
 {
  if(item_index[grade]==1)item_index[grade] = item_index[grade]+4;
  else item_index[grade] = item_index[grade]+1;
  if(item_index[grade] > item_max[grade]) item_index[grade] = 1; 
 }
 else
 {
  item_index[grade]++;
  if(item_index[grade] > item_max[grade]) item_index[grade] = 1;
 }
}

void CMenuDlg::OnButOnward() //Onward
{
 // TODO: Add your control notification handler code here
 bflash_allow = true;
 nFlash_Pos = 1; 

 if(grade<3)grade++;
 
}

void CMenuDlg::OnClose()
{
 // TODO: Add your message handler code here and/or call default
 KillTimer(1);
 KillTimer(2);
 CDialog::OnClose();
}


char** CMenuDlg::get_item_what(int igrade)
{
 switch(igrade)
 {
 case 0:
  bgrade_end = false;
  bflash_allow = false;
  index = 0;
  item_max[0] = 1;
  item_index[1] = 1;
  return menu_0;
  break;
 case 1:
  bflash_allow = true;
  if(item_index[1]>=1 && item_index[1]<=7) index = item_index[1]-1;
  else index = 0;
  item_max[1] = 7;
  item_index[2] = 1;
  return &menu_1_x[0];
  break;
 case 2:
  bflash_allow = true;
  bgrade_end = false;
  index = item_index[2]-1;
  item_index[3] = 1;
  switch(item_index[1])
  {
  case 1:
   item_max[2] = 5;
   return menu_1_1_x;
   break;
  case 2:
   item_max[2] = 5;
   return menu_1_2_x;
   break;
  case 3:
   item_max[2] = 5;
   return menu_1_3_x;
   break;
  case 4:
   item_max[2] = 5;
   return menu_1_2_x;
   break;
  case 5:
   item_max[2] = 6;
   return menu_1_5_x;
   break;
  case 6:
   item_max[2] = 5;
   return menu_1_6_x;
   break;
  case 7:
   item_max[2] = 4;
   return menu_1_7_x;
   break;
  default:
   return menu_1_x;
  }
  break;
 case 3:
  bflash_allow = false;
  bgrade_end = true;
  index = item_index[3]-1;
  switch(item_index[2])
  {
  case 1:
   item_max[3] = 11;
   return menu_1_1_1_x;
   break;
  case 2:
   item_max[3] = 11;
   return menu_1_1_2_x;
   break;
  case 3:
  case 4:
  case 5:
  case 6:
  case 7:
  default:
   index = 0;
   return menu_1_1_1_x;
  }
  break;
 default:
  return menu_0;
  break;
 }

}

关键词:MFC VC 多层 菜单 液晶 汉字 单片机 

分享到:

上一篇:反激式开关电源设计的思考二---气隙

下一篇:反激式开关电源设计的思考三---磁芯

评论 (0条) 发表评论

抢沙发,第一个发表评论
验证码