Tag Archives: listview

Listing Processes – Part 4: Using Remote Desktop Services API

Using Remote Desktop Services API

We can call WTSEnumerateProcesses function to get information about the active processes on a specified Remote Desktop Session Host server. However, if pass WTS_CURRENT_SERVER_HANDLE in first argument (server handle), we can enumerate and get info about processes which are running on local machine.
The following example calls WTSEnumerateProcesses function, then fills an array of WTS_PROCESS_INFO structures.

If the target OS is Windows Vista or newer, we can alternatively use WTSEnumerateProcessesEx which can get additional info in WTS_PROCESS_INFO_EX structures.
Here is an example that enumerates processes, then fills an array of application-defined structures, (CProcessInfoEx) which contain the following info:

  • the process identifier;
  • the identifier of session associated with the process;
  • the name of the executable file associated with the process;
  • the user account name;
  • the user domain name;
  • the number of threads in the process;
  • the number of handles in the process;
  • the page file usage of the process, in bytes;
  • the peak page file usage of the process, in bytes;
  • the working set size of the process, in bytes;
  • the peak working set size of the process, in bytes;
  • the time, in milliseconds, the process has been running in user mode;
  • the time, in milliseconds, the process has been running in kernel mode.

Now, let’s fill a listview control with the processes info grabbed by RDSAPI_EnumProcessesEx.

More implementation details can be found in the attached demo project.

Notes

  • WTSEnumerateProcesses function requires at least Windows XP or Windows Server 2003;
  • WTSEnumerateProcessesEx function requires at least Windows 7 or Windows Server 2008 R2;
  • WTS prefix comes from Windows Terminal Services which is the former name of Remote Desktop Services.

Demo Project

The demo project is a simple MFC dialog-based application that uses the above functions.
Download: Listing_Processes_Using_RDS_API.zip (753)

Using Remote Desktop Services API - Demo Application

Using Remote Desktop Services API – Demo Application

References

See also

Fill a List with Large Amount of Data – Part 3

The previous article demonstrates how to improve performance by using a virtual listview control (having LVS_OWNERDATA style set) and handling LVN_GETDISPINFO notification. That’s pretty cool! However, it still can be improved by caching input data. That means, instead of first loading the whole input data, we can load only how much is necessary at a time.
For that purpose, before sending LVN_GETDISPINFO, a virtual list control sends LVN_ODCACHEHINT, giving a “hint” of what range of items should be loaded. An application can verify if these items are already loaded into cache. If not, then can load them.
Let’s see a simple example!

Using a cached list

  1. Set LVS_OWNERDATA style.
  2. Set the virtual list items count with CListCtrl::SetItemCountEx.
  3. Handle LVN_GETDISPINFO notification like in the previous example.
  4. Finally, handle LVN_ODCACHEHINT for loading cached data.

Notes

  • The caching mode presented here is as simple as posible. It presume the total number of items known. Also it adds data in cache each time is needed without care about memory. If necessary, that can be improved for handling an unspecified number of items and/or for keeping a maximum number of items in cache. That would be necessary if dealing with very large amounts of data.
  • See also the previous article notes.

Demo project

The demo project uses the same database and performs the same query like the one presented in the previous article. Please, feel free to download and compare.
Download: Cached_List_Demo.zip (Demo Project) (684)

Using Cached List - Demo Application

Using Cached List – Demo Application

Resources

See also

Fill a List with Large Amount of Data – Part 2

Inserting a large number of items in a listview control, may take a lot of time.
A virtual list does not internally keep items information (like text and so on). Instead, it notifies its parent, asking info only for the items/subitems which are currently displayed. That makes it a good choyce if dealing with a large number of items.

Using a virtual list

  1. Set LVS_OWNERDATA style.
    First note this style cannot be set after control creation. For a listview control contained in a dialog resource, it can be done by setting True for Owner Data property. For a listview control kept by a CListView class, the right place is in the overridden PreCreateWindow
  2. Load data.
    May be, for example, an array of database records as a result of an SQL query. See the attached demo project for a concrete example.
  3. Set the virtual list items count.
  4. Finally, handle the LVN_GETDISPINFO notification.
    As said in the beginning, a virtual list doesn’t internally keep items info. Instead, it sends LVN_GETDISPINFO notification via WM_NOTIFY message, each time it needs info about the items to be actually displayed.
    For a listview control we can use the wizard to map LVN_GETDISPINFO in the parent dialog class or the reflected =LVN_GETDISPINFO notification, in a class derived from CListCtrl.
    In a class derived from CListView we can also use the wizard to map reflected =LVN_GETDISPINFO notification. 

    First argument is a pointer to a NMLVDISPINFO structure. From its member of type LVITEM, we can get which info is required (text, image, etc) and the index of item and subitem that is being displayed. Next, we have to fill that structure with the information from an external data collection.

Demo project

Download: Virtual_List_Demo.zip (1020)

The demo project uses the same SQL query to fill a non-virtual and a virtual listview. As can be seen in the screenshot, the virtual list worked over ten times faster.

Using Virtual List - Demo Application

Using Virtual List – Demo Application

 

