DoEvent() in Windows and Linux errors - c++

I want to write a function like DoEvents() in C++.
I found DoEvents equivalent for C++? and In C/C++, which function is like DoEvents( ).
Here is the code:
void DoEvents()
{
MSG msg; // Error 1
while ( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE ) ) //Error 2
{
if ( GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
break;
}
}
I have two questions:
Q1. What is the equivalent of DoEvent() in Linux?
Q2. I got errors when I try to use it on windows using Qt creator.
Error1 : unknown type name 'MSG'
Error2 : use of undeclared identifier'PM_NOREMOVE'
Any Help, please?

Related

Serial Comms between Microsoft Visual C++ 2010 and Arduino UNO via USB

I need to establish a serial comm between Microsoft Windows Visual C++ 2010 and an Arduino microcontroller via USB. A motion tracking algorithm produces an X and Y coordinate which needs to be sent to the Arduino which in turn controls two pan and tilt servos.
I am a final year mechanical engineering student and have very little experience with Microsoft Visual Studios and C++, so please bear with me and please forgive me if my terms are incorrect...
I have done extensive research on multiple forums, but cannot find an answer specific to my problem:
All the solutions that I have come across only support comms when a normal/"empty" project is created in Visual Studios. An example can be found here: Serial communication (for Arduino) using Visual Studio 2010 and C
When I try and debug the same body of code (which successfully runs in an "empty" project) in a "Win32 Console Application" project, I am presented with the following errors:
error C2065: 'LcommPort' : undeclared identifier
error C2228: left of '.c_str' must have class/struct/union
Unfortunately I cannot simply change my project from a "Win32 Console Application" to a normal "Empty" project due to the fact that the motion tracking algorithm necessitates the use of the console application type of project.
The main body of code that I am using is as follows (this is a simplified test source file to confirm whether comms are established between MS Visual and the Arduino where the frequency at which an LED turns on and off is altered through the serial connection):
#include <Windows.h>
#include "ArduinoSerial.h"
#include "StdAfx.h"
int main() {
try {
ArduinoSerial arduino( "COM3" );
Sleep( 2000 ); // Initial wait to allow Arduino to boot after reset
char buffer[] = { 25, 100 };
arduino.Write( buffer, 2 ); // Send on/off delays to Arduino (if return value is 0, something went wrong)
}
catch ( const ArduinoSerialException &e ) {
MessageBoxA( NULL, e.what(), "ERROR", MB_ICONERROR | MB_OK );
}
return 0;
}
The corresponding source code which is the home of the error is found in line9 of the code:
#include <algorithm>
#include <sstream>
#include <Windows.h>
#include "stdafx.h"
#include "ArduinoSerial.h"
ArduinoSerial::ArduinoSerial( const std::string commPort ) {
comm = CreateFile( TEXT( commPort.c_str() ),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL );
if ( comm == INVALID_HANDLE_VALUE ) {
std::ostringstream error;
error << "Unable to acquire handle for " << commPort << ": ";
DWORD lastError = GetLastError();
if ( lastError == ERROR_FILE_NOT_FOUND ) {
error << "Invalid port name";
}
else {
error << "Error: " << lastError;
}
throw ArduinoSerialException( error.str() );
}
DCB dcb;
SecureZeroMemory( &dcb, sizeof DCB );
dcb.DCBlength = sizeof DCB;
dcb.BaudRate = CBR_9600;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.Parity = NOPARITY;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
if ( !SetCommState( comm, &dcb ) ) {
CloseHandle( comm );
std::ostringstream error;
error << "Unable to set comm state: Error " << GetLastError();
throw ArduinoSerialException( error.str() );
}
PurgeComm( comm, PURGE_RXCLEAR | PURGE_TXCLEAR );
}
std::size_t ArduinoSerial::Read( char buffer[], const std::size_t size ) {
DWORD numBytesRead = 0;
BOOL success = ReadFile( comm, buffer, size, &numBytesRead, NULL );
if ( success ) {
return numBytesRead;
}
else {
return 0;
}
}
std::size_t ArduinoSerial::Write( char buffer[], const std::size_t size ) {
DWORD numBytesWritten = 0;
BOOL success = WriteFile( comm, buffer, size, &numBytesWritten, NULL );
if ( success ) {
return numBytesWritten;
}
else {
return 0;
}
}
ArduinoSerial::~ArduinoSerial() {
CloseHandle( comm );
}
ArduinoSerialException::ArduinoSerialException( const std::string message ) :
std::runtime_error( message ) {
}
Any help or advice will be really greatly appreciated.
I am presented with the following errors:
error C2065: 'LcommPort' : undeclared identifier error C2228: left of '.c_str' must have class/struct/union
This little piece of code
TEXT( commPort.c_str())
becomes actually
LcommPort.c_str()
That's why you get this compiler error.
You should notice that TEXT() is a preprocessor macro meant for character literals, to prefix them with L depending in which mode (Unicode/ASCII) your project is compiled. It doesn't work with any variables obviously.
Use either commPort.c_str() directly, or const std::wstring commPort.

C++: Deleting a printer queue

I'm trying to remove all the files in queue from a printer. I found this piece of code which seemed pretty straight forward.
I tried deleting the queue with the code below. It compiles, but SetPrinter returns false. The error message I got was 5, which I tried to decode to a "normal" error message using the approach from this question. But I wasn't able to compile with that, because STR_ELEMS is undefined. Searched google for "STR_ELEMS is undefined" but hit a dead end.
Can someone help me decode the error message and delete the printer queue?
BOOL bStatus = false;
HANDLE hPrinter = NULL;
DOC_INFO_1 DocInfo;
bStatus = OpenPrinter((LPTSTR)_T("CN551A"), &hPrinter, NULL);
if(bStatus) {
DWORD dwBufsize=0;
GetPrinterA(hPrinter, 2, NULL, 0, &dwBufsize); // Edit: Returns false
PRINTER_INFO_2* pinfo = (PRINTER_INFO_2*)malloc(dwBufsize);
long result = GetPrinterA(hPrinter, 2,
(LPBYTE)pinfo, dwBufsize, &dwBufsize);
if ( pinfo->cJobs==0 ) // Edit: pinfo->cJobs is not 0
{
printf("No printer jobs found.");
}
else
{
if ( SetPrinter(hPrinter, 0, 0, PRINTER_CONTROL_PURGE)==0 )
printf("SetPrinter call failed: %x\n", GetLastError() );
else printf("Number of printer jobs deleted: %u\n",
pinfo->cJobs);
}
ClosePrinter( hPrinter );
}
My includes are:
#include <windows.h>
#include <winspool.h>
The error code of 5 means "access is denied". (System Error Codes)
Try running with admin privileges.
To format a printable error message from the return value of GetLastError, use FormatMessage something like this:
TCHAR buffer[256];
if (0 == FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0,
GetLastError(), 0, buffer, 256, 0)) {
// FormatMessage failed.
}
Also, you can try passing a PRINTER_DEFAULTS struct to OpenPrinter, maybe like this:
PRINTER_DEFAULTS PrnDefs;
PrnDefs.pDataType = "RAW";
PrnDefs.pDevMode = 0;
PrnDefs.DesiredAccess = PRINTER_ALL_ACCESS;
bStatus = OpenPrinter((LPTSTR)_T("CN551A"), &hPrinter, &PrnDefs);

Windows: PeekMessage loop anomaly

Here's a code snippet from a project I am currently working on:
MSG msg;
bool msgAvail = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
while(msgAvail)
{
TranslateMessage(&msg);
...
...
msgAvail = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
}
While analyzing a customer crash dump, I found that the call to TranslateMessage() has the parameter as NULL. I am confused as to how could &msg become NULL in the above scenario. Could someone explain what could be happening in the above code due to which the address of msg is becoming NULL?

Sending http request repeatedly, more fast (async mode)

