Change the height of selected listbox/listctrl items.

Posted on 2003-03-07
Medium Priority
Last Modified: 2013-11-20
Basically, I want to figure out how to get a list control that looks like the list of currently installed programs in the Add/Remove Programs control panel app in Windows XP.

I've played around a bit with owner-drawn listboxes and can change the look of an item when it is selected (different height), but the items below aren't redrawn, so they get hidden when I increase the height of the selection.

I'm using VC++ 6; running on XP but would prefer it if this code would also run on Win9x as well as NT 4 or 2000.

Question by:jbladan
  • 5
  • 3

Expert Comment

ID: 8092351
You have to create your listbox with LBS_OWNERDRAWVARIABLE style, and provide a virtual function for MeasureItem and set the itemHeight value of each of the listbox item.

for example:
with Selected_Height and Unselected_Height defined some where else in your program, you can set the height of each item as follows:

void CMyListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
   if (lpMeasureItemStruct->itemID == GetCurSel())
       lpMeasureItemStruct->itemHeight = Selected_Height
       lpMeasureItemStruct->itemHeight = Unselected_Height
LVL 49

Expert Comment

ID: 8094791
That "listbox" is actually a page of HTML.  Using Spy++, you can see that the class is "HTML Application Host Window" and none of the buttons etc. are actual windows, but rather the psuedo-controls that are created by HTML tags like:
    <input type=button value="Remove">
So, the best solution would be to implement a web-browser control and formulate the HTML code that would do all of the cool things you see in that example.

-- Dan

Author Comment

ID: 8104219
Sorry for the delay in my response -- haven't been on any computer all weekend.  Anyway, both answers look good, but I'll wait until I have a chance to try them out today to accept one (or ask a couple follow up questions).

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.


Author Comment

ID: 8105278

I can't get your solution to work.  The MeasureItem function is only called when the list item is first created, not as it is selected, so the code in the "if(lpMeasureItemStruct->itemID == GetCurSel())" block is never run.

Author Comment

ID: 8105431

Your solution sounds like it'd be a nice one to use.  Would you be able to provide a bit more detail on how I'd create a "HTML Application Host Window" class and hook into events from it, like buttons or hyperlinks being clicked (or a reference to a page that describes it)?

I'm assuming that the change in the appearance of the selected item is done through some sort of DHTML, otherwise, that'd involve a lot of regeneration of HTML code for the control...  If you think I'm off on my guess, please let me know.

Note that I'm only using VC++ 6.  When I used Spy++ I don't see the HTML thing, just ComboBoxes.

LVL 49

Accepted Solution

DanRollins earned 1000 total points
ID: 8105731
Since you are using MFC, this is all quite easy.  Do some experimentation by using the AppWizard to create a new Dialog-based App.  Right-click in the dlg editor and choose Insert ActiveX Control and choose Microsoft WebBrowser.  Use the ClassWizard to create a control-type variable (m_ctlBrowser)

For testing, use an OnButton1 handler to load an .htm file from disk -- m_ctlBrowser.Navigate(...).   Your HTML can have all kinds of JScript in it.  For instance:

=-=-=-=-=-=-=-=-=-=-=-=-=- start of test.htm
function DoClick() {
   alert("Now you DON'T!");

<div id="divTest" style="visibility: visible">
Now you see it...
<input type=button value="Click me" onclick="DoClick">
=-=-=-=-=-=-=-=-=-=-=-=-=- end
(I did not test the above, but I think you can get the idea)

Obviously, you gave very precise control over what is displayed -- you can do anything you have ever seen done on a webpage anywhere on the Internet! -- but you will be using JScript for much of the display logic.  

That is not the only way.  For instance, you can rewrite the html file and reload it, or insert/remove/modify any element in the HTML (see:
for some example C++ code

Now here is a trick that lets your html communicate with your C++ program:  

Use the ClassWizard to add an BeforeNavigate2 handler.  Now each link clicked (or anytime the document.location="blahbla" gets executed in script), you program will get a chance to examine the URL.  

What I did was make some pseudo-URLs like

then in BeforeNavigate2, I can simple check to see if the first few characters are "myfn:" and if so, parse the rest of the line and figure out what the HTML wants to pass back to the C++.

There is another, more complicated way to communicate between the browser control and the C++ program, but I have described a good, robust way to do it that is utterly simple to implement.

When you have tried out some of these concepts, I'll explain a way to read the HTML from a resource rather than from a disk file.

-- Dan

Author Comment

ID: 8115102
Okay, so I've played around a bit with this stuff.  Please do share how to read the HTML from a resource.  I gave it a shot, but had no luck.

Also, where can I look to find out how to use the up & down cursor keys for changing item selection?

I also still have no idea how I'd make the list items show/hide information as they're selected...

Thanks again,
LVL 49

Expert Comment

ID: 8115861
To place an HTML file into a resource, follow the steps here:
In your Navigate() call, you will use a URL like:

>>Also, where can I look to find out how to use the up & down cursor keys for changing item selection?

That's a question of the JavaScript TA.  Tell the Experts there you will be using IE5+ (no need for Netscape compatibility).  I'm pretty sure it will be a simple OnFocus handler.

>>I also still have no idea how I'd make the list items show/hide information as they're selected...


I'd like to remind you that you are attempting to do something quite difficult -- the sort of window you see in Add/Remove Programs is not part of the Windows common controls; that is, there is no class-wizard help or much written about it.  If you just wanted to do a simple listview or treeview, then the process would be much easier.  But this is a much cooler interface -- and harder to program.  So expect to spend some time learning the ropes. The final result will be worth the effort.

-- Dan

Author Comment

ID: 8121099
Thanks for your help, Dan.  Hopefully now I can find out the details of the JavaScript programming...


Featured Post

[Webinar On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
Ready to get certified? Check out some courses that help you prepare for third-party exams.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
Suggested Courses
Course of the Month12 days, 21 hours left to enroll

578 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question