USB lucky cat


  • :belt_onion:

    @anotherusername said in USB lucky cat:

    Actually I'm kind of surprised that there isn't an app that does nothing but add an animated icon to your system tray, so you could just point it to the animation you wanted and put it in your startup group. Seems like the sort of novelty application that somebody would've built before...

    I keep meaning to write an application that will take a video as input then regularly update your desktop background to stills from that video. Updating slowly enough that it doesn't really divert your attention but regularly enough that the video plays itself out over the course of a day, you have a new scene if you come back from a meeting, etc. There are some cool videos that could be used with such an application; I just don't have the time.



  • @heterodox said in USB lucky cat:

    There are some cool videos that could be used with such an application

    I think the Bergen to Oslo train video would work really well in a digital picture frame at one frame per minute. Preferably with motion interpolation so you can't actually see the picture change no matter how hard you stare at it.


  • Grade A Premium Asshole

    @heterodox said in USB lucky cat:

    I keep meaning to write an application that will take a video as input then regularly update your desktop background to stills from that video. Updating slowly enough that it doesn't really divert your attention but regularly enough that the video plays itself out over the course of a day, you have a new scene if you come back from a meeting, etc. There are some cool videos that could be used with such an application; I just don't have the time.

    That is...A surprisingly cool idea.



  • @heterodox @Polygeekery You could probably do that easily with ffmpeg and some scripting in Windows Script Host.



  • @anotherusername Last time I tried writing a script to set the desktop background, I ended up giving up. There are Windows Explorer shenanigans that need invoking to make it actually update, and the API for that is not stable across Windows versions.



  • @flabdablet as far as I can tell, the biggest issue appears to be that to support Windows XP the wallpaper image has to be a BMP. But you can just have ffmpeg output that.

    The script that I found was using the command

    %windir%\System32\RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters
    

    to actually make the wallpaper update after the registry key had been changed. That worked when I tried it, on both Windows XP and 7.



  • @anotherusername That worked in XP. Doesn't work reliably in 7; only takes effect after logging out and in again.



  • @flabdablet ... it worked for me just now when I tried it.



  • @anotherusername What happens if you have an Aero theme turned on? I think that's when it failed for me. Or maybe it was during a logon script. It's quite some while ago now.


  • :belt_onion:

    Also, running a Win32 API via rundll32 is rarely the right thing to do; that's not for what it's designed. Using something like PowerShell that has P/Invoke is better. Anyway, it's still on my "wishlist" for personal projects, but as I said above, too many projects, too little time. :P



  • @flabdablet Aero was turned on.



  • @flabdablet said in USB lucky cat:

    The amount of power being used inside any two-terminal electric device - whether that be an appliance like a light or a heater or a motor, or simply a length of wire - can be calculated by multiplying the voltage across the device's terminals by the current flowing through the device: watts = volts × amps.

    That's true for DC circuits. It's slightly more complicated than that for AC, since for some kinds of devices the voltage and current may not be in phase. Strictly speaking, you also need to multiply by the power factor, which is the cosine of the phase difference. However, unless you're dealing with large industrial motors, the difference is not going to be significant, so ignoring the power factor is mostly OK.



  • @HardwareGeek good point... inductances (or capacitances) will cause phase shifts between the voltage and current. The result is that the peaks in the voltage and current waveforms aren't aligned. The actual power available to the device is lower, but the power company has to put just as much energy in to supply the peak voltage and current -- resulting in lost energy. This energy isn't going to register as power on your electric meter, but it's very real to the power company.

    The phase difference can be corrected, however... inductive and capacitive effects cancel each other out, so a customer who has large inductive loads (such as electric motors) can improve their power factor again by adding large capacitors to compensate. By correcting the power factor -- bringing the voltage and current waveforms back into sync with one another -- the power company's happy again, and you're getting the most out of the energy that they're actually delivering.



  • @anotherusername said in USB lucky cat:

    By correcting the power factor -- bringing the voltage and current waveforms back into sync with one another -- the power company's happy again, and you're getting the most out of the energy that they're actually delivering.

    And if you don't, the power company will add a power factor adjustment to your bill, so you're paying for the peak voltage and current they're delivering, rather than the (lower) power indicated on your meter.

    BTW, a lot of heavy-duty electrical equipment is rated in VA (or kVA) rather than W or (kW), because it's the voltage and current it can handle that matters for that equipment, regardless of the phase.


  • Notification Spam Recipient

    @remi said in USB lucky cat:

    Unless... what happens if I short-circuit the wires in my stripped USB cable? Will that blow (figuratively, I hope...) the USB port? The USB controller? The motherboard? Do nothing?

    In theory, the hub will detect over current and shut down that port, which will require a power cycle of the machine (if it's not a separate hub), but that's about it.

    In practice.... Well, do you want to be safe or convenient?


  • Notification Spam Recipient

    @anotherusername said in USB lucky cat:

    @Tsaukpaetra

    edit: well I guess that wouldn't work... phooey. Like they already made animation work built-in for mouse cursors, it's almost the same exact file format as an icon, so you'd really think, right? But apparently you do have to use a series of still icons and update it on a timer in order to get an animated icon in the system tray.

    Actually I'm kind of surprised that there isn't an app that does nothing but add an animated icon to your system tray, so you could just point it to the animation you wanted and put it in your startup group. Seems like the sort of novelty application that somebody would've built before...

    Challenge accepted? Maybe? I'll set a reminder for tomorrow if I'm bored.


  • 🚽 Regular

    @Tsaukpaetra If you can find a better animation than this one I whipped up based on an animated GIF from the interwebs...

    0_1483963126264_kot-128x128-horizontal.png

    Here's some code:

    Program.cs
    using System;
    using System.Windows.Forms;
    
    namespace SystrayManekiNeko
    {
        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.Run( new ManekiNekoApplicationContext() );
            }
        }
    }
    
    ManekiNekoApplicationContext.cs
    using System;
    using System.Windows.Forms;
    using System.Drawing;
    using System.ComponentModel;
    
    namespace SystrayManekiNeko
    {
        public class ManekiNekoApplicationContext : ApplicationContext
        {
            private Container components;
            private NotifyIcon notifyIcon;
            private ContextMenuStrip contextMenu;
            private Timer timer;
            private int interval = 100;
            private int currentAnimationFrame = 0;
    
            private const int NUM_FRAMES = 10;
            private Icon[] frames = new Icon[NUM_FRAMES];
    
            public ManekiNekoApplicationContext()
            {
                Application.ApplicationExit += new EventHandler( Application_Exit );
    
                components = new Container();
    
                contextMenu = new ContextMenuStrip();
                contextMenu.Opening += new CancelEventHandler(this.ContextMenu_Opening);
    
                initializeFrames();
    
                notifyIcon = new NotifyIcon( components )
                {
                    ContextMenuStrip = contextMenu,
                    Icon = frames[0],
                    Text = Properties.Resources.ApplicationName,
                    Visible = true
                };
                notifyIcon.DoubleClick += new EventHandler( notifyIcon_DoubleClick );
    
                timer = new Timer();
                timer.Interval = this.interval;
                timer.Tick += new EventHandler( this.timer_Tick );
    
                StartAnimation();
            }
    
            private void initializeFrames()
            {
                Bitmap sourceBitmap = Properties.Resources.Neko128;
                int iconWidth = sourceBitmap.Width / NUM_FRAMES;
                int iconHeight = sourceBitmap.Height;
                for( int i = 0; i < NUM_FRAMES; ++i )
                {
                    int x = iconWidth * i;
                    int y = 0;
                    Rectangle srcRect = new Rectangle( x, y, iconWidth, iconHeight );
                    using( Bitmap bmp = sourceBitmap.Clone( srcRect, sourceBitmap.PixelFormat ) )
                    {
                        frames[i] = Icon.FromHandle( bmp.GetHicon() );
                    }
                }
            }
    
            public bool IsAnimationRunning
            {
                get { return this.timer.Enabled; }
                set
                {
                    if( value != IsAnimationRunning )
                    {
                        if( value )
                        {
                            StartAnimation();
                        }
                        else {
                            StopAnimation();
                        }
                    }
                }
            }
    
            public void StartAnimation()
            {
                if( !IsAnimationRunning )
                {
                    timer.Start();
                }
            }
    
            public void StopAnimation()
            {
                if( IsAnimationRunning )
                {
                    timer.Stop();
                    notifyIcon.Icon = frames[0];
                }
            }
    
            private void animate()
            {
                if( !IsAnimationRunning ) return;
    
                currentAnimationFrame = (currentAnimationFrame + 1) % NUM_FRAMES;
                notifyIcon.Icon = frames[currentAnimationFrame];
            }
    
            private void timer_Tick( object sender, EventArgs e )
            {
                animate();
            }
    
            public void ToggleAnimation()
            {
                IsAnimationRunning = !IsAnimationRunning;
            }
    
            public void Exit()
            {
                StopAnimation();
                notifyIcon.Visible = false;
                Application.Exit();
            }
    
            private void ContextMenu_Opening( object sender, CancelEventArgs e )
            {
                if( contextMenu.Items.Count == 0 )
                {
                    contextMenu.Items.Add( new ToolStripMenuItem( Properties.Resources.ToggleAnimation, null, new EventHandler( ToggleAnimation_Clicked ) ) );
                    contextMenu.Items.Add( new ToolStripSeparator() );
                    contextMenu.Items.Add( Properties.Resources.Exit, null, new EventHandler( Exit_Clicked ));
                }
                var toggleAnimationMenuItem = contextMenu.Items[0] as ToolStripMenuItem;
                toggleAnimationMenuItem.Checked = IsAnimationRunning;
                e.Cancel = false;
            }
    
            private void ToggleAnimation_Clicked( object sender, EventArgs e )
            {
                ToggleAnimation();
            }
    
            private void notifyIcon_DoubleClick( object sender, EventArgs e )
            {
                ToggleAnimation();
            }
    
            private void Application_Exit( object sender, EventArgs e )
            {
                Exit();
            }
    
            private void Exit_Clicked( object sender, EventArgs e )
            {
                Exit();
            }
    
            protected override void Dispose( bool disposing )
            {
                if( disposing && components != null ) { components.Dispose(); }
            }
        }
    }
    

    Here's a release build if you trust an executable some random guy posted on the internet (:doing_it_wrong:):

    SystrayManekiNeko.exe


  • Notification Spam Recipient

    @Zecc said in USB lucky cat:

    @Tsaukpaetra If you can find a better animation than this one I whipped up based on an animated GIF from the interwebs...

    0_1483963126264_kot-128x128-horizontal.png

    Here's some code:

    Program.cs
    using System;
    using System.Windows.Forms;
    
    namespace SystrayManekiNeko
    {
        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.Run( new ManekiNekoApplicationContext() );
            }
        }
    }
    
    ManekiNekoApplicationContext.cs
    using System;
    using System.Windows.Forms;
    using System.Drawing;
    using System.ComponentModel;
    
    namespace SystrayManekiNeko
    {
        public class ManekiNekoApplicationContext : ApplicationContext
        {
            private Container components;
            private NotifyIcon notifyIcon;
            private ContextMenuStrip contextMenu;
            private Timer timer;
            private int interval = 100;
            private int currentAnimationFrame = 0;
    
            private const int NUM_FRAMES = 10;
            private Icon[] frames = new Icon[NUM_FRAMES];
    
            public ManekiNekoApplicationContext()
            {
                Application.ApplicationExit += new EventHandler( Application_Exit );
    
                components = new Container();
    
                contextMenu = new ContextMenuStrip();
                contextMenu.Opening += new CancelEventHandler(this.ContextMenu_Opening);
    
                initializeFrames();
    
                notifyIcon = new NotifyIcon( components )
                {
                    ContextMenuStrip = contextMenu,
                    Icon = frames[0],
                    Text = Properties.Resources.ApplicationName,
                    Visible = true
                };
                notifyIcon.DoubleClick += new EventHandler( notifyIcon_DoubleClick );
    
                timer = new Timer();
                timer.Interval = this.interval;
                timer.Tick += new EventHandler( this.timer_Tick );
    
                StartAnimation();
            }
    
            private void initializeFrames()
            {
                Bitmap sourceBitmap = Properties.Resources.Neko128;
                int iconWidth = sourceBitmap.Width / NUM_FRAMES;
                int iconHeight = sourceBitmap.Height;
                for( int i = 0; i < NUM_FRAMES; ++i )
                {
                    int x = iconWidth * i;
                    int y = 0;
                    Rectangle srcRect = new Rectangle( x, y, iconWidth, iconHeight );
                    using( Bitmap bmp = sourceBitmap.Clone( srcRect, sourceBitmap.PixelFormat ) )
                    {
                        frames[i] = Icon.FromHandle( bmp.GetHicon() );
                    }
                }
            }
    
            public bool IsAnimationRunning
            {
                get { return this.timer.Enabled; }
                set
                {
                    if( value != IsAnimationRunning )
                    {
                        if( value )
                        {
                            StartAnimation();
                        }
                        else {
                            StopAnimation();
                        }
                    }
                }
            }
    
            public void StartAnimation()
            {
                if( !IsAnimationRunning )
                {
                    timer.Start();
                }
            }
    
            public void StopAnimation()
            {
                if( IsAnimationRunning )
                {
                    timer.Stop();
                    notifyIcon.Icon = frames[0];
                }
            }
    
            private void animate()
            {
                if( !IsAnimationRunning ) return;
    
                currentAnimationFrame = (currentAnimationFrame + 1) % NUM_FRAMES;
                notifyIcon.Icon = frames[currentAnimationFrame];
            }
    
            private void timer_Tick( object sender, EventArgs e )
            {
                animate();
            }
    
            public void ToggleAnimation()
            {
                IsAnimationRunning = !IsAnimationRunning;
            }
    
            public void Exit()
            {
                StopAnimation();
                notifyIcon.Visible = false;
                Application.Exit();
            }
    
            private void ContextMenu_Opening( object sender, CancelEventArgs e )
            {
                if( contextMenu.Items.Count == 0 )
                {
                    contextMenu.Items.Add( new ToolStripMenuItem( Properties.Resources.ToggleAnimation, null, new EventHandler( ToggleAnimation_Clicked ) ) );
                    contextMenu.Items.Add( new ToolStripSeparator() );
                    contextMenu.Items.Add( Properties.Resources.Exit, null, new EventHandler( Exit_Clicked ));
                }
                var toggleAnimationMenuItem = contextMenu.Items[0] as ToolStripMenuItem;
                toggleAnimationMenuItem.Checked = IsAnimationRunning;
                e.Cancel = false;
            }
    
            private void ToggleAnimation_Clicked( object sender, EventArgs e )
            {
                ToggleAnimation();
            }
    
            private void notifyIcon_DoubleClick( object sender, EventArgs e )
            {
                ToggleAnimation();
            }
    
            private void Application_Exit( object sender, EventArgs e )
            {
                Exit();
            }
    
            private void Exit_Clicked( object sender, EventArgs e )
            {
                Exit();
            }
    
            protected override void Dispose( bool disposing )
            {
                if( disposing && components != null ) { components.Dispose(); }
            }
        }
    }
    

    Here's a release build if you trust an executable some random guy posted on the internet (:doing_it_wrong:):

    SystrayManekiNeko.exe

    What?!?!? You're not using NodeBB WPF UWP FWP framework?


  • 🚽 Regular

    @Tsaukpaetra said in USB lucky cat:

    UWP

    Ah, the Universal Windows Platform. Where "Universe" is defined as Windows 10.

    Hmm, I should have used Qt for extra portability.


  • FoxDev

    @Zecc said in USB lucky cat:

    Ah, the Universal Windows Platform. Where "Universe" is defined as Windows 10.

    Given MS are trying to make Windows 10 the 'Universal Windows', the name kinda makes sense 🙂



  • @izzion said in USB lucky cat:

    Shorting the USB cable will at a minimum kill the USB port it was connected to.

    Meh... not necessarily. Motherboards mostly do have overcurrent protection, and Windows at least will even inform you of a power surge and disable the device - I got that quite a few times when testing my breadboards.

    Of course, mostly working doesn't mean always working, and Murphy's law is still in effect, but there's no need to panic.



  • @flabdablet said in USB lucky cat:

    @remi said in USB lucky cat:

    I'd need to find out (and even maybe, heavens forbid, buy it!) the bit of hardware

    Ten bucks.

    http://www.howtogeek.com/228869/how-to-monitor-your-usb-device-power-usage-and-output/

    I can now report that my over-powered cat draws less than the precision of this monitoring device (I'd say "less than 0.01 A" but I have no idea how accurate the measurements are, so it might be more than that). Anyway, it basically doesn't draw anything, which isn't really a surprise.

    Good, back to work now.


Log in to reply