'Virtual' list-box
Ellis Brover -- brover@siemens.com.au Tuesday, November 14, 1995 Hi, I am trying to create a "virtual" list-box deriving from CListCtrl (i.e. using the Windows95 list-view control). It needs to handle scrolling completely, so that only the items visible on the screen are actually in the list at any given time. This is necesary so that I can dynamically read in just a few items from a huge database cursor query. I have looked at the VLIST sample on MSDN, but it doesn't really work the same for the list-view control. For example, the list-view tries to set the scroll position/range on every WM_PAINT, so I need to intercept WM_PAINT and reset my own scroll position. This creates flickering and all sorts of recursion problems with WM_SIZE being called repeatedly. The only way I can find to tell Windows to leave scrolling alone is the LVS_NOSCROLL style, but this has an unexpected side-effect: under NT 3.51 it also turns off the column headers! Any help would be appreciated! Also if anybody has written a virtual tree-view control that would be even more appreciated! Thanks, Ellis Brover Ellis.Brover@siemens.com.au
jerry_albro@tcpgate.ibi.com Thursday, November 16, 1995 Maybe a proper database grid contol would be more useful. I've used the Kansmen table tool control, and it allows exactly what you need. You tell it how many records you have, and it will request data when the user scrolls, with a selectable amount of buffering so you dont bang on the database more than you want to. I'm sure other database grid controls can also do this. It surely will be a lot easier than force-fitting a listbox into your scheme... Jerry Albro _________________________Reply Header_________________________ Author: mfc-l@netcom.com Subject: "Virtual" list-box 11-14-95 08:23 PM Hi, I am trying to create a "virtual" list-box deriving from CListCtrl (i.e. using the Windows95 list-view control). It needs to handle scrolling completely, so that only the items visible on the screen are actually in the list at any given time. This is necesary so that I can dynamically read in just a few items from a huge database cursor query. I have looked at the VLIST sample on MSDN, but it doesn't really work the same for the list-view control. For example, the list-view tries to set the scroll position/range on every WM_PAINT, so I need to intercept WM_PAINT and reset my own scroll position. This creates flickering and all sorts of recursion problems with WM_SIZE being called repeatedly. The only way I can find to tell Windows to leave scrolling alone is the LVS_NOSCROLL style, but this has an unexpected side-effect: under NT 3.51 it also turns off the column headers! Any help would be appreciated! Also if anybody has written a virtual tree-view control that would be even more appreciated! Thanks, Ellis Brover Ellis.Brover@siemens.com.au
Mike Blaszczak -- mikeblas@interserv.com Friday, November 17, 1995 On Tue, 14 Nov 95, Ellis Broverwrote: >I am trying to create a "virtual" list-box deriving from CListCtrl >(i.e. using the Windows95 list-view control). It needs to handle >scrolling completely, so that only the items visible on the screen >are actually in the list at any given time. This is necesary so that >I can dynamically read in just a few items from a huge database >cursor query. You don't need to worry about doing any virtualization yourself if you're using a Windows list view common control. Just implement a handler for the get disp info notification message from the list (in MFC, it would be OnGetDispInfo() in the owner window) and tell the list control that all of your strings are LPSTR_TEXTCALLBACK. You can find information on how this works starting with this section in the Win32 SDK documentation: Win32 Overviews Window Controls Common Controls List View Controls About List View COntrols Callback Items and the Callback Mask .B ekiM -- #ifdef JOHNELS_SAID_I_COULD_STEAL_HIS_SIG //REVIEW: JohnEls changed his and now it's cooler than the one I stole TCHAR szDisc[] = _T("These words are my own; I do not speak for Microsoft."); #endif
Colin Oatley -- ColinOatley@msn.com Sunday, January 28, 1996 I am trying to follow up on the suggestions that were given in the message, "Re 'Virtual' list-box," dated 11/17/95. You will recall that a "Virtual" list box is a CListCtrl that contains the visible subset of a database cursor query; as the user scrolls through the CListCtrl, the virtual list box would insert the newly visible items and delete the newly invisible items from the control. If a cursor contains only a few rows, one can afford to insert all of them into the control. But if a cursor contains thousands or millions of rows, it's impractical to insert them all at once. I've studied the suggested solution and the MFC & SDK manuals, I've run some tests, and I don't see how inserting rows as callback items helps to achieve the virtual list box. It appears that the LVN_GETDISPINFO notification message only applies to items that I have already inserted into the control; it doesn't tell me when I need to insert or remove items from the control. Am I missing something? At present, the only way I can think of to implement a virtual list box is to insert, say, 100 items into the CListCtrl and intercept the scrolling messages, adding/deleting items to/from the control as the user scrolls. Does this sound reasonable? Does anyone know of a better way? >From: owner-mfc-l@netcom.com on behalf of mikeblas@interserv.com >Sent: Friday, November 17, 1995 2:43 PM >To: mfc-l@netcom.com >Subject: Re: "Virtual" list-box > >On Tue, 14 Nov 95, Ellis Broverwrote: > >>I am trying to create a "virtual" list-box deriving from CListCtrl >>(i.e. using the Windows95 list-view control). It needs to handle >>scrolling completely, so that only the items visible on the screen >>are actually in the list at any given time. This is necesary so that >>I can dynamically read in just a few items from a huge database >>cursor query. > >You don't need to worry about doing any virtualization yourself if you're >using a Windows list view common control. Just implement a handler for the >get disp info notification message from the list (in MFC, it would be >OnGetDispInfo() in the owner window) and tell the list control that all of >your strings are LPSTR_TEXTCALLBACK. >You can find information on how this works starting with this section in the >Win32 SDK documentation: > >Win32 > Overviews > Window Controls > Common Controls > List View Controls > About List View COntrols > Callback Items and the Callback Mask > >.B ekiM >-- >#ifdef JOHNELS_SAID_I_COULD_STEAL_HIS_SIG >//REVIEW: JohnEls changed his and now it's cooler than the one I stole >TCHAR szDisc[] = _T("These words are my own; I do not speak for Microsoft."); >#endif
Tim Philip -- philip@cs.usask.ca Monday, January 29, 1996 [Mini-digest: 2 responses] Colin Oatley writes: > > I am trying to follow up on the suggestions that were given in the message, > "Re 'Virtual' list-box," dated 11/17/95. You will recall that a "Virtual" list > box is a CListCtrl that contains the visible subset of a database cursor > query; as the user scrolls through the CListCtrl, the virtual list box would > insert the newly visible items and delete the newly invisible items from the > control. If a cursor contains only a few rows, one can afford to insert all of > them into the control. But if a cursor contains thousands or millions of rows, > it's impractical to insert them all at once. > > I've studied the suggested solution and the MFC & SDK manuals, I've run some > tests, and I don't see how inserting rows as callback items helps to achieve > the virtual list box. It appears that the LVN_GETDISPINFO notification message > only applies to items that I have already inserted into the control; it > doesn't tell me when I need to insert or remove items from the control. Am I > missing something? > > At present, the only way I can think of to implement a virtual list box is to > insert, say, 100 items into the CListCtrl and intercept the scrolling > messages, adding/deleting items to/from the control as the user scrolls. > > Does this sound reasonable? Does anyone know of a better way? > I've never tried this ... but this is what I would look into: Set up a very simple CVirtualListCtrl which acts just like a CListCtrl except that it accepts a posted message to insert a new element. Then create a threaded class that will read extra elements from the database and send messages to the CVirtualListCtrl to add more items. Hook this class into OnIdle() so that it doesn't suck up too much CPU time (effectively stopping the user from scrolling through the list). The end result should be a listbox that slowly grows (ie. growing faster the less the user does, so if the user gets to the end of the list and pauses it should quickly fill in extra entries). As I said, I've never done this and I'm not even sure that it is do-able. But it sure sounds good, eh! :) ------- Tim Philip, B.Sc. Randco Software Corporation Consultant 2530 Hanover Avenue Saskatoon, SK Phone: +1-306-343-3380 philip@cs.usask.ca Canada S7J 1G1 Fax: +1-306-343-3341 -----From: kitk@mudshark.sunquest.com (Kit Kauffmann) >"Re 'Virtual' list-box," dated 11/17/95. You will recall that a "Virtual" list >box is a CListCtrl that contains the visible subset of a database cursor >query; as the user scrolls through the CListCtrl, the virtual list box would > FYI, "virtual listbox" usually refers to a freebie from MS called VLIST, which is a simple virtual listbox that makes it possible to have a standard-looking listbox which can handle a huge (2^31) number of items (by using a regular listbox control which actually only contains the # of visible items: it then calls you to ask for the next or previous record, and so forth) If anyone cares, I provide both an updated version of that (rather bug-ridden) VLIST control which is in commercial use in a number of programs (worldwide!), and an MFC wrapper class which is also in use by most of those programs (not in programs I wrote: I've only used it in a few myself, so it may not be perfect but lots of people are using it. (Shameless self-promotion for some free software: you can get it and other items at mudshark.sunquest.com in the pub/kitk directory -there is an index which briefly describes the VLIST stuff and some other useful stuff for MFC and Windows programmers) K
Stephen Keeler -- keelers@igs.net Tuesday, January 30, 1996 > I am trying to follow up on the suggestions that were given in the > message, "Re 'Virtual' list-box," dated 11/17/95. You will recall > that a "Virtual" list box is a CListCtrl that contains the visible > subset of a database cursor query; as the user scrolls through the > CListCtrl, the virtual list box would insert the newly visible items > and delete the newly invisible items from the control. If a cursor > contains only a few rows, one can afford to insert all of them into > the control. But if a cursor contains thousands or millions of rows, > it's impractical to insert them all at once. > > I've studied the suggested solution and the MFC & SDK manuals, I've > run some tests, and I don't see how inserting rows as callback items > helps to achieve the virtual list box. It appears that the > LVN_GETDISPINFO notification message only applies to items that I > have already inserted into the control; it doesn't tell me when I > need to insert or remove items from the control. Am I missing > something? > > At present, the only way I can think of to implement a virtual list > box is to insert, say, 100 items into the CListCtrl and intercept > the scrolling messages, adding/deleting items to/from the control as > the user scrolls. > > Does this sound reasonable? Does anyone know of a better way? > This is the approach that I took 3 years ago, using Windows 3.1 and a subclassed LISTBOX control. You set up a row buffer that is somewhat larger than the max number of displayed rows in the control, then intercept user movement requests. While it certainly is possible to go after data on a one-by-one basis -- the callback mentioned above for CListCtrl and also the approach used in the VLIST sample -- it is terribly inefficient for certain types of data sources. In our case, we're going after data in SQL Server databases. This is definitely a non-trivial task. In order to justify the amount of work required to provide this type of functionality, we implemented our original solution as a VBX so that it could be easily reused. Regards, Stephen Keeler On-Line Systems Inc.
Balaji S -- balaji@hiso.honeywell.soft.net Friday, February 02, 1996 Hello, I am using the VLIST and a class based implementation of the same. I want the Drag'n Drop feature also to be added to the VLIST box. I am using MSVC 1.52 and Windows v3.11. The application should be able to send me messages when some item is clicked and dragged. I don't want drag'n drop within the same VLIST, but I should be able to Drop it to another normal listbox. For this normal listbox, I am processing the OnLButtonDown, OnMouseMove and OnLButtonUp messages. It is inherited from CListbox ( MFC class ). Should I do the same way for VLIST also by processing all the above mouse messages ? Moreover is it possible to have multiple selection in the VLIST box ? Are there any freeware implementations available or any style bit can be set for this purpose ? Any pointers will be appreciated. TIA WM_CHEERS | WM_REGARDS Balaji ____________________________ | Balaji Subramaniam | /)| balaji@honeywell.soft.net |(\ / )| Balaji.S@CORP.honeywell.com|( \ __( (|____________________________|) )__ ((( \ \ > /_) ( \ < / / ))) (\\\ \ \_/ / \ \_/ / ///) \ / \ / \ _/ \_ / / / \ \ / / \ \ ********************************************************************* fu cn rd ths, u cn gt a gd jb n cmptr prgrmmng ********************************************************************* 02/01/96 10:00:28 IST
Kit Kauffmann -- kitk@mudshark.sunquest.com Thursday, February 01, 1996 >> I am trying to follow up on the suggestions that were given in the >> message, "Re 'Virtual' list-box," dated 11/17/95. You will recall >> that a "Virtual" list box is a CListCtrl that contains the visible >> subset of a database cursor query; as the user scrolls through the >> CListCtrl, the virtual list box would insert the newly visible items >> and delete the newly invisible items from the control. If a cursor >> contains only a few rows, one can afford to insert all of them into >> the control. But if a cursor contains thousands or millions of rows, >> it's impractical to insert them all at once. >> >> I've studied the suggested solution and the MFC & SDK manuals, I've >> run some tests, and I don't see how inserting rows as callback items >> helps to achieve the virtual list box. It appears that the >> LVN_GETDISPINFO notification message only applies to items that I >> have already inserted into the control; it doesn't tell me when I >> need to insert or remove items from the control. Am I missing >> something? >> >> At present, the only way I can think of to implement a virtual list >> box is to insert, say, 100 items into the CListCtrl and intercept >> the scrolling messages, adding/deleting items to/from the control as >> the user scrolls. >> >> Does this sound reasonable? Does anyone know of a better way? >> > >This is the approach that I took 3 years ago, using Windows 3.1 and a >subclassed LISTBOX control. You set up a row buffer that is somewhat >larger than the max number of displayed rows in the control, then >intercept user movement requests. > >While it certainly is possible to go after data on a one-by-one basis >-- the callback mentioned above for CListCtrl and also the approach >used in the VLIST sample -- it is terribly inefficient for certain >types of data sources. In our case, we're going after data in SQL >Server databases. > >This is definitely a non-trivial task. In order to justify the >amount of work required to provide this type of functionality, we >implemented our original solution as a VBX so that it could be easily >reused. > >Regards, >Stephen Keeler >On-Line Systems Inc. > You could save yourself some work and use Microsoft's VLIST - here is my standard posting on the subject: MS provides (MSDN, ftp, or Compu$erve) VLIST.DLL, a single-selection listbox (capable of owner-draw and/or LBS_USETABSTOPS, either of which can provide columnar-style output). It has two modes, one of which can handle 2^32-1 items; the other can handle any number of rows, but the UI is broken (the thumb will not function correctly). See the VLIST docs for more details on this. BTW, it does this by sending the listbox owner messages like "get the next record", "get the previous record", and so forth. I provide an MFC-compatible wrapper for this DLL at: mudshark.sunquest.com pub/kitk/vl.zip This wrapper considerably simplifies (IMHO) the mechanics of dealing with VLIST. Also, akin to the "self-draw" semantics of CListBox, CComboBox, and CButton (replacing the less OO owner-draw semantics), the wrapper returns the responsibility of record-fetching to the listbox, making a more object- oriented style of listbox (and derivation) possible. (self-fetching listboxes? :-) In 3.1, the limits are: 32K item data, and 64K of string data. This gives you a max of 8160 items, with an owner draw box without the LBS_HASSTRINGS style. If you are exceeding this limit, you may wish to look at the VLIST custom control provided by MS at ftp site, on MSDN, or on CIS in the WINSDK forum. If you are an MFC user, you might be interested in my MFC-based wrapper class for VLIST: mudshark.sunquest.com pub/kitk/vl.zip (Also available in the MSMFC Doc/View/UI forum library on CIS)
Tim Philip -- philip@cs.usask.ca Monday, February 05, 1996 Balaji Subramaniam writes: > > I want the Drag'n Drop feature also to be added to the VLIST box. I > am using MSVC 1.52 and Windows v3.11. The application should be able to > send me messages when some item is clicked and dragged. I don't want drag'n > drop within the same VLIST, but I should be able to Drop it to another > normal listbox. > I'm trying to do something along a similar line. I'm using MSVC 1.52 and I want to implement drag and drop between a couple listboxes. Everything in the documentation associated OLE with drag and drop so I started looking at OLE containers and drag'n'drop. However, I do not want any interaction with other applications so I'm not quite sure that OLE is appropriate. What is the correct "MFC-way" to implement drag'n'drop? Is OLE the right way to do it or is it possible to implement it without OLE?! Any hints/tips/pointers would be greatly appreciated. Thanks! ------- Tim Philip, B.Sc. Randco Software Corporation Consultant 2530 Hanover Avenue Saskatoon, SK Phone: +1-306-343-3380 philip@cs.usask.ca Canada S7J 1G1 Fax: +1-306-343-3341
Kit Kauffmann -- kitk@mudshark.sunquest.com Tuesday, February 06, 1996 >Balaji Subramaniam writes: >> >> I want the Drag'n Drop feature also to be added to the VLIST box. I >> am using MSVC 1.52 and Windows v3.11. The application should be able to >> send me messages when some item is clicked and dragged. I don't want drag'n >> drop within the same VLIST, but I should be able to Drop it to another >> normal listbox. >> > >I'm trying to do something along a similar line. I'm using MSVC 1.52 and >I want to implement drag and drop between a couple listboxes. Everything >in the documentation associated OLE with drag and drop so I started looking >at OLE containers and drag'n'drop. However, I do not want any interaction >with other applications so I'm not quite sure that OLE is appropriate. > >What is the correct "MFC-way" to implement drag'n'drop? Is OLE the >right way to do it or is it possible to implement it without OLE?! > >Any hints/tips/pointers would be greatly appreciated. > >Thanks! > >------- >Tim Philip, B.Sc. Randco Software Corporation >Consultant 2530 Hanover Avenue > Saskatoon, SK Phone: +1-306-343-3380 >philip@cs.usask.ca Canada S7J 1G1 Fax: +1-306-343-3341 > Certainly you can do this with OLE - but that is quite a lot of overhead if all you want is some simple listbox drag'n'drop: if you are interested in doing it by hand, I provide some sample code adapted for MFC (from some C code provided by the famous John Grant) by ftp at: mudshark.sunquest.com pub/kitk/dragdrop.zip It has absolutely no documentation (I'm getting lazier every day). All you do to use it is create an object of type CDragDropListBox in your dialog class, and use the Subclass method to connect it to the resource-based listbox, as in: CDragDropListBox m_ListBox; // declared in dialog class YourDialog::OnInitDialog() { ... m_ListBox.Subclass( ID_LISTBOX, this ); ... } Note that using LBS_SORT with this would probably not yield the expected results :-) The code allows you to use drag and drop to resort the elements of a listbox (I've also adapted it for drag'n'drop between two LB's - all pretty straightforward). HTH!
| Вернуться в корень Архива |