added logging basics
This commit is contained in:
parent
eab95844b8
commit
730b1205f7
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
* @file logger.h
|
||||
* @brief cppSimpleLogger Header
|
||||
* @author hendrik schutter
|
||||
* @date 04.09.2020
|
||||
*/
|
||||
|
||||
#ifndef LOGGER_H_
|
||||
#define LOGGER_H_
|
||||
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <math.h>
|
||||
#include <mutex>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define MENU_LINE_SIZE 110 //Size of menu lines
|
||||
|
||||
#ifndef LOG_PATH
|
||||
//#define LOG_PATH "./test.txt"
|
||||
#endif
|
||||
|
||||
#ifndef DESCRIPTION
|
||||
#define DESCRIPTION "Software-Name - Copyright Company 2020" //use your values here
|
||||
#endif
|
||||
|
||||
#ifndef DEVICE_ID
|
||||
#define DEVICE_ID "Device-Name" //use your values here
|
||||
#endif
|
||||
|
||||
#ifndef SOFTWARE_VERSION
|
||||
#define SOFTWARE_VERSION "0.1.1.8" //use your values here
|
||||
#endif
|
||||
|
||||
#ifndef HARDWARE_VERSION
|
||||
#define HARDWARE_VERSION "7.77.9" //use your values here
|
||||
#endif
|
||||
|
||||
class Logger
|
||||
{
|
||||
private:
|
||||
string logPath;
|
||||
mutex mtxLog;
|
||||
|
||||
static bool instanceFlag;
|
||||
static Logger *single;
|
||||
|
||||
string getTimestamp();
|
||||
void writeLog(string s);
|
||||
string getMacAddress();
|
||||
string padStringMenu(char cBorder, string text, uint8_t u8LineLenght);
|
||||
string menuLine(char cBorder, uint8_t u8LineLenght);
|
||||
Logger();
|
||||
~Logger();
|
||||
|
||||
public:
|
||||
|
||||
void info(string s);
|
||||
void warning(string s);
|
||||
void error(string s);
|
||||
void newLine();
|
||||
|
||||
static Logger* logThis();
|
||||
};
|
||||
|
||||
#endif // LOGGER_H_
|
|
@ -18,6 +18,13 @@
|
|||
#define READ 0
|
||||
#define WRITE 1
|
||||
|
||||
// Logger Settings
|
||||
#define LOG_PATH "./reHDD.log"
|
||||
#define DESCRIPTION "reHDD - Copyright Hendrik Schutter 2020"
|
||||
#define DEVICE_ID "generic"
|
||||
#define SOFTWARE_VERSION "alpha"
|
||||
#define HARDWARE_VERSION "generic"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
@ -43,7 +50,9 @@ using namespace std;
|
|||
#include "shred/shred.h"
|
||||
#include "delete.h"
|
||||
#include "tui.h"
|
||||
#include "logger/logger.h"
|
||||
|
||||
extern Logger* logging;
|
||||
|
||||
template <typename T, typename I> T* iterator_to_pointer(I i)
|
||||
{
|
||||
|
@ -56,10 +65,12 @@ protected:
|
|||
|
||||
public:
|
||||
reHDD(void);
|
||||
void app_logic();
|
||||
static void app_logic();
|
||||
|
||||
private:
|
||||
|
||||
//static Logger* logging;
|
||||
|
||||
static void searchDrives(vector <Drive>* pvecDrives);
|
||||
static void printDrives(vector <Drive>* pvecDrives);
|
||||
static void filterIgnoredDrives(vector <Drive>* pvecDrives);
|
||||
|
@ -76,4 +87,4 @@ private:
|
|||
};
|
||||
|
||||
|
||||
#endif // REHDD_H_
|
||||
#endif // REHDD_H_
|
||||
|
|
|
@ -0,0 +1,235 @@
|
|||
/**
|
||||
* @file logger.cpp
|
||||
* @brief cppSimpleLogger implementation
|
||||
* @author hendrik schutter
|
||||
* @date 04.09.2020
|
||||
*/
|
||||
|
||||
|
||||
#include "../../include/reHDD.h" //for logger settings
|
||||
#include "../../include/logger/logger.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
string version = "0.2.1"; //logger version
|
||||
|
||||
bool Logger::instanceFlag = false;
|
||||
Logger* Logger::single = NULL;
|
||||
|
||||
/**
|
||||
* \brief create new logger instance
|
||||
* \param path to log file
|
||||
* \param struct with data
|
||||
* \return instance of Logger
|
||||
*/
|
||||
Logger::Logger()
|
||||
{
|
||||
this->logPath = LOG_PATH;
|
||||
|
||||
writeLog(menuLine('+', MENU_LINE_SIZE));
|
||||
writeLog(padStringMenu('+', " ", MENU_LINE_SIZE));
|
||||
|
||||
writeLog(padStringMenu('+', ("Device: " + string(DEVICE_ID) + " -- " + string(DESCRIPTION)), MENU_LINE_SIZE));
|
||||
writeLog(padStringMenu('+', " ", MENU_LINE_SIZE));
|
||||
|
||||
writeLog(padStringMenu('+', ("Software ID: " + string(SOFTWARE_VERSION) + " -- Build time: " + __DATE__ + " " + __TIME__), MENU_LINE_SIZE));
|
||||
writeLog(padStringMenu('+', " ", MENU_LINE_SIZE));
|
||||
|
||||
writeLog(padStringMenu('+', ("Hardware ID: " + string(HARDWARE_VERSION) + " -- MAC: " + getMacAddress()), MENU_LINE_SIZE));
|
||||
writeLog(padStringMenu('+', " ", MENU_LINE_SIZE));
|
||||
|
||||
writeLog(padStringMenu('+', ("cppSimpleLogger -- available from https://git.mosad.xyz/localhorst/cppSimpleLogger -- Version: " + version), MENU_LINE_SIZE));
|
||||
writeLog(padStringMenu('+', " ", MENU_LINE_SIZE));
|
||||
|
||||
writeLog(menuLine('+', MENU_LINE_SIZE));
|
||||
newLine();
|
||||
info("Created new log file");
|
||||
newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief deconstructor
|
||||
* \return void
|
||||
*/
|
||||
Logger::~Logger()
|
||||
{
|
||||
instanceFlag = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief log info
|
||||
* \param log-text as string
|
||||
* \return void
|
||||
*/
|
||||
void Logger::info(string s)
|
||||
{
|
||||
string tmp = getTimestamp() + " [INFO] " + s;
|
||||
writeLog(tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief log warning
|
||||
* \param log-text as string
|
||||
* \return void
|
||||
*/
|
||||
void Logger::warning(string s)
|
||||
{
|
||||
string tmp = getTimestamp() + " [WARNING] " + s;
|
||||
writeLog(tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief log error
|
||||
* \param log-text as string
|
||||
* \return void
|
||||
*/
|
||||
void Logger::error(string s)
|
||||
{
|
||||
string tmp = getTimestamp() + " [ERROR] " + s;
|
||||
writeLog(tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief write to log file
|
||||
* \param log as string
|
||||
* \return void
|
||||
*/
|
||||
void Logger::writeLog(string s)
|
||||
{
|
||||
ofstream logFile;
|
||||
Logger::mtxLog.lock(); //lock this section for other threads
|
||||
logFile.open(this->logPath, ios_base::app);
|
||||
|
||||
logFile << (s + "\n"); //append to existing file
|
||||
|
||||
logFile.close();
|
||||
Logger::mtxLog.unlock(); //unlock this section for other threads
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief write new line to log file
|
||||
* \return void
|
||||
*/
|
||||
void Logger::newLine()
|
||||
{
|
||||
writeLog(" ");
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief get timestamp (system time) as string
|
||||
* \param void
|
||||
* \return string timestamp (formatted)
|
||||
*/
|
||||
string Logger::getTimestamp()
|
||||
{
|
||||
struct tm * timeinfo;
|
||||
struct timeval tv;
|
||||
int millisec;
|
||||
char cpDate [80];
|
||||
char buffer [120];
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
millisec = lrint(tv.tv_usec/1000.0); // Round to nearest millisec
|
||||
if (millisec>=1000) // Allow for rounding up to nearest second
|
||||
{
|
||||
millisec -=1000;
|
||||
tv.tv_sec++;
|
||||
}
|
||||
timeinfo = localtime(&tv.tv_sec);
|
||||
strftime (cpDate,80,"%d/%m/%Y %T",timeinfo);
|
||||
sprintf(buffer, "%s.%03d", cpDate, millisec);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief get MAC address (system first eth0 interface) as string
|
||||
* \param void
|
||||
* \return string MAC address (formatted)
|
||||
*/
|
||||
string Logger::getMacAddress()
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int s = socket(AF_INET, SOCK_STREAM,0);
|
||||
|
||||
strcpy(ifr.ifr_name, "eth0");
|
||||
if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0)
|
||||
{
|
||||
strcpy(ifr.ifr_name, "eno1");
|
||||
|
||||
}
|
||||
|
||||
unsigned char *hwaddr = (unsigned char *)ifr.ifr_hwaddr.sa_data;
|
||||
char buffer [80];
|
||||
sprintf(buffer,"%02X:%02X:%02X:%02X:%02X:%02X", hwaddr[0], hwaddr[1], hwaddr[2],
|
||||
hwaddr[3], hwaddr[4], hwaddr[5]);
|
||||
close(s);
|
||||
string tmp = buffer;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief format menu text in center
|
||||
* \param char for border
|
||||
* \param menu text
|
||||
* \param size of menu line
|
||||
* \return string menu line
|
||||
*/
|
||||
string Logger::padStringMenu(char cBorder, string text, uint8_t u8LineLenght)
|
||||
{
|
||||
string result(1,cBorder);
|
||||
uint8_t u8TextSize = text.length();
|
||||
uint8_t u8Padding = ((u8LineLenght-u8TextSize)/2);
|
||||
|
||||
for(uint8_t i = 0 ; i < u8Padding; i++)
|
||||
{
|
||||
result.append(" ");
|
||||
}
|
||||
|
||||
result.append(text);
|
||||
|
||||
while((uint8_t)result.length() < (u8LineLenght-1))
|
||||
{
|
||||
|
||||
result.append(" ");
|
||||
}
|
||||
|
||||
result.append(string(1, cBorder));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief format a separator
|
||||
* \param char for border
|
||||
* \param size of menu line
|
||||
* \return string menu line
|
||||
*/
|
||||
string Logger::menuLine(char cBorder, uint8_t u8LineLenght)
|
||||
{
|
||||
string result(1,cBorder);
|
||||
|
||||
while((uint8_t)result.length() < u8LineLenght)
|
||||
{
|
||||
result.append(string(1, cBorder));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief return a instance of the logger
|
||||
* \return logger obj
|
||||
*/
|
||||
Logger* Logger::logThis()
|
||||
{
|
||||
if (!instanceFlag)
|
||||
{
|
||||
single = new Logger(); //create new obj
|
||||
instanceFlag = true;
|
||||
return single;
|
||||
}
|
||||
else
|
||||
{
|
||||
return single; //return existing obj
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +32,6 @@ static fd_set selectSet;
|
|||
*/
|
||||
reHDD::reHDD(void)
|
||||
{
|
||||
cout << "created app" << endl;
|
||||
u8SelectedEntry = 0U;
|
||||
}
|
||||
|
||||
|
@ -43,7 +42,6 @@ reHDD::reHDD(void)
|
|||
*/
|
||||
void reHDD::app_logic(void)
|
||||
{
|
||||
cout << "app logic" << endl;
|
||||
ui = new TUI();
|
||||
ui->initTUI();
|
||||
|
||||
|
@ -90,6 +88,7 @@ Drive* reHDD::getSelectedDrive()
|
|||
}
|
||||
else
|
||||
{
|
||||
Logger::logThis()->warning("selected drive not present");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +97,6 @@ void reHDD::ThreadScannDevices()
|
|||
{
|
||||
while(true)
|
||||
{
|
||||
// cout << "Thread" << endl;
|
||||
mxScannDrives.lock();
|
||||
vecNewDrives.clear();
|
||||
searchDrives(&vecNewDrives); //search for new drives and store them in list
|
||||
|
@ -180,13 +178,13 @@ void reHDD::ThreadShred()
|
|||
if (getSelectedDrive() != nullptr)
|
||||
{
|
||||
Shred::shredDrive(getSelectedDrive(), &fdShredInformPipe[1]);
|
||||
Logger::logThis()->info("Finished shred for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial());
|
||||
ui->updateTUI(&vecDrives, u8SelectedEntry);
|
||||
}
|
||||
}
|
||||
|
||||
void reHDD::filterNewDrives(vector <Drive>* pvecOldDrives, vector <Drive>* pvecNewDrives)
|
||||
{
|
||||
|
||||
vector <Drive>::iterator itOld; //Iterator for current (old) drive list
|
||||
vector <Drive>::iterator itNew; //Iterator for new drive list that was created from to scann thread
|
||||
|
||||
|
@ -209,6 +207,7 @@ void reHDD::filterNewDrives(vector <Drive>* pvecOldDrives, vector <Drive>* pvecN
|
|||
if(bOldDriveIsOffline == true)
|
||||
{
|
||||
//cout << "offline drive found: " << itOld->getPath() << endl;
|
||||
Logger::logThis()->warning("offline drive found delete for: " + itOld->getPath());
|
||||
itOld->state = Drive::NONE;
|
||||
}
|
||||
}
|
||||
|
@ -217,6 +216,7 @@ void reHDD::filterNewDrives(vector <Drive>* pvecOldDrives, vector <Drive>* pvecN
|
|||
for (long unsigned int i=0; i<pvecNewDrives->size(); i++)
|
||||
{
|
||||
pvecOldDrives->push_back((*pvecNewDrives)[i]);
|
||||
Logger::logThis()->info("Attached drive: " + i + string("-") + pvecNewDrives->at(i).getPath());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,8 +263,6 @@ void reHDD::filterIgnoredDrives(vector <Drive>* pvecDrives)
|
|||
|
||||
vector<tuple<string, string>> vtlIgnoredDevices; //store drives from ingnore file
|
||||
|
||||
//vector <Drive> vecTmpDrives
|
||||
|
||||
ifstream input( "ignoreDrives.conf" ); //read ingnore file
|
||||
|
||||
for(string sLine; getline( input, sLine );)
|
||||
|
@ -280,8 +278,6 @@ void reHDD::filterIgnoredDrives(vector <Drive>* pvecDrives)
|
|||
sLine.erase(0, pos + sDelimiter.length());
|
||||
sIgnoredDriveUUID = sLine;
|
||||
} //end while
|
||||
//cout << "Path: " << sIgnoredDrivePath << std::endl;
|
||||
//cout << "UUID: " << sIgnoredDriveUUID << std::endl;
|
||||
vtlIgnoredDevices.emplace_back(sIgnoredDrivePath, sIgnoredDriveUUID); //add found path and uuid from ingnore file to vector
|
||||
}
|
||||
}
|
||||
|
@ -322,14 +318,15 @@ void reHDD::filterIgnoredDrives(vector <Drive>* pvecDrives)
|
|||
if (get<1>(row).compare(sUUID)) //compare uuid from ignore file and uuid from drive
|
||||
{
|
||||
cout << "[ERROR] different uuid found than in ignore file:" << it->getPath() << endl;
|
||||
Logger::logThis()->error("[ERROR] different uuid found than in ignore file: " + it->getPath());
|
||||
exit(EXIT_FAILURE); // exit to prevent accidentally shred a system drive
|
||||
}
|
||||
else
|
||||
{
|
||||
// same uuid found than in ignore file --> ignore this drive
|
||||
Logger::logThis()->info("same uuid found than in ignore file --> ignore this drive: " + it->getPath());
|
||||
it = pvecDrives->erase(it);
|
||||
it--;
|
||||
//cout << "same uuid found than in ignore file --> ignore this drive:" << it->getPath() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -402,6 +399,8 @@ void reHDD::handleArrowKey(TUI::UserInput userInput)
|
|||
u8SelectedEntry = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
Logger::logThis()->info("ArrowKey - selected drive: " + to_string(u8SelectedEntry));
|
||||
}
|
||||
|
||||
void reHDD::handleEnter()
|
||||
|
@ -410,6 +409,7 @@ void reHDD::handleEnter()
|
|||
{
|
||||
if(getSelectedDrive()->state == Drive::TaskState::SHRED_SELECTED)
|
||||
{
|
||||
Logger::logThis()->info("Started shred for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial());
|
||||
getSelectedDrive()->state = Drive::TaskState::SHRED_ACTIVE;
|
||||
//task for drive is running --> don´t show more task options
|
||||
thread(ThreadShred).detach();
|
||||
|
@ -417,11 +417,13 @@ void reHDD::handleEnter()
|
|||
|
||||
if(getSelectedDrive()->state == Drive::TaskState::DELETE_SELECTED)
|
||||
{
|
||||
Logger::logThis()->info("Started delete for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial());
|
||||
getSelectedDrive()->state = Drive::TaskState::DELETE_ACTIVE;
|
||||
//task for drive is running --> don´t show more task options
|
||||
Delete::deleteDrive(getSelectedDrive()); //blocking, no thread
|
||||
getSelectedDrive()->state = Drive::TaskState::NONE; //delete finished
|
||||
getSelectedDrive()->bWasDeleteted = true;
|
||||
Logger::logThis()->info("Finished delete for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -451,6 +453,7 @@ void reHDD::handleAbort()
|
|||
if(getSelectedDrive()->state == Drive::SHRED_ACTIVE || getSelectedDrive()->state == Drive::DELETE_ACTIVE )
|
||||
{
|
||||
getSelectedDrive()->state = Drive::NONE;
|
||||
Logger::logThis()->info("Abort-Shred for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial());
|
||||
//task for drive is running --> remove selection
|
||||
}
|
||||
}
|
||||
|
|
15
src/tui.cpp
15
src/tui.cpp
|
@ -11,10 +11,8 @@ static std::mutex mxUIrefresh;
|
|||
|
||||
TUI::TUI(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief wipe drive with shred
|
||||
* \param pointer of Drive instance
|
||||
|
@ -33,6 +31,7 @@ void TUI::initTUI()
|
|||
else
|
||||
{
|
||||
printf("Your terminal does not support color\n");
|
||||
Logger::logThis()->error("Your terminal does not support color");
|
||||
exit(1);
|
||||
}
|
||||
clear();
|
||||
|
@ -48,6 +47,7 @@ void TUI::initTUI()
|
|||
init_pair(COLOR_AREA_DETAIL, COLOR_BLACK, COLOR_WHITE);
|
||||
|
||||
mvprintw(0, 2, "reHDD - HDD refurbishing tool - GPL 3.0 ");
|
||||
Logger::logThis()->info("UI successfully initialized");
|
||||
}
|
||||
|
||||
void TUI::updateTUI(vector <Drive>* pvecDrives, uint8_t u8SelectedEntry)
|
||||
|
@ -122,6 +122,7 @@ void TUI::updateTUI(vector <Drive>* pvecDrives, uint8_t u8SelectedEntry)
|
|||
if(pvecDrives->size() == 0)
|
||||
{
|
||||
//no selected drive present
|
||||
Logger::logThis()->warning("no selected drive present");
|
||||
struct MenuState menustate;
|
||||
menustate.bAbort = false;
|
||||
menustate.bConfirmDelete = false;
|
||||
|
@ -195,7 +196,6 @@ WINDOW* TUI::createOverViewWindow( int iXSize, int iYSize)
|
|||
|
||||
centerTitle(newWindow, "Detected Drives");
|
||||
|
||||
//keypad(newWindow, TRUE);
|
||||
return newWindow;
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,6 @@ WINDOW* TUI::createDetailViewWindow( int iXSize, int iYSize, int iXStart, Drive
|
|||
mvwaddstr(newWindow,u16Line++, 3, sErrorCount.c_str());
|
||||
}
|
||||
|
||||
//keypad(newWindow, TRUE);
|
||||
return newWindow;
|
||||
}
|
||||
|
||||
|
@ -295,7 +294,6 @@ WINDOW* TUI::overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart)
|
|||
|
||||
attroff(COLOR_PAIR(COLOR_AREA_DETAIL));
|
||||
|
||||
//keypad(newWindow, TRUE);
|
||||
return newWindow;
|
||||
}
|
||||
|
||||
|
@ -325,14 +323,11 @@ WINDOW* TUI::createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart,
|
|||
|
||||
mvwaddstr(newWindow,2, iXSize-sState.length()-5, sState.c_str());
|
||||
|
||||
//keypad(newWindow, TRUE);
|
||||
|
||||
return newWindow;
|
||||
}
|
||||
|
||||
WINDOW* TUI::createSystemStats(int iXSize, int iYSize, int iYStart)
|
||||
{
|
||||
|
||||
WINDOW *newWindow;
|
||||
newWindow = newwin(iYSize, iXSize, iYStart, 2);
|
||||
|
||||
|
@ -351,7 +346,6 @@ WINDOW* TUI::createSystemStats(int iXSize, int iYSize, int iYStart)
|
|||
|
||||
mvwaddstr(newWindow,2, 2, time.c_str());
|
||||
|
||||
//keypad(newWindow, TRUE);
|
||||
return newWindow;
|
||||
}
|
||||
|
||||
|
@ -380,7 +374,7 @@ WINDOW* TUI::createMenuView(int iXSize, int iYSize, int iXStart, int iYStart, st
|
|||
{
|
||||
mvwaddstr(newWindow,u16Line++, 3, "Press D for Delete");
|
||||
}
|
||||
//keypad(newWindow, TRUE);
|
||||
|
||||
return newWindow;
|
||||
}
|
||||
|
||||
|
@ -398,7 +392,6 @@ WINDOW* TUI::createDialog(int iXSize, int iYSize, int iXStart, int iYStart, stri
|
|||
mvwaddstr(newWindow,u16Line++, 3, optionA.c_str());
|
||||
mvwaddstr(newWindow,u16Line++, 3, optionB.c_str());
|
||||
|
||||
//keypad(newWindow, TRUE);
|
||||
return newWindow;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue