LoginSignup
1
1

More than 3 years have passed since last update.

今更ながらWPFに置き換えてみる(7)

Last updated at Posted at 2020-03-17

遅い原因は単にCanvasのChildrenをClearしていなかっただけの模様。
修正したところ何とか違和感ないレベルになりました。
とはいえWindowトランジションの際はメキメキパフォーマンスが落ちるのでいったん不要なコントロールは非表示に。
TestApp3.gif

NotifyIconの動的な生成・更新

NotifyIconに左上のCanvasのBitmapイメージを突っ込んでいます。
左に同じようなアイコンがもう一つありますが、そちらはForms+VB版のアイコン。同じようにGDIで描画したものを動的に入れてますが16ピクセル固定のイメージをそのまま入れているので当ノートPC(125%)のスケーリングにより20ピクセルサイズになっているため、ボケ度合いが激しいです。

toolbar-1.PNG

拡大するとより分かりやすい。

キャプチャ-2.PNG

NotifyIconのもとになるCanvasのサイズを16ピクセルではなく20ピクセルで作ってるので、きれいに表示されています。16のサイズで作っちゃうと
Froms版と大して変わりません

NotifyIconへのセット手順としては
①Canvas上に作成した時計のイメージを
②CanvasごとRenderTargetBitmapにして
③RenderTargetBitmapをCopyPixelsで普通のBitmap(System.Drawing)にして
④IconHandleをとって
⑤アイコン化してセット
という流れ。

       private void MainLoop(object sender, EventArgs e)
        {
            //毎秒処理
            if (G.DispIcon != 0)
            { 
                DrawClock2(this.aCanvas);

                aCanvas.Arrange(new Rect(aCanvas.RenderSize));
                aCanvas.Measure(aCanvas.RenderSize);
                var bounds = VisualTreeHelper.GetDescendantBounds(aCanvas);
                var RTbitmap = new RenderTargetBitmap((int)bounds.Width, (int)bounds.Height, 96.0d,96.0d,PixelFormats.Pbgra32);
                var dv = new DrawingVisual();
                using (var dc = dv.RenderOpen())
                {
                    var vb = new VisualBrush(aCanvas);
                    dc.DrawRectangle(vb, null, bounds);
                }
                RTbitmap.Render(dv);
                RTbitmap.Freeze();

                //RenderTargetBitmap => bitmap
                var bitmap = new System.Drawing.Bitmap((int)bounds.Width, (int)bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
                var bitmapData = bitmap.LockBits(new System.Drawing.Rectangle(System.Drawing.Point.Empty, bitmap.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, bitmap.PixelFormat);
                RTbitmap.CopyPixels(Int32Rect.Empty, bitmapData.Scan0, bitmapData.Stride * bitmapData.Height, bitmapData.Stride);

                //bitmap => bitmapHandler => ImageSource(参考)
                IntPtr Hbitmap = bitmap.GetHbitmap();
                var ImageSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(Hbitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                this.image.Source = ImageSource;

                //bitmap =>iconHandler => icon
                bitmap.UnlockBits(bitmapData);
                IntPtr Hicon = bitmap.GetHicon();
                System.Drawing.Icon icon = System.Drawing.Icon.FromHandle(Hicon);
                this.NotifyIcon.Icon = icon;

                bitmap.Dispose();
                DestroyIcon(icon.Handle);

            }
       }

変換が多くて非常に手間がかるやり方なんですが、stream使うのも、なんかなあという気がしてこのような手順で行くことに。きっともっとうまい方法があるに違いない。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1