Click here to Skip to main content
15,894,177 members
Articles / Programming Languages / C++

Scroll LED-Matrix Class

Rate me:
Please Sign up or sign in to vote.
4.95/5 (17 votes)
4 Feb 2014CPOL3 min read 30.9K   3.2K   38  
C++ classes that implement scrolling simulated-LED displays
  • fntcol17.zip
    • &arabic.f14
    • &europe.f14
    • &farsi.f14
    • &gaelic.f14
    • &greek.f14
    • &hebrew.f14
    • &polish.f14
    • &russian.f14
    • &turkish.f14
    • &urdu.f14
    • &yugosla.f14
    • 00-files.lst
    • 2_hebrew.f14
    • 2_hebrew.f16
    • antique.f14
    • apeaus.f08
    • apeaus.f14
    • apeaus.f16
    • apls.f08
    • arabdrft.f14
    • arabkufi.f14
    • arabnaf.f14
    • arbnaskh.f14
    • armenian.f08
    • armenian.f14
    • armenian.f16
    • art.f16
    • ascii.f14
    • backward.f14
    • bdeclo.f14
    • bhexall.f14
    • bhexbox.f14
    • bhexhi.f14
    • bhexlo.f14
    • bigserif.f14
    • bigserif.f16
    • bigsf.f14
    • binaryed.f14
    • blcksnsf.f10
    • block.f14
    • bold.f14
    • boxround.f14
    • boxround.f16
    • broadway.f14
    • broadway.f19
    • broadway.f8
    • broadway.f9
    • bthin.f14
    • bway2.f14
    • cafe.f10
    • cafe.f12
    • cntdown.f14
    • cntdown.f16
    • computer.f14
    • copyleft.txt
    • courier.f14
    • courier.f19
    • courier.f8
    • courier.f9
    • cp111.f08
    • cp111.f14
    • cp111.f16
    • cp111.f19
    • cp112.f08
    • cp112.f14
    • cp112.f16
    • cp112.f19
    • cp113.f08
    • cp113.f14
    • cp113.f16
    • cp113.f19
    • cp437.f08
    • cp437.f14
    • cp437.f16
    • cp437.f19
    • cp437alt.f08
    • cp437bgr.f08
    • cp850.f08
    • cp850.f14
    • cp850.f16
    • cp850.f19
    • cp851.f08
    • cp851.f14
    • cp851.f16
    • cp851.f19
    • cp852.f08
    • cp852.f14
    • cp852.f16
    • cp852.f19
    • cp853.f08
    • cp853.f14
    • cp853.f16
    • cp853.f19
    • cp860.f08
    • cp860.f14
    • cp860.f16
    • cp860.f19
    • cp861.f08
    • cp861.f14
    • cp861.f16
    • cp861.f19
    • cp862.f08
    • cp862.f14
    • cp862.f16
    • cp863.f08
    • cp863.f14
    • cp863.f16
    • cp863.f19
    • cp864.f08
    • cp864.f14
    • cp864.f16
    • cp865.f08
    • cp865.f14
    • cp865.f16
    • cp865.f19
    • cp866.f08
    • cp866.f14
    • cp866.f16
    • cp880.f08
    • cp880.f14
    • cp880.f16
    • cp881.f08
    • cp881.f14
    • cp881.f16
    • cp882.f08
    • cp882.f14
    • cp882.f16
    • cp883.f08
    • cp883.f14
    • cp883.f16
    • cp884.f08
    • cp884.f14
    • cp884.f16
    • cp885.f08
    • cp885.f14
    • cp885.f16
    • cyril_b.f08
    • cyril2.f14
    • cyrill1.f08
    • cyrill1.f14
    • cyrill1.f16
    • cyrill2.f08
    • cyrill2.f14
    • cyrill2.f16
    • cyrill3.f08
    • cyrill3.f14
    • cyrill3.f16
    • cyrillic.f14
    • data.f14
    • data.f19
    • data.f8
    • data.f9
    • decorate.f16
    • draw.f14
    • drawhi.f14
    • evga-alt.f08
    • evga-alt.f09
    • evga-alt.f10
    • evga-alt.f11
    • evga-alt.f12
    • evga-alt.f13
    • finnish.f14
    • fontorig.txt
    • fractur.f14
    • future.f14
    • gaelic.f14
    • georgian.f14
    • grckssrf.f08
    • grckssrf.f14
    • grckssrf.f16
    • greek.f06
    • greek.f07
    • greek.f08
    • greek.f14
    • greek.f16
    • greek2.f14
    • hack4th.f16
    • handugly.f16
    • handwrit.f14
    • handwrit.f16
    • heb-7bit.f16
    • heb-big.f14
    • heb-bold.f16
    • hebboldk.f16
    • hebclrgf.f14
    • hebclrgf.f16
    • heb-ktab.f14
    • hebktav1.f16
    • hebktav2.f16
    • heblarge.f14
    • heblarge.f16
    • heb-med.f14
    • heb-snsf.f14
    • hebugly.f16
    • hebyogi.f16
    • hercital.f08
    • hercules.f08
    • hercules.f10
    • hercules.f14
    • history.txt
    • hollow.f14
    • hrkgreek.f14
    • hylas.f14
    • icons.f14
    • inverted.f14
    • iso.f14
    • iso2.f14
    • iso3.f14
    • iso4.f14
    • italics.f14
    • kana.f14
    • kana.f16
    • lb_large.f16
    • lb_misc.f14
    • lb_ocr.f14
    • lb_ocr.f16
    • lbarabic.f14
    • lbitalic.f14
    • lbitalic.f16
    • lbscript.f14
    • lcd.f14
    • looking4.txt
    • mac.f08
    • macntosh.f14
    • macntosh.f16
    • madrid.f10
    • medieval.f14
    • modern.f16
    • newfont1.f14
    • newfont1.f19
    • newfont1.f8
    • newfont1.f9
    • newfont2.f14
    • newfont2.f19
    • newfont2.f8
    • newfont2.f9
    • newfont3.f14
    • newfont3.f19
    • norway.f14
    • norway2.f14
    • oldeng.f14
    • oldeng-f.f16
    • oldengl.f14
    • old-engl.f14
    • old-engl.f16
    • oldengl.f19
    • pc.f14
    • pc.f19
    • pc.f24
    • pc.f8
    • pc.f9
    • pc_6.f14
    • pc_7.f14
    • pc-sc.f14
    • pc-sc.f19
    • pc-sc.f8
    • pc-sc.f9
    • persian.f14
    • persian.f16
    • police.f16
    • polish.f14
    • pp_roman.f16
    • pp_sser.f16
    • readabl7.f16
    • readabl8.f16
    • readable.f08
    • readable.f10
    • reverse.f14
    • rimrock.f10
    • rmrkbold.f14
    • rom8pix.f08
    • roman.f14
    • roman.f16
    • roman1.f14
    • roman1.f19
    • roman1.f8
    • roman1.f9
    • roman2.f14
    • roman2.f19
    • roman2.f8
    • roman2.f9
    • runic.f14
    • runic.f16
    • russian.f08
    • russian.f14
    • russian.f16
    • sans1.f14
    • sans1.f19
    • sans1.f8
    • sans1.f9
    • sans1-sc.f14
    • sans1-sc.f19
    • sans1-sc.f8
    • sans1-sc.f9
    • sans2.f14
    • sans2.f19
    • sans2.f8
    • sans2.f9
    • sans2-sc.f14
    • sans2-sc.f19
    • sans2-sc.f8
    • sans2-sc.f9
    • sans3.f14
    • sans3.f19
    • sans3-sc.f14
    • sans3-sc.f19
    • sans4.f14
    • sans4.f19
    • sans4-sc.f14
    • sans4-sc.f19
    • sanserif.f14
    • sanserif.f16
    • script.f14
    • script1.f14
    • script1.f19
    • script1.f8
    • script1.f9
    • script2.f14
    • script2.f19
    • script2.f8
    • script2.f9
    • scrwl---.f16
    • scrwl~~~.f16
    • security.f14
    • side.f10
    • slant.f14
    • smalcaps.f14
    • smcapnum.f14
    • spranto.f14
    • spranto1.f16
    • spranto2.f16
    • square.f12
    • standard.f14
    • standard.f16
    • stretch.f14
    • subsup.f16
    • super.f16
    • swiss.f16
    • swiss-av.f16
    • swissav2.f16
    • swissbox.f16
    • swissbx2.f16
    • tex-math.f14
    • tex-math.f16
    • thai.f14
    • thin.f08
    • thin.f10
    • thin_ss.f08
    • thin_ss.f14
    • thin_ss.f16
    • thinasci.f07
    • thincaps.f14
    • thindemo.f14
    • thinscrp.f14
    • uv.cnf
    • vga-rom.f08
    • vga-rom.f14
    • vga-rom.f16
    • voynich.f16
    • wiggly.f16
    • windows.f14
    • windows.f19
    • windows.f8
    • windows.f9
    • yogiprog.inf
  • led.scroll.zip
  • led.scroll.src.zip
  • led.scroll-noexe.zip
  • led.scroll-noexe-noexe.zip
//**********************************************************************
//  Copyright (c) 2009-2014  Daniel D Miller
//  wShowFont.exe - Viewer for raster font files
//  
//  Written by:   Daniel D. Miller
//**********************************************************************
//  version		changes
//	 =======		======================================
//    1.00     original, derived from wFontList
//****************************************************************************

static char const * const Version = "wShowFont, Version 1.00" ;

#include <windows.h>
#include <stdio.h>
#include <math.h>
#include <sys/stat.h>
#include <time.h>
// #include <commctrl.h>

#include "resource.h"
#include "common.h"
#include "commonw.h"
#include "statbar.h"
#include "fontmgr.h"
#include "lrender.h"
#ifdef  USE_WINMSGS
#include "winmsgs.h"
#endif

//  tooltips.cpp
extern HWND create_tooltips(HWND hwnd, uint max_width, uint popup_msec, uint stayup_msec);
extern void add_program_tooltips(HWND hwnd, HWND hwndToolTip);

//lint -esym(526, atoi)
//lint -esym(628, atoi)
//lint -esym(746, atoi)
//lint -esym(1055, atoi)

//lint -esym(715, hwnd, private_data, message, wParam, lParam)
//***********************************************************************

extern HINSTANCE g_hinst ;
static uint main_timer_id = 0 ;

