I am trying to display SQL result on a list control using MFC - sql

Please, I have list control on, I want to display my query result on a list control. The program runs without error, but it does not display the SQL result on the list control.
BOOL CClassDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
// TODO: Add extra initialization here
CString DSN;
DSN = _T("DRIVER=SQL Server;SERVER=DESKTOP-
DICUCDS\\SQL2K14;Trusted_Connection=Yes;APP=Microsoft\x00ae Visual Studio\x00ae 2013;WSID=DESKTOP-
DICUCDS;DATABASE=School");
CDatabase aDB;
try {
aDB.OpenEx(DSN);
CRecordset aRS(&aDB);
aRS.Open(CRecordset::forwardOnly, (L"SELECT DISTINCT Myclass FROM MyFacts"));
// populate Grids
ListView_SetExtendedListViewStyle(m_classlist, LVS_EX_GRIDLINES);
// Column width and heading
m_classlist.InsertColumn(1, L"Class", LVCFMT_LEFT, -1, 1);
m_classlist.InsertColumn(2, L"Age", LVCFMT_LEFT, -1, 1);
m_classlist.SetColumnWidth(0, 120);
m_classlist.SetColumnWidth(1, 200);
m_classlist.SetColumnWidth(2, 200);
while(!aRS.IsEOF())
{
CString strValue;
aRS.GetFieldValue(L"Myclass", strValue);
m_classlist.SetItemText(-1, 1, strValue);
//strValue.AddString(strValue);
aRS.MoveNext();
}
aRS.Close();
aDB.Close();
}
catch (CDBException * ex)
{
TCHAR buf[255];
ex->GetErrorMessage(buf, 255);
CString strPrompt(buf);
AfxMessageBox(strPrompt);
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CClassDialog::ResetListControl()
{
m_classlist.DeleteAllItems();
int iNbrOfColumns;
CHeaderCtrl* pHeader = (CHeaderCtrl*)m_classlist.GetDlgItem(0);
if (pHeader) {
iNbrOfColumns = pHeader->GetItemCount();
}
for (int i = iNbrOfColumns; i >= 0; i--) {
m_classlist.DeleteColumn(i);
}
}

Are you sure this is right? m_classlist.SetItemText(-1, 1, strValue);
If you research the official documentation for the CListCtrl (for example, here) you will see:
CString strText;
int nColumnCount = m_myListCtrl.GetHeaderCtrl()->GetItemCount();
// Insert 10 items in the list view control.
for (int i = 0; i < 10; i++)
{
strText.Format(TEXT("item %d"), i);
// Insert the item, select every other item.
m_myListCtrl.InsertItem(LVIF_TEXT | LVIF_STATE, i, strText,
(i % 2) == 0 ? LVIS_SELECTED : 0, LVIS_SELECTED, 0, 0);
// Initialize the text of the subitems.
for (int j = 1; j < nColumnCount; j++)
{
strText.Format(TEXT("sub-item %d %d"), i, j);
m_myListCtrl.SetItemText(i, j, strText);
}
}
You are making references to SetItemText but you have not actually added any elements into the list. The code before shows an example:
// Insert the item, select every other item.
m_myListCtrl.InsertItem(LVIF_TEXT | LVIF_STATE, i, strText,
(i % 2) == 0 ? LVIS_SELECTED : 0, LVIS_SELECTED, 0, 0);
I am not saying that you have to use that specific set of paramaters. But the point is that you must insert an item into the list before you can update it's properties. Or even set the properties at the moment you add it into the list.

Related

How to add JSpinner output into array and check for duplicate

I'm working on a code which has a JSpinner, which gives an output and moves it to int = n, I want to save every JSpinner output and add it into an array to check for duplicates and once found the JPanel should close itself or say you lost.
Scanner s = new Scanner(System.in);
int n = (Integer) spinner.getValue();
if (isPrime(n)) {
Input.setText(n + " is a prime number");
score++;
Highscore.setText("Score: " + score);
int[] array = new int[4];
for(int i=0; i<4;i++)
{
array[i]= (Integer) spinner.getValue();
}
for (int i=0; i < 4;i++)
{
System.out.println(array[i]);
}
Spinner output into array but it fills the whole array with one number example: [3,3,3,3].
private <T> boolean duplicate(T... array)
{
for (int i = 0; i < array.length; i++)
{
for (int j = i + 1; j < array.length; j++)
{
if (array[i] != null && array[i].equals(array[j])) {
return true;
dispose();
}
}
}
return false;
}
Duplicate check
I tried adding the user input from the JSpinner into an array and from there to check for duplicates.
Searched Online but could'nt find anything.
This if my first post so if you need anything more you can tell me.

wxGrid destructor Triggers Breakpoint on

I'm new to wxWidgets, although I've been able to get an application up and running fairly smoothly up until this point. For the main window, I'm using a wxGrid inside a wxPanel. Everything runs fine until I close the program.
Thanks in advance for any insight.
The grid is a member of a class derived from wxPanel:
class FormDataView
: public wxPanel
{
public:
FormDataView(wxWindow* parent);
virtual ~FormDataView();
private:
wxGrid* grid_;
}
And created in the constructor. The data for the grid comes from another thread, so I create a custom event for actually writing the data.
wxDEFINE_EVENT(FORMDATAVIEW_UPDATE, wxThreadEvent);
FormDataView::FormDataView(wxWindow* parent)
: wxPanel(parent,wxID_ANY )
{
wxBoxSizer* mbox = new wxBoxSizer(wxVERTICAL);
grid_ = new wxGrid(this, wxID_ANY );
grid_->CreateGrid(0, 0);
mbox->Add(grid_,wxSizerFlags(1).Expand());
Bind(FORMDATAVIEW_UPDATE, &FormDataView::onDataUpdate, this);
}
///
/// This function is called by a child thread when data is received.
///
void
FormDataView::onDataReceived(IFORMATTERBASE_PFONDATARECEIVED_ARGS)
{
newHeaders_ = headers;
newData_ = data;
wxThreadEvent* evt = new wxThreadEvent(FORMDATAVIEW_UPDATE);
evt->SetString("Yo.");
wxQueueEvent(this, evt);
}
///
/// Called by the event loop. This function puts the data
/// into the grid.
///
void
FormDataView::onDataUpdate(wxThreadEvent& evt)
{
FormatterStringList& headers = newHeaders_;
FormatterStringList& data = newData_;
if (grid_->GetNumberRows() <= 0)
{
wxGridCellAttr* attr = new wxGridCellAttr();
attr->SetReadOnly(true);
attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
for (size_t i = 0; i<headers.size(); ++i)
{
if (grid_->GetNumberCols() <= 0)
grid_->InsertCols();
else
grid_->AppendCols();
grid_->SetColLabelValue(i, headers[i].data());
grid_->SetColAttr(i, attr);
}
}
// suspend redrawing while we add data.
grid_->BeginBatch();
// insert a new row at the top of the table
grid_->InsertRows(
0, // position
1, // number of rows to insert
true); // update labels (not current used)
for (size_t i = 0; i<headers.size(); ++i)
{
if (data.size() < i)
{
grid_->SetCellValue(0, i, "");
}
else
{
grid_->SetCellValue(0, i, data[i].data());
}
}
// resume redrawing.
grid_->EndBatch();
}
Everything runs fine, but when I close, I get the following message. I've indicated the line upon which the breakpoint occurs. Is there some short of sequence for clearing data out of the grid I'm supposed to follow?
wxGrid::CellSpan
wxGrid::GetCellSize( int row, int col, int *num_rows, int *num_cols ) const
{
wxGridCellAttr *attr = GetCellAttr(row, col);
attr->GetSize( num_rows, num_cols );
attr->DecRef();
>>>>>>> if ( *num_rows == 1 && *num_cols == 1 )
return CellSpan_None; // just a normal cell
if ( *num_rows < 0 || *num_cols < 0 )
return CellSpan_Inside; // covered by a multi-span cell
// this cell spans multiple cells to its right/bottom
return CellSpan_Main;
}
The problem was with where I was creating the column attribute. I was re-using the same column attribute instance for every column, but each column needs to have its own instance.
BEFORE:
if (grid_->GetNumberRows() <= 0)
{
///
/// NO! The columns will share the same cell attribute
/// instance.
///
wxGridCellAttr* attr = new wxGridCellAttr();
attr->SetReadOnly(true);
attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
for (size_t i = 0; i<headers.size(); ++i)
{
if (grid_->GetNumberCols() <= 0)
grid_->InsertCols();
else
grid_->AppendCols();
grid_->SetColLabelValue(i, headers[i].data());
grid_->SetColAttr(i, attr);
}
}
CORRECT:
if (grid_->GetNumberRows() <= 0)
{
for (size_t i = 0; i<headers.size(); ++i)
{
if (grid_->GetNumberCols() <= 0)
grid_->InsertCols();
else
grid_->AppendCols();
grid_->SetColLabelValue(i, headers[i].data());
///
/// Each column will have its own cell attribute.
/// Supposedly, the column will take ownership of this
/// instance.
///
wxGridCellAttr* attr = new wxGridCellAttr();
attr->SetReadOnly(true);
attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
grid_->SetColAttr(i, attr);
}
}

How to acquire skeletal joint data to text file from two kinect cameras in SkeletalViewer? (C++)

I am currently working on a project to use multiple kinect cameras to acquire x,y,z coordinates of skeletal data in SkeletalViewer. I have an idea to use the KinectID or index of different kinect cameras to extract the sets of skeletal joints data into 2 different text files. But I am not sure if I am doing right. Please help to take a look at the modification below, or I will appreciate all your kind advice on other method to solve this problem.
In SkeletalViewer.h, I modified as following:
public:
FILE* mp3DFile0;
FILE* mp3DFile1;
char mText[1024];
INuiSensor * m_pNuiSensor;
BSTR m_instanceId;
array SensorIndex;
In NuiImpl.cpp, I modified as following:
1) define array
ref class MyClass {
public:
int m_i;
};
array<MyClass^>^ arrSensor() {
int i;
array< MyClass^ >^ local = gcnew array< MyClass^ >(2);
for (i = 0; i < 2; i++) {
local[i] = gcnew MyClass;
local[i]->m_i = i;
}
return local;
}
2) create array to store sensor index to do for loop later
HRESULT CSkeletalViewerApp::Nui_Init( )
{
HRESULT hr;
bool result;
//create an array to store two file pointers
FILE* mp3DFile[] = { mp3DFile0, mp3DFile1 };
fopen_s(mp3DFile0, "D:/Kinect/KinectCam0.txt", "w+");
fopen_s(mp3DFile1, "D:/Kinect/KinectCam1.txt", "w+");
.
.
if ( !m_pNuiSensor )
{
hr = NuiCreateSensorByIndex(0, &m_pNuiSensor);
//I am not sure about how to utilize this index in this case
.
.
}
if (NuiGetSensorCount(&m_pNuiSensor) > 1)
{
array< MyClass^ >^ SensorIndex;
SensorIndex = arrSensor();
}
}
3) use for loop to store data to different text file using index
void CSkeletalViewerApp::Nui_DrawSkeleton( const NUI_SKELETON_DATA & skel, int windowWidth, int windowHeight )
{
int i;
int h;
for (h = 0; h < 2; h++)
{
//when index point to the current kinect
if (SensorIndex[h] == &m_pNuiSensor)
{
for (i = 0; i < NUI_SKELETON_POSITION_COUNT; i++)
{
m_Points[i] = SkeletonToScreen(skel.SkeletonPositions[i], windowWidth, windowHeight);
memset(mText, 0, 1024);
sprintf(mText, "(%0.3f,%0.3f,%0.3f)", skel.SkeletonPositions[i].x, skel.SkeletonPositions[i].y, skel.SkeletonPositions[i].z);
if (mp3DFile[h]) {
fputs((const char*)mText, mp3DFile[h]);
}
}
if (mp3DFile[h]) {
fputs("\n", mp3DFile[h]);
}
}
}
.
.
}
I am a newbie in this Kinect programming. Thank you very much for your help! :)

