欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
在Dialog中創(chuàng )建View【文集】
共5篇文章:
《略談如何在對話(huà)框創(chuàng )建視圖類(lèi)畫(huà)圖》
《An alternative to the often asked view-in-dialog problem using a dialog bar》
《Creating a View in Dialog (An easy way). 》
《如何在沒(méi)有文檔的情況下使用CView及其派生類(lèi)》
《淺談:切換視時(shí)基于FormView的對話(huà)框屬性設置與ASSERT報錯的問(wèn)題》


 
作者:朱金燦
來(lái)源:blog.csdn.net/clever101
 
     在對話(huà)框上畫(huà)圖可以通過(guò)添加控件來(lái)進(jìn)行,但這種畫(huà)圖有一個(gè)嚴重弊端就是畫(huà)圖范圍受控件范圍控制。最近做一個(gè)程序,需要一個(gè)數據報告窗口,因為輸出的內容比較多,格式不一致(涉及多個(gè)表,但每個(gè)表的數據要嚴格對齊),所以如ListControl等控件并不適合。所以我想到在對話(huà)框上創(chuàng )建視圖類(lèi)上進(jìn)行數據顯示。
 
一是視圖窗口如何動(dòng)態(tài)創(chuàng )建。首先是視圖窗口的定位。一般的動(dòng)態(tài)創(chuàng )建窗口定位窗口的位置不太容易。我從網(wǎng)上找到的一個(gè)好辦法在對話(huà)框上加一個(gè)靜態(tài)文本控件,然后把視圖創(chuàng )建在該控件之上。這個(gè)問(wèn)題想好,創(chuàng )建就基本完成了。
 
創(chuàng )建的具體步驟如下:
1.     定義一個(gè)派生自CScrollView類(lèi)的視圖類(lèi)CDrawView(至于為什么不是CView而是CScrollView,原因我會(huì )在下面談)。
 
2. 在對話(huà)框類(lèi)上定義一個(gè)CDrawView類(lèi)指針*m_pDrawView
具體代碼如何:

BOOL CStaticDataReport::OnInitDialog()
{
 CDialog::OnInitDialog();
 UINT TargetCtrlID = IDC_STATIC;
 CWnd *pWnd = this->GetDlgItem(TargetCtrlID);
 CRect RectTargetCtrl;
 pWnd->GetWindowRect(RectTargetCtrl);
 pWnd->DestroyWindow();
 this->ScreenToClient(RectTargetCtrl);
 //在目標位置動(dòng)態(tài)創(chuàng )建CScrollView
 if (NULL==m_pDrawView)
 {
  return FALSE;
 }
m_pDrawView = (CDrawView*)RUNTIME_CLASS(CDrawView)->CreateObject();
 m_pDrawView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW|WS_VSCROLL|WS_HSCROLL, RectTargetCtrl, this, TargetCtrlID);
 m_pDrawView->ShowWindow(SW_SHOW);
 return TRUE;
}
 
 
二.前面我已經(jīng)談到了在對話(huà)框上繪圖的一個(gè)弊端是繪圖范圍受控件范圍所謂,一不小心就會(huì )出界,如下圖所示:
 
 

  
 使用視圖類(lèi)的好處是你可以使用滾動(dòng)條擴大繪圖范圍,這也是我為何將自定義視圖類(lèi)繼承CScrollView類(lèi)的原因。
 
   實(shí)際上滾動(dòng)條的處理也是不太容易的,主要是滾動(dòng)條添加后如何重繪新的顯示范圍比較麻煩。為此我重翻petzod的名著(zhù)《Windows程序設計》的里面一節:建立更好的滾動(dòng)。將里面的Win API代碼改為MFC實(shí)現。因為我的程序是輸出文字的,我就以如何在文字輸出視圖窗口創(chuàng )建滾動(dòng)條。
 
   首先要創(chuàng )建窗口的滾動(dòng)條,你就必須在動(dòng)態(tài)創(chuàng )建是指定兩種窗口風(fēng)格:WS_VSCROLL|WS_HSCROLL。
 
   其次你需要指定窗口的滾動(dòng)范圍,具體就是滾動(dòng)的最大高度和寬度。我的做法是在視圖類(lèi)定義兩個(gè)變量:
    int m_iMaxWidth;    // 滾動(dòng)的的最大寬度
    int m_MaxNumLines;  // 滾動(dòng)的最大高度
 
