Solved

CFormView and modeless dialogs...

Posted on 2000-04-14
22
1,009 Views
Last Modified: 2013-11-20
I tried to create a modeless dialog as a child of a CFormView derived class and got an ASSERT in wincore.cpp:


#ifndef _AFX_NO_OCC_SUPPORT
BOOL CWnd::SetOccDialogInfo(_AFX_OCC_DIALOG_INFO*)
{
      ASSERT(FALSE); // this class doesn't support dialog creation
      return FALSE;
}
#endif

Is it possible to do it? I'd like to achieve the effect of overlaying different dialog templates over the same form view -- the dialog template will change in the view based upon a user selection. I suppose I could create different view classes, but I'm trying to incorporate legacy code from a dialog-based app.

thanks, all...
0
Comment
Question by:captainkirk
  • 12
  • 4
  • 4
  • +2
22 Comments
 
LVL 11

Expert Comment

by:mikeblas
ID: 2717899

Anyway, it's certainly possible to create a modeless dialog as a child of a CFormView. You've done something wrong, so we need to figure out what that is.

To that end, please provide a stack trace leading ot the CWnd::SetOccDialogInfo() call where you say you've asserted.

Also, please let us know which version of MFC you're using.  Show some source code, too--how are you creating the involved windows?

..B ekiM

0
 
LVL 4

Author Comment

by:captainkirk
ID: 2718011
I'm using MFC version 6.00 (as defined in AFXVER_.H)

Here's the stack trace: (I installed symbols for debug, but somehow I can't trace into wincore.cpp)

The assert dialog points to wincore.cpp line 3535 which is the first assert in the function SetOccDialogInfo():

MFC42D! 5f43240e()
MFC42D! 5f433e68()
MFC42D! 5f433d40()
CPageDialog::Create(const char * 0x0000010d, CWnd * 0x0115f520 {CSystemStateInfoFormView hWnd=0x0003075e}, CRect {top=41 bottom=421 left=150 right=707}, unsigned int 0, unsigned long 1342177280) line 49 + 16 bytes
CSystemStateInfoFormView::OnActivateItem(tagNMHDR * 0x0012ee44, long * 0x0012eac0) line 295 + 88 bytes
MFC42D! 5f437616()
MFC42D! 5f437c2b()
MFC42D! 5f446045()
MFC42D! 5f42fc71()
MFC42D! 5f42edb0()
MFC42D! 5f42ece8()
MFC42D! 5f42c889()
MFC42D! 5f42cd25()
MFC42D! 5f4905fd()
COXLayoutManager::LayoutManagerProc(HWND__ * 0x0003075e, unsigned int 78, unsigned int 1095, long 1240644) line 873 + 24 bytes
COXLayoutManager::GlobalLayoutManagerProc(HWND__ * 0x0003075e, unsigned int 78, unsigned int 1095, long 1240644) line 843
USER32! 77e71ff1()
USER32! 77e725bc()
MFC42D! 5f4817c4()
COXShortcutBar::SendSHBNotification(_tagNMSHORTCUTBAR * 0x0012ee44) line 9234 + 23 bytes
COXSHBListCtrl::SendSHBNotification(_tagNMSHORTCUTBAR * 0x0012ee44) line 3734 + 15 bytes
COXSHBListCtrl::ActivateItem(int 0) line 3869 + 12 bytes
CSystemStateInfoFormView::OnInitialUpdate() line 238
CMainFrame::CreateView(int 14, CWnd * 0x002f7348 {CTVGSplitterWnd hWnd=???}, CCreateContext * 0x0012f0fc) line 413 + 16 bytes
CMainFrame::ChangeView(int 14) line 423 + 26 bytes
CMainFrame::OnNotify(unsigned int 101, long 1244240, long * 0x0012f274) line 376
MFC42D! 5f42edb0()
MFC42D! 5f42ece8()
COXMenuBarFrame<CFrameWnd,CDockBar>::WindowProc(unsigned int 78, unsigned int 101, long 1244240) line 1291
MFC42D! 5f42c889()
MFC42D! 5f42cd25()
MFC42D! 5f4905fd()
COXBitmapMenuOrganizer::MenuOrganizerProc(HWND__ * 0x00010730, unsigned int 78, unsigned int 101, long 1244240) line 832 + 24 bytes
COXBitmapMenuOrganizer::GlobalMenuOrganizerProc(HWND__ * 0x00010730, unsigned int 78, unsigned int 101, long 1244240) line 810
USER32! 77e727fe()
USER32! 77e72889()
COXHookWnd::WindowProc(unsigned int 78, unsigned int 101, long 1244240) line 273 + 89 bytes
COXCaptionPainter::WindowProc(unsigned int 78, unsigned int 101, long 1244240) line 733 + 20 bytes
HookWndProc(HWND__ * 0x00010730, unsigned int 78, unsigned int 101, long 1244240) line 330 + 25 bytes
USER32! 77e719d0()
USER32! 77e71982()
NTDLL! 77f763a3()
MFC42D! 5f483080()
COpConView::OnNotify(unsigned int 101, long 1244240, long * 0x0012f974) line 447
MFC42D! 5f42edb0()
MFC42D! 5f42ece8()
MFC42D! 5f42c889()
MFC42D! 5f42cd25()
MFC42D! 5f4905fd()
USER32! 77e71ff1()
USER32! 77e725bc()
MFC42D! 5f4817c4()
COXShortcutBar::SendSHBNotification(_tagNMSHORTCUTBAR * 0x0012fc50) line 9234 + 23 bytes
COXSHBListCtrl::SendSHBNotification(_tagNMSHORTCUTBAR * 0x0012fc50) line 3734 + 15 bytes
COXSHBListCtrl::OnLButtonUp(unsigned int 0, CPoint {x=62 y=152}) line 1325
MFC42D! 5f42f818()
MFC42D! 5f42ece8()
MFC42D! 5f42c889()
MFC42D! 5f42cd25()
MFC42D! 5f4905fd()
USER32! 77e71820()


