⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctrls.cpp

📁 一个嵌入式系统的C代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//*************************************************************************//  MODULE : Ctrls - Class bodies code for Pb, Rb and Sys objects	  *//  AUTHOR : Ron Chernich                                                 *//  PURPOSE: Provides MS Windows-like GUI controls for graphic DOS mode   *//           programs, specifically:                                      *//              Check Box (Cb)                                            *//              Push Buttons (Pb)                                         *//              Radio Buttons (Rb)                                        *//              System Controls (Sys)                                     *//  HISTORY:                                                              *//   19-JAN-93  First (MSC/C++ 7.00) version                              *//   24-JAN-93	Modified to use Clipping where speed was low.		  *//   02-FEB-94  ALT-F5 redraw key added to system control gadget.         *//   04-FEB-94  BIOS_GET_TICKS macro changed to Timer::GetTock func call  *//*************************************************************************#include "ctrls.hpp"//////////////////////////////////////////////////////////////////////////// Routine to label a Push Button, Radio Button or Check Box ..//// An optional ampersand in the string is used as an escape char to place an// underline under the following character (which is the accelerator). Labels// longer than 128 characters will be truncated (character-wise).  All labels// are clipped (horizontally and vertically) into the passed bounding// rectangle.  The text justification relative to x1/x2 is specified in// <mode>.  You can fool this routine in several ways, but it was designed// to be fast, not bullet proof.//static void CtrlTxtLab (char *st, rect &r, UINT16 uMode, UINT16 nColor){  #define MAXLEN 128  INT16 x, y, dx, dy, xln;  char  *cp, str[MAXLEN], st1[2];  if ((dx = MAX(0, r.lr.x-r.ul.x)) && (dy = MAX(0, r.lr.y-r.ul.y))) {    xln = -1;    y = r.ul.y + ((dy - GfxTextHeight()) >> 1) + 1;    strncpy(str, st, MAXLEN-1);    str[MIN(strlen(st),MAXLEN-1)] = '\0';    if (cp = strchr(str, '&')) {      *cp = '\0';      xln = GfxTextExtent(str);      strcpy(cp, cp+1);      st1[0] = *cp, st1[1] = '\0';    }    x = r.ul.x + 1;    if (uMode == CTLS_Centre)      x += (dx - GfxTextExtent(str)) >> 1;    if (uMode == CTLS_RJustify)      x += (dx - GfxTextExtent(str));    GfxTextColor(nColor);    GfxSetClip(r.ul.x, r.ul.y, r.lr.x, r.lr.y);    Mickey.AutoPointer(r.ul.x, r.ul.y, r.lr.x, r.lr.y);    GfxText(x, y, str, GFX_Transparent);    if (xln >= 0) {      x += xln;      y += (GfxTextHeight() - GFX_UlnOffset);      GfxMoveTo(x, y), GfxLineTo(x+GfxTextExtent(st1), y);    }    Mickey.ShowPointer();    GfxClrClip();  }}//////////////// A (horrible) time consumer - used to ensure hardware independant// graphic button activation simulation..//static void CtrlDelay (UINT32 lTks){  UINT32 lLim, lNow;  lNow = Clock.GetTocks();  lLim = lNow + lTks;  while (lLim > lNow)    lNow = Clock.GetTocks();}//////////////////////////////////////////////////////////////////////////// Perform initial rendering of passed push button//void PbCtrl::Render (btn *p){  INT16 x1, y1, x2, y2;  x1 = p->r.ul.x + 1;  y1 = p->r.ul.y + 1;  x2 = p->r.lr.x - 1;  y2 = p->r.lr.y - 1;  GfxRect(x1, y1, x2, y2, GFX_Fill, _White);  GfxTextColor(_DarkGrey);  GfxMoveTo(x1, y2), GfxLineTo(x2, y2), GfxLineTo(x2, y1);  GfxMoveTo(x1, y2-1), GfxLineTo(x2-1, y2-1), GfxLineTo(x2-1, y1);  GfxTextColor(_BrightWhite);  GfxMoveTo(x1, y2), GfxLineTo(x1, y1), GfxLineTo(x2, y1);  GfxMoveTo(x1+1, y2-1), GfxLineTo(x1+1, y1+1), GfxLineTo(x2-1, y1+1);  GfxTextColor(_Black);  GfxMoveTo(x1, y1-1), GfxLineTo(x2, y1-1);  GfxMoveTo(x1-1, y1), GfxLineTo(x1-1, y2);  GfxMoveTo(x1, y2+1), GfxLineTo(x2, y2+1);  GfxMoveTo(x2+1, y1), GfxLineTo(x2+1, y2);  if (p->pst) {    rect rr = p->r;    rr.ul.y += 2, rr.lr.y -= 2, rr.ul.x += 4, rr.lr.x -= 4;    CtrlTxtLab(p->pst->StrGet(), rr, CTLS_Centre);  }}/////////////// Toggle button status and redraw its graphic state accordingly.//void PbCtrl::Toggle (btn *p){  PIMBUF pImage;  INT16  x1, y1, x2, y2;  x1 = p->r.ul.x + 1, y1 = p->r.ul.y + 1;  x2 = p->r.lr.x - 1, y2 = p->r.lr.y - 1;  p->status = (p->status & 0xfffe) | ((p->status & 0x01) ^ 0x01);  if (p->status & 0x01) {    if (pImage = GfxGetImage(x1+2, y1+2, x2-2, y2-2)) {      GfxPutImage(x1+4, y1+4, pImage);      GfxFreeImage(pImage);    }    GfxTextColor(_DarkGrey);    GfxMoveTo(x1, y2), GfxLineTo(x1, y1), GfxLineTo(x2, y1);    GfxTextColor(_White);    GfxMoveTo(x1+1, y2), GfxLineTo(x1+1, y1+1), GfxLineTo(x2, y1+1);    GfxMoveTo(x1+2, y2), GfxLineTo(x1+2, y1+2), GfxLineTo(x2, y1+2);    GfxMoveTo(x1+3, y2), GfxLineTo(x1+3, y1+3), GfxLineTo(x2, y1+3);  }  else {    if (pImage = GfxGetImage(x1+4, y1+4, x2, y2)) {      GfxPutImage(x1+2, y1+2, pImage);      GfxFreeImage(pImage);    }    GfxTextColor(_DarkGrey);    GfxMoveTo(x1+1, y2), GfxLineTo(x2, y2), GfxLineTo(x2, y1-1);    GfxMoveTo(x1+2, y2-1), GfxLineTo(x2-1, y2-1), GfxLineTo(x2-1, y1-1);    GfxTextColor(_BrightWhite);    GfxMoveTo(x1, y2), GfxLineTo(x1, y1), GfxLineTo(x2, y1);    GfxMoveTo(x1+1, y2-1), GfxLineTo(x1+1, y1+1), GfxLineTo(x2-1, y1+1);  }}/////////////// Create a new push button as defined by the passed params and draw it.// The four coords define the upper-left and lower right limits of the// button graphic (we assume the deltas are positive!).// RETURNS: TRUE  .. button added to list//          FALSE .. unable to create button//BOOL PbCtrl::Create (UINT16 n, char *st,                      INT16 x1, INT16 y1, INT16 x2, INT16 y2){  btn *pb;  BOOL bOk;  rect r(point(x1, y1), point(x1+x2, y1+y2));  if (bOk = BtnNew(n, st, r)) {    pb = (btn*)DblGetTail();    Render(pb);  }  return bOk;}///////////////// Remove button with passed ID from the list (if it exists)// RETURNS: TRUE  .. button destroyed//	    FALSE .. did not exist!//BOOL PbCtrl::Destroy (UINT16 n){  BOOL bRes = BtnFind(n);  if (bRes)    BtnKill(n);  return bRes;}//////////////////////// Whack through the list to see if any button corresponds to the passed// ALT-key scan code.  If so, graphiically "click" it and return its ID.// RETURNS: ZERO if code unknown, or ID of button pressed.//UINT16 PbCtrl::Scan (char ch){  if (BtnHit(ch)) {    Mickey.AutoPointer(pb->r.ul.x, pb->r.ul.y, pb->r.lr.x, pb->r.lr.y);    Toggle(pb);    CtrlDelay();    Toggle(pb);    Mickey.ShowPointer();    return pb->Id;  }  return 0;}///////////////// Same as above, but using a point as the event trigger..// RETURNS: ZERO if code unknown, or ID of Push button clicked..//UINT16 PbCtrl::Scan (point& Pt){  if (BtnHit(Pt)) {    Mickey.HidePointer();    Toggle(pb);    CtrlDelay();    Toggle(pb);    Mickey.ShowPointer();    return pb->Id;  }  return 0;}///////////////// Repaint all defined push buttons//void PbCtrl::Refresh (void){  btn *pb;  pb = (btn*)DblGetHead();  while (pb) {    Render(pb);    pb = (btn*)DblGetNext();  }}  //////////////////////////////////////////////////////////////////////////// Draw and optionally label a Radio Button.//void RbCtrl::Render (btn *p){  p->status = (p->status & 0xfffe) | ((p->status & 0x01) ^ 0x01);  Toggle(p);  if (p->pst) {    rect rr = p->r;    rr.ul.x += (RB_Radius << 1) + GfxTextExtent(" ");    CtrlTxtLab(p->pst->StrGet(), rr, CTLS_LJustify);  }}/////////////////// This constructor could have been in the class definition, but a little// explaination is in order.. Every "group" (instance) of Radio Buttons// must act in a mutually exclusive way (only one ON at any one time).// When an instance is created, a default param sets the state to OFF, but// this can be over-ridden.  The boolean <bNoDefault> is cleared after// the first button is created in the ON state, preventing a (dumb) user// from creating an impossible situation with further ON buttons.//RbCtrl::RbCtrl (){  bNoDefault = TRUE;}/////////////// Toggle button status and redraw its graphic state accordingly.//void RbCtrl::Toggle (btn *p){  BOOL bOn;  INT16 x1, y1;  x1 = p->r.ul.x + RB_Radius;  y1 = p->r.ul.y + ((p->r.lr.y - p->r.ul.y) >> 1);  p->status = (p->status & 0xfffe) | ((p->status & 0x01) ^ 0x01);  bOn = (BOOL)(p->status & 0x01);  Mickey.AutoPointer(p->r.ul.x, p->r.ul.y,    p->r.ul.x+(RB_Radius << 1), p->r.ul.y+(RB_Radius << 1));  GfxCircle(x1, y1, RB_LedRad, GFX_Fill, (bOn ? _Red : _White));  GfxArc(x1, y1, RB_Radius, 225.0, 45.0, (bOn ? _DarkGrey : _BrightWhite));  GfxArc(x1, y1, RB_Radius, 45.0, 225.0, (bOn ? _BrightWhite : _DarkGrey));  Mickey.ShowPointer();}/////////////// Create a new Radio Button as defined by the passed params and draw it.// The coords define the centre of the actual button.  A "Hot" area is// developed from this to include the button label.// RETURNS: TRUE  .. button added to list//          FALSE .. unable to create button//BOOL RbCtrl::Create (UINT16 n, char *st, INT16 x, INT16 y, BOOL bDefault){  btn *rb;  BOOL bOk;  rect r;  r.ul.x = MAX(0, x - RB_Radius);  r.ul.y = MAX(0, y - MAX(RB_Radius, GfxTextHeight() >> 1));  r.lr.y = y + MAX(RB_Radius, GfxTextHeight() >> 1);  r.lr.x = x + GfxTextExtent(" ") + (RB_Radius << 1);  r.lr.x += GfxTextExtent(st);  if (strchr(st, '&'))    r.lr.x -= GfxTextExtent("&");  if (bOk = BtnNew(n, st, r)) {    rb = (btn*)DblGetTail();  if (bDefault)    if (bNoDefault) {      bNoDefault = FALSE;      rb->status |= 0x01;    }    Render(rb);  }  return bOk;}///////////////// Remove button with passed ID from the list (if it exists)// RETURNS: TRUE  .. button destroyed//	    FALSE .. did not exist!//BOOL RbCtrl::Destroy (UINT16 n){  BOOL bRes = BtnFind(n);  if (bRes)    BtnKill(n);  return bRes;}//////////////////////// Wreave through the list to see if any button corresponds to the passed// ALT-key scan code.  If so, graphically set "off" all other buttons// (there should only be one!) and set it "on", returning its ID.// RETURNS: ZERO if code unknown, or ID of radio button set.//UINT16 RbCtrl::Scan (char ch){  if (BtnHit(ch)) {    btn *p = (btn*)DblGetHead();    while (p) {      if (p->status & 0x01) {	if (p != pb) {	  Toggle(p);  	  break;	}      }      p = (btn*)DblGetNext();    }    if ((pb->status & 0x01) == 0)      Toggle(pb);    return pb->Id;  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -