Access 2013 Custom Images for the Ribbon

不问归期 提交于 2020-07-22 05:29:07

问题


I've started using the Access Ribbon for menus in my database, but now I'm afraid I've come to an impasse.

I'd like to use my own images for the icons in the ribbon, but am having loads of difficulty accomplishing this task.

The code is just below, but the error message I keep getting is that Access cannot run the macro or callback function 'getImages'.

Ribbon xml Code:

<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
      <ribbon startFromScratch="true"> 
        <tabs>          
          <tab id="tMainMenu" label="Main Menu"> 
            <group id="Developer"> 
              <button id="DevTools1"/> 
            </group>
            <group id="MainMenuSpacer1">
            </group>
            <group id="gSupport">
              <button id="Support1" label="Custom Image" getImage="getImages"/>
            </group>
            <group id="MainMenuSpacer2">
            </group>
            <group id="gShutdown"> 
              <button id="Shutdown"/>
            </group>
          </tab>
        </tabs> 
      </ribbon>
    </customUI>

VBA Procedure Code:

Public Sub getImages(control As IRibbonControl, ByRef image)
If irc.ID = "Support1" Then
    MyPath = "J:\Images\OperatorAssistantButton1.png"
    Set image = LoadPicture(MyPath)
End If
End Sub

My company does not have the 12.0 Reference. We are using 15.0


回答1:


Keep in mind that there are TWO types of image loads.

1 One time image load.

A one-time image load is used for “most” image loads. This is used when you want a custom icon, but are NOT going to change the image once loaded. This approach is thus used for “most” custom image loads for the ribbon.

2 Runtime ability to change image.

This is used when you want the image to be able to not only be loaded, but ALSO want to have the image change - say an image that shows the weather as sunny, and then you change it to a cloud for cloudy.

So VERY important to distinguish between your goal, and the type of image load you need and want.

One time image load example

For “general” image load and setting in the ribbon, you thus ONLY ONE TIME specify the routine you will use (at the start of the ribbon xml). This routine is then used for ALL of your image settings and you do NOT specify the call back routine for each control.

You thus use the “image” attribute setting for each control, but ONLY specify the call back routine one time.

The ribbon code will thus look like this:

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"
 loadImage="CallBackLoadImage"
 onLoad="MyRibbonLoadA">

    <group id="group1" label="Basic Button Attributes Examples">
      <button id="button1" label="Button1" 
             size="large"
             getEnabled="MyEnable"
             getVisible="MyVisible" 
             image="CokeClassic.png"
             onAction="=Bt1()"
             supertip= "example load a image without ability to change"
        />
      <button id="button2" label="button2"  
             size="large"
             getEnabled="MyEnable"
             image="CokeZero.png"
             onAction="=Bt2()"
       />

Note in above HOW we set the image for the first button.

image="CokeClassic.png"

and for second button we ue:

image="CokeZero.png"

So in effect, we hard code and specify the image in the XML of the ribbon. And in above at the start we set the GLOBAL image load routine that is to be use for ALL images we specify in the ribbon.

The routine we will use/call for all these images is thus specified at the start:

 loadImage="CallBackLoadImage"

Note how this is ONLY done ONE TIME and at the start of the ribbon XML – you do NOT specify this call back for each button.

The VBA routine (CallBAckLoadImage in our example) has to be placed in a standard VBA code module (not a class, and not in a forms code module). The ribbon load code we have is thus this:

Sub CallbackLoadImage(strImage As String, _
                 ByRef image)

  Dim strImagePath  As String
   ' Callback loadImage

  strImagePath = CurrentProject.Path & "\ribbon\" & strImage
  Set image = LoadPicture(strImagePath)

End Sub

In above, note how our code “assumes” that a folder called ribbon will be placed in the SAME folder as where the front end (accDB/accDE) is running. Thus we don’t hard code any path names, and assume that a ribbon “icon” folder will always exist in the same folder as where we run the application from. So we can copy, rename the folder, or move it anywhere, and our image load code will still run.

So just keep in mind that you do NOT specify the call back for EACH button – only one time. And NOTE HOW the image name is automatic passed to the routine we call. So the “image = some image” is rather nice, since we don’t require SPECIAL code to pluck out or figure out what image we want.

Case 2 - runtime change of image.

We want to CHANGE the icons at runtime. As noted, for most images, we use approach #1, but in some cases we need and want a dynamic routine. However, on ribbon startup, this means the code will have to supply some default type of image, and thus for this example, I used the “tag” setting to set a default ribbon.

So our button code now looks like:

      <button id="Weather" label = "The Weather button" 
             size="large"
             getImage="MyImage" tag="sunny.png"
             onAction= "=BtWeather()"
       />

So in above WE DO set the call back for EACH button etc.

The call back code looks like:

Public Sub MyImage(control As IRibbonControl, ByRef image)

  Dim strImagePath  As String
  Dim strImage      As String

   ' for the 1st call when ribbon loads there no images set. So we
   ' use the tag as kludge workaround to set the starting image

   If strGlobalImage = "" then   
      strImage = control.Tag
   End If

  If strImage <> "" Then
     If Left(strImage, 4) = "mso." Then
        image = Mid(strImage, 5)
     Else
        strImagePath = CurrentProject.Path & "\ribbon\" & strImage
        Set image = LoadPicture(strImagePath)
     End If
  End If
End Sub

Note in above, I also have provisions for using built-in images – because there are so many useful ones, then I adopted the standard that I can place the text “iso.ImageName” for built-in icons. So if you use "iso.BuiltInImageName", then above will work.

I also do this for process #1 above, and thus I have:

Sub CallbackLoadImage(strImage As String, _
                 ByRef image)

  Dim strImagePath  As String
   ' Callback loadImage


  If Left(strImage, 4) = "mso." Then
     strImage = Mid(strImage, 5)
     image = strImage
  Else
     strImagePath = CurrentProject.Path & "\ribbon\" & strImage
     Set image = LoadPicture(strImagePath)
  End If

End Sub

So above allows me to use any of the “many” icons built into office – there are lot of useful ones.

So keep a “STRONG” distinction between the two kinds of image loads:

1) you want a image for a button etc.

2) you want to CHANGE the image after loaded to other kinds of images for status etc.

Last but not least: For any button, it is REALLY a pain to have to declare a set of variables that hold the state of a SINGLE button. You have: Visible, Enabled, Label text Image

So for each button, you in general have to declare a variable to hold all the states. For just 2-3 buttons, you need like 12 global variables to hold these states of the button. So I build a class that automatic creates and does all the dirty work for you.

You can find the above same code, and more in this sample working of mine here:

http://www.kallal.ca/Ribbon/ribbon.htm

The main advantage of above is you don’t have to declare new variables for each new button etc. that you want dynamic change of the image or label text.



来源:https://stackoverflow.com/questions/52915787/access-2013-custom-images-for-the-ribbon

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!