zoukankan      html  css  js  c++  java
  • 控件给父窗口的消息

       一、 创建自定义控件的窗口类

        利用Visual C++6.0集成开发环境创建一个名为Ryg的正规的动态连接库。在Ryg.cpp中,加入

    extern"C" __declspec(dllexport)void RygEntry(){}

        此虚构的导出RygEntry 函数只是为了DLL能被隐式连接。客户必须包括对该函数的调用,而且调用必须在程序的执行路径里,否则编 译器会忽略该调用。作为选择,客户程序也可以在其InitInstance 函数中调用Win32的LoadLibrary函数,这样可显示连接该 DLL。 在Ryg.cpp 中加入

    CRygWnd::RegisterWndClass(AfxGetInstanceHandle());

    此函数注册一个窗口。

        现在编制CRygWnd类,在Insert菜单下选择New Class...子菜单,然后创建一个CWnd的派生类CRygWnd类,打开RygWnd.h文件,增加如下内容:

    class CRygWnd : public CWnd

    {

    .........

    public:

    static BOOL RegisterWndClass(HINSTANCE hInstance);

    .........

    };

    在RygWnd.h中声明了RegisterWndClass函数,现在打开RygWnd.cpp文件,在此文件中编写此函数如下:

    BOOL CRygWnd::RegisterWndClass(HINSTANCE hInstance)

    { WNDCLASS wc; wc.lpszClassName = "RYG"; wc.hInstance = hInstance; wc.lpfnWndProc = RygWndProc; wc.hCursor = ::LoadCursor(NULL,IDC_ARROW); wc.hIcon = 0; wc.lpszMenuName = NULL; wc.hbrBackground = (HBRUSH) ::GetStockObject(LTGRAY_BRUSH); wc.style = CS_GLOBALCLASS; wc.cbClsExtra = 0; wc.cbWndExtra = 0; return (::RegisterClass(&wc) != 0);

    }

        在函数RegisterWndClass中,首先是构造一个窗口类结构WNDCLASS ,然后,用窗口注册函数 RegisterClass对此窗口注册。对话框资源板利用符号化的窗口类名来指定自定义控件RYG(如图一所示)。在此函数中,最重要的是类名 lpszClassName和指向WNDPROC函数的指针 lpfnWndProc 。在构造好WNDCLASS类结构后,函数 RegisterClass把该结构拷贝到进程内存,进程中的任何函数都可以用该类创建窗口。当对话框被初始化时,Windows根据保存在模板里的窗口 类名,创建自定义控件子窗口。

    图 一

        二、 编制Windows过程处理函数WndProc

        在掌握了注册一个窗口类名后,下面要做的是如何编制一个Windows过程WndProc。过程WndProc主要是处理自定义控件窗口 消息,它是自定义窗口与类CRygWnd建立连接的桥梁。为了完成这个工作,首先,我们必须用new构造一个C++类目标,然后,告诉Windows把自 定义控件窗口中的所有消息送到C++类目标,当第一个消息WM_NCCREATE到达时,句柄hWnd为空,因此必须先用new构造一个C++类。下面是 WndProc函数的具体内容。

    LRESULT CALLBACK AFX_EXPORT RygWndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)

    { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CWnd* pWnd; pWnd = CWnd::FromHandlePermanent(hWnd); if(pWnd == NULL){ pWnd = new CRygWnd(); pWnd->Attach(hWnd); } ASSERT(pWnd->m_hWnd == hWnd); ASSERT(pWnd == CWnd::FromHandlePermanent(hWnd)); LRESULT lResult = AfxCallWndProc(pWnd,hWnd,message,wParam,lParam); return lResult;

    }

        当对话框管理者构造一个对话框时,它为对话框里的每一个控件依据其类名调用:CreateWindow,因为我们已经为交通灯注册了类名 RYG,并且告诉Windows送所有的消息到RygWndProc,所以,当对话框管理者创建交通灯控件时,RygWndProc将接收到消息 WM_NCCREATE并构造一个C++类RygWnd。以后所有其他消息将送到AfxCallWndProc。

        三、 自定义控件的窗口消息

        控件窗口与C++类CRygWnd建立起连接后,下面要做的是如何响应窗口消息。控件通过给父窗口发送特定的WM_COMMAND窗口消息与父窗口进行通讯。控件以下面的方式发送窗口消息:

    GetParent()->SendMessage(WM_COMMAND,GetDlgCtrlID() | ID_NOTIFYCODE, (LONG)GetSafeHwnd());

    在客户方,可以用MFC的ON_CONTROL宏映射消息,如下所示:

    ON_CONTROL(ID_NOTIFYCODE,ID_MYCONTROL,OnClickedMyControl)

    在此应充分理解SendMessage函数,SendMessage函数原型是:

    LRESULT SendMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 )

    其中,message是指需要发送的消息,可以是WM_COMMAND,WM_HVSCROLL等消息,wParam和lParam参数是一个32位的附加依赖信息,wParam的高16位为通知码,wParam的低16位为子窗口ID,lParam为子窗口句柄。

        下面创建一个左鼠标按下事件:

    void CRygWnd::OnLButtonDown(UINT nFlags, CPoint point)

    {GetParent()->SendMessage(WM_COMMAND,GetDlgCtrlID() | 0, (LONG)GetSafeHwnd()); CWnd::OnLButtonDown(nFlags, point);

    }

    通过以上步骤就建立了一个自定义控件RYG的框架,然后,我们可以写设置背景色、三个交通灯等函数,这样一个自定义控件就圆满完成了。

        四、 在程序中使用自定义控件DLL

        以上是自定义控件DLL编程,下面是客户程序如何应用此自定义控件DLL的例子。首先,用对话框编辑器创建一个IDD_RYGTEMP模板,在控件窗口里,选择自定义控件,然后,在模板里画一个自定义窗口ID_RYG,如图二所示:


    图 二

        指定自定义窗口类名为RYG(如图一),然后用ClassWizard生产CDialog派生的类CRygDialog。其次,在 RygDialog.cpp文件中编辑构造函数,加入RygEntry()函数,初始化数据成员。最后,映射控件的左按键窗口消息,在 RygDialog.cpp文件里加入消息映射入口和控制函数:

    ON_CONTROL(0,IDR_RYG,OnClickRyg)

    在上面的OnLButtonDown 函数中的SendMessage定义了通知码0,因此,在ON_CONTROL函数中相应的用0通知码。
  • 相关阅读:
    Educational Codeforces Round 10 C. Foe Pairs 水题
    Educational Codeforces Round 10 B. z-sort 构造
    CDOJ 1048 Bob's vector 三分
    Educational Codeforces Round 10 A. Gabriel and Caterpillar 模拟
    第14届电子科大初赛民间盗版部分题目题解
    HDU 5654 xiaoxin and his watermelon candy 离线树状数组 区间不同数的个数
    HDU 5653 Bomber Man wants to bomb an Array. dp
    HDU 5652 India and China Origins 二分+并查集
    HDU 5651 xiaoxin juju needs help 数学
    HDU 5650 so easy 数学
  • 原文地址:https://www.cnblogs.com/cplusplus/p/2160426.html
Copyright © 2011-2022 走看看