你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 编程语言
Demo程序使用条件及环境
 

  境: Windows NT Server 4.0  VC++5.0 

pdh.dll (Win32 SDK 4)Demo例程pdh目录中带有该动态链接库,将这个文件放在VCbin 目录中。

    如果在VC+6.0中使用,则要将pdh目录中的pdh.dllpdh.hpdh.lib ,分别放在VC binincludelib目录中,重新编译、链接。

使用方法:

先在Meters菜单中选择监控面板,与所要连接的机器建立连接(本地或网络),如下图示。然后在Timer菜单中选择Start,就可以进行监视了。

 

 

如何实现图像列表

 

 

在利用VC开发应用程序时,通常会用到列表控件,它的使用是相当容易的,但对于用户来说,在列表上查看信息时形式比较简单,特别是一些数据库应用,需要在查看记录的同时,显示出相应的图像信息,对于这一点常用的列表控件就无能为力了。

如果需要在应用中设置更为直观的列表,特别是在列表中以一定规律显示图象,可以为列表控件增加相应的属性和操作来完成。这里介绍一个实现图像列表控件的方法.

1图像列表控件的定义

以列表控件为基类,我们可以如下定义图像列表控件:

class CImageListBox : public CListBox

{

    DECLARE_DYNAMIC(CImageListBox)

 

// Constructors

public:

    CImageListBox();

    BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);

 

// Attributes

    CImageList* SetImageList(CImageList* pImageList);

    CImageList* GetImageList();

    int AddItem(int nImageIndex, DWORD dwItemData = 0);

 

// Overridables

    virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);

 

// Implementation

protected:

 

    void PreDrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

    void PreMeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);

    int PreCompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct);

    void PreDeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct);

 

    virtual BOOL OnChildNotify(UINT, WPARAM, LPARAM, LRESULT*);

 

#ifdef _DEBUG

    virtual void PreSubclassWindow();

#endif

 

    int CalcMinimumItemHeight();

 

    CImageList* m_pImageList;

    CSize m_bmSize;

 

    // Message map functions

protected:

    //{{AFX_MSG(CImageListBox)

    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

    afx_msg LRESULT OnSetFont(WPARAM wParam, LPARAM lParam);

    afx_msg LRESULT OnLBAddString(WPARAM wParam, LPARAM lParam);

    afx_msg LRESULT OnLBFindString(WPARAM wParam, LPARAM lParam);

    afx_msg LRESULT OnLBFindStringExact(WPARAM wParam, LPARAM lParam);

    afx_msg LRESULT OnLBGetItemData(WPARAM wParam, LPARAM lParam);

    afx_msg LRESULT OnLBGetText(WPARAM wParam, LPARAM lParam);

    afx_msg LRESULT OnLBInsertString(WPARAM wParam, LPARAM lParam);

    afx_msg LRESULT OnLBSelectString(WPARAM wParam, LPARAM lParam);

    afx_msg LRESULT OnLBSetItemData(WPARAM wParam, LPARAM lParam);

    afx_msg LRESULT OnLBSetItemHeight(WPARAM wParam, LPARAM lParam);

    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()

};

 

2 消息响应函数的实现

在以上的定义中可以看到,较之列表控件而言,在图像列表控件中定义了一组消息响应函数,下面介绍两个主要的消息响应函数的实现方法。

l         OnLBGetItemData

OnLBGetItemData的作用是获得当前项的数据内容,实现时需要调用系统的DefWindowProc(LB_GETITEMDATA, wParam, lParam)方法,若返回结果不会出现错误,则进入具体的取数据阶段,这里有一个很重要的结构ILB_IMAGE_DATA,即图像数据内容,结构定义为:

struct ILB_IMAGE_DATA

{

public:

int m_nImage;

DWORD m_dwUserData;

 

ILB_IMAGE_DATA()

{

     m_nImage = -1;

     m_dwUserData = 0;

};

};

将系统调用的结果数据强制为ILB_IMAGE_DATA类型,由于有关项的实际数据就是在ILB_IMAGE_DATA结构中的m_dwUserData属性中保存,其初始值定为0,因此再将结构中的m_dwUserData域内容返回即可。

具体实现为:

LRESULT CImageListBox::OnLBGetItemData(WPARAM wParam, LPARAM lParam)

{

    LRESULT lResult = DefWindowProc(LB_GETITEMDATA, wParam, lParam);

    if (lResult != LB_ERR)

    {

        ILB_IMAGE_DATA* pState = (ILB_IMAGE_DATA*)lResult;

        if (pState == NULL)

            return 0; // default

        lResult = pState->m_dwUserData;

    }

    return lResult;

}

 

l         OnLBSetItemData

与获取项数据对应,OnLBSetItemData完成项图像数据的设置,与获取事件不同的是,如果由系统调用返回的数据内容为空,需要申请一个ILB_IMAGE_DATA结点空间,并且设置其数据域内容m_dwUserData为参数lParam的值,再调用DefWindowProc,并置消息类型为LB_SETITEMDATAlParam参数设置为pState,注意这里需要对pState进行类型强制。具体实现为:

LRESULT CImageListBox::OnLBSetItemData(WPARAM wParam, LPARAM lParam)

{

    LRESULT lResult = DefWindowProc(LB_GETITEMDATA, wParam, 0);

    if (lResult != LB_ERR)

    {

        ILB_IMAGE_DATA* pState = (ILB_IMAGE_DATA*)lResult;

        if (pState == NULL)

            pState = new ILB_IMAGE_DATA;

        pState->m_dwUserData = lParam;

        lResult = DefWindowProc(LB_SETITEMDATA, wParam, (LPARAM)pState);

        if (lResult == LB_ERR)

            delete pState;

    }

    return lResult;

}

 

3 成员函数的实现

在图像列表控件中还定义了一组成员函数,正是对这些成员函数的实现可以完成列表控件功能的扩充。下面介绍几个重要的成员函数的实现方法。

l         AddItem

AddItem的作用是在图像列表控件中增加一项,具体项的图像和数据内容由参数nImageIndexdwItemData确定,其中nImageIndex为与控件对应的图像列表中的元素下标,dwItemData为新增项的数据内容。实现时首先需要判断现有的图像个数是否超出范围,再调用DefWindowProc,发出 LB_ADDSTRING消息,若响应结果没有异常的话,申请一个图像数据结占空间,并置图像域内容m_nImage为参数nImageIndex的值,实际上它反映了该图像项所对应的索引值,另外置数据域内容m_dwUserDatadwItemData,同样需要发出LB_SETITEMDATA消息,由系统调用完成图像项的增加。具体实现如下:

int CImageListBox::AddItem(int nImageIndex, DWORD dwItemData)

{

    ASSERT(m_pImageList != NULL);

    if (m_pImageList->GetImageCount() < nImageIndex)

        return LB_ERR;

    char szText[] = "";

    WPARAM wParam = 0;

    LRESULT lResult = DefWindowProc(LB_ADDSTRING, wParam, (LPARAM)szText);

    if (lResult == LB_ERR || lResult == LB_ERRSPACE)

        return lResult;

ILB_IMAGE_DATA* pState = NULL;

pState = new ILB_IMAGE_DATA;

    pState->m_nImage = nImageIndex;

pState->m_dwUserData = dwItemData;

    wParam = (WPARAM)lResult;

    LRESULT lRes = DefWindowProc(LB_SETITEMDATA, wParam, (LPARAM)pState);

if (lRes == LB_ERR && pState != NULL)

     delete pState;

return lResult;

}

 

l         PreDrawItem

PreDrawItem完成图像项的绘制工作,这里有一个重要的参数lpDrawItemStruct,它是一个LPDRAWITEMSTRUCT类型的结构,首先需要将此结构内容复制到drawItem变量中,这是函数的工作变量。在项索引合理的情况下,利用一系列的图形设备操作完成项的绘制,特别要注意这里的图像大小的设置。具体实现如下:

void CImageListBox::PreDrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