static CStatusBar *MainStatusBar = NULL;

static uint cxClient = 0;
static uint cyClient = 0;   //  subtrace height of status bar

static bool init_done = false ;
static bool handle_restore = false ;

//lint -esym(844, hwndBitGapSpin, hwndCharGapSpin, hwndPixDiamSpin)
static HWND hwndFontName    = NULL ;
static HWND hwndPixDiam     = NULL ;
static HWND hwndBitGap      = NULL ;
static HWND hwndCharGap     = NULL ;
static HWND hwndPixDiamSpin = NULL ;
static HWND hwndBitGapSpin  = NULL ;
static HWND hwndCharGapSpin = NULL ;
static HWND hwndSetAttr     = NULL ;
static HWND hwndClearAttr   = NULL ;
static HWND hwndBgndAttr    = NULL ;
static HWND hwndShowFont    = NULL ;

static char font_name[1024] = "script2.f19" ;
// static char font_name[1024] = "fntcol\\readable.f08" ;
static lrender *test_led ;

// static uint const MAX_DIAMETER = 3 ;   //  from lrender.h
// static uint const MAX_BIT_GAP  = 3 ;   //  from lrender.h
static uint const MAX_CHAR_GAP = 6 ;

static lrender_init_t test_init = {
   font_name, 3, 1, 2, SQUARE_PIXELS, RGB(31, 31, 31), RGB(63, 181, 255), RGB(23, 64, 103)
} ;

//***********************************************************************
static uint screen_width  = 0 ;
static uint screen_height = 0 ;

static void get_monitor_dimens(HWND hwnd)
{
   HMONITOR currentMonitor;      // Handle to monitor where fullscreen should go
   MONITORINFO mi;               // Info of that monitor
   currentMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
   mi.cbSize = sizeof(MONITORINFO);
   if (GetMonitorInfo(currentMonitor, &mi) != FALSE) {
      screen_width  = mi.rcMonitor.right  - mi.rcMonitor.left ;
      screen_height = mi.rcMonitor.bottom - mi.rcMonitor.top ;
   }
}

static uint get_screen_width(void)
{
   return screen_width ;
}

static uint get_screen_height(void)
{
   return screen_height ;
}

//***********************************************************************
void show_statbar_msg(char *msg)
{
   // StatusBar_SetBgndColor(hwndStatusBar, RGB(0, 255, 0)) ;
   // StatusBar_SetText(hwndStatusBar, 0, 0, msg);
   MainStatusBar->show_message(msg);
}

//***********************************************************************
//lint -esym(714, show_statbar_msg)
//lint -esym(759, show_statbar_msg)
//lint -esym(765, show_statbar_msg)
void show_statbar_msg(uint idx, char *msg)
{
   // StatusBar_SetBgndColor(hwndStatusBar, RGB(0, 255, 0)) ;
   // StatusBar_SetText(hwndStatusBar, 0, 0, msg);
   MainStatusBar->show_message(idx, msg);
}

//***********************************************************************
void show_statbar_msg(char *msg, COLORREF bgnd)
{
   MainStatusBar->set_bgnd_color(bgnd);
   // StatusBar_SetText(hwndStatusBar, 0, 0, msg);
   MainStatusBar->show_message(msg);
}

