View Single Post
  #15   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,

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