{

    DRAWITEMSTRUCT drawItem;

    memcpy(&drawItem, lpDrawItemStruct, sizeof(DRAWITEMSTRUCT));

    if ((((LONG)drawItem.itemID) >= 0) &&

       ((drawItem.itemAction & (ODA_DRAWENTIRE | ODA_SELECT)) != 0))

    {

        int cyItem = GetItemHeight(drawItem.itemID);

        CDC* pDC = CDC::FromHandle(drawItem.hDC);

        COLORREF newBkColor = GetSysColor(COLOR_WINDOW);

        BOOL fDisabled = !IsWindowEnabled();

        if ((drawItem.itemState & ODS_SELECTED) && !fDisabled)

            newBkColor = GetSysColor(COLOR_HIGHLIGHT);

        COLORREF oldBkColor = pDC->SetBkColor(newBkColor);

        CDC bitmapDC;

        if (bitmapDC.CreateCompatibleDC(pDC))

        {

          ILB_IMAGE_DATA*pState=(ILB_IMAGE_DATA*)lpDrawItemStruct->itemData;

            CRect rectImage = drawItem.rcItem;

            RectImage.left += 1 + max(0, (rectImage.right - m_bmSize.cx) / 2);

            rectImage.top += 1 + max(0, (cyItem - m_bmSize.cy) / 2);

            rectImage.right = rectImage.left + m_bmSize.cx;

            rectImage.bottom = rectImage.top + m_bmSize.cy;

            CBrush brush(newBkColor);

            pDC->FillRect(&(drawItem.rcItem), &brush);

            POINT pt;

            pt.x = rectImage.left;

            pt.y = rectImage.top;

            m_pImageList->Draw(pDC, pState->m_nImage, pt, ILD_NORMAL);

        }

        pDC->SetBkColor(oldBkColor);

    }

    if ((drawItem.itemAction & ODA_FOCUS) != 0)

    {

        CDC* pDC = CDC::FromHandle(drawItem.hDC);

        pDC->DrawFocusRect(&(drawItem.rcItem));

    }

}

l         PreDeleteItem

与一般的列表项相比,图像项的删除需要更多的操作完成,首先将待删除的图像项内容作为参数交给PreDeleteItem处理,此内容将复制到工作变量deleteItem中,这里需要区别两种情况,首先如果其数据内容itemData返回为0,则调用DefWindowProc发出LB_GETITEMDATA消息,并将左右参数设置为deleteItem.itemID0,由系统调用的处理完成删除工作;或itemData域内容不为0,则取出具体数据内容,强制化为ILB_IMAGE_DATA类型,并将其m_dwUserData域的内容赋予工作变量的itemData域,这样就可以调用其父类的删除项操作完成工作了。具体实现如下:

void CImageListBox::PreDeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct)

{

    DELETEITEMSTRUCT deleteItem;

    memcpy(&deleteItem, lpDeleteItemStruct, sizeof(DELETEITEMSTRUCT));

    if (deleteItem.itemData == 0)

    {

        LRESULT lResult = DefWindowProc(LB_GETITEMDATA, deleteItem.itemID, 0);

        if (lResult != LB_ERR)

            deleteItem.itemData = (UINT)lResult;

    }

    if (deleteItem.itemData != 0)

    {

        ILB_IMAGE_DATA* pState = (ILB_IMAGE_DATA*)deleteItem.itemData;

        deleteItem.itemData = pState->m_dwUserData;

        delete pState;

    }

    DeleteItem(&deleteItem);

}

 

4  图像列表控件的使用

在主对话框的定义中需要增加以下代码:

   //{{AFX_DATA(CDemoDlg)

   enum { IDD = IDD_DEMO_DIALOG };

    CImageListBox  m_lstDemo;

   //}}AFX_DATA

m_lstDemo即为对应列表框控件的成员变量,其类型不是CListBox 而是CImageListBox,表明可以由m_lstDemo表示图像列表控件的内容。

如若生成以下的图像列表:

需要在对话框的初始化函数OnInitDialog中只要增加如下代码:

   m_ImageList.Create(IDB_BITMAP, 40, 0, RGB(255, 255, 255));

//创建图像列表

   m_lstDemo.SetImageList(&m_ImageList);       //设置图像列表属性

    for (int i=0; i<7; i++)                        //增加图像列表项

        m_lstDemo.AddItem(i);

可见,图像列表控件的初始化主要是各图像项的加入,图像列表控件要与图像列表对应起来,即图像列表中元素的下标即对应到图像列表控件的项索引。

另外,需要说明的是,为了在列表框控件中显示图像,需要增加相应的位图资源。

 

  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089