Use system tray & icons in VBA (Access) - winapi

I've found a few tutorials that explain how to use the windows API to get a custom icon in the system tray.
These are all for Visual Basic, and they don't seem to be scaling to VBA well.
I'm following this short tutorial:
http://atchoo.org/vb/systray.php
Basically, you have to set the hIcon value (a 'long' variable) but it does not work.
I've tried to use the LoadPicture() function, which does not give me any errors, but also fails to add a new icon.
I can't supply Me.Icon, nor can I set it on Form_Load.
Does anyone have any experience with this?

Using loadpicture was the right approach, but not directly.
I had to define a new variable first, and load that.
Like this:
Dim myPicture As IPictureDisp
strPath = "F:\Databank\Icons\stone.ico"
Set myPicture = LoadPicture(strPath)
And then, somewhere along the way, I could set hIcon without problems:
.hIcon = myPicture
When I change the trayicon (like, say, adding a balloontip) I have to supply the icon information again, too.

Related

How do I add a hyperlinks to image using VBA?

I have a script that will run on GPO on Windows Server 2012.
It's pretty simple stuff, but I cannot fathom how to add a hyperlink around an image! I have:
objSelection.InlineShapes.AddPicture "linktoimage.html"
This works a dream, I can see the image and there is no issue. But how do I add a hyperlink to this image so that when folks click on it they are taken to my desired hyperlink location. I know adding an image is simply a line of code, hoping for same for adding a hyperlink.
I am not doing this in excel or anything of the kind, just Notepad++
Assuming this is about Word, you need to save a reference the shape you just created and then use that reference as an argument to Document.Hyperlinks.Add
Option Explicit
Sub LinkImageTest()
Dim oSelection As Selection
Dim oDocument As Document
Dim oShape As InlineShape
Set oSelection = Application.Selection
Set oDocument = oSelection.Document
Set oShape = oSelection.InlineShapes.AddPicture("https://yt3.ggpht.com/-Pde_zs2tuj0/AAAAAAAAAAI/AAAAAAAAAAA/iBq9KSwTTLk/s88-c-k-no-mo-rj-c0xffffff/photo.jpg")
oDocument.Hyperlinks.Add oShape, "http://www.microsoft.com"
End Sub

How do I set program title and icon in Clutter toolkit?

I have recently been learning how to program with the Clutter GUI toolkit. One thing I haven't been able to figure out is how to set the programs title and icon for the window manager.
As illustrated in the image below, Gnome Shell says that the program name is "Unknown" and that the program does not have an icon.
So, how do I do this?
you cannot do this from Clutter: the windowing system API inside Clutter only allows basic operations.
if you want proper integration in a windowing system you should use Clutter-GTK, and embed a ClutterStage into a Gtk application.
In theory, you can do that in this way:
let stage = Clutter.Stage.get_default ();
let gdkWind = ClutterGdk.get_stage_window (stage);
// The list most containt icons in different sizes.
let list = [GdkPixbuf.Pixbuf.new_from_file("test.png")];
gdkWind.set_icon_list(list);
//The next line not work
gdkWind.set_title("This title is not added");
In practice, you only will can load the icon and the windows title, but not the task bar title for the windows. The set_title won't work as Gdk.Window reference say it will (https://people.gnome.org/~gcampagna/docs/Gdk-3.0/Gdk.Window.set_title.html). Is then a Clutter issue, because is not a GDK "special case". But well is not working.

Deleting shape in PowerPoint programatically and undoing causes shape to be "lost"

(This seems mostly to be a PowerPoint 2007 specific problem, which I can't easily reproduce in PPT 2010)
Easy way to reproduce locally is to:
1) Insert a shape into blank slide
2) Run command: ActivePresentation.Slides(1).Shapes(1).Delete in immediate window in Visual Studio. (You can alternatively delete through C#)
3) Undo the deletion in the PowerPoint presentation (do this non-programatically)
For some reason, you cannot access the shape again using calls like:
ActivePresentation.Slides(1).Shapes(1) //Does not allow any methods/properties to work
The only thing I've remotely gotten is that through Selection.ShapeRange, you can kind of get a reference to the item, but most of the Properties/Methods throw ComExceptions when trying to using that object.
Does anyone know how I can re-get the shape or somehow refresh the presentation to get some clean Com Objects?
I can confirm in Ppt2007 SP3. Try as workaround .cut and .paste. Afterwards I was able to access the other methods/properties. - cheers, www.MSO-dlx.com
ActivePresentation.Slides(1).Shapes(1).Delete
Application.CommandBars.ExecuteMso "Undo" 'or manually Undo
ActiveWindow.Selection.SlideRange(1).Shapes(1).Cut
ActiveWindow.Selection.SlideRange(1).Shapes.Paste
ActiveWindow.Selection.SlideRange(1).Shapes(1).TextFrame.TextRange.Text = "ABC"
so, I can confirm that this is an issue; even in 2010 and found a "cheaper" alternative:
Public Sub arf()
Dim arf As Slide
Dim shape As shape
Dim shapes As shapes
Set shapes = ActivePresentation.Slides(1).shapes
Set shape = shapes(2)
shape.Select
shape.Delete
Application.CommandBars.ExecuteMso "Undo"
MsgBox ("shape: " & shape.Name & ",Type: " & shape.Type)
Set shapes = ActivePresentation.Slides(1).shapes
Set shape = Nothing
Set shape = shapes(2)
' Cut and paste makes this work, but not required...
'shape.Select
'shape.Cut
'shapes.Paste
'Set shape = Nothing
'Set shape = shapes(2)
Set arf = shape.Parent
MsgBox ("slide: " & arf.Name)
End Sub
Just now I have successfully solved the problem, share the web page which helped a lot : https://www.add-in-express.com/creating-addins-blog/2014/06/24/exception-hresult-0x800a01a8/
The critical point is releasing the object after deleting it,which is exactly as Skovly and sharkTwo did.However,I don't know how to do this using C#,and the link gave me the answer.
Marshal.ReleaseComObject(titleShape); titleShape = null;
Just like this.