//**************************************************************************
//  remove static, to get rid of compiler warning about unused function.
//  I want to keep this function present, for reference purposes.
//**************************************************************************
//lint -esym(714, show_statbar_msgf)
//lint -esym(759, show_statbar_msgf)
//lint -esym(765, show_statbar_msgf)
int show_statbar_msgf(const char *fmt, ...)
{
   char consoleBuffer[260] ;
   va_list al; //lint !e522

   va_start(al, fmt);   //lint !e1055 !e530
   vsprintf(consoleBuffer, fmt, al);   //lint !e64
   show_statbar_msg(consoleBuffer);
   va_end(al);
   return 1;
}

//********************************************************************
static int show_statbar_msgfn(uint idx, const char *fmt, ...)
{
   char consoleBuffer[260] ;
   va_list al; //lint !e522

   va_start(al, fmt);   //lint !e1055 !e530
   vsprintf(consoleBuffer, fmt, al);   //lint !e64
   show_statbar_msg(idx, consoleBuffer);
   va_end(al);
   return 1;
}

/****************************************************************************
 * This hook procedure, which allows ClearIcon to position the color dialog
 * as desired, was extracted from Nancy Cluts, Chapter 06, cmndlg32.
 * The technique of setting the dialog position by trapping WM_INITDIALOG
 * in the hook procedure, was taken from comments on the web.
****************************************************************************/
#define  USE_CHOOSECOLOR_HOOK    1

#ifdef  USE_CHOOSECOLOR_HOOK
static BOOL APIENTRY ChooseColorHookProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
{
   switch (message) {
   case WM_INITDIALOG:
      {
      DWORD UFLAGS = SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW;
      SetWindowPos(hDlg, HWND_TOP, 400, 300, 0, 0, UFLAGS);
      }   
      break;
        
   //  Calling syslog() here, causes dialog to not close
   // case WM_COMMAND:
   //    if (LOWORD(wParam) == IDOK) {
   //       syslog("IDOK\n") ;
   //       return (TRUE);
   //    }
   //    else if (LOWORD(wParam) == IDCANCEL) {
   //       syslog("IDCANCEL\n") ;
   //       return TRUE;
   //    } else {
   //       syslog("0x%04X\n", LOWORD(wParam)) ;
   //    }
   //    break;
   }  //lint !e744 switch statement has no default
   return (FALSE);
}
#endif

//****************************************************************
static COLORREF select_color(HWND hwnd, COLORREF old_attr)
{
   static CHOOSECOLOR cc ;
   static COLORREF    crCustColors[16] ;

   // uint idx ;
   // for (idx=0; idx<16; idx++) {
   //    crCustColors[idx] = RGB(idx, idx, idx) ;
   // }

   ZeroMemory(&cc, sizeof(cc));
   cc.lStructSize    = sizeof (CHOOSECOLOR) ;
   cc.rgbResult      = old_attr ;
   cc.lpCustColors   = crCustColors ;
#ifdef  USE_CHOOSECOLOR_HOOK
   cc.Flags          = CC_RGBINIT | CC_FULLOPEN | CC_ENABLEHOOK;
   cc.lpfnHook = (LPCCHOOKPROC) ChooseColorHookProc;
   // cc.lpTemplateName = (LPTSTR) NULL;  //  not needed, struct was 0'd out
#else
   cc.Flags          = CC_RGBINIT | CC_FULLOPEN ;
#endif
   cc.hwndOwner      = hwnd ;

   if (ChooseColor(&cc) == TRUE) {
      return cc.rgbResult ;
   } else {
      return old_attr ;
   }
}  //lint !e715

//*********************************************************************
//  clear entire background of current field
//*********************************************************************
static void fill_color_field(HWND hwnd, COLORREF attr)
{
   RECT m_rect ;
   GetClientRect(hwnd, &m_rect);

   HDC hdc = GetDC(hwnd) ;
   HBRUSH hbBkBrush = CreateSolidBrush(attr);
   FillRect(hdc, &m_rect, hbBkBrush);
   DeleteObject(hbBkBrush);
   ReleaseDC(hwnd, hdc) ;
}

