当前位置:编程文档 >> C# >> Visual Studio 2003插件编写简单介绍(三)
首页

Visual Studio 2003插件编写简单介绍(三)

所属类别:C#
推荐指数:★★☆
文档人气:2
本周人气:1
发布日期:2008-8-2
Resource排序器主要是将Resource.h里面的ID进行排序。只是需要注意的是该文件中有几个宏定义:APS_NEXT_RESOURCE_VALUE, APS_NEXT_COMMAND_VALUE,_APS_NEXT_CONTROL_VALUE, _APS_NEXT_SYMED_VALUE。因为每在rc文件里面添加一个资源(对话框),都会在resource.h里面自动生成一个ID值,但它怎么知道应该生成的值是多少呢?就是去读这几个宏定义的。然后每次在resource.h里面生成一个ID后,相对应的宏的值就会+1。具体每个宏是什么意思可以参考MSDN文章:Using Multiple Resource Files and Header Files with Visual C++。

为了使用的方便,首先用一个Define类f这些宏定义和换行符等东西

view plaincopy to clipboardprint?
public class Define

{

public const string _APS_NEXT_RESOURCE_VALUE_STR = "_APS_NEXT_RESOURCE_VALUE";

public const string _APS_NEXT_COMMAND_VALUE_STR = "_APS_NEXT_COMMAND_VALUE";

public const string _APS_NEXT_CONTROL_VALUE_STR = "_APS_NEXT_CONTROL_VALUE";

public const string _APS_NEXT_SYMED_VALUE_STR = "_APS_NEXT_SYMED_VALUE";



// _APS_NEXT_RESOURCE_VALUE的范围

public const long _APS_NEXT_RESOURCE_VALUE_BEGIN = 1;

public const long _APS_NEXT_RESOURCE_VALUE_END = 0x6FFF;



// _APS_NEXT_COMMAND_VALUE的范围

public const long _APS_NEXT_COMMAND_VALUE_BEGIN = 0x8000;

public const long _APS_NEXT_COMMAND_VALUE_END = 0xDFFF;



// _APS_NEXT_CONTROL_VALUE的范围

public const long _APS_NEXT_CONTROL_VALUE_BEGIN = 8;

public const long _APS_NEXT_CONTROL_VALUE_END = 0xDFFF;



// 几个换行符

public const string CLRF = "\r\n";

public const string CL = "\r";

public const string RF = "\n";



public const string RESOURCE_NAME = "resource.h";

}

public class Define

{

public const string _APS_NEXT_RESOURCE_VALUE_STR = "_APS_NEXT_RESOURCE_VALUE";

public const string _APS_NEXT_COMMAND_VALUE_STR = "_APS_NEXT_COMMAND_VALUE";

public const string _APS_NEXT_CONTROL_VALUE_STR = "_APS_NEXT_CONTROL_VALUE";

public const string _APS_NEXT_SYMED_VALUE_STR = "_APS_NEXT_SYMED_VALUE";



// _APS_NEXT_RESOURCE_VALUE的范围

public const long _APS_NEXT_RESOURCE_VALUE_BEGIN = 1;

public const long _APS_NEXT_RESOURCE_VALUE_END = 0x6FFF;



// _APS_NEXT_COMMAND_VALUE的范围

public const long _APS_NEXT_COMMAND_VALUE_BEGIN = 0x8000;

public const long _APS_NEXT_COMMAND_VALUE_END = 0xDFFF;



// _APS_NEXT_CONTROL_VALUE的范围

public const long _APS_NEXT_CONTROL_VALUE_BEGIN = 8;

public const long _APS_NEXT_CONTROL_VALUE_END = 0xDFFF;



// 几个换行符

public const string CLRF = "\r\n";

public const string CL = "\r";

public const string RF = "\n";



public const string RESOURCE_NAME = "resource.h";

}最后就是的ResoureParse类了,需要处理注意的有下面几个地方: 1.不同的资源类型是有区间范围的,例如Dialog, Menu和IDD_开头的普通控件就在不同的区间。因此 ID递增的时候必须在各自的区间内(就是上面所说的宏,换句话说上面的宏就应该是该区间的最大值 再加一)。 2.Int.Parse函数是不支持"0x"开头的16进制数字,因此要去掉0x前缀进行处理。

