|
-
Aug 18th, 2010, 06:47 AM
#1
Thread Starter
Addicted Member
[RESOLVED] Combo box notification messages with a Toolbar parent
I have my WM_COMMAND CBN_messages trapped and working when the combo box has a frame control as a parent, lParam having the combo box handle.
I have since moved the combo box to a toolbar (placeholder style), now I want to trap the CBN_messages again, but I can't find the parent for the combo.
I tried WndProc-ing frm.toolbar1.hwnd as the parent also tried
htoolbar = GetWindow(frm.toolbar1.hwnd,GW_CHILD)
also tried "htoolbar" as the parent window handle which is required for any TB_messages.
Neither handle worked, so how do I find/get the parent?
-
Aug 18th, 2010, 11:46 AM
#2
Re: Combo box notification messages with a Toolbar parent
I'd double check your code.
I Used Spy++, that comes with VB installation disks, & trapped its messages. The WM_Command related combobox messages were being seen. The messages came in under Toolbar1.hWnd as expected.
A quick test & it worked for me. Trapped cbn_closeup and cbn_dropdown, subclassing toolbar1.hWnd
Check to see if GetParent API returns the toolbar's hWnd. If not, then your combobox is in some other container?
Edited: The cbn_xxxx message is in the hiword of wParam. I assume you know that and know how to extract it out.
Code:
If uMsg = WM_COMMAND Then
Select Case (wParam And &HFFFF0000) \ &H10000
Case CBN_CLOSEUP: Debug.Print "Closed"
Case CBN_DROPDOWN: Debug.Print "Opened"
End Select
End If
Last edited by LaVolpe; Aug 18th, 2010 at 12:56 PM.
-
Aug 18th, 2010, 06:25 PM
#3
Thread Starter
Addicted Member
Re: Combo box notification messages with a Toolbar parent
Hi LaVolpe,
I didn't think about using the GetParent API to see where the combo1 was sitting, thanks...found it on the frmMain instead of in the toolbar, good now I can subclass CBN_messages...HOWEVER after dropping the combo inside the toolbar, I can NO longer see TB_messages ...such as TB_BUTTONCOUNT, and TB_GETMAXSIZE, they return cy and cx = 0 and the button count = -1, removing the combo from the toolbar and putting in back on frmMain gets the TB_messages working again. Any more suggestions?
Note: following this microsoft bulletin, http://support.microsoft.com/kb/153928, which I did originally, doesn't indicate that the control should go inside the toolbar. To place the control inside the toolbar I used the Cut (from frmMain) highlighted the toolbar, then Paste the control into the toolbar.
Note: if I shut off subclassing the CBN_messages, I still have the TB_messages problem.
Note: same thing happens if I drop an edit box into the toolbar, TB_messages stop working, it doesn't matter if I set the .top and .left properties of the dropped in control to the toolbar placeholder or not.
Last edited by vb_lover; Aug 19th, 2010 at 05:44 AM.
Reason: typo TBN_ >>>CBN_
-
Aug 18th, 2010, 06:47 PM
#4
Re: Combo box notification messages with a Toolbar parent
Think we may need to see your window procedure routine, with any module-wide variable descriptions needed for us to know what that subclassing routine is referring to.
-
Aug 18th, 2010, 07:23 PM
#5
Thread Starter
Addicted Member
Re: Combo box notification messages with a Toolbar parent
 Originally Posted by LaVolpe
