MS Visual C++ Multithreading accessing allocated variables causes access violation - c++

I have an issue with an MFC dialog based application build with MSVC 2013. To make the main dialog accessible also during more elaborate functions, I'm using multi-threading. A click on a button in the dialog calls a "worker function" that is worked out by another thread.
Here's an excerpt of the class:
class CpiezcamDlg : public CDialogEx
{
protected:
virtual BOOL OnInitDialog();
public:
CWinThread *m_thread1;
void StartSweepAndImageThread()
{
m_thread1 = AfxBeginThread(SweepAndImageThreadProc, this);
}
private:
static UINT SweepAndImageThreadProc(LPVOID pParam)
{
CpiezcamDlg *pThis = (CpiezcamDlg *)pParam;
UINT nRet = pThis->DoSweepAndImage();
return nRet;
}
UINT DoSweepAndImage();
UINT16 steps;
CString *imgs_name;
};
Clicking a button calls StartSweepAndImageThread which itself calls SweepAndImageThreadProc and finally DoSweepAndImage. In the function DoSweepAndImage, variables of the class are accessed (read and write). Amongst others, there is imgs_name. The usage is:
UINT CpiezcamDlg::DoSweepAndImage()
{
// ...
CString str;
str.Format(_T("Test"));
AddStageListText(str);
imgs_name[i] = str;
// ...
}
while imgs_name is initialized like
steps = 4;
imgs_name = new CString[steps];
in the OnInitDialog function.
The problem is that when pressing the mention button I receive
0xC0000005: Access violation reading location 0xFDFDFDF9.
exactly on imgs_name[i] = str;. When using a statical array, that is instead of CString *imgs_name; I define CString imgs_name[4];, everything works well. However, I very much would like to have that CString variable a dynamical one. Thanks in advance for your help!
PS: When I evaluated this in a serial way, i.e. when running the DoSweepAndImage function in the main thread, everything goes well. That's why I assume the access violation is due to the multi-threading.
#Wimmel: The loop over i in DoSweepAndImage is
for (UINT16 i = 0; i < steps; i++)

Related

a non static member reference must be relative to a specific object