這個(gè)你可以自定義滾動(dòng)范圍。
 
其次你還要定義一些文字大小的相關(guān)變量:
    int m_cxChar;
    int m_cxCaps;
    int m_cyChar;
 
在OnCreate函數()(WM_CREATE消息映射函數)獲取字體大小,代碼如下:
 
 
int CDrawView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CScrollView::OnCreate(lpCreateStruct) == -1)
  return -1;
 // TODO: Add your specialized creation code here
 CDC *pDC = GetDC();
 TEXTMETRIC  tm ;
 pDC->GetTextMetrics(&tm) ;
 m_cxChar = tm.tmAveCharWidth ;
 m_cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * m_cxChar / 2 ;
 m_cyChar = tm.tmHeight + tm.tmExternalLeading ;
    ReleaseDC(pDC);
 return 0;
}
 
 
在OnSize函數(WM_SIZE消息映射函數)設置滾動(dòng)范圍:

void CDrawView::OnSize(UINT nType, int cx, int cy)
{
 SCROLLINFO  si ;
 si.cbSize     = sizeof (si) ;
 si.fMask      = SIF_RANGE | SIF_PAGE ;
 si.nMin       = 0 ;
 si.nMax       = m_MaxNumLines - 1 ;
 si.nPage      = cy/m_cyChar ;
 SetScrollInfo (SB_VERT, &si, TRUE) ;
 // Set horizontal scroll bar range and page size
 si.cbSize     = sizeof (si) ;
 si.fMask      = SIF_RANGE | SIF_PAGE ;
 si.nMin       = 0 ;
    si.nMax  = m_iMaxWidth;
 si.nPage      = cx/m_cxChar ;
 SetScrollInfo (SB_HORZ, &si, TRUE) ;
}
 
 

分別響應WM_VSCROLL消息和WM_HSCROLL,主要目的是設置滾定信息和決定是否要更新窗口:
 
void CDrawView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
 // TODO: Add your message handler code here and/or call default
 SCROLLINFO  si ;
 si.cbSize     = sizeof (si) ;
 si.fMask      = SIF_ALL ;
 GetScrollInfo (SB_VERT, &si) ;
 // Save the position for comparison later on
 int iVertPos = si.nPos ;
 switch (nSBCode)
 {
 case   SB_TOP:
  si.nPos       = si.nMin ;
  break ;
 case   SB_BOTTOM:
  si.nPos       = si.nMax ;
  break ;
 case SB_LINEUP:
  si.nPos -= 1 ;
  break ;
 case   SB_LINEDOWN:
  si.nPos += 1 ;
  break ;
 case   SB_PAGEUP:
  si.nPos -= si.nPage ;
  break ;
 case   SB_PAGEDOWN:
  si.nPos += si.nPage ;
  break ;
 case   SB_THUMBTRACK:
  si.nPos = si.nTrackPos ;
  break ;
 default:
  break ;      
 }
 // Set the position and then retrieve it.  Due to adjustments
 //  by Windows it may not be the same as the value set.
 si.fMask = SIF_POS ;
 SetScrollInfo(SB_VERT, &si, TRUE) ;
 GetScrollInfo(SB_VERT, &si) ;
 // If the position has changed, scroll the window and update it
 if (si.nPos != iVertPos)
 {                 
  ScrollWindow (0, m_cyChar * (iVertPos - si.nPos),NULL, NULL) ;
  UpdateWindow() ;
 }
 CScrollView::OnVScroll(nSBCode, nPos, pScrollBar);
}
void CDrawView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
 // TODO: Add your message handler code here and/or call default
 // Get the minimum and maximum scroll-bar positions.
 // Get all the vertical scroll bar information
 int minpos=0;
 int maxpos = 2 + m_iMaxWidth/m_cxChar ;
 SCROLLINFO  si ;
 si.cbSize = sizeof (si) ;
 si.fMask  = SIF_ALL ;
 // Save the position for comparison later on
 GetScrollInfo (SB_HORZ, &si) ;
 int iHorzPos = si.nPos ;
 switch (nSBCode)
 {
 case SB_LEFT:      // Scroll to far left.
  si.nPos = minpos;
  break;
 case SB_RIGHT:      // Scroll to far right.
  si.nPos = maxpos;
  break;
 case SB_ENDSCROLL:   // End scroll.
  break;
 case SB_LINELEFT:      // Scroll left.
  if (si.nPos > minpos)
   si.nPos--;
  break;
 case SB_LINERIGHT:   // Scroll right.
  if (si.nPos < maxpos)
   si.nPos++;
  break;
 case SB_PAGELEFT:    // Scroll one page left.
  {
   // Get the page size.
   SCROLLINFO   info;
   GetScrollInfo (SIF_ALL, &info) ;
   //   pScrollBar->GetScrollInfo(&info, SIF_ALL);
   if (si.nPos > minpos)
    si.nPos = max(minpos, si.nPos - (int) info.nPage);
  }
  break;
 case SB_PAGERIGHT:      // Scroll one page right.
  {
   // Get the page size.
   SCROLLINFO   info;
   GetScrollInfo (SIF_ALL, &info) ;
   //   pScrollBar->GetScrollInfo(&info, SIF_ALL);
   if (si.nPos < maxpos)
    si.nPos = min(maxpos, si.nPos + (int) info.nPage);
  }
  break;
 case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position
  si.nPos = nPos;      // of the scroll box at the end of the drag operation.
  break;
 case SB_THUMBTRACK:   // Drag scroll box to specified position. nPos is the
  si.nPos = nPos;     // position that the scroll box has been dragged to.
  break;
 }
 si.fMask = SIF_POS ;
 SetScrollInfo (SB_HORZ, &si, TRUE) ;
 GetScrollInfo (SB_HORZ, &si) ;
 // If the position has changed, scroll the window
 if (si.nPos != iHorzPos)
 {
ScrollWindow (m_cxChar * (iHorzPos - si.nPos), 0,NULL, NULL) ;
 }
 CScrollView::OnHScroll(nSBCode, nPos, pScrollBar);
}
 
 
然后在OnPaint函數(WM_PAINT消息響應函數)你就可以獲取當前繪圖范圍了:
 