//*********************************************************************
//  draw the target objects
//*********************************************************************
static void update_display(void)
{
   // show_statbar_msgf("font: %s", font_name) ;
   fill_color_field(hwndShowFont,  test_init.bgnd) ;
   unsigned diameter, bit_gap, char_gap ;
   test_led->get_dimens(&diameter, &bit_gap, &char_gap) ;
   unsigned char_dx = test_led->get_char_width() ;
   unsigned char_dy = test_led->get_char_height() ;

   unsigned y_offset = 10 ;
   u8 idx = 0 ;
   unsigned row, col ;
   for (row=0; row<8; row++) {
      unsigned x_offset = 10 ;
      for (col=0; col<32; col++) {
         test_led->write_led_char(x_offset, y_offset, idx) ;
         x_offset += char_dx + char_gap;
         idx++ ;
      }
      y_offset += char_dy + char_gap;
   }
}

//************************************************************************
static char const szPalFilter[]  = "Font Files (*.F*)\0*.f*\0"  \
                                   "All Files (*.*)\0*.*\0\0" ;

static bool read_font_file(HWND hwnd)
{
   OPENFILENAME ofn;       // common dialog box structure
   char szFile[260];       // buffer for file name
   char oldFile[260];       // buffer for file name
   char dirFile[260];       // buffer for file name
   // HWND hwnd;              // owner window
   // HANDLE hf;              // file handle

   // Initialize OPENFILENAME
   ZeroMemory(&ofn, sizeof(ofn));
   ofn.lStructSize = sizeof(ofn);
   ofn.hwndOwner = hwnd;
   ofn.lpstrFile = szFile;
   //
   // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
   // use the contents of szFile to initialize itself.
   //
   ofn.lpstrFile[0] = '\0';
   strcpy(dirFile, font_name) ;
   char *strptr = strrchr(dirFile, '\\') ;
   if (strptr != 0) {
      strptr++ ;  //  leave the backslash in place
      *strptr = 0 ;  //  strip off filename
      // OutputDebugString(dirFile) ;
   }
   ofn.lpstrInitialDir = dirFile ;
   ofn.nMaxFile = sizeof(szFile);
   ofn.lpstrFilter = szPalFilter ;
   ofn.nFilterIndex = 1;
   ofn.lpstrTitle = "select font file" ;
   ofn.lpstrFileTitle = NULL ;
   ofn.lpstrDefExt = TEXT ("f*") ;
   // ofn.nMaxFileTitle = 0;
   // ofn.lpstrInitialDir = NULL;
   ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

   // Display the Open dialog box. 
   if (GetOpenFileName(&ofn) == TRUE) {
      strncpy(oldFile, font_name, sizeof(oldFile)) ;
      strncpy(font_name, ofn.lpstrFile, sizeof(font_name)) ;

      // test_led->set_options(WHOLE_SPACE, SQUARE_PIXELS) ;
      int result = test_led->read_file(font_name) ;
      if (result != 0) {
         // wsprintf(tempstr, "%s: %s", palette_filename, strerror(result)) ;
         syslog("%s: read failed", font_name) ;
         strncpy(font_name, oldFile, sizeof(font_name)) ;
         return false;
      }
      return true;
   }
   return false;
}

//****************************************************************************
static uint read_count(HWND hwnd)
{
   char tempbfr[11] ;
   GetWindowTextA (hwnd, tempbfr, 10);
   tempbfr[10] = 0 ;
   char *tptr = strip_leading_spaces(tempbfr) ;
   return (uint) atoi(tptr) ;
}