1) The form view is created as the right pane of a splitter window

2) The form view creates a CPageDialog object as a result of clicking a custom button control:

void CSystemStateInfoFormView::OnActivateItem(NMHDR* pNotifyStruct, LRESULT* result)
{
      LPNMSHORTCUTBAR pNMSHB = (LPNMSHORTCUTBAR)pNotifyStruct;
      ASSERT(pNMSHB != NULL);

      if(pNMSHB->nItem != m_nActivePage && pNMSHB->nItem >= 0 &&
         pNMSHB->nItem < m_arrPages.GetSize())
      {
            CPageDialog* pPageDlg = NULL;
            
            if(m_nActivePage != -1)
            {
                  pPageDlg = m_arrPages[m_nActivePage].pPageDlg;
                  ASSERT(pPageDlg != NULL);
                  ASSERT(::IsWindow(pPageDlg->GetSafeHwnd()));
                  pPageDlg->ShowWindow(SW_HIDE);
            } // end if

            CRect rectFrame = GetPageRect();

            pPageDlg = m_arrPages[pNMSHB->nItem].pPageDlg;
            ASSERT(pPageDlg != NULL);
            
            if(::IsWindow(pPageDlg->GetSafeHwnd()))
            {
                  pPageDlg->ShowWindow(SW_SHOW);
                  pPageDlg->MoveWindow(rectFrame);
            } // end if
            else
            {
                  VERIFY(pPageDlg->Create(MAKEINTRESOURCE(m_arrPages[pNMSHB->nItem].nTemplateID),
                                                      this,
                                                      rectFrame,
                                                      pNMSHB->nItem));
                  
                  ASSERT(::IsWindow(pPageDlg->GetSafeHwnd()));
            } // end else

            pPageDlg->SetFocus();
            m_btnRefresh.EnableWindow(pPageDlg->IsRefreshAvailable());
            m_nActivePage = pNMSHB->nItem;
      } // end if

      ASSERT(m_shb.GetGroupListCtrl(pNMSHB->hGroup) != NULL);
      CString sTopic = m_shb.GetGroupListCtrl(pNMSHB->hGroup)->GetItemText(pNMSHB->nItem, 0);
      m_ctlTopic.SetWindowText(sTopic);

      *result = 0;
} // end OnActivateItem()







