News menu

HMG en Español

Moderator: Rathinagiri

Post Reply
User avatar
danielmaximiliano
Posts: 2716
Joined: Fri Apr 09, 2010 4:53 pm
Location: Argentina
Contact:

News menu

Post by danielmaximiliano »

Hola a todos:
uno de los participantes de este foro por telegram me envio un pequeño ejemplo donde habia un "menu" basado en la clasica opcion de usar imagenes pero se me ocurrio mostrarles otro tipo de menu diferentes al Menu moderno que implemente para Workspace .

se compila desde cmd : c:\hmg.3.6\build.bat MenuButtons.prg

Code: Select all

/*
 * MenuButtonsDemo.prg
 *
 * Ejemplos:
 *   1. Split Button    -> BS_SPLITBUTTON
 *   2. Drop-Down       -> BS_COMMANDLINK + men£ agregado manualmente
 *   3. Popup Menu      -> boton normal + TrackPopupMenuEx
 *   4. Flyout          -> ventana WS_POPUP personalizada
 *
 * Compilar:
 *   hbmk2 MenuButtonsDemo.prg <ruta>\hmg64.hbc -gtgui
 */

#include "hmg.ch"

FUNCTION Main()

   DEFINE WINDOW MainWindow AT 0, 0 WIDTH 720 HEIGHT 520 TITLE "HMG - Menus modernos Win32" MAIN ON INIT NativeMenuDemo_Init( GetFormHandle( "MainWindow" ) )

      @ 25, 25 LABEL TitleLabel VALUE "Controles de menu para Workspace" WIDTH 500 HEIGHT 30 FONT "Segoe UI" SIZE 15 BOLD

      @ 65, 25 LABEL SplitLabel VALUE "1. Split Button: zona principal + flecha independiente" WIDTH 600 HEIGHT 24 FONT "Segoe UI" SIZE 10

      @ 150, 25 LABEL CommandLabel VALUE "2. Command Link usado como Drop-Down completo" WIDTH 600 HEIGHT 24 FONT "Segoe UI" SIZE 10

      @ 270, 25 LABEL PopupLabel VALUE "3. Bot¢n normal que abre TrackPopupMenuEx" WIDTH 600 HEIGHT 24 FONT "Segoe UI" SIZE 10

      @ 350, 25 LABEL FlyoutLabel VALUE "4. Flyout: panel emergente personalizado" WIDTH 600 HEIGHT 24 FONT "Segoe UI" SIZE 10

      @ 455, 25 LABEL InfoLabel VALUE "Los cuatro controles inferiores son creados directamente con Win32." WIDTH 650 HEIGHT 24 FONT "Segoe UI" SIZE 9

   END WINDOW

   CENTER WINDOW MainWindow
   ACTIVATE WINDOW MainWindow

RETURN NIL


#pragma BEGINDUMP

#define _WIN32_WINNT 0x0601

#include <windows.h>
#include <commctrl.h>

#include "hbapi.h"

#ifndef BS_SPLITBUTTON
#define BS_SPLITBUTTON 0x0000000CL
#endif

#ifndef BS_COMMANDLINK
#define BS_COMMANDLINK 0x0000000EL
#endif

#ifndef BCN_FIRST
#define BCN_FIRST ( 0U - 1250U )
#endif

#ifndef BCN_DROPDOWN
#define BCN_DROPDOWN ( BCN_FIRST + 0x0002 )
#endif

#ifndef BCM_FIRST
#define BCM_FIRST 0x1600
#endif

#ifndef BCM_SETNOTE
#define BCM_SETNOTE ( BCM_FIRST + 0x0009 )
#endif

#define ID_SPLIT_BUTTON      1001
#define ID_COMMAND_BUTTON    1002
#define ID_POPUP_BUTTON      1003
#define ID_FLYOUT_BUTTON     1004

#define ID_MENU_NEW          2001
#define ID_MENU_OPEN         2002
#define ID_MENU_SAVE         2003
#define ID_MENU_BUILD        2004
#define ID_MENU_SETTINGS     2005

#define ID_FLYOUT_PROJECT    3001
#define ID_FLYOUT_TERMINAL   3002
#define ID_FLYOUT_CLOSE      3003

static HWND s_hMainWindow = NULL;
static HWND s_hSplitButton = NULL;
static HWND s_hCommandButton = NULL;
static HWND s_hPopupButton = NULL;
static HWND s_hFlyoutButton = NULL;
static HWND s_hFlyoutWindow = NULL;

static LRESULT CALLBACK MenuDemo_SubclassProc(
   HWND hWnd,
   UINT nMessage,
   WPARAM wParam,
   LPARAM lParam,
   UINT_PTR nSubclassId,
   DWORD_PTR nReferenceData
);

static LRESULT CALLBACK FlyoutWindowProc(
   HWND hWnd,
   UINT nMessage,
   WPARAM wParam,
   LPARAM lParam
);

static void MenuDemo_CreateControls( HWND hParent );
static void MenuDemo_ShowPopupMenu( HWND hOwner, HWND hAnchor );
static void MenuDemo_ShowFlyout( HWND hOwner, HWND hAnchor );
static void MenuDemo_CreateFlyoutWindow( HWND hOwner );
static void MenuDemo_ExecuteCommand( HWND hOwner, UINT nCommand );
static void MenuDemo_SetDefaultFont( HWND hControl );
static POINT MenuDemo_GetControlBottomLeft( HWND hControl );


static void MenuDemo_SetDefaultFont( HWND hControl )
{
   HFONT hFont;

   hFont = ( HFONT ) GetStockObject( DEFAULT_GUI_FONT );

   SendMessage(
      hControl,
      WM_SETFONT,
      ( WPARAM ) hFont,
      TRUE
   );
}


static POINT MenuDemo_GetControlBottomLeft( HWND hControl )
{
   RECT rcControl;
   POINT ptPosition;

   GetWindowRect( hControl, &rcControl );

   ptPosition.x = rcControl.left;
   ptPosition.y = rcControl.bottom;

   return ptPosition;
}


static void MenuDemo_ExecuteCommand( HWND hOwner, UINT nCommand )
{
   const char *pszMessage;

   pszMessage = NULL;

   switch( nCommand )
   {
      case ID_MENU_NEW:
         pszMessage = "Nuevo proyecto";
         break;

      case ID_MENU_OPEN:
         pszMessage = "Abrir proyecto";
         break;

      case ID_MENU_SAVE:
         pszMessage = "Guardar proyecto";
         break;

      case ID_MENU_BUILD:
         pszMessage = "Compilar proyecto";
         break;

      case ID_MENU_SETTINGS:
         pszMessage = "Configuracion";
         break;
   }

   if( pszMessage != NULL )
   {
      MessageBoxA(
         hOwner,
         pszMessage,
         "Comando seleccionado",
         MB_OK | MB_ICONINFORMATION
      );
   }
}


static void MenuDemo_ShowPopupMenu( HWND hOwner, HWND hAnchor )
{
   HMENU hPopupMenu;
   POINT ptPosition;
   UINT nCommand;

   hPopupMenu = CreatePopupMenu();

   if( hPopupMenu == NULL )
   {
      return;
   }

   AppendMenuA(
      hPopupMenu,
      MF_STRING,
      ID_MENU_NEW,
      "Nuevo proyecto"
   );

   AppendMenuA(
      hPopupMenu,
      MF_STRING,
      ID_MENU_OPEN,
      "Abrir proyecto..."
   );

   AppendMenuA(
      hPopupMenu,
      MF_SEPARATOR,
      0,
      NULL
   );

   AppendMenuA(
      hPopupMenu,
      MF_STRING,
      ID_MENU_SAVE,
      "Guardar"
   );

   AppendMenuA(
      hPopupMenu,
      MF_STRING,
      ID_MENU_BUILD,
      "Compilar"
   );

   AppendMenuA(
      hPopupMenu,
      MF_SEPARATOR,
      0,
      NULL
   );

   AppendMenuA(
      hPopupMenu,
      MF_STRING,
      ID_MENU_SETTINGS,
      "Configuracion"
   );

   ptPosition = MenuDemo_GetControlBottomLeft( hAnchor );

   SetForegroundWindow( hOwner );

   nCommand = TrackPopupMenuEx(
      hPopupMenu,
      TPM_LEFTALIGN |
      TPM_TOPALIGN |
      TPM_LEFTBUTTON |
      TPM_RETURNCMD,
      ptPosition.x,
      ptPosition.y,
      hOwner,
      NULL
   );

   PostMessage(
      hOwner,
      WM_NULL,
      0,
      0
   );

   DestroyMenu( hPopupMenu );

   if( nCommand != 0 )
   {
      MenuDemo_ExecuteCommand(
         hOwner,
         nCommand
      );
   }
}