Why can't I get input from the ifstream?

I am trying to read in a text file for a maze program. The input is something like:
10 10
OO+E+OO+++
O++O+O+OOO
OOOOOO+O+O
+++++O++OO
OOO+OOO+O+
O+O+O+++O+
O+O+OOO+OO
++O+++O++O
O+OOOOO++O
O+O++O+OOO
When the user click on the open button, this opens a open file dialog box
{
openFileDialog1->InitialDirectory = "C:\Desktop;";
openFileDialog1->Filter = "Maze files (*.DAT)|*.DAT";
if (openFileDialog1->ShowDialog() == ::DialogResult::OK)
{
char filename[1024];
for (int i = 0; i < openFileDialog1->FileName->Length; i++)
{
filename[i] = openFileDialog1->FileName[i];
}
ifstream ifs;
ifs.open(filename); // NULL terminate this
maze = new Maze( panel1, ifs);
ifs.close();
}
}
the following is the maze constructor
Maze::Maze( Panel ^ drawingPanel, ifstream & ifs )
{
try
{
valid = false;
ifs >> width >> height;
int temp = width;
drawingPanel->Size.Width = width;
drawingPanel->Size.Height = height;
for (int i = 0; i < height; i++) // height is always nothing
for (int j = 0; j < width; j++)
{
if (orig[j][i] == DEADEND ||
orig[j][i] == OPEN ||
orig[j][i] == EXIT )
ifs >> orig[j][i]; // NULLS????
else
throw 'D'; // i had to throw something....so i threw the D /* make a slit class and throw the D there? slit.fill(D); */
}
// this should be last
panel = drawingPanel;
valid = true;
}
catch (...)
{
valid = false;
MessageBox::Show( "Not a proper maze file!" );
}
}
when the program runs: ifs >> width >> height width and height do not get set correctly.
I have searched this site for this problem and have not been able to find anything that has helped. Sorry for my inexperience, any help is greatly appreciated.
You'e program very ugly : don't know if you're programming in C or C++ or C++/CLI, or try to mix the 3...
Because you use Windows Form projet, i will give you a .Net solution for read a file, it's not the better solution but this does not mix things.
First for read the file, on a first window :
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
openFileDialog1->Filter = "Maze Files (*.dat) | *.dat";
if (openFileDialog1->ShowDialog() == ::DialogResult::OK)
{
String ^fileName = openFileDialog1->FileName;
IO::StreamReader ^myMazeFile = gcnew IO::StreamReader(fileName);
String ^content = myMazeFile->ReadToEnd();
richTextBox1->Text = content;
myMazeFile->Close();
// display button for open second form wich draw maze
button2->Visible = true;
}
}
now we have our file content, so we pass it to a second form who will draw the maze :
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)
{
String ^content = richTextBox1->Text;
Maze ^frm = gcnew Maze(content);
frm->Show();
}
Second window, create overload constructor :
Maze(String ^contentMap)
{
InitializeComponent();
String ^dimension = getWords(contentMap, 2);
array<String ^> ^coordsString = dimension->Split(gcnew array<Char> {' '});
m_width = Convert::ToInt32(coordsString[0]);
m_height = Convert::ToInt32(coordsString[1]);
panel1->Width = m_width;
panel1->Height = m_height;
}
getWords method :
String ^getWords(String ^input, int numWords)
{
try
{
int words = numWords;
for (int i = 0; i < input->Length; ++i)
{
if (input[i] == ' ' ||input[i] == '\n')
words--;
if (words == 0)
{
return input->Substring(0, i);
}
}
}
catch (Exception ^ex)
{
// ...
}
return String::Empty;
}
You have your dimension in full .Net (private member m_width and m_height).

Sort array fix code

This method needs to sort and array and I am close with the following code but what it does is puts the list forwards to backwards i.e. if the list was "5, 4, 3" this would change it to "3, 4, 5". This is because after the if statement completes it goes back to the for and once it is finished the for it sets lowest back to 1000. How do I make it not set it back to 1000 each time?
public void sortList()
{
for(int i=0; i<myList.size(); i++)
{
int lowest = 1000;
if(myList.get(i)<lowest)
{
myList.add(0, myList.get(i));
myList.remove(i+1);
}
}
}
This :
public void sortList() {
int lowest = 1000;
for(int i=0; i<myList.size(); i++)
{
if(myList.get(i)<lowest)
{
myList.add(0, myList.get(i));
myList.remove(i+1);
}
}
}
You simply declare lowest outside of the loop, and update it in the loop.
With the example you gave, I would move the 'lowest' declaration out of the for loop, like so:
int lowest = 1000;
for(int i=0; i<myList.size(); i++)
{
if(myList.get(i)<lowest)
{
myList.add(0, myList.get(i));
myList.remove(i+1);
}
}
That way it's not reset to 1000 with each for loop. You can then update it within the loop as needed as you would any other numeric variable.