void CDrawView::OnPaint()
{
 CPaintDC dc(this); // device context for painting
SCROLLINFO  si ;
 si.cbSize = sizeof (si) ;
 si.fMask  = SIF_POS ;
 GetScrollInfo(SB_VERT, &si) ;
 int iVertPos = si.nPos ;
 // Get horizontal scroll bar position
 GetScrollInfo (SB_HORZ, &si) ;
 int iHorzPos = si.nPos ;
 // Find painting limits
 int iPaintBeg = max(0,iVertPos + dc.m_ps.rcPaint.top /m_cyChar) ;
 int iPaintEnd = min(m_MaxNumLines - 1,iVertPos + dc.m_ps.rcPaint.bottom/m_cyChar);
 int x = 0;
 int y = 0;
 int i = 0;
 int j =0;
// iPaintBeg為繪圖起始行,iPaintEnd為繪圖結束行
 for (i = iPaintBeg ; i <= iPaintEnd;i++)
 {
      
……
}
}
 
 

效果圖如下:
 

本文來(lái)自CSDN博客,轉載請標明出處:http://blog.csdn.net/clever101/archive/2009/01/14/3779089.aspx
 

An alternative to the often asked view-in-dialog problem using a dialog bar
http://www.codeproject.com/KB/dialog/view_in_dialog.aspx
 

Introduction

I tried to create a View on a Dialog, and thus looked up all the articles on the web. There are several attempts to do this, but more or less all of them produce errors and aren't too useful in  my opinion. So I decided to go a different way. I created a new Window type (called CDialogWindow in my demo project) by deriving the class from CFrameWnd. In this CDialogWindow I created a View using Jorge Vigils code from http://www.codeguru.com/doc_view/ReplacingView.shtml (I modified it of course, but am nonetheless grateful to Jorge). This View was a CScrollView which was my main intention, and perhaps this is also yours. Just imagine a task like displaying a bitmap on a dialog in full-size, which doesn't fit in the Dialog form. My own task was to display a video image generated by an ActiveX-Control. Instead of really displaying this image in a dialog, I created the just mentioned view in the CDialogWindow and added a CDialogBar to this window. The result looks nearly like a dialog containing a view.

But unfortunately I have to deal with an unexpected disadvantage using this simple technique. As the CDialogBar isn't connected with an own class but with the CDialogWindow Class, it is not possible to connect variables with the controls. This means of course, that all the advanced controls like spin buttons, scroll bars etc. which need to be represented by a variable of "Control" type, cannot be used. The functionality of the Window is reduced to input and output in text fields using the methods GetDlgItemInt(), GetDlgItemText(), SetDlgItemInt(), SetDlgItemText(). Perhaps someone can improve my project and tell me how to use all sort of controls in such a window.