static void MenuDemo_CreateFlyoutWindow( HWND hOwner )
{
   WNDCLASSEXA WindowClass;
   HINSTANCE hInstance;
   HWND hLabel;
   HWND hProjectButton;
   HWND hTerminalButton;
   HWND hCloseButton;

   if( IsWindow( s_hFlyoutWindow ) )
   {
      return;
   }

   hInstance = GetModuleHandle( NULL );

   ZeroMemory(
      &WindowClass,
      sizeof( WindowClass )
   );

   WindowClass.cbSize = sizeof( WindowClass );
   WindowClass.style = CS_HREDRAW | CS_VREDRAW;
   WindowClass.lpfnWndProc = FlyoutWindowProc;
   WindowClass.hInstance = hInstance;
   WindowClass.hCursor = LoadCursor( NULL, IDC_ARROW );
   WindowClass.hbrBackground = ( HBRUSH ) ( COLOR_WINDOW + 1 );
   WindowClass.lpszClassName = "HMG_WORKSPACE_FLYOUT";

   RegisterClassExA( &WindowClass );

   s_hFlyoutWindow = CreateWindowExA(
      WS_EX_TOOLWINDOW |
      WS_EX_TOPMOST |
      WS_EX_CONTROLPARENT,
      "HMG_WORKSPACE_FLYOUT",
      "",
      WS_POPUP |
      WS_BORDER,
      0,
      0,
      270,
      185,
      hOwner,
      NULL,
      hInstance,
      NULL
   );

   if( s_hFlyoutWindow == NULL )
   {
      return;
   }

   hLabel = CreateWindowExA(
      0,
      "STATIC",
      "Acciones de Workspace",
      WS_CHILD |
      WS_VISIBLE,
      18,
      15,
      225,
      24,
      s_hFlyoutWindow,
      NULL,
      hInstance,
      NULL
   );

   hProjectButton = CreateWindowExA(
      0,
      "BUTTON",
      "Abrir proyecto",
      WS_CHILD |
      WS_VISIBLE |
      WS_TABSTOP |
      BS_PUSHBUTTON,
      18,
      48,
      232,
      34,
      s_hFlyoutWindow,
      ( HMENU ) ( INT_PTR ) ID_FLYOUT_PROJECT,
      hInstance,
      NULL
   );

   hTerminalButton = CreateWindowExA(
      0,
      "BUTTON",
      "Abrir terminal",
      WS_CHILD |
      WS_VISIBLE |
      WS_TABSTOP |
      BS_PUSHBUTTON,
      18,
      88,
      232,
      34,
      s_hFlyoutWindow,
      ( HMENU ) ( INT_PTR ) ID_FLYOUT_TERMINAL,
      hInstance,
      NULL
   );

   hCloseButton = CreateWindowExA(
      0,
      "BUTTON",
      "Cerrar",
      WS_CHILD |
      WS_VISIBLE |
      WS_TABSTOP |
      BS_PUSHBUTTON,
      172,
      136,
      78,
      28,
      s_hFlyoutWindow,
      ( HMENU ) ( INT_PTR ) ID_FLYOUT_CLOSE,
      hInstance,
      NULL
   );

   MenuDemo_SetDefaultFont( hLabel );
   MenuDemo_SetDefaultFont( hProjectButton );
   MenuDemo_SetDefaultFont( hTerminalButton );
   MenuDemo_SetDefaultFont( hCloseButton );
}


static void MenuDemo_ShowFlyout( HWND hOwner, HWND hAnchor )
{
   POINT ptPosition;

   MenuDemo_CreateFlyoutWindow( hOwner );

   if( ! IsWindow( s_hFlyoutWindow ) )
   {
      return;
   }

   ptPosition = MenuDemo_GetControlBottomLeft( hAnchor );

   SetWindowPos(
      s_hFlyoutWindow,
      HWND_TOPMOST,
      ptPosition.x,
      ptPosition.y + 4,
      270,
      185,
      SWP_SHOWWINDOW
   );

   ShowWindow(
      s_hFlyoutWindow,
      SW_SHOWNOACTIVATE
   );

   SetForegroundWindow( s_hFlyoutWindow );
}