//*******************************************************************
static bool do_init_dialog(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LPVOID private_data)
{
   char msgstr[81] ;
   wsprintfA(msgstr, "%s", Version) ;
   SetWindowTextA(hwnd, msgstr) ;

   SetClassLongA(hwnd, GCL_HICON,   (LONG) LoadIcon(g_hinst, (LPCSTR) LCDTICO));
   SetClassLongA(hwnd, GCL_HICONSM, (LONG) LoadIcon(g_hinst, (LPCSTR) LCDTICO));
   get_monitor_dimens(hwnd);

   {  //  create local context
   RECT myRect ;
   GetClientRect(hwnd, &myRect) ;
   cxClient = (myRect.right - myRect.left) ;
   cyClient = (myRect.bottom - myRect.top) ;

   //****************************************************************
   //  create/configure status bar first
   //****************************************************************
   MainStatusBar = new CStatusBar(hwnd) ;
   MainStatusBar->MoveToBottom(cxClient, cyClient) ;

   //  re-position status-bar parts
   {
   int sbparts[3];
   sbparts[0] = (int) (6 * cxClient / 10) ;
   sbparts[1] = (int) (8 * cxClient / 10) ;
   sbparts[2] = -1;
   MainStatusBar->SetParts(3, &sbparts[0]);
   }
   }

   //*****************************************
   //  initialize controls
   //*****************************************
   CheckRadioButton (hwnd, IDC_RB_ROUND, IDC_RB_SQUARE, IDC_RB_ROUND + test_init.pixel_type) ;
   // show_statbar_msgf("pixel type = %s", (test_init.pixel_type == ROUND_PIXELS) ? "Round" : "Square") ;

   hwndFontName = GetDlgItem(hwnd, IDC_FONTNAME) ;
   wsprintf(msgstr, "%s", test_init.font_name) ;
   SetWindowText(hwndFontName, msgstr) ;

   //  manage pixel-diameter field
   hwndPixDiam = GetDlgItem(hwnd, IDC_PIXDIAM) ;
   hwndPixDiamSpin = MyCreateUpDownControl(
      // WS_CHILD|WS_VISIBLE|UDS_SETBUDDYINT|UDS_ALIGNRIGHT|WS_BORDER,
      // 0, 0, 0, 0,          // size and position
      hwnd,                // parent handle
      IDC_PIXDIAMSPIN,     // updown ID
      g_hinst,             // instance handle
      hwndPixDiam,         // associated field, or NULL
      MAX_DIAMETER,        // max value
      1,                   // min value
      test_init.diameter); // initial value

   //  manage bit-gap field
   hwndBitGap  = GetDlgItem(hwnd, IDC_BITGAP) ;
   hwndBitGapSpin = MyCreateUpDownControl(
      // WS_CHILD|WS_VISIBLE|UDS_SETBUDDYINT|UDS_ALIGNRIGHT|WS_BORDER,
      // 0, 0, 0, 0,          // size and position
      hwnd,                // parent handle
      IDC_BITGAPSPIN,      // updown ID
      g_hinst,             // instance handle
      hwndBitGap,          // associated field, or NULL
      MAX_BIT_GAP,         // max value
      0,                   // min value
      test_init.bit_gap);  // initial value

   //  manage char-gap field
   hwndCharGap = GetDlgItem(hwnd, IDC_CHARGAP) ;
   hwndCharGapSpin = MyCreateUpDownControl(
      // WS_CHILD|WS_VISIBLE|UDS_SETBUDDYINT|UDS_ALIGNRIGHT|WS_BORDER,
      // 0, 0, 0, 0,          // size and position
      hwnd,                // parent handle
      IDC_CHARGAPSPIN,     // updown ID
      g_hinst,             // instance handle
      hwndCharGap,         // associated field, or NULL
      MAX_CHAR_GAP,        // max value
      0,                   // min value
      test_init.char_gap); // initial value

   //  fill in color fields
   hwndSetAttr   = GetDlgItem(hwnd, IDC_SHOW_SET) ;
   hwndClearAttr = GetDlgItem(hwnd, IDC_SHOW_CLEAR) ;
   hwndBgndAttr  = GetDlgItem(hwnd, IDC_SHOW_BGND) ;
   hwndShowFont  = GetDlgItem(hwnd, IDC_SHOW_FONT) ;

   HWND hToolTip = create_tooltips(hwnd, 150, 100, 10000) ;
   add_program_tooltips(hwnd, hToolTip) ;

   //  do some of the init work later, because it does not work now
   main_timer_id = SetTimer(hwnd, IDT_TIMER_MAIN, 100, (TIMERPROC) NULL) ;
   return true ;
}

//*******************************************************************
static bool do_timer(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LPVOID private_data)
{
   switch (wParam) {
   case IDT_TIMER_MAIN:
      if (main_timer_id != 0) {
         if (!init_done) {
            fill_color_field(hwndSetAttr,   test_init.set_bit) ;
            fill_color_field(hwndClearAttr, test_init.clear_bit) ;
            fill_color_field(hwndBgndAttr,  test_init.bgnd) ;

            test_led = new lrender(hwndShowFont, &test_init) ;
            test_led->set_clipping_region() ;
            update_display() ;
            show_statbar_msgfn(1, "screen size: %ux%u", get_screen_width(), get_screen_height());
            init_done = true ;
         } else if (handle_restore) {
            update_display() ;
            handle_restore = false ;
         }

         KillTimer(hwnd, main_timer_id) ;
         main_timer_id = 0 ;
      }
      break;

   default:
      break;
      // return DefWindowProcA(hwnd, iMsg, wParam, lParam);
   }
   return true ;
}