Usage

As you can see in the demo project, I have added my CDialogWindow to an MDI project, not using any of the classes created by the application wizard. So if you take my project as a start point, you still have all the functionality of an MDI-app. Mainly I haven't used the generated view class but a class which I imported from another project, because this class was good for my purpose. Just to show you how the window works, I have replaced my video image by a simple text. What does this mean for you, if you want to copy some of my code:

  • Copy the CDialogWindow class to your project and create an object with the DoModeless() method as you can see it in the project.
  • If you also want to display anything but not a document, also copy the CExtraView class and modify the OnDraw() method in order to make it display your stuff.
  • If you want to create a view of a document or create a view from your own view class, just replace the class name in the RUNTIME_CLASS Macro in CDialogWindow::OnCreateClient() and don't forget to declare CVideoWindow friend of your own view class. Of course you will have to do some other little modifications like including the header files and so on.

Conclusion

Pleas write me an email if you could improve my classes, especially, if you achieve to use all sort of controls in the dialog bar. I'm sorry, but I generated the demo project using the German version of the SDK. Thus the auto-generated comments are in German. This should not prevent you from understanding the code, as all pieces of my own code are commented in English.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

thom_as


Member
Thomas Schuster, studying Physics in Ulm / Germany and therefore programming Visual C++.
Occupation: Web Developer
Location:
Germany
 

Creating a View in Dialog (An easy way).
http://www.codeguru.com/Cpp/W-D/dislog/article.php/c5009/
 
 

Environment developed: VC6 Win 2K]

To create a view you normally follow the Microsoft's Document template model. (i.e) Single document template or multi doc template. You can pass three runtime classes to the constructors:

CSingleDocTemplate( UINT nIDResource,CRuntimeClass* pDocClass,CRuntimeClass* pFrameClass,CRuntimeClass* pViewClass );

OR

CMultiDocTemplate( UINT nIDResource,CRuntimeClass* pDocClass,CRuntimeClass* pFrameClass,CRuntimeClass* pViewClass );

When the document template is added, frame (child for MDI , main frame for SDI), document, and a view is created dynamically and added to the application's document template list.

But some times you may need to create a view without using the default document template classes. For instance, if you are to create a view in dialog, you can not use the regular way of document template. In those cases you can use the following method:

