ここで本当に助けが必要です。事前に乗算されたアルファを備えた 32bpp であると思われる画像をMenuItemにロードしようとしています(このガイドに従って GIMP で画像を作成しました)。ContextMenuStrip クラスは知っていますが、使用したくありません。
以下は、MenuItem に画像を設定するために使用しているコードです。
// apis
[DllImport("user32.dll", SetLastError = true)]
static extern bool SetMenuItemInfo(IntPtr hMenu, uint uItem, bool fByPosition,
[In] ref MENUITEMINFO lpmii);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr LoadImage(IntPtr hinst, string lpszName, uint uType,
int cxDesired, int cyDesired, uint fuLoad);
// structures
[StructLayout(LayoutKind.Sequential)]
struct MENUITEMINFO
{
public uint cbSize;
public uint fMask;
public uint fType;
public uint fState;
public uint wID;
public IntPtr hSubMenu;
public IntPtr hbmpChecked;
public IntPtr hbmpUnchecked;
public IntPtr dwItemData;
public string dwTypeData;
public uint cch;
public IntPtr hbmpItem;
}
// constants
private const uint LR_LOADFROMFILE = 0x10u;
private const uint IMAGE_BITMAP = 0x0u;
private const uint MIIM_BITMAP = 0x80u;
// points the to the image below in the preview of GIMP
private const string IMAGE_PATH = @"C:\Test\Images\premultalpha.bmp";
// methods
private void SetMenuItemImage()
{
// get the hbitmap for the image
// i am assuming that the alpha channel is preservered on this call
IntPtr hbitmap = LoadImage(IntPtr.Zero, IMAGE_PATH,
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
// create the menuiteminfo structure
MENUITEMINFO mii = new MENUITEMINFO();
mii.cbSize = (uint)Marshal.SizeOf(typeof(MENUITEMINFO));
// retrieves or sets the hbmpItem member
mii.fMask = MIIM_BITMAP;
// handle to the bitmap displayed
mii.hbmpItem = hbitmap;
// returns true
SetMenuItemInfo(this.ContextMenu1.Handle, 0, true, ref mii);
}
これは私の画像を使用したコードの結果です:
ここで明らかな問題は、透明度がなく、代わりに黒い背景があることです。
これは、保存して再度開く前に、事前に乗算されたアルファチャンネルを作成するためのガイドに従って、GIMP で画像がどのように見えるかです。
これは、保存して再度開いた後の GIMP での画像の外観です。
以前のバージョンの写真にあったアルファ チャネル マスクが見えなくなっていることに気付きました。変更前の画像を .bmp として保存しようとしたときに表示される次のメッセージと関係があるかどうかはわかりません。
とても長い投稿で申し訳ありませんが、できる限りの情報を提供しようとしています。MenuItem の透明性に関して、私の問題が何であるかわかりません。32bpp であらかじめ乗算されたアルファを含むビットマップをロードすると、透明度が正常に機能すると言われています。
Bitmap.Gethbitmap()
アルファ チャネルが失われるため、マネージ メソッドを使用できないことはわかっています。これがLoadImage
、保存することを期待して、代わりに winapi 呼び出しを使用する理由です。
どんな助けでも大歓迎です。