1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
//------------------------------------------------------------------------------ // <copyright file="CryptoUtil.cs" company="Microsoft"> // Copyright (c) Microsoft Corporation. All rights reserved. // </copyright> //------------------------------------------------------------------------------ namespace System.Web.Security.Cryptography { using System; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using System.Web.Util; // Contains helper methods for dealing with cryptographic operations. internal static class CryptoUtil { /// <summary> /// Similar to Encoding.UTF8, but throws on invalid bytes. Useful for security routines where we need /// strong guarantees that we're always producing valid UTF8 streams. /// </summary> public static readonly UTF8Encoding SecureUTF8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); /// <summary> /// Converts a byte array into its hexadecimal representation. /// </summary> /// <param name="data">The binary byte array.</param> /// <returns>The hexadecimal (uppercase) equivalent of the byte array.</returns> public static string BinaryToHex(byte[] data) { if (data == null) { return null; } char[] hex = new char[checked(data.Length * 2)]; for (int i = 0; i < data.Length; i++) { byte thisByte = data[i]; hex[2 * i] = NibbleToHex((byte)(thisByte >> 4)); // high nibble hex[2 * i + 1] = NibbleToHex((byte)(thisByte & 0xf)); // low nibble } return new string(hex); } // Determines if two buffer instances are equal, e.g. whether they contain the same payload. This method // is written in such a manner that it should take the same amount of time to execute regardless of // whether the result is success or failure. The modulus operation is intended to make the check take the // same amount of time, even if the buffers are of different lengths. // // !! DO NOT CHANGE THIS METHOD WITHOUT SECURITY [MethodImpl(MethodImplOptions.NoOptimization)] public static bool BuffersAreEqual(byte[] buffer1, int buffer1Offset, int buffer1Count, byte[] buffer2, int buffer2Offset, int buffer2Count) { Debug.ValidateArrayBounds(buffer1, buffer1Offset, buffer1Count); Debug.ValidateArrayBounds(buffer2, buffer2Offset, buffer2Count); bool success = (buffer1Count == buffer2Count); // can't possibly be successful if the buffers are of different lengths for (int i = 0; i < buffer1Count; i++) { success &= (buffer1[buffer1Offset + i] == buffer2[buffer2Offset + (i % buffer2Count)]); } return success; } /// <summary> /// Computes the SHA256 hash of a given input. /// </summary> /// <param name="input">The input over which to compute the hash.</param> /// <returns>The binary hash (32 bytes) of the input.</returns> public static byte[] ComputeSHA256Hash(byte[] input) { return ComputeSHA256Hash(input, 0, input.Length); } /// <summary> /// Computes the SHA256 hash of a given segment in a buffer. /// </summary> /// <param name="buffer">The buffer over which to compute the hash.</param> /// <param name="offset">The offset at which to begin computing the hash.</param> /// <param name="count">The number of bytes in the buffer to include in the hash.</param> /// <returns>The binary hash (32 bytes) of the buffer segment.</returns> public static byte[] ComputeSHA256Hash(byte[] buffer, int offset, int count) { Debug.ValidateArrayBounds(buffer, offset, count); using (SHA256 sha256 = CryptoAlgorithms.CreateSHA256()) { return sha256.ComputeHash(buffer, offset, count); } } /// <summary> /// Returns an IV that's based solely on the contents of a buffer; useful for generating /// predictable IVs for ciphertexts that need to be cached. The output value is only /// appropriate for use as an IV and must not be used for any other purpose. /// </summary> /// <remarks>This method uses an iterated unkeyed SHA256 to calculate the IV.</remarks> /// <param name="buffer">The input buffer over which to calculate the IV.</param> /// <param name="ivBitLength">The requested length (in bits) of the IV to generate.</param> /// <returns>The calculated IV.</returns> public static byte[] CreatePredictableIV(byte[] buffer, int ivBitLength) { // Algorithm: // T_0 = SHA256(buffer) // T_n = SHA256(T_{n-1}) // output = T_0 || T_1 || ... || T_n (as many blocks as necessary to reach ivBitLength) byte[] output = new byte[ivBitLength / 8]; int bytesCopied = 0; int bytesRemaining = output.Length; using (SHA256 sha256 = CryptoAlgorithms.CreateSHA256()) { while (bytesRemaining > 0) { byte[] hashed = sha256.ComputeHash(buffer); int bytesToCopy = Math.Min(bytesRemaining, hashed.Length); Buffer.BlockCopy(hashed, 0, output, bytesCopied, bytesToCopy); bytesCopied += bytesToCopy; bytesRemaining -= bytesToCopy; buffer = hashed; // next iteration (if it occurs) will operate over the block just hashed } } return output; } /// <summary> /// Converts a hexadecimal string into its binary representation. /// </summary> /// <param name="data">The hex string.</param> /// <returns>The byte array corresponding to the contents of the hex string, /// or null if the input string is not a valid hex string.</returns> public static byte[] HexToBinary(string data) { if (data == null || data.Length % 2 != 0) { // input string length is not evenly divisible by 2 return null; } byte[] binary = new byte[data.Length / 2]; for (int i = 0; i < binary.Length; i++) { int highNibble = HttpEncoderUtility.HexToInt(data[2 * i]); int lowNibble = HttpEncoderUtility.HexToInt(data[2 * i + 1]); if (highNibble == -1 || lowNibble == -1) { return null; // bad hex data } binary[i] = (byte)((highNibble << 4) | lowNibble); } return binary; } // converts a nibble (4 bits) to its uppercase hexadecimal character representation [0-9, A-F] private static char NibbleToHex(byte nibble) { return (char)((nibble < 10) ? (nibble + '0') : (nibble - 10 + 'A')); } } } |
通过openssl工具生成RSA的公钥和私钥(opnssl工具可在互联网中下载到,也可以点此下载无线接口包,里面包含此工具) 打开openssl文件夹下的bin文件夹,执行openssl.exe文件: 1)生成RSA私钥 输入“生成命令.txt”文件中:“genrsa -out rsa_private_key.pem 1024”,并回车得到生成成功的结果,如下图: 此时,我们可以在bin文件夹中看到一个文件名为rsa_private_key.pem的文件,用记事本方式打开它,可以看到—--BEGIN RSA PRIVATE KEY—--开头,—--END RSA PRIVATE KEY—--结尾的没有换行的字符串,这个就是原始的私钥。 2)把RSA私钥转换成PKCS8格式 输入命令:pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt,并回车当前界面中会直接显示出生成结果,这个结果就是PKCS8格式的私钥,如下图: 右键点击openssl窗口上边边缘,选择编辑→标记,选中要复制的文字(如上图), 此时继续右键点击openssl窗口上边边缘,选择编辑→复制, 把复制的内容粘土进一个新的记事本中,可随便命名,只要知道这个是PKCS8格式的私钥即可。 3)生成RSA公钥 输入命令:rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem,并回车,得到生成成功的结果,如下图: 此时,我们可以在bin文件夹中看到一个文件名为rsa_public_key.pem的文件,用记事本方式打开它,可以看到—--BEGIN PUBLIC KEY—--开头,—--END PUBLIC KEY—--结尾的没有换行的字符串,这个就是公钥。 详情见开放平台对于密钥生成说明 注意:请妥善保管好生成的公私钥! 附:点此查看如何上传公钥 from:https://cshall.alipay.com/enterprise/help_detail.htm?help_id=474010
View Details前两天在VS2008下做个项目,用到了excel组件没有问题,但当把该项目在IIS下配置后,用浏览器浏览结果则不正确,网上说用dcom组件配置下,可是我按照要求配了,结果还是不对。 后来找到一个方法好用了。 Web.config中加了一句话:“<identity impersonate="true" userName="操作系统用户" password="用户密码"/>”,浏览…,结果正确,后来我就在网上查了下这句话的作用,MSDN是这样说的: 1、模拟 IIS 验证的帐户或用户 若要在收到 ASP.NET 应用程序中每个页的每个请求时模拟 Microsoft Internet 信息服务 (IIS) 身份验证用户,必须在此应用程序的 Web.config 文件中包含 <identity> 标记,并将 impersonate 属性设置为 true 2、为 ASP.NET 应用程序的所有请求模拟特定用户 若要为 ASP.NET 应用程序的所有页面上的所有请求模拟特定用户,可以在该应用程序的 Web.config 文件的 <identity> 标记中指定 userName 和 password 属性。例如: <identity impersonate="true" userName="accountname" password="password" /> from:http://blog.csdn.net/lazyleland/article/details/7726528
View Details1. 全部 Activity 可继承自 BaseActivity,便于统一风格与处理公共事件,构建对话框统一构建器的建立,万一需要整体变动,一处修改到处有效。 2. 数据库表段字段常量和 SQL 逻辑分离,更清晰,建议使用 Lite 系列框架 LiteOrm 库,超级清晰且重心可以放在业务上不用关心数据库细节。 3. 全局变量放全局类中,模块私有放自己的管理类中,让常量清晰且集中. 4. 不要相信庞大的管理类的东西会带来什么好处,可能是一场灾难,而要时刻注意单一职责原则,一个类专心做好一件事情更为清晰。 5. 如果数据没有必要加载,数据请务必延迟初始化,谨记为用户节省内存,总不会有坏处。 6. 异常抛出,在合适的位置处理或者集中处理,不要搞的到处是 catch,混乱且性能低,尽量不要在循环体中捕获异常,以提升性能。 7. 地址引用链长时(3 个以上指向)小心内存泄漏,和警惕堆栈地址指向,典型的易发事件是:数据更新了,ListView 视图却没有刷新,这时 Adapter 很可能指向并的并不是你更新的数据容器地址(一般为 List)。 8. 信息同步:不管是数据库还是网网络操作,新插入的数据注意返回 ID(如果没有赋予唯一 ID),否则相当于没有同步。 9. 多线程操作数据库时,db 关闭了会报错,也很可能出现互锁的问题,推荐使用事务,推荐使用自动化的 LiteOrm 库操作。 10. 做之前先考虑那些可以公用,资源,layout,类,做一个结构、架构分析以加快开发,提升代码可复用度。 11. 有序队列操作 add、delete 操作时注意保持排序,否则你会比较难堪喔。 12. 数据库删除数据时,要注意级联操作避免出现永远删不掉的脏数据喔。 13. 关于形参实参:调用函数时参数为基本类型传的是值,即传值;参数为对象传递的是引用,即传址。 14. listview 在数据未满一屏时,setSelection 函数不起作用;ListView 批量操作时各子项和视图正确对应,可见即所选。 15 控制 Activity 的代码量,保持主要逻辑清晰。其他类遵守 SRP(单一职能),ISP(接口隔离)原则。 16. arraylist 执行 remove 时注意移除 int 和 Integer 的区别。你懂得。 17. Log 请打上 Tag,调试打印一定要做标记,能定位打印位置,否则尴尬是:不知道是哪里在打印。 18. 码块/常量/资源可以集中公用的一定共用,即使共用逻辑稍复杂一点也会值得,修改起来很轻松,修改一种,到处有效。 19. setSelection 不起作用,尝试 smoothScrollToPosition。ListView 的 LastVisiblePosition(最后一个可见子项)会随着 getView 方法执行位置不同变动而变。 20. 与 Activity 通讯使用 Handler 更方便; 如果你的框架回调链变长,考虑监听者模式简化回调。 […]
View Details
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
#region 排序方法 #region 冒泡排序法 /// <summary> /// 冒泡排序法 /// </summary> /// <param name="list">数据列表</param> /// <param name="SortType">排序类型,选择是升序还是降序</param> public static void BubbleSort(int[] list, string SortType) { int j, temp; j = 1; while ((j < list.Length)) { for (int i = 0; i < list.Length - j; i++) { bool Bl; if (SortType == "asc") { Bl = list[i] > list[i + 1]; } else if (SortType == "desc") { Bl = list[i] < list[i + 1]; } else { Bl = false; } if (Bl) { temp = list[i]; list[i] = list[i + 1]; list[i + 1] = temp; } } j++; } } #endregion 冒泡排序法 #region 选择排序法 /// <summary> /// 选择排序法 /// </summary> /// <param name="list">数据列表</param> public static void ChoiceSort(int[] list) { int min; for (int i = 0; i < list.Length - 1; i++) { min = i; for (int j = i + 1; j < list.Length; j++) { if (list[j] < list[min]) min = j; } int t = list[min]; list[min] = list[i]; list[i] = t; } } #endregion 选择排序法 #region 插入排序法 /// <summary> /// 插入排序法 /// </summary> /// <param name="list">数据列表</param> public static void InsertSort(int[] list) { for (int i = 1; i < list.Length; i++) { int t = list[i]; int j = i; while ((j > 0) && (list[j - 1] < t)) { list[j] = list[j - 1]; --j; } list[j] = t; } } #endregion 插入排序法 #region 希尔排序法 /// <summary> /// 希尔排序法 /// </summary> /// <param name="list">数据列表</param> public static void ShellSort(int[] list) { int inc; for (inc = 1; inc <= list.Length / 9; inc = 3 * inc + 1) ; for (; inc > 0; inc /= 3) { for (int i = inc + 1; i <= list.Length; i += inc) { int t = list[i - 1]; int j = i; while ((j > inc) && (list[j - inc - 1] > t)) { list[j - 1] = list[j - inc - 1]; j -= inc; } list[j - 1] = t; } } } #endregion 希尔排序法 #endregion 排序方法 |
移动端越来越火了,我们在开发过程中,总会碰到要和移动端打交道的场景,比如.NET和android或者iOS的打交道。为了让数据交互更安全,我们需要对数据进行加密传输。今天研究了一下,把几种语言的加密都实践了一遍,实现了.NET,java(android),iOS都同一套的加密算法,下面就分享给大家。 AES加密有多种算法模式,下面提供两套模式的可用源码。 加密方式: 先将文本AES加密 返回Base64转码 解密方式: 将数据进行Base64解码 进行AES解密 一、CBC(Cipher Block Chaining,加密块链)模式 是一种循环模式,前一个分组的密文和当前分组的明文异或操作后再加密,这样做的目的是增强破解难度. 密钥 密钥偏移量 java/adroid加密AESOperator类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
package com.bci.wx.base.util; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; /** * AES 是一种可逆加密算法,对用户的敏感信息加密处理 对原始数据进行AES加密后,在进行Base64编码转化; */ public class AESOperator { /* * 加密用的Key 可以用26个字母和数字组成 此处使用AES-128-CBC加密模式,key需要为16位。 */ private String sKey = "smkldospdosldaaa";//key,可自行修改 private String ivParameter = "0392039203920300";//偏移量,可自行修改 private static AESOperator instance = null; private AESOperator() { } public static AESOperator getInstance() { if (instance == null) instance = new AESOperator(); return instance; } public static String Encrypt(String encData ,String secretKey,String vector) throws Exception { if(secretKey == null) { return null; } if(secretKey.length() != 16) { return null; } Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] raw = secretKey.getBytes(); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); IvParameterSpec iv = new IvParameterSpec(vector.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度 cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); byte[] encrypted = cipher.doFinal(encData.getBytes("utf-8")); return new BASE64Encoder().encode(encrypted);// 此处使用BASE64做转码。 } // 加密 public String encrypt(String sSrc) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] raw = sKey.getBytes(); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度 cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8")); return new BASE64Encoder().encode(encrypted);// 此处使用BASE64做转码。 } // 解密 public String decrypt(String sSrc) throws Exception { try { byte[] raw = sKey.getBytes("ASCII"); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes()); cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密 byte[] original = cipher.doFinal(encrypted1); String originalString = new String(original, "utf-8"); return originalString; } catch (Exception ex) { return null; } } public String decrypt(String sSrc,String key,String ivs) throws Exception { try { byte[] raw = key.getBytes("ASCII"); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec iv = new IvParameterSpec(ivs.getBytes()); cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);// 先用base64解密 byte[] original = cipher.doFinal(encrypted1); String originalString = new String(original, "utf-8"); return originalString; } catch (Exception ex) { return null; } } public static String encodeBytes(byte[] bytes) { StringBuffer strBuf = new StringBuffer(); for (int i = 0; i < bytes.length; i++) { strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a'))); strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a'))); } return strBuf.toString(); } public static void main(String[] args) throws Exception { // 需要加密的字串 String cSrc = "[{\"request_no\":\"1001\",\"service_code\":\"FS0001\",\"contract_id\":\"100002\",\"order_id\":\"0\",\"phone_id\":\"13913996922\",\"plat_offer_id\":\"100094\",\"channel_id\":\"1\",\"activity_id\":\"100045\"}]"; // 加密 long lStart = System.currentTimeMillis(); String enString = AESOperator.getInstance().encrypt(cSrc); System.out.println("加密后的字串是:" + enString); long lUseTime = System.currentTimeMillis() - lStart; System.out.println("加密耗时:" + lUseTime + "毫秒"); // 解密 lStart = System.currentTimeMillis(); String DeString = AESOperator.getInstance().decrypt(enString); System.out.println("解密后的字串是:" + DeString); lUseTime = System.currentTimeMillis() - lStart; System.out.println("解密耗时:" + lUseTime + "毫秒"); } } |
.NET AES加密解密:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
using System; using System.Security.Cryptography; using System.Text; namespace AESDome { class Program { private static string key = "smkldospdosldaaa"; //key,可自行修改 private static string iv = "0392039203920300"; //偏移量,可自行修改 static void Main(string[] args) { string encrytpData = Encrypt("abc", key, iv); Console.WriteLine(encrytpData); string decryptData = Decrypt("5z9WEequVr7qtd+WoxV+Kw==", key, iv); Console.WriteLine(decryptData); Console.ReadLine(); } public static string Encrypt(string toEncrypt, string key, string iv) { byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key); byte[] ivArray = UTF8Encoding.UTF8.GetBytes(iv); byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); RijndaelManaged rDel = new RijndaelManaged(); rDel.BlockSize = 128; rDel.KeySize = 256; rDel.FeedbackSize = 128; rDel.Padding = PaddingMode.PKCS7; rDel.Key = keyArray; rDel.IV = ivArray; rDel.Mode = CipherMode.CBC; ICryptoTransform cTransform = rDel.CreateEncryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } public static string Decrypt(string toDecrypt, string key, string iv) { byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key); byte[] ivArray = UTF8Encoding.UTF8.GetBytes(iv); byte[] toEncryptArray = Convert.FromBase64String(toDecrypt); // 这里的模式,请保持和上面加密的一样。但源代码里,这个地方并没有修正,虽然也能正确解密。看到博客的朋友,请自行修改。 // 这是个人疏忽的地址,感谢@jojoka 的提醒。 RijndaelManaged rDel = new RijndaelManaged(); rDel.Key = keyArray; rDel.IV = ivArray; rDel.Mode = CipherMode.CBC; rDel.Padding = PaddingMode.Zeros; rDel.BlockSize = 128; rDel.KeySize = 256; rDel.FeedbackSize = 128; rDel.Padding = PaddingMode.PKCS7; rDel.Key = keyArray; rDel.IV = ivArray; rDel.Mode = CipherMode.CBC; ICryptoTransform cTransform = rDel.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return UTF8Encoding.UTF8.GetString(resultArray); } } } |
iOS源码,请下载源码,源码里有包含。 java,.net,iOS,android通用AES加密解密源码:AES_CBC_ECB_android_java_ios_net通用模式 二、ECB(Electronic Code Book,电子密码本)模式 是一种基础的加密方式,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一个个输出组成密文。 只需要提供密码即可。 iOS,android,java已调通源码:AES_CBC_ECB_android_java_ios_net通用模式 AES在线加解密验证工具: http://www.seacha.com/tools/aes.html from:http://www.cnblogs.com/jys509/p/4768120.html
View Details本文目录 1.窗口的外观 2.窗口的位置 3.窗口的大小 4.窗口的可见性和状态 5.窗口的生命周期 1.窗口的外观 WPF中默认窗口框架的外观,主要取决于Icon、Title、WindowsStyle、ResizeMode等属性。 Icon 指定窗口的图标; Title 指定窗口的标题; WindowStyle 指定窗口样式,有4个取值: None,无边框;(当ResizeMode属性为NoResize时,仅剩下窗口核心。) SingleBorderWindow,单边框【默认】; ThreeDBorderWindow,3D边框; ToolBorderWindow,工具箱窗口; ResizeMode 是指定大小调节样式,有4个取值: NoResize,不可调节,同时没有最大最小按钮; CanMinimize,不可调节。但可以最小化;(此时最大化按钮不可用) CanResize,可调节【默认】; CanResizeWithGrid,可根据网格调节;(窗口右下脚显示可调节网格) 2.窗口的位置 WindowStartLocation 指定窗口初始位置,有3个取值: Manual,手工指定位置,表示可以通过设置其Top、Left属性值来决定窗口的初始位置; CenterScreen,屏幕中央; CenterOwner,父窗体中央; TopMost 调节窗口的前后顺序,属性值为true时,窗口位于最前。 TopMost值为true的窗口,位于TopMost值为false的窗口之前(如下图记事本与示例窗口); TopMost值都为true的窗口,获得焦点的窗口位于前(如下图QQ与示例窗口)。 3.窗口的大小 Width、Height,分别表示窗口的宽度和高度,称为“尺寸属性”。 MaxWidth、MinWidth、MaxHeight、MinHeight,分别表示窗口最大宽度、最小宽度、最大高度、最小高度。可以通过得到和更改这些属性值,来获取和改变窗口的大小和长宽范围。 ActualWidth、ActualHeight,分别表示窗口的实际宽度和实际高度,称为“实际尺寸属性”。 实际尺寸属性是根据当前窗口大小、最小化时窗口大小和最大化时窗口大小来计算得到的,其值是只读的,也就是说,不能通过改变ActualWidth、ActualHeight的值来更改窗口大小。 SizeToContent,表示窗口大小由内容决定,有4个取值: Manual,手工【默认】; Width,窗体宽度由内容决定; Height,窗体高度由内容决定; WidthAndHeight,窗体大小由内容决定; 如果内容尺寸超过了窗口的最大或最小范围,还是以最大/最小范围为主。如果手工指定了窗口的Width、Height 属性,那么SizeToContent将被忽略。 ReSize,窗口大小的可调整性(第1部分已提到)。 4.窗口的可见性和状态 Visibility,窗口可见性,有4个枚举值: Visiable,可见; Hidden,隐藏; Collapsed,折叠。 虽然窗口类认为Collapsed与Hidden一样,但二者区别在于,Hidden仅仅将元素设为不可见,但是元素在画面上依然占有空间;而Collapsed,在不可视的基础上,能将元素在画面上的占位符清除,元素彻底不影响画面。 Show、Hide,显示窗口和隐藏窗口的两个方法。如果窗口的ShowInTaskbar属性值为true,Hide不但隐藏窗口本身,同时隐藏其在任务栏上的图标。 WindowState,窗口状态属性,有3个枚举值: Normal,正常; Maximized,最大化; Minimized,最小化; RestoreBounds,获取窗口在最小化或最大化之前的大小和位置,有4个枚举值,Top、Left、Width、Height。
1 2 3 4 |
<span style="color:#008000;line-height:1.5 !important;">//</span><span style="color:#008000;line-height:1.5 !important;">输出当前窗口的RestoreBounds值</span><span style="color:#008000;line-height:1.5 !important;"> </span><span style="color:#0000FF;line-height:1.5 !important;">private</span> <span style="color:#0000FF;line-height:1.5 !important;">void</span> button1_Click(<span style="color:#0000FF;line-height:1.5 !important;">object</span> sender, RoutedEventArgs e) { MessageBox.Show(<span style="color:#0000FF;line-height:1.5 !important;">this</span>.RestoreBounds.ToString()); } |
该主窗口的Top:75,Left:75,Width:525,Height:350 只有窗口在Normal状态下移动或调整时,RestoreBounds的值才会改变。于是可以在窗口关闭时将RestoreBounds属性值保存到配置文件,下一次启动程序窗口时,读取上次保存的窗口大小、位置,来初始化窗口,以此实现保存用户配置等功能。MSDN上的例子:http://msdn.microsoft.com/zh-cn/library/system.windows.window.restorebounds.aspx 。但推荐使用config文件来保存配置,更方便。 应用程序窗口在上次关闭处启动 向资源中添加两个变量MainRestoreBounds和MainWindowState,对应类型如图所示,用于保存主窗口的RestoreBounds属性值。 XAML
1 |
<span style="color:#0000FF;line-height:1.5 !important;"><</span><span style="color:#800000;line-height:1.5 !important;">Window </span><span style="color:#FF0000;line-height:1.5 !important;">x:Class</span><span style="color:#0000FF;line-height:1.5 !important;">="WpfApplication1.MainWindow"</span><span style="color:#FF0000;line-height:1.5 !important;"> xmlns</span><span style="color:#0000FF;line-height:1.5 !important;">="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span><span style="color:#FF0000;line-height:1.5 !important;"> xmlns:x</span><span style="color:#0000FF;line-height:1.5 !important;">="http://schemas.microsoft.com/winfx/2006/xaml"</span><span style="color:#FF0000;line-height:1.5 !important;"> Width</span><span style="color:#0000FF;line-height:1.5 !important;">="360"</span><span style="color:#FF0000;line-height:1.5 !important;"> Height</span><span style="color:#0000FF;line-height:1.5 !important;">="240"</span><span style="color:#FF0000;line-height:1.5 !important;"> Closing</span><span style="color:#0000FF;line-height:1.5 !important;">="Window_Closing"</span><span style="color:#0000FF;line-height:1.5 !important;">></span> <span style="color:#0000FF;line-height:1.5 !important;"></</span><span style="color:#800000;line-height:1.5 !important;">Window</span><span style="color:#0000FF;line-height:1.5 !important;">></span> |
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<span style="color:#0000FF;line-height:1.5 !important;">using</span> System; <span style="color:#0000FF;line-height:1.5 !important;">using</span> System.Collections.Generic; <span style="color:#0000FF;line-height:1.5 !important;">using</span> System.Linq; <span style="color:#0000FF;line-height:1.5 !important;">using</span> System.Text; <span style="color:#0000FF;line-height:1.5 !important;">using</span> System.Windows; <span style="color:#0000FF;line-height:1.5 !important;">using</span> System.Windows.Controls; <span style="color:#0000FF;line-height:1.5 !important;">using</span> System.Windows.Data; <span style="color:#0000FF;line-height:1.5 !important;">using</span> System.Windows.Documents; <span style="color:#0000FF;line-height:1.5 !important;">using</span> System.Windows.Input; <span style="color:#0000FF;line-height:1.5 !important;">using</span> System.Windows.Media; <span style="color:#0000FF;line-height:1.5 !important;">using</span> System.Windows.Media.Imaging; <span style="color:#0000FF;line-height:1.5 !important;">using</span> System.Windows.Navigation; <span style="color:#0000FF;line-height:1.5 !important;">using</span> System.Windows.Shapes; <span style="color:#0000FF;line-height:1.5 !important;">namespace</span> WpfApplication1 { <span style="color:#0000FF;line-height:1.5 !important;">public</span> <span style="color:#0000FF;line-height:1.5 !important;">partial</span> <span style="color:#0000FF;line-height:1.5 !important;">class</span> MainWindow : Window { <span style="color:#0000FF;line-height:1.5 !important;">public</span> MainWindow() { InitializeComponent(); <span style="color:#008000;line-height:1.5 !important;">//</span><span style="color:#008000;line-height:1.5 !important;">读取配置文件</span><span style="color:#008000;line-height:1.5 !important;"> </span> <span style="color:#0000FF;line-height:1.5 !important;">try</span> { <span style="color:#008000;line-height:1.5 !important;">//</span><span style="color:#008000;line-height:1.5 !important;">设置位置、大小</span><span style="color:#008000;line-height:1.5 !important;"> </span> Rect restoreBounds = Properties.Settings.Default.MainRestoreBounds; <span style="color:#0000FF;line-height:1.5 !important;">this</span>.WindowState = WindowState.Normal; <span style="color:#0000FF;line-height:1.5 !important;">this</span>.Left = restoreBounds.Left; <span style="color:#0000FF;line-height:1.5 !important;">this</span>.Top = restoreBounds.Top; <span style="color:#0000FF;line-height:1.5 !important;">this</span>.Width = restoreBounds.Width; <span style="color:#0000FF;line-height:1.5 !important;">this</span>.Height = restoreBounds.Height; <span style="color:#008000;line-height:1.5 !important;">//</span><span style="color:#008000;line-height:1.5 !important;">设置窗口状态</span><span style="color:#008000;line-height:1.5 !important;"> </span> <span style="color:#0000FF;line-height:1.5 !important;">this</span>.WindowState = Properties.Settings.Default.MainWindowState; } <span style="color:#0000FF;line-height:1.5 !important;">catch</span> { } } <span style="color:#0000FF;line-height:1.5 !important;">private</span> <span style="color:#0000FF;line-height:1.5 !important;">void</span> Window_Closing(<span style="color:#0000FF;line-height:1.5 !important;">object</span> sender, System.ComponentModel.CancelEventArgs e) { <span style="color:#008000;line-height:1.5 !important;">//</span><span style="color:#008000;line-height:1.5 !important;">保存当前位置、大小和状态,到配置文件</span><span style="color:#008000;line-height:1.5 !important;"> </span> Properties.Settings.Default.MainRestoreBounds = <span style="color:#0000FF;line-height:1.5 !important;">this</span>.RestoreBounds; Properties.Settings.Default.MainWindowState = <span style="color:#0000FF;line-height:1.5 !important;">this</span>.WindowState; Properties.Settings.Default.Save(); } } } |
5.窗口的生命周期 关于各事件的描述: Initialized:当窗口的FrameworkElement底层初始化时触发,即InitializeComponent方法调用时触发。 LocationChanged:窗口被移动时触发。 Activated:窗口被激活时触发。 Deactivated:窗口处于非激活时(即其他窗口处于激活时)触发。 Loaded:显示窗口之前触发。 ContentRendered:当内容显示的时候触发。 Closing:尝试关闭窗口时触发,可以将参数CancelEventArgs的Cancel的属性设置为true,取消关闭操作。 Closed:在窗口关闭后触发该事件,无法取消。 Unloaded:当关闭窗口并且从可视化树移除后触发。 from:http://www.cnblogs.com/libaoheng/archive/2011/11/18/2253751.html
View DetailsWPF / Silverlight中的 Timer 与 DispatcherTimer 有什么区别呢? 这里我给大家简单介绍一下他们在使用和实现上的区别。 在一个应用程序中,Timer会重复生成time事件,而DispatcherTimer是一个集成到了Dispatcher队列中的时钟,这可以使它被按照指定的时间间隔以指定的priority定期执行。 对于一个Timer时钟事件,系统并不能保证在时间间隔到达后被立即执行,但是能够确保在时间间隔到达之前不被执行。这是因为DispatcherTimer像其他操作一样被放置在了Dispatcher队列中。何时执行DispatcherTimer事件依赖于队列中的其他任务以及他们的优先级. 如果一个WPF应用程序使用了Timer时钟,那么它的事件必须在一个单独的时钟线程中运行,而不是在UI线程中,这对于WPF应用程序毫无用处——你没法在UI线程之外直接访问UI元素,而只能通过Invoke或者BeginInvoke将操作发送给Dispatcher 对象,委托Dispatcher去执行UI操作。 看到这里,你大概知道了为什么我们在WPF中应该用DispatcherTimer而不是Timer了:DispatcherTimer与Dispatcher运行于同一个线程中——UI线程,而且具有相同的DispatcherPriority优先级。 所以,在WPF/Silverlight应用中,正确的做法如下所示:
1 2 3 4 |
DispatcherTimer timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromSeconds(10); //10秒 timer.Tick += new EventHandler(timer_Tick); timer.Start(); |
1 2 3 4 |
private void timer1_Tick(object sender, EventArgs e) { //(你的定时处理) } |
参考:http://www.roboby.com/the_different_bitween_timer_and_dispatchertimer_in_wpf.html
View Detailseclipse打开当前文件所在文件夹 Run-->External Tools-->External Tools Configurations… new 一个 program Name 里面填:打开当前目录 location 里面填:C:\WINDOWS\explorer.exe Arguments 里面填:${container_loc} 打开文件夹目录 from:http://blog.csdn.net/aerchi/article/details/7102496
View Details在学习Android开发的过程你,你往往会去借鉴别人的应用是怎么开发的,那些漂亮的动画和精致的布局可能会让你爱不释手,作为一个开发者,你可能会很想知道这些效果界面是怎么去实现的,这时,你便可以对改应用的APK进行反编译查看。下面是我参考了一些文章后简单的教程详解。 (注:反编译不是让各位开发者去对一个应用破解搞重装什么的,主要目的是为了促进开发者学习,借鉴好的代码,提升自我开发水平。) 测试环境: win 7 使用工具: CSDN上下载地址: apktool (资源文件获取) 下载 dex2jar(源码文件获取) 下载 jd-gui (源码查看) 下载 Android反编译整合工具包(最新) 下载 官方最新版本下载地址: apktool(google code) dex2jar(google code) jd-gui(google code)最新版请见官方 工具介绍: apktool 作用:资源文件获取,可以提取出图片文件和布局文件进行使用查看 dex2jar 作用:将apk反编译成java源码(classes.dex转化成jar文件) jd-gui 作用:查看APK中classes.dex转化成出的jar文件,即源码文件 反编译流程: 一、apk反编译得到程序的源代码、图片、XML配置、语言资源等文件 下载上述工具中的apktool,解压得到3个文件:aapt.exe,apktool.bat,apktool.jar ,将需要反编译的APK文件放到该目录下, 打开命令行界面(运行-CMD) ,定位到apktool文件夹,输入以下命令:apktool.bat d -f test.apk test (命令中test.apk指的是要反编译的APK文件全名,test为反编译后资源文件存放的目录名称,即为:apktool.bat d -f [apk文件 ] [输出文件夹]) 说明获取成功,之后发现在文件夹下多了个test文件,点击便可以查看该应用的所有资源文件了。 如果你想将反编译完的文件重新打包成apk,那你可以:输入apktool.bat b test(你编译出来文件夹)便可,效果如下: 之后在之前的test文件下便可以发现多了2个文件夹: build dist(里面存放着打包出来的APK文件) 二、Apk反编译得到Java源代码 下载上述工具中的dex2jar和jd-gui ,解压 将要反编译的APK后缀名改为.rar或则 .zip,并解压,得到其中的额classes.dex文件(它就是java文件编译再通过dx工具打包而成的),将获取到的classes.dex放到之前解压出来的工具dex2jar-0.0.9.15 文件夹内, 在命令行下定位到dex2jar.bat所在目录,输入dex2jar.bat classes.dex,效果如下: 在改目录下会生成一个classes_dex2jar.jar的文件,然后打开工具jd-gui文件夹里的jd-gui.exe,之后用该工具打开之前生成的classes_dex2jar.jar文件,便可以看到源码了,效果如下: 被混淆过的效果图(类文件名称以及里面的方法名称都会以a,b,c….之类的样式命名): 三、 […]
View Details