jueves, 5 de enero de 2006

Menú Nk reportándose :->

¡No puedo creerlo!

No le he puesto título al post, no sé qué pensar... qué hacer.

Vengo de revolcarme en el mueble tomado de los cabellos y pujar "ggggg" con una especie de chillido; mis músculos hicieron mucha fuerza, como si todo mi ser fuera a estallar.

Tiemblo, me manoseo los cabellos, todavía tengo la imagen en mi mente: hacía click en un CommandButton1 que creé hace 1 minuto y veía en el frmMain aparecer los menú de prueba que había creado.

Bien, la cosa es así:

Después de que escribí el post pasado hace (creo) no menos de media hora, seguí viendo mi código y pensando en cuál podía ser la función API para hacer aparecer mi barra de menús. Se me vino a la mente el que pudiera ser una función de entrada, digamos, una forma de crear el primer menú, pero no fue así.

Me pasé a la ventana de MSDN y di un vistazo a todas las "Menu Functions" hasta que vi una nada fuera de lo normal: SetMenu. Accedí a su descripción buscando datos en "Remark" que encontré:

"The window is redrawn to reflect the menu change.



The SetMenu function replaces the previous menu, if any, but it does  not destroy it. An application should call the DestroyMenu function to  accomplish this task."

"Uhmmm...", pensé y medio balbuceé. Entonces mi linea "   Call DrawMenuBar (hWnd)" no está mal, y si se supone que mi código para los menús está bien creado, significa que el problema no era eso, sino que mi Barra no se dibujaba... ¡lo que vengo diciéndome y escribiendo desde hace días! Pero aun así me sonó una explicación tonta, tan tonta como las explicaciones que me han llevado a quedarme desvelado y avanzar, así que hice un experimento:

Mi procedimiento para crear los menús está en el módulo modMenú.bas, como ya había dicho, y como mi proyecto inicia en SubMain para llamar al procedimiento del modMenú antes de crear el formulario, entonces pensé que quizá todo eso pasaba y no se dibujaba en el formulario. Creé un botón de comando Command1 en donde cayera (encima del RichTextBox) y en su evento _Click() le puse "Call DrawMenuBar(hWnd)". Lo ejecuté pero no sirvió, además, ¿por qué habría de servir, si tengo esa linea al final de otras en el evento _Resize()?

Bueno, no sirvió, pero de repente me surgió una idea algo más extravagante: Volver a llamar al procedimiento pero ya cuando esté pintado el Form, y para aplicar eso del reciclaje, pues usé el mismo botón de comando. El código quedó:

Private Sub Command1_Click()
Call Crear_Menús_Estándar
End Sub


(Lo hice a la carrera, pero así de desordenado con mis códigos no soy). Ejecuto y ¡oh sorpresa! Aparece mi menú "Nk" y sus submenús "a1" y "b1".

Sin pensarlo me levanté tieso de la silla y me fui al mueble a revolcar. Después de eso vine aquí, pero ahora vamos a testearlo y a escribir en el blog los apuntes, como todo un científico xD, y para que sepan que todo lo que anoto ocurre en tiempo real. (Lo guardo antes que nada :P).

¿Qué ocurre al hacer click en Command1?

Antes tenía una ToolBar llamada "Barra_de_Herramientas", pero por sospechas la cambié a un Label llamado igual. Pues bien, al crearse el menú, el Label y el RichTextBox se hacen un tantito pa'bajo y se crea el menú "Nk".

¿Qué ocurre su presiono más de una vez el Command1?
No aparecen más barras de menús ni menús, sino que, acorde con el texto citado de MSDN, la barra es redibujada en su mismo lugar, pero sin destruir las otras, que quedan invisibles e inabilitadas.

¿Qué ocurre si borramos el Label y reestablecemos nuevamente la ToolBar que tenía?
Veamos...Lo mismo: se hace para abajo.

Ahora tendré que buscar la forma de que se dibuje esa barra sin necesidad de oprimir el botón y haciendo lo posible por mantenerla en el procedimiento Main.

Comienzo a las 3:05 am...

