【问题标题】:How do I can call each other function in the different view in MFC?如何在 MFC 的不同视图中调用其他函数?
【发布时间】:2015-10-31 02:40:03
【问题描述】:

我在 MFC 的对话框中创建了一个视图。 我想从对话框中调用一个函数来查看。 如何在不同的视图中调用其他函数?

这里是代码我也附上link

void Cmfc_test5Dlg::OnDropFiles(HDROP hDropInfo)
{
int nFiles;
char szPathName[MAX_PATH]; 
CString strFileName;
nFiles = ::DragQueryFile( hDropInfo, 0xFFFFFFFF, szPathName, MAX_PATH );

{
::DragQueryFile(hDropInfo, 0, szPathName, MAX_PATH);
}
::DragFinish(hDropInfo);
CDialog::OnDropFiles(hDropInfo);

DoDisplayImage(); <---Here is My call function.

CDialogEx::OnDropFiles(hDropInfo);

}

这是另一个函数

void CTestview::DoDisplayImage()
{
  CDC *pDC = GetDC();
  if (pDC != NULL && m_Image.isValid() ) 
    {
      CRect rectClient;
      GetClientRect(rectClient);
      pDC->FillSolidRect(rectClient,pDC->GetBkColor());
      // Set up the Windows bitmap header
      BITMAPINFOHEADER bmi;
      bmi.biSize = sizeof(BITMAPINFOHEADER);    // Size of structure
      bmi.biWidth = m_Image.columns();          // Bitmaps width in pixels
      bmi.biHeight = (-1)*m_Image.rows();       // Bitmaps height n pixels
      bmi.biPlanes = 1;                         // Number of planes in the image
       bmi.biBitCount = 32;                      // The number of bits per pixel
       bmi.biCompression = BI_RGB;               // The type of 
       ...

以及从这里调用的 DoDisplayImage 函数

void CTestview::OnDraw(CDC* pDC)
{
    CDocument* pDoc = GetDocument();
    // TODO: add draw code here
    DoDisplayImage();
}

但是,如您所知,我的问题是我无法在 void Cmfc_test5Dlg::OnDropFiles(HDROP hDropInfo) 函数中调用 DoDisplayImage(),我还想在 DoDisplayImage 中获取 OnDropFiles 函数的 szPathName。

我应该怎么做才能解决这个问题?

更新 1

当我做如下错误。

1>d:\work\mfc_test5\mfc_test5\Testview.h(29):错误 C2143:语法错误:缺少 ';'前 '*' 1>d:\work\mfc_test5\mfc_test5\Testview.h(29):错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持默认整数 1>d:\work\mfc_test5\mfc_test5\Testview.h(29):错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持默认整数 1> 1>构建失败。

在 TestView.h 中,

#pragma once



// CTestview view

class CTestview : public CScrollView
{
    DECLARE_DYNCREATE(CTestview)

protected:
    CTestview();           // protected constructor used by dynamic creation
    virtual ~CTestview();

public:
#ifdef _DEBUG
    virtual void AssertValid() const;
#ifndef _WIN32_WCE
    virtual void Dump(CDumpContext& dc) const;
#endif
#endif

protected:
    virtual void OnDraw(CDC* pDC);      // overridden to draw this view
    virtual void OnInitialUpdate();     // first time after construct

    DECLARE_MESSAGE_MAP()
public:
    CTestView* pTestView; <---- is this right?
};

这里是代码我也附上link

更新2

我做了如下。

// mfc_test5Dlg.h : header file
//

#pragma once
#include "afxcmn.h"


// Cmfc_test5Dlg dialog
class CTestview;//adding
class Cmfc_test5Dlg : public CDialogEx
{
// Construction
public:
    Cmfc_test5Dlg(CWnd* pParent = NULL);    // standard constructor
    CTestview* pTestView;//adding

// Dialog Data
    enum { IDD = IDD_MFC_TEST5_DIALOG };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support


Cmfc_test5Dlg::Cmfc_test5Dlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(Cmfc_test5Dlg::IDD, pParent)
    , m_CString(_T(""))
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    pTestView = NULL; //adding
}

但是在这部分我不明白如何在我的情况下实现它。

You have to set pTestView each time the dialog is created. For example:

void CTestview::foo()
{
    Cmfc_test5Dlg dlg(...);
    dlg.pTestView = this;
    dlg.DoModal();
}

【问题讨论】:

  • 为什么不能调用DoDisplayImage()?那是因为您没有对视图的任何引用吗?
  • 在您的第二次编辑中,您将CTestViewCTestview 放在一起导致错误(我的意思是在答案中写CTestview)。我说在对话框中放一个CTestview指针,而不是CTestview
  • @BarmakShemirani 请你帮我在我的代码中提供链接
  • 我更新了答案。您应该先在一个简单的 c++ 控制台程序上尝试一下。

标签: c++ visual-studio-2010 visual-c++ mfc imagemagick


【解决方案1】:

在 MFC 的 Document/View 架构中,您不会从外部调用 View 的方法。

让 View 绘制内容的方法是通过其 Document 更新内容并调用 UpdateAllViews(),可能带有提示(用于优化)。

【讨论】:

    【解决方案2】:

    这是基本的 C++。您有不相关的 A 类和 B 类。如何从 B 访问 A?试试这个控制台程序:

    class TA {
    public:
        void foo() {
            cout << "TA\n";
        }
    };
    
    class TB {
    public:
        TA *A;
        TB() {
            A = nullptr;
        }
    
        void foo() {
            if (A)
                A->foo();
        }
    };
    
    int main()
    {
        TA *a = new TA;
        TB *b = new TB;
    
        b->A = a;
        b->foo(); //prints "TA"
    
        delete a;
        delete b;
        return 0;
    }
    

    在 MFC 中也是如此。您可以声明一个指向CTestView 的指针并在对话框类中使用该指针:

    class CTestview;
    class Cmfc_test5Dlg : public CDialogEx
    {
    public:
        CTestView* pTestView;
        ...
    };
    
    include "TestView.h"
    Cmfc_test5Dlg::Cmfc_test5Dlg()
    {
        pTestView = NULL;
    }
    

    您必须在每次创建对话框时设置pTestView。例如:

    void CTestview::foo()
    {
        Cmfc_test5Dlg dlg(...);
        dlg.pTestView = this;
        dlg.DoModal();
    }
    

    然后在Cmfc_test5Dlg 的任何地方使用pTestView-&gt;DoDisplayImage()。例如:

    void Cmfc_test5Dlg::OnDropFiles(HDROP hDropInfo)
    {
       ...
       if (pTestView != NULL)
           pTestView->DoDisplayImage();
    }
    

    另一种方法是使用全局变量:

    CTestview *global_TestView;
    CTestview::CTestview()
    {
        global_TestView = this;
        ...
    }
    
    //---- another cpp file:
    extern CTestview *global_TestView;
    ...
    void Cmfc_test5Dlg::OnDropFiles(HDROP hDropInfo)
    {
       ...
       if (global_TestView != NULL)
           global_TestView->DoDisplayImage();
    }
    

    但由于多种原因,此方法可能会失败。例如,如果可能有多个 CTestview

    ps,不要连续调用CDialogEx::OnDropFiles(hDropInfo);CDialogEx::OnDropFiles(hDropInfo);,没有意义。

    【讨论】:

    • 谢谢,但我不能完全理解这里“这是基本的 c++,它不是特定于 MFC。您可以声明指向 CTestView 的指针并在对话框类中使用该指针:class CTestview; class Cmfc_test5Dlg: public CDialogEx { public: CTestView* pTestView; ... }; include "TestView.h" Cmfc_test5Dlg::Cmfc_test5Dlg() { pTestView = NULL; }" 请再告诉我一次好吗?
    • 我已更新为链接。请检查我的代码好吗?
    • 我的意思是它是基本的 c++,这意味着你不知道基本的 c++。如果不了解基本的 c++,很难在 MFC 中找到自己的方式。
    • 谢谢,但这种情况在不同的班级之间有效。顺便说一句,这是否适用于我的情况(对话框类和视图类)的不同视图?
    • 再次阅读说明。我还展示了一种使用“全局变量”的不同方法。谷歌搜索“C++ 全局变量”。有一百万个例子。
    【解决方案3】:

    所以您想在将文件拖放到子对话框时在视图中显示图像?

    在对话框的构造函数中提供一个指向视图的指针作为附加参数,并将其存储在对话框成员变量m_view 中。然后调用它:

    m_view->DoDisplayImage();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-03
      • 2018-06-09
      相关资源
      最近更新 更多