BOOL CPageDialog::Create(LPCTSTR lpszTemplateName, CWnd* pParentWnd, CRect rect,
                                     UINT nID, DWORD dwStyle/*=WS_VISIBLE|WS_CHILD*/)
{
      ASSERT(pParentWnd!=NULL);
      ASSERT(lpszTemplateName!=NULL);

      // initialize common controls
      VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTLS_REG));

      // call PreCreateWindow to get prefered extended style
      CREATESTRUCT cs={ 0 };
      cs.style=dwStyle;
      if(!PreCreateWindow(cs))
            return FALSE;

      // create a modeless dialog
      if (!CreateDlg(lpszTemplateName, pParentWnd))
            return FALSE;

      // we use the style from the template - but make sure that
      //  the WS_BORDER bit is correct
      // the WS_BORDER bit will be whatever is in dwRequestedStyle
      ModifyStyle(WS_BORDER|WS_CAPTION,(cs.style&(WS_BORDER|WS_CAPTION))|WS_CHILD);
      ModifyStyleEx(WS_EX_CLIENTEDGE,(cs.dwExStyle&WS_EX_CLIENTEDGE));

      SetDlgCtrlID(nID);

      // initialize controls etc
      if (!ExecuteDlgInit(lpszTemplateName))
            return FALSE;

      OnInitDialog();

      // force the size requested
      SetWindowPos(NULL, rect.left, rect.top,
            rect.right - rect.left, rect.bottom - rect.top,
            SWP_NOZORDER|SWP_NOACTIVATE);

      // make visible if requested
      if (dwStyle & WS_VISIBLE)
            ShowWindow(SW_NORMAL);

      return TRUE;
}


The CreateDlg() call asserts...

This project is quite large to post all of the code, but if you need any more pieces, I'll try to ferret out the needed stuff...

Thanks...
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2718162
> Here's the stack trace: (I installed symbols for debug,
 > but somehow I can't trace into wincore.cpp)

