📄 svclistview.hpp
字号:
// Copyright E骾n O'Callaghan 2008 - 2008.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef SVCLISTVIEW_HPP_INCLUDED
#define SVCLISTVIEW_HPP_INCLUDED
#include "Resource.h"
#include <boost/statechart/event.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/statechart/state_machine.hpp>
#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/state.hpp>
#include <boost/statechart/event.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <winstl/controls/listview_sequence.hpp>
#include "SettingsIni.hpp"
#include "SortListViewCtrlEx.hpp"
#include "ListViewIterators.hpp"
#include "nt_service.hpp"
#include "event_logger.hpp"
struct ev_switch_to_overview : boost::statechart::event<ev_switch_to_overview> {};
struct ev_switch_to_profile : boost::statechart::event<ev_switch_to_profile> {};
struct overview_mode;
class SvcListViewCtrl;
struct list_state_machine :
public boost::statechart::state_machine<list_state_machine, overview_mode>
{
list_state_machine(SvcListViewCtrl* list) :
list_(list)
{}
bool is_overview_mode() const;
SvcListViewCtrl* list() { return list_; }
private:
SvcListViewCtrl* list_;
};
class SvcListViewCtrl :
public WTLx::SortListViewCtrlEx<SvcListViewCtrl>,
public WTLx::ListViewIterators<SvcListViewCtrl>,
public WTL::CCustomDraw<SvcListViewCtrl>,
private SettingsIni<SvcListViewCtrl>
{
typedef SvcListViewCtrl thisClass;
typedef WTLx::SortListViewCtrlEx<thisClass> listClass;
typedef WTL::CCustomDraw<thisClass> ownDrawClass;
typedef SettingsIni<thisClass> iniClass;
friend class listClass;
typedef boost::function<void (size_t)> listview_setting_changed_fn;
typedef boost::function<void (std::vector<service_ptr>)> listview_items_selected_fn;
typedef std::vector<std::pair<service_ptr,
boost::optional<nt_service::service_settings> > > services_vector;
public:
BEGIN_MSG_MAP_EX(SvcListViewCtrl)
MSG_WM_SHOWWINDOW(OnShowWindow)
MSG_WM_DESTROY(OnDestroy)
COMMAND_ID_HANDLER(ID_ACTIVE_NO_CHANGE, OnStateChange)
COMMAND_ID_HANDLER(ID_ACTIVE_STARTED, OnStateChange)
COMMAND_ID_HANDLER(ID_ACTIVE_PAUSED, OnStateChange)
COMMAND_ID_HANDLER(ID_ACTIVE_STOPPED, OnStateChange)
COMMAND_ID_HANDLER(ID_STARTTYPE_NO_CHANGE, OnStartTypeChange)
COMMAND_ID_HANDLER(ID_STARTTYPE_AUTOMATIC, OnStartTypeChange)
COMMAND_ID_HANDLER(ID_STARTTYPE_MANUAL, OnStartTypeChange)
COMMAND_ID_HANDLER(ID_STARTTYPE_DISABLED, OnStartTypeChange)
REFLECTED_NOTIFY_CODE_HANDLER(NM_CLICK, OnLClick)
if (test_notification_lock())
{
REFLECTED_NOTIFY_CODE_HANDLER(LVN_ITEMCHANGED, OnItemChanged)
}
CHAIN_MSG_MAP_ALT(ownDrawClass, 1)
CHAIN_MSG_MAP(listClass)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
SvcListViewCtrl(aux::txml_ini& ini, listview_setting_changed_fn lsc, listview_items_selected_fn lis) :
iniClass("service_pane", "service_listview", ini),
listview_setting_changed_(lsc),
listview_items_selected_(lis),
state_machine_(this)
{}
DWORD OnPrePaint(int idCtrl, LPNMCUSTOMDRAW lpNMCD)
{
return CDRF_NOTIFYITEMDRAW;
}
DWORD OnItemPrePaint(int idCtrl, LPNMCUSTOMDRAW lpNMCD)
{
NMLVCUSTOMDRAW* pnmlv = (NMLVCUSTOMDRAW*) lpNMCD;
size_t index = pnmlv->nmcd.lItemlParam;
if (!overview_mode())
{
if (!services_[index].second || services_[index].second->is_inert() &&
!GetCheckState(pnmlv->nmcd.dwItemSpec))
{
pnmlv->clrText = RGB(180,180,205);
}
else if (services_[index].second && !services_[index].second->is_inert() &&
!GetCheckState(pnmlv->nmcd.dwItemSpec))
{
pnmlv->clrText = RGB(50,50,150);
}
else
pnmlv->clrText = RGB(0,0,40);
}
return CDRF_DODEFAULT;
}
void OnShowWindow(UINT, INT);
void DeleteItem(LPDELETEITEMSTRUCT) {};
void OnDestroy()
{
iniClass::SaveSettings();
}
LRESULT OnLClick(int i, LPNMHDR pnmh, BOOL& b)
{
WTL::CPoint point;
GetCursorPos(&point);
ScreenToClient(&point);
UINT flags;
HitTest(point, &flags);
if (flags & LVHT_ONITEMLABEL)
return OnRClick(i, pnmh, b);
else
{
SetMsgHandled(false);
return 0;
}
}
LRESULT OnStateChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
winstl::listview_sequence lv_seq(*this);
DWORD state;
switch(wID)
{
case ID_ACTIVE_STARTED:
state = SERVICE_RUNNING;
break;
case ID_ACTIVE_PAUSED:
state = SERVICE_PAUSED;
break;
case ID_ACTIVE_STOPPED:
state = SERVICE_STOPPED;
break;
case ID_ACTIVE_NO_CHANGE:
default:
state = SERVICE_NO_CHANGE;
};
foreach(const winstl::listview_sequence::sequence_value_type val,
std::make_pair(is_selected_begin(), is_selected_end()))
{
WTLx::notification_lock<listClass> lock(*this);
if (!services_[val.data()].second)
{
services_[val.data()].second =
nt_service::service_settings(*services_[val.data()].first, false, false);
}
nt_service::service_settings& settings = *services_[val.data()].second;
settings.set_dwCurrentState(state);
SetCheckState(val.index(), true);
set_item_settings_text(val.index(), settings);
}
listview_setting_changed_(0);
return 0;
}
LRESULT OnStartTypeChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
winstl::listview_sequence lv_seq(*this);
DWORD type;
switch(wID)
{
case ID_STARTTYPE_AUTOMATIC:
type = SERVICE_AUTO_START;
break;
case ID_STARTTYPE_MANUAL:
type = SERVICE_DEMAND_START;
break;
case ID_STARTTYPE_DISABLED:
type = SERVICE_DISABLED;
break;
case ID_STARTTYPE_NO_CHANGE:
default:
type = SERVICE_NO_CHANGE;
};
foreach(const winstl::listview_sequence::sequence_value_type val,
std::make_pair(is_selected_begin(), is_selected_end()))
{
WTLx::notification_lock<listClass> lock(*this);
if (!services_[val.data()].second)
{
services_[val.data()].second =
nt_service::service_settings(*services_[val.data()].first, false, false);
}
nt_service::service_settings& settings = *services_[val.data()].second;
settings.set_dwStartType(type);
SetCheckState(val.index(), true);
set_item_settings_text(val.index(), settings);
}
listview_setting_changed_(0);
return 0;
}
LRESULT OnItemChanged(int, LPNMHDR pnmh, BOOL&)
{
if (test_notification_lock())
{
LPNMLISTVIEW pnmlv = (LPNMLISTVIEW) pnmh;
if (pnmlv->uChanged & LVIF_STATE &&
(pnmlv->uOldState & LVIS_STATEIMAGEMASK) != (pnmlv->uNewState & LVIS_STATEIMAGEMASK))
{
item_checked(pnmlv, (GetCheckState(pnmlv->iItem) ? true : false));
}
else if (pnmlv->uChanged & LVIF_STATE &&
(pnmlv->uNewState & LVIS_SELECTED))
{
item_selected();
}
}
return 0;
}
void display_all_services();
void item_selected()
{
std::vector<service_ptr> vec;
foreach(const winstl::listview_sequence::sequence_value_type val,
std::make_pair(is_selected_begin(), is_selected_end()))
{
vec.push_back(services_[val.data()].first);
}
listview_items_selected_(vec);
}
void item_checked(LPNMLISTVIEW item, bool checked)
{
size_t index = item->lParam;
if (!checked)
{
services_[index].second.reset();
reset_item_settings_text(item->iItem);
}
else
{
if (!services_[index].second)
{
services_[index].second =
nt_service::service_settings(*services_[index].first, false, false);
}
}
listview_setting_changed_(item->iItem);
}
void set_item_settings_text(unsigned iItem, const nt_service::service_settings& settings);
void reset_item_settings_text(unsigned iItem);
int add_and_list_service(service_ptr svc_p);
int list_service(nt_service& svc, size_t i=-1);
void update_with_settings(std::set<nt_service::service_settings> services);
void reset_display_services();
void reset_display_item_text(unsigned iItem, service_ptr svc);
std::vector<nt_service::service_settings> get_checked_settings()
{
std::vector<nt_service::service_settings> vec;
foreach(const winstl::listview_sequence::sequence_value_type val,
std::make_pair(is_checked_begin(), is_checked_end()))
{
logger.post(new event_type(event_logger::dev,
wformat(L"get_checked_settings %1%, %2%.") % val.data() % val.index()));
assert(services_[val.data()].second);
if (services_[val.data()].second)
vec.push_back(*services_[val.data()].second);
}
return vec;
}
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & boost::serialization::make_nvp("listview",
boost::serialization::base_object<listClass>(*this));
}
bool overview_mode();
void set_overview_mode(bool ob);
bool is_empty() { return services_.empty(); }
private:
listview_setting_changed_fn listview_setting_changed_;
listview_items_selected_fn listview_items_selected_;
list_state_machine state_machine_;
services_vector services_;
WTL::CIcon ico_;
WTL::CImageList i_list_;
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -