• <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
            久久露脸国产精品| 久久九九全国免费| 久久久久亚洲AV无码网站| 久久精品亚洲一区二区三区浴池| 国产精品久久久久9999| 久久AⅤ人妻少妇嫩草影院| 无码人妻久久一区二区三区免费| 久久精品天天中文字幕人妻| 久久亚洲2019中文字幕| 国产∨亚洲V天堂无码久久久| 久久久精品日本一区二区三区 | 亚洲国产成人久久综合野外 | 99久久www免费人成精品| 国产精品九九久久精品女同亚洲欧美日韩综合区 | 四虎国产精品免费久久5151| 免费精品国产日韩热久久| 久久青青草原国产精品免费 | 久久久久噜噜噜亚洲熟女综合| 亚洲va中文字幕无码久久不卡| 精品久久久久久无码中文野结衣| 久久Av无码精品人妻系列| 亚洲国产成人精品久久久国产成人一区二区三区综 | 亚洲αv久久久噜噜噜噜噜| 久久综合一区二区无码| 国产成人综合久久精品尤物| 91视频国产91久久久| 久久久久亚洲AV成人片| 狠狠综合久久综合88亚洲| 伊人久久大香线蕉精品不卡| 性欧美大战久久久久久久| 色婷婷噜噜久久国产精品12p| 国产69精品久久久久99尤物| 久久精品国产精品国产精品污| 久久精品九九亚洲精品| 99国产欧美久久久精品蜜芽| 久久99精品久久久久子伦| 国产精品美女久久久久网| 人人狠狠综合久久亚洲88| 国内精品久久久久久久coent| 久久精品国产精品亚洲下载| 女同久久|