我碰到两个麻烦:
1.先建个Console Application,定义了数据结构后
public struct MSGBOXPARAMS
{
public uint cbSize;
public IntPtr hwndOwner;
public IntPtr hInstance;
public string lpszText;
public string lpszCaption;
public uint dwStyle;
public string lpszIcon;
public int dwContextHelpId;
public string lpfnMsgBoxCallback;
public uint dwLanguageId;
};
MSGBOXPARAMS MsgBp = new MSGBOXPARAMS();
MsgBp.cbSize = (uint)sizeof(MSGBOXPARAMS);//因为没赋初值所以sizeof出错,其他语言怎么就行了.若有初值这个后也可能改变初值啊!
2.MsgBp.lpszIcon//指像Icon资源的指针,这个指针是string类型,我还是不会玩.
1.先建个Console Application,定义了数据结构后
public struct MSGBOXPARAMS
{
public uint cbSize;
public IntPtr hwndOwner;
public IntPtr hInstance;
public string lpszText;
public string lpszCaption;
public uint dwStyle;
public string lpszIcon;
public int dwContextHelpId;
public string lpfnMsgBoxCallback;
public uint dwLanguageId;
};
MSGBOXPARAMS MsgBp = new MSGBOXPARAMS();
MsgBp.cbSize = (uint)sizeof(MSGBOXPARAMS);//因为没赋初值所以sizeof出错,其他语言怎么就行了.若有初值这个后也可能改变初值啊!
2.MsgBp.lpszIcon//指像Icon资源的指针,这个指针是string类型,我还是不会玩.
cbSize的大小是为以后扩展用的 public struct HelpInfo
{
}
public delegate void MsgboxCallback(HelpInfo helpInfo); [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
public struct MsgboxParams
{
public int cbSize;
public IntPtr hwndOwner;
public IntPtr hInstance;
public string text;
public string caption;
public int style;
public string icon;
public int helpId;
public IntPtr callback;
public int languageId;
}
class Program
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int MessageBoxIndirect(ref MsgboxParams param); [DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr LoadIcon(IntPtr hInstance, string iconName); static void Main(string[] args)
{
MsgboxParams mp=new MsgboxParams();
mp.hwndOwner = IntPtr.Zero;
mp.hInstance = IntPtr.Zero;
mp.text = "ok";
mp.caption = "ti xing";
mp.style = 0;
mp.icon = "32512";
mp.helpId = 0;
mp.callback = IntPtr.Zero;
mp.languageId = 0;
mp.cbSize = Marshal.SizeOf(mp); MessageBoxIndirect(ref mp);
}
}
MsgBp.cbSize = Marshal.Sizeof(MsgBp);
这个是相关的类:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;namespace HWin32
{
public static class User
{ [StructLayout(LayoutKind.Sequential)]
public struct HELPINFO
{
public uint cbSize;
public int iContextType;
public int iCtrlId;
public IntPtr hItemHandle;
public IntPtr dwContextId;
public HPoint MousePos;
}
[StructLayout(LayoutKind.Sequential)]
public struct MSGBOXPARAMS
{
public uint cbSize;
public IntPtr hwndOwner;
public IntPtr hInstance;
public String lpszText;
public String lpszCaption;
public uint dwStyle;
public IntPtr lpszIcon;
public IntPtr dwContextHelpId;
public MsgBoxCallback lpfnMsgBoxCallback;
public uint dwLanguageId;
} public delegate void MsgBoxCallback(HELPINFO lpHelpInfo);
[DllImport("User32.dll")]
public static extern int MessageBoxIndirect([In] ref MSGBOXPARAMS lpMsgBoxParams);
}
}这里是调用代码: User.MSGBOXPARAMS mp = new User.MSGBOXPARAMS();
mp.cbSize = (uint)Marshal.SizeOf(mp);
mp.lpszText = "what?";
mp.lpszCaption = "nonono"; User.MessageBoxIndirect(ref mp);
OK.
在C#中,ICON位置一片空白.
public delegate void MsgBoxCallback(HELPINFO lpHelpInfo);这样也行啊?
我的结构是
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct MSGBOXPARAMS
{
public uint cbSize;
public IntPtr hwndOwner;
public IntPtr hInstance;
public string lpszText;
public string lpszCaption;
public uint dwStyle;
public string lpszIcon;
public int dwContextHelpId;
public string lpfnMsgBoxCallback;
public uint dwLanguageId;
};
lpsz一般是指字符串。sz的意思可能是指string Zero吧?这点我不太确定,隐约记得在哪里看到过,是说以\0结尾的字符串。
ResourceManager rm = new ResourceManager("API版MessageBox.myIconRes", Assembly.GetExecutingAssembly());MsgBp.lpszIcon = (Image)rm.GetObject("Pake");现在的问题就是这个指针--->图片
怎么办啊?
ResourceManager rm = new ResourceManager("API版MessageBox.myIconRes", Assembly.GetExecutingAssembly());MsgBp.lpszIcon = (Image)rm.GetObject("Pake");现在的问题就是这个指针--->图片
怎么办啊?
比如有一种方法:
LoadIcon(hInstance,strIconName);
这个方法如果第一个参数为NULL,后一个参数为系统定义的一个图标名称,比如:IDI_ERR,应该返回那个熟悉的错误图标的句柄。
这个函数在其它VC++的程序中都可以正常运行,但在.NET的程序中执行是地总是返回了0。如果要使用,我目前能够想得到的办法是:
1:使用其它API把Win32的资源文件模块加载到进程中,取得这个模块的句柄。
2:用1得到的句柄和资源名称调用LoadIcon返回一个IntPtr。
3:用这个IntPtr调用msg。不过我觉得这个方法纯属多余,为什么要这样使用呢?
MessageBox.Show().就完成了所有的工作。为啥要这么麻烦。
using System.Runtime.InteropServices;//API要用的
using System.Resources;//使用资源文件要用的
using System.Reflection;//Assembly类装这里面
using System.Drawing;namespace API版MessageBox
{
class Program
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct MSGBOXPARAMS
{
public uint cbSize;
public IntPtr hwndOwner;
public IntPtr hInstance;
public string lpszText; //匈牙利命名法lpsz==long point string Zero
public string lpszCaption;
public uint dwStyle;
public Icon lpszIcon;
public int dwContextHelpId;
public string lpfnMsgBoxCallback;
public uint dwLanguageId;
};
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
internal static extern void MessageBoxIndirect(ref MSGBOXPARAMS MsgBp);//自己设定参数
internal const int MB_YESNO = 0x00000004;
internal const int MB_USERICON = 0x00000080;
static int Main()
{
ResourceManager rm = new ResourceManager("API版MessageBox.myIconRes", Assembly.GetExecutingAssembly());
MSGBOXPARAMS MsgBp = new MSGBOXPARAMS();
MsgBp.hInstance = IntPtr.Zero;//不能直接写0(int 不能转化为IntPtr),更不能写null
MsgBp.hwndOwner = IntPtr.Zero;
MsgBp.lpszText = "一定要成功啊MessageBoxIndirect我的ICON";
MsgBp.lpszCaption = "Hi";
MsgBp.dwStyle = MB_USERICON | MB_YESNO;
MsgBp.lpszIcon =(Icon)rm.GetObject("Pake");
MsgBp.dwContextHelpId = 0;
MsgBp.lpfnMsgBoxCallback = null;
MsgBp.dwLanguageId = SUBLANG_ENGLISH_US;
MsgBp.cbSize = (uint)Marshal.SizeOf(MsgBp);
MessageBoxIndirect(ref MsgBp);
return 0;
}
}
}问题一:MsgBp.lpszIcon =(Icon)rm.GetObject("Pake");查API函数手册上lpszIcon是个指向资源文件Icon的指针,而我记得API指针应该对应C#里的string,但是string怎么能做ICON用呢?
问题二:还是那行报错Unable to cast object of type 'System.Drawing.Bitmap' to type 'System.Drawing.Icon.执行后ICON根本就没有显示.还有就是我把ICON改成Image能运行但是执行后ICON根本就没有显示制作资源文件也有点麻烦.我找了张KaKaxi.icousing System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Resources;namespace 把忍犬帕克做成资源文件
{
class Program
{
static void Main(string[] args)
{//把KaKaxi.ico先拖入该.\Bin\Debug\下运行会生成一个资源文件
ResourceWriter rw = new ResourceWriter("myIconRes.resources");//将资源文件存入PaKe.resources文件中
Image Img = Image.FromFile("KaKaxi.ico");
rw.AddResource("Pake",Img);
rw.Generate(); //以系统默认的format保存所有的资源
rw.Close();
}
}
}问题三:本来我想把这行Image Img = Image.FromFile("KaKaxi.ico");改成Icon myIcon=Icon.From(****);//可是Icon只有From句柄没有FromFile.所以上面用(Icon)会报错,我左右为难啊?
public struct HelpInfo
{
}
public delegate void MsgboxCallback(HelpInfo helpInfo); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MsgboxParams
{
public int cbSize;
public IntPtr hwndOwner;
public IntPtr hInstance;
public string text;
public string caption;
public int style;
public IntPtr icon;
public int helpId;
public MsgboxCallback callback;
public int languageId;
}
class Program
{
[DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern int MessageBoxIndirect(ref MsgboxParams param); [DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr LoadIcon(IntPtr hInstance, string iconName); static void Main(string[] args)
{
MsgboxParams mp = new MsgboxParams();
mp.hwndOwner = IntPtr.Zero;
mp.hInstance = IntPtr.Zero;
mp.text = "ok";
mp.caption = "ti xing";
mp.style = (int)0x00000080L;
mp.icon = (IntPtr)32512;
mp.helpId = 0;
mp.callback = null;
mp.languageId = 0;
mp.cbSize = Marshal.SizeOf(mp);
MessageBoxIndirect(ref mp);
}
}这样的话就可以用系统定义的图标了
问题一:MsgBp.lpszIcon =(Icon)rm.GetObject("Pake");查API函数手册上lpszIcon是个指向资源文件Icon的指针,而我记得API指针应该对应C#里的string,但是string怎么能做ICON用呢?
1:指针怎么可能对应string?严格的说指针只能用IntPtr.但是在C#中指针是没有任何意义的(你除了显示出这个指针的实际整数值、传递给其它的非托管函数之外,但这不在C#的托管代码中执行)没有意义。你之所以认为string=指针是因为在C/C++中字符串是字符数组,往往是用指针(char *)表示的,所以你就这样觉得。
在这个所谓的Icon的指针,应该是指向内在中某个表示Icon的内存块的指针(也有可能是指向一个handle,其中包含了指向最终Icon数据的指针),而绝不是什么string.
问题二:还是那行报错Unable to cast object of type 'System.Drawing.Bitmap' to type 'System.Drawing.Icon.执行后ICON根本就没有显示.还有就是我把ICON改成Image能运行但是执行后ICON根本就没有显示
没错,因为你传递的东西根本就是两码事,一个是托管资源,一个是非托管的。即使你传递过去又有什么意义?
问题三:本来我想把这行Image Img = Image.FromFile("KaKaxi.ico");改成Icon myIcon=Icon.From(****);//可是Icon只有From句柄没有FromFile.所以上面用(Icon)会报错,我左右为难啊?这个方法也和上面的一样在。我查找过了,问题的关键我在上面的帖子就说过了,就是这个非托管的图标指针在C#中无法取得。在C#中可以调用LoadLibrary这个API函数,但这个函数的第一个参数我不知道应该如何取得。
你说的很对 MspBp.lpszIcon 是个句柄并且
托管创建的ICON 的技术 Icon icon=new Icon("myfileICon");
icon.Handle 获取句柄
但是我们传进去后 不会得到显示
因为 我们的hInstance 没法设置
hinstance是包含此资源的实例。
MessageBoxIndirect从hinstance中加载icon,参见LoadIcon。
如果要使用系统图标,就把hinstance设为0.