You need to get working symbols for the trace to be meaningful.  (I mean, I can decode it as it is, but that's far too much work to do for free.)

..B ekiM
0
 
LVL 4

Author Comment

by:captainkirk
ID: 2722874
Adjusted points from 150 to 200
0
 
LVL 4

Author Comment

by:captainkirk
ID: 2722875
Mike - I followed the instructions for installing debug symbols for NT SP5, but not all symbols are available. The documentation only showed procedure for earlier service packs, and the EXE used to install them were named differently, so I made an assumption about how to proceed based upon directory/exe names in the service pack install. Could you point me to a complete set of instructions for getting symbols set up properly for NT SP5??? I'm upping the points for you as well...

0
 
LVL 3

Expert Comment

by:_mb_
ID: 2723421
I mean, you can't change the assoziated dialog template of a form view at runtime. You should create a form view for each dialog version. For displaying another dialog you can use code similar to this:
CMainFrame *mf = (CMainFrame *)AfxGetMainWnd();
CView *currentView = mf->GetActiveView();
currentView->DestroyWindow();
mf->CreateView(...);
0
 
LVL 4

Author Comment

by:captainkirk
ID: 2723448
I'm not changing the template of the form view, just attempting to create a child of the form view which is modeless and will visually obscure the client area of the form view.

I can't seem to get a breakpoint set in wincore.cpp for some reason, although I have followed all of the instructions as to getting NT SP5 debug symbols set up...
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2724196
I don't believe the NT symbols include the MFC symbols. Your problem is that you have an MFC42D.DLL that doesn't match your MFC42D.PDB file.  They should be from the exact same build and the exact same date, and they're not.

(You probably also have mismatches for the MFCO42D.*, MFCD42D.*, MFCS42D.*, and MFCN42D.* files.)

..B ekiM

0
 
LVL 4

Author Comment

by:captainkirk
ID: 2724207
Mike - I think you're right, and I have been trying to get them sync'd up by doing total reinstalls of VC++ 6.0 - this hasn't solved the problem, though... the IDE used to ask where certain PDB files were located and now I can't get that to happen. Is there a way to force VC++ to look in a particular place for the MFC debug info???
0
 
LVL 4

Author Comment

by:captainkirk
ID: 2724320
Mike - I think I've finally got the symbol thing straightened out - here's a more readable stack trace:

CWnd::SetOccDialogInfo(_AFX_OCC_DIALOG_INFO * 0x0012e740) line 3535 + 28 bytes
CWnd::CreateDlgIndirect(const DLGTEMPLATE * 0x00622988, CWnd * 0x0115f520 {CSystemStateInfoFormView hWnd=0x001c0158}, HINSTANCE__ * 0x00400000) line 284 + 18 bytes
CWnd::CreateDlg(const char * 0x0000010d, CWnd * 0x0115f520 {CSystemStateInfoFormView hWnd=0x001c0158}) line 238 + 20 bytes
CPageDialog::Create(const char * 0x0000010d, CWnd * 0x0115f520 {CSystemStateInfoFormView hWnd=0x001c0158}, CRect {top=41 bottom=421 left=150 right=707}, unsigned int 0, unsigned long 1342177280) line 49 + 16 bytes
CSystemStateInfoFormView::OnActivateItem(tagNMHDR * 0x0012ee44, long * 0x0012eac0) line 295 + 88 bytes
_AfxDispatchCmdMsg(CCmdTarget * 0x0115f520 {CSystemStateInfoFormView hWnd=0x001c0158}, unsigned int 1095, int 1152, void (void)* 0x00401280 CSystemStateInfoFormView::OnActivateItem(struct tagNMHDR *,long *), void * 0x0012e9d4, unsigned int 38, AFX_CMDHANDLERINFO * 0x00000000) line 118
CCmdTarget::OnCmdMsg(unsigned int 1095, int 1152, void * 0x0012e9d4, AFX_CMDHANDLERINFO * 0x00000000) line 302 + 39 bytes
CView::OnCmdMsg(unsigned int 1095, int 5112960, void * 0x0012e9d4, AFX_CMDHANDLERINFO * 0x00000000) line 159 + 24 bytes
CWnd::OnNotify(unsigned int 1095, long 1240644, long * 0x0012eac0) line 2114
CWnd::OnWndMsg(unsigned int 78, unsigned int 1095, long 1240644, long * 0x0012eb04) line 1609 + 40 bytes
CWnd::WindowProc(unsigned int 78, unsigned int 1095, long 1240644) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x0115f520 {CSystemStateInfoFormView hWnd=0x001c0158}, HWND__ * 0x001c0158, unsigned int 78, unsigned int 1095, long 1240644) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x001c0158, unsigned int 78, unsigned int 1095, long 1240644) line 368
AfxWndProcBase(HWND__ * 0x001c0158, unsigned int 78, unsigned int 1095, long 1240644) line 220 + 21 bytes
COXLayoutManager::LayoutManagerProc(HWND__ * 0x001c0158, unsigned int 78, unsigned int 1095, long 1240644) line 873 + 24 bytes
COXLayoutManager::GlobalLayoutManagerProc(HWND__ * 0x001c0158, unsigned int 78, unsigned int 1095, long 1240644) line 843
USER32! SendMessageWorker@20 + 154 bytes
USER32! SendMessageA@16 + 71 bytes
CWnd::SendMessageA(unsigned int 78, unsigned int 1095, long 1240644) line 39 + 75 bytes
COXShortcutBar::SendSHBNotification(_tagNMSHORTCUTBAR * 0x0012ee44) line 9234 + 23 bytes
COXSHBListCtrl::SendSHBNotification(_tagNMSHORTCUTBAR * 0x0012ee44) line 3734 + 15 bytes
COXSHBListCtrl::ActivateItem(int 0) line 3869 + 12 bytes
CSystemStateInfoFormView::OnInitialUpdate() line 238
CMainFrame::CreateView(int 14, CWnd * 0x002f7348 {CTVGSplitterWnd hWnd=???}, CCreateContext * 0x0012f0fc) line 413 + 16 bytes
CMainFrame::ChangeView(int 14) line 423 + 26 bytes
CMainFrame::OnNotify(unsigned int 101, long 1244240, long * 0x0012f274) line 376
CWnd::OnWndMsg(unsigned int 78, unsigned int 101, long 1244240, long * 0x0012f2b8) line 1609 + 40 bytes
CWnd::WindowProc(unsigned int 78, unsigned int 101, long 1244240) line 1585 + 30 bytes
COXMenuBarFrame<CFrameWnd,CDockBar>::WindowProc(unsigned int 78, unsigned int 101, long 1244240) line 1291
AfxCallWndProc(CWnd * 0x002f6df0 {CMainFrame hWnd=???}, HWND__ * 0x00030216, unsigned int 78, unsigned int 101, long 1244240) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x00030216, unsigned int 78, unsigned int 101, long 1244240) line 368
AfxWndProcBase(HWND__ * 0x00030216, unsigned int 78, unsigned int 101, long 1244240) line 220 + 21 bytes
COXBitmapMenuOrganizer::MenuOrganizerProc(HWND__ * 0x00030216, unsigned int 78, unsigned int 101, long 1244240) line 832 + 24 bytes
COXBitmapMenuOrganizer::GlobalMenuOrganizerProc(HWND__ * 0x00030216, unsigned int 78, unsigned int 101, long 1244240) line 810
USER32! CallWindowProcAorW@24 + 41 bytes
USER32! CallWindowProcA@20 + 25 bytes
COXHookWnd::WindowProc(unsigned int 78, unsigned int 101, long 1244240) line 273 + 89 bytes
COXCaptionPainter::WindowProc(unsigned int 78, unsigned int 101, long 1244240) line 733 + 20 bytes
HookWndProc(HWND__ * 0x00030216, unsigned int 78, unsigned int 101, long 1244240) line 330 + 25 bytes
USER32! DispatchClientMessage@20 + 42 bytes
USER32! __fnDWORD@4 + 36 bytes
NTDLL! KiUserCallbackDispatcher@12 + 19 bytes
OPCON! @ILT+5310(?HookWndProc@@YGJPAUHWND__@@IIJ@Z) address 0x004024c3
USER32! SendNotifyMessageA@16 + 106 bytes

