Winapi CStatusBarCtrl自动调整大小
在MFC中,当父窗口更新时,状态栏不应该自动调整大小吗?是否需要使用缺少的设置来实现这一点Winapi CStatusBarCtrl自动调整大小,winapi,mfc,Winapi,Mfc,在MFC中,当父窗口更新时,状态栏不应该自动调整大小吗?是否需要使用缺少的设置来实现这一点 class Mainwindow { public: MainWindow() { Create(NULL, _T("Main Window")); } afx_msg int OnCreate(LPCREATESTRUCT lp) { // Status bar CRect rc; this->GetClientRect(&a
class Mainwindow {
public:
MainWindow() {
Create(NULL, _T("Main Window"));
}
afx_msg int OnCreate(LPCREATESTRUCT lp) {
// Status bar
CRect rc;
this->GetClientRect(&rc);
std::array<int, 3> sb = { rc.right / 3,rc.right / 3 * 2,-1 };
status_bar.Create(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP, CRect(0, 0, 0, 0), this, IDS_STATUSBARCTRL);
status_bar.SetParts(3, sb.data());
status_bar.SetTipText(1, _T("Tooltip text"));
status_bar.SetText(_T("Left"), 0, SBT_POPOUT);
status_bar.SetText(_T("Middle"), 1, 0);
status_bar.SetText(_T("Right"), 2, 0);
return TRUE;
}
// This resizes the status bar fine, but shouldn't MFC handle it?
afx_msg void OnSize(UINT, int cx, int cy) {
status_bar.SendMessage(WM_SIZE, 0, 0);
}
DECLARE_MESSAGE_MAP()
private:
CStatusBarCtrl status_bar;
};
BEGIN_MESSAGE_MAP(MainWindow,CFrameWnd)
ON_WM_CREATE()
ON_WM_SIZE()
END_MESSAGE_MAP()
class主窗口{
公众:
主窗口(){
创建(空,_T(“主窗口”);
}
afx_msg int OnCreate(LPCREATESTRUCT lp){
//状态栏
正确的rc;
此->GetClientRect(&rc);
数组sb={rc.right/3,rc.right/3*2,-1};
状态栏。创建(WS|u CHILD | WS|u VISIBLE | CCS|u BOTTOM | SBARS|u SIZEGRIP,正确(0,0,0),this,id_STATUSBARCTRL);
状态栏设置部件(3,sb数据());
状态栏.setTiptText(1,_T(“工具提示文本”);
状态栏设置文本(_T(“左”),0,SBT_弹出);
status_bar.SetText(_T(“中间”),1,0;
状态栏SetText(_T(“右”),2,0;
返回TRUE;
}
//这会很好地调整状态栏的大小,但MFC不应该处理它吗?
afx\U消息无效大小(UINT、int cx、int cy){
状态栏SendMessage(WM_大小,0,0);
}
声明消息映射()
私人:
CStatusBarCtrl状态_栏;
};
开始消息映射(主窗口,CFrameWnd)
关于\u WM\u CREATE()
关于_WM_SIZE()
结束消息映射()
只需扫描MFC代码。。。(目前无法让我的调试器单步执行,啊)
在CFrameWnd类中,有一个名为RecalcLayout的函数。MSDN说:
当打开或关闭标准控制栏或调整框架窗口的大小时,框架调用
RecalcLayout调用CWnd::RespositionBars。函数中有一条注释:
// walk kids in order, control bars get the resize notification
// which allow them to shrink the client area
通知似乎是通过WM_SIZEPARENT消息完成的:
a) CControlBar类具有WM_SIZEPARENT的消息处理程序
b) CStatusBarCtrl是从CWnd派生的,而不是从CControlBar派生的,因此不会获取消息
解决方案:我会像应用程序向导那样做——将您的状态栏成员变量设置为CStatusBar。(从CControlBar派生)从那里可以调用GetStatusBarCtrl()
我这里有一个替代解决方案,它不会避免使用
CStatusBarCtrl
。这是一个老问题,但如果您感兴趣,请继续阅读:
如果仔细观察,每当创建CStatusBarCtrl
时,它总是知道它在父窗口中的确切位置,并忽略cost RECT&RECT
参数。因此,它具有调整自身大小的能力。您只需在父窗口调整大小时唤醒它,方法是调用CStatusBarCtrl
中的CWnd::SetWindowPos
方法。参数可以全部为零,因为CStatusBarCtrl
无论如何都会忽略它,只需提醒它需要重新定位
这是您实现它的方式:
步骤1:在父窗口的OnCreate()方法中,创建CStatusBarCtrl
:
int MainFrmWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
m_infoBar = new CStatusBar;
m_infoBar->Create(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP,
CRect(), 0x1234);
int partWidths[] = { 100, 200, -1 };
m_infoBar->SetParts(3, partWidths);
m_infoBar->SetText(_T("Pane 1..."), 0, NULL);
m_infoBar->SetText(_T("Pane 2..."), 1, NULL);
m_infoBar->SetText(_T("Pane 3..."), 2, NULL);
return 0;
}
步骤2:在父窗口的WM_大小中,用SetWindowPos
戳出CStatusBarCtrl
:
void MainFrmWnd::OnSize(UINT nType, int cx, int cy) {
CFrameWnd::OnSize(nType, cx, cy);
// Parameter values don't matter,
// This is just to remind CStatusBarCtrl it needs repositioning
m_infoBar->SetWindowPos(&wndTop, 0, 0, 0, 0, NULL);
}
使用VS2019测试
这是可行的,但仅供参考,您必须完全删除
WM_SIZE
处理程序,让MFC自己执行所有更新,或者在任何自定义大小调整后调用CFrameWnd::OnSize()
void MainFrmWnd::OnSize(UINT nType, int cx, int cy) {
CFrameWnd::OnSize(nType, cx, cy);
// Parameter values don't matter,
// This is just to remind CStatusBarCtrl it needs repositioning
m_infoBar->SetWindowPos(&wndTop, 0, 0, 0, 0, NULL);
}