how to access form controls in another view
-
Hi there, I have a class called CChecklist that derives from CFormview and a checkmark image that I made invisible until the user finishes entry of another view called CFruits. How can I access IDC_CHECKMARK from CFruits class? I tried creating a object of class CChecklist to access its member function in order to change the visibility property of the control, but it gave me a run-time error. Please see below. How can I accomplish this? void CCheckList::makeVisible() { GetDlgItem(IDC_CHECKMARK)->ShowWindow(TRUE); } void CFruits::OnOK() { CChecklist cl; cl.makeVisible(); //run-time error PostMessage(WM_COMMAND,ID_FILE_CLOSE); }
-
Hi there, I have a class called CChecklist that derives from CFormview and a checkmark image that I made invisible until the user finishes entry of another view called CFruits. How can I access IDC_CHECKMARK from CFruits class? I tried creating a object of class CChecklist to access its member function in order to change the visibility property of the control, but it gave me a run-time error. Please see below. How can I accomplish this? void CCheckList::makeVisible() { GetDlgItem(IDC_CHECKMARK)->ShowWindow(TRUE); } void CFruits::OnOK() { CChecklist cl; cl.makeVisible(); //run-time error PostMessage(WM_COMMAND,ID_FILE_CLOSE); }
The CChecklist object you create in the CFruits::OnOK() isn't the same you have subclassed somewhere else in your code. That object isn't subclassed at all and I suppose that this is why you get that runtime error. You could try to do something like this (ain't that pretty though and I'm not sure does this work):
void CFruits::OnOK() { // Obtain handle to checklists parent here HWND hCheckMark = ::GetDlgItem( ::GetDlgItem(handle_to_checklists_parent, IDC_CHECKLIST), IDC_CHECKMARK ); ::ShowWindow( hCheckMark, SW_SHOW ); PostMessage(WM_COMMAND,ID_FILE_CLOSE); }
Cohen
-
Hi there, I have a class called CChecklist that derives from CFormview and a checkmark image that I made invisible until the user finishes entry of another view called CFruits. How can I access IDC_CHECKMARK from CFruits class? I tried creating a object of class CChecklist to access its member function in order to change the visibility property of the control, but it gave me a run-time error. Please see below. How can I accomplish this? void CCheckList::makeVisible() { GetDlgItem(IDC_CHECKMARK)->ShowWindow(TRUE); } void CFruits::OnOK() { CChecklist cl; cl.makeVisible(); //run-time error PostMessage(WM_COMMAND,ID_FILE_CLOSE); }
makeVisible
will try to find a child-control ofCCheckList
with the idIDC_CHECKMARK
. Furthermore, you are creating an instance ofCChecklist
out of the blue - this instance has nothing to do with your other view/control. You should not try to access controls between views, this makes it impossible to move one view to another application, and is considered Real Bad Programming. If you have two views, I assume that you have a single document holding both of them? In that case, the proper way to go about this is via theCDocument
update-mechanism. You do this by callingCDocument::OnUpdateAllViews
when you want to change stuff across view-boundaries, in (pseudo)code:void CFirstView::SomeFunction()
{
// some code making it necessary to change some control
// in another view...CSomeDoc* pDoc = GetDocument();
pDoc->UpdateAllViews( this, HINT_SOME_VALUE_YOU_DEFINE );}
and in the recipient view, you add an update handler, so:
void CSecondView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
if( lHint == HINT_SOME_VALUE_YOU_DEFINE )
{
// Do your stuff
}
}You should also get a basic textbook on C++, you'll have to learn the difference between a class and an instance of a class, for example. Lots of grief lies ahead if you don't know this :-)
-
makeVisible
will try to find a child-control ofCCheckList
with the idIDC_CHECKMARK
. Furthermore, you are creating an instance ofCChecklist
out of the blue - this instance has nothing to do with your other view/control. You should not try to access controls between views, this makes it impossible to move one view to another application, and is considered Real Bad Programming. If you have two views, I assume that you have a single document holding both of them? In that case, the proper way to go about this is via theCDocument
update-mechanism. You do this by callingCDocument::OnUpdateAllViews
when you want to change stuff across view-boundaries, in (pseudo)code:void CFirstView::SomeFunction()
{
// some code making it necessary to change some control
// in another view...CSomeDoc* pDoc = GetDocument();
pDoc->UpdateAllViews( this, HINT_SOME_VALUE_YOU_DEFINE );}
and in the recipient view, you add an update handler, so:
void CSecondView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
if( lHint == HINT_SOME_VALUE_YOU_DEFINE )
{
// Do your stuff
}
}You should also get a basic textbook on C++, you'll have to learn the difference between a class and an instance of a class, for example. Lots of grief lies ahead if you don't know this :-)
I did just as you suggested but I might have missed something. Here are my code samples just in case you can pinpoint the problem. //Main application class BOOL CMPSApp::InitInstance() { /* additional code present */ CMultiDocTemplate* pFirstView = new CMultiDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CMDIChildWnd), RUNTIME_CLASS(CFirstView)); AddDocTemplate(pMHCEditDocTemplate); CMultiDocTemplate* pFirstView = new CMultiDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CMDIChildWnd), RUNTIME_CLASS(CSecondView)); AddDocTemplate(pMHCEditDocTemplate); } void CFirstView::OnOK() { if (g_selected == TRUE) { CDocument* pDoc = GetDocument(); pDoc->UpdateAllViews(NULL); } PostMessage(WM_COMMAND, ID_FILE_CLOSE); } void CSecondView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { If (g_list->items.selected == 0) { GetDlgItem(IDC_APPLE)->ShowWindow(TRUE); } } When UpdateAllViews() is called, there is only one view in the list and that is CFirstView, the calling view. Why does it not recognize the other views? Am I missing something? Thanks!
-
I did just as you suggested but I might have missed something. Here are my code samples just in case you can pinpoint the problem. //Main application class BOOL CMPSApp::InitInstance() { /* additional code present */ CMultiDocTemplate* pFirstView = new CMultiDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CMDIChildWnd), RUNTIME_CLASS(CFirstView)); AddDocTemplate(pMHCEditDocTemplate); CMultiDocTemplate* pFirstView = new CMultiDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CMDIChildWnd), RUNTIME_CLASS(CSecondView)); AddDocTemplate(pMHCEditDocTemplate); } void CFirstView::OnOK() { if (g_selected == TRUE) { CDocument* pDoc = GetDocument(); pDoc->UpdateAllViews(NULL); } PostMessage(WM_COMMAND, ID_FILE_CLOSE); } void CSecondView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { If (g_list->items.selected == 0) { GetDlgItem(IDC_APPLE)->ShowWindow(TRUE); } } When UpdateAllViews() is called, there is only one view in the list and that is CFirstView, the calling view. Why does it not recognize the other views? Am I missing something? Thanks!
You are not only trying to send data between two views, they reside in different documents as well. First, you have to get the doc templates from, the app, loop them and get the documents from each doc template. Well, it's easier to explain in code :-)
POSITION templatePosition = AfxGetApp()->GetFirstDocTemplatePosition();
while( templatePosition != NULL )
{
CDocTemplate* documentTemplate = AfxGetApp()->GetNextDocTemplate( templatePosition );
if( documentTemplate )
{
POSITION documentPosition = documentTemplate->GetFirstDocPosition();
while( documentPosition != NULL )
{
CDocument* document = documentTemplate->GetNextDoc( documentPosition );
if( document )
document->UpdateAllViews( NULL );
}
}
}Now,
OnUpdate
will be called for all views. -
You are not only trying to send data between two views, they reside in different documents as well. First, you have to get the doc templates from, the app, loop them and get the documents from each doc template. Well, it's easier to explain in code :-)
POSITION templatePosition = AfxGetApp()->GetFirstDocTemplatePosition();
while( templatePosition != NULL )
{
CDocTemplate* documentTemplate = AfxGetApp()->GetNextDocTemplate( templatePosition );
if( documentTemplate )
{
POSITION documentPosition = documentTemplate->GetFirstDocPosition();
while( documentPosition != NULL )
{
CDocument* document = documentTemplate->GetNextDoc( documentPosition );
if( document )
document->UpdateAllViews( NULL );
}
}
}Now,
OnUpdate
will be called for all views.It works beautifully! Thanks Johan!
-
It works beautifully! Thanks Johan!
My pleasure :-)