Re: extracticon api using vba (in Word or Excel)
From: Terry Hornsby (t.hornsby_at_lineone.net)
Date: 02/08/04
- Next message: Becky: "List Box"
- Previous message: Fred: "How to write a multi-formatted string to a Word doc?"
- In reply to: Lars-Eric Gisslén: "Re: extracticon api using vba (in Word or Excel)"
- Messages sorted by: [ date ] [ thread ]
Date: Sun, 8 Feb 2004 16:39:18 -0000
Lars-Eric,
Many thanks for all the help you've given. I took a look at enumchildwindows
& knew that the activewindows wasn't right. I even looked at GetWindowText &
had the vague notion I'd have to use one or more of them, but it's like
having pieces of a jigsaw & not knowing how they go together!
The tips you gave are certainly useful, because at least I know now WHAT api
calls to look at & how they can work together to get what I want. The
copyicon & bit-thingy apis might be useful later on, too. Finally, releasedc
& avoiding nesting is NOT something I had looked at, so those tips in
themselves are gold-dust.
Many thanks,
Terry.
P.S I might be able to use a repaint or refresh on the image if needed.
Alternatively, I might simply try to assign the images to commandbuttons &
kill two-birds with one stone (ie, clicking it will paste the image over to
whatever toolbar I want to create).
----------------------------------------------------------------------------
----------------
"Lars-Eric Gisslén" <nowhere@inter.net> wrote in message
news:uIWbl$j7DHA.2028@TK2MSFTNGP10.phx.gbl...
> Terry,
>
> I would not use nested calls like you do. GetWindowDC returns the DC for
the
> entire Window while GetDC returns the DC of the client area where the
> drawing should actually take place. Plus, DC's should always be relesed
with
> ReleaseDC(). The way you have coded it you have lost the handle to the DC
> and can not release it when you are done. Your code will propably lead to
> memory leakage.
>
> To find the correct control to draw in I think you will need some trial
and
> error. I would suggest you get the handle to the Window and use it in a
call
> to EnumChildWindows(). Create a callback function that is called from the
> EnumChildWindow. In the callback function can try to use call
GetWindowText
> to get the caption of the control or using SendMessage() with some of the
> WM_GET... parameters and to get some meaningful value from the control
that
> indentifies it.
>
> What you also have think about is the redrawing the Icons. If you open
> another application that covers your dialog you must find a way to trigger
> when your dialog is uncovered so you can redraw the icons. As you use
WinAPI
> calls to draw the Icons you are responsible for redrawing them when
needed.
> In my code example I had my code in a Method called Expose and that method
> is always called when a Windows needs to be repainted, fully or partial. I
> don't know if you can trigger that in VBA.
>
> I'm not so familiar with VBA forms so I can tell what to actually do, just
> give some hints. I'm not even a VB programmer so I'm a little bit lost
when
> it comes to deaper VB/VBA programming. My dev tool let's me take full
> control over every thing, when I want to, even the event handling at
> application level.
>
> "Terry Hornsby" <t.hornsby@lineone.net> skrev i meddelandet
> news:%23K8V5nh7DHA.2404@TK2MSFTNGP11.phx.gbl...
> > Lars-Eric,
> >
> > Your help was very much appreciated. By pasting in the two extra api
> > functions & amending the DrawIcon code to this:
> >
> > Call DrawIcon(GetWindowDC(GetActiveWindow), rowX,
> colX,
> > hIcon)
> >
> > The rest of the code worked & I got a nice neat row of icons on my
form -
> > except for one thing - the icons were ON my form (top left) instead of
> > pasted into the image control on the form. I've had a look through the
api
> > index to see how I can get a hook on the image control, but no luck,
> unless
> > SENDMESSAGE is the api I need for a callback to the drawicon api, but it
> > isn't clear.
> >
> > Can anyone help with this bit?!
> >
> > Best,
> >
> >
> > Terry.
> >
> >
> > "Terry Hornsby" <t.hornsby@lineone.net> wrote in message
> > news:%231sDV8a7DHA.1716@TK2MSFTNGP10.phx.gbl...
> > > Lars-Eric,
> > >
> > > Many thanks for the help.
> > >
> > > I'll take a close look later & see if I can adapt the example you
gave.
> > >
> > >
> > >
> > > Best wishes,
> > >
> > > Terry.
> > >
> > > ---------------
> > >
> > >
> > > "Lars-Eric Gisslén" <nowhere@inter.net> wrote in message
> > > news:OH$QgPa7DHA.2712@tk2msftngp13.phx.gbl...
> > > > Terry,
> > > >
> > > > When you Win API to do the drawing you must allways draw to the
device
> > > > context, never mind if the context is a printer driver or a Window
> (even
> > a
> > > > control is a Window). So, you must get the device context for the
> Window
> > > to
> > > > draw the icon on. You normally don't draw an Icon in a control but
on
> > the
> > > > Windows/dialogs surface. To get the device context for your Dialog
> (Form
> > > in
> > > > VBA) you should be able to it by calling the WinAPI function
> > > > GetActiveWindow. With handle returned you acn get the handle to the
> > device
> > > > context by calling GetDC() Win API function.
> > > >
> > > > The code below shows how I draw an Icon on a dialog but from a
> different
> > > > development tool. I guess you can convert the code to VBA and make
it
> > > > working: Replace the SELF:Handle() with the handle returned from
> > > > GetActiveWindow()
> > > >
> > > > METHOD Expose() CLASS YesNoAllBox
> > > > //s Call Back method that is called when the Window needs to be
> > repainted
> > > > //l The Icon set in code, or default Icon, will be painted in the
> method
> > > > //r NIL, nothing to return
> > > >
> > > > LOCAL hIcon AS PTR
> > > > LOCAL hDC AS PTR
> > > >
> > > > SUPER:Expose()
> > > >
> > > > IF SELF:MessageIcon <> NULL_PTR // Load Icon, if any
> > > > hIcon := LoadIcon(0, SELF:MessageIcon) // Load a default Windows
> > Icon
> > > > hDC := GetDC(SELF:Handle()) // Get the Device Context of the
> Dialog
> > > > DrawIcon(hDC, 20, 20, hIcon) // Paint the Icon on the surface at
> > fixed
> > > > possition
> > > > ReleaseDC(SELF:Handle(), hDC) // Device Contexts must always be
> > > released
> > > > hIcon := NULL_PTR
> > > > ENDIF
> > > >
> > > > RETURN NIL
> > > >
> > > > --
> > > > Regards,
> > > > Lars-Eric Gisslén
> > > >
> > > > "Terry Hornsby" <t.hornsby@lineone.net> skrev i meddelandet
> > > > news:uIVdltZ7DHA.2676@TK2MSFTNGP10.phx.gbl...
> > > > > How can I use the EXTRACTICON & DRAWICONS apis within vba to: -
> > > > >
> > > > > (1) extract icons from files
> > > > > hIcon = ExtractIcon(0&, sIconFile, cnt)
> > > > > appears to work, but as DRAWICON doesn't seem to do anything, I'm
> none
> > > the
> > > > > wiser.
> > > > >
> > > > > (2) paste the icon images to a userform. My attempt to adapt the
> call
> > > > > doesn't work:
> > > > > Call DrawIcon(Me.Img1.Height, rowX, colX, hIcon)
> > > > > original code:
> > > > > Call DrawIcon(Picture1.hdc, x, Y, hIcon)
> > > > > doesn't work either because image controls on userforms do not
have
> a
> > > > "hdc"
> > > > > property. I'm assuming this is 'height'. ("hicon" would appear to
be
> > the
> > > > > pointer to the actual icon).
> > > > >
> > > > > (3) Export the extracted icons to a file or copy them to a button
> face
> > > (in
> > > > > other words, how do I get the code to recognise I have selected an
> > .ico
> > > > file
> > > > > from the form or by looping thru code?).
> > > > >
> > > > > The api calls I'm making are: -
> > > > >
> > > > > Private Declare Function DrawIcon Lib "user32" _
> > > > >
> > > > > (ByVal hdc As Long, _
> > > > >
> > > > > ByVal x As Long, _
> > > > >
> > > > > ByVal Y As Long, _
> > > > >
> > > > > ByVal hIcon As Long) As Long
> > > > >
> > > > >
> > > > >
> > > > > Private Declare Function ExtractIcon Lib "shell32" _
> > > > >
> > > > > Alias "ExtractIconA" _
> > > > >
> > > > > (ByVal hInst As Long, _
> > > > >
> > > > > ByVal lpszExeFileName As String, _
> > > > >
> > > > > ByVal nIconIndex As Long) As Long
> > > > >
> > > > >
> > > > >
> > > > > Private Declare Function DestroyIcon Lib "user32" _
> > > > >
> > > > > (ByVal hIcon As Long) As Long
> > > > >
> > > > >
> > > > >
> > > > > Is it just that I should be using command buttons (& button faces)
> > > rather
> > > > > than trying to pull the images into an image control as you can do
> > with
> > > > > picture controls in vb.net?
> > > > >
> > > > > ---------------------------------------------------
> > > > >
> > > > >
> > > > >
> > > > > This bit is just to respond to Helmut: -
> > > > >
> > > > > The ExtractIcon method is exactly what I meant.
> > > > >
> > > > > I already have: -
> > > > >
> > > > > (1) several routines & utilities to get the button faces & face
ids
> > from
> > > > > Office applications;
> > > > >
> > > > > (2) an api based browse for folder/file routine from which I can
> pick
> > a
> > > > file
> > > > > to examine for hidden .ico files. I have no intention of
extracting
> > ALL
> > > > > icons willy-nilly into any file;
> > > > >
> > > > > (3) a third party utility to extract icons. I am aware of
> Microangelo.
> > I
> > > > > don't need it; &
> > > > >
> > > > > (4) a utility to convert .ico files to .bmp files & to import
these
> as
> > > > > button faces on command bar buttons*.
> > > > >
> > > > > *I find storing the icons this way (in a folder) means that I have
a
> > > well
> > > > of
> > > > > images I can readily use to create my own office toolbars with
> > > distinctive
> > > > &
> > > > > possibly more meaningful button faces than those available from
the
> > > > built-in
> > > > > faces for Office.
> > > > >
> > > > > For example, if I wanted a commandbar button to call a non-office
> > > > > application, wouldn't it be neat to have that application's icon
as
> > the
> > > > > button face? Wouldn't it be a drag to have to write reams of code
> > every
> > > > time
> > > > > I wanted to do that, when I can simply use a browse for file form
&
> > > > extract
> > > > > whatever icon I wanted whenever I wanted?
> > > > >
> > > > > Using Apis within vba is entirely possible, Helmut, & if you are
to
> > > > presume
> > > > > to help people with problems like this you should at least be
aware
> > that
> > > > the
> > > > > functionality is there.
> > > > >
> > > > > The reasons for wanting to use apis directly are: (a) no
additional
> > > > > overheads going through the scripting or shell libraries (b) Most
of
> > my
> > > > code
> > > > > aleady calls many of the api functions EXTRACTICON also uses, so
> there
> > > > would
> > > > > be unnecessary redundancy using scripting; (c) I believe it's
> > marginally
> > > > > quicker using apis directly (d) I don't have to set a reference to
> the
> > > > other
> > > > > libraries in my utility, which makes it more user-friendly, more
> > > portable.
> > > > >
> > > > > I am aware that calling these apis from within vba is possible, I
> have
> > > 95%
> > > > > of the code worked out to do it.
> > > > >
> > > > > So, my original questions still stand.
> > > > >
> > > > > Many thanks, however, for giving it a go.
> > > > >
> > > > > Best wishes,
> > > > >
> > > > > Terry.
> > > > >
> > > > > -------------------------------------------------------
> > > > >
> > > > >
> > > > > "Helmut Weber" <elmkqznfwvccbf@mailinator.com> wrote in message
> > > > > news:uic920lgj86fpov7ro433tl4s7ebsnv8ek@4ax.com...
> > > > > > Hi Terry,
> > > > > > why api at all?
> > > > > > >I would like to be able to extract all the icons from a file
and:
> > > > > > Really? From just 1 file or from any file? The second would mean
> to
> > > > > > check any (!) file for possibly contained icons, and to extract
> > them.
> > > > > > A program namend Microangelo did that. May be, it is still
> > available.
> > > > > > But anyway, a program that extracts all icons from all files on
a
> > 400
> > > > > > GB Server and stores them in seperate files in an icon-folder
> would
> > be
> > > > > > of no help, if the icons weren't classified at the same time
> > according
> > > > > > to there possible meaning.
> > > > > > >(b) export the icons to a folder
> > > > > > What would that be good for? Wouldn't it be sufficient, to store
> > icons
> > > > > > and FaceIDs in an Excel-*** or a in a table in a Word-File?
> > > > > > >And I can't figure out what the vba equivalents are!
> > > > > > If you are talking about any icon in any file, there might be no
> > > > > > VBA equivalent at all.
> > > > > > Collecting faces of icons and the VBA-IDs is not that difficult.
> > > > > > A very, very limited demo using the commandbar "Standard" to
show
> > > > > > the principles:
> > > > > > (It is assumed, that there is a "1 row 2 column table".)
> > > > > >
> > > > > > Dim c As CommandBar
> > > > > > Dim l As Long
> > > > > > Dim s As String
> > > > > > Dim t As Table
> > > > > > Set t = ActiveDocument.Tables(1)
> > > > > > Set c = CommandBars("Standard")
> > > > > > For l = 1 To c.Controls.Count
> > > > > > c.Controls.Item(l).CopyFace
> > > > > > s = CStr(c.Controls.Item(l).FaceId)
> > > > > > t.Cell(l, 1).Select
> > > > > > Selection.Paste
> > > > > > t.Cell(l, 2).Select
> > > > > > Selection.TypeText Text:=s
> > > > > > t.Rows.Add ' a once redundant empty row
> > > > > > Next
> > > > > > Greetings from Bavaria, Germany
> > > > > > Helmut Weber
> > > > > > "red.sys" & chr$(64) & "t-online.de"
> > > > > > Word XP, Win 98
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > >
> > > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>
- Next message: Becky: "List Box"
- Previous message: Fred: "How to write a multi-formatted string to a Word doc?"
- In reply to: Lars-Eric Gisslén: "Re: extracticon api using vba (in Word or Excel)"
- Messages sorted by: [ date ] [ thread ]