Think we may need to see your window procedure routine, with any module-wide variable descriptions needed for us to know what that subclassing routine is referring to.
I don't know if you saw my edited post which added some notes. I can turn off the CBN_subclassing, and the problem still exists which is that whenever a control (combo box or edit box) is placed inside the toolbar making the toolbar the parent, TB_messages no longer work. I am not using TB_messages inside of subclassing. Actually testing them with a command button click.
Dim htoolbar as long
htoolbar = GetWindow(combo1.hwnd,GW_CHILD)
Msgbox SENDMESSAGE (htoolbar, TB_BUTTONCOUNT, 0,0)
Last edited by vb_lover; Aug 19th, 2010 at 05:46 AM.
Reason: mistake in GetWindow API call, forgot to type in the GW_CHILD originally, TBN_ >>> CBN_
-
Aug 18th, 2010, 07:25 PM
#6
Re: Combo box notification messages with a Toolbar parent
The messages are going somewhere. That's why I suggested we see your code; maybe it's something rather simple. But I have no idea what method(s) you are using: 1 windowprocedure for both combo & toolbar, 2 windowprocedures, something else?
Edited: What is GetWindow? I know it is an API, but is it an API declaration for you or a custom routine? Custom routine most likely. Is it returning the right hWnd? Does the toolbar have any buttons? Lots of questions not enough details.
Last edited by LaVolpe; Aug 18th, 2010 at 07:31 PM.
-
Aug 18th, 2010, 07:50 PM
#7
Re: Combo box notification messages with a Toolbar parent
Is this a VB toolbar control? If so, see this thread. You may be using the wrong hWnd
http://forums.devx.com/showthread.php?t=42939
-
Aug 19th, 2010, 05:25 AM
#8
Thread Starter
Addicted Member
Re: Combo box notification messages with a Toolbar parent
 Originally Posted by LaVolpe
The messages are going somewhere. That's why I suggested we see your code; maybe it's something rather simple. But I have no idea what method(s) you are using: 1 windowprocedure for both combo & toolbar, 2 windowprocedures, something else?
Edited: What is GetWindow? I know it is an API, but is it an API declaration for you or a custom routine? Custom routine most likely. Is it returning the right hWnd? Does the toolbar have any buttons? Lots of questions not enough details.
Its not a custom API call, I just forgot to type in the GW_CHILD earlier.
-
Aug 19th, 2010, 05:35 AM
#9
Thread Starter
Addicted Member
Re: Combo box notification messages with a Toolbar parent
 Originally Posted by LaVolpe
