MFC 控件布局随窗口大小自动变化大小 位置
参考抄袭:
控件布局通用解决方案
在stdafx.h中增加代码,目的是在哪都容易调用
1 // CtrlId : 控件ID 2 // LeftChangeMode : 0:与窗口客户区左边的距离不变; 1:按比例变化; 2:保持控件宽度不变; 3 // RightChangeMode : 0:与窗口客户区右边的距离不变; 1:按比例变化; 2:保持控件宽度不变; 4 // TopChangeMode : 0:与窗口客户区上边的距离不变; 1:按比例变化; 2:保持控件高度不变; 5 // BottomChangeMode : 0:与窗口客户区下边的距离不变; 1:按比例变化; 2:保持控件高度不变; 6 #ifndef AUTO_SET_CONTROL_POS 7 8 // LeftChangeMode取值宏定义 9 #define LEFT_CHANGE_MODE_FIXED_LEFTPADDING 0 10 #define LEFT_CHANGE_MODE_RATIO 1 11 #define LEFT_CHANGE_MODE_FIXED_WIDTH 2 12 13 // RightChangeMode取值宏定义 14 #define RIGHT_CHANGE_MODE_FIXED_RIGHTPADDING 0 15 #define RIGHT_CHANGE_MODE_RATIO 1 16 #define RIGHT_CHANGE_MODE_FIXED_WIDTH 2 17 18 // TopChangeMode取值宏定义 19 #define TOP_CHANGE_MODE_FIXED_TOPPADDING 0 20 #define TOP_CHANGE_MODE_RATIO 1 21 #define TOP_CHANGE_MODE_FIXED_HEIGHT 2 22 23 // BottomChangeMode取值宏定义 24 #define BOTTOM_CHANGE_MODE_FIXED_LEFEPADDING 0 25 #define BOTTOM_CHANGE_MODE_RATIO 1 26 #define BOTTOM_CHANGE_MODE_FIXED_HEIGHT 2 27 28 #define AUTO_SET_CONTROL_POS(CtrlId, LeftChangeMode, RightChangeMode, TopChangeMode, BottomChangeMode)\ 29 {\ 30 static int nFirstCtrlId = -1; \ 31 static CRect rectLastClientWindow; \ 32 static CRect rectLastClientWindowTmp; \ 33 if (-1 == nFirstCtrlId)\ 34 {\ 35 nFirstCtrlId = CtrlId; \ 36 }\ 37 if (nFirstCtrlId == CtrlId)\ 38 {\ 39 rectLastClientWindowTmp = rectLastClientWindow; \ 40 }\ 41 rectLastClientWindow.right = cx; \ 42 rectLastClientWindow.bottom = cy; \ 43 CWnd *pWndDlgItem = GetDlgItem(CtrlId); \ 44 if (pWndDlgItem)\ 45 {\ 46 CRect rectDlgItem; \ 47 pWndDlgItem->GetWindowRect(rectDlgItem); \ 48 ScreenToClient(rectDlgItem); \ 49 \ 50 static int nDefaultLeftPadding_##CtrlId = rectDlgItem.left; \ 51 static float fDefaultLeftRatio_##CtrlId = (float)rectDlgItem.left\ 52 / rectLastClientWindowTmp.right; \ 53 static int nDefaultRightPadding_##CtrlId = rectLastClientWindowTmp.right\ 54 - rectDlgItem.right; \ 55 static float fDefaultRightRatio_##CtrlId = (float)rectDlgItem.right\ 56 / rectLastClientWindowTmp.right; \ 57 static int nDefaultCtrlWidth_##CtrlId = rectDlgItem.right - rectDlgItem.left; \ 58 int nXChangeMode = (LeftChangeMode << 8) + RightChangeMode; \ 59 \ 60 static int nDefaultTopPadding_##CtrlId = rectDlgItem.top; \ 61 static float fDefaultTopRatio_##CtrlId = (float)rectDlgItem.top\ 62 / rectLastClientWindowTmp.bottom; \ 63 static int nDefaultBottomPadding_##CtrlId = rectLastClientWindowTmp.bottom\ 64 - rectDlgItem.bottom; \ 65 static float fDefaultBottomRatio_##CtrlId = (float)rectDlgItem.bottom\ 66 / rectLastClientWindowTmp.bottom; \ 67 static int nDefaultCtrlHeight_##CtrlId = rectDlgItem.bottom - rectDlgItem.top; \ 68 int nYChangeMode = (TopChangeMode << 8) + BottomChangeMode; \ 69 \ 70 if (0x0000 == nXChangeMode)\ 71 {\ 72 rectDlgItem.right = cx - nDefaultRightPadding_##CtrlId; \ 73 }\ 74 else if (0x0001 == nXChangeMode)\ 75 {\ 76 rectDlgItem.right = fDefaultRightRatio_##CtrlId * cx; \ 77 }\ 78 else if (0x0002 == nXChangeMode)\ 79 {\ 80 /*这里不用更改*/\ 81 }\ 82 else if (0x0100 == nXChangeMode)\ 83 {\ 84 rectDlgItem.left = fDefaultLeftRatio_##CtrlId * cx; \ 85 rectDlgItem.right = cx - nDefaultRightPadding_##CtrlId; \ 86 }\ 87 else if (0x0101 == nXChangeMode)\ 88 {\ 89 rectDlgItem.left = fDefaultLeftRatio_##CtrlId * cx; \ 90 rectDlgItem.right = fDefaultRightRatio_##CtrlId * cx; \ 91 }\ 92 else if (0x0102 == nXChangeMode)\ 93 {\ 94 rectDlgItem.left = fDefaultLeftRatio_##CtrlId * cx; \ 95 rectDlgItem.right = rectDlgItem.left + nDefaultCtrlWidth_##CtrlId; \ 96 }\ 97 else if (0x0200 == nXChangeMode)\ 98 {\ 99 rectDlgItem.right = cx - nDefaultRightPadding_##CtrlId; \ 100 rectDlgItem.left = rectDlgItem.right - nDefaultCtrlWidth_##CtrlId; \ 101 }\ 102 else if (0x0201 == nXChangeMode)\ 103 {\ 104 rectDlgItem.right = fDefaultRightRatio_##CtrlId * cx; \ 105 rectDlgItem.left = rectDlgItem.right - nDefaultCtrlWidth_##CtrlId; \ 106 }\ 107 else if (0x0202 == nXChangeMode)\ 108 {\ 109 /*这里不用更改*/\ 110 }\ 111 \ 112 \ 113 if (0x0000 == nYChangeMode)\ 114 {\ 115 rectDlgItem.bottom = cy - nDefaultBottomPadding_##CtrlId; \ 116 }\ 117 else if (0x0001 == nYChangeMode)\ 118 {\ 119 rectDlgItem.bottom = fDefaultBottomRatio_##CtrlId * cy; \ 120 }\ 121 else if (0x0002 == nYChangeMode)\ 122 {\ 123 /*这里不用更改*/\ 124 }\ 125 else if (0x0100 == nYChangeMode)\ 126 {\ 127 rectDlgItem.top = fDefaultTopRatio_##CtrlId * cy; \ 128 rectDlgItem.bottom = cy - nDefaultBottomPadding_##CtrlId; \ 129 }\ 130 else if (0x0101 == nYChangeMode)\ 131 {\ 132 rectDlgItem.top = fDefaultTopRatio_##CtrlId * cy; \ 133 rectDlgItem.bottom = fDefaultBottomRatio_##CtrlId * cy; \ 134 }\ 135 else if (0x0102 == nYChangeMode)\ 136 {\ 137 rectDlgItem.top = fDefaultTopRatio_##CtrlId * cy; \ 138 rectDlgItem.bottom = rectDlgItem.top + nDefaultCtrlHeight_##CtrlId; \ 139 }\ 140 else if (0x0200 == nYChangeMode)\ 141 {\ 142 rectDlgItem.bottom = cy - nDefaultBottomPadding_##CtrlId; \ 143 rectDlgItem.top = rectDlgItem.bottom - nDefaultCtrlHeight_##CtrlId; \ 144 }\ 145 else if (0x0201 == nYChangeMode)\ 146 {\ 147 rectDlgItem.bottom = fDefaultBottomRatio_##CtrlId * cy; \ 148 rectDlgItem.top = rectDlgItem.bottom - nDefaultCtrlHeight_##CtrlId; \ 149 }\ 150 else if (0x0202 == nYChangeMode)\ 151 {\ 152 /*这里不用更改*/\ 153 }\ 154 pWndDlgItem->MoveWindow(rectDlgItem); \ 155 }\ 156 } 157 #endif
增加对话框的WM_SIZE消息处理函数
1 AUTO_SET_CONTROL_POS(IDC_xxx, LEFT_CHANGE_MODE_RATIO, RIGHT_CHANGE_MODE_RATIO, TOP_CHANGE_MODE_RATIO, BOTTOM_CHANGE_MODE_RATIO);
每一个控件都要调用这个宏,参数调试调试看看参数说明
如果是combo控件,改变大小后会下拉框下拉不了,则可以BOTTOM设为0即解决此问题
AUTO_SET_CONTROL_POS(IDC_COMBO1, LEFT_CHANGE_MODE_RATIO, RIGHT_CHANGE_MODE_RATIO, TOP_CHANGE_MODE_RATIO, BOTTOM_CHANGE_MODE_FIXED_HEIGHT);