Solved

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

Posted on 1999-01-05
9
362 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Include multiple hostnames in this command? 3 55
Hibernate methods 2 83
Change to event 1 129
Problem to App 4 119
Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
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.

733 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