View Single Post
  #17   Report Post  
Posted to microsoft.public.excel.programming
Greg Maxey[_4_] Greg Maxey[_4_] is offline
external usenet poster
 
Posts: 14
Default getImage and VBA Callback

Bob,

If those images can't be accessed then to put it bluntly the scheme is not
only stupid, but broken too! IMHO.


Bob Phillips wrote:
Greg,

You are right, it is easily pointed to, but it is in the XML, and
isn't exposed to VBA (AFAICS). MS have set out on a deliberate policy
of stopping us from controlling the ribbon, they call it giving full
control to the user, I call it MS deciding what the user wants.

I'll drop you an email if I find anything new at the mvp addy.


"Greg Maxey" wrote in
message ...
Bob,

A shame truly if what you believe is true. It doesn't seem to make
much sense. Images in the customUI\images folder are easily pointed
to and accessed with the image attribute, so it seems they should be
accessible with the getImage attribute.

Regardless you have been a tremendous help. I don't mind looking
for a needle in a haystack when I know it is there ;-)

Thanks and please let me know if you confirm your last response.



--
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org
"Bob Phillips" wrote in message
...
Greg,

In my contextual definition, here any document that contains code
is an application <g. Distributing such is always a problem, and
increases if you have subsidiary/dependent files that are needed
with it. OCXs and DLLs are the worst, but the principle here is the
same. What I am saying is that I don't believe that you can access the
files in the customUI\images folder of the OpenXML File container
from within your code, so to toggle the images requires the images
to be outside of your document. I am still checking that it is a
correct statement, but it is what I believe to be the case. A shame
I agree, it could open a lot of possibilities, but that is my
understanding that the ribbon is pretty effectively locked down.

But IMO, having the images outside of the document is not that big a
deal, as long as you accept the application paradigm <bg.


--
__________________________________
HTH

Bob

"Greg Maxey" wrote in
message ...
Bob,

Yes. In actual practice I would use a togglebutton control and the
pressed state to determine which image to apply.

You are way ahead of me as far a programming Word, Excel, or
otherwise. I don't really want to neccessarily write an
applicaton. I just want to send a file to someone that contains a
custom toggle button. If it is pressed it displays one image if
not it displays anther. I can store both images in the
customUI\images folder of the OpenXML File container. Are you saying
that there is no way that you know of to point to
those two files using the cal getImage callback?

Thanks.



Bob Phillips wrote:
Greg,

The way I would do it is to store those images in the same
directory, or at most an \images sub-directory, of the actual
application file. I'm an Excel guy, so I tend to write these
things as addins, and use an installer to install them (Inno
Setup) which takes care of installing everything where you want.
The user can choose the base folder, but your can direct the
installer where to laod and subsidiary files. Although I tend to use
addins, it would work
just as well for non-addins.
BTW, in the situation that you describe, the XML should refer to
togglebutton, not button.

<toggleButton id="BTN1"
label="Button 1"
getImage="myGetImage"
size="large"
onAction="ButtonOnAction" /

and you would just have a boolean in your code and load one
picture or another depending upon the boolean state. You can also
use a routine to get the label rather than stick with the same


<toggleButton id="BTN1"
getLabel="myGetLabel"
getImage="myGetImage"
size="large"
onAction="ButtonOnAction" /


"Greg Maxey" wrote in
message ...
Bob,

If it is not possible to point to a file stored in the
activedocument customUI\images folder when using the getImages
callback then how would you send a file that contained custom
images on the ribbon controls (e.g., images located in a folder
on my hardrive) to another person? Say I have a toggle button
control that I wanted to display one
custom image if pressed and another custorm image if not
pressed? It seems that I would have to use the getImage
attribute? Thanks



Bob Phillips wrote:
Everything looks good Greg, aside from one small type in the XML

