• <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>

            我用VC寫的一個可以自動改變控件位置和大小的對話框類。從這個類繼承的對話框類,只要在OnInitDialog()里寫幾行簡單的代碼,對話框上的控件就會隨著對話框大小的改變而改變自己的位置和大小。

             

                    在用VC開發應用程序時,經常會要做一些可以改變大小的對話框,而這個時候就要求對話框上的控件會隨著對話框大小的改變而改變自己的位置和大小。如果控件比較少,那可以在對話框的OnSize()事件里面添加代碼,通過計算來調整各個控件的位置和大小;但是,如果對話框上的控件比較多的話,那這將是一件非常痛苦的事情!要是程序中又有很多可以改變大小的對話框,那一個一個的OnSize()寫下來,那會使程序員崩潰的!
                    為了解決這個問題,我寫了一個自動改變控件位置和大小的對話框類ClxDialog。從這個類繼承的對話框類,只要在OnInitDialog()里對控件做一些簡單的設置,對話框上的控件就會隨著對話框大小的改變而改變自己的位置和大小。
                    為了保存控件信息,我定義了一個結構:

            typedef struct _dlgControlTag
            {
                int iId;  //  控件ID
                int iFlag;  //  標志,表示怎樣改變控件的位置或者大小
                int iPercent;  //  改變值占對話框改變值的百分比
            } DLGCTLINFO, *PDLGCTLINFO;

                    這里要對結構中的iFlag和iPercent進行一些解釋。其中iFlag是下面的枚舉值:

            enum
            {
                MOVEX = 0,  //  控件在X方向(左右)移動
                MOVEY,  //  控件在Y方向(上下)移動
                MOVEXY,  //  控件在X方向和Y方向同時移動
                ELASTICX,  //  控件在X方向(寬度)改變大小
                ELASTICY,  //  控件在Y方向改(高度)改變大小
                ELASTICXY  //  控件在X方向和Y方向同時改變大小
            };

                    iPercent表示改變值占對話框改變值的百分比。例如,一個控件的iPercent值為100,iFlag值為MOVEX,那么當對話框的寬度改變100個單位的時候,這個控件就在X方向移動100個單位;又如,一個控件的iPercent值為100,iFlag值為ELASTICXY,那么當對話框的寬度和高度分別改變100個單位的時候,控件的高度和寬度也相應的改變100個單位。
                    下面是設置控件信息的函數:

            BOOL SetControlProperty(PDLGCTLINFO lp, int nElements);

                    使用起來非常簡單,在對話框的OnInitDialog()函數里面添加類似下面的代碼就行了:

            //  控件信息數組
            static DLGCTLINFO  dcMenuGroup[] =
            {
                {IDOK, MOVEX, 100},
                {IDCANCEL, MOVEX, 100},
                {IDC_BUTTON1, MOVEX, 50},
                {IDC_BUTTON1, MOVEY, 100},
                {IDC_EDIT1, ELASTICX, 100},
                {IDC_EDIT2, ELASTICX, 50},
                {IDC_EDIT3, ELASTICX, 50},
                {IDC_EDIT3, MOVEX, 50},
                {IDC_EDIT4, ELASTICY, 100},
                {IDC_EDIT5, ELASTICX, 100},
                {IDC_EDIT5, ELASTICY, 50},
                {IDC_EDIT6, ELASTICX, 100},
                {IDC_EDIT6, ELASTICY, 50},
                {IDC_EDIT6, MOVEY, 50},
            };

            //  設置控件信息
            SetControlProperty(dcMenuGroup, sizeof(dcMenuGroup)/sizeof(DLGCTLINFO));

                    下面就是使用上面這段代碼的對話框改變大小前后的效果圖:

             

              

                    對兩張截圖的比較我們可以很容易的理解上面那段代碼。
                    我還提供了一個函數:

            void ShowSizeIcon(BOOL bShow = TRUE);

                    來設置是否顯示對話框右下角表示可以改變大小的圖標。這個圖標是從系統中讀取的,我上面的截圖是Windows2000下的,在WindowsXP中就會自動變成XP風格的。
                    好了,閑話不多說了,下面貼出該對話框類ClxDialog的源代碼,里面有詳細的注釋:
                    lxDialog.h文件:

            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //      自動改變控件位置和大小的對話框類
            //      文件名:lxDialog.h
            //      作者:StarLee(
            coolstarlee@sohu.com )
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            class ClxDialog : public CDialog
            {
            public:
                ClxDialog(UINT nID, CWnd* pParent = NULL);

                typedef struct _dlgControlTag
                {
                    int iId;
                    int iFlag;
                    int iPercent;
                } DLGCTLINFO, *PDLGCTLINFO;

                enum
                {
                    MOVEX = 0,
                    MOVEY,
                    MOVEXY,
                    ELASTICX,
                    ELASTICY,
                    ELASTICXY
                };

                //  設置控件信息
                BOOL SetControlProperty(PDLGCTLINFO lp, int nElements);

                //  是否在對話框右下角顯示表示可改變大小的圖標
                void ShowSizeIcon(BOOL bShow = TRUE);

            protected:
                virtual BOOL OnInitDialog();
                afx_msg void OnSize(UINT nType, int cx, int cy);
                afx_msg void OnSizing(UINT nSide, LPRECT lpRect);
                DECLARE_MESSAGE_MAP()

            private:
                int m_iClientWidth;  //  對話框client區域的寬度
                int m_iClientHeight;  //  對話框client區域的高度
                int m_iMinWidth;  //  對話框的最小寬度
                int m_iMinHeight;  //  對話框的最小高度
                PDLGCTLINFO m_pControlArray;  //  控件信息數組指針
                int m_iControlNumber;  //  設置控件信息的控件個數
                BOOL m_bShowSizeIcon;  //  是否顯示表示可改變大小的圖標
                CStatic m_wndSizeIcon;  //  放圖標的靜態控件
                //  保存圖標的bitmap
                CBitmap m_bmpSizeIcon;
                BITMAP m_bitmap; 
            };

                    lxDialog.cpp文件:

            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //      自動改變控件位置和大小的對話框類
            //      文件名:lxDialog.cpp
            //      作者:StarLee(
            coolstarlee@sohu.com )
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            #include "stdafx.h"
            #include "lxDialog.h"

            //  表示可改變大小的圖標ID
            #ifndef OBM_SIZE
            #define OBM_SIZE 32766
            #endif

            ClxDialog::ClxDialog(UINT nID, CWnd* pParent /*=NULL*/)
                : CDialog(nID, pParent)
                , m_iClientWidth(0)
                , m_iClientHeight(0)
                , m_iMinWidth(0)
                , m_iMinHeight(0)
                , m_pControlArray(NULL)
                , m_iControlNumber(0)
                , m_bShowSizeIcon(TRUE)
            {}

            BEGIN_MESSAGE_MAP(ClxDialog, CDialog)
                ON_WM_SIZE()
                ON_WM_SIZING()
            END_MESSAGE_MAP()

            BOOL ClxDialog::OnInitDialog()
            {
                CDialog::OnInitDialog();

                //  設置對話框為可變大小的
                ModifyStyle(0, WS_SIZEBOX);

                //  以對話框的初始大小作為對話框的寬度和高度的最小值
                CRect rectDlg;
                GetWindowRect(rectDlg);
                m_iMinWidth = rectDlg.Width();
                m_iMinHeight = rectDlg.Height();

                //  得到對話框client區域的大小
                CRect rectClient;
                GetClientRect(rectClient);
                m_iClientWidth = rectClient.Width();
                m_iClientHeight = rectClient.Height();

                //  Load圖標
                m_bmpSizeIcon.LoadOEMBitmap(OBM_SIZE);
                m_bmpSizeIcon.GetBitmap(&m_bitmap);

                //  創建顯示圖標的靜態控件并放在對話框右下角
                m_wndSizeIcon.Create(NULL, WS_CHILD | WS_VISIBLE | SS_BITMAP, CRect(0, 0, m_bitmap.bmWidth, m_bitmap.bmHeight), this, 0);
                m_wndSizeIcon.SetBitmap(m_bmpSizeIcon);
                m_wndSizeIcon.MoveWindow(m_iClientWidth - m_bitmap.bmWidth, m_iClientHeight - m_bitmap.bmHeight, m_bitmap.bmWidth, m_bitmap.bmHeight);

                //  顯示圖標
                m_wndSizeIcon.ShowWindow(m_bShowSizeIcon);

                return TRUE;
            }

            void ClxDialog::OnSize(UINT nType, int cx, int cy)
            {
                CDialog::OnSize(nType, cx, cy);
             
                //  對話框寬度和高度的增量 
                int iIncrementX = cx - m_iClientWidth;
                int iIncrementY = cy - m_iClientHeight;

                //  最小化時增量為0
                if (nType == SIZE_MINIMIZED)
                {
                    iIncrementX = iIncrementY = 0;
                }

                for (int i = 0; i < m_iControlNumber; i++)
                {
                    CWnd *pWndCtrl = NULL;

                    int iId = m_pControlArray[i].iId;
                    int iFlag = m_pControlArray[i].iFlag;
                    int iPercent = m_pControlArray[i].iPercent;

                    //  無效值
                    if ((iPercent < 0) || (iPercent > 100))
                        continue;

                    //  得到控件指針
                    pWndCtrl = GetDlgItem(iId);
                    if ((NULL != pWndCtrl) && IsWindow(pWndCtrl->GetSafeHwnd()))
                    {
                        CRect rectCtrl;
                        pWndCtrl->GetWindowRect(rectCtrl);

                        ScreenToClient(rectCtrl);

                        int iLeft = rectCtrl.left;
                        int iTop = rectCtrl.top;
                        int iWidth = rectCtrl.Width();
                        int iHeight = rectCtrl.Height();

                        switch (iFlag)
                        {
                        case MOVEX:  //  X方向移動
                            iLeft += (iIncrementX * iPercent / 100);
                            break;

                        case MOVEY:  //  Y方向移動
                            iTop += (iIncrementY * iPercent / 100);
                            break;

                        case MOVEXY:  //  X方向和Y方向同時移動
                            iLeft += (iIncrementX * iPercent / 100);
                            iTop += (iIncrementY * iPercent / 100);
                            break;

                        case ELASTICX:  //  X方向改變大小
                            iWidth += (iIncrementX * iPercent / 100);
                            break;

                        case ELASTICY:  //  Y方向改變大小
                            iHeight += (iIncrementY * iPercent / 100);
                            break;

                        case ELASTICXY:  //  X方向和Y方向同時改變大小
                            iWidth += (iIncrementX * iPercent / 100);
                            iHeight += (iIncrementY * iPercent / 100);
                            break;

                        default:
                            ;
                        }

                        //  把控件移動到新位置
                        pWndCtrl->MoveWindow(iLeft, iTop, iWidth, iHeight);
                        }
                }

                //  把圖標移動到對話框右下角
                if (IsWindow(m_wndSizeIcon.GetSafeHwnd()))
                    m_wndSizeIcon.MoveWindow(cx - m_bitmap.bmWidth, cy - m_bitmap.bmHeight, m_bitmap.bmWidth, m_bitmap.bmHeight);

                //  記錄對話框client區域的大小
                if (nType != SIZE_MINIMIZED)
                {
                    m_iClientWidth = cx;
                    m_iClientHeight = cy;
                }
            }

            void ClxDialog::OnSizing(UINT nSide, LPRECT lpRect)
            {
                CDialog::OnSizing(nSide, lpRect);

                //  對話框不能小于初始大小

                int iWidth = lpRect->right - lpRect->left;
                int iHeight = lpRect->bottom - lpRect->top;

                if (iWidth <= m_iMinWidth)
                    lpRect->right = lpRect->left + m_iMinWidth;
              
                if(iHeight <= m_iMinHeight)
                    lpRect->bottom = lpRect->top + m_iMinHeight;
            }

            BOOL ClxDialog::SetControlProperty(PDLGCTLINFO lp, int nElements)
            {
                //  設置控件數組信息

                if (NULL == lp)
                    return FALSE;

                if (nElements <= 0)
                    return FALSE;

                m_pControlArray = lp;
                m_iControlNumber = nElements;

                return TRUE;
            }

            void ClxDialog::ShowSizeIcon(BOOL bShow /*=NULL*/)
            {
                m_bShowSizeIcon = bShow;
            }

            Posted on 2007-01-21 14:25 艾凡赫 閱讀(2208) 評論(0)  編輯 收藏 引用 所屬分類: MFC
            久久婷婷成人综合色综合| 亚洲欧美成人久久综合中文网| 久久人人爽爽爽人久久久| 久久国产免费观看精品| 国产免费久久久久久无码| 久久精品国产99久久久古代| 欧美一区二区三区久久综| 国产精品亚洲综合专区片高清久久久| 亚洲日本va午夜中文字幕久久| 欧洲成人午夜精品无码区久久| 久久亚洲视频| 国产成人精品久久亚洲| 日韩精品久久久久久久电影蜜臀| 国产呻吟久久久久久久92| 欧洲人妻丰满av无码久久不卡| 最新久久免费视频| 久久精品国产精品亚洲| 亚洲国产精品久久久久婷婷老年| 奇米影视7777久久精品| 久久亚洲精品无码VA大香大香| 国产免费福利体检区久久| 欧美久久精品一级c片片| 亚洲精品乱码久久久久久中文字幕| 韩国三级中文字幕hd久久精品| 久久婷婷国产综合精品| 日韩人妻无码精品久久免费一| 久久综合色老色| 欧美日韩精品久久久久| 一本久道久久综合狠狠躁AV| 久久亚洲国产成人影院网站| 97久久精品人人做人人爽| aaa级精品久久久国产片| 2020久久精品国产免费| 国产精品99久久久久久人| 国内精品久久久久伊人av| 国产成人久久精品一区二区三区| 一本色道久久88精品综合| 久久精品国产亚洲av高清漫画| 国产99久久精品一区二区| 久久综合九色综合久99| 精品久久久久久无码中文字幕|