BOOL CVwindlgDlg::OnInitDialog(){...CCreateContext pContext;/*** Note:CDialig derived pointer is converted to* CWnd pointer (a common base class for CDialog and CFrameWnd).* Thus casting it back to CFrameWnd is also easy.*/CWnd* pFrameWnd = this;pContext.m_pCurrentDoc = new CMyDocument;pContext.m_pNewViewClass = RUNTIME_CLASS(CMyVw);CMyVw *pView =(CMyVw *) ((CFrameWnd*)pFrameWnd)->CreateView(&pContext);ASSERT(pView);pView->ShowWindow(SW_NORMAL);/*** After a view is created, resize that to* have the same size as the dialog.*/CRect rectWindow;GetWindowRect(rectWindow);/*** Leave a little space for border and title...*/rectWindow.right += 15;rectWindow.top   -= 10;pView->MoveWindow(rectWindow);CString str(AfxGetApp()->m_lpCmdLine);/*** Note: "CMyVw" is a CHTMLView derived class to add some*       spice to the view, I have provided a HTML page*       to which it navigates when the dialog is up.*/char strPath[255];::GetCurrentDirectory(255,(LPSTR)(LPCSTR)strPath);strcat(strPath,"\\defaultpage.html");pView->Navigate(strPath);....return TRUE;  // return TRUE  unless you set the// focus to a control}

Downloads

Download demo project - 6 KB
Download source - 38 KB
 

【錯誤】
ASSERT(  pParentFrame == pDesktopWnd || pDesktopWnd->IsChild(pParentFrame));
解決方法:
重載OnMouseActive(),屏蔽掉找主框架的代碼,就不會(huì )出錯了。但是在debug模式下可以,但是在release版本下卻還是會(huì )出錯?。?!據說(shuō)代碼還是在mfc42.dll里出錯的。難道是MFC4.2的問(wèn)題?  
另一種解決辦法見(jiàn)下篇文章:

如何在沒(méi)有文檔的情況下使用CView及其派生類(lèi)
 
   在MFC中,CView及其派生類(lèi)將顯示及其相關(guān)的操作做的很好,比如在程序中
如果我們的視圖類(lèi)繼承CScrollView了那么我們不用寫(xiě)任何代碼該視圖就能夠
具有滾動(dòng)的響應機制,能夠自動(dòng)根據設置的滾動(dòng)范圍和窗口實(shí)際大小確定是
否顯示滾動(dòng)條(水平或者豎直的),CEditView,CRichEditView等也提供了
相應的在不同實(shí)用范圍內的一些基本操作處理。

    通常在程序中,我們需要處理并且顯示一些數據,將顯示部分如果放到視圖中
的話(huà),我們將可以忽略大部分的窗口交互的細節,將注意力關(guān)注在數據的顯示
上。

    本文是在處理如下的情況中提出的:在數據采集和分析的時(shí)候,常常需要觀(guān)看很
多的數據。我們不可能在程序的主界面上顯示。我們需要一個(gè)彈出窗口來(lái)顯示,
可以隨時(shí)的關(guān)閉之,也就是說(shuō)這樣的窗口應該動(dòng)態(tài)的生成,數量不定(這樣限制
了我們使用切分視圖的選擇)。對于這些彈出窗口,我們可以自己寫(xiě)一個(gè)CWnd
派生類(lèi),自然這是完全可以的,但是這樣要求你可能處理滾動(dòng)等等的一些列消息(我
曾經(jīng)在一個(gè)顯示圖像灰度直方圖、以及二值圖像投影等中遇到過(guò)要求這樣顯示的
情況,當時(shí)就是自己從CWnd派生了一個(gè)類(lèi)來(lái)顯示數據,由于圖像比較大,一屏顯
示不完整,所以要給窗口加滾動(dòng)條,這樣在處理這些消息上花費了我大量的時(shí)間,
而真正顯示數據的代碼卻很少)。因此我也在一直想使用MFC已經(jīng)封裝的非常好的
CView類(lèi)及其派生類(lèi)來(lái)顯示數據。由于我主要用到的就是CScrollView,因此我也
以它為列來(lái)講述怎么用視圖。


基于對話(huà)框和SDI結構的實(shí)現上有不同細節, 必須分開(kāi)了說(shuō):

 
1、如果你的程序是一個(gè)基于對話(huà)框的程序的話(huà)(指的是如利用MFC向導生成的對話(huà)
框程序之類(lèi)),那么事情就很簡(jiǎn)單:
   首先,很自然的在Insert/New Class中插入一個(gè)類(lèi),選擇CScrollView做基類(lèi)
假設你自己的視圖類(lèi)命名為CMyScrollView。
   在對話(huà)框(不論是主界面的對話(huà)框還是新彈出的對話(huà)框,都一樣)的OnInitDialog
中加上如下的代碼:
    
 CRect rectWndClient;
 GetClientRect(&rectWndClient);

 CRuntimeClass *pViewRuntimeClass=RUNTIME_CLASS(CMyScrollView);

 CMyScrollView *pView=(CMyScrollView*)pViewRuntimeClass->CreateObject();
 pView->Create(NULL,NULL,WS_VISIBLE|WS_CHILD,
                          rectWndClient,
                           this,123,NULL);
  pView->OnInitialUpdate();
   
    說(shuō)明:
          1)、由于CView及其派生類(lèi)的構造函數是保護成員,所以采用RuntimeClass方式來(lái)構造
      對對象,
          2)、在Create函數中第一個(gè)參數必須有WS_CHILD屬性,表明視圖是一個(gè)子窗口
          3)、第四個(gè)參數rectWndClient可以視情況,改變,因為你可能只想在對話(huà)框的某個(gè)區域
      創(chuàng )建視圖。
          4)、第五個(gè)參數表明把對話(huà)框作為視圖的父窗口。
          5)、第六個(gè)參數是視圖的ID可以任意指定一個(gè)整數
     
      在創(chuàng )建之后,如果不掉用OnInitialUpdate的話(huà)會(huì )有錯誤,這是因為CScrollView類(lèi)有個(gè)保護成員
     m_nMapMode,它在CScrollView的構造函數中被置為 0,如下
     m_nMapMode = MM_NONE;//在VIEWSCRL.CPP的115行,MM_NONE是宏, 定義為0
    
     下面是錯誤的分析原因:
      通常窗口是在響應WM_PAINT的時(shí)候繪制客戶(hù)區。所有的視圖都派生自CView,他們的的WM_PAINT響應函數如下
           
   void CView::OnPaint() //在VIEWCORE.CPP 176行
  {
   // standard paint routine
   CPaintDC dc(this);
   OnPrepareDC(&dc);
   OnDraw(&dc);
  }
  
       可見(jiàn),在繪圖之前虛函數OnPrepareDC會(huì )被調用,在CScroolView中重寫(xiě)了這個(gè)虛函數,這個(gè)虛函數的
       開(kāi)頭部分如下
      
       ASSERT_VALID(pDC);
      
       #ifdef _DEBUG
   if (m_nMapMode == MM_NONE)
   {
    TRACE0("Error: must call SetScrollSizes() or SetScaleToFitSize()");
    TRACE0("\tbefore painting scroll view.\n");
    ASSERT(FALSE);
    return;
   }
   #endif //_DEBUG
  
   可見(jiàn)如果m_nMapMode是0(在構造函數中被默認置為0)的話(huà)將在調試程序的時(shí)候錯誤
   所以通常應該在調用OnInitialUpdate的時(shí)候(注意:OnInitialUpdate被聲明為CView的public成員函數,但是用MFC向導產(chǎn)生自己派生類(lèi)的OnInitialUpdate函數的時(shí)候被聲明成了protect,你可以將它改成public,然后調用OnInitialUpdate來(lái)初始化自己的視圖,或者在構造函數中設置m_nMapMode為自己想要的映射模式)初始化一些東西,并且設置m_nMapMode的正確值,m_nMapMode的一個(gè)典型值就是 MM_TEXT(關(guān)于映射模式可以看有關(guān)文章或者書(shū)詳細介紹)。
  
  
   上面講述了如何在對話(huà)框中創(chuàng )建視圖和相關(guān)函數調用的原因。 有一點(diǎn)要講的是如果你的對話(huà)框加上了
   最大化按鈕的話(huà),你可能想要在最大話(huà)對話(huà)框的時(shí)候讓視圖也跟著(zhù)變化,所以你要處理對話(huà)框的
   WM_SIZE消息。在其中你依據當前對話(huà)框的實(shí)際大小來(lái)調整視圖大小。這樣你就需要視圖的指針
   因此你可能的程序應該是這樣的
  
   // 在對話(huà)框頭文件中,聲明一個(gè)指向你的視圖的指針
   CMyScrollView     * m_pView;
   // 在構造函數中將指針賦值NULL
   m_pView = NULL;
       
  //在OnInitDialog創(chuàng )建視圖
        
 CRect rectWndClient;
  GetClientRect(&rectWndClient);
 
  CRuntimeClass *pViewRuntimeClass=RUNTIME_CLASS(CMyScrollView);
 
  m_pView=(CMyScrollView*)pViewRuntimeClass->CreateObject();
  m_pView->Create(NULL,NULL,WS_VISIBLE|WS_CHILD,
                               rectWndClient,
                               this,123,NULL);
  m_pView->OnInitialUpdat();
  // 在OnSize中改變視圖大小
 if  (m_pView) //注意在第一次調用OnSize之前視圖還沒(méi)有創(chuàng )建,這也是要在構造函數中將
 {            // m_pView)置NULL的原因
         m_pView->SetWindowPos(NULL,0,0,cx,cy,SWP_NOZORDER);
 }

 

       // 注意我們在上面用new的方法【具體是在pViewRuntimeClass->CreateObject()的時(shí)候】產(chǎn)生了一個(gè)
       CMyScrollView對象,我們的程序并沒(méi)有調用delete的語(yǔ)句,這樣會(huì )不會(huì )產(chǎn)生內存泄漏呢?

      答案是否定的:窗口接受最后一個(gè)消息是WM_NCDESTROY,在OnNcDestroy()中CView調用了PostNcDestory這個(gè)虛函數
      我們的類(lèi)和CScrolView都沒(méi)有重寫(xiě)PostNcDestory,因此他調用CView的PostNcDestory函數 在這個(gè)函數中調用了
      delete this; CView自己刪除了自己 所以不會(huì )有內存泄漏。