<customUI
xmlns="http://schemas.microsoft.com/office/2006/01/customui"
<ribbon <tabs
<tab id="custTab1" label="Demo Tab"
<group id="Grp1" label="Demo Group"
<button id="BTN1"
label="Button 1"
image="Test"
size="large"
onAction="ButtonOnAction" /
<button id="BTN2"
label="BTN2"
getImage="GetImage"
size="large"
onAction="ButtonOnAction" /
</group
</tab
</tabs
</ribbon
</customUI

Is it not working for you?


"Greg Maxey" wrote
in message ...
Bob,

Much progress.

I can now define and display a custom image with:

Sub GetImage(control As IRibbonControl, ByRef image)
Set image = LoadImage("C:\Test.png")
End Sub

because I know the path and name of the image file.

I use the Office 2007 Custom UI Editor for building my ribbon
XML. I use the "Insert Icon" toolbar button and import the
Test.png file into the document Open Office XML File format
container. I can verify that the image is now stored with the
document by unzipping the folder and looking in the
CustomUI\Images folder. Now I want to create a couple of buttons
using the same image.
On one button I can use the static attribut image="Test" When
the ribbon loads button 1 displays the Test image.

In the other button I want to use the dynamic attribute
getImage. How do I modify:

Set image = LoadImage("C:\Test.png")

So that it loads the image named "Test" that is stored in the
document CustomUI\Images folder?

Thank you very much for helping me get this far!!


<customUI
xmlns="http://schemas.microsoft.com/office/2006/01/customui"
<ribbon <tabs
<tab id="custTab1" label="Demo Tab"
<group id="Grp1" label="Demo Group"
<button id="BTN1"
label="Button 1"
image="Test"
size="large"
onAction="ButtonOnAction" /
<button id="BTN2"
label="BTN2"
getImaage="GetImage"
size="large"
onAction="ButtonOnAction" /
</group
</tab
</tabs
</ribbon
</customUI


Bob Phillips wrote:
Greg,

I'll try doing it properly and give you all of the code, not
piecemeal (I keep forgetting that you don't have the book
yet!) Option Explicit

Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type

Private Type PICTDESC
Size As Long
Type As Long
hPic As Long
hPal As Long
End Type

Private Type GdiplusStartupInput
GdiplusVersion As Long
DebugEventCallback As Long
SuppressBackgroundThread As Long
SuppressExternalCodecs As Long
End Type

Private Declare Function GdiplusStartup Lib "GDIPlus" (token
As Long, _ inputbuf As GdiplusStartupInput, Optional ByVal
outputbuf As Long = 0) As Long
Private Declare Function GdipCreateBitmapFromFile Lib
"GDIPlus" ( _ ByVal filename As Long, bitmap As Long) As
Long Private Declare Function GdipCreateHBITMAPFromBitmap Lib
"GDIPlus" ( _ ByVal bitmap As Long, _
hbmReturn As Long, _
ByVal background As Long) As Long
Private Declare Function GdipDisposeImage Lib "GDIPlus" ( _
ByVal image As Long) As Long
Private Declare Function GdiplusShutdown Lib "GDIPlus" ( _
ByVal token As Long) As Long
Private Declare Function OleCreatePictureIndirect Lib
"olepro32.dll" ( _ PicDesc As PICTDESC, _
RefIID As GUID, _
ByVal fPictureOwnsHandle As Long, _
IPic As IPicture) As Long

Public Function LoadImage(ByVal strFName As String) As
IPicture Dim uGdiInput As GdiplusStartupInput
Dim hGdiPlus As Long
Dim hGdiImage As Long
Dim hBitmap As Long

uGdiInput.GdiplusVersion = 1

If GdiplusStartup(hGdiPlus, uGdiInput) = 0 Then
If GdipCreateBitmapFromFile(StrPtr(strFName),
hGdiImage) = 0 Then GdipCreateHBITMAPFromBitmap
hGdiImage, hBitmap, 0 Set LoadImage =
ConvertToIPicture(hBitmap) GdipDisposeImage
hGdiImage End If
GdiplusShutdown hGdiPlus
End If

