Reputation: 7548
I have a list of items that are each associated with a start and end time and date. What I want to do is, given a time and date range, display only the items that fall within that window, even partially.
What I'm doing is creating a CListCtrl with all the items in it and the CListCtrl is sorted by start time by default. But given a time range, I don't know how to search for the first item that is within the range.
Another problem with the list control is it displays as a list, whereas it would be nice if there was a control that could also show things that are concurrent side by side.
I'm doing this within a dialog application.
Upvotes: 3
Views: 887
Reputation: 12763
You're asking for some very specific functionality. It sounds like you are either building a scheduling app or are trying to display a log of things that have happened in the past. This is called a Gantt Chart. You can buy Gannt Chart controls for MFC on the web. Google for some.
There's more to your question than just how to paint it; You cannot and should not be using a CListCtrl as your data structure. You seem to have an array of objects that are start & end times. For example:
struct Range {
int startTime;
int endTime;
};
std::vector<Range> events;
Once you have put your events into this simple vector, you will have to loop through all of the elements and compare the start/end times to see if they overlap the Range that you are considering:
typedef std::vector<Range> RangeVec;
typedef RangeVec::iterator RangeIter;
void is_between(int time, const Range& r)
{
return time >= r.start && time <= r.end;
}
void findRanges(RangeVec *matches, const RangeVec& input, const Range& query)
{
for (RangeIter it = input.begin(); it != input.end(); ++it) {
if (is_between(it.start, query) || is_between(it.end, query) ||
(it.start <= query.start && it.end >= query.end))
{
matches->push_back(*it);
}
}
You can now loop through your matches and display them however you want. If you are brave, it's rather easy to write a custom control with a subclassed CWnd::OnPaint() that just draws rectangles as long as your overlapped range representing each match.
Upvotes: 2
Reputation: 19642
Concurrent things side by side is going to require a custom control.
Filling the list with things within a data range is done by checking which items are within that range at the moment you insert them into the list box. So don't make a list with all items. This is so obvious that I guess I misunderstood your question.
Upvotes: 0