Hola amigos,
Muy buenos días, espero que esten bien...
Necesito la ayuda para crear en VB6 un combo box con "separador" de texto, no seleccionable...
¿Que es esto?
Sería algo como lo siguiente:
-comidas-
pizza
pollo
choripan
-bebidas-
agua
cerveza
gaseosa
vino
Donde "-comidas-" y "-bebidas-" sí se puede ver, pero no es seleccionable... (esto sirve, obviamente, como separador de items)
El asunto que estoy buscando en Internet, pero no encuentro como hacer esto en VB6... aunque sí se puede hacer en VB.NET... pero no me sirve...
También se puede hacer eso mismo en HTML... pero tampoco sirve... ya que esto es VB6...
Alguien sabe cómo hacer eso??
Espero que me puedan ayudar ya que aparte, es interesante para cualquier aplicación...
Es más... seguramente alguien ya lo haya implementado o visto alguna vez...
Desde ya muchas gracias,
Un Saludo
.
Una solucion sencilla es que les pongas un tag a los nodos seleccionables y a los que no los dejas tal cual (Sin tocarlos) y al momento del clic Cancelarlo (Dejando el click en el Nodo Madre es decir el que tiene el Tag con algo)
Seria algo asi
Desde el Item donde se dio un clic ir en reversa buscando el item que tiene tag (este seria el Nodo seleccionable!¡.)
Me parece que de igual forma se puede hacer con SendMessage, pero ignoro el como!¡.
Dulces Lunas!¡.
hola, es un verdadero quilombo hacer eso, mas aun si lo queres hacer desde el el combobox de vb tenes que hookear la aplicación esperando que se cree la ventana "ComboLBox" para poder cambiar su estilo a LBS_OWNERDRAWFIXED despues subclasificar esa ventana y redibujar el control y elminar algunos mensajes, mas facil es crear directamente el control con CreateWindowEx y hacer el subclasificado.
de todas formas es algo muy abanzado si es que no tienes los conocimientos necesarios.
no se que tantas necesidad tengas de hacer eso o cual es la situación, pero creo que tenes opciones mas sencillas como por ejemplo crear un formulario con algunos labels o utilizar un menu. o un treeview. un poco de imaginación
Saludos.
Hola Leandro,
Gracias por tu mensaje, tomo tu palabra, porque sé que la tenes más clara que yo en estos temas, años luz... voy a buscar alternativas a esta forma de presentar y desplegar las opciones que necesito...
gracias!!
Un saludo
ProgramadorVB (Hugo)
o sino usa "Frame" ;)
Ejemplo:
(http://r.i.elhacker.net/cache?url=http://www.recursosvisualbasic.com.ar/htm/tutoriales/img/control_frame.gif)
El frame es lo que dice "Sumar Los Datos"..
Osea, Ese "Cuadrado" Que Contiene Cosas :3
Responde que me pongo nervioso :¬¬
No hace falta ser un genio para saer que lo que dices pedro_boca no tiene nada que ver con lo que pide...
Pd: Eres el rey del doble post... :¬¬
DoEvents¡! :P
Cita de: *PsYkE1* en 23 Agosto 2010, 01:03 AM
No hace falta ser un genio para saer que lo que dices pedro_boca no tiene nada que ver con lo que pide...
ajjaja , pero igual le sirve XD
porq no pone un combo box(o lo que quiera) adentro del frame ¬¬
Cita de: *PsYkE1* en 23 Agosto 2010, 01:03 AM
Pd: Eres el rey del doble post... :¬¬
;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D ;D
Hola,
Gracias por los comentarios... pero quiero seguir en el tema principal... el tema del combobox...
Alguien más sabe como hacer eso que pido??
Desde ya gracias!!!
Cita de: ProgramadorVB en 23 Agosto 2010, 03:27 AM
Hola,
Gracias por los comentarios... pero quiero seguir en el tema principal... el tema del combobox...
Alguien más sabe como hacer eso que pido??
Desde ya gracias!!!
No probaste lo que mencionó BlackZeroX??? seria mas o menos asi:
Private Sub Combo1_Click()
If InStr(Combo1.Text, "----") Then
Dim i As Integer
For i = 1 To Combo1.ListCount
If Not InStr(Combo1.List(i), "----") Then
Combo1.Text = Combo1.List(i)
Exit Sub
End If
Next
End If
End Sub
Private Sub Form_Load()
Combo1.AddItem ("----comidas----")
Combo1.AddItem ("pizza")
Combo1.AddItem ("pollo")
Combo1.AddItem ("choripan")
Combo1.AddItem ("----bebidas----")
Combo1.AddItem ("agua")
Combo1.AddItem ("cerveza")
Combo1.AddItem ("gaseosa")
Combo1.AddItem ("vino")
End Sub
Estudialo y adaptalo a tu caso.
Saludos
la opcion de leandro seria lo mejor, aparte de eso, implementas un form sin bordes y cuando se hace click en el combo lo muestras como si fuese el dropdown original. de esta forma puedes personalizarlo 100%. incluso si en el segundo form metes un treeview vas a poder tener items con subitems dentro ;).
hola amigos... muy buenos días a todos...
rob1104,
Sí ya probé tu ejemplo... es bueno... pero no es exactamente lo que me gustaría usar... igualmente te agradezco por tu ayuda, de verdad.
ctlon,
Lo de Leandro es poderoso, sería LA SOLUCIÓN... pero no tengo ni la capacidad... ni el tiempo físico para hacerlo yo mismo... ya que me llevaría varios días, con suerte...
Igualmente, estoy pensando (publiqué pensandolo desde el principio)... en que alguien sepa donde encontrar esa solución, ya resuelta... ya que seguramente eso que quiero hacer... o algo muy similar... ya fue creado por otro programador, en este mismo lenguaje VB6... no creo que esa ocurrencia, sea exclusiva mia... ni que eso no exista publicado en internet al día de hoy... el asunto es... que no lo pude encontrar... puse varios terminos de busqueda alternativos... y nada... nada para este lenguaje.
Desde ya muchas gracias... si acaso, accidentalmente encuentro la solución... la publicaré...
Un saludo!!!!
Buen día, muchacho(a):
Prueba con este sencillo código y si no te sirve (o no te gusta), lo siento, no puedo hacer más por tí.
Para correrlo necesitas un Combo1 y un Text1. En el combo seleccionas la comida o bebida y en el Text te muestra el precio.
Option Explicit
Dim precios As New Collection
Private Sub Combo1_Click()
Text1.Text = precios.Item(Combo1.ListIndex + 1)
If Val(Text1.Text) = 0 Then
Text1.Text = " - "
End If
End Sub
Private Sub Form_Load()
Text1.Text = ""
Combo1.AddItem ("----comidas----")
precios.Add ""
Combo1.AddItem ("pizza")
precios.Add 110
Combo1.AddItem ("pollo")
precios.Add 65
Combo1.AddItem ("choripan")
precios.Add 20
Combo1.AddItem ("----bebidas----")
precios.Add ""
Combo1.AddItem ("agua")
precios.Add 8.5
Combo1.AddItem ("cerveza")
precios.Add 15
Combo1.AddItem ("gaseosa")
precios.Add 10.5
Combo1.AddItem ("vino")
precios.Add 30
Combo1.ListIndex = 0
End Sub
Saludos.
Tokes,
Excelente aporte, muchas gracias...
Sin más comentarios...
Un saludo
Es mejor SubClasificar el ComboBox asi evitamos un PArpadeo como el codigo siguente, es algo cutre pero bueno de algo te servira!¡.
En un Modulo de Clase
Cls_CmbBox.cls
Option Explicit
Public WithEvents CmbBox As ComboBox
Public StrToVerific As String
Public StrExplicit As Boolean
Private SwitchErr As Boolean
Event ErrorSel()
Private Sub CmbBox_click()
Dim CmbBox_Index As Long
Dim LenV As Long
If SwitchErr = False Then SwitchErr = Not SwitchErr: Exit Sub
With CmbBox
LenV = Len(StrToVerific)
If LenV <= 0 Then Exit Sub
For CmbBox_Index = .ListIndex To 1 Step -1
If Len(.List(CmbBox_Index)) >= LenV Then
If StrComp(Left$(.List(CmbBox_Index), Len(StrToVerific)), StrToVerific, Abs(Not StrExplicit)) = 0 Then
' CmbBox.Text = .List(CmbBox_Index)
.ListIndex = CmbBox_Index ' // "es lo mismo que la linea de arriba" solo que rehubica el item seleccionado
Exit For
End If
End If
Next CmbBox_Index
If CmbBox_Index <= 0 Then RaiseEvent ErrorSel
End With
End Sub
Codigo prueba en un Form.
Agrega run ComboBox con nombre Combo1
Option Explicit
Private WithEvents ClsCmbBox As Cls_CmbBox
Private Sub ClsCmbBox_ErrorSel()
Caption = "Error"
End Sub
Private Sub Combo1_Click()
Caption = Combo1.Text
End Sub
Private Sub Form_Load()
Set ClsCmbBox = New Cls_CmbBox
With ClsCmbBox
Set .CmbBox = Combo1
.StrExplicit = True
.StrToVerific = "----"
End With
Combo1.AddItem ("Miguel")
Combo1.AddItem ("Angel")
Combo1.AddItem ("Ortega")
Combo1.AddItem ("Avila")
Combo1.AddItem ("----comidas----")
Combo1.AddItem ("pizza")
Combo1.AddItem ("pollo")
Combo1.AddItem ("choripan")
Combo1.AddItem ("----bebidas----")
Combo1.AddItem ("agua")
Combo1.AddItem ("cerveza")
Combo1.AddItem ("gaseosa")
Combo1.AddItem ("vino")
Combo1.ListIndex = 0
End Sub
Dulces Lunas!¡.
o tambien guardar en algun lado los items que no podes seleccionar y cuando el usuario los seleccione simplemente no haces nada...
aca te paso un ejemplo que se me ocurrio, el ejemplo principal pinta los items de diferentes colores, en este ejemplo pinte los deshabilitados de color gris...probalo y me contas.
En un Modulo (bas)
Option Explicit
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type DRAWITEMSTRUCT
CtlType As Long
CtlID As Long
itemID As Long
itemAction As Long
itemState As Long
hwndItem As Long
hdc As Long
rcItem As RECT
itemData As Long
End Type
Private Type CWPSTRUCT
lParam As Long
wParam As Long
message As Long
hWnd As Long
End Type
Private Type CREATESTRUCT
lpCreateParams As Long
hInstance As Long
hMenu As Long
hWndParent As Long
cy As Long
cx As Long
y As Long
x As Long
style As Long
lpszName As Long
lpszClass As Long
ExStyle As Long
End Type
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private 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
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function SetBkColor Lib "gdi32" (ByVal hdc As Long, ByVal crColor As Long) As Long
Private Declare Function SetTextColor Lib "gdi32" (ByVal hdc As Long, ByVal crColor As Long) As Long
Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
Private Declare Function GetSysColor Lib "user32" (ByVal nIndex As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function FillRect Lib "user32" (ByVal hdc As Long, lpRect As RECT, ByVal hBrush As Long) As Long
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
Private Const WH_CALLWNDPROC = 4
Private Const CBS_OWNERDRAWVARIABLE = &H20&
Private Const CB_GETLBTEXT = &H148
Private Const COLOR_HIGHLIGHT = 13
Private Const COLOR_HIGHLIGHTTEXT = 14
Private Const COLOR_WINDOW = 5
Private Const COLOR_WINDOWTEXT = 8
Private Const GWL_WNDPROC = (-4)
Private Const GWL_STYLE = (-16)
Private Const ODS_SELECTED = &H1
Private Const ODT_COMBOBOX = 3
Private Const WM_CREATE = &H1
Private Const WM_DRAWITEM = &H2B
Private lPrevWndProc As Long
Private lHook As Long
Private lSubCombo As Long
Sub Main()
lHook = SetWindowsHookEx(WH_CALLWNDPROC, AddressOf HookApp, App.hInstance, App.ThreadID)
Form1.Show
Call UnhookWindowsHookEx(lHook)
End Sub
Public Sub SubClassForm(ByVal hWnd As Long)
lPrevWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf SubClassedForm)
End Sub
Public Sub RemoveSubClassing(ByVal hWnd As Long)
Call SetWindowLong(hWnd, GWL_WNDPROC, lPrevWndProc)
End Sub
Public Function SubClassedForm(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim tItem As DRAWITEMSTRUCT
Dim sItem As String
Dim lBackBrush As Long
If Msg = WM_DRAWITEM Then
Call CopyMemory(tItem, ByVal lParam, Len(tItem))
If tItem.CtlType = ODT_COMBOBOX Then
sItem = Space(255)
Call SendMessage(tItem.hwndItem, CB_GETLBTEXT, tItem.itemID, ByVal sItem)
sItem = Left(sItem, InStr(sItem, Chr(0)) - 1)
If (tItem.itemState And ODS_SELECTED) Then
lBackBrush = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT))
Call SetBkColor(tItem.hdc, GetSysColor(COLOR_HIGHLIGHT))
Call SetTextColor(tItem.hdc, GetSysColor(COLOR_HIGHLIGHTTEXT))
Else
lBackBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW))
Call SetBkColor(tItem.hdc, GetSysColor(COLOR_WINDOW))
Call SetTextColor(tItem.hdc, tItem.itemData)
End If
FillRect tItem.hdc, tItem.rcItem, lBackBrush
TextOut tItem.hdc, tItem.rcItem.Left, tItem.rcItem.Top, ByVal sItem, Len(sItem)
SubClassedForm = 0
Exit Function
End If
End If
SubClassedForm = CallWindowProc(lPrevWndProc, hWnd, Msg, wParam, lParam)
End Function
Private Function HookApp(ByVal lHookID As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim tCWP As CWPSTRUCT
Dim sClass As String
Call CopyMemory(tCWP, ByVal lParam, Len(tCWP))
If tCWP.message = WM_CREATE Then
sClass = Space(128)
Call GetClassName(tCWP.hWnd, ByVal sClass, 128)
sClass = Left(sClass, InStr(sClass, Chr(0)) - 1)
If sClass = "ComboLBox" Then
lSubCombo = SetWindowLong(tCWP.hWnd, GWL_WNDPROC, AddressOf SubComboCreate)
End If
End If
HookApp = CallNextHookEx(lHook, lHookID, wParam, ByVal lParam)
End Function
Private Function SubComboCreate(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim tCreate As CREATESTRUCT
If Msg = WM_CREATE Then
Call CopyMemory(tCreate, ByVal lParam, Len(tCreate))
tCreate.style = tCreate.style Or CBS_OWNERDRAWVARIABLE
Call CopyMemory(ByVal lParam, tCreate, Len(tCreate))
Call SetWindowLong(hWnd, GWL_STYLE, tCreate.style)
Call SetWindowLong(hWnd, GWL_WNDPROC, lSubCombo)
End If
SubComboCreate = CallWindowProc(lSubCombo, hWnd, Msg, wParam, lParam)
End Function
En el Formulario, con un combobox llamado Combo1
Option Explicit
Dim vIndiceAnterior As Long
Private Sub Combo1_Change()
Call Combo1_Click
End Sub
Private Sub Combo1_Click()
Select Case Combo1.ListIndex
Case 2, 4, 6
MsgBox "Item Deshabilitado"
Combo1.ListIndex = vIndiceAnterior
Case Else
Me.Caption = "Item Seleccionado"
vIndiceAnterior = Combo1.ListIndex
End Select
End Sub
Private Sub Form_Load()
With Combo1
.AddItem ("Item Normal 1")
.itemData(.NewIndex) = vbBlack
.AddItem ("Item Normal 2")
.itemData(.NewIndex) = vbBlack
.AddItem ("Item Deshabilitado 1")
.itemData(.NewIndex) = &HE0E0E0
.AddItem ("Item Normal 3")
.itemData(.NewIndex) = vbBlack
.AddItem ("Item Deshabilitado 3")
.itemData(.NewIndex) = &HE0E0E0
.AddItem ("Item Normal 4")
.itemData(.NewIndex) = vbBlack
.AddItem ("Item Deshabilitado 3")
.itemData(.NewIndex) = &HE0E0E0
.ListIndex = 0
vIndiceAnterior = .ListIndex
End With
Call SubClassForm(Me.hWnd)
End Sub
Private Sub Form_Unload(Cancel As Integer)
Call RemoveSubClassing(Me.hWnd)
End Sub
saludos.
Jaja, me parece mucho esfuerzo y la verdad perdida de tiempo para una cosa de estetica y diseño. Pero bueno, cada quien tiene su forma de trabajar.
Suerte..
seba123neo,
;-) Impresionante... te felicito y agradezco mucho por tu esfuerzo...
Chicos, gracias por todo, doy por terminado este tema...
;D Un saludo y suerte!!!
Cita de: rob1104 en 24 Agosto 2010, 07:52 AM
Jaja, me parece mucho esfuerzo y la verdad perdida de tiempo para una cosa de estetica y diseño. Pero bueno, cada quien tiene su forma de trabajar.
Suerte..
He... gracias por el comentario, pero la verdad que no tiene valor de uso...
Cita de: ProgramadorVB en 26 Agosto 2010, 21:29 PM
Cita de: rob1104 en 24 Agosto 2010, 07:52 AM
Jaja, me parece mucho esfuerzo y la verdad perdida de tiempo para una cosa de estetica y diseño. Pero bueno, cada quien tiene su forma de trabajar.
Suerte..
He... gracias por el comentario, pero la verdad que no tiene valor de uso...
Eso dices ahora, pero espero nunca te encuentres en una situación contrareloj donde la funcionalidad sea más importante que el diseño. Mientras tanto puedes perder días en mejorar las situaciones secundarias de los programas.
Saludos
Cita de: rob1104 en 24 Agosto 2010, 07:52 AM
Jaja, me parece mucho esfuerzo y la verdad perdida de tiempo para una cosa de estetica y diseño. Pero bueno, cada quien tiene su forma de trabajar.
Suerte..
Te Admiro. :laugh:
Jaja, tenes razon XD
rob1104,
Muy bien, aceptaste bastante bien la crítica... te felicito... pero sí... me encuentro contra reloj... ya que mis ahorros para auto-financiarme se me están terminando y tengo que... no solo sacar al mercado un producto terminado y funcional... sino que también generar ventas...
O sea, que esté ganando tiempo publicando en este y otros 10 foros en español y otros tantos en inglés... no significa que este perdiendo tiempo... de echo... así gano mucho más tiempo... avanzo en paralelo... y gracias a este método de buscar y eventualmente pedir ayuda... hoy puedo decir que ya está terminado... solo falta crear la carta de ventas y publicarlo en... por ejemplo clickbank... para hacer una buena diferencia... todo un tema...
Esto es solo una pizca... no te confundas... no soy primerizo en esto... sin embargo me doy el permiso de publicar post como estos..
Un saludo y muchas gracias a todos...
PD: Doy por terminado este tema.