NotifyIconChange.dll

taximania

Well-Known Member
Licensed User
Longtime User
Credit to AGraham for his Notification and Icon code.
Also to DZT for the link to the NotifyIcon code.

This lib allows you to toggle the notifyIcon Icon in the system tray.

I'll post the class.cs files tomorrow because there's still some
work to be done on this one !

This works on my WM6 device un-compiled, BUT, throws wobblies when
I try to compile it on the desktop 'for' the device.

Instead of the notification bubble in the example, I've got it to turn my
autoanswer and BlueTooth on/off. It works fine, as long as you don't try to
run another b4ppc program (device, code).

@Erel, why do I need to add a desktop reference to a lib to compile for the device, especially when the lib is designed for the device ?
The desktop doesn't like my lib. Won't compile optimized.
Does compile non-optimized, without a reference, but doesn't work on the device.
:confused:
 

Attachments

  • NotifyIconChange.zip
    10.6 KB · Views: 36
Last edited:

taximania

Well-Known Member
Licensed User
Longtime User
I've tried to comment out the lines of code that I think the 'dummy' desktop dll won't like but i've achieved nothing.
Here's my un-edited class.cs code. Based on the example posted by DZT.

I've altered the original Add and Modify methods to convert the icon to a
handle, as used in Agrahams Icon routine. Is this the problem ?
The dll compiles and runs on my device.

What bit's do I need to comment out for a dummy dll so I can compile programs on the desktop using this dll ?

This is really 'bugging' me. All my other dll's have never needed this !


B4X:
using System;
using System.Collections;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using Microsoft.VisualBasic;
using Microsoft.WindowsCE.Forms;
using System.Runtime.InteropServices;

namespace NotifyIconNS
{
    

    public class NotifyIcon : IDisposable
    {
        public event EventHandler Click;
        private object[] eventObject;


        public string IconText
        {
            get { return iconText; }
            set { iconText = value; }
        }

        private String iconText;


        private WS ws;
        private int uID = 5000;

        public NotifyIcon()
        {
            eventObject = new object[] { this, "Click" };

            ws = new WS(this);
            ws.uID = uID;
        }

        public double DLLVersion
        {
            get { return 1; }
        }


        public void Add(Icon ike)
        {
            IntPtr hIcon;
            hIcon = ike.Handle;


            TrayMessage(ws.Hwnd, NIM_ADD, (uint)uID, hIcon);
        }

        public void Remove()
        {

            TrayMessage(ws.Hwnd, NIM_DELETE, (uint)uID, IntPtr.Zero);
        }

        public void Modify(Icon ike2)
        {
            IntPtr hIcon;
            hIcon = ike2.Handle;
            TrayMessage(ws.Hwnd, NIM_MODIFY, (uint)uID, hIcon);

        }

        private void TrayMessage(IntPtr hwnd, int dwMessage, uint uID, IntPtr hIcon)
        {
            NOTIFYICONDATA notdata = new NOTIFYICONDATA();

            notdata.cbSize = 152;
            notdata.hIcon = hIcon;
            notdata.hWnd = hwnd;
            notdata.uCallbackMessage = WM_NOTIFY_TRAY;
            notdata.uFlags = NIF_MESSAGE | NIF_ICON;
        notdata.uID = uID;

           int ret = Shell_NotifyIcon(dwMessage, ref notdata);
       }


        public void Dispose()
        {
           try
            {
                Click = null;
                Remove();
            }
            finally { }
        }


        internal const int WM_LBUTTONDOWN = 0x0201;
        internal const int WM_NOTIFY_TRAY = 0x0400 + 2001;

        internal const int NIM_ADD = 0x00000000;
        internal const int NIM_MODIFY = 0x00000001;
        internal const int NIM_DELETE = 0x00000002;

        const int NIF_MESSAGE = 0x00000001;
        const int NIF_ICON = 0x00000002;


        internal struct NOTIFYICONDATA
        {
            internal int cbSize;
            internal IntPtr hWnd;
            internal uint uID;
            internal uint uFlags;
            internal uint uCallbackMessage;
            internal IntPtr hIcon;
        }

        [DllImport("coredll.dll")]
        internal static extern int Shell_NotifyIcon(
            int dwMessage, ref NOTIFYICONDATA pnid);

        [DllImport("coredll.dll")]
        internal static extern int SetForegroundWindow(IntPtr hWnd);

        [DllImport("coredll.dll")]
        internal static extern int ShowWindow(
            IntPtr hWnd,
            int nCmdShow);

        [DllImport("coredll.dll")]
       internal static extern IntPtr GetFocus();

        [DllImport("coredll.dll")]
        internal static extern IntPtr LoadIcon(IntPtr hInst, string IconName);