3:09 am: pasé Call SetMenu(hWnd, hMenú) hasta abajo de SubMain, después de hacer el frmMain.Visible = True; para eso tuve que cambiar hMenú de Dim a Public en modMenú.bas

Por el momento eso es todo. Les voy a mostrar mi código en modMenú.bas:

'Handle de la Barra de Menús
Public hMenú As Long

'Handle para los Submenús
Dim hPopupMenu As Long
Private Function Crear_Menú(ByVal Valor As String, ByVal Tipo As mnuTipo, _
                           Máscara As mnuMáscara, Estado_Inicial As mnuEstado, _
                           ByVal Menú_Matriz As Long, ByVal Submenús As Long, _
                           Optional ByVal Posición As Long) As Long

  Dim Información_del_Menú As MENUITEMINFO

  With Información_del_Menú
       .cbSize = LenB(Información_del_Menú)
       .cch = Len(Valor)
       .dwTypeData = Valor
       .fMask = Máscara
       .fState = Estado_Inicial
       .fType = Tipo
       .hSubMenu = Submenús
  End With

  If Posición >= 0 Then Posición = GetMenuItemCount(Menú_Matriz) + 1

  Crear_Menú = InsertMenuItem(Menú_Matriz, Posición, True, Información_del_Menú)

  Call DrawMenuBar(hWnd)

End Function

Public Sub Crear_Menús_Estándar()
   
   hMenú = CreateMenu
   hPopupMenu = CreatePopupMenu
   
   Call Crear_Menú("a1", MFT_STRING, MIIM_TYPE, MFS_DEFAULT, hPopupMenu, vbNull)
   Call Crear_Menú("a2", MFT_STRING, MIIM_TYPE, MFS_DEFAULT, hPopupMenu, vbNull)
   Call Crear_Menú("Nk", MFT_STRING, MIIM_TYPE + MIIM_SUBMENU, MFS_DEFAULT, hMenú, hPopupMenu)
   
End Sub



No incluye declaraciones, ni tipos, ni nada más porque harían un buen de espacio.
Y en el SubMain de modMain.bas:

'Inicializar Menús
   Crear_Menús_Estándar
     
   'Y, después de un gran movimiento por parte del personal, abrimos el telón...
   frmMain.Visible = True
   
   'Haremos que aparezca la Barra de Menús
   Call SetMenu(hWnd, hMenú)


y en frmMain:

Private Sub Form_Resize()
   
   On Error Resume Next
   
   With Área_de_Trabajo
        .Top = Barra_de_Herramientas.Top + Barra_de_Herramientas.Height
        .Left = 0
        .Height = Me.Height - .Top - 1100
        .Width = Me.Width - 100
   End With
   
   Call DrawMenuBar(hWnd)
   
End Sub


Evidentemente esto no es todo. Ya resuelto este problema me creo capaz de editarlos, crear, esconder, darles valores, y lo del evento Click supongo que no será mucha lata, si a casi una desvelada como máximo (que me tarde muchísimo).

También falta perfeccionar mi código: haré que mi función de Crear_Menú() devuelva el ID del menú creado y no el valor Booleano de la API de si se pudo o no crear. También haré otro hPopupMenú_secundario o algo así para lo de "Archivo/Nuevo/Documento en blanco" y otras cosas por el estilo. Pero eso será mañana porque, me apena decirlo, me toca estudiar álgebra.

También voy a jugar Mythology hasta que amanezca y trataré de hacer actividades algo pesadas durante el día para mantenerme despierto (haber si puedo).

Lo que dije entre la primera y segunda desvelada lo sostengo ahora con más ahinco: crear menús con APIs no es difícil, lo que cuesta es descubrir la forma.

Hilsen



PD: Disculpen por las irregularidades del código pero en la edición no puedo empezar líneas con espacios; bueno, sí, pero eso requiere de un esfuerzo que por ahora no estoy dispuesto a realizar.




Editado Viernes 29 de Junio del 2007: Ya le corregí los aspectos del código haciéndolo más legible.

No hay comentarios.:

Publicar un comentario