3

この単純なプログラムは機能せず、ウィンドウに画像が表示されません。

namespace ClipBoardTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void CopyButton_Click(object sender, RoutedEventArgs e)
        {
            if (Clipboard.ContainsImage())
            {
                ImageUIElement.Source = Clipboard.GetImage();
                Console.WriteLine("Clipboard copied to UIElement");
            }
            else
            {
                Console.WriteLine("No image in Clipboard");
            }
        }
    }
 }

出力は「UIElement にコピーされたクリップボード」ですが、ウィンドウに画像が表示されません。

XAML:

 <Window x:Class="ClipBoardTest.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Title="MainWindow" Height="350" Width="525">
     <Grid>
         <Button x:Name="CopyButton" Content="Copy" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Click="CopyButton_Click"/>
         <Image x:Name="ImageUIElement" Margin="90,10,10,10"/>
     </Grid>
 </Window>

何が悪いのか理解できる人はいますか?

4

3 に答える 3

6

Clipboard.GetDataObjectビットマップを取得して bitmapSource に変換するために使用します。また、Bitmap.GetHbitmap()DeleteObject を呼び出さない限り、メモリ リークが発生することに注意してください。

したがって、正しい解決策は、使用後に IntPtr を破棄することです。メソッドをクラス レベルで宣言し、コードから使用します。

// at class level
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);

if (Clipboard.ContainsImage())
{
    IDataObject clipboardData = Clipboard.GetDataObject();
    if (clipboardData != null)
    {
        if (clipboardData.GetDataPresent(System.Windows.Forms.DataFormats.Bitmap))
        {
            System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)clipboardData.GetData(System.Windows.Forms.DataFormats.Bitmap);
            IntPtr hBitmap = bitmap.GetHbitmap();
            try
            {
                ImageUIElement.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                Console.WriteLine("Clipboard copied to UIElement");
            }
            finally 
            {
                DeleteObject(hBitmap)
            }
        }
    }
}

ソース - MSDNおよびBitmap でのメモリ リーク

于 2014-09-09T17:59:08.640 に答える
1

今では正常に動作します。

if (Clipboard.ContainsImage())
{
    // ImageUIElement.Source = Clipboard.GetImage(); // does not work
    System.Windows.Forms.IDataObject clipboardData = System.Windows.Forms.Clipboard.GetDataObject();
    if (clipboardData != null)
    {
        if (clipboardData.GetDataPresent(System.Windows.Forms.DataFormats.Bitmap))
        {
            System.Drawing.Bitmap bitmap = (System.Drawing.Bitmap)clipboardData.GetData(System.Windows.Forms.DataFormats.Bitmap);
            ImageUIElement.Source =  System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions());
            Console.WriteLine("Clipboard copied to UIElement");
        }
    }
}
于 2014-09-09T17:41:23.727 に答える