이제 WPF로 바꾸어보세요 (7)

느린 원인은 단순히 Canvas의 Children를 Clear하지 않았던 것처럼 본.
수정했는데 어떻게든 위화감 없는 레벨이 되었습니다.
그렇다고는 해도 Window 트랜지션시에는 메키메키 퍼포먼스가 떨어지므로 일단 불필요한 컨트롤은 비표시에.


NotifyIcon의 동적 생성 및 업데이트



NotifyIcon에 왼쪽 상단의 Canvas Bitmap 이미지를 넣습니다.
왼쪽에 같은 아이콘이 또 하나 있습니다만, 그쪽은 Forms+VB판의 아이콘. 마찬가지로 GDI로 그린 것을 동적으로 넣고 있습니다만 16 픽셀 고정의 이미지를 그대로 넣고 있기 때문에 당 노트북(125%)의 스케일링에 의해 20 픽셀 사이즈가 되어 있기 때문에, 노망 정도가 격렬하다 입니다.



확대하면 보다 알기 쉽다.



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 사용하는 것도, 뭔가 라는 생각이 들고 이런 순서로 가는 것에. 분명 더 좋은 방법이 있을 것임에 틀림없다.

좋은 웹페이지 즐겨찾기