Announcement

Collapse
No announcement yet.

Simple Windows Ribbon Example

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Simple Windows Ribbon Example

    Hosting a Ribbon control in a PowerBASIC application is easy using my Windows API headers, as the following example demonstrates.

    The Windows Ribbon control is a COM control and since it has a user interface you must initialize an STA (single threaded) apartment. The Windows Ribbon control is not an ActiveX control. This means that you do not have to provide an ActiveX control site, which simplifies considerably the code that you have to write in your application.

    For a more detailed explanation on how to use the Windows Ribbon, specially writing the markup language and compiling it to a BML resource, see: http://msdn.microsoft.com/en-us/libr.../ff963530.aspx

    The attached file contains the full source code and resources used in the example.

    Code:
    ' ########################################################################################
    ' Microsoft Windows
    ' File: SimpleRibbon
    ' Contents: CWindow with a ribbon
    ' Compilers: PBWIN 10+, PBCC 6+
    ' Headers: Windows API headers 2.03+
    ' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
    ' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
    ' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
    ' ########################################################################################
    #COMPILE EXE
    #DIM ALL
    %UNICODE = 1
    
    ' // Include files for external files
    #INCLUDE ONCE "CWindow.inc"   ' // CWindow class
    #INCLUDE ONCE "UIRibbon.inc"
    #RESOURCE RES "SimpleRibbon.res"
    
    ' ========================================================================================
    ' Custom implementations of the IUIApplication and IUICommandHandler interfaces.
    ' ========================================================================================
    CLASS CApplication AS COM
    
       ' =====================================================================================
       INTERFACE IUIApplicationImpl $IID_IUIApplication : INHERIT IUnknown
       ' =====================================================================================
    
       METHOD OnViewChanged(BYVAL viewId AS DWORD, BYVAL typeID AS LONG, BYVAL view AS IUnknown, BYVAL verb AS LONG, BYVAL uReasonCode AS LONG) AS LONG
          METHOD = %E_NOTIMPL
       END METHOD
    
       METHOD OnCreateUICommand(BYVAL commandId AS DWORD, BYVAL typeID AS LONG, BYREF pCommandHandler AS IUICommandHandler) AS LONG
          pCommandHandler = ME
          METHOD = %S_OK
       END METHOD
    
       METHOD OnDestroyUICommand(BYVAL commandId AS DWORD, BYVAL typeID AS LONG, BYREF pCommandHandler AS IUICommandHandler) AS LONG
          METHOD = %E_NOTIMPL
       END METHOD
    
       END INTERFACE
       ' =====================================================================================
    
       ' =====================================================================================
       INTERFACE IUICommandHandlerImpl $IID_IUICommandHandler : INHERIT IUnknown
       ' =====================================================================================
    
       METHOD Execute (BYVAL commandId AS DWORD, BYVAL verb AS LONG, BYREF key AS PROPERTYKEY, BYREF currentValue AS PROPVARIANT, BYVAL pCommandExecutionProperties AS IUISimplePropertySet) AS LONG
          ?  "Command identifier:" & STR$(commandiD)
          METHOD = %S_OK
       END METHOD
    
       METHOD UpdateProperty (BYVAL commandId AS DWORD, BYREF key AS PROPERTYKEY, BYREF currentValue AS PROPVARIANT, BYREF newValue AS PROPVARIANT) AS LONG
          METHOD = %E_NOTIMPL
       END METHOD
    
       END INTERFACE
       ' =====================================================================================
    
    END CLASS
    ' ========================================================================================
    
    ' ========================================================================================
    ' Main
    ' ========================================================================================
    FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
    
       ' // Set process DPI aware
       IF AfxGetWindowsVersion => 6 THEN SetProcessDPIAware
    
       ' // Create an instance of the class
       LOCAL pWindow AS IWindow
       pWindow = CLASS "CWindow"
       IF ISNOTHING(pWindow) THEN EXIT FUNCTION
    
       ' // Create the main window
       LOCAL hwnd AS DWORD
       hWnd = pWindow.CreateWindow(%NULL, "CWindow with a ribbon", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
       ' // Set the client size
       pWindow.SetClientSize 500, 320
       ' // Center the window
       pWindow.CenterWindow
    
       ' =====================================================================================
       ' // Initialize tne ribbon
       ' =====================================================================================
    
       ' // Create an instance of our host class
       LOCAL pApplication AS IUIApplicationImpl
       pApplication = CLASS "CApplication"
       IF ISNOTHING(pApplication) THEN EXIT FUNCTION
    
       ' // Create an instance of the IUIFramework interface
       LOCAL pFramework AS IUIFramework
       pFramework = NEWCOM CLSID $CLSID_UIRibbonFramework
       IF ISNOTHING(pFramework) THEN EXIT FUNCTION
    
       ' // Connects the host application to the Windows Ribbon framework.
       LOCAL hr AS LONG
       hr = pFramework.Initialize(hwnd, pApplication)
       IF hr <> %S_OK THEN EXIT FUNCTION
       ' // Specifies the application modes to enable.
       hr = pFramework.SetModes(1)
       ' // Loads the Ribbon framework UI resource, or compiled markup, file.
       hr = pFramework.LoadUI(hInstance, "APPLICATION_RIBBON")
       ' =====================================================================================
    
       ' // Default message pump (you can replace it with your own)
       pWindow.DoEvents(nCmdShow)
    
    END FUNCTION
    ' ========================================================================================
    
    ' ========================================================================================
    ' Main callback function.
    ' ========================================================================================
    FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
    
       ' // Process window mesages
       SELECT CASE uMsg
    
          CASE %WM_COMMAND
             SELECT CASE LO(WORD, wParam)
                CASE %IDCANCEL
                   ' // If the Escape key has been pressed...
                   IF HI(WORD, wParam) = %BN_CLICKED THEN
                      ' // ... close the application by sending a WM_CLOSE message
                      SendMessage hwnd, %WM_CLOSE, 0, 0
                      EXIT FUNCTION
                   END IF
             END SELECT
    
          CASE %WM_DESTROY
             ' // End the application
             PostQuitMessage 0
             EXIT FUNCTION
    
       END SELECT
    
       ' // Pass unprocessed messages to Windows
       FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)
    
    END FUNCTION
    ' ========================================================================================
    Attached Files
    Last edited by José Roca; 15 Mar 2013, 11:18 PM.
    Forum: http://www.jose.it-berater.org/smfforum/index.php

  • #2
    DDT version. Just replace the above code with:

    Code:
    ' ########################################################################################
    ' Microsoft Windows
    ' File: SimpleRibbon
    ' Contents: DDT dialog with a ribbon
    ' Compilers: PBWIN 10+, PBCC 6+
    ' Headers: Windows API headers 2.03+
    ' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
    ' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
    ' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
    ' ########################################################################################
    #COMPILE EXE
    #DIM ALL
    %UNICODE = 1
    
    ' // Include files for external files
    #INCLUDE ONCE "CWindow.inc"   ' // CWindow class
    #INCLUDE ONCE "UIRibbon.inc"
    #RESOURCE RES "SimpleRibbon.res"
    
    ' ========================================================================================
    ' Custom implementations of the IUIApplication and IUICommandHandler interfaces.
    ' ========================================================================================
    CLASS CApplication AS COM
    
       ' =====================================================================================
       INTERFACE IUIApplicationImpl $IID_IUIApplication : INHERIT IUnknown
       ' =====================================================================================
    
       METHOD OnViewChanged(BYVAL viewId AS DWORD, BYVAL typeID AS LONG, BYVAL view AS IUnknown, BYVAL verb AS LONG, BYVAL uReasonCode AS LONG) AS LONG
          METHOD = %E_NOTIMPL
       END METHOD
    
       METHOD OnCreateUICommand(BYVAL commandId AS DWORD, BYVAL typeID AS LONG, BYREF pCommandHandler AS IUICommandHandler) AS LONG
          pCommandHandler = ME
          METHOD = %S_OK
       END METHOD
    
       METHOD OnDestroyUICommand(BYVAL commandId AS DWORD, BYVAL typeID AS LONG, BYREF pCommandHandler AS IUICommandHandler) AS LONG
          METHOD = %E_NOTIMPL
       END METHOD
    
       END INTERFACE
       ' =====================================================================================
    
       ' =====================================================================================
       INTERFACE IUICommandHandlerImpl $IID_IUICommandHandler : INHERIT IUnknown
       ' =====================================================================================
    
       METHOD Execute (BYVAL commandId AS DWORD, BYVAL verb AS LONG, BYREF key AS PROPERTYKEY, BYREF currentValue AS PROPVARIANT, BYVAL pCommandExecutionProperties AS IUISimplePropertySet) AS LONG
          ?  "Command identifier:" & STR$(commandiD)
          METHOD = %S_OK
       END METHOD
    
       METHOD UpdateProperty (BYVAL commandId AS DWORD, BYREF key AS PROPERTYKEY, BYREF currentValue AS PROPVARIANT, BYREF newValue AS PROPVARIANT) AS LONG
          METHOD = %E_NOTIMPL
       END METHOD
    
       END INTERFACE
       ' =====================================================================================
    
    END CLASS
    ' ========================================================================================
    
    ' ========================================================================================
    ' Main
    ' ========================================================================================
    FUNCTION PBMAIN
    
       LOCAL hDlg AS DWORD
    
       ' // Create the dialog
       DIALOG NEW PIXELS, 0, "Simple Ribbon", , , 500, 320, %WS_OVERLAPPED OR %WS_THICKFRAME OR %WS_SYSMENU OR _
       %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_VISIBLE OR %DS_CENTER TO hDlg
    
       ' =====================================================================================
       ' // Initialize tne ribbon
       ' =====================================================================================
    
       ' // Create an instance of our host class
       LOCAL pApplication AS IUIApplicationImpl
       pApplication = CLASS "CApplication"
       IF ISNOTHING(pApplication) THEN EXIT FUNCTION
    
       ' // Create an instance of the IUIFramework interface
       LOCAL pFramework AS IUIFramework
       pFramework = NEWCOM CLSID $CLSID_UIRibbonFramework
       IF ISNOTHING(pFramework) THEN EXIT FUNCTION
    
       ' // Connects the host application to the Windows Ribbon framework.
       LOCAL hr AS LONG
       hr = pFramework.Initialize(hDlg, pApplication)
       IF hr <> %S_OK THEN EXIT FUNCTION
       ' // Specifies the application modes to enable.
       hr = pFramework.SetModes(1)
       ' // Loads the Ribbon framework UI resource, or compiled markup, file.
       hr = pFramework.LoadUI(EXE.INST, "APPLICATION_RIBBON")
       ' =====================================================================================
    
       ' // Display and activate the dialog
       DIALOG SHOW MODAL hDlg, CALL DlgProc
    
    END FUNCTION
    ' ========================================================================================
    
    ' ========================================================================================
    ' Main Dialog procedure
    ' ========================================================================================
    CALLBACK FUNCTION DlgProc() AS LONG
    
       SELECT CASE CBMSG
    
          CASE %WM_COMMAND
             SELECT CASE CB.CTL
                ' ...
                ' ...
             END SELECT
    
       END SELECT
    
    END FUNCTION
    ' ========================================================================================
    Last edited by José Roca; 16 Mar 2013, 01:03 AM.
    Forum: http://www.jose.it-berater.org/smfforum/index.php

    Comment


    • #3
      Great to see new examples from you, Jose!
      --Theo Gottwald
      ------------------------------------------------
      76706 Dettenheim * Germany * [email protected]
      ------------------------------------------------
      Joses Forum * Theo's Link Site * IT-Berater.org

      Comment


      • #4
        The exe sizes differ ... a lot
        Code:
        18/03/2013  08:52           105.472 SimpleRibbon DDT.EXE
        16/03/2013  03:34            78.336 SimpleRibbon.EXE
        "The trouble with quotes on the Internet is that you can never know if they are genuine." - Abraham Lincoln.

        Comment


        • #5
          DDT applications are always bigger that SDK equivalents.
          Forum: http://www.jose.it-berater.org/smfforum/index.php

          Comment


          • #6
            but less code to type

            PD: why José is not drinking wine in "Las Fallas"?

            Comment


            • #7
              Great code. Thanks José
              Francisco J Castanedo
              Software Developer
              Distribuidora 3HP, C.A.
              [URL]http://www.distribuidora3hp.com[/URL]

              Comment


              • #8
                Very nice, José.
                Thanks!!
                Eddy

                Comment


                • #9
                  Any idea how can I modify ribbon element at run time (i.e text, state etc.)
                  TIA

                  Comment


                  • #10
                    Sorry to open again this old thread but Josè example is very nice.
                    I noted that reducing window size ... ribbon menu completely disappear if vertical or horizontal size is more than some limit.
                    I checked source code but didn't find a way to avoid this behave

                    Thanks a lot
                    Eros

                    Click image for larger version  Name:	Ribbon Disappear.png Views:	0 Size:	25.6 KB ID:	792292
                    thinBasic programming language
                    Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

                    Comment


                    • #11
                      You will have to process the WM_GETMINMAXINFO message and don't allow to reduce the size beyond a minimum size.
                      Forum: http://www.jose.it-berater.org/smfforum/index.php

                      Comment


                      • #12
                        Yes, already done, I was wondering if there was a way to avoid disappearing.
                        Later I checked MS Office applications like Outlook 2013 and behave is the same, below some point of reduction ribbon disappear while in Outlook 2019 you cannot reduce main window under a certain limit.

                        Thanks José.
                        thinBasic programming language
                        Win10 64bit - 8GB Ram - i7 M620 2.67GHz - NVIDIA Quadro FX1800M 1GB

                        Comment


                        • #13
                          For those that were wondering...

                          Code:
                          CALLBACK FUNCTION DlgProc() AS LONG
                             LOCAL mminfo   AS MINMAXINFO PTR
                          
                             SELECT CASE CBMSG
                                CASE %WM_GETMINMAXINFO
                                    mminfo = CBLPARAM
                                    'Set the minimum dialog width and height so the ribbon does not disappear.
                                    @mminfo.ptMinTrackSize.x = 470
                                    @mminfo.ptMinTrackSize.y = 260
                                    FUNCTION = 0
                          
                                CASE %WM_COMMAND
                                   SELECT CASE CB.CTL
                                      ' ...
                                      ' ...
                                   END SELECT
                          
                             END SELECT
                          
                          END FUNCTION

                          Comment

                          Working...
                          X