Start by displaying print-layout in VS10 Report Designer when running the form

When I run my report from VS10, I have to switch everytime to print-layout. Because I need to make 100+ small adjustment to my big table, I have to press the print-layout button everytime to see the result.
Is there a way, I can set it up, so I start by seeing the print-layout when running the form?
It´s an old post but found the exact answer. Setting Print-Layout instead of setting Zoom mode for the ReportViewer.
ReportViewer1.SetDisplayMode(DisplayMode.PrintLayout)
It looks like you can adjust report viewer properties. I found a adjustment that sets the zoom, in your case (print layout = whole page) so the default would need to be changed.
Here is the VB script for it from MS.
'Declaration
<CategoryAttribute("Appearance")> _
<DefaultValueAttribute(ZoomMode.Percent)> _
Public Property ZoomMode As ZoomMode
'Usage
Dim instance As ReportViewer
Dim value As ZoomMode
value = instance.ZoomMode
instance.ZoomMode = value
I don't know if you have to use a # like value = 50 or if you can use value = Whole Page, it seems like the latter can be used since it bases the figures dimensions on the logical page to assume the view size.
Goood luck and check http://msdn.microsoft.com/en-us/library/microsoft.reporting.winforms.reportviewer.zoommode.aspx for further guidance and different code options.

How to copy to clipboard using Access/VBA?

Using VBA inside Access2003/2007.
How to copy the contents of a string variable to the clipboard?
This site recommends a creating a zero length TextBox, copying the string to the TextBox, then running DoCmd.RunCommand acCmdCopy. Ugh. I mean, we may go down the route. But still. Ugh.
While the MS knowledgebase article shows us how to do it but it involves a number of Windows API calls. Yuk.
Are those the only two options?
VB 6 provides a Clipboard object that makes all of this extremely simple and convenient, but unfortunately that's not available from VBA.
If it were me, I'd go the API route. There's no reason to be scared of calling native APIs; the language provides you with the ability to do that for a reason.
However, a simpler alternative is to use the DataObject class, which is part of the Forms library. I would only recommend going this route if you are already using functionality from the Forms library in your app. Adding a reference to this library only to use the clipboard seems a bit silly.
For example, to place some text on the clipboard, you could use the following code:
Dim clipboard As MSForms.DataObject
Set clipboard = New MSForms.DataObject
clipboard.SetText "A string value"
clipboard.PutInClipboard
Or, to copy text from the clipboard into a string variable:
Dim clipboard As MSForms.DataObject
Dim strContents As String
Set clipboard = New MSForms.DataObject
clipboard.GetFromClipboard
strContents = clipboard.GetText
User Leigh Webber on the social.msdn.microsoft.com site posted VBA code implementing an easy-to-use clipboard interface that uses the Windows API:
http://social.msdn.microsoft.com/Forums/en/worddev/thread/ee9e0d28-0f1e-467f-8d1d-1a86b2db2878
You can get Leigh Webber's source code here
If this link doesn't go through, search for "A clipboard object for VBA" in the Office Dev Center > Microsoft Office for Developers Forums > Word for Developers section.
I created the two classes, ran his test cases, and it worked perfectly inside Outlook 2007 SP3 32-bit VBA under Windows 7 64-bit. It will most likely work for Access.
Tip: To rename classes, select the class in the VBA 'Project' window, then click 'View' on the menu bar and click 'Properties Window' (or just hit F4).
With his classes, this is what it takes to copy to/from the clipboard:
Dim myClipboard As New vbaClipboard ' Create clipboard
' Copy text to clipboard as ClipboardFormat TEXT (CF_TEXT)
myClipboard.SetClipboardText "Text to put in clipboard", "CF_TEXT"
' Retrieve clipboard text in CF_TEXT format (CF_TEXT = 1)
mytxt = myClipboard.GetClipboardText(1)
He also provides other functions for manipulating the clipboard.
It also overcomes 32KB MSForms_DataObject.SetText limitation - the main reason why SetText often fails. However, bear in mind that, unfortunatelly, I haven't found a reference on Microsoft recognizing this limitation.
-Jim
I couldn't figure out how to use the API using the first Google results. Fortunately a thread somewhere pointed me to this link:
http://access.mvps.org/access/api/api0049.htm
Which works nicely. :)
Easy TWO line code:
It's not so complicated, I don't understand why all solutions found in the net are so complicated.
Sub StoreData()
Set objCP = CreateObject("HtmlFile")
objCP.ParentWindow.ClipboardData.SetData "text", "Some text for clipboard"
End Sub
There are many examples listed here but none seem to cover the direct way of using the API that also works with Access and Excel 32 bit and 64 bit.
I don't want to steal anyone else's work so I'm pointing to an article that has a solution.
https://stackoverflow.com/a/35512118/1898524
Following up on David's idea, if you want to pass in an argument, it has to be double-quoted.
Public Sub SetClipboardText(ByVal Text As String)
Dim QuotedText As String
QuotedText = """" & Text & """"
Set HtmlFileObject = CreateObject("HtmlFile")
HtmlFileObject.ParentWindow.ClipboardData.SetData "text", Eval(QuotedText)
End Sub

Resources