It looks like it's trying to create OLE controls in the dialog, of which there are none. Other form views in the application are intended to be containers, however. Maybe this will help shed a little light...

thanks...
0
 
LVL 4

Author Comment

by:captainkirk
ID: 2724530
Mike - here's another tidbit:  it seems that calling AfxEnableControlContainer() is the culprit. The next question is, as mentioned earlier, some of the form views contain ActiveX controls and others do not. In the present case, control containment seem to foul things up. It is recommended that AfxEnableControlContainer() be called in the InitInstance() function of the app. Is it possible to enable containment for the selected views and disable it for the others??
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Expert Comment

by:sk_gupta
ID: 2726115
can you send the entire code so that i can look into the code and solve ur problem..
0
 
LVL 4

Author Comment

by:captainkirk
ID: 2732064
Mike - any ideas about previous comment??
0
 
LVL 1

Expert Comment

by:cdepetris
ID: 2744331
What class is CPageDialog derived from?



0
 
LVL 4

Author Comment

by:captainkirk
ID: 2747483
It's derived directly from CWnd...
0
 
LVL 1

Accepted Solution

by:
cdepetris earned 200 total points
ID: 2747578
Add the virtual function SetOccDialogInfo to your CPageDialog class and return TRUE), or derive CPageDialog from CDialog (Is there a reason you didn't?).

Chris
0
 
LVL 4

Author Comment

by:captainkirk
ID: 2751617
cdpetris - the code is legacy stuff from a third party, designed to work in a dialog-based app, but I can try your suggestion. I'll get back to you...
0
 
LVL 4

Author Comment

by:captainkirk
ID: 2777437
cdpetris - I still haven't gotten back to this issue because of higher priority items on the plate, but I'm confident that the suggestion will work and so I'll go ahead and give you the points... Mike B: if you're still looking in on this one, I'll post another question to give you some points as well for the effort...

thanks, guys...
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 2919709
> Add the virtual function SetOccDialogInfo to your
 > CPageDialog class and return TRUE), or derive CPageDialog
 > from CDialog (Is there a reason you didn't?).

Err, that strikes me as a bit of a hack.  Can you explain _why_ you recommend doing that?

..B ekiM
0
 
LVL 1

Expert Comment

by:cdepetris
ID: 2920319
It is somewhat of a hack, as it is using an undocumented virtual function from CWnd. I personally would have derived my class from CDialog, as I alluded to in the comment. I however do not know the reason that CWnd was used as a base class, and since by doing that he would not be able to use ActiveX controls on his dialogs anyway, the solution of overriding SetOccDialogInfo (undocumented as it may be) was a possible solution to his problem. If you disagree, I would like to know.

Chris
0
 
LVL 1

Expert Comment

by:cdepetris
ID: 2920391
It is somewhat of a hack, as it is using an undocumented virtual function from CWnd. I personally would have derived my class from CDialog, as I alluded to in the comment. I however do not know the reason that CWnd was used as a base class, and since by doing that he would not be able to use ActiveX controls on his dialogs anyway, the solution of overriding SetOccDialogInfo (undocumented as it may be) was a possible solution to his problem. If you disagree, I would like to know.

Chris
0
 
LVL 4

Author Comment

by:captainkirk
ID: 2932873
This code is from a third party company that I am attempting to reuse within the formview - although now I'm looking atr WMI to do the same thing and may scrap this altogether...
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
VB.NET how to use the Vertical ScrollBar 5 87
sumDigits challenge 9 98
sum67 challenge 35 89
changeXy challenge 13 58
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now