Solved

Q: How to write a window class to replace the dropdown window of combo box

Posted on 1999-01-05
9
348 Views
Last Modified: 2013-11-20
Hi,

  I want to write a window class to replace the combolbox window of combox, so that in my own combobox control, I can popup this window to act as the dropdown window. But I meet some difficulties:

1. If I use a popup window, when my window appear, the background window become gray.

2. If I use combolbox, I can not know when the user click out of my dropdown window at which time I can close my dropdown window.

3. If I use SetCapture() to trace mouse input, the scroll bar of my dropdown window acts strengly. When you click at the scroll bar, my mouse capture disappears.

4. I have seen some controls which do not use mouse capture at all, but they act well. When I click outside of it, it disappears, without receiving any mouse message. How can they do that?

Can anyone give me any advice?
Thank a lot in advance.

Regards
wu xz
0
Comment
Question by:wuxz
  • 5
  • 3
9 Comments
 

Expert Comment

by:dagangwang
ID: 1327275
Why do you replace the combolbox window? What are you doing? I think that the default combolbox window is almost suitable for  everything. If not, you can change style owner it......
0
 
LVL 2

Expert Comment

by:zyqwert
ID: 1327276
1) The background window becomes grey.
This is because it is getting a WM_NCACTIVATE message with wParam == 0.  It gets this because your popup window becomes the active window for the thread when you bring it to the top of the Z order.  You want your window to be a popup, on top, but not the active window -- the only way to do this is make your window WS_EX_TOPMOST.

2) The two ways to know about a BUTTONDOWN outside of your window are setting capture and hooks.  Capture is preferred because there are other events which should cause you to close the dropdown window.  These other events will send your window a WM_CANCELMODE message which, when passed to DefWindowProc will cause a ReleaseCapture.

3) The scrollbar acts funny when your ComboLBox has capture.  Indeed it does. The scrolling happens when a WM_NCLBUTTONDOWN with HTVSCROLL goes to DefWindowProc.  When a window has capture, windows delivers only WM_LBUTTONDOWN messages.  The real comboLBox gets around this roughly like this:
case WM_LBUTTONDOWN:
// did this hit the scrollbar?
// yes.
ReleaseCapture();
SendMessage(h, WM_NCLBUTTONDOWN)
SetCapture(h);
// End hit the scrollbar

4) When you click outside of the control, on a window which belongs to another thread, you get activation messages which you could use to return to the normal state.  But if you click on you own parent window and you don't have capture, you don't get any messages.  The choices are capture or a hook.

5) You are definitely doing this the hard way.  The Combo box and the ComboLBox work together and talk to each other.  Chances are good that you want to change only some of the ComboLBox behaviour.  The way to do this is to subclass the ComboLBox.  Then you have complete control of it, but you can use the default behaviour when convenient.  To subclass the comboLBox, you can use a hook if you need to subclass it when it is first created.  If you can wait until it's infancy, then an wasier way to subclass it is when you are given a WM_CTLCOLORLISTBOX, the lParam is the hWnd of the listbox.  Then you can call:
pOldProc= SetWindowLong(GWL_WNDPROC, (LONG)YourWndProc);
and in YourWndProc, to get the default behaviour,
CallWindowProc(pOldProc, hWnd, message, wParam, lParam);

If you only want to change the appearance of the items, then an owner draw combo box is for you.


0
 
LVL 2

Expert Comment

by:zyqwert
ID: 1327277
1) The background window becomes grey.
This is because it is getting a WM_NCACTIVATE message with wParam == 0.  It gets this because your popup window becomes the active window for the thread when you bring it to the top of the Z order.  You want your window to be a popup, on top, but not the active window -- the only way to do this is make your window WS_EX_TOPMOST.

2) The two ways to know about a BUTTONDOWN outside of your window are setting capture and hooks.  Capture is preferred because there are other events which should cause you to close the dropdown window.  These other events will send your window a WM_CANCELMODE message which, when passed to DefWindowProc will cause a ReleaseCapture.

3) The scrollbar acts funny when your ComboLBox has capture.  Indeed it does. The scrolling happens when a WM_NCLBUTTONDOWN with HTVSCROLL goes to DefWindowProc.  When a window has capture, windows delivers only WM_LBUTTONDOWN messages.  The real comboLBox gets around this roughly like this:
case WM_LBUTTONDOWN:
// did this hit the scrollbar?
// yes.
ReleaseCapture();
SendMessage(h, WM_NCLBUTTONDOWN)
SetCapture(h);
// End hit the scrollbar

4) When you click outside of the control, on a window which belongs to another thread, you get activation messages which you could use to return to the normal state.  But if you click on you own parent window and you don't have capture, you don't get any messages.  The choices are capture or a hook.

5) You are definitely doing this the hard way.  The Combo box and the ComboLBox work together and talk to each other.  Chances are good that you want to change only some of the ComboLBox behaviour.  The way to do this is to subclass the ComboLBox.  Then you have complete control of it, but you can use the default behaviour when convenient.  To subclass the comboLBox, you can use a hook if you need to subclass it when it is first created.  If you can wait until it's infancy, then an wasier way to subclass it is when you are given a WM_CTLCOLORLISTBOX, the lParam is the hWnd of the listbox.  Then you can call:
pOldProc= SetWindowLong(GWL_WNDPROC, (LONG)YourWndProc);
and in YourWndProc, to get the default behaviour,
CallWindowProc(pOldProc, hWnd, message, wParam, lParam);

If you only want to change the appearance of the items, then an owner draw combo box is for you.


0
 
LVL 2

Author Comment

by:wuxz
ID: 1327278
Ok,

Thank you for your answer, but I find that capturing mouse is not a good method. In fact, the DBCombo control in Microsoft DataBind Listbox control(c:\windows\system\dblist32.ocx) does not use mouse capture at all, but it know when to close itself, what technology it uses?

Thank you very much

Regards
wu xz
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 2

Expert Comment

by:zyqwert
ID: 1327279
As I indicated in my previous comment, the other way to know about mouse events outside of your window is to set a hook.  dblist32.ocx does exactly that.
It sets a WH_MOUSE hook when it drops down.  If you want to do the same, see SetWindowsHookEx.
When it gets a LBUTTONDOWN in it's hook, it pops up.

It also uses a scrollbar child control, not a scroll style.

0
 
LVL 2

Author Comment

by:wuxz
ID: 1327280
Hi,

Thank you for your answer. You are right, only mouse hook can work.

I already know that mouse hook can work, but I do not like it, it likes waste its talent on petty job. Now, it seems that it is not a "simple job".

BTW, how can you sure that dblist32.ocx use hook?

Thank you very much.

0
 
LVL 2

Expert Comment

by:zyqwert
ID: 1327281
I made a test program, put a dbcombo on it, and ran it using Bounds Checker.  Bounds Checker is a program which can make a log of every API called by an application, and every message processed by the application.
When I looked at the log produced by Bounds Checker, I saw the dblist created, saw the hook get set, and saw the unhook occur when I clicked the mouse.
Bounds Checker is made by NuMega Software (www.numega.com).  Whenever I'm curious how a program implements something, I check it with Bounds Checker.
I find it and SoftIce to be valuable tools.

0
 
LVL 2

Author Comment

by:wuxz
ID: 1327282
Thand you very much.

Have you gotten my points? I do not find anywhere let me to accept your answer and give my points to you. If you do not get the deserved point, please tell me.

Thank you again.
0
 
LVL 2

Accepted Solution

by:
zyqwert earned 100 total points
ID: 1327283
Answer in comments.

0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Suggested Solutions

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
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.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

747 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now