65.9K
CodeProject 正在变化。 阅读更多。
Home

鱼,鱼,

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (40投票s)

2010年3月19日

CPOL

3分钟阅读

viewsIcon

96746

downloadIcon

5846

仅为好玩;一群鱼在屏幕上游动

引言

这篇文章是对 Davidwu 的优秀文章 一个可爱的金鱼桌面宠物 的致敬。 在那篇文章中,David 演示了使用 alpha 混合和 GDI+ 来制作一条小鱼在屏幕上游动。

我已经采用了该代码并扩展了它以支持多条鱼,以及一个 SysTray 图标来控制您的鱼缸中的鱼的数量。

FishTank/screenshot2.png

我还添加了一些不同颜色的鱼的图像,以增加一些多样性。

FishTank/screenshot.jpg

Using the Code

该代码与原始代码基本相同,尽管我稍微调整了一下以支持多条鱼。 与原始代码不同的是,帧是在启动时从源 PNG 提取的,而不是在每个计时器滴答声时提取。

class Frameset : List<Bitmap>, IDisposable
{
    public Frameset(Bitmap b, int framecount)
    {
        if (!Bitmap.IsCanonicalPixelFormat(b.PixelFormat) || 
              !Bitmap.IsAlphaPixelFormat(b.PixelFormat))
            throw new ApplicationException("The picture must be 32bit
                  picture with alpha channel.");

        FrameWidth = b.Width / framecount;
        FrameHeight = b.Height;

        for (int i = 0; i < framecount; i++)
        {
            Bitmap bitmap = new Bitmap(FrameWidth, FrameHeight);
            using (Graphics g = Graphics.FromImage(bitmap))
                g.DrawImage(b, new Rectangle(0, 0, FrameWidth, FrameHeight),
                   new Rectangle(FrameWidth * i, 0, FrameWidth, FrameHeight), 
                   GraphicsUnit.Pixel);

            Add(bitmap);
        }
    }

    public int FrameWidth { get; private set; }

    public int FrameHeight { get; private set; }

    public void Dispose()
    {
        foreach (Bitmap f in this)
            f.Dispose();

        Clear();
    }
}

这大大降低了动画的 CPU 使用率,这对于整个鱼缸游泳来说非常重要。 还有一个从主 FishForm 派生的 Form 来托管系统托盘中的 NotifyIcon。 此窗体的实例将始终是第一个创建的。 NotifyIcon 上下文菜单允许用户添加和删除鱼,显示和隐藏所有鱼,当然还有退出应用程序。

.NET 4

项目文件都在 VS.NET 2010 格式中,但唯一使用的 .NET 4 类型是 Tuple。 Sacha 在下面的评论中发布了一个 Tuple 的版本。 因此,如果您想在 2008 和 .NET 3.5 中使用它,您需要合并该代码片段或以其他方式替换 Tuple 的用法,这应该不会太难。

转换为 UWP

随着 Windows 10 周年纪念版的发布以及 Desktop App Converter 的引入,我决定看看这是否可以作为 UWP 应用程序运行。 整个转换过程非常简单。

1) 第一步是将项目从 vs.net 2010 更新到 2015 (特别是 15 Release 3 Preview - 稍后会详细介绍),然后以 .NET 4.6.1 为目标。 没有任何问题。

2) 接下来,需要创建一个 UWP AppXManifest 布局文件。 我决定采用 手动方式,因为这个东西可以 xcopy 部署。 清单尽可能简单。 真正最难的部分是让我自己重新熟悉应用程序签名。 最后,我添加了几个构建事件脚本,每次构建时都会使用它们来重建 appx 包。 将其和一些 logo png 放入解决方案文件夹中。

AppXManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<Package
   xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
   xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
   xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities">
  <Identity Name="[this is the guid of your package]"
    ProcessorArchitecture="x86"
    Publisher="CN=kackman.net"
    Version="1.1.11.0" />
  <Properties>   
    <DisplayName>Fishy Fishy Fish</DisplayName>
    <PublisherDisplayName>Reserved</PublisherDisplayName>
    <Description>Some fish. Swimming around on your screen.</Description>
    <Logo>StoreLogo.png</Logo>
  </Properties>
  <Resources>
    <Resource Language="en-us" />
  </Resources>
  <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14316.0" MaxVersionTested="10.0.14393.0" />
  </Dependencies>
  <Capabilities>
    <rescap:Capability Name="runFullTrust"/>   
  </Capabilities>
  <Applications>
    <Application Id="FishyFishyFish" Executable="FishyFish.exe" EntryPoint="Windows.FullTrustApplication">     
      <uap:VisualElements
         BackgroundColor="transparent"
         DisplayName="Fishy Fishy Fish"
         Square150x150Logo="Square150x150Logo.png"
         Square44x44Logo="Square44x44Logo.png"
         Description="Some fish. Swimming around on your screen." />      
    </Application>
  </Applications>
</Package>
构建前
:: clean any previous AppX outputs
rmdir AppX /s /q
del $(TargetName).appx /q /f
构建后
:: copy all of the files that go into the AppX into a working folder
mkdir AppX
xcopy "$(TargetPath)" AppX\ /R /Y
xcopy "$(TargetPath).config" AppX\ /R /Y
xcopy "$(SolutionDir)appxmanifest.xml" AppX\ /R /Y
xcopy "$(SolutionDir)StoreLogo.png" AppX\ /R /Y
xcopy "$(SolutionDir)Square44x44Logo.png" AppX\ /R /Y
xcopy "$(SolutionDir)Square150x150Logo.png" AppX\ /R /Y

:: build a new AppX package
"$(Win10SDKDir)MakeAppX.exe" pack /d AppX /p $(TargetName).appx
"$(Win10SDKDir)SignTool.exe" sign -f d:\temp\tempca.pfx -fd SHA256 -v .\$(TargetName).appx
(注意 $(Win10SDKDir) 是一个添加到 csproj 文件中的变量,它指向 Windows 10 SDK 文件夹。)
  <PropertyGroup>
    <Win10SDKDir Condition=" '$(Win10SDKDir)' == '' ">C:\Program Files (x86)\Windows Kits\10\bin\x64\</Win10SDKDir>
  </PropertyGroup>
 
3) 然后,安装一个 vs.net 插件,该插件允许您调试 AppX。 这就是您需要 Visual Studio 15 Preview 的地方(这与 Visual Studio 2015 不同,足以让人困惑),因为在撰写本文时,该扩展仅适用于 Preview VS。 安装后,调试器像您的项目是一个普通的 UWP 应用程序一样附加到 AppX,然后您就可以开始了。
 
就这样了。 总而言之,有关应用程序转换器的文档非常有帮助,提供了大量您自己无法理解的逐步说明。 我强烈建议在开始转换之前仔细阅读它。

结论

哦,而且我在鱼的着色上作弊了。 我在 Paint.Net 中对源 PNG 进行了颜色偏移,并将每个 PNG 保存为一组新的图像。 这就是项目大小大的原因。 也许有一天我会纠正那个捷径,但现在为额外的下载量表示歉意。 :)

大致就是这样了。 这是一个有趣的、可以玩的小项目(我给它的人和朋友也很喜欢它)。 这可能是我最后一篇 WinForms 文章。 我已经感染了 WPF 病毒,并且终于开始克服学习曲线。

历史

  • 2010 年 3 月 31 日 - 初始帖子
  • 2016 年 8 月 3 日 - UWP 部分
© . All rights reserved.