DataGridView二维表头实例
RowMergeView.cs文件内容:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Design;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;
/// <summary>
/// DataGridView行合并.请对属性MergeColumnNames 赋值既可
/// </summary>
public partial class RowMergeView : DataGridView
{
#region 构造函数
public RowMergeView()
{
InitializeComponent();
}
#endregion
#region 重写的事件
protected override void OnPaint(PaintEventArgs pe)
{
// TODO: 在此处添加自定义绘制代码
// 调用基类 OnPaint
base.OnPaint(pe);
}
protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
try
{
if (e.RowIndex > -1 && e.ColumnIndex > -1)
{
DrawCell(e);
}
else
{
//二维表头
if (e.RowIndex == -1)
{
if (SpanRows.ContainsKey(e.ColumnIndex)) //被合并的列
{
//画边框
Graphics g = e.Graphics;
e.Paint(e.CellBounds, DataGridViewPaintParts.Background | DataGridViewPaintParts.Border);
int left = e.CellBounds.Left, top = e.CellBounds.Top + 2,
right = e.CellBounds.Right, bottom = e.CellBounds.Bottom;
switch (SpanRows[e.ColumnIndex].Position)
{
case 1:
left += 2;
break;
case 2:
break;
case 3:
right -= 2;
break;
}
//画上半部分底色
g.FillRectangle(new SolidBrush(this._mergecolumnheaderbackcolor), left, top,
right - left, (bottom - top) / 2);
//画中线
g.DrawLine(new Pen(this.GridColor), left, (top + bottom) / 2,
right, (top + bottom) / 2);
//写小标题
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
g.DrawString(e.Value + "", e.CellStyle.Font, Brushes.Black,
new Rectangle(left, (top + bottom) / 2, right - left, (bottom - top) / 2), sf);
left = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Left, true).Left - 2;
if (left < 0) left = this.GetCellDisplayRectangle(-1, -1, true).Width;
right = this.GetColumnDisplayRectangle(SpanRows[e.ColumnIndex].Right, true).Right - 2;
if (right < 0) right = this.Width;
g.DrawString(SpanRows[e.ColumnIndex].Text, e.CellStyle.Font, Brushes.Black,
new Rectangle(left, top, right - left, (bottom - top) / 2), sf);
e.Handled = true;
}
}
}
base.OnCellPainting(e);
}
catch
{ }
}
protected override void OnCellClick(DataGridViewCellEventArgs e)
{
base.OnCellClick(e);
}
#endregion
#region 自定义方法
/// <summary>
/// 画单元格
/// </summary>
/// <param name="e"></param>
private void DrawCell(DataGridViewCellPaintingEventArgs e)
{
if (e.CellStyle.Alignment == DataGridViewContentAlignment.NotSet)
{
e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
}
Brush gridBrush = new SolidBrush(this.GridColor);
SolidBrush backBrush = new SolidBrush(e.CellStyle.BackColor);
SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor);
int cellwidth;
//上面相同的行数
int UpRows = 0;
//下面相同的行数
int DownRows = 0;
//总行数
int count = 0;
if (this.MergeColumnNames.Contains(this.Columns[e.ColumnIndex].Name) && e.RowIndex != -1)
{
cellwidth = e.CellBounds.Width;
Pen gridLinePen = new Pen(gridBrush);
string curValue = e.Value == null ? "" : e.Value.ToString().Trim();
string curSelected = this.CurrentRow.Cells[e.ColumnIndex].Value == null ? "" : this.CurrentRow.Cells[e.ColumnIndex].Value.ToString().Trim();
if (!string.IsNullOrEmpty(curValue))
{
#region 获取下面的行数
for (int i = e.RowIndex; i < this.Rows.Count; i++)
{
if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue))
{
//this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected;
DownRows++;
if (e.RowIndex != i)
{
cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width;
}
}
else
{
break;
}
}
#endregion
#region 获取上面的行数
for (int i = e.RowIndex; i >= 0; i--)
{
if (this.Rows[i].Cells[e.ColumnIndex].Value.ToString().Equals(curValue))
{
//this.Rows[i].Cells[e.ColumnIndex].Selected = this.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected;
UpRows++;
if (e.RowIndex != i)
{
cellwidth = cellwidth < this.Rows[i].Cells[e.ColumnIndex].Size.Width ? cellwidth : this.Rows[i].Cells[e.ColumnIndex].Size.Width;
}
}
else
{
break;
}
}
#endregion
count = DownRows + UpRows - 1;
if (count < 2)
{
return;
}
}
if (this.Rows[e.RowIndex].Selected)
{
backBrush.Color = e.CellStyle.SelectionBackColor;
fontBrush.Color = e.CellStyle.SelectionForeColor;
}
//以背景色填充
e.Graphics.FillRectangle(backBrush, e.CellBounds);
//画字符串
PaintingFont(e, cellwidth, UpRows, DownRows, count);
if (DownRows == 1)
{
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1);
count = 0;
}
// 画右边线
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top, e.CellBounds.Right - 1, e.CellBounds.Bottom);
e.Handled = true;
}
}
/// <summary>
/// 画字符串
/// </summary>
/// <param name="e"></param>
/// <param name="cellwidth"></param>
/// <param name="UpRows"></param>
/// <param name="DownRows"></param>
/// <param name="count"></param>
private void PaintingFont(System.Windows.Forms.DataGridViewCellPaintingEventArgs e, int cellwidth, int UpRows, int DownRows, int count)
{
SolidBrush fontBrush = new SolidBrush(e.CellStyle.ForeColor);
int fontheight = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Height;
int fontwidth = (int)e.Graphics.MeasureString(e.Value.ToString(), e.CellStyle.Font).Width;
int cellheight = e.CellBounds.Height;
if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomCenter)
{
e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y + cellheight * DownRows - fontheight);
}
else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomLeft)
{
e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y + cellheight * DownRows - fontheight);
}
else if (e.CellStyle.Alignment == DataGridViewContentAlignment.BottomRight)
{
e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y + cellheight * DownRows - fontheight);
}
else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleCenter)
{
e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
}
else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleLeft)
{
e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
}
else if (e.CellStyle.Alignment == DataGridViewContentAlignment.MiddleRight)
{
e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
}
else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopCenter)
{
e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1));
}
else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopLeft)
{
e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X, e.CellBounds.Y - cellheight * (UpRows - 1));
}
else if (e.CellStyle.Alignment == DataGridViewContentAlignment.TopRight)
{
e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + cellwidth - fontwidth, e.CellBounds.Y - cellheight * (UpRows - 1));
}
else
{
e.Graphics.DrawString((String)e.Value, e.CellStyle.Font, fontBrush, e.CellBounds.X + (cellwidth - fontwidth) / 2, e.CellBounds.Y - cellheight * (UpRows - 1) + (cellheight * count - fontheight) / 2);
}
}
#endregion
#region 属性
/// <summary>
/// 设置或获取合并列的集合
/// </summary>
[MergableProperty(false)]
[Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
[DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Visible)]
[Localizable(true)]
[Description("设置或获取合并列的集合"), Browsable(true), Category("单元格合并")]
public List<string> MergeColumnNames
{
get
{
return _mergecolumnname;
}
set
{
_mergecolumnname = value;
}
}
private List<string> _mergecolumnname = new List<string>();
#endregion
#region 二维表头
private struct SpanInfo //表头信息
{
public SpanInfo(string Text, int Position, int Left, int Right)
{
this.Text = Text;
this.Position = Position;
this.Left = Left;
this.Right = Right;
}
public string Text; //列主标题
public int Position; //位置,1:左,2中,3右
public int Left; //对应左行
public int Right; //对应右行
}
private Dictionary<int, SpanInfo> SpanRows = new Dictionary<int, SpanInfo>();//需要2维表头的列
/// <summary>
/// 合并列
/// </summary>
/// <param name="ColIndex">列的索引</param>
/// <param name="ColCount">需要合并的列数</param>
/// <param name="Text">合并列后的文本</param>
public void AddSpanHeader(int ColIndex, int ColCount, string Text)
{
if (ColCount < 2)
{
throw new Exception("行宽应大于等于2,合并1列无意义。");
}
//将这些列加入列表
int Right = ColIndex + ColCount - 1; //同一大标题下的最后一列的索引
SpanRows[ColIndex] = new SpanInfo(Text, 1, ColIndex, Right); //添加标题下的最左列
SpanRows[Right] = new SpanInfo(Text, 3, ColIndex, Right); //添加该标题下的最右列
for (int i = ColIndex + 1; i < Right; i++) //中间的列
{
SpanRows[i] = new SpanInfo(Text, 2, ColIndex, Right);
}
}
/// <summary>
/// 清除合并的列
/// </summary>
public void ClearSpanInfo()
{
SpanRows.Clear();
//ReDrawHead();
}
private void DataGridViewEx_Scroll(object sender, ScrollEventArgs e)
{
if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)// && e.Type == ScrollEventType.EndScroll)
{
timer1.Enabled = false; timer1.Enabled = true;
}
}
//刷新显示表头
public void ReDrawHead()
{
foreach (int si in SpanRows.Keys)
{
this.Invalidate(this.GetCellDisplayRectangle(si, -1, true));
}
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
ReDrawHead();
}
/// <summary>
/// 二维表头的背景颜色
/// </summary>
[Description("二维表头的背景颜色"), Browsable(true), Category("二维表头")]
public Color MergeColumnHeaderBackColor
{
get { return this._mergecolumnheaderbackcolor; }
set { this._mergecolumnheaderbackcolor = value; }
}
private Color _mergecolumnheaderbackcolor = System.Drawing.SystemColors.Control;
#endregion
}
使用时调用:
rowMergeView1.AddSpanHeader(7, 4, "表头标题")
7为开始列,4为所跨列数。
分享按钮
淘宝客网站备案通过,推荐一个免费的空间给大家。
等了快2个月了,前几天才收到备案退回的邮件。
问了下代备案的服务商,说是少了一个文件。
怎么能这样子,不过好在服务商马上补发了文件过去,备案就下来了。
http://www.fasttao.net就是我淘宝客的网站了,用的是店盟淘宝客程序,感觉还是有些问题,现在备案下来也没太多时间去弄,先放着。
朋友们可以进去看下。呵呵
接下来给朋友们推荐的一款空间是德国的com.nu空间,还赠送Mysql空间都足够了。而且有中文,这点确实不错。
想尝试做网站的可以先用用。就是有一点,访问起来有点慢,而且有广告(可以破解去掉)。
另转载破解广告方法:
第一种:
在页面</body>前加上<noscript> ,在</html>后面也加上<noscript> ,现在结构就变成了:
<noscript>
</body>
</html>
<noscript>
如果安装的是WordPress,则可以采用上述方法对主题模版下的footer.php和管理界面的admin-footer.php进行修改。但是最好还是把footer.php、admin-footer.php的属性改为只读(444),以防反弹!
第二种:
去广告的代码比较简单 只要在尾部加入下列代码即可:
* <div id=”noAds” >
<script language=”javascript” type=”text/javascript”>document.getElementById(“noAds”).style.display=”none”;</script>
记住,<div>不要加后面的</div>括号,只要一半就OK了!
耒阳,秋风…继续奋斗
秋风,凉意来袭。吹走的不是夏日炎炎而是一腔的创业激情。继续累积创业经验。
分享按钮管理经验
森林之王狮子聘请豹子帮他管理10只狼。
在上岗的第一天,狮子就给了豹子一大块肉并让他分给狼。
豹子把肉平均分成了11份,自己拿一份,其他都分给了狼群。大家都相安无事。
在上岗的第二天,狮子又给了豹子一大块肉并让他分给狼,但是很明显肉比昨天的少了。
豹子照旧把肉平均分成11份,自己拿一份,其他都分给了狼群。狼群开始有意见:豹子不用做事情还跟我们吃一样多,这样太不公平了。狼的不满情绪愈演愈烈。
在上岗的第三天,狮子又给了豹子一块肉并让他分给狼,这次肉的分量却只够填饱2只动物的肚子。
豹子照旧把肉平均分成11份,自己拿一份,其他都分给了狼群。狼群看到肉的分量。纷纷向豹子发难。最终在狼群团结一致的情况下。豹子不得不把自己的肉交出来。
第4天,豹子直接向狮子提出辞职。他说10只狼他无法管理。并且向狮子说明了他管理的方式。这个时候狮子又拿出了一块肉,分量和第一天的一样。
狮子把肉分成了11份,并且大小不均,自己拿了一块最大的。其他的抛向狼群。这个时候狼群都在为拿到最大的那块肉战斗。并没有狼提出意见。
豹子很佩服,问狮子这叫什么方法,狮子说“有木有听过人类的绩效工资”
而后狮子又拿出一块和第2天分量一样的肉,分成了10份,同样是大小不均,自己拿了最大的一块。同样狼还是为了自己的那一份食物战斗。最后一条弱小的狼没有分的食物。
豹子很佩服,问狮子这叫什么方法。狮子说“有木有听过末位淘汰法则”
最后狮子又拿出了一块肉,分量和第三天的一样。狮子把肉份成了2份。自己拿一块。其他抛向狼群。最后狼群中最强壮的狼打败了其他所有狼并且吃掉那块肉。
豹子很佩服,问狮子这叫什么方法。狮子说“有木有听过竞争上岗”
分享按钮
辞职,解脱还是失业,打工还是创业。
终于在杂七杂八的工作中解脱出来了。辞职前同事们都叫我先去看下别处的情况,当放2个月长假。但是我实在是忍受不了在这公司工作了。心一横,就是想走。
今天正好辞职一个礼拜。看了下别处的工作,总的来说比之前好了。但是需要跟女朋友2地相隔了。这滋味不怎么好受,年初把女朋友从中山叫过来,说好老老实实做完一年。哪里想实在是超出我的想象了。其实女朋友也没怪我。只是自己心里过意不去。还有就是又需要搬家了。
不搬不知道,一搬才知道4个多月我们买了这么多东西了。整整4趟才完全转移,其中还有一张电视桌送给公司煮饭阿姨了。
搬完东西,整理下心情。正好家里有个朋友酒店开张,回去取下经。看看有没有希望彻底甩掉打工的生活。
未完待续……
分享按钮地磅程序实例片段[源代码]
最后加的读取ini配置文件功能:
—————————————————————
[DllImport("kernel32.dll")] private static extern long WritePrivateProfileString(string section, string key, string val, string filePath); [DllImport("kernel32.dll")] private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath); public static string inifilepath = Application.StartupPath.ToString() + @"\config.ini";//配置文件名称和存放地址 public static string server = IniReadValue("settings", "databasepath", inifilepath);//数据库连接字符串 public static int iPort = int.Parse(IniReadValue("settings", "Port", inifilepath));//COM口号 public static int iRate = int.Parse(IniReadValue("settings", "Rate", inifilepath));//波特率 public static byte bSize = byte.Parse(IniReadValue("settings", "Size", inifilepath));//数据大小 public static byte bParity = byte.Parse(IniReadValue("settings", "Parity", inifilepath));//奇偶校验 public static byte bStopBits = byte.Parse(IniReadValue("settings", "StopBits", inifilepath));//停止位 public static string BackUpPath = IniReadValue("settings", "backupPath", inifilepath);//数据清理备份存放路径 public static string DATAPATH = IniReadValue("settings", "DATAPath", inifilepath);//数据存放路径 public static void IniWriteValue(string Section, string Key, string Value, string filepath)//对ini文件进行写操作的函数 { WritePrivateProfileString(Section, Key, Value, filepath); } public static string IniReadValue(string Section, string Key, string filepath)//对ini文件进行读操作的函数 { StringBuilder temp = new StringBuilder(255); int i = GetPrivateProfileString(Section, Key, "", temp, 255, filepath); return temp.ToString(); } public int isbl; public int iTimeout = 1000; public string rstr="0";//最后一次正确读数 public mycom mycom1 = new mycom(); public byte[] recb; public byte[] recb1; |
—————————————————————
使用时钟控件检测地磅重量变化
—————————————————————
private void timer1_Tick(object sender, EventArgs e) { textBox12.Text = "";//textBox12用来显示地磅重量 recb = null; //存放通过COM口接收的字符串 mycom1.Close(); //关闭COM连接实例 mycom1.Open(); //打开COM连接实例 recb = mycom1.Read(9);//通过COM口接收的字符串,保存9位 try { rstr = Convert.ToString(Convert.ToInt32(aConvert(aToInt(recb)))); textBox12.Text = rstr;//把正确输出的重量保存,(在实际使用过程中会出现乱码) } catch { textBox12.Text = rstr;//出现异常情况(出现乱码)的时候,显示最后一次正确的重量! } } |
—————————————————————
把COM口接收的数据连接成数字
aToInt方法
public string aToInt(byte[] reb) { string temp = ""; for (int i = 1; i <= 8; i++) { temp += Convert.ToString((char)reb[i]); } return temp; } |
—————————————————————
把连接好的数字重新排序
aConvert方法
public string aConvert(string rtemp) { string atemp = ""; int len = rtemp.Length; for (int i = 1; i <= len; i++) { atemp += rtemp.Substring(len - i, 1); } return atemp; } |
—————————————————————
就这些代码加上一个COMM.Dll接口和kernel32.dll实现 上海耀华xk3190-d2 地磅仪表与计算机的通讯。
分享按钮【转载】C#调用dll时的类型转换总结
| C++(Win 32) | C# |
| char** | 作为输入参数转为char[],通过Encoding类对这个string[]进行编码后得到的一个char[] |
| 作为输出参数转为byte[],通过Encoding类对这个byte[]进行解码,得到字符串 | |
| C++ Dll接口:
void CplusplusToCsharp(in char** AgentID, out char** AgentIP); C#中的声明: [DllImport("Example.dll")] public static extern void CplusplusToCsharp(char[] AgentID, byte[] AgentIP); C#中的调用: Encoding encode = Encoding.Default; byte[] tAgentID; byte[] tAgentIP; string[] AgentIP; tAgentID = new byte[100]; tAgentIP = new byte[100]; CplusplusToCsharp(encode.GetChars(tAgentID), tAgentIP); AgentIP[i] = encode.GetString(tAgentIP,i*Length,Length); |
|
| Handle | IntPtr |
| Hwnd | IntPtr |
| int* | ref int |
| int& | ref int |
| void* | IntPtr |
| unsigned char* | ref byte |
| BOOL | bool |
| DWORD | int 或 uint(int 更常用一些) |
| 枚举类型 | Win32:
BOOL MessageBeep(UINT uType // 声音类型); 其中的声音类型为枚举类型中的某一值。 C#: 用户需要自己定义一个枚举类型: public enum BeepType { SimpleBeep = -1, IconAsterisk = 0×00000040, IconExclamation = 0×00000030, IconHand = 0×00000010, IconQuestion = 0×00000020, Ok = 0×00000000, } C#中导入该函数: [DllImport("user32.dll")] public static extern bool MessageBeep(BeepType beepType); C#中调用该函数: MessageBeep(BeepType.IconQuestion); |
| 结构类型 | Win32:
使用结构指针作为参数的函数: BOOL GetSystemPowerStatus( LPSYSTEM_POWER_STATUS lpSystemPowerStatus ); Win32中该结构体的定义: typedef struct _SYSTEM_POWER_STATUS { BYTE ACLineStatus; BYTE BatteryFlag; BYTE BatteryLifePercent; BYTE Reserved1; DWORD BatteryLifeTime; DWORD BatteryFullLifeTime; } SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS; C#: 用户自定义相应的结构体: struct SystemPowerStatus { byte ACLineStatus; byte batteryFlag; byte batteryLifePercent; byte reserved1; int batteryLifeTime; int batteryFullLifeTime; } C#中导入该函数: [DllImport("kernel32.dll")] public static extern bool GetSystemPowerStatus( ref SystemPowerStatus systemPowerStatus); C#中调用该函数: SystemPowerStatus sps; ….sps初始化赋值…… GetSystemPowerStatus(ref sps); |
| 字符串 | 对于字符串的处理分为以下几种情况:
1、 字符串常量指针的处理(LPCTSTR),也适应于字符串常量的处理,.net中的string类型是不可变的类型。 2、 字符串缓冲区的处理(char*),即对于变长字符串的处理,.net中StringBuilder可用作缓冲区 Win32: BOOL GetFile(LPCTSTR lpRootPathName); C#: 函数声明: [DllImport("kernel32.dll", CharSet = CharSet.Auto)] static extern bool GetFile ( [MarshalAs(UnmanagedType.LPTStr)] string rootPathName); 函数调用: string pathname; GetFile(pathname); 备注: DllImport中的CharSet是为了说明自动地调用该函数相关的Ansi版本或者Unicode版本
变长字符串处理: C#: 函数声明: [DllImport("kernel32.dll", CharSet = CharSet.Auto)] public static extern int GetShortPathName( [MarshalAs(UnmanagedType.LPTStr)] string path, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder shortPath, int shortPathLength); 函数调用: StringBuilder shortPath = new StringBuilder(80); int result = GetShortPathName( @”d:\test.jpg”, shortPath, shortPath.Capacity); string s = shortPath.ToString(); |
| struct | 具有内嵌字符数组的结构:
Win32: typedef struct _TIME_ZONE_INFORMATION { LONG Bias; WCHAR StandardName[ 32 ]; SYSTEMTIME StandardDate; LONG StandardBias; WCHAR DaylightName[ 32 ]; SYSTEMTIME DaylightDate; LONG DaylightBias; } TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION; C#: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] struct TimeZoneInformation { public int bias; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string standardName; SystemTime standardDate; public int standardBias; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string daylightName; SystemTime daylightDate; public int daylightBias; } |
| 具有回调的函数 | Win32:
BOOL EnumDesktops( HWINSTA hwinsta, // 窗口实例的句柄 DESKTOPENUMPROC lpEnumFunc, // 回调函数 LPARAM lParam // 用于回调函数的值 ); 回调函数DESKTOPENUMPROC的声明: BOOL CALLBACK EnumDesktopProc( LPTSTR lpszDesktop, // 桌面名称 LPARAM lParam // 用户定义的值 ); C#: 将回调函数的声明转化为委托: delegate bool EnumDesktopProc( [MarshalAs(UnmanagedType.LPTStr)] string desktopName, int lParam); 该函数在C#中的声明: [DllImport("user32.dll", CharSet = CharSet.Auto)] |
该表对C#中调用win32函数,以及c++编写的dll时参数及返回值的转换做了一个小的总结,如果想进一步了解这方面内容的话,可以参照msdn中“互操作封送处理”一节。
转载于:http://blog.csdn.net/xiaochongchong1248/archive/2010/01/13/5181345.aspx
分享按钮电话语音查询系统开发
很久之前就说要做一个语音查询系统,无奈客户那边一直没有确认我们的报价.
现在终于确认下来了,也可以开始研究了.
网上找了些资料
客户要求主要是:用户自己打电话查询水费.
客户来电查询
技术要点
其他相关函数介绍请参见实例“语音卡电话呼叫系统”,本实例主要介绍GetCallerIDStr函数,该函数用于获取主叫号码。语法如下:
[DllImport("Tc08a32.dll", CharSet = CharSet.Auto)]
public static extern short GetCallerIDStr(short wChnlNo, byte[] IDStr);
参数说明如下。
l wChnlNo:标识通道号。
l IDStr:用于接收读取的号码。
l 返回值:为0,表示未收到任何信息;为1,表示正在接收头信息;为2表示正在接收ID号码;为3表示接收完毕,校验正确;为4表示接收完毕,校验错误。
在调用GetCallerIDStr函数时,只有返回值为3或4才表示已经正确接收了主机号码。
实现过程
(1)新建一个项目,命名为Ex13_12,默认窗体为Form1。
(2)在Form1窗体中,主要添加一个DataGridView控件,显示语音卡各通道和通道状态,并在来电时显示来电号码;添加一个Timer控件用于时刻检测来电信息;添加其他控件及用途如图13.13所示。
(3)主要程序代码。
private void timer1_Tick(object sender, EventArgs e)
{
byte[] ss = new byte[100];
for (short i = 0; i < 8; i++)
{
DJ160API.StartSigCheck(i);
if(open_close==false)
DJ160API.ResetCallerIDBuffer(i);
if (DJ160API.RingDetect(i))
{
open_close = true;
//获取来电号码
result = DJ160API.GetCallerIDStr(i, ss);
if (result == 3 || result == 4)
{
string str = Encoding.UTF8.GetString(ss);
txtTel.Text = str;
txtTel.Text = txtTel.Text.Substring(txtTel.Text.Length - 8, 8);
dataGridView1[2, i].Value = txtTel.Text;
//查询客户资料
this.getMessage(txtTel.Text);
}
}
}
}
private void getMessage(string str)
{
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + "db_csell.mdb" + ";Persist Security Info=False");
OleDbDataAdapter dap = new OleDbDataAdapter("SELECT * FROM 个人名录表 WHERE 电话='" + str + "'", con);
DataSet ds = new DataSet();
dap.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
txtName.Text = ds.Tables[0].Rows[0]["姓名"].ToString();
txtDuty.Text = ds.Tables[0].Rows[0]["职务"].ToString();
txtAddress.Text = ds.Tables[0].Rows[0]["地址"].ToString();
txtMobile.Text = ds.Tables[0].Rows[0]["手机"].ToString();
txtCompany.Text = ds.Tables[0].Rows[0]["公司名称"].ToString();
txtPostId.Text = ds.Tables[0].Rows[0]["邮编"].ToString();
}
else
{
labStatus.Text = “非本单位会员客户。。。。”;
}
}
希望有用!
本文代码转载于:http://blog.csdn.net/long102/archive/2007/10/31/1859287.aspx
wordpress Tag中文找不到页面
因为要升级wordpress3.1.1,昨天晚上备份了下数据库,就匆匆的自动升级了.
现在想想觉的有点冲动.要不然想恢复都没办法了.
还好有惊无险,除了网站管理那个模块恢复到从前以外其他都正常.
下午闲着无事到Google看下网站收录情况,针对及个热门的关键字搜索了以下.排名还不错,呵呵!
可是一点进去就转到404页面了.第一反应是不是升级了3.1.1导致的.
因为没升级之前都正常,我有实验过.在Google浏览器正常显示中文都没问题,IE下面转成乱码但是也能访问.
立马BAIDU一下,已经有很多这样的提问了和分享了.随便找了一个
CtuSky:http://www.ctusky.com/archives/chinese-tags-solution-wordpress-error.html
提供了两种解决方法.
一种Win主机(而且必须是使用IIS服务):
1.打开wp-includes/classes.php文件
因为升级到3.1.1之后可能跟之前的版本有点区别,在wp-includes目录下面没有classes.php文件了,而是改成classes-wp.php了.
打开classes-wp.php找到这段代码
if ( isset($_SERVER['PATH_INFO']) ) $pathinfo = $_SERVER['PATH_INFO']; else $pathinfo = ''; $pathinfo_array = explode('?', $pathinfo); $pathinfo = str_replace("%", "%25", $pathinfo_array[0]); $req_uri = $_SERVER['REQUEST_URI']; |
修改成:
if ( isset($_SERVER['PATH_INFO']) )
$pathinfo = mb_convert_encoding($_SERVER['PATH_INFO'], "UTF-8", "GBK");
else
$pathinfo = '';
$pathinfo_array = explode('?', $pathinfo);
$pathinfo = str_replace("%", "%25", $pathinfo_array[0]);
$req_uri = mb_convert_encoding($_SERVER['REQUEST_URI'], "UTF-8", "GBK");
测试已经OK!
但是很纳闷为什么之前我都没修改过文件显示标签页面也没有问题.
一种Linux主机:
修改wp-includes/rewrite.php(3.1.1版中这个文件没有变)
这是网上最常见的方法,原理是,让WordPress在对其他内容使用Permalink的时候,对tag不使用,而使用链接2的QueryString模式发送中文编码:
function get_tag_permastruct() {
if (isset($this->tag_structure)) {
return $this->tag_structure;
}
if (empty($this->permalink_structure)) { //-----this line need change------
$this->tag_structure = '';
return false;
}
把第5行改为
if (!empty($this->permalink_structure)) {
局限:没有起到Permalink的“漂亮”作用,如果不能自己修改WP的文件就没办法了。
三、修改tag base
原理同上,只要让WordPress在打开了Permalink功能后继续对tag不理不问就行了。那么,欺骗WordPress,让它用链接2的格式来显示Permalink,可行么?可行,因为WordPress可以自定义Permalink的形式:
在WordPress的 Settings – Permalinks – Tag base 中填上
/?tag=
注意””不能少,引用原文中的写法不对。另外要注意每次输入””,WP都会再次转义为”\”,所以每次点提交都会把””翻一倍,点两次就是”\\”,所以不要多点,一次就对了。
这个方法的结果是使得链接变成这个样子
www.example.com/?tag=/中文/
多出来的斜杠对于服务器丝毫没有影响,还是被视为QueryString,效果同上。
局限是链接变得更加不好看了,更为致命的是插件生成的Sitemap中,tag链接会变成错误的形式,如果你很在乎Sitemap,请不要使用这个方法,除非你真的无法修改自己的rewrite.php文件。
但是当你使用WP-SuperCache或者类似的缓存插件时,它会加入自己的rewrite规则,所有请求先由自己判断,不在缓存中或者不符合缓存规则才交由WordPress处理。但问题在于,它不支持中文URL的解析,哪怕是QueryString也不行。于是我们必须绕过它。
这是WP-SuperCache在.htaccess文件里所添加的rewrite规则
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{QUERY_STRING} !.*s=.*
RewriteCond %{QUERY_STRING} !.*p=.*
RewriteCond %{QUERY_STRING} !.*attachment_id=.*
RewriteCond %{QUERY_STRING} !.*wp-subscription-manager=.*
RewriteCond %{HTTP_COOKIE} !^.*(comment_author_|wordpress|wp-postpass_).*$
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz -f
RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz [L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{QUERY_STRING} !.*s=.*
RewriteCond %{QUERY_STRING} !.*p=.*
RewriteCond %{QUERY_STRING} !.*wp-subscription-manager=.*
RewriteCond %{QUERY_STRING} !.*attachment_id=.*
RewriteCond %{HTTP_COOKIE} !^.*(comment_author_|wordpress|wp-postpass_).*$
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html -f
RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html [L]
我们要做的就是不让它去判断中文tag链接,在两个 RewriteCond %{REQUEST_METHOD} !=POST 后面分别加入这样一句:
RewriteCond %{QUERY_STRING} !.*tag=.*
含义是如果QueryString中含有tag字样,请不要解析(交给下一条规则,一般来说就是WordPress的index.php了)。
结论:
Windows+IIS主机下,通过方案一可以完美解决中文tag问题
Linux+Apache主机下,不能使用中文Permalink,除非修改Apache,否则只有用方案二和方案三绕行。
方案二是较为推荐的方法,但是搭配WP-SuperCache使用的时候,需要自己在.htaccess文件中加入一条不处理tag链接的规则。
最后面2个方案没有测试过,如果你的是Linux你可以尝试一下.
分享按钮
早间主播

下在几天了才翻出来看,没想到这么给力.
看的我2次感动落泪……呵呵!
片尾曲不错,听听看!
http://www.yinyuetai.com/video/swf/131380/3/a.swf
分享按钮
