65.9K
CodeProject 正在变化。 阅读更多。
Home

在 VC++ 中创建和使用自定义控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.66/5 (77投票s)

2003年9月22日

6分钟阅读

viewsIcon

265639

downloadIcon

4308

本文将介绍如何创建并使用控件栏上的自定义控件。

Sample Image - CustomControl.gif

引言

您好!这是我为 Code Project 撰写的第四篇文章。在转向 **VC++** 的过程中,我首先关注的是如何借助 **VC++** 创建自定义控件,因为当您想修改任何控件的内容或创建自己的控件时,这是一种非常有用的功能。因此,我决定写这篇文章,希望能为想开发任何控件的新开发者或初学者提供一些我的微薄知识的帮助。

好了,介绍就到这里,我现在转向正题:如何以及为何要创建任何自定义控件。由于我热衷于使用 **Win32 API** 开发应用程序,因为它体积小且是独立的执行文件,所以我从未在 **VC++** 上工作过,但它是一个非常强大的语言,其中的强大功能吸引了我。其中之一就是自定义控件。CodeProject 上有太多文章使用了自定义控件。但当我第一次阅读它们时,我并不明白如何在简单的 Windows 应用程序中创建它们、获取消息并处理这些消息。自定义控件为开发人员提供了一种便捷的方式来创建控件,并将其可视化为常规控件。

(由于我是 VC++ 的初学者,如果在本文中有任何错误,请告诉我).

它在哪里?

现在,问题来了,自定义控件在哪里?答案就在下面。下图显示了自定义控件,它位于控件栏中。

这张图片显示了自定义控件的位置。您可以选择它并直接在您的窗体资源上绘制。

将控件放在窗体后,主要问题出现了:如果您构建并执行程序,但视图不可用,因为您没有为控件选择任何类。这部分将在后面的章节中讨论。

创建类

现在,上图显示了绘制在窗体视图中的自定义控件。现在,您需要右键单击它,然后从弹出菜单中选择“类向导”。

选择类

单击类向导后,这里显示的对话框将出现在屏幕上。从中选择“添加类”,然后选择“新建”。

现在,一旦您点击了“新建”按钮,用于选择自定义控件基类的对话框将如下所示。在这里,您有多种选择来选择任何基类。这意味着您可以自定义基本控件,如静态控件或编辑控件,通过添加新功能,或者您可以创建一个全新的控件。我决定创建一个全新的控件,例如一个画板,因此,我选择了一个基本的 CWnd 类作为基类。

最后,您已经为您的控件创建了一个类。现在,真正的工作开始了……

由于该类是使用 CWnd 作为基类创建的,因此我们需要注册该类,因为它是一个自定义类。所以,我们需要编写 RegisterWndClass() 函数来完成此操作。代码可以如下编写……

BOOL MyCustomControl::RegisterWndClass()
{
    WNDCLASS windowclass;
    HINSTANCE hInst = AfxGetInstanceHandle();

    //Check weather the class is registerd already
    if (!(::GetClassInfo(hInst, MYWNDCLASS, &windowclass)))
    {
        //If not then we have to register the new class
        windowclass.style = CS_DBLCLKS;// | CS_HREDRAW | CS_VREDRAW;
        windowclass.lpfnWndProc = ::DefWindowProc;
        windowclass.cbClsExtra = windowclass.cbWndExtra = 0;
        windowclass.hInstance = hInst;
        windowclass.hIcon = NULL;
        windowclass.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
        windowclass.hbrBackground = ::GetSysColorBrush(COLOR_WINDOW);
        windowclass.lpszMenuName = NULL;
        windowclass.lpszClassName = MYWNDCLASS;

        if (!AfxRegisterClass(&windowclass))
        {
            AfxThrowResourceException();
            return FALSE;
        }
    }

    return TRUE;
}

这样,我们就注册了新的窗口类。现在,您需要在默认类的构造函数中添加以下函数,如下所示:

MyCustomControl::MyCustomControl()
{
    //Register My window class
    RegisterWndClass();
}

我想任何人都想知道 MYWNDCLASS 是什么。答案是,它是我们自定义类的已定义类名。它在 MyCustomControl.h 文件的顶部定义如下:

#define MYWNDCLASS "MyDrawPad"

现在,我们有了自己的类,名为 MyDrawPad

将类附加到自定义控件

一切顺利,我们即将完成自定义控件的创建。最后剩下的就是将自定义控件设置为我们创建的窗口类。为此,在资源视图中右键单击自定义控件,然后选择自定义控件的属性。对话框将如下所示……

然后,将类名设置为我们之前创建的 MyDrawPad。在这里,您可以选择窗口样式,只需更改样式编辑框中的十六进制值。

我尝试了一些值,您也可以尝试一下。

进行数据交换

现在,所有设置都已完成。但是数据必须在窗口和我们的应用程序之间进行交换。所以,在您的对话框类中添加一个自定义控件的变量,如下所示:

// Implementation
protected:
HICON m_hIcon;
MyCustomControl m_drawpad;//This is our custom control

之后,您需要在 DoDataExchage() 函数中添加以下代码来与自定义控件进行交互。

void CCustomControlDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CCustomControlDlg)
    // NOTE: the ClassWizard will add DDX and DDV calls here
    DDX_Control(pDX,IDC_CUSTOM1,m_drawpad);
    //}}AFX_DATA_MAP
}

现在,**您准备好行动了吗?** 然后,按 **Ctrl+F5** 编译并执行程序。(祝您一切顺利……我想不会有错误!!!)

不要忘记在对话框的头文件中编写 #include "MyCustomControl.h",否则会产生太多错误。(*我想您不会怪我的,哈哈哈哈哈哈*)。

添加和处理消息

在成功完成上述关键部分后,您应该会看到包含白色矩形的对话框。这就是我们的自定义控件 **(相信我!)**。那只是一个小窗口。现在,我们需要添加一些 Windows 消息来与该控件进行交互。请仔细阅读……

要向窗口添加 Windows 消息,请右键单击 MyCustomControl 类,然后选择“添加 Windows 消息处理程序”来添加消息,例如鼠标移动、单击等……

就这样,经过一番努力 **(是吗?)**,您已经创建了自己的自定义控件。现在放松一下,开始编写您自己的代码吧。并且请评价我的文章(我喜欢它)。例如,我在包含的源代码中编写了一个简单的 DrawPad

现在,我们将简要总结一下这篇文章。

要创建自定义控件,我们需要执行以下操作:

  • 创建一个包含对话框资源的简单 **MFC 应用程序**。
  • 从 **控件栏** 中选择自定义控件。
  • 在 **对话框资源** 上绘制自定义控件。
  • 右键单击自定义控件并选择 **类向导**。
  • 从“添加类”弹出菜单中,通过选择适当的 **基类** 来添加新的自定义类。
  • 添加代码并注册 **自定义窗口类**。
  • 在对话框中为 **基类(自定义类)** 添加成员变量。
  • 将自定义控件的类设置为 **注册的窗口类名**。
  • 添加 DoDataExchange 代码。
  • 现在,按 **Ctrl+F5** 编译并执行应用程序。
  • 通过 **右键单击类视图中的自定义控件类** 来添加/编辑 Windows 消息处理程序。

如果您真的喜欢它,请发送邮件给我:yogmj@hotmail.com,并向我发送您的建议和本文中的拼写错误。还有源代码中的任何错误(因为我是 BugHunter{ 我想是吧,您觉得呢?})。

© . All rights reserved.