End Function

Public Function ConvertToIPicture(ByVal hPic As Long) As
IPicture Dim uPicInfo As PICTDESC
Dim IID_IDispatch As GUID
Dim IPic As IPicture

Const PICTYPE_BITMAP = 1

With IID_IDispatch
.Data1 = &H7BF80980
.Data2 = &HBF32
.Data3 = &H101A
.Data4(0) = &H8B
.Data4(1) = &HBB
.Data4(2) = &H0
.Data4(3) = &HAA
.Data4(4) = &H0
.Data4(5) = &H30
.Data4(6) = &HC
.Data4(7) = &HAB
End With

With uPicInfo
.Size = Len(uPicInfo)
.Type = PICTYPE_BITMAP
.hPic = hPic
.hPal = 0
End With

OleCreatePictureIndirect uPicInfo, IID_IDispatch, True,
IPic Set ConvertToIPicture = IPic
End Function



"Greg Maxey"
wrote in message
...
Bob,

Thanks for posting back. I think I am getting close, but
still not there. I added the two functions and changed my
callback as shown below. I used an image located on my hard
drive because I know how to identify it with a string. When
I try to run the code, I get and error on this line: Dim
uGdiInput As GdiplusStartupInput Compile error user defined
type not defined. I assume that I am missing a reference, but
don't know which
one. Questions:

What reference do I need to load in the project?

How would I change "C:\Test.pgn" in the callback to
represent a file name that I have already placed in the Open
XML File file CustomUI\images folder?

Thanks.

Sub GetImage(control As IRibbonControl, ByRef image)
Set image = LoadImage("C:\Nose.pgn")
End Sub

Public Function LoadImage(ByVal strFName As String) As
IPicture Dim uGdiInput As GdiplusStartupInput
Dim hGdiPlus As Long
Dim hGdiImage As Long
Dim hBitmap As Long
uGdiInput.GdiplusVersion = 1
If GdiplusStartup(hGdiPlus, uGdiInput) = 0 Then
If GdipCreateBitmapFromFile(StrPtr(strFName), hGdiImage) = 0
Then GdipCreateHBITMAPFromBitmap hGdiImage, hBitmap, 0
Set LoadImage = ConvertToIPicture(hBitmap)
GdipDisposeImage hGdiImage
End If
GdiplusShutdown hGdiPlus
End If
End Function

Public Function ConvertToIPicture(ByVal hPic As Long) As
IPicture Dim uPicInfo As PICTDESC
Dim IID_IDispatch As GUID
Dim IPic As IPicture
Const PICTYPE_BITMAP = 1
With IID_IDispatch
.Data1 = &H7BF80980
.Data2 = &HBF32
.Data3 = &H101A
.Data4(0) = &H8B
.Data4(1) = &HBB
.Data4(2) = &H0
.Data4(3) = &HAA
.Data4(4) = &H0
.Data4(5) = &H30
.Data4(6) = &HC
.Data4(7) = &HAB
End With
With uPicInfo
.Size = Len(uPicInfo)
.type = PICTYPE_BITMAP
.hPic = hPic
.hpal = 0
End With
OleCreatePictureIndirect uPicInfo, IID_IDispatch, True, IPic
Set ConvertToIPicture = IPic
End Function



Bob Phillips wrote:
Oops, you also need the ConvertToPicture procedure


Public Function ConvertToIPicture(ByVal hPic As Long) As
IPicture Dim uPicInfo As PICTDESC
Dim IID_IDispatch As GUID
Dim IPic As IPicture

Const PICTYPE_BITMAP = 1

With IID_IDispatch
.Data1 = &H7BF80980
.Data2 = &HBF32
.Data3 = &H101A
.Data4(0) = &H8B
.Data4(1) = &HBB
.Data4(2) = &H0
.Data4(3) = &HAA
.Data4(4) = &H0
.Data4(5) = &H30
.Data4(6) = &HC
.Data4(7) = &HAB
End With

