原来你就相信他?他能做出来早给你了!算了,帮人如同还债,我还是给你一个例子代码:这是用ListView做下拉的例子,你试试!!!'In a module ===== Option Explicit Public defWinProc As LongPublic Const GWL_WNDPROC As Long = -4 Private Const CBN_DROPDOWN As Long = 7 Private Const WM_LBUTTONDOWN As Long = &H201 Private Const WM_KEYDOWN As Long = &H100 Private Const VK_F4 As Long = &H73Private Declare Function CallWindowProc _ Lib "user32" Alias "CallWindowProcA" _ (ByVal lpPrevWndFunc As Long, _ ByVal hwnd As Long, ByVal Msg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As LongPrivate Declare Function SendMessage Lib "user32" _ Alias "SendMessageA" _ (ByVal hwnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ lParam As Any) As LongPublic Declare Function SetWindowLong _ Lib "user32" Alias "SetWindowLongA" _ (ByVal hwnd As Long, ByVal nIndex As Long, _ ByVal dwNewLong As Long) As Long Public Sub Unhook(hwnd As Long)If defWinProc <> 0 ThenCall SetWindowLong(hwnd, _ GWL_WNDPROC, _ defWinProc) defWinProc = 0 End IfEnd Sub Public Sub Hook(hwnd As Long)'Don't hook twice or you will 'be unable to unhook it. If defWinProc = 0 ThendefWinProc = SetWindowLong(hwnd, _ GWL_WNDPROC, _ AddressOf WindowProc)End IfEnd Sub Public Function WindowProc(ByVal hwnd As Long, _ ByVal uMsg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long'only if the window is the combo box... If hwnd = Form1.Combo1.hwnd ThenSelect Case uMsgCase CBN_DROPDOWN 'the list box of a combo 'box is about to be made visible.'return 1 to indicate we ate the message WindowProc = 1Case WM_KEYDOWN 'prevent the F4 key from showing 'the combo's listIf wParam = VK_F4 Then'set up the parameters as though a 'mouse click occurred on the combo, 'and call this routine again Call WindowProc(hwnd, WM_LBUTTONDOWN, 1, 1000)Else'there's nothing to do keyboard-wise 'with the combo, so return 1 to 'indicate we ate the message WindowProc = 1End IfCase WM_LBUTTONDOWN 'process mouse clicks'if the listview is hidden, position and show it If Form1.ListView1.Visible = False ThenWith Form1 .ListView1.Left = .Combo1.Left .ListView1.Width = .Combo1.Width .ListView1.Top = .Combo1.Top + .Combo1.Height + 1 .ListView1.Visible = True .ListView1.SetFocus End WithElse'the listview must be visible, so hide it Form1.ListView1.Visible = False End If'return 1 to indicate we processed the message WindowProc = 1Case Else'call the default window handler WindowProc = CallWindowProc(defWinProc, _ hwnd, _ uMsg, _ wParam, _ lParam)End SelectEnd If 'If hwnd = Form1.Combo1.hwndEnd Function===='In a form, add a combo box, a listview and three command buttons===== Option ExplicitPrivate bKeepOpen As BooleanPrivate Sub Form_Load()Dim c As Long Dim chd As ColumnHeader Dim itmx As ListItem'Add some dummy data to the listview and hide With ListView1Set chd = .ColumnHeaders.Add(, , "Name", 1000) Set chd = .ColumnHeaders.Add(, , "Col 2", 1000) Set chd = .ColumnHeaders.Add(, , "Col 3", 1000) Set chd = .ColumnHeaders.Add(, , "Col 4", 600)For c = 1 To 15 Set itmx = .ListItems.Add(, , Screen.Fonts(c)) itmx.SubItems(1) = "screen" itmx.SubItems(2) = "font" itmx.SubItems(3) = c Next.View = lvwReport .FullRowSelect = True 'vb6 only .BorderStyle = ccNone .Visible = FalseEnd With'set inital state of command buttons Command1.Caption = "hook combo" Command2.Caption = "unhook combo" Command3.Caption = "unhook && end" Command1.Enabled = True Command2.Enabled = False End Sub Private Sub Command1_Click()If defWinProc = 0 Then Hook Combo1.hwnd Command1.Enabled = False Command2.Enabled = True End IfEnd Sub Private Sub Command2_Click()'unhook the combo If defWinProc <> 0 Then Unhook Combo1.hwnd defWinProc = 0 Command1.Enabled = True Command2.Enabled = False End IfEnd Sub Private Sub Command3_Click()Unload MeEnd Sub Private Sub Form_Unload(Cancel As Integer)If defWinProc <> 0 Then Unhook Combo1.hwndEnd Sub Private Sub List1_KeyDown(KeyCode As Integer, Shift As Integer)'set flag to allow arrow and enter 'keys to simulate behaviour of normal 'combo bKeepOpen = TrueEnd Sub Private Sub List1_KeyPress(KeyAscii As Integer)'set flag to allow arrow and enter 'keys to simulate behaviour of normal 'combo If KeyAscii = vbKeyReturn Then'simulate selecting item with enter bKeepOpen = False Call ListView1_Click Else'alpha or arrow keys being used, 'so keep open bKeepOpen = TrueEnd IfEnd Sub Private Sub ListView1_Click()Dim itmx As ListItemIf ListView1.ListItems.Count > 0 ThenSet itmx = ListView1.SelectedItem'For a style 0 combo, you can not assign 'to the Text property from within the click 'event, so the selected item must be 'added' 'as the only combo item, and selected using 'its listindex property. ' 'For a style 2 combo, the text property 'can't be set unless there is an exact 'match to a list item, so again we fake it 'by adding the selection to the combo and 'selecting it. ' 'Finally, since the tabs can't be used 'in the combo's edit window, as it doesn't 'support tabstops either, on selection we'll 'display the main listview item With Combo1 .Clear .AddItem itmx.Text .ListIndex = 0 End WithEnd IfIf bKeepOpen = False Then ListView1.Visible = False Combo1.SetFocus End IfEnd Sub =====
要自动隐藏 下一代码有此原理:Form1: Sub Form_Load() 'Store handle to this form's window gHW = Me.hWnd 'Call procedure to begin capturing messages for this window Hook End Sub Private Sub Form_Unload(Cancel As Integer) 'Call procedure to stop intercepting the messages for this window Unhook End Subthe module: Option Explicit Declare Function CallWindowProc Lib "user32" Alias _ "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _ ByVal hwnd As Long, ByVal Msg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _ (ByVal hwnd As Long, ByVal nIndex As Long, _ ByVal dwNewLong As Long) As Long Public Const WM_ACTIVATEAPP = &H1C Public Const GWL_WNDPROC = -4 Global lpPrevWndProc As Long Global gHW As Long Public Sub Hook() 'Establish a hook to capture messages to this window lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, _ AddressOf WindowProc) End Sub Public Sub Unhook() Dim temp As Long 'Reset the message handler for this window temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc) End Sub Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long 'Check for the ActivateApp message If uMsg = WM_ACTIVATEAPP Then 'Check to see if Activating the application If wParam <> 0 Then 'Application Received Focus Form1.Caption = "Focus Restored" Else 'Application Lost Focus Form1.Caption = "Focus Lost" End If End If 'Pass message on to the original window message handler WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, _ lParam) End Function
目标是它的颜色不变灰:用下列两个函数: Public Declare Function ShowWindow Lib "user32" Alias "ShowWindow" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long '第二个参数的常量,可用 Or 逻辑相加 Public Const SW_NORMAL = 1 Public Const SW_RESTORE = 9 Public Const SW_SHOWNOACTIVATE = 4Public Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long '第二个参数 Const HWND_TOPMOST = -1 '最后一个参数的常量 Public Const SWP_NOMOVE = &H2 Public Const SWP_NOSIZE = &H1 Public Const SWP_NOZORDER = &H4如果仍是这样,则我再想办法!
问题已经解决:: 请用: Private Declare Function SetParent Lib "user32" Alias "SetParent" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long 设定下拉窗口的父窗口为控件所在窗口即可!你再查一下,这样, 上面的自动消失代码是否仍有效!!!!!!
ComboBox实际是一个Windows预定义的一个窗口类,你可以用SetWindowLong重新设定它的窗口函数,用自己的代替,然后在自己的窗口函数中用GDI函数自己画出需要的东西,最后别忘了调用DefWindowProc,否则……
我曾用c SDK只作过一些简单的东西。对于用setWindowLong重新设定它的窗口函数不知怎样作,劳您费点心给点代码好吗?!
不胜感激!!!
谢谢!
[email protected]
=====
Option Explicit
Public defWinProc As LongPublic Const GWL_WNDPROC As Long = -4
Private Const CBN_DROPDOWN As Long = 7
Private Const WM_LBUTTONDOWN As Long = &H201
Private Const WM_KEYDOWN As Long = &H100
Private Const VK_F4 As Long = &H73Private Declare Function CallWindowProc _
Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, _
ByVal hwnd As Long, ByVal Msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As LongPrivate Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" _
(ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As LongPublic Declare Function SetWindowLong _
Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Public Sub Unhook(hwnd As Long)If defWinProc <> 0 ThenCall SetWindowLong(hwnd, _
GWL_WNDPROC, _
defWinProc)
defWinProc = 0
End IfEnd Sub
Public Sub Hook(hwnd As Long)'Don't hook twice or you will
'be unable to unhook it.
If defWinProc = 0 ThendefWinProc = SetWindowLong(hwnd, _
GWL_WNDPROC, _
AddressOf WindowProc)End IfEnd Sub
Public Function WindowProc(ByVal hwnd As Long, _
ByVal uMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long'only if the window is the combo box...
If hwnd = Form1.Combo1.hwnd ThenSelect Case uMsgCase CBN_DROPDOWN 'the list box of a combo
'box is about to be made visible.'return 1 to indicate we ate the message
WindowProc = 1Case WM_KEYDOWN 'prevent the F4 key from showing
'the combo's listIf wParam = VK_F4 Then'set up the parameters as though a
'mouse click occurred on the combo,
'and call this routine again
Call WindowProc(hwnd, WM_LBUTTONDOWN, 1, 1000)Else'there's nothing to do keyboard-wise
'with the combo, so return 1 to
'indicate we ate the message
WindowProc = 1End IfCase WM_LBUTTONDOWN 'process mouse clicks'if the listview is hidden, position and show it
If Form1.ListView1.Visible = False ThenWith Form1
.ListView1.Left = .Combo1.Left
.ListView1.Width = .Combo1.Width
.ListView1.Top = .Combo1.Top + .Combo1.Height + 1
.ListView1.Visible = True
.ListView1.SetFocus
End WithElse'the listview must be visible, so hide it
Form1.ListView1.Visible = False
End If'return 1 to indicate we processed the message
WindowProc = 1Case Else'call the default window handler
WindowProc = CallWindowProc(defWinProc, _
hwnd, _
uMsg, _
wParam, _
lParam)End SelectEnd If 'If hwnd = Form1.Combo1.hwndEnd Function===='In a form, add a combo box, a listview and three command buttons=====
Option ExplicitPrivate bKeepOpen As BooleanPrivate Sub Form_Load()Dim c As Long
Dim chd As ColumnHeader
Dim itmx As ListItem'Add some dummy data to the listview and hide
With ListView1Set chd = .ColumnHeaders.Add(, , "Name", 1000)
Set chd = .ColumnHeaders.Add(, , "Col 2", 1000)
Set chd = .ColumnHeaders.Add(, , "Col 3", 1000)
Set chd = .ColumnHeaders.Add(, , "Col 4", 600)For c = 1 To 15
Set itmx = .ListItems.Add(, , Screen.Fonts(c))
itmx.SubItems(1) = "screen"
itmx.SubItems(2) = "font"
itmx.SubItems(3) = c
Next.View = lvwReport
.FullRowSelect = True 'vb6 only
.BorderStyle = ccNone
.Visible = FalseEnd With'set inital state of command buttons
Command1.Caption = "hook combo"
Command2.Caption = "unhook combo"
Command3.Caption = "unhook && end"
Command1.Enabled = True
Command2.Enabled = False
End Sub
Private Sub Command1_Click()If defWinProc = 0 Then
Hook Combo1.hwnd
Command1.Enabled = False
Command2.Enabled = True
End IfEnd Sub
Private Sub Command2_Click()'unhook the combo
If defWinProc <> 0 Then
Unhook Combo1.hwnd
defWinProc = 0
Command1.Enabled = True
Command2.Enabled = False
End IfEnd Sub
Private Sub Command3_Click()Unload MeEnd Sub
Private Sub Form_Unload(Cancel As Integer)If defWinProc <> 0 Then Unhook Combo1.hwndEnd Sub
Private Sub List1_KeyDown(KeyCode As Integer, Shift As Integer)'set flag to allow arrow and enter
'keys to simulate behaviour of normal
'combo
bKeepOpen = TrueEnd Sub
Private Sub List1_KeyPress(KeyAscii As Integer)'set flag to allow arrow and enter
'keys to simulate behaviour of normal
'combo
If KeyAscii = vbKeyReturn Then'simulate selecting item with enter
bKeepOpen = False
Call ListView1_Click
Else'alpha or arrow keys being used,
'so keep open
bKeepOpen = TrueEnd IfEnd Sub
Private Sub ListView1_Click()Dim itmx As ListItemIf ListView1.ListItems.Count > 0 ThenSet itmx = ListView1.SelectedItem'For a style 0 combo, you can not assign
'to the Text property from within the click
'event, so the selected item must be 'added'
'as the only combo item, and selected using
'its listindex property.
'
'For a style 2 combo, the text property
'can't be set unless there is an exact
'match to a list item, so again we fake it
'by adding the selection to the combo and
'selecting it.
'
'Finally, since the tabs can't be used
'in the combo's edit window, as it doesn't
'support tabstops either, on selection we'll
'display the main listview item
With Combo1
.Clear
.AddItem itmx.Text
.ListIndex = 0
End WithEnd IfIf bKeepOpen = False Then
ListView1.Visible = False
Combo1.SetFocus
End IfEnd Sub
=====
下一代码有此原理:Form1: Sub Form_Load()
'Store handle to this form's window
gHW = Me.hWnd 'Call procedure to begin capturing messages for this window
Hook
End Sub Private Sub Form_Unload(Cancel As Integer)
'Call procedure to stop intercepting the messages for this window
Unhook
End Subthe module: Option Explicit Declare Function CallWindowProc Lib "user32" Alias _
"CallWindowProcA" (ByVal lpPrevWndFunc As Long, _
ByVal hwnd As Long, ByVal Msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long Public Const WM_ACTIVATEAPP = &H1C
Public Const GWL_WNDPROC = -4 Global lpPrevWndProc As Long
Global gHW As Long Public Sub Hook()
'Establish a hook to capture messages to this window
lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, _
AddressOf WindowProc)
End Sub Public Sub Unhook()
Dim temp As Long 'Reset the message handler for this window
temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)
End Sub Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
'Check for the ActivateApp message If uMsg = WM_ACTIVATEAPP Then
'Check to see if Activating the application
If wParam <> 0 Then
'Application Received Focus
Form1.Caption = "Focus Restored"
Else
'Application Lost Focus
Form1.Caption = "Focus Lost"
End If
End If 'Pass message on to the original window message handler
WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, _
lParam)
End Function
请参考:
http://www.csdn.net/expert/topic/442/442025.shtm
所以我决定再给贴子加50分,希望高手再赐教!
(巴顿:暂时还没有加分,请再等一等,见凉!)
Public Declare Function ShowWindow Lib "user32" Alias "ShowWindow" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
'第二个参数的常量,可用 Or 逻辑相加
Public Const SW_NORMAL = 1
Public Const SW_RESTORE = 9
Public Const SW_SHOWNOACTIVATE = 4Public Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
'第二个参数
Const HWND_TOPMOST = -1
'最后一个参数的常量
Public Const SWP_NOMOVE = &H2
Public Const SWP_NOSIZE = &H1
Public Const SWP_NOZORDER = &H4如果仍是这样,则我再想办法!
http://www.csdn.net/expert/topic/484/484431.shtm
http://www.csdn.net/expert/topic/487/487941.shtm
(2002-1-21 17:52:03) 的方法不行,因为mouse点击时一个窗口会activated 另一个则deactivated另外,同时再请看一下这个贴子,我已经没法回复了
http://www.csdn.net/expert/TopicView.asp?id=484448
谢谢
你能够运行的代码能否给我发一个,我也一直想做这个控件,想用TREEVIEW代替弹出的LISTBOX。但是遇到了好多问题无法解决。能把代码给我参考一下吗。
[email protected]
问题是我现在的关键问题还没解决(没有达到标准combo的效果),你帮我up吧!目前的问题---遗憾:如果在本窗体空白的地方点击mouse,listview1也能自动消失就好了,而且我曾用一个form代替listview,用setparent将它设为子窗口,当这个form弹出时父窗口的标题栏的颜色变灰,我的目标是它的颜色不变灰,一切效果就象标准combo一样。
请用:
Private Declare Function SetParent Lib "user32" Alias "SetParent" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
设定下拉窗口的父窗口为控件所在窗口即可!你再查一下,这样,
上面的自动消失代码是否仍有效!!!!!!
继续跟贴!给分!
TO:Bardo
(2002-1-21 17:52:03) 的方法不行,因为mouse点击时一个窗口会activated 另一个则deactivated另外,同时再请看一下这个贴子,我已经没法回复了http://www.csdn.net/expert/TopicView.asp?id=484448
谢谢 这个贴子我已给了新的回复!请注意!
http://www.csdn.net/Expert/topic/484/484448.shtm
TO:Bardo
(2002-1-21 17:52:03) 的方法不行,因为mouse点击时一个窗口会activated 另一个则deactivated另外,同时再请看一下这个贴子,我已经没法回复了http://www.csdn.net/expert/TopicView.asp?id=484448
谢谢 这个贴子我已给了新的回复!请注意!
http://www.csdn.net/Expert/topic/484/484448.shtm
TO:Bardo
(2002-1-21 17:52:03) 的方法不行,因为mouse点击时一个窗口会activated 另一个则deactivated另外,同时再请看一下这个贴子,我已经没法回复了http://www.csdn.net/expert/TopicView.asp?id=484448
谢谢 这个贴子我已给了新的回复!请注意!
http://www.csdn.net/Expert/topic/484/484448.shtm
up
同时,如果做成activeX,则必须要用窗口,可以仿制IME窗口,
但须要找到对应的函数。
思路是,要在Windows中注册新的窗口类,参看CreateWindowEx函数的帮助。
然后再用那儿的代码显示出来。须要明了这个新类的参数一部分要与Combo下拉list或Edit的共有参数相同。(Combo的下拉有List与edit两种)
你可以用Spy查看常见Combo与Office中的Combo的子窗口的参数。前者是list,后者是Edit当然,
还要解决的是如何将这个建好的下拉窗体映射到你注册的窗口类中。操作注册表要写到程序代码中。工作量较大,主要是以前都未做过,所以一下子不可能有代码给你!抱歉!
因为你不可能将整个控件作为新的窗口类注册。
因为注册窗口类,所以下拉显示时,只是让数值窗口失去焦点。原理就是这样!
因为你不可能将整个控件作为新的窗口类注册。
因为是注册窗口类,即二者已绑定,所以下拉显示时,只是让数值窗口失去焦点。原理就是这样!
原来在combo中list是它的子窗口!