view plaincopy to clipboardprint?
using System;

using System.Text;

using System.IO;



namespace Commands.FileParser

{

/// <summary>

/// ResourceParser 的摘要说明。

/// </summary>

public class ResourceParser: IParser

{

private long m_counter = 0;

private long m_last = 1;

private long m_APS_NEXT_RESOURCE_VALUE = 0;

private long m_APS_NEXT_COMMAND_VALUE = 0;

private long m_APS_NEXT_CONTROL_VALUE = 0;

//private long m_APS_NEXT_SYMED_VALUE = 0;

public ResourceParser()

{



}



// 函数名: ParseLine

// 参数: line 被解析的字符串

// 描述: 解析传入的一行字符串,并调整资源ID的值

void ParseLine(ref string line)

{

// 首先找到#define 字段

int pos = line.IndexOf("#define");

if (pos == -1)

{

return;

}



// 再找到最后一个空格

pos = line.LastIndexOf(' ');

if (pos == -1)

{

return;

}



// 如果是_APS_NEXT开头的几个宏要进行格外处理

if (!ParseAPS_NEXTLine(ref line))

{

// 将最后一个ID逐行加1再替换

string oldNumber = line.Substring(pos + 1);

string newNumber = GetLineIndex(NumberToInt(oldNumber)).ToString();

line = line.Replace(oldNumber, newNumber);

}

}



// 函数名: ParseNumber

// 参数: oldNumber 需要转换的字符串

// 描述: 字符串转换成整形,并一并处理16进制的情况

private int NumberToInt( string oldNumber )

{

int HexPos = oldNumber.IndexOf("0x");



int Value = 0;

//不是以Hex开头的字符串

if (HexPos == -1)

{

Value = int.Parse(oldNumber);

}

else

{

string HexNumber = oldNumber.Remove(HexPos, 2);

Value = Int32.Parse(HexNumber, System.Globalization.NumberStyles.AllowHexSpecifier);

}

return Value;

}



// 函数名: IsAPSLine

// 参数: line 被解析的字符串

// 描述: 解析传入的一行字符串,并调整资源ID的值

bool ParseAPS_NEXTLine(ref string line)

{

int pos = line.LastIndexOf(' ');



bool found = true;



string oldNumber = line.Substring(pos);

if (line.IndexOf(Define._APS_NEXT_RESOURCE_VALUE_STR) != -1)

{

line = line.Replace(oldNumber, m_APS_NEXT_RESOURCE_VALUE.ToString());

}

else if (line.IndexOf(Define._APS_NEXT_CONTROL_VALUE_STR) != -1)

{

line = line.Replace(oldNumber, m_APS_NEXT_CONTROL_VALUE.ToString());

}

else if (line.IndexOf(Define._APS_NEXT_COMMAND_VALUE_STR) != -1)

{

line = line.Replace(oldNumber, m_APS_NEXT_CONTROL_VALUE.ToString());

}

else if (line.IndexOf(Define._APS_NEXT_SYMED_VALUE_STR) != -1)

{

// Do nothing

}

else

{

found = false;

}



return found;

}



// 函数名: GetRange

// 参数: number

// 描述: 获得该数字所属的区间

// < 100, 返回100

// 100 <= && < 1000, 返回1000

// >= 1000 && <10000, 返回10000

// >10000, 直接返回10000

long GetRange(long number)

{

long range = 1;



if (number < 100)

{

range = 1;

}

else if (number >= 100 && number < 1000)

{

range = 100;

}

else if (number >= 1000 && number < 10000)

{

range = 1000;

}

else if (number >= 10000 && number < Define._APS_NEXT_COMMAND_VALUE_BEGIN)

{

range = 10000;

}

else

{

range = number;

}



return range;

}



// 函数名: GetLineIndex

// 参数: void

// 描述: 每有一个新的#define ID xxx,数字就加1

long GetLineIndex(long number)

{

// 记录上一次的range



long range = GetRange(number);

if (m_last != range)

{

m_counter = 0;

m_last = range;

}



m_counter++;



long result = m_counter + range;

if (result < 1000)

{

m_APS_NEXT_RESOURCE_VALUE = result + 1;

}

else if (result >= 1000 && result < Define._APS_NEXT_COMMAND_VALUE_BEGIN)

{

m_APS_NEXT_CONTROL_VALUE = result + 1;

}

else if (result >= Define._APS_NEXT_COMMAND_VALUE_BEGIN)

{

m_APS_NEXT_COMMAND_VALUE = result + 1;

}



return result;

}



#region IParser 成员





public int Parse(string fileName)

{

string line;

StringBuilder sb = new StringBuilder();

using (System.IO.StreamReader reader = new System.IO.StreamReader(fileName))

{

while((line = reader.ReadLine()) != null)

{

ParseLine(ref line);

sb.Append(line);

sb.Append(Define.CLRF);

}

sb.Append(Define.RF);

reader.Close();

}





File.SetAttributes(fileName,FileAttributes.Normal);



// TODO: 添加 ResourceParser.Parse 实现

using (StreamWriter outWriter = new StreamWriter(fileName))

{

outWriter.Write(sb.ToString());

}

return 0;

}



/// <summary>

/// 应用程序的主入口点。

/// </summary>

[STAThread]

static void Main(string[] args)

{

//

// TODO: 在此处添加代码以启动应用程序

//

ResourceParser parser = new ResourceParser();

parser.Parse("resource.h");

}



#endregion

}

}

