Opening Serial Port?

Hello! I am trying to open my serial port in a Windows Form Application (Visual C++) however, I'm getting errors! Any help is much appreciated!




gpsProject.cpp

----
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// gpsProject.cpp : main project file.

#include "stdafx.h"
#include "Form1.h"
#include <iostream>
#include <windef.h>
#include <WinBase.h>
#include <Windows.h>
#include <string>

using namespace gpsProject;
using namespace System;
using namespace System::Windows::Forms;
using namespace std;

[STAThreadAttribute]
int main()
{
	HANDLE myCommPort;
	
	myCommPort = CreateFile("COM3",
       GENERIC_READ|GENERIC_WRITE,  // access ( read and write)
       0,                           // (share) 0:cannot share the
                                    // COM port
       0,                           // security  (None)
       OPEN_EXISTING,               // creation : open_existing
       FILE_FLAG_OVERLAPPED,        // we want overlapped operation
       0                            // no templates file for
                                    // COM port...
       );

	if (myCommPort == INVALID_HANDLE_VALUE)
		cout<<("Error in opening serial port");
	else 
		cout<<("Opening serial port was successful");

		CloseHandle(myCommPort);

	// Enabling Windows XP visual effects before any controls are created
	Application::EnableVisualStyles();
	Application::SetCompatibleTextRenderingDefault(false); 

	// Create the main window and run it
	Application::Run(gcnew Form1());
	return 0;
	
}




1>------ Build started: Project: gpsProject, Configuration: Debug Win32 ------
1>Build started 4/11/2017 9:36:22 PM.
1>InitializeBuildStatus:
1> Touching "Debug\gpsProject.unsuccessfulbuild".
1>GenerateTargetFrameworkMonikerAttribute:
1>Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the input files.
1>ClCompile:
1> All outputs are up-to-date.
1> gpsProject.cpp
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(6361): error C2146: syntax error : missing ';' before identifier 'ContextRecord'
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(6361): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(6361): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(12983): error C2065: 'PCONTEXT' : undeclared identifier
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(12984): error C2146: syntax error : missing ')' before identifier 'ContextRecord'
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(12984): warning C4229: anachronism used : modifiers on data are ignored
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(12984): error C2182: 'RtlCaptureContext' : illegal use of type 'void'
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(12984): warning C4394: 'RtlCaptureContext' : per-appdomain symbol should not be marked with __declspec(dllimport)
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(12984): error C2491: 'RtlCaptureContext' : definition of dllimport data not allowed
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(12984): error C2059: syntax error : ')'
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(13372): error C2143: syntax error : missing ';' before '__stdcall'
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(13372): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(13372): warning C4394: 'PCONTEXT' : per-appdomain symbol should not be marked with __declspec(dllimport)
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(13376): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(14982): error C3861: '__readfsdword': identifier not found
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\WinBase.h(1048): error C2146: syntax error : missing ';' before identifier 'LPCONTEXT'
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\WinBase.h(1048): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\WinBase.h(1048): error C2378: 'PCONTEXT' : redefinition; symbol cannot be overloaded with a typedef
1> C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\winnt.h(13372) : see declaration of 'PCONTEXT'
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\WinBase.h(1048): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\WinBase.h(3610): error C2061: syntax error : identifier 'PCONTEXT'
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\WinBase.h(4449): error C2061: syntax error : identifier 'LPCONTEXT'
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\WinBase.h(4457): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\WinBase.h(4457): error C2143: syntax error : missing ',' before '*'
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\WinBase.h(15112): error C2143: syntax error : missing ';' before '__stdcall'
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\WinBase.h(15112): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\WinBase.h(15116): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:01.92
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Last edited on
There is an easier way to deal with the serial port.
In the toolbox under Componets you can drag a SerialPort component unto your form.
Here is a tutorial in C#, should be not too difficult to adapt to C++ .NET
https://www.youtube.com/watch?v=Fer_q9LXDnQ
Thank you so much! That really helped me out. I found another tutorial as well if anyone is having issues:

Part 1: https://www.youtube.com/watch?v=W4NyevEQnCI
Part 2: https://www.youtube.com/watch?v=lTW7CDG-jkc
So here is the finished code (at least so far):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

namespace gpsChallenge
{
public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            GetAvailablePortNames();
        }
        void GetAvailablePortNames()
        {
            string[] ports = SerialPort.GetPortNames();
            portNamesComboBox.Items.AddRange(ports);
        }

        private void openPortBtn_Click(object sender, EventArgs e)
        {
            try
            {
                if (portNamesComboBox.Text == "" || baudRateTextBox.Text == "")
                {
                    MessageBox.Show("Please select a port", "Port Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                else
                {
                    serialPort1.PortName = portNamesComboBox.Text;
                    serialPort1.BaudRate = Convert.ToInt32(baudRateTextBox.Text);
                    progressBar1.Value = 100;
                    serialPort1.Parity = Parity.None;
                    serialPort1.StopBits = StopBits.One;
                    serialPort1.DataBits = 8;
                    serialPort1.Handshake = Handshake.None;
                    serialPort1.Open();
                    receiveButton.Enabled = true;
                    textMessage.Enabled = true;
                    closePortBtn.Enabled = true;
                    openPortBtn.Enabled = false;
                }
            }
            catch (UnauthorizedAccessException)
            {
                MessageBox.Show("Not authorized", "Authorization Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }           
        }

        private void closePortBtn_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
            progressBar1.Value = 0;
            openPortBtn.Enabled = true;
            receiveButton.Enabled = false;
            textMessage.Enabled = false;
            textMessage.Text = "";
        }

        private void receiveButton_Click(object sender, EventArgs e)
        {
            try
            {
                textMessage.Text = serialPort1.ReadLine();
            }

            catch (TimeoutException)
            {
                MessageBox.Show("Connection has been timed out", "Timeout Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
      
    }
}


The problem I'm having now is getting the text box (textMessage.text) to update in real time without me to keep hitting the receive button.

If I put a loop in the try catch statement, [ while(true)], of course the form just generates all of the data but I need it to add it to the existing text in the text box until the user hits close port.

https://preview.ibb.co/i2JBGQ/scr_shot.png
I was reading that earlier and I'm still a tad bit confused! Maybe I'm slow or overthinking the problem.
Why don't you try to implement this event handler. AFAIK once the port is open it will fire the event when data is available and you need to add the text to your textbox.
Maybe like this:
1
2
3
4
5
6
7
// in openPortBtn_Click
serialPort1.DataReceived += (s,e) => 
{
  SerialPort sp = s as SerialPort;
  string indata = sp.ReadExisting();
  textMessage.Text += indata; 
}

Another option would be use a Timer and try to read data when the timer proc gets called.
Topic archived. No new replies allowed.