Click here to Skip to main content
14,865,126 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi,

I am trying to access globally variables declared in MainFrame of my solution from a thread that starts in my CMyView.cpp. How can I access these parameters without the CMainFrame * _MainFrame; in my structure THREADVIEW in CMyView.h, as below? Any ideas?

C++
typedef struct THREADVIEW{
    * _this;

   //CMainFrame * _MainFrame; /* I cannot have this here */
 
} THREADVIEW;


Many thanks,

Yoldas


addition by the OP:
Hi,
First of all many thanks for your immediate comments. Here are the things in more detail.

C++
///////////////In my view.cpp:
void CView::OnSprint()
{
	CMainFrame *pFrame = (CMainFrame*) AfxGetMainWnd();		
.
.
. 	/* kick off thread */
THREADVIEW *_pview = new THREADVIEW;
_pview->_this = this;
AfxBeginThread(ChangeColorThread, _pview);

}
UINT CView::ChangeColorThread(LPVOID param)
{
	THREADVIEW * thd = (THREADVIEW*)param;
	thd->_this->StateOnThread();

	AfxEndThread(1, FALSE); 

	return 1;
}

void CView:: StateOnThread ()
{
	CMainFrame *pFrame = (CMainFrame*) AfxGetMainWnd();	
	int a = pFrame->AA;
	/* I want to return AA from main frame but I cannot because I cannot declare CMainFrame * pFrame; in my THREADVIEW */
}

///////////// in my view.h

public:

	typedef struct THREADVIEW{
		CView * _this;
		// cannot have CMainFrame * pFrame;
	} THREADVIEW;


	void StateOnThread();

	static UINT ChangeColorThread(LPVOID param);


////////////my mainframe has my in AA:

class CMainFrame : public CMDIFrameWnd
{
	DECLARE_DYNAMIC(CMainFrame)
public:
int AA;
}


which I am trying to access. My thread kicks off from toolbar button after the child frame is displayed but I do not see why this has anything to do with why I cannot access Cmainframe parameters.

I greatly appreciate your input.

Regards,

Yoldas
Posted
Updated 1-Nov-12 12:59pm
v5
Comments
Eugen Podsypalnikov 1-Nov-12 14:52pm
   
What types of the variables and
what kind of the access (read/write) are wanted, please ? :)

You could access it there, but it's a bad idea as you'd need to lock the MainFrame and that can get dirty and complex.

I recommend that you create a singleton class to handle your globals. Keep the member variables protected and provide thread safe access methods for the data.

Something like this.

Header File
C++
class CWorkSpace;

extern CWorkSpace WorkSpace;

class CWorkSpace
{
protected:
   THREADVIEW ThreadView;

public:
   THREADVIEW GetThreadView(void) const
   {
      CLock Lock;
      return ThreadView;
   }

   void SetThreadView(const THREADVIEW & NewThreadView)
   {
      CLock Lock;

      ThreadView = NewThreadView;
   }
}


CPP File

C++
#include "WorkSpace.h"

CWorkSpace WorkSpace;


You'll need to substitute the CLock Lock; code with whatever locking mechanism you choose.
   
Comments
JackDingler 1-Nov-12 16:10pm
   
The CMainFrame shouldn't be used as a miscellaneous bin to put all of your global variables in.

And you do not want threads directly accessing your CMainFrame. If you don't lock it properly and intercept every message path that may cause a problem, your application will suffer from mystery crashes.

If you enable locking, you run a risk of seeing severe performance problems in message handling and possible freezing up in the case of race conditions.

CMainFrame has plenty to do in maintaining your main window. Don't give it a bunch of unrelated tasks to manage. Build other classes to take on this role.
If the variables are global then you can access them (simply declare them extern in your thread source file).
   
v2
Comments
[no name] 1-Nov-12 15:49pm
   
Not sure how, would you kindly look at my question which I have just updated and has more info. Regards.
JackDingler 1-Nov-12 16:05pm
   
You can access your CMainFrame from a thread, though it's a bad idea and you shouldn't do it.

You shouldn't be accessing globals at all without a locking mechanism, unless you know for a fact that they will never change.

CMainFrame * pMainFrame = (CMainFrame *) AfxGetMainWnd();
CPallini 1-Nov-12 16:07pm
   
Why cannot you just call AfxGetMainWnd inside the thread?
However, beware worker threads should not 'touch the GUI' see Newcomer's essay:
http://www.flounder.com/workerthreads.htm
[no name] 1-Nov-12 16:09pm
   
Hi, as you see that's exactly what I have but I cannot access the variables. Changing their values is not an issue. I just want my code to return these parameters. Confusing me.
JackDingler 1-Nov-12 16:41pm
   
See my comment just above to learn how to do it.
CPallini 1-Nov-12 16:44pm
   
Why cannot?
What is the problem are you experiencing?
1. You have a memory leak now, fix:
C++
// cpp:
void CYourView::OnSprint()
{
  //..
  THREADVIEW sPar = { this }; // on-stack instance, will be automatically "deleted"
  AfxBeginThread(ChangeColorThread, &sPar); // note: you could pass this directly as well
  //..
}

2. Your thread parameter could contain the CMainFrame-pointer:
C++
// cpp:
typedef struct {
  CYourView* pView;
  CMainFrame* pFrame;
} THREADVIEW;

void CYourView::OnSprint()
{
  //..
  THREADVIEW sPar = { this, static_cast<CMainFrame*>(::AfxGetMainWnd()) };
  AfxBeginThread(ChangeColorThread, &sPar);
  //..
}

3. Your StateOnThread could return the value or even the reference of the frame variable:
C++
// cpp:
int /*int&*/ CYourView::StateOnThread()
{
  CMainFrame* pcFrame(static_cast<CMainFrame*>(AfxGetMainWnd()));
  return pcFrame ? pcFrame->AA : 0;
  /*
  static int si(0);
  return pcFrame ? pcFrame->AA : si;
  */
}

4. Do not use this kind of access for the types longer as INT_PTR :)
   
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900