Перечисления и константы, как все это работает?

Я был в Интернете в течение последних нескольких дней в поисках ответа на мой вопрос, и мне не повезло.

Итак, я пытаюсь понять роль констант в программе и как на них ссылаются в классах.

Я просматривал исходный код 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 ( здесь).

Я нашел документацию ( здесь), которая объясняет, что некоторые из них являются перечислениями. вышеупомянутый пример - перечисление для переноса слова (перенос по слову, символу или пробелу).

Однако есть некоторые константы, определенные так:

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,

Не только это, но и в реализации в классе (принимая 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));
    }
}

Эти значения отправляются в Scintilla с помощью DirectMessage функция (аналогично Microsoft SendMessage функция). Однако я пытаюсь выяснить, как приложение получает от получения значений enum до (в данном случае) переноса текста. Это как-то связано с .dll файлы?

Итак, мои вопросы:

  1. Почему некоторые перечисления начинаются с такой большой ссылки (>2000)?
  2. Как приложение знает, что делать со значениями, чтобы получить желаемый результат.
  3. Что наиболее важно, как я могу создать свои собственные функции, которые можно задействовать, посылая им значения enum, и как программа узнает, что делать со значениями MY enum?

Если возможно, я бы хотел, чтобы кто-то просто пошагово рассказал мне об этом и объяснил общий процесс происходящего здесь.

В настоящее время у меня сложилось впечатление, что значение enum отправлено .dll файл, где он вызывает метод, но я могу быть далеко.

1 ответ

Решение

Имейте в виду, что элемент управления Scintilla изначально был разработан как традиционный элемент управления Windows, не отличающийся, скажем, от элемента управления TextBox или RichTextBox, который вы найдете на панели инструментов для проекта Winforms. ScintillaNET является оберткой для него, так же как классы.NET TextBox и RichTextBox являются обертками, упрощая использование элемента управления из управляемого языка, такого как C#. В хранилище GitHub, на которое вы ссылаетесь, содержится только оболочка, а не код самого элемента управления.

Следует традиционный способ взаимодействия с такими элементами управления, вы отправляете ему сообщение. Конкретный номер сообщения указывает, что делать, необязательные аргументы сообщения wparam и lparam могут содержать дополнительные значения. Стиль объявления, который вы видите, является образцом для способа, которым эти сообщения и значения были объявлены 25 лет назад.

Основной рецепт для выбора номеров сообщений: "выберите номер, любой номер, если он больше 1024 (WM_USER) и является уникальным". Смещение требуется, чтобы они не конфликтовали с системными сообщениями, такими как WM_CREATE. Первоначальный автор просто решил, что 2000 год - хорошее место для начала.

Конкретный номер сообщения указывает элементу управления, что делать и как интерпретировать аргументы сообщения (wparam и lparam). Вы можете добавить функцию, только выбрав для нее номер сообщения и изменив элемент управления для распознавания сообщения и реализации функции. Оконная процедура элемента управления (традиционно называемая WndProc) интерпретирует сообщение, вы можете увидеть его здесь. Имейте в виду, что вам нужны навыки C++ и хорошее понимание существующей кодовой базы, чтобы довести это до конца.

Другие вопросы по тегам