static void MenuDemo_CreateControls( HWND hParent )
{
   HINSTANCE hInstance;

   hInstance = GetModuleHandle( NULL );

   s_hSplitButton = CreateWindowExA(
      0,
      "BUTTON",
      "Compilar",
      WS_CHILD |
      WS_VISIBLE |
      WS_TABSTOP |
      BS_SPLITBUTTON,
      25,
      95,
      210,
      42,
      hParent,
      ( HMENU ) ( INT_PTR ) ID_SPLIT_BUTTON,
      hInstance,
      NULL
   );

   s_hCommandButton = CreateWindowExA(
      0,
      "BUTTON",
      "Abrir Workspace",
      WS_CHILD |
      WS_VISIBLE |
      WS_TABSTOP |
      BS_COMMANDLINK,
      25,
      180,
      340,
      72,
      hParent,
      ( HMENU ) ( INT_PTR ) ID_COMMAND_BUTTON,
      hInstance,
      NULL
   );

   SendMessageW(
      s_hCommandButton,
      BCM_SETNOTE,
      0,
      ( LPARAM ) L"Seleccionar proyecto, carpeta o configuracion"
   );

   s_hPopupButton = CreateWindowExA(
      0,
      "BUTTON",
      "Mostrar Popup Menu",
      WS_CHILD |
      WS_VISIBLE |
      WS_TABSTOP |
      BS_PUSHBUTTON,
      25,
      300,
      210,
      40,
      hParent,
      ( HMENU ) ( INT_PTR ) ID_POPUP_BUTTON,
      hInstance,
      NULL
   );

   s_hFlyoutButton = CreateWindowExA(
      0,
      "BUTTON",
      "Mostrar Flyout",
      WS_CHILD |
      WS_VISIBLE |
      WS_TABSTOP |
      BS_PUSHBUTTON,
      25,
      380,
      210,
      40,
      hParent,
      ( HMENU ) ( INT_PTR ) ID_FLYOUT_BUTTON,
      hInstance,
      NULL
   );

   MenuDemo_SetDefaultFont( s_hSplitButton );
   MenuDemo_SetDefaultFont( s_hCommandButton );
   MenuDemo_SetDefaultFont( s_hPopupButton );
   MenuDemo_SetDefaultFont( s_hFlyoutButton );
}


static LRESULT CALLBACK FlyoutWindowProc(
   HWND hWnd,
   UINT nMessage,
   WPARAM wParam,
   LPARAM lParam
)
{
   switch( nMessage )
   {
      case WM_COMMAND:
      {
         UINT nControlId;

         nControlId = LOWORD( wParam );

         switch( nControlId )
         {
            case ID_FLYOUT_PROJECT:
               MessageBoxA(
                  s_hMainWindow,
                  "Abrir proyecto desde el Flyout",
                  "Flyout",
                  MB_OK | MB_ICONINFORMATION
               );

               ShowWindow(
                  hWnd,
                  SW_HIDE
               );

               return 0;

            case ID_FLYOUT_TERMINAL:
               MessageBoxA(
                  s_hMainWindow,
                  "Abrir terminal desde el Flyout",
                  "Flyout",
                  MB_OK | MB_ICONINFORMATION
               );

               ShowWindow(
                  hWnd,
                  SW_HIDE
               );

               return 0;

            case ID_FLYOUT_CLOSE:
               ShowWindow(
                  hWnd,
                  SW_HIDE
               );

               return 0;
         }

         break;
      }

      case WM_ACTIVATE:
      {
         if( LOWORD( wParam ) == WA_INACTIVE )
         {
            ShowWindow(
               hWnd,
               SW_HIDE
            );
         }

         break;
      }

      case WM_CLOSE:
      {
         ShowWindow(
            hWnd,
            SW_HIDE
         );

         return 0;
      }
   }

   return DefWindowProc(
      hWnd,
      nMessage,
      wParam,
      lParam
   );
}