I am using the standard VB toolbar control (Ver 6, SP6)
This is the method I am using to retrieve the proper window handle for the TB_messages. I edited my earlier post, which was confusing because I forgot the GW_CHILD in the follow up post, however it was correctly stated in the origial post.
Because I have tons of code in my program I am going to start a new project with just the VB toolbar (Ver 6) and do some testing. As I mentioned before, if I completely turn off subclassing, the problem with not being able to return valid results from SENDMESSAGE (htoolbar,TB_BUTTONCOUNT,0,0) and TB_GETMAXSIZE still exists once I drop a combo box or edit box control inside the toolbar.
Thank you for your suggestions so far.
Last edited by vb_lover; Aug 19th, 2010 at 06:08 AM.
Reason: added toolbar version
-
Aug 19th, 2010, 05:53 AM
#10
Thread Starter
Addicted Member
Re: Combo box notification messages with a Toolbar parent
What I am doing with the subclassing is trapping the CBN_CLOSEUP and CBN_DROPDOWN which I presume you already knew since you mentioned it earlier in this thread...guessing you may have stumbled on a my post from Dec 29,30 2008. But if I disable the WNDPROC call to turn on subclassing, the TB_message problem still exists. I am doing just a simple command button click to obtain the results >>
htoolbar = GETWINDOW (toolbar1.hwnd,GW_CHILD)
msgbox SENDMESSAGE htoolbar, TB_BUTTONCOUNT, 0,0
Last edited by vb_lover; Aug 19th, 2010 at 06:01 AM.
-
Aug 19th, 2010, 08:12 AM
#11
Re: Combo box notification messages with a Toolbar parent
Check the htoolbar return value. Is it the combobox's hWnd? Maybe. The GetWindow API call is returning the 1st child hWnd & it might just be the combobox! And that would explain your problem I think.
GW_CHILD
The retrieved handle identifies the child window at the top of the Z order, if the specified window is a parent window; otherwise, the retrieved handle is NULL. The function examines only child windows of the specified window. It does not examine descendant windows.
Edited: If you can't figure it out. Suggest using Spy++ and compare the htoolbar value you are getting with the actual toolbar window.
Spy++ comes with VB installation disks.
Last edited by LaVolpe; Aug 19th, 2010 at 08:20 AM.
-
Aug 19th, 2010, 08:22 AM
#12
Thread Starter
Addicted Member
Re: Combo box notification messages with a Toolbar parent
Although this thread was originally about combo boxes the the toolbar, I also have the same problem with the textbox control inside the toolbar.
OK what I have done is created a new project to test this problem and added the following controls on a form:
toolbar1 (ver 6): then add 2 default buttons and no placeholder buttons
toolbar2 (ver 5): then added 3 default buttons and no placeholder buttons
text1: added this directly to the form, and tested the button count and it came back with a "2" as it should. Cut it from the form and pasted onto toolbar1, tested the text1 parent with GetParent to make sure it returned the same handle as toolbar1.hwnd and it did. Then pressed the command button the the button count failed and returned "0"
text2: added this directly to the form, and tested the button count for toolbar2 and it returned a "3" as it should. Then did a copy and paste into toolbar2, now I have the exact same bug as i do with toolbar1 but using toolbar2 (ver5)
command button 1: added code to test TB_BUTTONCOUNT of toolbar1
command button 2: added code to test TB_BUTTONCOUNT of toolbar2
Do I somehow have to identify the text1 control to a placeholder?
Is there a way a using Spy++ to see where/why the TB_BUTTONCOUNT becomes invalid? where the messages are going? In my other project, I do have the placeholder buttons in the Ver6 toolbar, but I thought it not neccessary to bother to add them here to duplicate the problem. I also have the same problem using TB_GETMAXSIZE on the original project but purposely didn't include it on this project to keep things simple.
this is the complete code in this project--------------------------
Option Explicit
Public Const WM_USER = &H400
'Toolbar Constants
Public Const TB_GETTOOLTIPS = (WM_USER + 35)
Public Const TB_GETMAXSIZE = (WM_USER + 83)
Public Const TB_BUTTONCOUNT = (WM_USER + 24)
Public Const TB_GETROWS = (WM_USER + 40)
Public Const TB_SETROWS = (WM_USER + 39)
Public Const TB_SETPARENT = (WM_USER + 37)
Public Const TB_AUTOSIZE = (WM_USER + 33)
'GetWindow constants
Public Const GW_HWNDFIRST = 0
Public Const GW_HWNDLAST = 1
Public Const GW_HWNDNEXT = 2
Public Const GW_HWNDPREV = 3
Public Const GW_OWNER = 4
Public Const GW_CHILD = 5
'Used to set and retrieve various information
Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Function GetWindow Lib "user32.dll" ( _
ByVal hwnd As Long, ByVal wCmd As Long) As Long
Declare Function GetParent Lib "user32" ( _
ByVal hwnd As Long) As Long
--------------
Private Sub Command1_Click()
Dim hToolbar As Long
Dim n As Long
Dim lparent As Long
lparent = GetParent(Text1.hwnd)
hToolbar = GetWindow(Toolbar1.hwnd, GW_CHILD)
n = SendMessage(hToolbar, TB_BUTTONCOUNT, 0, 0)
MsgBox n & " " & Toolbar1.hwnd & " " & lparent
End Sub
Private Sub Command2_Click()
Dim hToolbar As Long
Dim n As Long
hToolbar = GetWindow(Toolbar2.hwnd, GW_CHILD)
n = SendMessage(hToolbar, TB_BUTTONCOUNT, 0, 0)
MsgBox n
End Sub
-
Aug 19th, 2010, 08:28 AM
#13
Re: Combo box notification messages with a Toolbar parent
I've tried to explain to you that your toolbar handle is probably invalid. Here is a simple test
1. New form, add toolbar & create 2 toolbar buttons in it
2. Add a combobox to the form, not the toolbar
3. Add a command button to the form and paste this code
Code:
Private Sub Command1_Click()
Dim tHwnd As Long
tHwnd = GetWindow(Toolbar1.hwnd, GW_CHILD)
Debug.Print tHwnd, Combo1.hwnd, SendMessage(tHwnd, TB_BUTTONCOUNT, 0&, ByVal 0&)
Set Combo1.Container = Toolbar1
tHwnd = GetWindow(Toolbar1.hwnd, GW_CHILD)
Debug.Print tHwnd, Combo1.hwnd, SendMessage(tHwnd, TB_BUTTONCOUNT, 0&, ByVal 0&)
End Sub
You can see that the same code does not work once you place other controls on the toolbar. You should enumerate the child windows until you get the lowest in the zOrder. Or use FindWindowEx to locate the toolbar window by providing a hardcoded classname.
Edited: Here's a way to get the lowest zOrder child of the vb toolbar. It should solve your problem assuming no one goes and changes the actual toolbar's zOrder to something higher.
Code:
Private Sub Command1_Click()
Dim tHwnd As Long
tHwnd = GetWindow(Toolbar1.hwnd, GW_CHILD)
Debug.Print tHwnd, Combo1.hwnd, SendMessage(tHwnd, TB_BUTTONCOUNT, 0&, ByVal 0&)
Debug.Print vbTab; "Lowest zOrder Child Window: "; GetWindow(tHwnd, GW_HWNDLAST)
Set Combo1.Container = Toolbar1
tHwnd = GetWindow(Toolbar1.hwnd, GW_CHILD)
Debug.Print tHwnd, Combo1.hwnd, SendMessage(tHwnd, TB_BUTTONCOUNT, 0&, ByVal 0&)
Debug.Print vbTab; "Lowest zOrder Child Window: "; GetWindow(tHwnd, GW_HWNDLAST)
End Sub
Last edited by LaVolpe; Aug 19th, 2010 at 08:53 AM.
-
Aug 19th, 2010, 09:21 AM
#14
Thread Starter
Addicted Member
Re: Combo box notification messages with a Toolbar parent
LaVolpe,
Thanks, thats exactly whats happening, the GETWINDOW is returning the first child which is the combobox(or textbox) once it is placed into the toolbar control. How do I insure the first window is always the toolbar window, and not one of the added controls? If I add placeholder button(s) for the added controls, then change the zorder of the combo (or edit) controls to 1 (text1.zorder 1) then the TB_message works after getting the GW_CHILD of the toolbar, but then the edit control(s) become invisible when the command button is clicked. The placeholders don't provide a means of visual support
even though the edit box properties have been set top, left and width to the placeholder button(s). The Visible check box is checked for all toolbar buttons in the Custom toolbar property dialog. What is the proper way of handling this issue?
-
Aug 19th, 2010, 09:36 AM
#15
Re: Combo box notification messages with a Toolbar parent
Did you see my updated reply? Get handle of 1st child and then use it to get handle of lowest zOrder child.
-
Aug 19th, 2010, 09:40 AM
#16
Thread Starter
Addicted Member
Re: Combo box notification messages with a Toolbar parent
I am going to take your suggestion and use FindWindowEx to obtain the toolbar window to solve this problem. Thanks for your help!
-
Aug 19th, 2010, 09:44 AM
#17
Re: Combo box notification messages with a Toolbar parent
 Originally Posted by vb_lover
I am going to take your suggestion and use FindWindowEx to obtain the toolbar window to solve this problem. Thanks for your help! 
You're welcome. Ensure the toolbar classname is the same compiled and uncompiled. VB does not always use the same classnames in IDE as it does when compiled.
Edited: Probably not applicable here; you aren't using intrinsic VB objects but an OCX. The classname should be the same
Last edited by LaVolpe; Aug 19th, 2010 at 09:53 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|