• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            無(wú)我

            讓內(nèi)心永遠(yuǎn)燃燒著偉大的光明的精神之火!
            靈活的思考,嚴(yán)謹(jǐn)?shù)膶?shí)現(xiàn)
            豪邁的氣魄、頑強(qiáng)的意志和周全的思考

            MFC的listctrl控件中水平添加按鈕并刷新

                  這個(gè)項(xiàng)目中需要用MFC實(shí)現(xiàn)一個(gè)界面功能:listctrl中水平添加按鈕。
                  MFC本身的listctrl控件只能顯示簡(jiǎn)單的文本,簡(jiǎn)單的添加按鈕也不是一兩句代碼能解決的問(wèn)題,從這方面講,MFC開(kāi)發(fā)界面真是不得已而為之。
               
                  因?yàn)樾枰陌粹o數(shù)目是不確定的,所以只能是動(dòng)態(tài)創(chuàng)建,然后再根據(jù)listctrl控件的位置計(jì)算出按鈕應(yīng)該放置的位置,然后將按鈕移動(dòng)到指定坐標(biāo)。
                  對(duì)MFC里面的類和關(guān)系,我并不熟悉,所以花了很長(zhǎng)時(shí)間搜索,最終在下載的好幾個(gè)版本的代碼中找了一個(gè)基本可用的,修改開(kāi)發(fā)。

               一、      針對(duì)我們需要管理自己動(dòng)態(tài)創(chuàng)建的按鈕,所以我們自定義了一個(gè)CButton的子類。

             1
             2class CButtonEx : public CButton
             3{
             4    DECLARE_DYNAMIC(CButtonEx)
             5
             6public:
             7    CButtonEx();
             8    CButtonEx( int nItem, int nSubItem, CRect rect, HWND hParent,void * pData );
             9    virtual ~CButtonEx();
            10
            11protected:
            12    DECLARE_MESSAGE_MAP()
            13public:
            14    afx_msg void OnBnClicked(); //點(diǎn)擊響應(yīng)函數(shù)
            15    int m_inItem;           //所屬listctrl的行
            16    int m_inSubItem;        //所屬listctrl的列
            17    CRect m_rect;           //按鈕所在的位置
            18    HWND m_hParent;         //按鈕的父窗口
            19    BOOL bEnable;
            20    void * m_pData;         //按鈕帶的用戶自定義數(shù)據(jù)
            21}
            ;

            1CButtonEx::CButtonEx( int nItem, int nSubItem, CRect rect, HWND hParent,void * pData )   
            2{
            3    m_inItem = nItem;
            4    m_inSubItem = nSubItem;
            5    m_rect = rect;
            6    m_hParent = hParent;
            7    bEnable = TRUE;
            8    m_pData = pData;
            9}

                  按鈕點(diǎn)擊的響應(yīng)邏輯在OnBnClicked函數(shù)中。之所以加入m_pData成員變量,是便于存放用戶自定義數(shù)據(jù),這樣就可以在OnBnClicked函數(shù)中根據(jù)自定義變量做出相應(yīng)的處理。

              二、自定義listctrl子類
             1#pragma once
             2
             3#include "ButtonEx.h"
             4#include <map>
             5using namespace std;
             6
             7typedef map<int,CButtonEx*> button_map;
             8// CListCtrlEx
             9
            10class CListCtrlEx : public CListCtrl
            11{
            12    DECLARE_DYNAMIC(CListCtrlEx)
            13
            14public:
            15    CListCtrlEx();
            16    virtual ~CListCtrlEx();
            17
            18protected:
            19    DECLARE_MESSAGE_MAP()
            20
            21public:
            22    //動(dòng)態(tài)創(chuàng)建Button
            23    void createItemButton( int nItem, int nSubItem, HWND hMain,LPCTSTR lpszCaption ,void * pData);
            24    //釋放創(chuàng)建的Button
            25    void release();
            26    void deleteItemEx( int nItem );
            27    button_map m_mButton;
            28
            29public:
            30    UINT m_uID;     
            31    CFont font ;    //按鈕上面的字體
            32    void updateListCtrlButtonPos(); //更新按鈕的位置
            33    //void enableButton( BOOL bFlag, int iItem );
            34    //重載水平滾動(dòng)條滾動(dòng)函數(shù)
            35    afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
            36}
            ;

            CListCtrlEx實(shí)現(xiàn)如下:
             1CListCtrlEx::CListCtrlEx()
             2{
             3    m_uID = 0;
             4
             5    font.CreatePointFont(100,"宋體");
             6}

             7
             8CListCtrlEx::~CListCtrlEx()
             9{
            10    release();
            11}

            然后是創(chuàng)建按鈕的邏輯,注意我這里是在ListCtrl控件中水平添加按鈕(同一行的每一列),而不是垂直(同一列的每一行):
             1void CListCtrlEx::createItemButton( int nItem, int nSubItem, HWND hMain,LPCTSTR lpszCaption ,void * pData)
             2{
             3    CRect rect;
             4    /*if( !EnsureVisible(nItem, TRUE)) 
             5        return ;*/

             6
             7    GetSubItemRect(nItem, nSubItem, LVIR_BOUNDS, rect);
             8    rect.bottom = rect.top + 150;
             9    //rect.right = rect.left + 150;
            10
            11    DWORD dwStyle =  WS_CHILD | WS_VISIBLE | BS_MULTILINE;
            12    CButtonEx *pButton = new CButtonEx(nItem,nSubItem,rect,hMain,pData);
            13    m_uID++;
            14
            15    pButton->Create(lpszCaption,dwStyle, rect, this, m_uID);
            16    //CDC* pDC = pButton->GetDC();
            17    //pDC->SetTextColor(RGB(255,0,0));
            18    pButton->SetFont(&font);
            19    
            20   // m_mButton.insert( make_pair( nItem, pButton ) );    //縱向添加用
            21    m_mButton.insert( make_pair( nSubItem, pButton ) ); //單行橫向添加用
            22    
            23    return;
            24}

            25
            上面的代碼中,我將按鈕的高都設(shè)為了150,而不是listctrl默認(rèn)的一點(diǎn)點(diǎn)高。
             1void CListCtrlEx::release()
             2{
             3    button_map::iterator iter = m_mButton.begin();
             4    while ( iter != m_mButton.end() )
             5    {
             6        delete iter->second;
             7        iter->second = NULL;
             8        iter++;
             9    }

            10    m_mButton.clear();
            11}

            當(dāng)完成以上代碼以后,就可以在對(duì)話框中添加listctrl控件的成員變量了:CListCtrlEx m_lsPath;
            然后在OnInitDialog函數(shù)中給listctrl控件添加按鈕:
            1int i = 0;
            2    m_lsPath.InsertColumn(i,_T(""),LVCFMT_LEFT,150); 
            3
            4    nRow = m_lsPath.InsertItem(0"tim");
            5
            6    TCHAR caption[1000= {0};//標(biāo)題
            7    ImageCfg * pImageCfg = new ImageCfg;//自定義數(shù)據(jù)
            8    m_lsPath.createItemButton(nRow,i++,m_lsPath,caption,pImageCfg);

            這樣看起來(lái)一切很好,但是運(yùn)行時(shí)發(fā)現(xiàn),當(dāng)按鈕較多需要水平滾動(dòng)條時(shí),拖動(dòng)水平滾動(dòng)條并不能正確的顯示按鈕!
            所以我們還需要處理CListCtrlEx的水平滾動(dòng)命令:
            1void CListCtrlEx::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
            2{
            3    // TODO: 在此添加消息處理程序代碼和/或調(diào)用默認(rèn)值    
            4    CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
            5    updateListCtrlButtonPos();
            6    //Invalidate(FALSE);
            7}
             
             1void CListCtrlEx::updateListCtrlButtonPos()
             2{
             3    button_map::iterator iter = m_mButton.begin();
             4    button_map::iterator itrEnd = m_mButton.end();
             5    //調(diào)整橫向的
             6    int posx = GetScrollPos(SB_HORZ);//取得水平滾動(dòng)條的位置
             7    for (;iter != itrEnd;++iter)
             8    {
             9        CRect rect;
            10        rect = iter->second->m_rect;
            11        rect.left -= posx;
            12        rect.right -= posx;
            13        iter->second->ShowWindow( SW_HIDE );
            14
            15        iter->second->MoveWindow( &rect );
            16        iter->second->ShowWindow( SW_SHOW );
            17        /*if( iLine < iTopIndex )
            18        {
            19            iterUp->second->ShowWindow( SW_HIDE );
            20        }*/

            21    }

            22    return;
            23}

            這里操作的過(guò)程是:取得控件水平滾動(dòng)條的位置,然后將所有按鈕的水平坐標(biāo)左移響應(yīng)的值。其實(shí)這里可以優(yōu)化一下:判斷只有那些按鈕會(huì)被顯示才處理,其他的并不需要處理,例如:
             1void CListCtrlEx::updateListCtrlButtonPos()
             2{
             3    button_map::iterator iter = m_mButton.begin();
             4    button_map::iterator itrEnd = m_mButton.end();
             5
             6    CRect rect;
             7    GetClientRect(rect);
             8    LONG width = rect.right;
             9    //調(diào)整橫向的
            10    int posx = GetScrollPos(SB_HORZ);//取得水平滾動(dòng)條的位置
            11    for (;iter != itrEnd;++iter)
            12    {
            13        iter->second->ShowWindow( SW_HIDE );
            14
            15        rect = iter->second->m_rect;
            16        rect.left -= posx;
            17        rect.right -= posx;
            18        if (rect.right > 0)
            19        {
            20            if (rect.left > width)
            21            {
            22                //其他的都超出了顯示范圍
            23                break;
            24            }

            25            iter->second->MoveWindow( &rect );
            26            iter->second->ShowWindow( SW_SHOW );
            27        }

            28                
            29        /*if( iLine < iTopIndex )
            30        {
            31            iterUp->second->ShowWindow( SW_HIDE );
            32        }*/

            33    }

            34    return;
            35}
             
            這樣,按鈕就能正確刷新了。

            不過(guò),還有一個(gè)小問(wèn)題:在拖動(dòng)滾動(dòng)條時(shí),我們發(fā)現(xiàn)界面有些閃爍。但是我還沒(méi)找到合適的解決方法。歡迎大家給出可行的方案。

            posted on 2014-05-10 17:01 Tim 閱讀(5982) 評(píng)論(0)  編輯 收藏 引用 所屬分類: windows系統(tǒng)

            <2025年6月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            導(dǎo)航

            統(tǒng)計(jì)

            公告

            本博客原創(chuàng)文章,歡迎轉(zhuǎn)載和交流。不過(guò)請(qǐng)注明以下信息:
            作者:TimWu
            郵箱:timfly@yeah.net
            來(lái)源:m.shnenglu.com/Tim
            感謝您對(duì)我的支持!

            留言簿(9)

            隨筆分類(173)

            IT

            Life

            搜索

            積分與排名

            最新隨筆

            最新評(píng)論

            閱讀排行榜

            色噜噜狠狠先锋影音久久| 久久久久亚洲精品无码网址| 亚洲国产婷婷香蕉久久久久久| 国产精品亚洲美女久久久| 久久香蕉国产线看观看猫咪?v| 亚洲精品久久久www| 亚洲中文字幕无码一久久区| 天堂久久天堂AV色综合| 国产精品日韩深夜福利久久| 日韩精品久久久久久久电影| 亚洲香蕉网久久综合影视| 色偷偷888欧美精品久久久| 久久综合亚洲色HEZYO社区| 国产一区二区三区久久| 亚洲国产成人精品久久久国产成人一区二区三区综 | 免费无码国产欧美久久18| 久久精品国产亚洲AV高清热| 久久人人爽人人爽AV片| 国产精品禁18久久久夂久 | 一本久道久久综合狠狠爱| 国产成人精品久久综合| 久久久久久久人妻无码中文字幕爆| 国产精品久久久99| 精品久久久久久无码专区| 国产精品久久久久a影院| 国内精品久久久久久麻豆| WWW婷婷AV久久久影片| 狠狠色婷婷久久一区二区| 久久久久综合中文字幕 | 精品国产91久久久久久久a| 久久综合久久自在自线精品自| 久久精品三级视频| 国产精品免费久久| 国产亚洲婷婷香蕉久久精品| 99久久99这里只有免费费精品 | 久久这里的只有是精品23| 精品久久人人爽天天玩人人妻| 国产美女久久精品香蕉69| 亚洲AV日韩精品久久久久久久| 久久九九久精品国产免费直播| 久久久WWW成人免费精品|