        [DllImport("coredll.dll")]
        internal static extern IntPtr GetModuleHandle(String lpModuleName);


        internal class WS : Microsoft.WindowsCE.Forms.MessageWindow
        {
            private int m_uID = 0;
           private NotifyIcon notifyIcon;

            protected internal WS(NotifyIcon notIcon)
            {
               notifyIcon = notIcon;
            }

            public int uID
            {
                set
                {
                    m_uID = value;

                }
            }

            protected override void WndProc(ref Microsoft.WindowsCE.Forms.Message msg)
            {

                if (msg.Msg == WM_NOTIFY_TRAY)
                {
                    if ((int)msg.LParam == WM_LBUTTONDOWN)
                    {
                        if ((int)msg.WParam == m_uID)
                        {

                            if (notifyIcon.Click != null)
                            {
                               notifyIcon.Click(notifyIcon.eventObject, null);
                            }
                        }
                   }
                }
            }
        }
    }
}
 

agraham

Expert
Licensed User
Longtime User
What bit's do I need to comment out for a dummy dll so I can compile programs on the desktop using this dll ?
Just about everything to leave only empty properties and methods that look the same as the ones for the device.

I've tried to upload a changed class1 for you but I'm getting "forum quota exceeded errors" :( Looks like Erel needs to wave his magic wand again!
 

taximania

Well-Known Member
Licensed User
Longtime User
Consider this thread closed.

My example works one day, then doesn't work the day after ???
The icon stays green !! , sometimes !!
Thanks for the help Agraham, perhaps you can sort a work round for this.

I admit defeat, and am done with this.
Google thinks I'm a family member of it :)
MSDN doesn't ;)

Not quitting the forum, perhaps some of the 'newbies' may
need more essential little questions answered.

If the 'OLD TIMERS' can help, then I'm sat watching :sign0188:
 

taximania

Well-Known Member
Licensed User
Longtime User
Ok, I lied, this thread isn't dead.

Finally got my, 'Device IDE', coded programs to work as expected, (on the device).

Yes it was a coding thing on my behalf, very confusing, but 'hey'.

What with the forum being down, i haven't the time to post everything I wanted too. I will do it tomorrow.


@Agraham, i've tried numerous variations for a desktop dummy lib,
the ones that do allow compilation of source code on the desktop, still don't work on the device when the exe is copied to it.

If you can upload the file you mentioned previously, I'll try it.
 

taximania

Well-Known Member
Licensed User
Longtime User
As usual AGraham your spot on :) Many thanks . . .


? If you don't show form1 in a compiled device.exe from the desktop it fails to show the icon on the device at start-up.

If you run the device sbp, it works fine.

Barry is getting there very slowly !!

But losing the plot :BangHead:

Never did like defeat, the 'Quest Continues'

Cheers AG ;-) I'm getting there :)
 
Last edited:

agraham

Expert
Licensed User
Longtime User
? If you don't show form1 in a compiled device.exe from the desktop it fails to show the icon on the device at start-up.
I think I understand why. The NotifyIcon needs an associated application to send messages to. Without a main form there is no message loop for your application and so nowhere to send messages to so I suspect that in this case the icon addition is cancelled.

If you run the device sbp, it works fine.
That's because the device IDE (unlike the desktop) is single threaded and runs your program on the IDE main thread so the NotifyIcon sees, and uses, the message loop of the IDE main window.
 

taximania

Well-Known Member
Licensed User
Longtime User
Right, here's NotiIcon.dll, NotiIconDesk.dll and Balloon.dll


I've included the on/off .bmp and .ico images/icons
You can play with the image filepath names but the examples use
the on/off .bmp's on the root of the device, and the on/off .ico's in the
application directory.

2 .sbp example files are included.
I'm sure you can decide where your code for the toggle of state goes.

OnOffNotify.sbp works on the device AOK :)

OnOffNotify2.sbp can be compiled on the desktop and seems AOK :)
I added a timer after showing form1 and hw.ShowTodayScreen in the timer1_tick routine.

Warning for newbies, this included me,
Make sure timer1.Enabled=False is in timer1_tick
Every time the balloon came up to quit the app, the timer closed the balloon,
I had to soft reset my device :BangHead:


:wav: Cheers Agraham
 

Attachments

  • NotiIcon.zip
    10.6 KB · Views: 12
Last edited:

taximania

Well-Known Member
Licensed User
Longtime User
Many thanks Erel :)

Here's another example .sbp
This one just sit's in the tray and toggles the icon every 5 seconds using a timer.
The ni_click event closes the application.
 

Attachments

  • OnOffNotify3.sbp
    951 bytes · Views: 13
Top