C#使用phantomjs 进行网页整页截屏
hantomjs 是一个基于js的webkit内核无头浏览器 也就是没有显示界面的浏览器,这样访问网页就省去了浏览器的界面绘制所消耗的系统资源,比较适合用于网络测试等应用 。我只是调用了其中的一个截取网页的小功能,可以完美的解析网页的js和css 而且兼容html5,不过最新的1.5版本不支持flash,所以我采用了1.4的版本,能够得到完整的网页体验。 先看看执行的效率(4M电信,22:30点测试): phantomjs的目录结构 dll挺多的 都是必须的 codecs里面包含编码信息 qcncodecs4.dll 这个是中文支持 里面还有韩文 日文和*繁体中文 这玩意必须有 要不然会出现乱码的。 imageformats目录里面是qgif4.dll和qjpeg4.dll两个dll 是用于图片转换的 默认png格式。 rasterize.js 就是官方写好的截屏的js代码 var page = require(‘webpage‘).create(), address, output, size; if (phantom.args.length < 2 || phantom.args.length > 3) { console.log(‘Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat]‘); console.log(‘ paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"‘); phantom.exit(); } else { address = phantom.args[0]; output = phantom.args[1]; page.viewportSize = { width: 600, height: 600 }; if (phantom.args.length === 3 && phantom.args[1].substr(-4) === ".pdf") { size = phantom.args[2].split(‘*‘); page.paperSize = size.length === 2 ? { width: size[0], height: size[1], border: ‘0px‘ } : { format: phantom.args[2], orientation: ‘portrait‘, border: ‘1cm‘ }; } page.open(address, function (status) { if (status !== ‘success‘) { console.log(‘Unable to load the address!‘); } else { window.setTimeout(function () { page.render(output); phantom.exit(); }, 200); } }); } 看这个js的意思貌似可以将pdf文件转换为图片文件,我没有测试。我调用的时候只是传了两个参数。 下面的就算调用的核心js代码 直接输出图像文件。 page.render(output); 在C#中调用这玩意的代码是: private void GetImage(string url) { string links = url.IndexOf("http://") > -1 ? url : "http://" + url; #region 启动进程 Process p = new Process(); p.StartInfo.FileName = Environment.CurrentDirectory+"//phantomjs.exe"; p.StartInfo.WorkingDirectory = Environment.CurrentDirectory+"//pic//"; p.StartInfo.Arguments = string.Format("--ignore-ssl-errors=yes --load-plugins=yes " + Environment.CurrentDirectory + "//rasterize.js " + links + " "+url+".png"); p.StartInfo.CreateNoWindow = true; p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; if (!p.Start()) throw new Exception("无法Headless浏览器."); #endregion } 关键是这里 p.StartInfo.Arguments = string.Format("--ignore-ssl-errors=yes --load-plugins=yes " + Environment.CurrentDirectory + "//rasterize.js " + links + " "+url+".png"); --ignore-ssl-errors=yes 忽视加密的ssl连接错误 --load-plugins=yes 载入插件 上面的两参数可以不用 ,加上了是为了体验真实的网页体验效果,比如,不载入插件的话 flash就不会加载的。 Environment.CurrentDirectory + "//rasterize.js " 这里就是调用写好的js驱动代码,下面带上的参数是作用于这个js的。 links 访问的网址连接,最好加入http://。 "+url+".png 输出的图片 默认是png格式 当包含了上面 imageformats里面的dll的话 就可以输出jpg格式和gif格式的图片。 所有代码就这样子的,用起来很简单,就像在代码中调用cmd一样的。这样就很容易在不错的机子上进行多线程的批量截图而不影响任何操作,效率方面还很不错!
C#使用GDI+制作背景颜色淡入淡出效果的按钮
用过QQ2009的网友都知道QQ主面板的界面非常炫丽,特别好看,鼠标移上去还有淡入淡出的效果。那这样效果是怎么做出来的呢?其实不难,只要自定义一个用户控件的外怪就可以了,用到GDI+技术和时钟控件来操作… 首先我们在VS2008里面新建一个Windows窗体控件库的项目,系统会自动生成一个用户控件UserControl1.cs出来,我们就用默认的名字吧~~ 本例子下载地址:http://files.cnblogs.com/mengxin523/自定义按钮控件.rar 程序所有代码如下: using System; using System.Data; using System.Drawing; using System.Collections; using System.Windows.Forms; using System.ComponentModel; using System.Drawing.Drawing2D; namespace MyButton { public partial class UserControl1 : UserControl { private bool calledbykey = false; private State mButtonState = State.None; //按钮的状态 private Timer mFadeIn = new Timer(); //淡入的时钟 private Timer mFadeOut = new Timer(); //淡出的时钟 private int mGlowAlpha = 0; //透明度 private System.ComponentModel.Container components = null; public UserControl1() { InitializeComponent(); //一下几个语句是对控件进行设置和对GDI+进行优化 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.DoubleBuffer, true); this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); this.SetStyle(ControlStyles.ResizeRedraw, true); this.SetStyle(ControlStyles.Selectable, true); this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); this.SetStyle(ControlStyles.UserPaint, true); this.UpdateStyles(); this.BackColor = Color.Transparent; //设置控件背景色透明 mFadeIn.Interval = 20; //淡入速度 mFadeOut.Interval = 20; //淡出速度 } protected override void Dispose(bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } private void InitializeComponent() { this.Name = "MySystemButton"; this.Size = new System.Drawing.Size(100, 32); this.Paint += new System.Windows.Forms.PaintEventHandler(this.VistaButton_Paint); this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.VistaButton_KeyUp); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.VistaButton_KeyDown); this.MouseEnter += new System.EventHandler(this.VistaButton_MouseEnter); this.MouseLeave += new System.EventHandler(this.VistaButton_MouseLeave); this.MouseUp += new MouseEventHandler(VistaButton_MouseUp); this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.VistaButton_MouseDown); this.GotFocus += new EventHandler(VistaButton_MouseEnter); this.LostFocus += new EventHandler(VistaButton_MouseLeave); this.mFadeIn.Tick += new EventHandler(mFadeIn_Tick); this.mFadeOut.Tick += new EventHandler(mFadeOut_Tick); this.Resize += new EventHandler(VistaButton_Resize); } enum State { None, Hover, Pressed }; /// <summary> /// 按钮的样式 /// </summary> public enum Style { /// <summary> /// Draw the button as normal /// </summary> Default, /// <summary> /// Only draw the background on mouse over. /// </summary> Flat }; /// <summary> /// 用于设置按钮的用处 /// </summary> public enum UseTo { Min, Close }; UseTo Ut = UseTo.Close; //默认作为关闭按钮 [Category("UseTo"), DefaultValue(UseTo.Close), Browsable(true), Description("设置按钮的用处")] public UseTo UT { get { return Ut; } set { Ut = value; this.Invalidate(); } } private string mText; /// <summary> /// 按钮上显示的文本 /// </summary> [Category("Text"), Description("按钮上显示的文本.")] public string ButtonText { get { return mText; } set { mText = value; this.Invalidate(); } } private Color mForeColor = Color.White; /// <summary> /// 文本颜色 /// </summary> [Category("Text"), Browsable(true), DefaultValue(typeof(Color), "White"), Description("文本颜色.")] public override Color ForeColor { get { return mForeColor; } set { mForeColor = value; this.Invalidate(); } } private ContentAlignment mTextAlign = ContentAlignment.MiddleCenter; /// <summary> /// 文本对齐方式 /// </summary> [Category("Text"), DefaultValue(typeof(ContentAlignment), "MiddleCenter")] public ContentAlignment TextAlign { get { return mTextAlign; } set { mTextAlign = value; this.Invalidate(); } } private Image mImage; /// <summary> 按钮上的图片 /// </summary> [Category("Image"), DefaultValue(null)] public Image Image { get { return mImage; } set { mImage = value; this.Invalidate(); } } private ContentAlignment mImageAlign = ContentAlignment.MiddleLeft; /// <summary> 按钮对齐方式 /// </summary> [Category("Image"), DefaultValue(typeof(ContentAlignment), "MiddleLeft")] public ContentAlignment ImageAlign
C#使用API屏蔽系统热键和任务管理器
最近做的一个winform类型的项目中需要屏蔽系统热键,在网上搜索了一下,基本上都是调用api来进行hook操作,下面的代码就可以完成功能 using System; using System.IO; using System.Reflection; using System.Runtime.InteropServices; using System.Windows.Forms; namespace WAT.PMS { /// <summary> /// Description: Hook Helper类,可以屏蔽一些热键并屏蔽任务管理器 /// Author: ZhangRongHua /// Create DateTime: 2009-6-19 20:21 /// UpdateHistory: /// </summary> public class HookHelper { #region Delegates public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); #endregion #region 变量声明 private HookProc KeyboardHookProcedure; private FileStream MyFs; // 用流来屏蔽ctrl alt delete private const byte LLKHF_ALTDOWN = 0x20; private const byte VK_CAPITAL = 0x14; private const byte VK_ESCAPE = 0x1B; private const byte VK_F4 = 0x73; private const byte VK_LCONTROL = 0xA2; private const byte VK_NUMLOCK = 0x90; private const byte VK_RCONTROL = 0xA3; private const byte VK_SHIFT = 0x10; private const byte VK_TAB = 0x09; public const int WH_KEYBOARD = 13; private const int WH_KEYBOARD_LL = 13; private const int WH_MOUSE = 7; private const int WH_MOUSE_LL = 14; private const int WM_KEYDOWN = 0x100; private const int WM_KEYUP = 0x101; private const int WM_LBUTTONDBLCLK = 0x203; private const int WM_LBUTTONDOWN = 0x201; private const int WM_LBUTTONUP = 0x202; private const int WM_MBUTTONDBLCLK = 0x209; private const int WM_MBUTTONDOWN = 0x207; private const int WM_MBUTTONUP = 0x208; private const int WM_MOUSEMOVE = 0x200; private const int WM_MOUSEWHEEL = 0x020A; private const int WM_RBUTTONDBLCLK = 0x206; private const int WM_RBUTTONDOWN = 0x204; private const int WM_RBUTTONUP = 0x205; private const int WM_SYSKEYDOWN = 0x104; private const int WM_SYSKEYUP = 0x105; private static int hKeyboardHook = 0; #endregion #region 函数转换 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); // 卸载钩子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern bool UnhookWindowsHookEx(int idHook); // 继续下一个钩子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); // 取得当前线程编号 [DllImport("kernel32.dll")] private static extern int GetCurrentThreadId(); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern short GetKeyState(int vKey); #endregion #region 方法 /// <summary> /// 钩子回调函数,在这里屏蔽热键。 /// <remark> /// Author:ZhangRongHua /// Create DateTime: 2009-6-19 20:19 /// Update History: /// </remark> /// </summary> /// <param name="nCode">The n code.</param> /// <param name="wParam">The w param.</param> /// <param name="lParam">The l param.</param> /// <returns></returns> private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) { KeyMSG m = (KeyMSG) Marshal.PtrToStructure(lParam, typeof (KeyMSG)); if (((Keys) m.vkCode == Keys.LWin) || ((Keys) m.vkCode == Keys.RWin) || ((m.vkCode == VK_TAB) && ((m.flags & LLKHF_ALTDOWN) != 0)) || ((m.vkCode == VK_ESCAPE) && ((m.flags & LLKHF_ALTDOWN) != 0)) || ((m.vkCode == VK_F4) && ((m.flags & LLKHF_ALTDOWN) != 0)) || (m.vkCode == VK_ESCAPE) && ((GetKeyState(VK_LCONTROL) & 0x8000) != 0) || (m.vkCode == VK_ESCAPE) && ((GetKeyState(VK_RCONTROL) & 0x8000) != 0) ) { return 1; } return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } /// <summary> /// 启动Hook,并用流屏蔽任务管理器 /// <remark> /// Author:ZhangRongHua /// Create DateTime: 2009-6-19 20:20 /// Update History: /// </remark> /// </summary> public void HookStart() { if (hKeyboardHook == 0) { // 创建HookProc实例 KeyboardHookProcedure = new HookProc(KeyboardHookProc); hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0); // 如果设置钩子失败 if (hKeyboardHook == 0) { HookStop(); //throw new Exception("SetWindowsHookEx failedeeeeeeee."); } //用二进制流的方法打开任务管理器。而且不关闭流.这样任务管理器就打开不了 MyFs = new FileStream(Environment.ExpandEnvironmentVariables("%windir%\\system32\\taskmgr.exe"), FileMode.Open); byte[] MyByte = new byte[(int) MyFs.Length]; MyFs.Write(MyByte, 0, (int) MyFs.Length); } } /// <summary> /// 卸载hook,并关闭流,取消屏蔽任务管理器。 /// <remark> /// Author:ZhangRongHua /// Create DateTime: 2009-6-19 20:21 /// Update History: /// </remark> /// </summary> public void HookStop() { bool retKeyboard = true; if (hKeyboardHook != 0) { retKeyboard = UnhookWindowsHookEx(hKeyboardHook); hKeyboardHook = 0; } if (null != MyFs) { MyFs.Close(); } if (!(retKeyboard)) { throw new Exception("UnhookWindowsHookEx failedsssss."); } } #endregion #region Nested type: KeyMSG public struct KeyMSG { public int dwExtraInfo; public int flags; public int scanCode; public int time; public int vkCode; } #endregion } } PS:也可以通过将[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System] 下的DisableTaskmgr项的值设为"1”来屏蔽任务管理器。
C#操作Win32 API函数
摘要:这里介绍C#操作Win32 API函数,C#使用的类库是.Net框架为所有.Net程序开发提供的一个共有的类库——.Net FrameWork SDK。 C#语言有很多值得学习的地方,这里我们主要介绍C#操作Win32 API函数,包括介绍section:INI文件中的段落名称等方面。 C#操作Win32 API函数 C#并不像C++,拥有属于自己的类库。C#使用的类库是.Net框架为所有.Net程序开发提供的一个共有的类库——.Net FrameWork SDK。虽然.Net FrameWork SDK内容十分庞大,功能也非常强大,但还不能面面俱到,至少它并没有提供直接操作INI文件所需要的相关的类。在本文中,C#操作Win32 API函数——WritePrivateProfileString()和GetPrivateProfileString()函数。这二个函数都位于“kernel32.dll”文件中。 我们知道在C#中使用的类库都是托管代码(Managed Code)文件,而Win32的API函数所处的文件,都是非托管代码(Unmanaged Code)文件。这就导致了在C#中不可能直接使用这些非托管代码文件中的函数。好在.Net框架为了保持对下的兼容,也为了充分利用以前的资源,提出了互操作,通过互操作可以实现对Win32的API函数的调用。互操作不仅适用于Win32的API函数,还可以用来访问托管的COM对象。C#中对 Win32的API函数的互操作是通过命名空间“System.Runtime.InteropServices”中的“DllImport”特征类来实现的。它的主要作用是指示此属性化方法是作为非托管DLL的输出实现的。下面代码就是在C#利用命名空间 “System.Runtime.InteropServices”中的“DllImport”特征类申明上面二个Win32的API函数: C#操作Win32 API函数: [ DllImport ( "kernel32" ) ] private static extern long WritePrivateProfileString ( string section , string key , string val , string filePath ) ; 参数说明:section:INI文件中的段落;key:INI文件中的关键字;val:INI文件中关键字的数值;filePath:INI文件的完整的路径和名称。 C#申明INI文件的读操作函数GetPrivateProfileString(): [ DllImport ( "kernel32" ) ] private static extern int GetPrivateProfileString ( string section , string key , string def , StringBuilder retVal , int size , string filePath ) ; 参数说明:section:INI文件中的段落名称;key:INI文件中的关键字;def:无法读取时候时候的缺省数值;retVal:读取数值;size:数值的大小;filePath:INI文件的完整路径和名称。 下面是一个读写INI文件的类 public class INIClass { public string inipath; [DllImport("kernel32")] private static extern long WritePrivateProfileString (string section,string key,string val,string filePath); [DllImport("kernel32")] private static extern int GetPrivateProfileString (string section,string key,string def,StringBuilder retVal,int size,string filePath); /// /// 构造方法 /// /// 文件路径 public INIClass(string INIPath) { inipath = INIPath; } /// /// 写入INI文件 /// /// 项目名称(如 [TypeName] ) /// 键 /// 值 public void IniWriteValue(string Section,string Key,string Value) { WritePrivateProfileString(Section,Key,Value,this.inipath); } /// /// 读出INI文件 /// /// 项目名称(如 [TypeName] ) /// 键 public string IniReadValue(string Section,string Key) { StringBuilder temp = new StringBuilder(500); int i = GetPrivateProfileString(Section,Key,"",temp,500,this.inipath); return temp.ToString(); } /// /// 验证文件是否存在 /// /// 布尔值 public bool ExistINIFile() { return File.Exists(inipath); } }