//*******************************************************************
static bool do_vscroll(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LPVOID private_data)
{
// #define SB_THUMBPOSITION   4
// #define SB_ENDSCROLL       8
// [3496] scroll code=4, nPos=2
// [3496] scroll code=8, nPos=2
//    syslog("scroll code=%u, nPos=%u\n", LOWORD(wParam), HIWORD(wParam)) ;
   if (LOWORD(wParam) != SB_ENDSCROLL)
      return false;
   if (hwndPixDiamSpin == (HWND) lParam) {
      test_init.diameter = read_count(hwndPixDiam) ;
      test_led->set_dimens(test_init.diameter, test_init.bit_gap, test_init.char_gap) ;
      update_display() ;
      return true;
   } 
   if (hwndBitGapSpin == (HWND) lParam) {
      test_init.bit_gap = read_count(hwndBitGap) ;
      test_led->set_dimens(test_init.diameter, test_init.bit_gap, test_init.char_gap) ;
      update_display() ;
      return true;
   } 
   if (hwndCharGapSpin == (HWND) lParam) {
      test_init.char_gap = read_count(hwndCharGap) ;
      test_led->set_dimens(test_init.diameter, test_init.bit_gap, test_init.char_gap) ;
      update_display() ;
      return true;
   } 
   return false ;
}

//*******************************************************************
//  handle minimize/restore
//*******************************************************************
static bool do_size(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LPVOID private_data)
{
   if (wParam == SIZE_RESTORED) {
      handle_restore = true ;
      main_timer_id = SetTimer(hwnd, IDT_TIMER_MAIN, 50, (TIMERPROC) NULL) ;
      //  I'm getting here on Restore, but update_display() is failing...
      //  Okay, this is actually working, but something else after this
      //  redraws the entire window, and erases this!!
      // update_display() ;
      // return true ;
   } 
   return false ;
}

//*******************************************************************
//  handle drag off-screen and the back on-screen,
//  or redraw after being covered by something else, then restored
//*******************************************************************
static bool do_erasebkgnd(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LPVOID private_data)
{
   if (init_done)
      update_display() ;
   return false ;
}

//*******************************************************************
static bool do_command(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LPVOID private_data)
{
   TCHAR msgstr[81] ;
   int result ;

   DWORD cmd = HIWORD (wParam) ;
   DWORD target = LOWORD(wParam) ;
   // termout(&this_term, "WM_COMMAND: cmd=%u, target=%u", cmd, target) ;
   if (cmd == BN_CLICKED) {
      switch (target) {
      case IDC_RB_SQUARE:
      case IDC_RB_ROUND:
         test_init.pixel_type = target - IDC_RB_ROUND ;
         CheckRadioButton (hwnd, IDC_RB_ROUND, IDC_RB_SQUARE, IDC_RB_ROUND + test_init.pixel_type) ;
         // show_statbar_msgf("pixel type = %s", (test_init.pixel_type == ROUND_PIXELS) ? "Round" : "Square") ;
         test_led->set_options(WHOLE_SPACE, test_init.pixel_type) ;
         update_display() ;
         return true;

      case IDB_LOAD_FONT:
         if (read_font_file(hwnd)) {
            wsprintf(msgstr, "%s", test_init.font_name) ;
            SetWindowText(hwndFontName, msgstr) ;
            update_display() ;
            return true;
         }
         return true;

      case IDB_ATTR_SET:
         result = select_color(hwnd, test_init.set_bit) ;
         if (result >= 0) {
            test_init.set_bit = (COLORREF) result ;
            fill_color_field(hwndSetAttr,   test_init.set_bit) ;
            test_led->set_attr(test_init.set_bit, test_init.clear_bit, test_init.bgnd) ;
            update_display() ;
         }
         return true;

      case IDB_ATTR_CLEAR:
         result = select_color(hwnd, test_init.clear_bit) ;
         if (result >= 0) {
            test_init.clear_bit = (COLORREF) result ;
            fill_color_field(hwndClearAttr, test_init.clear_bit) ;
            test_led->set_attr(test_init.set_bit, test_init.clear_bit, test_init.bgnd) ;
            update_display() ;
         }
         return true;

      case IDB_ATTR_BGND:
         result = select_color(hwnd, test_init.bgnd) ;
         if (result >= 0) {
            test_init.bgnd = (COLORREF) result ;
            fill_color_field(hwndBgndAttr,  test_init.bgnd) ;
            test_led->set_attr(test_init.set_bit, test_init.clear_bit, test_init.bgnd) ;
            update_display() ;
         }
         return true;
         
      case IDOK:
         PostMessage(hwnd, WM_CLOSE, 0, 0);
         return true;

      default:
         break;
      }  //lint !e744
   } 
   return false ;
}

