枚举和常量,它们是如何工作的?
Enums and constants, how does it all work?
最近几天我一直在网上寻找我的问题的答案,但没有成功。
因此,我试图了解常量在程序中的作用以及它们在 classes 中的引用方式。
我一直在翻看Scintilla的源代码,看到有几个值如:
public const int SC_WRAP_NONE = 0;
public const int SC_WRAP_WORD = 1;
public const int SC_WRAP_CHAR = 2;
public const int SC_WRAP_WHITESPACE = 3;
这些位于 NativeMethods.cs 文件 (here)。
我找到了说明其中一些是枚举的文档 (here)。上述示例是自动换行的枚举(按单词、字符或空格换行)。
但是,有些常量定义如下:
public const int SCI_START = 2000;
public const int SCI_OPTIONAL_START = 3000;
public const int SCI_LEXER_START = 4000;
public const int SCI_ADDTEXT = 2001;
public const int SCI_ADDSTYLEDTEXT = 2002;
public const int SCI_INSERTTEXT = 2003;
public const int SCI_CHANGEINSERTION = 2672;
public const int SCI_CLEARALL = 2004;
public const int SCI_DELETERANGE = 2645;
public const int SCI_CLEARDOCUMENTSTYLE = 2005;
//
// ... list continues
//
public const int SCI_SETWRAPINDENTMODE = 2472;
public const int SCI_GETWRAPINDENTMODE = 2473;
如果要将它们用作枚举,我想知道为什么它们从 2000
开始。
不仅如此,在class中的实现中(以SCI_SETWRAPINDENTMODE
和SCI_GETWRAPINDENTMODE
常量为例,其取值方式如下:
public WrapIndentMode WrapIndentMode
{
get
{
return (WrapIndentMode)DirectMessage(NativeMethods.SCI_GETWRAPINDENTMODE);
}
set
{
var wrapIndentMode = (int)value;
DirectMessage(NativeMethods.SCI_SETWRAPINDENTMODE, new IntPtr(wrapIndentMode));
}
}
这些值使用 DirectMessage
函数(类似于 Microsoft 的 SendMessage
函数)发送到 Scintilla。但是,我想弄清楚的是应用程序如何从接收枚举值到(在本例中)包装文本。这与 .dll
文件有关吗?
所以我的问题是:
- 为什么有些枚举以这么大的引用开头 (>2000)?
- 应用程序如何知道如何处理这些值以执行所需的输出。
- 最重要的是,我如何创建自己的函数,这些函数可以通过向它们发送枚举值来执行,程序如何知道如何处理我的枚举值?
如果可能的话,我希望有人能为我一步一步地分解它,并解释这里发生的事情的一般过程。
目前我的印象是枚举值被发送到一个 .dll
文件,它在其中调用一个方法,但我可能偏离了方向。
请记住,Scintilla 编辑控件最初是作为传统 Windows 控件设计的,与您在 Winforms 项目的工具箱中找到的 TextBox 或 RichTextBox 控件没有什么不同。 ScintillaNET 是它的包装器,就像 .NET TextBox 和 RichTextBox 类 是包装器一样,可以轻松地从 C# 等托管语言使用控件。您链接到的 GitHub 存储库仅包含包装器,不包含控件本身的代码。
它遵循与此类控件交互的传统方式,您向它发送一条消息。特定的消息编号告诉它要做什么,可选的 wparam 和 lparam 消息参数可能包含其他值。您看到的声明样式是 25 年前声明这些消息和值的方式的样板。
选择消息编号的基本方法是"pick a number, any number, as long as it larger than 1024 (WM_USER) and is unique"。偏移量是必需的,因此它们不会与系统消息冲突,例如 WM_CREATE。原作者只是认为 2000 年是一个很好的起点。
特定的消息编号告诉控件要做什么以及如何解释消息参数(wparam 和 lparam)。您只能通过为其选择消息编号并修改控件以识别消息并实现该功能来添加功能。控件(传统命名为WndProc)的window过程解释消息,可以看到it here。请记住,您需要 C++ 技能和对现有代码库的良好理解才能顺利完成。
最近几天我一直在网上寻找我的问题的答案,但没有成功。
因此,我试图了解常量在程序中的作用以及它们在 classes 中的引用方式。
我一直在翻看Scintilla的源代码,看到有几个值如:
public const int SC_WRAP_NONE = 0;
public const int SC_WRAP_WORD = 1;
public const int SC_WRAP_CHAR = 2;
public const int SC_WRAP_WHITESPACE = 3;
这些位于 NativeMethods.cs 文件 (here)。
我找到了说明其中一些是枚举的文档 (here)。上述示例是自动换行的枚举(按单词、字符或空格换行)。
但是,有些常量定义如下:
public const int SCI_START = 2000;
public const int SCI_OPTIONAL_START = 3000;
public const int SCI_LEXER_START = 4000;
public const int SCI_ADDTEXT = 2001;
public const int SCI_ADDSTYLEDTEXT = 2002;
public const int SCI_INSERTTEXT = 2003;
public const int SCI_CHANGEINSERTION = 2672;
public const int SCI_CLEARALL = 2004;
public const int SCI_DELETERANGE = 2645;
public const int SCI_CLEARDOCUMENTSTYLE = 2005;
//
// ... list continues
//
public const int SCI_SETWRAPINDENTMODE = 2472;
public const int SCI_GETWRAPINDENTMODE = 2473;
如果要将它们用作枚举,我想知道为什么它们从 2000
开始。
不仅如此,在class中的实现中(以SCI_SETWRAPINDENTMODE
和SCI_GETWRAPINDENTMODE
常量为例,其取值方式如下:
public WrapIndentMode WrapIndentMode
{
get
{
return (WrapIndentMode)DirectMessage(NativeMethods.SCI_GETWRAPINDENTMODE);
}
set
{
var wrapIndentMode = (int)value;
DirectMessage(NativeMethods.SCI_SETWRAPINDENTMODE, new IntPtr(wrapIndentMode));
}
}
这些值使用 DirectMessage
函数(类似于 Microsoft 的 SendMessage
函数)发送到 Scintilla。但是,我想弄清楚的是应用程序如何从接收枚举值到(在本例中)包装文本。这与 .dll
文件有关吗?
所以我的问题是:
- 为什么有些枚举以这么大的引用开头 (>2000)?
- 应用程序如何知道如何处理这些值以执行所需的输出。
- 最重要的是,我如何创建自己的函数,这些函数可以通过向它们发送枚举值来执行,程序如何知道如何处理我的枚举值?
如果可能的话,我希望有人能为我一步一步地分解它,并解释这里发生的事情的一般过程。
目前我的印象是枚举值被发送到一个 .dll
文件,它在其中调用一个方法,但我可能偏离了方向。
请记住,Scintilla 编辑控件最初是作为传统 Windows 控件设计的,与您在 Winforms 项目的工具箱中找到的 TextBox 或 RichTextBox 控件没有什么不同。 ScintillaNET 是它的包装器,就像 .NET TextBox 和 RichTextBox 类 是包装器一样,可以轻松地从 C# 等托管语言使用控件。您链接到的 GitHub 存储库仅包含包装器,不包含控件本身的代码。
它遵循与此类控件交互的传统方式,您向它发送一条消息。特定的消息编号告诉它要做什么,可选的 wparam 和 lparam 消息参数可能包含其他值。您看到的声明样式是 25 年前声明这些消息和值的方式的样板。
选择消息编号的基本方法是"pick a number, any number, as long as it larger than 1024 (WM_USER) and is unique"。偏移量是必需的,因此它们不会与系统消息冲突,例如 WM_CREATE。原作者只是认为 2000 年是一个很好的起点。
特定的消息编号告诉控件要做什么以及如何解释消息参数(wparam 和 lparam)。您只能通过为其选择消息编号并修改控件以识别消息并实现该功能来添加功能。控件(传统命名为WndProc)的window过程解释消息,可以看到it here。请记住,您需要 C++ 技能和对现有代码库的良好理解才能顺利完成。