2、在SDI(單文檔)程序中的對話(huà)框中使用CView

      在SDI中的彈出對話(huà)框中創(chuàng )建視圖,如果你用,上面的方法1做的話(huà),只要你的鼠標不點(diǎn)擊視圖,就不會(huì )有問(wèn)題(這樣的要求
      恐怕是沒(méi)有人能夠接受的^_^)。
      我們先分析這樣原因。在視圖上點(diǎn)擊鼠標會(huì )執行如下函數

int CView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
       int nResult = CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
       if (nResult == MA_NOACTIVATE || nResult == MA_NOACTIVATEANDEAT)
                return nResult;   // frame does not want to activate

      CFrameWnd* pParentFrame = GetParentFrame(); // 這里  **********(A)
      if (pParentFrame != NULL)
      {
            // eat it if this will cause activation
            ASSERT(  pParentFrame == pDesktopWnd
                        || pDesktopWnd->IsChild(pParentFrame)); //還有這里********(B)

           // 省略
                 ……
      }
       return nResult;
}


   上面的A B 兩處是我們找到的問(wèn)題所在,我們最后出錯的地方是在B處,但原因是在A(yíng).
    當是對話(huà)框程序的時(shí)候如前面1,返回值pParentFrame是0,不會(huì )執行B的斷言,也就不會(huì )有錯。
   但是在上面SDI況下,A返回的pParentFrame是應用程序主框架窗口而pDesktopWnd是視圖所在的對話(huà)框窗口,
   我們分析B的代碼,發(fā)現此時(shí)pParentFrame == pDesktopWnd 不成立。而且pParentFrame(此時(shí)是主窗口)
   也不是pDesktopWnd(此時(shí)是對話(huà)框)的子窗口,所以ASSERT斷言為FALSE ,產(chǎn)生了錯誤。

   單看上面的代碼,及其原因我們還是不能決定如何使用CScrollView。

   但是觀(guān)察A處GetParentFrame的實(shí)現,卻為我們打開(kāi)了希望之門(mén):

   GetParentFrame是從CWnd繼承而來(lái)


  CFrameWnd* CWnd::GetParentFrame() const
 {
      if (GetSafeHwnd() == NULL) // no Window attached
             return NULL;

       ASSERT_VALID(this);

       CWnd* pParentWnd = GetParent();  // start with one parent up
      while (pParentWnd != NULL)
     {
           if (pParentWnd->IsFrameWnd())
                    return (CFrameWnd*)pParentWnd;
            pParentWnd = pParentWnd->GetParent();
      }
       return NULL;
 }

 分析這段代碼,發(fā)現他的目的就是在他的祖先窗口中上溯,直到找到一個(gè)是FrameWnd類(lèi)型的窗口之后, 返回這個(gè)窗口對象的指針(如果沒(méi)有的話(huà),返回NULL),在SDI中這樣的窗口是一定存在的(主框架窗口便是!)。
 我們從前面的分析中知道,pDesktopWnd是對話(huà)框窗口,他一定不是一個(gè)框架窗口,所以斷言的前一部分不能滿(mǎn)足 只有考慮后一個(gè),即pDesktopWnd->IsChild(pParentFrame),先前已經(jīng)說(shuō)了主框架不可能是對話(huà)框的子窗口,所以要是 pDesktopWnd->IsChild(pParentFrame)滿(mǎn)足,即要存在一個(gè)CFrameWnd類(lèi)型的窗口是對話(huà)框的子窗口,也是視圖的 父窗口(因為GetParentFrame是從視圖開(kāi)始上溯尋找的),因此我們可以在對話(huà)框和視圖中間嵌入一個(gè)CFrameWnd或者起派生類(lèi) 的對象。 由于CFrameWnd本身不用什么操作,我們就不用派生一個(gè)自己的CMyFrameWnd了,直接用CFrameWnd, 因此 可能的代碼是這樣的

 CRect rectWndClient;
 GetClientRect(&rectWndClient);

 CFrameWnd *pFrame= new CFrameWnd();
 pFrame->Create(NULL,NULL,WS_VISIBLE|WS_CHILD,rectWndClient,this);

 CRuntimeClass *pViewClass=RUNTIME_CLASS(CMyScrollView);

 CMyScrollView *pView=(CMyScrollView*)pViewClass->CreateObject();
 pView->Create(NULL,NULL,WS_VISIBLE|WS_CHILD,
                         rectWndClient,
                         pFrame,123);
 pView->OnInitialUpdate();


 為了能夠動(dòng)態(tài)的隨對話(huà)框的大小改變視圖的大小,可以把pFrame和pView作為對話(huà)框的成員
 我自己的某此使用過(guò)程中實(shí)現如下

  // 在對話(huà)框頭文件中,聲明一個(gè)指向你的視圖的指針
  CFrameWnd * m_pFrame ;
  CMyScrollView     * m_pView;


   // 在構造函數中將指針賦值NULL
   m_pFrame = NULL;
   m_pView = NULL;
        
  //在OnInitDialog創(chuàng )建視圖
       
 CRect rectWndClient;
 GetClientRect(&rectWndClient);

  m_pFrame= new CFrameWnd();
  m_pFrame->Create(NULL,NULL,WS_VISIBLE|WS_CHILD,rectWndClient,this);
 
  CRuntimeClass *pViewClass=RUNTIME_CLASS(CMyScrollView);

  m_pView=(CMyScrollView*)pViewClass->CreateObject();
 
  m_pView->Create(NULL,NULL,WS_VISIBLE|WS_CHILD,
                                rectWndClient,
                                m_pFrame,123);
  m_pView->OnInitialUpdate();


 // 在OnSize中改變視圖大小

 //注意在第一次調用OnSize之前視圖還沒(méi)有創(chuàng )建,這也是要在構造函數中將
 // m_pFrame,m_pView 置NULL的原因

 if (m_pFrame && m_pView)
 {
  m_pFrame->SetWindowPos(NULL,0,0,cx,cy,SWP_NOZORDER);
  m_pView->SetWindowPos(NULL,0,0,cx,cy,SWP_NOZORDER);
 }
 