//*******************************************************************
//  handle main-dialog resizing
//*******************************************************************
static bool do_sizing(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LPVOID private_data)
{
   switch (wParam) {
   case WMSZ_BOTTOMLEFT:
   case WMSZ_BOTTOMRIGHT:
   case WMSZ_TOPLEFT:
   case WMSZ_TOPRIGHT:
   case WMSZ_LEFT:
   case WMSZ_RIGHT:
   case WMSZ_TOP:
   case WMSZ_BOTTOM:
      // resize_child_dialog(true);
      return true;

   default:
      return false;
   }
}

//*******************************************************************
#define  SF_MIN_DX      950
#define  SF_MIN_DY      400

static bool do_getminmaxinfo(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LPVOID private_data)
{
   LPMINMAXINFO lpTemp = (LPMINMAXINFO) lParam;
   POINT        ptTemp;
   //  set minimum dimensions
   ptTemp.x = SF_MIN_DX ;  //  empirical value
   ptTemp.y = SF_MIN_DY ;  //  empirical value
   lpTemp->ptMinTrackSize = ptTemp;
   //  set maximum dimensions
   ptTemp.x = get_screen_width() ;
   ptTemp.y = get_screen_height() ;
   lpTemp->ptMaxTrackSize = ptTemp;
   return true ;
}

//*******************************************************************
static bool do_exitsizemove(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LPVOID private_data)
{
   // save_window_origin() ;  //  update config file if necessary
   update_display() ;
   return true ;
}

//*******************************************************************
static bool do_close(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LPVOID private_data)
{
   DestroyWindow(hwnd);
   return true ;
}

//*******************************************************************
static bool do_destroy(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LPVOID private_data)
{
   delete MainStatusBar ;
   MainStatusBar = NULL ;

   delete test_led ;
   test_led = NULL ;

   init_done = false ;
   handle_restore = false ;
   
   // PostQuitMessage(0);  //  this closes parent as well
   return true ;
}

//*******************************************************************
// typedef struct winproc_table_s {
//    uint win_code ;
//    bool (*winproc_func)(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LPVOID private_data) ;
// } winproc_table_t ;

static winproc_table_t const winproc_table[] = {
{ WM_INITDIALOG,     do_init_dialog },
{ WM_COMMAND,        do_command },
{ WM_TIMER,          do_timer },
{ WM_VSCROLL,        do_vscroll },
{ WM_SIZE,           do_size },
{ WM_ERASEBKGND,     do_erasebkgnd },
{ WM_GETMINMAXINFO,  do_getminmaxinfo },
{ WM_SIZING,         do_sizing },
{ WM_EXITSIZEMOVE,   do_exitsizemove },
{ WM_CLOSE,          do_close },
{ WM_DESTROY,        do_destroy },
{ 0, NULL } } ;

//*******************************************************************
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
#ifdef  USE_WINMSGS
   switch (message) {
   //  list messages to be ignored
   case WM_CTLCOLORBTN:
   case WM_CTLCOLORSTATIC:
   case WM_CTLCOLOREDIT:
   case WM_MOUSEMOVE:
   case WM_NCMOUSEMOVE:
   case WM_NCHITTEST:
   case WM_SETCURSOR:
   case WM_TIMER:
   case WM_NOTIFY:
   case WM_COMMAND:  //  prints its own msgs below
      break;
   default:
      syslog("TOP [%s]\n", lookup_winmsg_name(message)) ;
      break;
   }
#endif
   uint idx ;
   for (idx=0; winproc_table[idx].win_code != 0; idx++) {
      if (winproc_table[idx].win_code == message) {
         return (*winproc_table[idx].winproc_func)(hwnd, message, wParam, lParam, NULL) ;
      }
   }
   return false;
}  //lint !e715

//*********************************************************************
static bool font_viewer_active = false ;

bool show_font_viewer(void)
{
   if (font_viewer_active)
      return false ;
   font_viewer_active = true ;
   load_exec_filename() ;     //  get our executable name

   //  create the main application
   // DialogBox(g_hinst, MAKEINTRESOURCE(IDD_SF_DIALOG), hwndParent, (DLGPROC) WndProc);
   DialogBox(g_hinst, MAKEINTRESOURCE(IDD_SF_DIALOG), NULL, (DLGPROC) WndProc);
   font_viewer_active = false ;
   return true;
}  //lint !e715

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Retired
United States United States
I have worked for 25+ years as a firmware engineer, in various environments. In my private life, I create a variety of applications, including console applications in Linux and Windows, and GUI applications in Windows. All of my programs and code snippets are freeware, with source code available. All programs are written in C or C++, and built using the MinGW toolchain.

Comments and Discussions