using System;

using System.Text;

using System.IO;



namespace Commands.FileParser

{

/// <summary>

/// ResourceParser 的摘要说明。

/// </summary>

public class ResourceParser: IParser

{

private long m_counter = 0;

private long m_last = 1;

private long m_APS_NEXT_RESOURCE_VALUE = 0;

private long m_APS_NEXT_COMMAND_VALUE = 0;

private long m_APS_NEXT_CONTROL_VALUE = 0;

//private long m_APS_NEXT_SYMED_VALUE = 0;

public ResourceParser()

{



}



// 函数名: ParseLine

// 参数: line 被解析的字符串

// 描述: 解析传入的一行字符串,并调整资源ID的值

void ParseLine(ref string line)

{

// 首先找到#define 字段

int pos = line.IndexOf("#define");

if (pos == -1)

{

return;

}



// 再找到最后一个空格

pos = line.LastIndexOf(' ');

if (pos == -1)

{

return;

}



// 如果是_APS_NEXT开头的几个宏要进行格外处理

if (!ParseAPS_NEXTLine(ref line))

{

// 将最后一个ID逐行加1再替换

string oldNumber = line.Substring(pos + 1);

string newNumber = GetLineIndex(NumberToInt(oldNumber)).ToString();

line = line.Replace(oldNumber, newNumber);

}

}



// 函数名: ParseNumber

// 参数: oldNumber 需要转换的字符串

// 描述: 字符串转换成整形,并一并处理16进制的情况

private int NumberToInt( string oldNumber )

{

int HexPos = oldNumber.IndexOf("0x");



int Value = 0;

//不是以Hex开头的字符串

if (HexPos == -1)

{

Value = int.Parse(oldNumber);

}

else

{

string HexNumber = oldNumber.Remove(HexPos, 2);

Value = Int32.Parse(HexNumber, System.Globalization.NumberStyles.AllowHexSpecifier);

}

return Value;

}



// 函数名: IsAPSLine

// 参数: line 被解析的字符串

// 描述: 解析传入的一行字符串,并调整资源ID的值

bool ParseAPS_NEXTLine(ref string line)

{

int pos = line.LastIndexOf(' ');



bool found = true;



string oldNumber = line.Substring(pos);

if (line.IndexOf(Define._APS_NEXT_RESOURCE_VALUE_STR) != -1)

{

line = line.Replace(oldNumber, m_APS_NEXT_RESOURCE_VALUE.ToString());

}

else if (line.IndexOf(Define._APS_NEXT_CONTROL_VALUE_STR) != -1)

{

line = line.Replace(oldNumber, m_APS_NEXT_CONTROL_VALUE.ToString());

}

else if (line.IndexOf(Define._APS_NEXT_COMMAND_VALUE_STR) != -1)

{

line = line.Replace(oldNumber, m_APS_NEXT_CONTROL_VALUE.ToString());

}

else if (line.IndexOf(Define._APS_NEXT_SYMED_VALUE_STR) != -1)

{

// Do nothing

}

else

{

found = false;

}



return found;

}



// 函数名: GetRange

// 参数: number

// 描述: 获得该数字所属的区间

// < 100, 返回100

// 100 <= && < 1000, 返回1000

// >= 1000 && <10000, 返回10000

// >10000, 直接返回10000

long GetRange(long number)

{

long range = 1;



if (number < 100)

{

range = 1;

}

else if (number >= 100 && number < 1000)

{

range = 100;

}

else if (number >= 1000 && number < 10000)

{

range = 1000;

}

else if (number >= 10000 && number < Define._APS_NEXT_COMMAND_VALUE_BEGIN)

{

range = 10000;

}

else

{

range = number;

}



return range;

}



// 函数名: GetLineIndex

// 参数: void

// 描述: 每有一个新的#define ID xxx,数字就加1

long GetLineIndex(long number)

{

// 记录上一次的range



long range = GetRange(number);

if (m_last != range)

{

m_counter = 0;

m_last = range;

}



m_counter++;



long result = m_counter + range;

if (result < 1000)

{

m_APS_NEXT_RESOURCE_VALUE = result + 1;

}

else if (result >= 1000 && result < Define._APS_NEXT_COMMAND_VALUE_BEGIN)

{

m_APS_NEXT_CONTROL_VALUE = result + 1;

}

else if (result >= Define._APS_NEXT_COMMAND_VALUE_BEGIN)

{

m_APS_NEXT_COMMAND_VALUE = result + 1;

}



return result;

}



#region IParser 成员





public int Parse(string fileName)

{

string line;

StringBuilder sb = new StringBuilder();

using (System.IO.StreamReader reader = new System.IO.StreamReader(fileName))

{

while((line = reader.ReadLine()) != null)

{

ParseLine(ref line);

sb.Append(line);

sb.Append(Define.CLRF);

}

sb.Append(Define.RF);

reader.Close();

}





File.SetAttributes(fileName,FileAttributes.Normal);



// TODO: 添加 ResourceParser.Parse 实现

using (StreamWriter outWriter = new StreamWriter(fileName))

{

outWriter.Write(sb.ToString());

}

return 0;

}



/// <summary>

/// 应用程序的主入口点。

/// </summary>

[STAThread]

static void Main(string[] args)

{

//

// TODO: 在此处添加代码以启动应用程序

//

ResourceParser parser = new ResourceParser();

parser.Parse("resource.h");

}



#endregion

}

}
view plaincopy to clipboardprint?
这篇文章写得比较懒,因为比较不喜欢一行一行的说代码,每个人的想法都不一样。还是那句话,只要

这篇文章写得比较懒,因为比较不喜欢一行一行的说代码,每个人的想法都不一样。还是那句话,只要view plaincopy to clipboardprint?
接口定义出来了,具体里面的实现就不会差到哪儿去。

文档说明:

     

相关文档


读取评论列表……