电子商城网站开发项目描述,洪梅镇做网站,中昌国际建设集团网站,wordpress婚礼主题公园场景
开发WTL/Win32的程序时#xff0c;经常会用到表格控件CListViewCtrl。这个控件需要设置列的宽度#xff0c;当用完100%的宽度来平均分配给列宽时#xff0c;一加载数据多#xff0c;就会出现垂直滚动条后#xff0c;水平滚动条也会同时出现的问题。怎么设置才能让水…场景
开发WTL/Win32的程序时经常会用到表格控件CListViewCtrl。这个控件需要设置列的宽度当用完100%的宽度来平均分配给列宽时一加载数据多就会出现垂直滚动条后水平滚动条也会同时出现的问题。怎么设置才能让水平滚动条不出现?
图1
说明 WTL的控件CListViewCtrl实际上就是Win32的listview控件的封装。当行个数超过它的可见区域时就会默认出现垂直滚动条。这个垂直滚动条也是占用了原本ListView的客户端区域导致ListView的客户端区域宽度减少也就是现在的客户端宽度 原来的客户端区域宽度-滑块的宽度。 当然也可以在行数据超过可见区域时重新计算列宽度只是这种做法需要在合适的时候进行判断行数据是否够多导致垂直滚动条出现。一般不建议做这个冗余的判断处理。 目前推荐的做法是布局ListView时也就是设置它的列宽时如果没有出现垂直滚动条那么预留滚动条的宽度不分配给列宽。 以下是获取滑块宽度的做法: 关于WTL/Win32开发请参考我的课程 使用WTL进行Windows桌面应用开发
void CView::layoutListView()
{CRect rect;listview_.GetClientRect(rect);auto width rect.Width();listview_.SetColumnWidth(0, width*0.2);listview_.SetColumnWidth(1, width*0.3);listview_.SetColumnWidth(2, width*0.2);auto last width * 0.3;if (buttonIsLayoutWithThumb_.GetCheck()) {auto thumbWidth GetWindowVScrollBarThumbWidth(listview_, false);// 如果默认没有滚动条减去滑块宽度。if (!thumbWidth) { thumbWidth GetWindowVScrollBarThumbWidth(listview_, true);last last - thumbWidth;}}listview_.SetColumnWidth(3, last);
}例子
View.h
// View.h : interface of the CView class
//
/#pragma once#include utility
#include string
#include vector
#include memory
#include atlmisc.h
#include atlctrls.h
#include atlctrlx.h
#include GdiPlus.husing namespace std;enum
{kMyButtonId WM_USER1,kMyButtonId2,kMyButtonId3,kMyButtonId4,kMyListViewId
};class Photo
{
public:wstring name;wstring createDate;wstring path;wstring format;
};class CView : public CWindowImplCView
{
public:DECLARE_WND_CLASS(NULL)BOOL PreTranslateMessage(MSG* pMsg);BEGIN_MSG_MAP_EX(CView)MSG_WM_CREATE(OnCreate)MSG_WM_SIZE(OnSize)MESSAGE_HANDLER(WM_PAINT, OnPaint)NOTIFY_HANDLER(kMyListViewId,NM_CLICK,OnNMClickListResult)NOTIFY_HANDLER(kMyListViewId,LVN_GETDISPINFO,OnGetListViewData)NOTIFY_HANDLER(kMyListViewId,LVN_ODCACHEHINT,OnPrepareListViewData)NOTIFY_HANDLER(kMyListViewId,LVN_ODFINDITEM,OnFindListViewData)COMMAND_RANGE_HANDLER_EX(kMyButtonId,kMyButtonId4,OnCommandIDHandlerEX)REFLECT_NOTIFICATIONS()END_MSG_MAP()protected:
// Handler prototypes (uncomment arguments if needed):
// LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL /*bHandled*/)
// LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL /*bHandled*/)
// LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL /*bHandled*/)int OnCreate(LPCREATESTRUCT lpCreateStruct);LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL /*bHandled*/);void UpdateLayout();LRESULT OnNMClickListResult(int idCtrl,LPNMHDR pnmh,BOOL bHandled);LRESULT OnGetListViewData(int idCtrl,LPNMHDR pnmh,BOOL bHandled);LRESULT OnPrepareListViewData(int idCtrl,LPNMHDR pnmh,BOOL bHandled);LRESULT OnFindListViewData(int idCtrl,LPNMHDR pnmh,BOOL bHandled);void OnCommandIDHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl);void OnSize(UINT nType, CSize size);void ReloadMockData(int count);void ReloadListView();protected:void layoutListView();static int GetWindowVScrollBarThumbWidth(HWND hwnd, bool bAutoShow);private:std::wstring GetControlText(HWND hwnd,wchar_t* buf NULL);CListViewCtrl listview_;vectorshared_ptrPhoto photos_;CFont font_normal_;CFont font_bold_;CBrushHandle brush_white_;CBrushHandle brush_hollow_;CBrush brush_red_;CButton buttonIsLayoutWithThumb_;CButton buttonReloadMockData_;CButton buttonReloadMockData10_;CButton buttonReloadListView_;
};
View.cpp
// View.cpp : implementation of the CView class
//
/#include stdafx.h
#include resource.h
#include utility
#include sstream
#include stdint.h
#include assert.h
#include Strsafe.h#include View.h
#include CommCtrl.h
#include string
#include regexusing namespace std;BOOL CView::PreTranslateMessage(MSG* pMsg)
{return FALSE;
}LRESULT CView::OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL /*bHandled*/)
{CPaintDC dc(m_hWnd);CMemoryDC mdc(dc,dc.m_ps.rcPaint);CRect rect_client;GetClientRect(rect_client);mdc.FillSolidRect(rect_client,RGB(255,255,255));//TODO: Add your drawing code herereturn 0;
}static HFONT GetFont(int pixel,bool bold,const wchar_t* font_name)
{LOGFONT lf; memset(lf, 0, sizeof(LOGFONT)); // zero out structure lf.lfHeight pixel; // request a 8-pixel-height fontif(bold){lf.lfWeight FW_BOLD; }lstrcpy(lf.lfFaceName, font_name); // request a face name ArialHFONT font ::CreateFontIndirect(lf);return font;
}std::wstring CView::GetControlText(HWND hwnd,wchar_t* buf)
{auto length ::GetWindowTextLength(hwnd);bool bufNull false;if(!buf){buf new wchar_t[length1]();bufNull true;}::GetWindowText(hwnd,buf,length1);std::wstring str(buf);if(bufNull)delete []buf;return str;
}static std::wstring GetProductBinDir()
{static wchar_t szbuf[MAX_PATH]; GetModuleFileName(NULL,szbuf,MAX_PATH); PathRemoveFileSpec(szbuf);int length lstrlen(szbuf);szbuf[length] L\\;szbuf[length1] 0;return std::wstring(szbuf);
}LRESULT CView::OnGetListViewData(int idCtrl,LPNMHDR pnmh,BOOL bHandled)
{NMLVDISPINFO* plvdi (NMLVDISPINFO*) pnmh;auto iItem plvdi-item.iItem;if (-1 iItem)return 0;auto count photos_.size();if(!count || count iItem)return 0;auto photo photos_[iItem];if(plvdi-item.mask LVIF_TEXT){switch(plvdi-item.iSubItem){case 0:StringCchCopy(plvdi-item.pszText, plvdi-item.cchTextMax, to_wstring((int64_t)iItem1).c_str());break;case 1:StringCchCopy(plvdi-item.pszText, plvdi-item.cchTextMax, photo-name.c_str());break;case 2:StringCchCopy(plvdi-item.pszText, plvdi-item.cchTextMax, photo-format.c_str());break;case 3:StringCchCopy(plvdi-item.pszText, plvdi-item.cchTextMax, photo-createDate.c_str());break;}}return 0;
}LRESULT CView::OnPrepareListViewData(int idCtrl,LPNMHDR pnmh,BOOL bHandled)
{return 0;
}LRESULT CView::OnFindListViewData(int idCtrl,LPNMHDR pnmh,BOOL bHandled)
{LPNMLVFINDITEM pnmfi (LPNMLVFINDITEM)pnmh;auto iItem pnmfi-iStart;if (-1 iItem)return -1;auto count photos_.size();if(!count || count iItem)return -1;return 0;
}LRESULT CView::OnNMClickListResult(int idCtrl,LPNMHDR pnmh,BOOL bHandled)
{return 0;
}void CView::OnCommandIDHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl)
{switch(nID){case kMyButtonId3:{buttonIsLayoutWithThumb_.SetCheck(!buttonIsLayoutWithThumb_.GetCheck());ReloadListView();layoutListView();break;}case kMyButtonId:{ReloadMockData(10000);break;}case kMyButtonId4:{ReloadMockData(10);break;}case kMyButtonId2:{ReloadListView();break;}}
}void CView::ReloadListView()
{listview_.SetItemCount(0);photos_.clear();
}void CView::ReloadMockData(int count)
{wchar_t buf[MAX_PATH] {0};LVCOLUMN co;memset(co,0,sizeof(co));co.mask LVCF_TEXT;co.pszText buf;co.cchTextMax MAX_PATH;listview_.GetColumn(1,co);std::wstring c0Text(buf);listview_.GetColumn(2,co);std::wstring c1Text(buf);listview_.GetColumn(3,co);std::wstring c2Text(buf);static int index 0;for(int i 0; i count;i,index){auto photo new Photo();wsprintf(buf,(c0TextL-%d).c_str(),index);photo-name buf;wsprintf(buf,(c1TextL-%d).c_str(),index);photo-format buf;wsprintf(buf,(c2TextL-%d).c_str(),index);photo-createDate buf;photos_.push_back(move(shared_ptrPhoto(photo)));}listview_.SetItemCount(photos_.size());
}int CView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{font_normal_ ::GetFont(16,false,LArial);font_bold_ ::GetFont(16,true,LArial);brush_hollow_ AtlGetStockBrush(HOLLOW_BRUSH);brush_white_ AtlGetStockBrush(WHITE_BRUSH);brush_red_.CreateSolidBrush(RGB(255,0,0));// 1.创建CListViewCtrllistview_.Create(m_hWnd,0,NULL,WS_CHILD | WS_TABSTOP |WS_VISIBLE|LVS_ALIGNLEFT|LVS_REPORT|LVS_SHOWSELALWAYS|WS_BORDER|LVS_OWNERDATA,0,kMyListViewId);listview_.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_DOUBLEBUFFER);listview_.SetFont(font_normal_);auto header listview_.GetHeader();header.SetFont(font_bold_);listview_.SetBkColor(RGB(255,255,255));listview_.InsertColumn(0,LNo.,LVCFMT_LEFT,0);listview_.InsertColumn(1,LName,LVCFMT_LEFT,0);listview_.InsertColumn(2,LFormat,LVCFMT_LEFT,0);listview_.InsertColumn(3,LCreate Date,LVCFMT_LEFT,0);// 2.创建按钮buttonIsLayoutWithThumb_.Create(m_hWnd, 0, L布局列宽是否计算滑块宽度, WS_CHILD | WS_VISIBLE | BS_CHECKBOX, 0, kMyButtonId3);buttonIsLayoutWithThumb_.SetFont(font_normal_);buttonReloadMockData_.Create(m_hWnd,0,L加载新数据10000条,WS_CHILD|WS_VISIBLE,0,kMyButtonId);buttonReloadMockData_.SetFont(font_normal_);buttonReloadMockData10_.Create(m_hWnd, 0, L加载新数据10条, WS_CHILD | WS_VISIBLE, 0, kMyButtonId4);buttonReloadMockData10_.SetFont(font_normal_);buttonReloadListView_.Create(m_hWnd,0,L清空表格,WS_CHILD|WS_VISIBLE,0,kMyButtonId2);buttonReloadListView_.SetFont(font_normal_);return 0;
}int CView::GetWindowVScrollBarThumbWidth(HWND hwnd, bool bAutoShow)
{SCROLLBARINFO sb { 0 };sb.cbSize sizeof(SCROLLBARINFO);GetScrollBarInfo(hwnd, OBJID_VSCROLL, sb);if (!bAutoShow)return sb.dxyLineButton;if (sb.dxyLineButton)return sb.dxyLineButton;::ShowScrollBar(hwnd, SB_VERT, TRUE);sb.cbSize sizeof(SCROLLBARINFO);GetScrollBarInfo(hwnd, OBJID_VSCROLL, sb);::ShowScrollBar(hwnd, SB_VERT, FALSE);return sb.dxyLineButton;
}void CView::layoutListView()
{CRect rect;listview_.GetClientRect(rect);auto width rect.Width();listview_.SetColumnWidth(0, width*0.2);listview_.SetColumnWidth(1, width*0.3);listview_.SetColumnWidth(2, width*0.2);auto last width * 0.3;if (buttonIsLayoutWithThumb_.GetCheck()) {auto thumbWidth GetWindowVScrollBarThumbWidth(listview_, false);if (!thumbWidth) {// 如果默认没有滚动条thumbWidth GetWindowVScrollBarThumbWidth(listview_, true);last last - thumbWidth;}}listview_.SetColumnWidth(3, last);
}void CView::OnSize(UINT nType, CSize size)
{if (!size.cx)return;UpdateLayout();
}void CView::UpdateLayout()
{CRect rect;GetClientRect(rect);CClientDC dc(m_hWnd);dc.SelectFont(font_normal_);CSize sizeCheck;buttonIsLayoutWithThumb_.GetIdealSize(sizeCheck);buttonIsLayoutWithThumb_.MoveWindow(CRect(20,2, sizeCheck.cx20, sizeCheck.cy2));CSize size_control(rect.Width() - 50,300);CRect rect_control CRect(CPoint(20,20),size_control);listview_.MoveWindow(rect_control);layoutListView();CSize size_button;buttonReloadMockData_.GetIdealSize(size_button);rect_control CRect(CPoint(rect_control.left,rect_control.bottom10),size_button);buttonReloadMockData_.MoveWindow(rect_control);CSize size_button4;buttonReloadMockData10_.GetIdealSize(size_button4);rect_control CRect(CPoint(rect_control.right10, rect_control.top), size_button);buttonReloadMockData10_.MoveWindow(rect_control);CSize sizeButton2;buttonReloadListView_.GetIdealSize(sizeButton2);rect_control CRect(CPoint(rect_control.right10,rect_control.top),sizeButton2);buttonReloadListView_.MoveWindow(rect_control);}图2 图3
项目下载地址
https://download.csdn.net/download/infoworld/89036594
参考 GetScrollBarInfo 函数 (winuser.h) - Win32 apps | Microsoft Learn SCROLLBARINFO (winuser.h) - Win32 apps | Microsoft Learn ShowScrollBar 函数 (winuser.h) - Win32 apps | Microsoft Learn