Additional notes

  • The demo application uses an SQL Server Compact 4.0 database. Its runtime engine usually comes with Visual Studio 2012. Anyway, if it isn’t already installed on your machine, you can download it for free, from Microsoft Download Center:
    http://www.microsoft.com/en-us/download/details.aspx?id=17876
  • A future article will show how to improve the virtual listview control in order to deal with much larger amount of data, by caching.

Resources

See also

Tiles-View List Control

Tiles View in Windows Explorer

Using Windows Explorer we can notice, aside others, the Tile View mode.

Tiles View (Windows Explorer)

Tiles View (Windows Explorer)

It looks like icon views but, beside a title (that shows the file name), it displays some additional info (file type and size).
This articles describe how to set Tiles View in our own listview (SysListView32) Windows control.

Set Tiles View in a list control

Let’s say, we’ve placed a list control in a dialog template. Possible, the first attempt is to search for a “Tile” value of the “View” property. No luck: we can see only “Icon”, “Small icon”, “List”, and “Report” (LVS_ICON, LVS_SMALLICON, LVS_LIST, and LVS_REPORT types).

However, there is a solution: send LVM_SETVIEW message or use ListView_SetView macro or (if using MFC) call CListCtrl::SetView.

Examples

In the same way, we can switch to the other view types, by passing LV_VIEW_ICON, LV_VIEW_SMALLICON, LV_VIEW_LIST, or LV_VIEW_DETAILS.
That’s pretty easy. However there are a little bit more things to do.

Set information for the list-view control in Tile View

For this purpose we can send LVM_SETTILEVIEWINFO message or use ListView_SetTileViewInfo or call CListCtrl::SetTileViewInfo.

Example

Set information for each item in Tile View

This can be done when the item is inserted or later, by sending LVM_SETTILEINFO, using ListView_SetTileInfo or calling CListCtrl::SetTileInfo.

Example

Demo Application

This is just a brief presentation. You can find more hints and details in the links below and in the demo project attached here.

Tiles View (Demo Application)

Tiles View (Demo Application)

Download: Tiles View List Control [Demo Project] (923)

Resources

Color Picker Listview Control

Among other common Windows dialogs we can find Color Dialog Box that allows to pick a color for our purposes. It can simply be created by a call of ChooseColor WinAPI function or, if using MFC, with the help of CColorDialog class.
Also, the MFC versions shipped with Visual Studio 2008 or newer, include CMFCColorDialog class which shows a little bit more fancy color selection dialog.

However, let’s say we have to make our own custom color picker control (let’s say, looking similar tho one used in Photoshop). Beside making a custom or ActiveX control from scratch, a faster approach is to customize the Windows listview (“SysListView32“) control, kept in MFC by CListCtrl class. There are two ways to customize a listview control: making it custom-draw or making it owner-draw.

Custom Draw Color Picker Listview

Color Picker Listview (custom-draw)

Color Picker Listview (custom-draw)

First we have to handle NM_CUSTOMDRAW notification, sent via WM_NOTIFY.
In subitem pre-paint phase, we can indicate which color has to be used to paint whatever list subitem.
Example

Finally, hadle NM_CLICK notification, get the color of the clicked item and send a user message to the parent.
Example

This method is pretty simple but it has a disadvantage: we cannot modify item/subitem height. So, if this is necessary we gave to make an owner-draw listview control.

Owner Draw Color Picker Listview

Color Picker Listview (owner-draw)

Color Picker Listview (owner-draw)

An owner-draw listview control must have LVS_OWNERDRAWFIXED style set (“Owner Draw Fixed” property must be set to “True” in the resource editor).
Next, we can handle WM_MEASUREITEM to set item size and override CListCtrl::DrawItem in order to perform custom drawing. Just to note: would be necessary to map by hand the WM_MEASUREITEM message; also DrawItem isn’t called for each subitem.
Example

Notes

  • Implementation details can be found in the attached demo projects
  • The color pickers presented here are just draft versions intended to demonstrate how to do. You can further improve them by adding new features like loading a custom color palette, adding custom colors on the fly, and so on.
  • A brief presentation of custom-draw and owner draw controls, can be found in this article: Custom Draw vs. Owner Draw Controls.

Downloads

Fill a List with Large Amount of Data – Part 1

In my opinion, making database queries in separate threads in order to avoid UI blocking is the last option a Windows developer should have. Of course, that’s an option like any others but, to avoid headaches of thread synchronization and so on, we have to consider first the following:

  • 1. Optimize the database, index fields if necessary.
  • 2. Choose the right database access technology.

Well, let’s say we are just “poor developers” and both database designer and project manager are idiots. Then, there’s no choice and we have to live with them without resolving #1 and #2. In most cases, UI is blocked as a result of populating a list control with a large number of rows, from a recordset. Have we to make this in a separate thread? Not really, wait a minute!

  • 3. Use a virtual list. A virtual list does not keep the UI busy until it’s filled with thousands, tens of thousands or even hundreds of thousands items. It just asks info about items which have to be currently displayed.
  • 4. Not enough? We have to deal with queries which return millions, tens of millions or even more results? No problem, can use a cache mechanism.

Both #3 and #4 are supported in the Windows common listview (SysListView32) control.

See also