ShehzadMunir
asked on
Scale Mode Property
Scale Mode property is avaialable for normal forms but it is not available for MDI forms. What's the solution for this problem. Actually I am trying to show an application icon in the system tray but my application is an MDI based. I am using the following API
Private Declare Function Shell_NotifyIcon Lib "shell32" _
Alias "Shell_NotifyIconA" _
(ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean
The problem is that I want to know when user clicked the icon in the tray and for that though this API provides you a way to find that user has clicked the icon in th tray but that only works for SDI. that does not work for MDI since SDI uses the form's Scale Mode property which is not available in MDI form.
Best Regards
Shehzad Munir.
Private Declare Function Shell_NotifyIcon Lib "shell32" _
Alias "Shell_NotifyIconA" _
(ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean
The problem is that I want to know when user clicked the icon in the tray and for that though this API provides you a way to find that user has clicked the icon in th tray but that only works for SDI. that does not work for MDI since SDI uses the form's Scale Mode property which is not available in MDI form.
Best Regards
Shehzad Munir.
Ignore the scalemode stuff, just use X / Screen.TwipsPerPixelX to determine the value of the message parameter 512,514 etc.
I guess MDI form sizes are always in Twips? In that case, Tim is right.
ASKER
TimCottee you are absoluitely righ t and I also did the same thing but does not work out. Here is the code.
Please try the following code by adding this code to MDI Application and then find whether it works or not.
You need to add two command buttons and one common dialog control on the form. Well you can change those command button clicks with menu clicks. I did the same thing but does not work out with MDI Application.
Option Explicit
'Declare a user-defined variable to pass to the Shell_NotifyIcon
'function.
Private Type NOTIFYICONDATA
cbSize As Long
hWnd As Long
uId As Long
uFlags As Long
uCallBackMessage As Long
hIcon As Long
szTip As String * 64
End Type
'Declare the constants for the API function. These constants can be
'found in the header file Shellapi.h.
'The following constants are the messages sent to the
'Shell_NotifyIcon function to add, modify, or delete an icon from the
'taskbar status area.
Private Const NIM_ADD = &H0
Private Const NIM_MODIFY = &H1
Private Const NIM_DELETE = &H2
'The following constant is the message sent when a mouse event occurs
'within the rectangular boundaries of the icon in the taskbar status
'area.
Private Const WM_MOUSEMOVE = &H200
'The following constants are the flags that indicate the valid
'members of the NOTIFYICONDATA data type.
Private Const NIF_MESSAGE = &H1
Private Const NIF_ICON = &H2
Private Const NIF_TIP = &H4
'The following constants are used to determine the mouse input on the
'the icon in the taskbar status area.
'Left-click constants.
Private Const WM_LBUTTONDBLCLK = &H203 'Double-click
Private Const WM_LBUTTONDOWN = &H201 'Button down
Private Const WM_LBUTTONUP = &H202 'Button up
'Right-click constants.
Private Const WM_RBUTTONDBLCLK = &H206 'Double-click
Private Const WM_RBUTTONDOWN = &H204 'Button down
Private Const WM_RBUTTONUP = &H205 'Button up
'Declare the API function call.
Private Declare Function Shell_NotifyIcon Lib "shell32" _
Alias "Shell_NotifyIconA" _
(ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean
'Dimension a variable as the user-defined data type.
Dim nid As NOTIFYICONDATA
Private Sub Command1_Click()
'Click this button to add an icon to the taskbar status area.
'Set the individual values of the NOTIFYICONDATA data type.
nid.cbSize = Len(nid)
nid.hWnd = Form1.hWnd
nid.uId = vbNull
nid.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
nid.uCallBackMessage = WM_MOUSEMOVE
nid.hIcon = Form1.Icon
nid.szTip = "Taskbar Status Area Sample Program" & vbNullChar
'Call the Shell_NotifyIcon function to add the icon to the taskbar
'status area.
Shell_NotifyIcon NIM_ADD, nid
End Sub
Private Sub Command2_Click()
'Click this button to delete the added icon from the taskbar
'status area by calling the Shell_NotifyIcon function.
Shell_NotifyIcon NIM_DELETE, nid
End Sub
Private Sub Form_Load()
'Set the captions of the command button when the form loads.
Command1.Caption = "Add an Icon"
Command2.Caption = "Delete Icon"
End Sub
Private Sub Form_Terminate()
'Delete the added icon from the taskbar status area when the
'program ends.
Shell_NotifyIcon NIM_DELETE, nid
End Sub
Private Sub Form_MouseMove _
(Button As Integer, _
Shift As Integer, _
X As Single, _
Y As Single)
'Event occurs when the mouse pointer is within the rectangular
'boundaries of the icon in the taskbar status area.
Dim msg As Long
Dim sFilter As String
msg = X / Screen.TwipsPerPixelX
Select Case msg
Case WM_LBUTTONDOWN
Case WM_LBUTTONUP
Case WM_LBUTTONDBLCLK
CommonDialog1.DialogTitle = "Select an Icon"
sFilter = "Icon Files (*.ico)|*.ico"
sFilter = sFilter & "|All Files (*.*)|*.*"
CommonDialog1.Filter = sFilter
CommonDialog1.ShowOpen
If CommonDialog1.FileName <> "" Then
Form1.Icon = LoadPicture(CommonDialog1. FileName)
nid.hIcon = Form1.Icon
Shell_NotifyIcon NIM_MODIFY, nid
End If
Case WM_RBUTTONDOWN
Dim ToolTipString As String
ToolTipString = InputBox("Enter the new ToolTip:", _
"Change ToolTip")
If ToolTipString <> "" Then
nid.szTip = ToolTipString & vbNullChar
Shell_NotifyIcon NIM_MODIFY, nid
End If
Case WM_RBUTTONUP
Case WM_RBUTTONDBLCLK
End Select
End Sub
Please try the following code by adding this code to MDI Application and then find whether it works or not.
You need to add two command buttons and one common dialog control on the form. Well you can change those command button clicks with menu clicks. I did the same thing but does not work out with MDI Application.
Option Explicit
'Declare a user-defined variable to pass to the Shell_NotifyIcon
'function.
Private Type NOTIFYICONDATA
cbSize As Long
hWnd As Long
uId As Long
uFlags As Long
uCallBackMessage As Long
hIcon As Long
szTip As String * 64
End Type
'Declare the constants for the API function. These constants can be
'found in the header file Shellapi.h.
'The following constants are the messages sent to the
'Shell_NotifyIcon function to add, modify, or delete an icon from the
'taskbar status area.
Private Const NIM_ADD = &H0
Private Const NIM_MODIFY = &H1
Private Const NIM_DELETE = &H2
'The following constant is the message sent when a mouse event occurs
'within the rectangular boundaries of the icon in the taskbar status
'area.
Private Const WM_MOUSEMOVE = &H200
'The following constants are the flags that indicate the valid
'members of the NOTIFYICONDATA data type.
Private Const NIF_MESSAGE = &H1
Private Const NIF_ICON = &H2
Private Const NIF_TIP = &H4
'The following constants are used to determine the mouse input on the
'the icon in the taskbar status area.
'Left-click constants.
Private Const WM_LBUTTONDBLCLK = &H203 'Double-click
Private Const WM_LBUTTONDOWN = &H201 'Button down
Private Const WM_LBUTTONUP = &H202 'Button up
'Right-click constants.
Private Const WM_RBUTTONDBLCLK = &H206 'Double-click
Private Const WM_RBUTTONDOWN = &H204 'Button down
Private Const WM_RBUTTONUP = &H205 'Button up
'Declare the API function call.
Private Declare Function Shell_NotifyIcon Lib "shell32" _
Alias "Shell_NotifyIconA" _
(ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean
'Dimension a variable as the user-defined data type.
Dim nid As NOTIFYICONDATA
Private Sub Command1_Click()
'Click this button to add an icon to the taskbar status area.
'Set the individual values of the NOTIFYICONDATA data type.
nid.cbSize = Len(nid)
nid.hWnd = Form1.hWnd
nid.uId = vbNull
nid.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
nid.uCallBackMessage = WM_MOUSEMOVE
nid.hIcon = Form1.Icon
nid.szTip = "Taskbar Status Area Sample Program" & vbNullChar
'Call the Shell_NotifyIcon function to add the icon to the taskbar
'status area.
Shell_NotifyIcon NIM_ADD, nid
End Sub
Private Sub Command2_Click()
'Click this button to delete the added icon from the taskbar
'status area by calling the Shell_NotifyIcon function.
Shell_NotifyIcon NIM_DELETE, nid
End Sub
Private Sub Form_Load()
'Set the captions of the command button when the form loads.
Command1.Caption = "Add an Icon"
Command2.Caption = "Delete Icon"
End Sub
Private Sub Form_Terminate()
'Delete the added icon from the taskbar status area when the
'program ends.
Shell_NotifyIcon NIM_DELETE, nid
End Sub
Private Sub Form_MouseMove _
(Button As Integer, _
Shift As Integer, _
X As Single, _
Y As Single)
'Event occurs when the mouse pointer is within the rectangular
'boundaries of the icon in the taskbar status area.
Dim msg As Long
Dim sFilter As String
msg = X / Screen.TwipsPerPixelX
Select Case msg
Case WM_LBUTTONDOWN
Case WM_LBUTTONUP
Case WM_LBUTTONDBLCLK
CommonDialog1.DialogTitle = "Select an Icon"
sFilter = "Icon Files (*.ico)|*.ico"
sFilter = sFilter & "|All Files (*.*)|*.*"
CommonDialog1.Filter = sFilter
CommonDialog1.ShowOpen
If CommonDialog1.FileName <> "" Then
Form1.Icon = LoadPicture(CommonDialog1.
nid.hIcon = Form1.Icon
Shell_NotifyIcon NIM_MODIFY, nid
End If
Case WM_RBUTTONDOWN
Dim ToolTipString As String
ToolTipString = InputBox("Enter the new ToolTip:", _
"Change ToolTip")
If ToolTipString <> "" Then
nid.szTip = ToolTipString & vbNullChar
Shell_NotifyIcon NIM_MODIFY, nid
End If
Case WM_RBUTTONUP
Case WM_RBUTTONDBLCLK
End Select
End Sub
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Yes this is the code from MSDN. But I have slightlty modified it in this way that I have created a module and changed function names accordingly as follows.
In this code I have three functions as :
1) AddIconToTaskBar()
2) RemoveIconFromTaskBar()
3) IdentifyIconClicked
First function for Adding Icon second for removing the icon and thirsd for Idenfying whether Icon clicked.
Note : fMainForm is a global variable for Main MDI Form.
In the Main MDI Form I have called these functions as
1) At load of the main form I call AddIconToTaskBar()
2) At unload of the main form I call RemoveIconFromTaskBar()
3) But I don't know where should I place call for IdentifyIconClicked because when my application would come to know that form icon in the tray has been clicked. That's all I don't know. In other words when the user click the icon in the tray that's all I need to know.
Code for Module is as follows:
Option Explicit
Public OldWindowProc As Long
'Declare the API function call.
Private Declare Function Shell_NotifyIcon Lib "shell32" _
Alias "Shell_NotifyIconA" _
(ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean
'Declare a user-defined variable to pass to the Shell_NotifyIcon
'function.
Private Type NOTIFYICONDATA
cbSize As Long
hwnd As Long
uId As Long
uFlags As Long
uCallBackMessage As Long
hIcon As Long
szTip As String * 64
End Type
'Declare the constants for the API function. These constants can be
'found in the header file Shellapi.h.
'The following constants are the messages sent to the
'Shell_NotifyIcon function to add, modify, or delete an icon from the
'taskbar status area.
Private Const NIM_ADD = &H0
Private Const NIM_MODIFY = &H1
Private Const NIM_DELETE = &H2
'The following constant is the message sent when a mouse event occurs
'within the rectangular boundaries of the icon in the taskbar status
'area.
Private Const WM_MOUSEMOVE = &H200
'The following constants are the flags that indicate the valid
'members of the NOTIFYICONDATA data type.
Private Const NIF_MESSAGE = &H1
Private Const NIF_ICON = &H2
Private Const NIF_TIP = &H4
'The following constants are used to determine the mouse input on the
'the icon in the taskbar status area.
'Left-click constants.
Private Const WM_LBUTTONDBLCLK = &H203 'Double-click
Private Const WM_LBUTTONDOWN = &H201 'Button down
Private Const WM_LBUTTONUP = &H202 'Button up
'Right-click constants.
Private Const WM_RBUTTONDBLCLK = &H206 'Double-click
Private Const WM_RBUTTONDOWN = &H204 'Button down
Private Const WM_RBUTTONUP = &H205 'Button up
'Dimension a variable as the user-defined data type.
Dim NID As NOTIFYICONDATA
Public Sub AddIconToTaskBar()
'add an icon to the taskbar status area.
' Install the new WindowProc.
' OldWindowProc = SetWindowLong(fMainForm.hw nd, GWL_WNDPROC, AddressOf NewWindowProc)
'Set the individual values of the NOTIFYICONDATA data type.
NID.cbSize = Len(NID)
NID.hwnd = fMainForm.hwnd
NID.uId = vbNull
NID.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
NID.uCallBackMessage = WM_MOUSEMOVE
NID.hIcon = fMainForm.Icon
NID.szTip = "SKMC Universe Project" & vbNullChar
'Call the Shell_NotifyIcon function to add the icon to the taskbar
'status area.
Shell_NotifyIcon NIM_ADD, NID
End Sub
Public Sub RemoveIconFromTaskBar()
' to delete the added icon from the taskbar
'status area by calling the Shell_NotifyIcon function.
'Also keep in mind to delete the added icon from the
'taskbar status area when the program ends.
With NID
.uFlags = 0
End With
Shell_NotifyIcon NIM_DELETE, NID
End Sub
Public Sub IdentifyIconClicked(lngMes sagePassed As Long)
'Is called when the mouse pointer is within the rectangular
'boundaries of the icon in the taskbar status area.
Select Case lngMessagePassed
Case WM_LBUTTONDOWN
MsgBox "Left button clicked down"
Case WM_LBUTTONUP
MsgBox "Left button clicked up"
Case WM_LBUTTONDBLCLK
MsgBox "Left button double clicked"
Case WM_RBUTTONDOWN
Case WM_RBUTTONUP
Case WM_RBUTTONDBLCLK
End Select
End Sub
In this code I have three functions as :
1) AddIconToTaskBar()
2) RemoveIconFromTaskBar()
3) IdentifyIconClicked
First function for Adding Icon second for removing the icon and thirsd for Idenfying whether Icon clicked.
Note : fMainForm is a global variable for Main MDI Form.
In the Main MDI Form I have called these functions as
1) At load of the main form I call AddIconToTaskBar()
2) At unload of the main form I call RemoveIconFromTaskBar()
3) But I don't know where should I place call for IdentifyIconClicked because when my application would come to know that form icon in the tray has been clicked. That's all I don't know. In other words when the user click the icon in the tray that's all I need to know.
Code for Module is as follows:
Option Explicit
Public OldWindowProc As Long
'Declare the API function call.
Private Declare Function Shell_NotifyIcon Lib "shell32" _
Alias "Shell_NotifyIconA" _
(ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean
'Declare a user-defined variable to pass to the Shell_NotifyIcon
'function.
Private Type NOTIFYICONDATA
cbSize As Long
hwnd As Long
uId As Long
uFlags As Long
uCallBackMessage As Long
hIcon As Long
szTip As String * 64
End Type
'Declare the constants for the API function. These constants can be
'found in the header file Shellapi.h.
'The following constants are the messages sent to the
'Shell_NotifyIcon function to add, modify, or delete an icon from the
'taskbar status area.
Private Const NIM_ADD = &H0
Private Const NIM_MODIFY = &H1
Private Const NIM_DELETE = &H2
'The following constant is the message sent when a mouse event occurs
'within the rectangular boundaries of the icon in the taskbar status
'area.
Private Const WM_MOUSEMOVE = &H200
'The following constants are the flags that indicate the valid
'members of the NOTIFYICONDATA data type.
Private Const NIF_MESSAGE = &H1
Private Const NIF_ICON = &H2
Private Const NIF_TIP = &H4
'The following constants are used to determine the mouse input on the
'the icon in the taskbar status area.
'Left-click constants.
Private Const WM_LBUTTONDBLCLK = &H203 'Double-click
Private Const WM_LBUTTONDOWN = &H201 'Button down
Private Const WM_LBUTTONUP = &H202 'Button up
'Right-click constants.
Private Const WM_RBUTTONDBLCLK = &H206 'Double-click
Private Const WM_RBUTTONDOWN = &H204 'Button down
Private Const WM_RBUTTONUP = &H205 'Button up
'Dimension a variable as the user-defined data type.
Dim NID As NOTIFYICONDATA
Public Sub AddIconToTaskBar()
'add an icon to the taskbar status area.
' Install the new WindowProc.
' OldWindowProc = SetWindowLong(fMainForm.hw
'Set the individual values of the NOTIFYICONDATA data type.
NID.cbSize = Len(NID)
NID.hwnd = fMainForm.hwnd
NID.uId = vbNull
NID.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
NID.uCallBackMessage = WM_MOUSEMOVE
NID.hIcon = fMainForm.Icon
NID.szTip = "SKMC Universe Project" & vbNullChar
'Call the Shell_NotifyIcon function to add the icon to the taskbar
'status area.
Shell_NotifyIcon NIM_ADD, NID
End Sub
Public Sub RemoveIconFromTaskBar()
' to delete the added icon from the taskbar
'status area by calling the Shell_NotifyIcon function.
'Also keep in mind to delete the added icon from the
'taskbar status area when the program ends.
With NID
.uFlags = 0
End With
Shell_NotifyIcon NIM_DELETE, NID
End Sub
Public Sub IdentifyIconClicked(lngMes
'Is called when the mouse pointer is within the rectangular
'boundaries of the icon in the taskbar status area.
Select Case lngMessagePassed
Case WM_LBUTTONDOWN
MsgBox "Left button clicked down"
Case WM_LBUTTONUP
MsgBox "Left button clicked up"
Case WM_LBUTTONDBLCLK
MsgBox "Left button double clicked"
Case WM_RBUTTONDOWN
Case WM_RBUTTONUP
Case WM_RBUTTONDBLCLK
End Select
End Sub
ShehzadMunir,
This is starting to get to be quite a lot for 10 points (but that has never stopped me before).
You have to think about what is happening here, when you issue the setwindowlong function call, you are redefining the recipient of any messages sent to the region encompassing the tray icon in the system tray. In this case to the Mouse_Move event of the form identified by the hWnd parameter: fMainForm.hWnd so the MDI main form must have the MDIForm_MouseMove event declared in it to receive and process these messages. You could of course hand that back to your identify function by
Private Sub MDIForm_MouseMove( ...)
IdentifyIconClicked(X)
End Sub
But this perhaps doesn't really do what you want it to do.
I would perhaps suggest a slightly different approach for you. If this is the route that you want to take and create a "standard" function that can be placed in one or more applications then create a usercontrol instead. You can use the usercontrol to receive the messages from the icon being clicked, expose the necessary properties and functions (including events if required) and can compile this as a seperate OCX which you can insert into any application or form.
This is starting to get to be quite a lot for 10 points (but that has never stopped me before).
You have to think about what is happening here, when you issue the setwindowlong function call, you are redefining the recipient of any messages sent to the region encompassing the tray icon in the system tray. In this case to the Mouse_Move event of the form identified by the hWnd parameter: fMainForm.hWnd so the MDI main form must have the MDIForm_MouseMove event declared in it to receive and process these messages. You could of course hand that back to your identify function by
Private Sub MDIForm_MouseMove( ...)
IdentifyIconClicked(X)
End Sub
But this perhaps doesn't really do what you want it to do.
I would perhaps suggest a slightly different approach for you. If this is the route that you want to take and create a "standard" function that can be placed in one or more applications then create a usercontrol instead. You can use the usercontrol to receive the messages from the icon being clicked, expose the necessary properties and functions (including events if required) and can compile this as a seperate OCX which you can insert into any application or form.
There has been no activity in this question in quite some time, and it looks like it has been abandoned. As part of our ongoing mission to clean up the topic areas, a Moderator will finalize this question within the next seven (7) days. At that time, either I or one of the other Moderators will force/accept the comment of TimCottee.
DO NOT ACCEPT THIS COMMENT AS AN ANSWER. If you have further comments on this question or the recommendation, please leave them here.
ShehzadMunir,
Some of these questions have been open for some time. Please resolve them appropriately as soon as possible.
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20090669
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20100224
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20137180
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20154981
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20230974
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20239948
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20243913
https://www.experts-exchange.com/jsp/qShow.jsp?ta=asp&qid=20193587
https://www.experts-exchange.com/jsp/qShow.jsp?ta=mssql&qid=20184112
Thanks,
Netminder
Community Support Moderator
Experts Exchange
DO NOT ACCEPT THIS COMMENT AS AN ANSWER. If you have further comments on this question or the recommendation, please leave them here.
ShehzadMunir,
Some of these questions have been open for some time. Please resolve them appropriately as soon as possible.
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20090669
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20100224
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20137180
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20154981
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20230974
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20239948
https://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20243913
https://www.experts-exchange.com/jsp/qShow.jsp?ta=asp&qid=20193587
https://www.experts-exchange.com/jsp/qShow.jsp?ta=mssql&qid=20184112
Thanks,
Netminder
Community Support Moderator
Experts Exchange