I have been building a simple application which requires a separate thread to run some background code in a while loop. I have a text box which I want to send messages to from the code running in the separate thread however I am unable to.
A non static member reference must be relative to a specific object. From my understanding to run an additional thread it seems that I have to make the function static. However when I try and write a message to m_Console I see the error:
A non static member reference must be relative to a specific object.
I tried initialising the object but it doesn't do anything.
CMFCApplication1Dlg obj;
obj.m_Console = "Test"
The code that uses a separate thread is:
static UINT checkSomething(LPVOID pParam);
The text box variable is:
CString m_Console;
void CMFCApplication1Dlg::OnBnClickedBtnAdd(){
m_Console = "Parser is now running..";
AfxBeginThread(checkSomething,"");
I have tried the suggestion:
UINT CMFCApplication1Dlg::checkSomething(LPVOID pParam){
CMFCApplication1Dlg* pObject = (CMFCApplication1Dlg*)pParam;
pObject->m_Console = "I am in thread";
But it throws an access violation error on: pObject->m_Console = "I am in thread";
Exception thrown at 0x0FE90DBD (mfc140ud.dll) in MFCApplication1.exe: 0xC0000005: Access violation reading location 0xFFFFFFFC.
Here is the code:
MFCApplication1Dlg.cpp
void CMFCApplication1Dlg::OnBnClickedBtnAdd(){
m_Console = "Something Parser is now running..";
AfxBeginThread(checkSomething,"");
CWnd* okbtn = GetDlgItem(IDC_BTN_ADD);
if (okbtn) {
okbtn->EnableWindow(FALSE);
}
// without UpdateData() status area will _NOT_ be updated.
UpdateData(FALSE);}
INT CMFCApplication1Dlg::checkSomething(LPVOID pParam){
CMFCApplication1Dlg* pObject = (CMFCApplication1Dlg*)pParam;
pObject->m_Console = "I am in thread";
MFCApplication1Dlg.h
public:
afx_msg void OnBnClickedBtnAdd();
static int messenger();
static UINT checkSomething(LPVOID pParam);
CString m_Console;
Textbox:
IDC_Console
Category: value
Access: public
Control type: LText
Name: m_Console
Variable type: CString
From reading everyone's comments, it seems as if this is something that I am not supposed to do in C++, question is then, what if I had a background task running a loop in in a separate thread which needed to update the status box on the UI? To me that seems a logical thing someone might wish to do but if I'm not supposed to do that then how would that be done? I am running the task in a separate thread because it uses a while loop and if I don't use a separate thread it just freezes the whole application.
You can deliver the object of CMFCApplication1Dlg as parameter for the Thread function.
e.g
UINT MyThreadProc( LPVOID pParam )
{
CMFCApplication1Dlg * pObject = (CMFCApplication1Dlg *)pParam;
pObject->m_Console = "I am in thread";
}
// .... .... ...
AfxBeginThread(MyThreadProc, this);
I hope this answer will work for you.
Changed
AfxBeginThread(checkSomething,""); to
AfxBeginThread(checkSomething,this);
as suggested by ysk silver, thanks!
I needed to add a Timer Function which I followed this article:
https://www.tutorialspoint.com/mfc/mfc_multithreading.htm
Once I did this, the UI box updates.
int currValue;int maxValue;BOOL stopNow;string output;
BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_ERASEBKGND()
ON_WM_CTLCOLOR()
ON_WM_TIMER() //TIMER
ON_BN_CLICKED(IDC_BTN_ADD, &CMFCApplication1Dlg::OnBnClickedBtnAdd)
END_MESSAGE_MAP()
void CMFCApplication1Dlg::OnTimer(UINT_PTR nIDEvent) {
CDialogEx::OnTimer(nIDEvent);
UpdateData(FALSE);}
void CMFCApplication1Dlg::OnBnClickedBtnAdd(){
SetTimer(1234, 333, 0); // 3 times per second
m_Console = "Parser is now running..";
AfxBeginThread(checkSomething,this);
I then can change the text in the checkSomething method:
CMFCApplication1Dlg* pObject = (CMFCApplication1Dlg*)pParam;
output = "I am in thread";
pObject->messenger(output);
//OR
pObject->m_Console = "I am in thread";
And the textbox updates!

ShowWindow fails to focus on Win10 Calculator app [duplicate]

I have an application which may only have one instance of itself open at a time. To enforce this, I use this code:
System.Diagnostics.Process[] myProcesses = System.Diagnostics.Process.GetProcesses();
System.Diagnostics.Process me = System.Diagnostics.Process.GetCurrentProcess();
foreach (System.Diagnostics.Process p in myProcesses)
{
if (p.ProcessName == me.ProcessName)
if (p.Id != me.Id)
{
//if already running, abort this copy.
return;
}
}
//launch the application.
//...
It works fine. I would also like it to be able to focus the form of the already-running copy. That is, before returning, I want to bring the other instance of this application into the foreground.
How do I do that?
SetForegroundWindow works, to a point:
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
// ...
if (p.Id != me.Id)
{
//if already running, focus it, and then abort this copy.
SetForegroundWindow(p.MainWindowHandle);
return;
}
// ...
This does bring the window to the foreground if it is not minimized. Awesome.
If the window IS minimized, however, it remains minimized.
It needs to un-minimize.
Solution via SwitchToThisWindow (Works!):
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
[STAThread]
static void Main()
{
System.Diagnostics.Process me = System.Diagnostics.Process.GetCurrentProcess();
System.Diagnostics.Process[] myProcesses = System.Diagnostics.Process.GetProcessesByName(me.ProcessName);
foreach (System.Diagnostics.Process p in myProcesses)
{
if (p.Id != me.Id)
{
SwitchToThisWindow(p.MainWindowHandle, true);
return;
}
}
//now go ahead and start our application ;-)
}
I had the same problem and SwitchToThisWindow() worked the best for me. The only limitation is that you must have XP sp1 installed. I played with SetForegroundWindow, ShowWindow, and they both had problems pulling the window into view.
C# equivalent of Tom Juergens's answer. Works like a charm for me.
private const int SW_SHOWNORMAL = 1;
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool SetForegroundWindow(IntPtr hwnd);
public void SetForeground()
{
Process[] processes = Process.GetProcessesByName("process name");
foreach (Process p in processes) {
ShowWindow(p.MainWindowHandle, SW_SHOWNORMAL);
SetForegroundWindow(p.MainWindowHandle);
}
}
Same as OP, I found that SetForegroundWindow alone wasn't enough when the window was minimized. Since I didn't want to use SwitchToThisWindow, I chose ShowWindow followed by SetForegroundWindow.
Works well for me!
private const SW_SHOWNORMAL = 1
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Function ShowWindow(ByVal hwnd As IntPtr, ByVal nCmdShow As integer) As Boolean
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Function SetForegroundWindow(ByVal hwnd As IntPtr) As Boolean
End Function
Sub SetForeground()
Dim processes As Process() = Process.GetProcessesByName("myprocess")
For Each p as Process in processes
ShowWindow(p.MainWindowHandle, SW_SHOWNORMAL)
SetForegroundWindow(p.MainWindowHandle)
Next
End Sub
I believe you will want to use SetForegroundWindow
MSDN Example
Complete Side Note...
You can use
Process.GetProcessesByName(me.ProcessName)
instead of looping over all the processes running on the system...
UPDATE
PInvoke Rules for this sort of thing...
Can you grab MainWindowHandle property of the Process object and send it a WM_USER message that you can interpret as "some other instance wants to bring me to the front".
It is a very frequent behavior in desktop applications, I regularly have to do this when I create a new WPF application. So I have created a SingletonApp class which inherits from Application :
public class SingletonApp : Application
{
private static readonly System.Threading.Mutex mutex;
private static readonly string processName;
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int flags);
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hwnd);
static SingletonApp()
{
processName = Process.GetCurrentProcess().ProcessName;
mutex = new System.Threading.Mutex(false, $"Local\\{processName}");
}
/// <summary>
/// A base class for application needing to prevent multiple instances
/// </summary>
public SingletonApp()
{
if (!mutex.WaitOne(0, false))
{
// Give focus to existing instance before shutdown
BringToFront(processName);
Current.Shutdown();
}
}
public void BringToFront(string processName)
{
Process process = Process.GetProcessesByName(processName).FirstOrDefault();
if (process != null)
{
// In case of window is minimized
ShowWindow(process.MainWindowHandle, 1); // 1 = Normal
SetForegroundWindow(process.MainWindowHandle);
}
}
}
To use it, you just have to inherit from SingletonApp instead of Application in your App.xaml.cs :
public partial class App : SingletonApp
Don't forget to update App.xaml too :
<utils:SingletonApp x:Class="MyApp.App"
[...]
xmlns:utils="clr-namespace:MyApp.Utils"
Startup="App_OnStartup">
With this it becomes very easy to implement this behavior in every new desktop client.

Drawing a Graph in C++ MFC App

I am writing a C++ MFC application to control a machine in a manufacturing setting. This app also needs to analyze a lot of information in a very short cycle time.
For testing purposes and long term maintenance, I need to be able to graph data coming from a sensor on the console. I may have totally overlooked an option (feel free to propose other options) but my research has taken me to using a picture control.
I am successfully drawing in this control by use of OnPaint(). My issue is that I need to redraw a new image every few seconds and I cannot call OnPaint() repetitively or pass data to it.
How can I create a new function that can be used to draw on the picture control repetitively? Also, this is my first foray into an MFC app so please explain on an appropriate level. Thanks!
class CPicture : public CStatic
{
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint();
};
BEGIN_MESSAGE_MAP(CPicture, CStatic)
ON_WM_PAINT()
END_MESSAGE_MAP()
void CPicture::OnPaint()
{
CPaintDC dc(this); // device context for painting
dc.SelectStockObject(BLACK_BRUSH);
dc.Rectangle(5, 50, 1000, 51);
}
I guess the question is how and where to access this
//Picture
class CPicture : public CStatic
{
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnPaint();
vector<Coordinates> GraphData;
};
void CPicture::OnPaint()
{
// device context for painting
CPaintDC dc(this);
// save current brush
CBrush *pOldBrush = (CBrush*)dc.SelectStockObject(BLACK_BRUSH);
int NumPoints = GraphData.size() - 1;
for (int N = 0; N <= NumPoints; N++) {
dc.Rectangle(GraphData[N].x, GraphData[N].y, GraphData[N].x, GraphData[N].y);
}
// select original brush into device contect
dc.SelectObject(pOldBrush);
}
You can call Invalidate() on your control when new data arrives, or use RedrawWindow() to force an immediate redraw:
CPicture myPicture;
myPicture.Invalidate();
or
myPicture.RedrawWindow();
I cannot call OnPaint() repetitively or pass data to it.
To pass data, a structure containg the data can be declared inside your CPicture class (or some place else in your program), and that data can then be accessed from within OnPaint():
struct myData {
int value1;
int value2; // or an array, or some other data structure
}
class CPicture : public CStatic
{
DECLARE_MESSAGE_MAP()
public:
myData m_data;
afx_msg void OnPaint();
};
In OnPaint() (you should also select the original brush back into the device context to avoid resource leaks):
void CPicture::OnPaint()
{
CPaintDC dc(this); // device context for painting
// save current brush
CBrush *pOldBrush = (CBrush*)dc.SelectStockObject(BLACK_BRUSH);
// check pOldBrush - could be NULL
// dc.Rectangle(5, 50, 1000, 51);
// access m_data here, for example
dc.Rectangle(m_data.value1, m_data.value2, 1000, 51);
// select original brush into device contect
dc.SelectObject(pOldBrush);
}
Update (working with threads):
Assuming the following (from the comments):
for the main thread you have a dialog CLongbowDlg.
for the graph, you have a PicControl derived from CStatic, and that control is placed on the dialog.
from the main thread, a worker thread is started to read the data.
PicControl and CLongbowDlg are defined in the same header, but are
independent of each other. I need to be able to call Invalidate() or
RedrawWindow() from inside CLongbowDlg's functions because they
represent the primary thread.
I'll try to give a short description of one of the possibilities here, because this should actually be a seperate question.
Firstly, an object of PicControl has to be a member of CLongbowDlg, which I assume is the case (let's call it m_PicControl) - So, in class CLongbowDlg:
PicControl m_PicControl;
For the data (I'll be using the above myData as example data): in your main thread (the Dialog), create a variable of type myData: m_data (for larger data you could allocate space on the heap, or use CArray or some other container):
myData m_data;
In PicControl create a member variable of type myData* and set it to NULL in the PicControl constructor.
myData *m_pData;
In OnInitDialog() (main dialog), provide m_picControl with a pointer to the data (or better create a function to do that in PicControl):
m_picControl.m_pData = &m_data;
When starting the worker thread, also provide it a pointer to m_data and/or a pointer to the dialog itself (this).
Make sure to protect the data with a critical section.
When data comes in, the worker thread can write to it via the provided pointer.
In PicControl::OnPaint(), the same data can be accessed through m_pData.
To initiate a redraw, there are several ways:
use a timer inside PicControl or in the main dialog, and call Invalidate() every time the timer fires.
to control the redrawing from the worker thread (when a certain amount of new data has arrived for example) a message can be posted, using PostMessage(), to the main dialog (using the pointer that was provided when starting the thread - the this pointer).
To receive the message you'll have to create a message handler in the main dialog, and from there call Invalidate() on m_picControl (you could also post a message directly to PicControl, but I prefer to do it via the main window).

Access Violation Error when accessing D object from D-to-C callback

I've recently begun to dip my toes into DerelictGLFW. I have two classes, one of them a Window class, and another an InputHandler class (a event manager for window events). In my cursor position callback, I take the window user pointer and try to set the position, but I get an Access Violation Error immediately upon attempting to set any value outside of the callback and GLFW. GLFW is initialized, and does not report any errors. Thank you for your time.
Class Window
{
private:
double cursorX;
...other stuffs...
#property
void cursorX(double x) nothrow
{
cursorX = x;
}
}
extern(C) void mousePosCallback(GLFWwindow* window, double x, double y)
{
Window* _window = window.userPointer
//userPointer is a static function that gets the window user pointer
//and casts it to a Window*
_window.cursorX = x;
}
static Window* userPointer(GLFWwindow* window)
{
return cast(Window*) glfwGetWindowUserPointer(window);
}
Edits:
Added extern(C) to callback, error persists.
Corrected "immediately upon entering the callback" to "immediately upon attempting to set any value outside of the callback and GLFW".
Added userPointer function to question
mousePosCallback must be declared in a extern(C) block. This is to make the calling convention match.
extern (C) void mousePosCallback(GLFWwindow* window, double x, double y)
{
Window* _window = window.userPointer
//userPointer is a static function that gets the window user pointer
//and casts it to a Window*
_window.cursorX = x;
}
It seems I have discovered the source of the error. During initialization of the window, I attempt to set the user pointer with this. I'm not sure why, but moving it into a different function that is not called from the constructor appears to remedy the problem. The problem is solved, but could anyone help me to understand why? It seems rather odd to me.

Application with multiple windows as instances of a class, C++

I wrote an application. There is a class named APP, with handle to the window, and message loop inside it, and all this stuff.
It is intended to "run" some objects of this class, each with its own window based on a set of variables necessary for a standard window.
Message loop is allowed for public use, it is ran by RunMessageLoop method.
int nCmdShow - of course, it is used to tell how to display a window.
Now, when i create some objects like this:
vector <APP *> App;
for (int i=0; i<3; i++)
{
App.push_back(&APP(nCmdShow))
App[i]->RunMessageLoop();
}
program waits for each message loop to end before it starts another.
I figured out to make it this way:
vector <APP *> App;
for (int i=0; i<3; i++)
{
App.push_back(&APP(nCmdShow))
}
for (int i=0; i<3; i++)
{
App[i]->RunMessageLoop();
}
When i know how many windows I want at startup to be run, it seems to be ok.
But I don't know how to create new windows dynamically, with complete independence of other windows. It should invoke message loops and immediately return to WinMain() without ending message loops.
I thought about multi-threaded app, each thread per one instance of an APP class. But don't know how to build multithreaded app, though.
Any ideas for a possible solution?
I see what you are trying to do now, I have achieved this in my application framework called Lucid (it is still a work in progress). For the sake of the answer, your window class will be called Window instead of APP.
This is done by passing a global procedure to every window you create. All windows share this same procedure. Every time any window gets a message, that message is sent to the global procedure, the global procedure checks if the HWND belongs to a Window that you created, and if it does, sends the message to that Windows' procedure. Here's an overview of how this works.
class Window
{
public:
// The contents of this function can vary from window to window
// provided that you make a subclass and override this method.
virtual LRESULT procedure(HWND wnd, UINT msg, WPARAM wp, LPARAM lp);
// When you create a Window object, add a pointer to it in this map.
// Eg. if (this->hwnd != NULL) createdWindows[this->hwnd] = this;
static map<HWND, Window*> createdWindows;
// When you create a window, make this its procedure.
static LRESULT CALLBACK routeMessage(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
{
if (createdWindows.find(wnd) != createdWindows.end()) {
// Message belongs to one of our 'Window' objects.
// Pass the message to that window and return the result.
return createdWindows[wnd]->procedure(wnd, msg, wp, lp);
} else {
// It seems you made 'routeMessage' the procedure
// of a window that doesn't belong in the map. Go ahead
// and process the message in the default manner.
return DefWindowProc(wnd, msg, wp, lp);
}
}
};
Now you will only need a single message loop and a single thread. I have a test project using Lucid that creates 2 windows with different procedures on a single thread with a single message loop:
#include "Lucid.h"
using namespace Lucid;
void sayBye(MessageEventArgs& e)
{
MessageBox(NULL, "Goodbye!", "Form 2", MB_OK);
e.handled = true;
}
void Program::onStart()
{
Form* myForm1 = new Form("Hello World!");
myForm1->show();
Form* myForm2 = new Form("Hello World!");
myForm2->addMessageHandler(WM_CLOSE, sayBye);
myForm2->show();
// This Program::onStart() function is called
// immediately before the single message loop is entered.
}
Create the threads with _beginthreadex equal to the number of window you need to run. Then, run message loop in the thread procedure and wait until all thread has been terminated with WaitForMultipleObjects.