I need to send one request to server more quickly and repeatedly.
So I implemented code like this.
BOOL CTestDlg::OnInitDialog()
{
...
m_hInstance = InternetOpen(L"asynchttp", INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,INTERNET_FLAG_ASYNC);
if(m_hInstance == NULL)
{
ErrorLog(L"InternetOpen Failed");
return TRUE;
}
if (InternetSetStatusCallback(m_hInstance,(INTERNET_STATUS_CALLBACK)&Callback) == INTERNET_INVALID_STATUS_CALLBACK)
{
ErrorLog(L"Set Callback Function Failed");
return TRUE;
}
m_hConnect = InternetConnect(m_hInstance, L"192.168.2.116", 8080,NULL,NULL,INTERNET_SERVICE_HTTP,INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_KEEP_CONNECTION,1);
if(m_hConnect == NULL)
{
if(DWORD dwError = GetLastError() != ERROR_IO_PENDING)
{
ErrorLog(L"Fail to Connect Server");
return TRUE;
}
WaitForSingleObject(hConnectedEvent, INFINITE);
}
CreateThread(0 , 0 , (LPTHREAD_START_ROUTINE)SendThread , 0 , 0 , 0);
return TRUE;
}
void __stdcall Callback(HINTERNET hInternet,DWORD dwContext,DWORD dwInternetStatus,LPVOID lpStatusInfo,DWORD dwStatusInfoLen)
{
switch(dwContext)
{
case 1:
{
SetEvent(hConnectedEvent);
}
break;
}
}
DWORD SendThread(LPVOID lpParam)
{
TCHAR *szAceptType[] = {_T("*/*") , NULL};
CString szContentType = _T("Content-Type: application/x-www-form-urlencoded\r\n");
char szPostData[MAX_PATH];
sprintf(szPostData , "num=1234&str=3240");
HINTERNET hRequest = HttpOpenRequest(m_hConnect, L"POST", L"/TestWeb/index.jsp", HTTP_VERSION , NULL , (LPCTSTR*)szAceptType , 0, 2);
while(1)
{
try
{
if (!HttpSendRequest(hRequest, szContentType, (DWORD)szContentType.GetLength(), szPostData,(DWORD)strlen(szPostData)))
{
if (DWORD dwError = GetLastError() != ERROR_IO_PENDING)
ErrorLog(L"SendRequest: Error = %d" , dwError);
}
}
catch (CException* e)
{
UNREFERENCED_PARAMETER(e);
}
Sleep(100);
}
return 0;
}
When execute or debug program, I saw this "SendRequest; Error = 1" log frequently.
And Server does not record anymore to database , after one or two request data recorded
It seems like HttpSendRequest API doesn't work correctly after error occured.
I aim to send one request to server more fast and more correctly, without loss.
Please teach me what is wrong problem.
Or if you got another best way, then please tell me.
Thanks.
Error code 1 is "Invalid Parameter".
You appear to be mixing ASCII (char and sprintf) and Unicode strings in your sample above. Have you tried with all Unicode strings (making szPostData a WCHAR array)? From MSDN: "There two versions of HttpSendRequest —HttpSendRequestA (used with ANSI builds) and HttpSendRequestW (used with Unicode builds)". It goes on to talk about when ERROR_INVALID_PARAMETER is returned. http://msdn.microsoft.com/en-us/library/windows/desktop/aa384247(v=vs.85).aspx
Also, I haven't used MFC in a long time, but I remember that you should call e->Delete() in your exception handler (unless you re-throw). The CException::Delete method will delete any thrown exception created on the heap (and do nothing otherwise).

Peekmessage (creating window loop)

Igot this error and I don't know why, I just follow correctly what he do, and he doesn't get this error. Here is the code.
//Main application loop
MSG msg = {0};
while(WM_QUIT != msg.message())
{
if(PeekMessage(&msg, NULL, NULL, NULL, PM_Remove))
{
//Translate message
TranslateMessage(&msg);
//Dispatch message
DispatchMessage(&msg);
}
}
And here are the error:
error C2064: term does not evaluate to a function taking 0 arguments
fatal error C1903: unable to recover from previous error(s); stopping compilation
And when I clicked it, they all pointing to the while loop.
The message member of the MSG structure is a field, not a method. You should access it instead of calling it:
while (WM_QUIT != msg.message) {
// ...
}
There are other issues in your code snippet. First, C++ is a case-sensitive language, so the last argument to PeekMessage() should be PM_REMOVE instead of PM_Remove.
In addition, PeekMessage() does not block if the message queue is empty, so your code will end up consuming 100% of the CPU core it runs on. You can use GetMessage() instead, which blocks if no message is available and would allow you to remove the explicit test for WM_QUIT:
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}