Hello LiamFitz and GimmieKnowledge,
Thank you so much for reading the 'Microsoft Access 2010 Programmer's Reference' book and for posting your questions here. I saw the questions here and I wanted to follow up to see if I could help you guys solve your problems!
Ok, so right off, I should say that I personally did not write this chapter and am not intimately familiar with it, but I did have a chance to review both of your questions and pages 285-287 (that you mentioned) in the book. I also tested the code that was provided in the sample files for the book and I had to modify things slightly to make it work, but I WAS ABLE to get this to work after a bit of tweaking the sample code provided. So, a couple of things to mention right away:
1. An ICO (.ico) file is a standard "icon" file. That is how I tested this and I did not try it with a PNG file...so that may or may not work, I'm not sure, but you can always test it with my code below.
2. For the form to show a custom icon (in MS Access 2010), the form MUST BE A POP-UP form. If the form is just a tabbed document, it WILL NOT show the custom icon that can be loaded with this code.
*** So please be aware of those 2 items when reviewing this example. ***
So, as for my example, I just created a new database with a new form in it, and placed the code example from the book behind it, but again, I had to modify the original code sample slightly. Also, my code example (below) expects the ICO file to be at the "C:\Sample.ico" location on your computer, and I have included this sample icon with the example database (as an attachment in the form) so that you can copy it to your "C:\" drive and test this code out for yourself. The complete code for the form (that ended up working for me) was this code:
Code:
Option Explicit
Option Compare Database
#If Win64 = 1 And VBA7 = 1 Then
' Declare the 64-bit 'Load Image' function from the user32.dll
Private Declare PtrSafe Function LoadImage Lib "user32" Alias "LoadImageA" ( _
ByVal hInst As LongPtr, _
ByVal lpsz As String, _
ByVal un1 As Long, _
ByVal n1 As Long, _
ByVal n2 As Long, _
ByVal un2 As Long _
) As LongPtr
' Declare the 64-bit 'Send Message' function from the user32.dll
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hWnd As LongPtr, _
ByVal wMsg As Long, _
ByVal wParam As LongPtr, _
LParam As Any _
) As Long
' Declare the 64-bit 'Format Message' function from the kernel32.dll
Private Declare PtrSafe Function FormatMessage Lib "kernel32" Alias "FormatMessageA" ( _
ByVal dwFlags As Long, _
lpSource As Long, _
ByVal dwMessageId As Long, _
ByVal dwLanguageId As Long, _
ByVal lpBuffer As String, _
ByVal nSize As Long, _
Arguments As Any _
) As Long
#ElseIf VBA6 = 1 Then
' Declare the 32-bit 'Load Image' function from the user32.dll
Private Declare Function LoadImage Lib "user32" Alias "LoadImageA" ( _
ByVal hInst As Long, _
ByVal lpsz As String, _
ByVal un1 As Long, _
ByVal n1 As Long, _
ByVal n2 As Long, _
ByVal un2 As Long _
) As Long
' Declare the 32-bit 'Send Message' function from the user32.dll
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
LParam As Any _
) As Long
' Declare the 32-bit 'Format Message' function from the kernel32.dll
Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" ( _
ByVal dwFlags As Long, _
lpSource As Long, _
ByVal dwMessageId As Long, _
ByVal dwLanguageId As Long, _
ByVal lpBuffer As String, _
ByVal nSize As Long, _
Arguments As Any _
) As Long
#End If
Private Const FORMAT_MESSAGE_FROM_SYSTEM As Long = &H1000
Private Const IMAGE_ICON As Long = 1 'Image type constants
Private Const LR_LOADFROMFILE As Long = &H10 'un2 Flags
'Message parameters
Private Const WM_SETICON As Long = &H80
Private Const ICON_SMALL As Long = 0
'Default image size for the Access Titlebar
Private Const IMG_DEFAULT_HEIGHT As Long = 16
Private Const IMG_DEFAULT_WIDTH As Long = 16
Public Sub SetFormIcon(hWnd As Long, strIcon As String)
Dim hIcon As Long
Dim lngReturn As Long
On Error Resume Next
'Pass the strIcon parameter as the icon path
hIcon = LoadImage(0, strIcon, IMAGE_ICON, IMG_DEFAULT_WIDTH, _
IMG_DEFAULT_HEIGHT, LR_LOADFROMFILE)
'Now check for an error
If hIcon <> 0 Then
lngReturn = SendMessage(hWnd, WM_SETICON, ICON_SMALL, ByVal hIcon)
Else
'Display the error
MsgBox "The last DLL error was: " & GetAPIErrorMessage(Err.LastDllError)
End If
End Sub
Public Function GetAPIErrorMessage(lngError As Long) As String
Dim strMessage As String
Dim lngReturn As Long
Dim nSize As Long
strMessage = Space(256)
nSize = Len(strMessage)
lngReturn = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, _
lngError, 0, strMessage, nSize, 0)
If lngReturn > 0 Then
GetAPIErrorMessage = Replace(Left(strMessage, lngReturn), vbCrLf, "")
Else
GetAPIErrorMessage = "Error not found."
End If
End Function
Private Sub Form_Load()
SetFormIcon Me.hWnd, "C:\Sample.ico"
End Sub
So, once I ran this code with a Pop-up form, I didn't have any problems seeing the icon show up in the top-left corner of the form. You can download my example database and code for your own testing from here:
http://www.imaginethought.net/c/exam...013-8-15.accdb
And just remember to save the "Sample.ico" file (that is an attachment on the "frmSample" form in this database) to your "C:\Sample.ico" location. Also, be sure to enable the database when testing this, otherwise the VBA code will not run (...I guess that goes without saying though...).
Anyway, I really hope this helps, but if you have any other questions or need any other help with this, please just let me know. And thank you again for reading the 'Microsoft Access 2010 Programmer's Reference' book, we truly appreciate your readership!
Thanks again,