《淺談:切換視時(shí)基于FormView的對話(huà)框屬性設置與ASSERT報錯的問(wèn)題
 
最近做的項目中用到了FormView切換視圖,其主要原理是:先新建一些Dialog對話(huà)框,然后給這些對話(huà)框綁定對應的View,注意:這些View要基于FormView。
      一開(kāi)始還好好的,利用切換視的代碼進(jìn)行的很順利(網(wǎng)上的相關(guān)代碼很多,我就不贅述了),但是,后來(lái)新加了兩個(gè)Dialog,不知我怎么弄的,奇怪的事發(fā)生了:先前添加了Dialog都能正常的切換,但是,一切換新添加的Dialog,每次運行到:
 BOOL CFormView::Create(LPCTSTR /*lpszClassName*/, LPCTSTR /*lpszWindowName*/,
 DWORD dwRequestedStyle, const RECT& rect, CWnd* pParentWnd, UINT nID,
 CCreateContext* pContext)
{
 ASSERT(pParentWnd != NULL);
 ASSERT(m_lpszTemplateName != NULL);
 
m_pCreateContext = pContext;    // save state for later OnCreate
 
 #ifdef _DEBUG
 // dialog template must exist and be invisible with WS_CHILD set 
<——請注意此處
 if (!_AfxCheckDialogTemplate(m_lpszTemplateName, TRUE))
 {
  ASSERT(FALSE);          // invalid dialog template name    
  PostNcDestroy();        // cleanup if Create fails too soon
return FALSE;
 }
#endif //_DEBUG
 
中的ASSERT時(shí)就報錯,而在Release版本下卻不會(huì )報錯。我檢查了一下這兩個(gè)新加的Dialog與先前的Dialog屬性有哪些不同,原來(lái)是自己把后來(lái)加的Dialog的Visible屬性設置成了TRUE了, 根據代碼的要求是:對話(huà)框模板必須存在,屬性要設置成不可見(jiàn)和子窗口風(fēng)格。SystemMenu和TitleBar屬性最好都設為False,改完以后,一切正常~~
注:還有一種方法就是在添加Dialog資源時(shí),在Dialog列表上點(diǎn)右鍵->添加資源,選擇Dialog->IDD_FORMVIEW,再點(diǎn)“新建”按鈕,這樣新建出來(lái)的Dialog屬性就會(huì )自動(dòng)配好了
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
CDialog中創(chuàng )設CView窗口
windows程序設計(5)使用滾動(dòng)條
Windows程序設計——窗口鍵盤(pán)消息滾動(dòng)事件
如何在沒(méi)有文檔的情況下使用CView及其派生類(lèi)!
VC彈出選擇“文件路徑”和選擇“文件夾路徑”對話(huà)框
用Excel巧做記帳憑證(轉載)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久