With uPicInfo
.Size = Len(uPicInfo)
.Type = PICTYPE_BITMAP
.hPic = hPic
.hPal = 0
End With

OleCreatePictureIndirect uPicInfo, IID_IDispatch, True,
IPic Set ConvertToIPicture = IPic
End Function



"Bob Phillips" wrote in message
...
Yes it does, an IPicture object.

Public Function LoadImage(ByVal strFName As String) As
IPicture Dim uGdiInput As GdiplusStartupInput
Dim hGdiPlus As Long
Dim hGdiImage As Long
Dim hBitmap As Long

uGdiInput.GdiplusVersion = 1

If GdiplusStartup(hGdiPlus, uGdiInput) = 0 Then
If GdipCreateBitmapFromFile(StrPtr(strFName),
hGdiImage) = 0 Then GdipCreateHBITMAPFromBitmap
hGdiImage, hBitmap, 0 Set LoadImage =
ConvertToIPicture(hBitmap) GdipDisposeImage
hGdiImage End If
GdiplusShutdown hGdiPlus
End If

End Function


--
HTH

Bob

(there's no email, no snail mail, but somewhere should be
gmail in my addy)

"Greg Maxey"
wrote in message
...
Bob,

Maybe I should and that looks promising. Unfortunaetly I
don't know how. Based on what you have shown, I assume
that there is another procedure involved name LoadImage. What
does it look like? Where does it go? What I have is
a Open Office Format file that I opened in Office
2007 Custom UI Editor. I used the picture icon on the
editor to load a custom picture named "CustomImage" in
the images folder. I can use this image on a control if I
use the attribute image="CustomImage" I read on one of
the many blogs that I have reviewed over the last
couple days that the getImage callback only accepts a
valid office conrol Id or a IPicture object. Does the
LoadImage("CustomImage") process you suggest have some
conversion process to process the image to a IPicture
object? Thanks Bob Phillips wrote:
Greg,

Shouldn't you be loading it?

Sub GetImage(Control As IRibbonControl, ByRef image)
Select Case Control.ID
Case "gallery1"
image = "ContentControlBuildingBlockGallery"
Case "gallery2"
Set image = LoadImage("CustomeImage" )
Case Else
'Do Nothing
End Select
End Sub



"Greg Maxey"
wrote in message
...
Hi,

First post here. I consider myself a dabbler not a
programmer. So if you can help, please help gently ;-)

Off an on for the past year or so I have been puzzling
(sometimes fretting)
over how to use the ribbon attribute getImage with a VBA
callback to dispaly
a custom image on a Word ribbon control. I have seen
code examples using C+,
.Net, VB, etc., which I don't have and don't know
anything about, that make
me believe that it can be done. When I try a VBA
callback like:

Sub GetImage(Control As IRibbonControl, ByRef image)
Select Case Control.ID
Case "gallery1"
image = "ContentControlBuildingBlockGallery" 'This
works Case "gallery2"
image = "CustomeImage" 'Where "CustomImage" is a png
format image file 'stored in the Open Office File
format zip container images folder. This doesn't work
Case Else
'Do Nothing
End Select
End Sub

Word throws an error stating "CustomImage" is not a
valid office control id.

The key it seems is a process that takes a *.png format
image file and converts it into a IPicture object that
Word at least thinks is a valid office
control id and then displays that image on the ribbon.

I have ordered Ken Puls book RibbonX hoping it will
provide a cookbook explanation of how this is done.

I am awaiting the arrival of the book, but I would
certainly appreciate learning how it is done.

Thanks.


--
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org

--
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org

--
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org

--
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org

--
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org

--
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org


--
Greg Maxey - Word MVP

My web site http://gregmaxey.mvps.org
Word MVP web site http://word.mvps.org