Найти глобальный атом из частичной строки - PullRequest
3 голосов
/ 22 апреля 2011

Я могу создать Глобальный Атом, используя GlobalAddAtom, и могу найти этот атом снова, используя GlobalFindAtom, если я уже знаю строку, связанную с атомом.Но есть ли способ найти все атомы, чья связанная строка соответствует заданной частичной строке?

Например, допустим, у меня есть атом, строка которого "Hello, World!"Как я могу позже найти этот атом, выполнив поиск «Hello»?

Ответы [ 2 ]

4 голосов
/ 22 апреля 2011

К сожалению, описываемое вами поведение невозможно для таблиц Atom.Это связано с тем, что таблицы Atom в Windows в основном являются хэш-таблицами, а процесс отображения обрабатывает строки целиком, а не по частям.

Конечно, это звучит почти так, как можно было бы, как процитировано из Документация MSDN :

Приложения также могут использовать таблицы локальных атомов для экономии времени при поиске конкретной строки.Чтобы выполнить поиск, приложению нужно только поместить строку поиска в таблицу атомов и сравнить полученный атом с атомами в соответствующих структурах.Сравнение атомов обычно выполняется быстрее, чем сравнение строк.

Однако они имеют в виду точные совпадения.Это ограничение, вероятно, устарело по сравнению с тем, что возможно с ресурсами, доступными в настоящее время для программного обеспечения.Тем не менее, Atoms были доступны еще в Win16, и в то время это средство позволяло приложениям эффективно управлять строковыми данными в минимальном объеме памяти.Атомы по-прежнему используются в настоящее время для управления именами классов окон и все еще обеспечивают приличные преимущества в уменьшении занимаемой площади нескольких хранимых копий строк.

Если вам необходимо эффективно хранить строковые данные и иметь возможность сканирования при частичном запускесоответствует, Suffix Tree может удовлетворить или превысить ваши потребности.

2 голосов
/ 12 октября 2016

Это на самом деле можно сделать, но только путем сканирования их всех.В LINQPad 5 это можно сделать за 0,025 секунды на моей машине, поэтому это довольно быстроВот пример реализации:

void Main()
{
  const string atomPrefix = "Hello";
  const int bufferSize = 1024;
  ushort smallestAtomIndex = 0XC000;
  var buffer = new StringBuilder(bufferSize);
  var results = new List<string>();
  for (ushort atomIndex = smallestAtomIndex; atomIndex < ushort.MaxValue; atomIndex++)
  {
    var resultLength = GlobalGetAtomName(atomIndex, buffer, bufferSize);
    if (buffer.ToString().StartsWith(atomPrefix))
    {
      results.Add($"{buffer} - {atomIndex}");
    }
    buffer.Clear();
  }

  results.Dump();
}

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern uint GlobalGetAtomName(ushort atom, StringBuilder buffer, int size);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...