static LRESULT CALLBACK MenuDemo_SubclassProc(
   HWND hWnd,
   UINT nMessage,
   WPARAM wParam,
   LPARAM lParam,
   UINT_PTR nSubclassId,
   DWORD_PTR nReferenceData
)
{
   HB_SYMBOL_UNUSED( nSubclassId );
   HB_SYMBOL_UNUSED( nReferenceData );

   switch( nMessage )
   {
      case WM_NOTIFY:
      {
         NMHDR *pNotify;

         pNotify = ( NMHDR * ) lParam;

         if(
            pNotify != NULL &&
            pNotify->hwndFrom == s_hSplitButton &&
            pNotify->code == BCN_DROPDOWN
         )
         {
            MenuDemo_ShowPopupMenu(
               hWnd,
               s_hSplitButton
            );

            return 0;
         }

         break;
      }

      case WM_COMMAND:
      {
         UINT nControlId;
         UINT nNotifyCode;

         nControlId = LOWORD( wParam );
         nNotifyCode = HIWORD( wParam );

         if( nNotifyCode == BN_CLICKED )
         {
            switch( nControlId )
            {
               case ID_SPLIT_BUTTON:
                  MessageBoxA(
                     hWnd,
                     "Accion principal del Split Button: Compilar",
                     "Split Button",
                     MB_OK | MB_ICONINFORMATION
                  );

                  return 0;

               case ID_COMMAND_BUTTON:
                  MenuDemo_ShowPopupMenu(
                     hWnd,
                     s_hCommandButton
                  );

                  return 0;

               case ID_POPUP_BUTTON:
                  MenuDemo_ShowPopupMenu(
                     hWnd,
                     s_hPopupButton
                  );

                  return 0;

               case ID_FLYOUT_BUTTON:
                  MenuDemo_ShowFlyout(
                     hWnd,
                     s_hFlyoutButton
                  );

                  return 0;
            }
         }

         break;
      }

      case WM_DESTROY:
      {
         if( IsWindow( s_hFlyoutWindow ) )
         {
            DestroyWindow( s_hFlyoutWindow );
            s_hFlyoutWindow = NULL;
         }

         RemoveWindowSubclass(
            hWnd,
            MenuDemo_SubclassProc,
            1
         );

         break;
      }
   }

   return DefSubclassProc(
      hWnd,
      nMessage,
      wParam,
      lParam
   );
}


HB_FUNC( NATIVEMENUDEMO_INIT )
{
   INITCOMMONCONTROLSEX CommonControls;
   HWND hParent;

   hParent = ( HWND ) ( HB_PTRUINT ) hb_parnint( 1 );

   if( ! IsWindow( hParent ) )
   {
      hb_retl( HB_FALSE );
      return;
   }

   CommonControls.dwSize = sizeof( CommonControls );
   CommonControls.dwICC = ICC_STANDARD_CLASSES;

   InitCommonControlsEx( &CommonControls );

   s_hMainWindow = hParent;

   MenuDemo_CreateControls( hParent );

   SetWindowSubclass(
      hParent,
      MenuDemo_SubclassProc,
      1,
      0
   );

   hb_retl( HB_TRUE );
}

#pragma ENDDUMP
Attachments
Captura de pantalla 2026-07-22 220346.png
Captura de pantalla 2026-07-22 220346.png (22.98 KiB) Viewed 484 times
*´¨)
¸.·´¸.·*´¨) ¸.·*¨)
(¸.·´. (¸.·` *
.·`. Harbour/HMG : It's magic !
(¸.·``··*

Saludos / Regards
DaNiElMaXiMiLiAnO

Whatsapp. := +54901169026142
Telegram Name := DaNiElMaXiMiLiAnO
User avatar
Steed
Posts: 453
Joined: Sat Dec 12, 2009 3:40 pm

Re: News menu

Post by Steed »

Great!
User avatar
serge_girard
Posts: 3412
Joined: Sun Nov 25, 2012 2:44 pm
DBs Used: 1 MySQL - MariaDB
2 DBF
Location: Belgium
Contact:

Re: News menu

Post by serge_girard »

Thanks !
There's nothing you can do that can't be done...
Post Reply